Skip to content

Conversation

@adam-vessey
Copy link
Contributor

@adam-vessey adam-vessey commented Jun 27, 2025

Can happen with views, say, creating a view of media with relationships to their files, for whatever reason.

As it was, it could end up exploding with assertions.

As is here, it would might end up tagging multiple times.

Summary by CodeRabbit

  • Refactor
    • Query tagging for file and media access delegated to a dedicated service for cleaner, more maintainable request handling; no user-facing behavior change.
  • Chores
    • Small signature and type-hint modernizations, plus formatting updates.
    • Dependency changed from islandora/islandora to drupal/islandora.
  • CI
    • PHPUnit workflow action reference updated to a newer tag.

Can happen with views, say, creating a view of media with relationships
to their files, for whatever reason.

As is here, it would might end up tagging multiple times.
@adam-vessey adam-vessey added the patch Backwards compatible bug fixes. label Jun 27, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 27, 2025

Walkthrough

Refactors query-tagging to pass an explicit type string into QueryTagger::tagQuery instead of embedding type in query metadata; callers updated accordingly. QueryTagger::tagQuery now requires a string $type and validates it ('media'|'file'). Several constructors gained trailing commas, generate() became ?EntityInterface nullable, and a GitHub Actions job reference was updated.

Changes

Cohort / File(s) Change Summary
Query tagging changes
islandora_hierarchical_access.module, src/Access/QueryTagger.php
Hook implementations no longer mutate query metadata; they obtain the QueryTagger service and call `tagQuery($query, 'file'
LUT generator nullable change
src/LUTGenerator.php, src/LUTGeneratorInterface.php
generate() parameter made explicitly nullable: ?EntityInterface $entity = NULL in both implementation and interface.
Trailing-comma formatting changes
src/Commands/IslandoraHierarchicalAccessCommands.php, src/EntityAccessHandler.php, src/EntityCUDHandler.php
Added trailing commas to multi-line constructor signatures / parameter lists. No behavioral changes.
Composer dependency update
composer.json
require entry changed from islandora/islandora (^2) to drupal/islandora (^2).
CI workflow reference
.github/workflows/phpunit.yml
PHPUnit job uses reference changed from discoverygarden/phpunit-action/.github/workflows/phpunit.yml@v1 to ...@fix/update-matrix (action tag/version update).

Sequence Diagram(s)

sequenceDiagram
    participant Hook as Hook implementation
    participant Service as QueryTagger
    participant Query as SelectInterface

    Hook->>Service: tagQuery(Query, "file" or "media")
    Note right of Service #D0E8D0: Validate type == "file" | "media"
    Service->>Query: Apply hierarchical-access tags/conditions
    Query-->>Hook: Query prepared for execution
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

A rabbit hops with careful cheer,
I passed a type and left no smear.
No hidden tags to chase my tail,
Just clear, small args along the trail.
Hop—access neat and error-free 🐇

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.

📜 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 b91cba4 and e1e1c84.

📒 Files selected for processing (1)
  • .github/workflows/phpunit.yml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/phpunit.yml

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately captures the PR's main objective — allowing both file_access and media_access to be present to avoid assertions and duplicate tagging — and directly corresponds to the changes in the query-tagging/hooks and QueryTagger updates described in the PR. It is concise, specific, and readable for teammates scanning history.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/multiple-taggings

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.

@MorganDawe MorganDawe marked this pull request as ready for review July 24, 2025 17:43
@MorganDawe
Copy link

Reviewing as part of https://github.com/discoverygarden/ctda-drupal/pull/432

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/LUTGenerator.php (1)

66-69: Replace assert with a runtime guard to avoid silent misuse in production.

assert($entity instanceof MediaInterface) is commonly disabled in prod. If a non-media entity slips through, the query will filter mid by a non-media ID, leading to confusing no-op behavior. Throw a clear exception (or early return) instead.

Apply within this hunk:

-    if ($entity) {
-      assert($entity instanceof MediaInterface);
-      $query->condition("{$media_alias}.mid", $entity->id());
-    }
+    if ($entity !== NULL) {
+      if (!($entity instanceof MediaInterface)) {
+        throw new \InvalidArgumentException('LUTGenerator::generate() expects a Media entity when $entity is provided.');
+      }
+      $query->condition("{$media_alias}.mid", $entity->id());
+    }
🧹 Nitpick comments (4)
src/EntityCUDHandler.php (2)

81-86: Trailing comma is fine on PHP 8+, but consider adding scalar types to constructor args.

  • The trailing comma after $operations is valid only on PHP 8.0+. Please confirm the module’s PHP constraint (composer.json) is >= 8.0.
  • Add scalar types for $column and $operations to align with the typed properties (string $column, int $operations) and fail fast.

Apply within this hunk:

   public function __construct(
     Connection $database,
     LUTGeneratorInterface $generator,
-    $column,
-    $operations,
+    string $column,
+    int $operations,
   ) {

96-103: Defaulting to DELETE when not configured—make intent explicit.

createInstance() falls back to OPERATIONS_DELETE if the entity type didn’t set operations. That’s likely intended for file/node, but it’s implicit. Consider explicitly setting operations in attach() for File and Node to avoid surprises if new entity types are attached without ops.

Outside this hunk (for clarity), suggested changes in attach():

// File entities.
$entity_type->setHandlerClass(static::NAME, static::class)
  ->set(static::PROPERTY_NAME__COLUMN, 'fid')
  ->set(static::PROPERTY_NAME__OPERATIONS, static::OPERATIONS_DELETE);

// Media entities.
$entity_type->setHandlerClass(static::NAME, static::class)
  ->set(static::PROPERTY_NAME__COLUMN, 'mid')
  ->set(static::PROPERTY_NAME__OPERATIONS, static::OPERATIONS_CREATE | static::OPERATIONS_UPDATE | static::OPERATIONS_DELETE);

// Node entities.
$entity_type->setHandlerClass(static::NAME, static::class)
  ->set(static::PROPERTY_NAME__COLUMN, 'nid')
  ->set(static::PROPERTY_NAME__OPERATIONS, static::OPERATIONS_DELETE);
src/LUTGeneratorInterface.php (1)

27-27: Nullable parameter: OK, but type should reflect actual usage (Media only).

generate(?EntityInterface $entity = NULL) widens acceptance, but the implementation only supports Media (filters on mid). Either:

  • Keep as-is and document that, if provided, $entity must be a MediaInterface; or
  • Preferably narrow the type to ?MediaInterface to make the contract explicit.

Option A (narrow type) within this hunk:

-  public function generate(?EntityInterface $entity = NULL): void;
+  public function generate(?\Drupal\media\MediaInterface $entity = NULL): void;

Additionally (outside this hunk), add the import and update the docblock:

use Drupal\media\MediaInterface;

/**
 * @param \Drupal\media\MediaInterface|null $entity
 *   If provided, only rows for the given media entity will be added.
 */
src/LUTGenerator.php (1)

103-114: Minor: use strict in_array to avoid accidental matches.

When de-duplicating field names, add strict comparison to be safe.

Suggested change (outside this hunk):

-        if (!in_array($name, $this->uniqueFileFields)) {
+        if (!in_array($name, $this->uniqueFileFields, true)) {
           $this->uniqueFileFields[] = $name;
         }
📜 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 dc5f335 and 308bbbb.

📒 Files selected for processing (6)
  • islandora_hierarchical_access.module (3 hunks)
  • src/Commands/IslandoraHierarchicalAccessCommands.php (1 hunks)
  • src/EntityAccessHandler.php (1 hunks)
  • src/EntityCUDHandler.php (1 hunks)
  • src/LUTGenerator.php (1 hunks)
  • src/LUTGeneratorInterface.php (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/EntityAccessHandler.php
  • src/Commands/IslandoraHierarchicalAccessCommands.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • islandora_hierarchical_access.module
🧰 Additional context used
🧬 Code graph analysis (2)
src/LUTGeneratorInterface.php (1)
src/LUTGenerator.php (1)
  • generate (53-91)
src/LUTGenerator.php (1)
src/LUTGeneratorInterface.php (1)
  • generate (27-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: PHPUnit / Drupal 10.2 | PHP 8.3
  • GitHub Check: PHPUnit / Drupal 10.3 | PHP 8.2
  • GitHub Check: PHPUnit / Drupal 10.3 | PHP 8.3
  • GitHub Check: PHPUnit / Drupal 10.2 | PHP 8.2
🔇 Additional comments (1)
src/LUTGenerator.php (1)

53-53: Signature stays consistent with the interface—LGTM.

Matches LUTGeneratorInterface::generate(?EntityInterface $entity = NULL). No issues.

jobs:
PHPUnit:
uses: discoverygarden/phpunit-action/.github/workflows/phpunit.yml@v1
uses: discoverygarden/phpunit-action/.github/workflows/phpunit.yml@fix/update-matrix
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is pointing at discoverygarden/phpunit-action#26 to fix tests. Should probably be merged and pointed at before this PR is merged.

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

Labels

patch Backwards compatible bug fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants