Skip to content

557 Show detail button for items in media library#438

Open
absumo wants to merge 1 commit intomasterfrom
557-copy-link-media-item
Open

557 Show detail button for items in media library#438
absumo wants to merge 1 commit intomasterfrom
557-copy-link-media-item

Conversation

@absumo
Copy link
Copy Markdown

@absumo absumo commented Apr 10, 2026

Summary by Sourcery

Add a detail/view action to media library items in the backend grid.

New Features:

  • Add a detail column to the media item data grid that links to the item’s public view.

Enhancements:

  • Generate media item view URLs based on storage type, supporting YouTube, Vimeo, and local files, and render them as a small action button in the grid.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 10, 2026

Reviewer's Guide

Adds a new "detail" column to the media library items datagrid that renders a context-specific “view” button linking to either YouTube, Vimeo, or a local media file, enabling users to open the media item directly from the list.

Updated class diagram for MediaItemDataGrid with new detail column and getDetailUrl

classDiagram
  class MediaItemDataGrid {
    +__construct(Type type, int folderId, string searchQuery)
    +setExtras(Type type, int folderId)
    +addColumn(string name)
    +setColumnFunction(callable callback, string[] parameters, string columnName, bool overwrite)
    +getParameters(Type type, int folderId, string searchQuery) array
    +getDetailUrl(string shardingFolderName, string url, string storageType) string
  }

  class DataGrid {
    +addColumn(string name)
    +setColumnFunction(callable callback, string[] parameters, string columnName, bool overwrite)
  }

  class Language {
    +lbl(string key) string
  }

  MediaItemDataGrid --|> DataGrid
  MediaItemDataGrid ..> Language : uses

  note for MediaItemDataGrid "Constructor now adds detail column and binds getDetailUrl to render context specific view button"
Loading

File-Level Changes

Change Details Files
Add a new "detail" column to the media items datagrid that renders per-row view links.
  • Register a new datagrid column named "detail" for media items.
  • Configure the column to render using a static callback with sharding folder name, URL, and storage type as arguments.
  • Ensure the column is appended without altering existing filtering or parameter logic.
src/Backend/Modules/MediaLibrary/Domain/MediaItem/MediaItemDataGrid.php
Implement URL construction and HTML rendering for the media item detail/view button.
  • Introduce static getDetailUrl helper that generates destination URLs based on storage type (YouTube, Vimeo, local file).
  • Build a Bootstrap-styled button with an eye icon and localized "View" label that opens in a new tab.
  • Use sharding folder and file URL to construct local media file paths under the MediaLibrary frontend directory.
src/Backend/Modules/MediaLibrary/Domain/MediaItem/MediaItemDataGrid.php

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The hardcoded media URLs in getDetailUrl (YouTube, Vimeo, and the local /src/Frontend/Files/MediaLibrary/ path) couple this grid to specific domains and paths; consider using configuration/constants or existing URL helpers so these links remain valid if the environment or routing changes.
  • The storageType string checks ('youtube', 'vimeo') are brittle; if you already have an enum/Type/constant representation for storage types elsewhere in the media library domain, reusing that here would reduce the risk of mismatch.
  • Since getDetailUrl builds HTML with interpolated values, it would be safer to ensure $link and the label are properly escaped (e.g. htmlspecialchars) and to use sprintf or a small template helper to make the markup clearer and less error-prone.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The hardcoded media URLs in `getDetailUrl` (YouTube, Vimeo, and the local `/src/Frontend/Files/MediaLibrary/` path) couple this grid to specific domains and paths; consider using configuration/constants or existing URL helpers so these links remain valid if the environment or routing changes.
- The `storageType` string checks (`'youtube'`, `'vimeo'`) are brittle; if you already have an enum/Type/constant representation for storage types elsewhere in the media library domain, reusing that here would reduce the risk of mismatch.
- Since `getDetailUrl` builds HTML with interpolated values, it would be safer to ensure `$link` and the label are properly escaped (e.g. `htmlspecialchars`) and to use `sprintf` or a small template helper to make the markup clearer and less error-prone.

## Individual Comments

### Comment 1
<location path="src/Backend/Modules/MediaLibrary/Domain/MediaItem/MediaItemDataGrid.php" line_range="223-227" />
<code_context>
         $this->setColumnFunction('htmlspecialchars', ['[title]'], 'title', false);
     }
