Skip to content

Conversation

@MorganDawe
Copy link
Contributor

@MorganDawe MorganDawe commented Nov 25, 2025

Summary by CodeRabbit

  • New Features

    • Improved node migration: refined processing of origin information and reuse of templates for date-related fields to preserve metadata consistency.
    • Added an OAI metadata map for the PC profile, aligning Drupal fields to Dublin Core for subjects, geographic data, origin details, and related items.
    • Introduced a structured, configurable mapping for consistent metadata export.
  • Chores

    • Declared migrate, dgi_standard_oai, and rest_oai_pmh dependencies in the module manifest and package configuration.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

Walkthrough

Adds a Migration Alter plugin that mutates the dssi_node migration process pipeline, introduces an OAI metadata map plugin (PcStandard) with paragraph-to-Dublin-Core mappings, and updates module and Composer manifests to declare/require additional dependencies.

Changes

Cohort / File(s) Change Summary
Migration Alter Plugin
src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php
New DssiNodeAlter class (extends MigrationAlterBase, implements MigrationAlterInterface) with public function alter(array &$migration): void. Alters the migration process pipeline: sets field_origin_information[1]['keys'] to a list of event/date/metadata keys and reuses the template from field_origin_information[2]['values']['field_frequency'] for field_origin_information[2]['values']['field_date_note'], then sets its first source to parent_value/date_note. Plugin annotation includes id = "pcdora_dssi_node_alter" and migration_id = "dssi_node".
OAI Metadata Map Plugin
src/Plugin/OaiMetadataMap/PcStandard.php
New PcStandard class (extends DgiStandard) with OAI metadata map annotation and a protected const PARAGRAPH_MAPPING containing nested mappings from paragraph/field names (e.g., field_faceted_subject, field_hierarchical_geographic_su, field_origin_information, field_related_item) to Dublin Core terms. No runtime methods added.
Module manifest
pcdora.info.yml
Adds dependencies: drupal:migrate, dgi_standard_oai:dgi_standard_oai, and rest_oai_pmh:rest_oai_pmh.
Composer manifest
composer.json
Adds package requirements: discoverygarden/dgi_standard_oai: ^1.4 and drupal/rest_oai_pmh: ^2 in the require block.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Inspect DssiNodeAlter::alter() for correct array paths and the full list of keys assigned to field_origin_information[1]['keys'].
  • Verify the template copy and that field_date_note source is exactly parent_value/date_note.
  • Validate PcStandard::PARAGRAPH_MAPPING for correct field-to-Dublin-Core mappings.
  • Confirm pcdora.info.yml and composer.json dependency syntax and versions.

Poem

🐇 I hop through keys and borrow a line,

I paste a date and make fields align,
PcStandard hums a Dublin Core tune,
DssiNodeAlter tweaks by light of the moon,
A tiny rabbit applauds the new design.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and specifically describes the main changes: adding OaiMetadataMap and DssiNodeAlter plugins, which aligns with the new classes and plugin declarations introduced in the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch SUP-7358-additional

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e6c261d and 7e07d5a.

📒 Files selected for processing (1)
  • composer.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • composer.json

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 519271c and 2a17685.

📒 Files selected for processing (2)
  • src/Plugin/OaiMetadataMap/DublinCore.php (1 hunks)
  • src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Code Linting
src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php

[error] 19-19: Opening brace should be on the same line as the declaration (Drupal.Classes.ClassDeclaration.BraceOnNewLine). PHPCS can fix automatically with PHPCBF.


[error] 25-25: Opening brace should be on the same line as the declaration (Drupal.Functions.MultiLineFunctionDeclaration.BraceOnNewLine). PHPCS can fix automatically with PHPCBF.

🔇 Additional comments (3)
src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php (1)

26-38: LGTM!

The migration process configuration correctly chains skip_on_empty and explode plugins for conditional field processing.

src/Plugin/OaiMetadataMap/DublinCore.php (2)

1-22: LGTM!

The plugin annotation and class structure are correctly configured for an OAI Dublin Core metadata map.


30-64: Verify the field name on line 32 matches actual Drupal field definitions.

The field name 'field_topic_general_subdivision_' on line 32 has a trailing underscore, which is inconsistent with the truncation pattern of other field names on lines 33-34 (field_temporal_chronological_sub, field_geographic_geographic_subd).

Since field definitions are not present in this repository, verify that this field name matches the actual machine name of the Drupal field in your installation. The trailing underscore may be a typo, or it could be the correct field name if your field was intentionally named with a trailing underscore.

'field_origin_information' => [
'field_date_created' => 'dcterms:created',
'field_date_issued' => 'dcterms:issued',
'field_date_note' => 'dcterms:date',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mapping overriden to include field_date_note

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cbbd305 and 8190263.

📒 Files selected for processing (1)
  • src/Plugin/OaiMetadataMap/PcStandard.php (1 hunks)
🔇 Additional comments (3)
src/Plugin/OaiMetadataMap/PcStandard.php (3)

1-6: LGTM!

The file header, namespace, and import statement follow Drupal coding standards.


30-64: Verify field names against your Drupal field configuration.

The field names in this mapping, particularly 'field_topic_general_subdivision_' on line 32, could not be verified in the codebase search. The trailing underscore is unusual and warrants confirmation. Please verify that all field names in the PARAGRAPH_MAPPING constant match the actual field names defined in your Drupal configuration, especially the one with the trailing underscore and the truncated field names like 'field_temporal_chronological_sub' and 'field_geographic_geographic_subd'.


22-23: Verify the dgi_standard_oai module documentation to confirm parent class usage.

The parent class DgiStandard is from an external Drupal module (dgi_standard_oai) which is not available in this repository. The web search found no public documentation for this module, suggesting it's a private or custom implementation. You'll need to:

  • Check the dgi_standard_oai module's DgiStandard class to confirm it actually references the PARAGRAPH_MAPPING constant
  • Review whether the constant override pattern is supported in that module's design

The pattern of defining a constant in a child class for parent usage is valid OOP design, but only the module maintainers can confirm this specific implementation follows that contract.

Comment on lines +7 to +21
/**
* OAI implementation for the PC metadata profile.
*
* @OaiMetadataMap(
* id = "pc_standard_oai",
* label = @Translation("DPLAVA (PC)"),
* metadata_format = "mdRecord",
* template = {
* "type" = "module",
* "name" = "rest_oai_pmh",
* "directory" = "templates",
* "file" = "oai-default"
* }
* )
*/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Verify the metadata format and template configuration.

The metadata_format is set to "mdRecord", which is non-standard for OAI-PMH (typical formats include "oai_dc", "oai_marc", etc.). Additionally, verify that the template file "oai-default" exists in the rest_oai_pmh module at the specified location.

Run the following script to verify the template reference:


🏁 Script executed:

#!/bin/bash
# Description: Verify the template file exists in rest_oai_pmh module

# Search for the template file
fd -t f "oai-default" --full-path --exec echo "Found: {}"

# Search for rest_oai_pmh module usage
rg -n "rest_oai_pmh" --type=php -C2

Length of output: 354



🏁 Script executed:

#!/bin/bash
# Search for template files with common extensions
echo "=== Searching for template files with common extensions ==="
fd -t f "oai" --exec file {} \; | grep -i "template\|text"

# Search for any files named "oai-default" with any extension
echo -e "\n=== Searching for oai-default with any extension ==="
fd "oai-default" -t f

# Search for rest_oai_pmh module/directory
echo -e "\n=== Searching for rest_oai_pmh directory or module ==="
fd "rest_oai_pmh" -t d

# Look at similar OaiMetadataMap plugins for comparison
echo -e "\n=== Checking other OaiMetadataMap plugins ==="
fd -t f ".*Standard\.php$" -path "*/OaiMetadataMap/*"

Length of output: 385



🏁 Script executed:

#!/bin/bash
# Find all OaiMetadataMap plugin files
echo "=== All OaiMetadataMap plugin files ==="
fd -t f -path "*/OaiMetadataMap/*.php"

# Check if there's a modules or contrib directory
echo -e "\n=== Checking for external modules directories ==="
fd -t d "modules\|contrib" -d 2

# Look for any configuration files that might reference rest_oai_pmh
echo -e "\n=== References to rest_oai_pmh in entire codebase ==="
rg "rest_oai_pmh" -n

# Check for template directories
echo -e "\n=== Template directories in repo ==="
fd -t d "templates"

Length of output: 427



🏁 Script executed:

#!/bin/bash
# Find all OaiMetadataMap plugin files (corrected syntax)
echo "=== All OaiMetadataMap plugin files ==="
find src -type f -name "*.php" -path "*/OaiMetadataMap/*" 2>/dev/null

# Show content of OaiMetadataMap directory
echo -e "\n=== Contents of OaiMetadataMap directory ==="
find src -type f -path "*/OaiMetadataMap/*" 2>/dev/null | head -20

# Check directory structure around PcStandard.php
echo -e "\n=== Directory structure of OaiMetadataMap ==="
find src/Plugin/OaiMetadataMap -type f 2>/dev/null || echo "Directory not found"

# Look at the actual class definition in PcStandard.php
echo -e "\n=== Full PcStandard.php file ==="
cat src/Plugin/OaiMetadataMap/PcStandard.php

Length of output: 2296



🏁 Script executed:

#!/bin/bash
# Find DgiStandard class (parent class)
echo "=== Searching for DgiStandard class ==="
find . -type f -name "*.php" -exec grep -l "class DgiStandard" {} \;

# Check for dgi_standard_oai module
echo -e "\n=== Searching for dgi_standard_oai module ==="
find . -type d -name "dgi_standard_oai"

# Look for composer.json to see dependencies
echo -e "\n=== Checking for composer.json ==="
find . -maxdepth 2 -name "composer.json" -exec cat {} \;

# Search for .info.yml files (Drupal module definitions)
echo -e "\n=== Drupal module files (.info.yml) ==="
find . -name "*.info.yml" | head -10

Length of output: 345



🏁 Script executed:

#!/bin/bash
# Check the module info file for dependencies
echo "=== pcdora.info.yml content ==="
cat ./pcdora.info.yml

Length of output: 177


</web_search>


🌐 Web query:

OAI-PMH metadata formats standard mdRecord

💡 Result:

Short answer: mdRecord is not part of the OAI‑PMH protocol standard — it’s an implementation‑specific metadataPrefix used by some repositories (e.g., Islandora/related projects) to expose a repository’s native/richer metadata. OAI‑PMH itself requires only oai_dc (Dublin Core) and allows repositories to define additional metadata formats identified by a metadataPrefix and a metadata schema. See the OAI‑PMH spec for how metadataPrefix/metadataSchema are defined and returned via ListMetadataFormats, and an example of mdRecord usage in Islandora/Islandora‑derived docs. [1][2][3]

If you need details for a particular repository:

  • Call ?verb=ListMetadataFormats on that repository’s baseURL to see whether it supports metadataPrefix=mdRecord and the schemaLocation it uses. The response will include the metadataPrefix, metadataNamespace/metadataSchema (or schemaLocation) you must use. [2]

Sources

  • OAI‑PMH v2.0 specification (metadataPrefix / ListMetadataFormats). [1]
  • Example: Islandora / Arca documentation showing metadataPrefix "mdRecord" (repository‑specific). [2]
  • Omeka / general OAI‑PMH docs showing repositories publish custom metadataPrefix values. [3]

References

  1. Open Archives Initiative Protocol for Metadata Harvesting (OAI‑PMH) v2.0 — metadataPrefix & ListMetadataFormats. [openarchives.org].
  2. OAI‑PMH harvesting — Islandora/Arca docs (example using metadataPrefix "mdRecord").
  3. Omeka S / OAI‑PMH documentation (examples of custom metadataPrefix values).

Add required module dependencies to pcdora.info.yml.

The code references external modules (dgi_standard_oai for the DgiStandard parent class and rest_oai_pmh for the template configuration) but these are not declared as dependencies in pcdora.info.yml. This will cause the module to fail at runtime when attempting to instantiate the class or load the template. Both modules must be explicitly declared in the module's info file.

Additionally, while metadata_format = "mdRecord" is not a standard OAI-PMH format (which typically use formats like "oai_dc" or "oai_marc"), it is a valid implementation-specific metadataPrefix used in projects like Islandora. Verify this is intentional for your use case.

🤖 Prompt for AI Agents
In src/Plugin/OaiMetadataMap/PcStandard.php around lines 7 to 21, the plugin
references external modules (dgi_standard_oai for the DgiStandard parent class
and rest_oai_pmh for the template) that are not declared as dependencies; update
pcdora.info.yml to add both dgi_standard_oai and rest_oai_pmh to the
dependencies list so Drupal installs/loads them before this module, and confirm
that metadata_format = "mdRecord" is intentional for your deployment (change to
a standard OAI-PMH metadataPrefix like oai_dc if that was a mistake).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8190263 and c1672c9.

📒 Files selected for processing (1)
  • src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php (1 hunks)
🔇 Additional comments (1)
src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php (1)

23-53: Alter logic for field_origin_information is clean and consistent

The use of a referenced $process plus the explicit keys list and two-step field_date_note pipeline (skip_on_empty then explode on ^) is clear and matches typical Drupal Migrate process patterns for sub-process/paragraph mappings, assuming the existing DSSI node migration structure.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
pcdora.info.yml (1)

6-7: Ensure all plugin provider modules are declared as dependencies

Adding drupal:migrate makes sense for the new migration alter plugin, but this module also depends on classes from dgi_migrate_alter (and, for the OAI metadata map, whatever module provides the OaiMetadataMap plugin type / DgiStandard base). To avoid enabling pcdora without its plugin providers, consider declaring those module dependencies here as well (in addition to drupal:migrate), or confirm they are already covered elsewhere in your stack.

src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php (1)

24-50: Optional: guard against unexpected migration process shapes

alter() assumes that $migration['process']['field_origin_information'][1] and [2] exist and that overwriting them is always safe for the dssi_node migration. That’s fine for the current config, but if the migration definition changes or this alter is reused, those hard‑coded indexes could end up clobbering unrelated process steps.

If you want this to be more defensive, consider bailing out when field_origin_information is missing/not an array, or when the expected indexes aren’t present, before assigning into them.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c1672c9 and 22f242c.

📒 Files selected for processing (2)
  • pcdora.info.yml (1 hunks)
  • src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Code Linting
src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php

[warning] 7-7: Unused use statement. Drupal.Classes.UnusedUseStatement.UnusedUse. PHPCBF can fix automatically.


[error] 1-1: PHPCS: Command '/home/runner/work/_actions/discoverygarden/CodeSniffer/v1/vendor/bin/phpcs -s --standard=Drupal,DrupalPractice --extensions=php,module,inc,install,test,profile,theme,css,info,md,yml ./ --ignore=*.md' exited with code 2.

🔇 Additional comments (1)
src/Plugin/dgi_migrate_alter/spreadsheet/DssiNodeAlter.php (1)

5-17: Verify the external dgi_migrate_alter module to confirm annotation class path and import requirement

The review recommends adding use Drupal\dgi_migrate_alter\Annotation\MigrationAlter;, but this cannot be verified within the current codebase. Codebase analysis shows:

  • @MigrationAlter annotation is used in the docblock without an explicit import
  • The Translation import is present and actively used in @Translation(...) annotations—the PHPCS "unused use" warning appears to be a false positive
  • dgi_migrate_alter is an external module providing MigrationAlterBase and MigrationAlterInterface, but the codebase does not contain its source to verify whether it provides a MigrationAlter annotation class

To resolve the review comment, you need to:

  1. Check the external dgi_migrate_alter module's source to confirm the exact namespace and existence of the MigrationAlter annotation class
  2. Verify whether Drupal's plugin discovery in your version requires explicit annotation class imports
  3. If the annotation class exists at a different namespace or the import is required, add it; otherwise, dismiss the review as speculative
  4. Keep the Translation import—do not remove it despite PHPCS warnings, as it is required for @Translation() in annotations

@nchiasson-dgi nchiasson-dgi added the minor Added functionality that is backwards compatible. label Dec 15, 2025
@nchiasson-dgi nchiasson-dgi merged commit d36bfe5 into 2.x Dec 15, 2025
2 checks passed
@nchiasson-dgi nchiasson-dgi deleted the SUP-7358-additional branch December 15, 2025 17:26
@github-actions
Copy link

Tag generated by PR: v2.2.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor Added functionality that is backwards compatible.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants