Skip to content

Commit

Permalink
HSD8-1416 Media usage page with links to the the parent content. (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
pookmish authored Oct 2, 2023
1 parent 2c748a6 commit a349984
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 195 deletions.
158 changes: 158 additions & 0 deletions src/Controller/MediaUsageController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php

namespace Drupal\stanford_media\Controller;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\entity_usage\EntityUsageInterface;
use Drupal\media\MediaInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MediaUsageController extends ControllerBase {

/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_usage.usage')
);
}

/**
* Controller constructor.
*
* @param \Drupal\entity_usage\EntityUsageInterface $entityUsage
* Entity usage service.
*/
public function __construct(protected EntityUsageInterface $entityUsage) {}

/**
* @param \Drupal\media\MediaInterface $media
* Media entity.
*
* @return \Drupal\Core\StringTranslation\TranslatableMarkup
* Page title.
*/
public function title(MediaInterface $media) {
return $this->t('Media Usage: @title', ['@title' => $media->label()]);
}

/**
* Controller table display to show the list of entities using a media item.
*
* @param \Drupal\media\MediaInterface $media
* Media entity.
*
* @return array
* Render array.
*/
public function view(MediaInterface $media) {
// Create a table to display a link to each of the sources from the entity usage.
$build = [
'#theme' => 'table',
'#header' => [
$this->t('Title'),
$this->t('Operations'),
],
'#rows' => [],
];
// Cache exists, use that.
$cache = $this->cache()->get('stanford_media:media_usage:' . $media->id());
if ($cache) {
$build['#rows'] = $cache->data;
return $build;
}

$cache_tags = ['media_usage:media:' . $media->id()];

foreach ($this->getParentEntityUses($media) as $parent_entity) {
$row = [];
$row['title']['data'] = [
'#type' => 'link',
'#title' => $parent_entity->label(),
'#url' => $parent_entity->toUrl(),
];
$row['operations']['data'] = [
'#type' => 'operations',
'#links' => $this->getOperationLinks($parent_entity),
];
$build['#rows'][] = $row;
}
$this->cache()
->set('stanford_media:media_usage:' . $media->id(), $build['#rows'], CacheBackendInterface::CACHE_PERMANENT, $cache_tags);

return $build;
}

protected function getOperationLinks(EntityInterface $entity) {
$links = [];
if ($entity->hasLinkTemplate('canonical') && $entity->access('view')) {
$links['view'] = [
'title' => $this->t('View'),
'url' => $entity->toUrl(),
];
}

if ($entity->hasLinkTemplate('edit-form') && $entity->access('update')) {
$links['edit'] = [
'title' => $this->t('Edit'),
'url' => $entity->toUrl('edit-form'),
];
}
return $links;
}

/**
* Get the parent entity of a media item.
*
* @param \Drupal\media\MediaInterface $media
* Media entity.
*
* @return \Drupal\Core\Entity\EntityInterface[]
* Array of parent entities.
*/
protected function getParentEntityUses(MediaInterface $media) {
$sources = $this->entityUsage->listSources($media);
$deduped = [];
$parent_entities = [];

/// Loop through the sources and create a link to the entity.
foreach ($sources as $entity_type => $entity_ids) {
$entities = $this->entityTypeManager()
->getStorage($entity_type)
->loadMultiple(array_keys($entity_ids));

foreach ($entities as $entity) {
$parent_entity = $this->getParentEntity($entity);

// Check if we've loaded this entity already.
if (!$parent_entity || isset($deduped[$parent_entity->id()])) {
continue;
}

$deduped[$parent_entity->id()] = TRUE;
$parent_entities[] = $parent_entity;
}
}
return $parent_entities;
}

/**
* Get the parent entity of an entity like a paragraph.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* Entity object.
*
* @return \Drupal\Core\Entity\EntityInterface[]
* Parent entity, or the original entity if it has no parent.
*/
protected function getParentEntity(EntityInterface $entity) {
if (method_exists($entity, 'getParentEntity') && $entity->getParentEntity()) {
return $this->getParentEntity($entity->getParentEntity());
}
return $entity->hasLinkTemplate('canonical') ? $entity : NULL;
}

}
45 changes: 45 additions & 0 deletions src/EventSubscriber/StanfordMediaSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Drupal\stanford_media\EventSubscriber;