+
+    public static function getDetailUrl(string $shardingFolderName, string $url, string $storageType): string
+    {
+        if ($storageType === 'youtube') {
+            $link = 'https://youtube.com/watch?v=' . $url;
+        } elseif ($storageType === 'vimeo') {
+            $link = 'https://www.vimeo.com/' . $url;
+        } else {
</code_context>
<issue_to_address>
**suggestion:** Avoid hard-coded storage type strings and normalise external URLs.

Using raw strings like `'youtube'` and `'vimeo'` for `storageType` makes this fragile to typos and harder to change later; if there’s an existing enum/constant set for storage types, please reuse it here. Also, consider normalising the generated URLs to the conventional forms `https://www.youtube.com/watch?v=...` and `https://vimeo.com/...` rather than mixing domains/subdomains.

Suggested implementation:

```
    public static function getDetailUrl(string $shardingFolderName, string $url, string $storageType): string
    {
        // map known storage types to their canonical external URL bases
        $externalUrlBaseMap = [
            'youtube' => 'https://www.youtube.com/watch?v=',
            'vimeo' => 'https://vimeo.com/',
        ];

        if (array_key_exists($storageType, $externalUrlBaseMap)) {
            $link = $externalUrlBaseMap[$storageType] . $url;
        } else {
            $link = '/src/Frontend/Files/MediaLibrary/' . $shardingFolderName . '/' . $url;
        }

        $html = '<a href="' . $link . '" target="_blank" class="btn btn-default btn-xs pull-right">';
        $html .= '<span class="fa fa-eye"></span>' . ucfirst(Language::lbl('View'));
        $html .= '</a>';

        return $html;
    }

```

To fully address the concern about hard-coded storage type strings, you should:
1. Replace the `'youtube'` and `'vimeo'` keys in `$externalUrlBaseMap` with the appropriate enum/constant values already used in the MediaLibrary domain (for example, something like `MediaItem::STORAGE_TYPE_YOUTUBE` / `MediaItem::STORAGE_TYPE_VIMEO` or a dedicated `StorageType` enum).
2. Import that enum/constant provider at the top of this file with a `use` statement if needed.
3. Optionally, extract `$externalUrlBaseMap` into a dedicated constant or method so that storage type → URL mappings are defined in a single, reusable place.
</issue_to_address>

### Comment 2
<location path="src/Backend/Modules/MediaLibrary/Domain/MediaItem/MediaItemDataGrid.php" line_range="225-231" />
<code_context>
+            $link = 'https://youtube.com/watch?v=' . $url;
+        } elseif ($storageType === 'vimeo') {
+            $link = 'https://www.vimeo.com/' . $url;
+        } else {
+            $link = '/src/Frontend/Files/MediaLibrary/' . $shardingFolderName . '/' . $url;
+        }
+
</code_context>
<issue_to_address>
**suggestion:** Consider using a generated/public-facing URL instead of a hard-coded path into `src/Frontend`.

Hard-coding `/src/Frontend/Files/MediaLibrary/` couples this link to the current directory structure and will likely break if the public path or deployment layout changes. Prefer using an existing helper/config value to build media URLs (or adding one if missing) instead of embedding the path directly.

```suggestion
        if ($storageType === 'youtube') {
            $link = 'https://youtube.com/watch?v=' . $url;
        } elseif ($storageType === 'vimeo') {
            $link = 'https://www.vimeo.com/' . $url;
        } else {
            $link = FRONTEND_FILES_URL . '/MediaLibrary/' . $shardingFolderName . '/' . $url;
        }
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +223 to +227
public static function getDetailUrl(string $shardingFolderName, string $url, string $storageType): string
{
if ($storageType === 'youtube') {
$link = 'https://youtube.com/watch?v=' . $url;
} elseif ($storageType === 'vimeo') {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion: Avoid hard-coded storage type strings and normalise external URLs.

Using raw strings like 'youtube' and 'vimeo' for storageType makes this fragile to typos and harder to change later; if there’s an existing enum/constant set for storage types, please reuse it here. Also, consider normalising the generated URLs to the conventional forms https://www.youtube.com/watch?v=... and https://vimeo.com/... rather than mixing domains/subdomains.

Suggested implementation:

    public static function getDetailUrl(string $shardingFolderName, string $url, string $storageType): string
    {
        // map known storage types to their canonical external URL bases
        $externalUrlBaseMap = [
            'youtube' => 'https://www.youtube.com/watch?v=',
            'vimeo' => 'https://vimeo.com/',
        ];

        if (array_key_exists($storageType, $externalUrlBaseMap)) {
            $link = $externalUrlBaseMap[$storageType] . $url;
        } else {
            $link = '/src/Frontend/Files/MediaLibrary/' . $shardingFolderName . '/' . $url;
        }

        $html = '<a href="' . $link . '" target="_blank" class="btn btn-default btn-xs pull-right">';
        $html .= '<span class="fa fa-eye"></span>' . ucfirst(Language::lbl('View'));
        $html .= '</a>';

        return $html;
    }

To fully address the concern about hard-coded storage type strings, you should:

  1. Replace the 'youtube' and 'vimeo' keys in $externalUrlBaseMap with the appropriate enum/constant values already used in the MediaLibrary domain (for example, something like MediaItem::STORAGE_TYPE_YOUTUBE / MediaItem::STORAGE_TYPE_VIMEO or a dedicated StorageType enum).
  2. Import that enum/constant provider at the top of this file with a use statement if needed.
  3. Optionally, extract $externalUrlBaseMap into a dedicated constant or method so that storage type → URL mappings are defined in a single, reusable place.

Comment on lines +225 to +231
if ($storageType === 'youtube') {
$link = 'https://youtube.com/watch?v=' . $url;
} elseif ($storageType === 'vimeo') {
$link = 'https://www.vimeo.com/' . $url;
} else {
$link = '/src/Frontend/Files/MediaLibrary/' . $shardingFolderName . '/' . $url;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion: Consider using a generated/public-facing URL instead of a hard-coded path into src/Frontend.

Hard-coding /src/Frontend/Files/MediaLibrary/ couples this link to the current directory structure and will likely break if the public path or deployment layout changes. Prefer using an existing helper/config value to build media URLs (or adding one if missing) instead of embedding the path directly.

Suggested change
if ($storageType === 'youtube') {
$link = 'https://youtube.com/watch?v=' . $url;
} elseif ($storageType === 'vimeo') {
$link = 'https://www.vimeo.com/' . $url;
} else {
$link = '/src/Frontend/Files/MediaLibrary/' . $shardingFolderName . '/' . $url;
}
if ($storageType === 'youtube') {
$link = 'https://youtube.com/watch?v=' . $url;
} elseif ($storageType === 'vimeo') {
$link = 'https://www.vimeo.com/' . $url;
} else {
$link = FRONTEND_FILES_URL . '/MediaLibrary/' . $shardingFolderName . '/' . $url;
}

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant