acquia_dam-1.0.0-rc1/modules/acquia_dam_integration_links/src/AssetDetector/MediaReferenceAssetDetector.php
modules/acquia_dam_integration_links/src/AssetDetector/MediaReferenceAssetDetector.php
<?php namespace Drupal\acquia_dam_integration_links\AssetDetector; use Drupal\acquia_dam\Plugin\media\Source\Asset; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\media\MediaInterface; /** * Detects DAM asset usage in media reference fields. */ final class MediaReferenceAssetDetector extends AssetDetectorBase { /** * List of field types supported by this detector. * * @var string[] */ protected $supportedFieldTypes = [ 'entity_reference', ]; /** * {@inheritdoc} */ public function discoverAsset(ContentEntityInterface $entity, array $field_definitions, bool $is_title_changed): array { $supported_fields = $this->filterSupportedFields($field_definitions, $this->supportedFieldTypes); // If there are no relevant updates we still need the current value, to make // sure that we do not delete an integration link for the given entity if a // referenced asset is removed from another field type. $has_relevant_updates = $this->hasRelevantUpdates($supported_fields, $entity); $old_asset_ids = []; $new_asset_ids = []; // Cannot filter the field by update status. If entity has more than one // field which supports DAM asset reference, then we must make sure that // removing a reference on update does not remove the integration link from // the API if the other field still has the asset. If we filter by relevant // update then we could remove integration link from a non-updated field // which is still needed. foreach ($supported_fields as $field) { // Not able to check isNew() since at this point entity is saved. if (isset($entity->original) && $has_relevant_updates) { // Media entities referenced before update. $old_referenced_entities = $entity->original->get($field->getName())->referencedEntities(); $old_asset_ids = array_merge($old_asset_ids, $this->getAssetIds($old_referenced_entities)); } // Media entities referenced after update. $new_referenced_entities = $entity->get($field->getName())->referencedEntities(); $new_asset_ids = array_merge($new_asset_ids, $this->getAssetIds($new_referenced_entities)); } // It can have duplicates, asset tracker will take care of those. return [ 'asset_to_register' => $new_asset_ids, 'assets_to_remove' => $old_asset_ids, ]; } /** * Returns asset ids of given Media entities. * * @param \Drupal\media\MediaInterface[] $media_entities * Media entity array. * * @return array * Referenced DAM asset ids. */ protected function getAssetIds(array $media_entities): array { // Array filter to work with only media entities from proper source. $media_entities = array_filter( $media_entities, static function (MediaInterface $media) { return $media->getSource() instanceof Asset; }); return array_map( static function (MediaInterface $media) { return $media->get('acquia_dam_asset_id')->asset_id; }, $media_entities ); } /** * {@inheritdoc} */ protected function filterSupportedFields(array $field_definitions, array $supported_field_types): array { $supported_fields = []; foreach (parent::filterSupportedFields($field_definitions, $supported_field_types) as $field) { $storage = $field->getFieldStorageDefinition(); $settings = $storage->getSettings(); if (!isset($settings['target_type']) || $settings['target_type'] !== 'media') { continue; } $supported_fields[] = $field; } return $supported_fields; } }