use Drupal\Core\Cache\Cache;
use Drupal\entity_usage\Events\EntityUsageEvent;
use Drupal\entity_usage\Events\Events;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* Stanford Media event subscriber.
*/
class StanfordMediaSubscriber implements EventSubscriberInterface {

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
Events::USAGE_REGISTER => 'onRegisterEntityUsage',
Events::DELETE_BY_SOURCE_ENTITY => 'onRegisterEntityUsage',
Events::DELETE_BY_TARGET_ENTITY => 'onRegisterEntityUsage',
];
}

/**
* Invalidate the media usage cache tag when a media entity is used.
*
* @param \Drupal\entity_usage\Events\EntityUsageEvent $event
* The entity usage event.
*/
public function onRegisterEntityUsage(EntityUsageEvent $event) {
if ($event->getTargetEntityId() && $event->getTargetEntityType() == 'media') {
Cache::invalidateTags(["media_usage:media:{$event->getTargetEntityId()}"]);
}

$source_type = $event->getSourceEntityType();
$source_id = $event->getSourceEntityId();

if ($source_type && $source_id) {
Cache::invalidateTags(["media_usage:$source_type:$source_id"]);
}
}

}
96 changes: 0 additions & 96 deletions src/Plugin/views/field/EntityUsageLink.php

This file was deleted.

10 changes: 10 additions & 0 deletions stanford_media.links.task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Media usage local task.
entity.media.usage:
route_name: entity.media.usage
title: 'Usage'
base_route: entity.media.canonical
weight: 10
options:
parameters:
media:
type: entity:media
26 changes: 26 additions & 0 deletions stanford_media.module
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,32 @@ use Drupal\stanford_media\Form\MediaLibraryEmbeddableForm;
use Drupal\stanford_media\Form\MediaLibraryFileUploadForm;
use Drupal\stanford_media\Form\MediaLibraryGoogleFormForm;

/**
* Implements hook_entity_type_alter().
*/
function stanford_media_entity_type_alter(array &$entity_types) {
// Add route for media entity type to view the usage details.
$entity_types['media']->setLinkTemplate('usage', '/media/{media}/usage');
}

/**
* Implements hook_entity_operation_alter().
*/
/**
* Implements hook_entity_operation().
*/
function stanford_media_entity_operation(EntityInterface $entity) {
$operations = [];
if ($entity->getEntityTypeId() == 'media' && $entity->access('update')) {
$operations['usage'] = [
'title' => t('Usage'),
'weight' => 100,
'url' => $entity->toUrl('usage'),
];
}
return $operations;
}

/**
* Implements hook_ENTITY_TYPE_delete().
*/
Expand Down
15 changes: 15 additions & 0 deletions stanford_media.routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,18 @@ stanford_media.bulk_upload:
_custom_access: '\Drupal\stanford_media\Form\BulkUpload::access'
options:
_admin_route: TRUE

# Media entity usage route.
entity.media.usage:
path: '/media/{media}/usage'
defaults:
_controller: '\Drupal\stanford_media\Controller\MediaUsageController::view'
_title_callback: '\Drupal\stanford_media\Controller\MediaUsageController::title'
options:
_admin_route: TRUE
parameters:
media:
type: entity:media
requirements:
_entity_access: 'media.update'
media: \d+
5 changes: 5 additions & 0 deletions stanford_media.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ services:
plugin.manager.embed_validator_plugin_manager:
class: Drupal\stanford_media\Plugin\EmbedValidatorPluginManager
parent: default_plugin_manager

stanford_media.event_subscriber:
class: Drupal\stanford_media\EventSubscriber\StanfordMediaSubscriber
tags:
- { name: event_subscriber }
Loading

0 comments on commit a349984

Please sign in to comment.