media_acquiadam-8.x-1.46/src/Traits/MigrationTrait.php
src/Traits/MigrationTrait.php
<?php
namespace Drupal\media_acquiadam\Traits;
use Drupal\acquia_dam\Entity\BundleFieldDefinition;
use Drupal\acquia_dam\Entity\ManagedFileField;
use Drupal\acquia_dam\Entity\ManagedImageField;
use Drupal\acquia_dam\Entity\MediaSourceField;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\Core\State\StateInterface;
use Drupal\media_acquiadam\Form\AcquiadamMigration;
/**
* The migration trait definition.
*/
trait MigrationTrait {
/**
* Drupal entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Drupal config service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The Logger Factory Service.
*
* @var \Drupal\Core\Logger\LoggerChannelInterface
*/
protected $logger;
/**
* The database connection to use.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* The media source plugin manager service.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
*/
protected $mediaSourcePluginManager;
/**
* The Drupal State Service.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* Helper function to get the list of media types to be deleted.
*
* @param array $stored_values
* The array with legacy and modern media type mapping info.
*
* @return array
* The array of media types to be deleted as part of the migration.
*/
protected static function getMediaTypeDeletionList(array $stored_values): array {
$bundle_to_delete = [];
// Combine modern and legacy DAM media types.
$all_media_types = array_merge(
$stored_values['modern_dam_media_types'],
$stored_values['legacy_dam_media_types']
);
// Iterate over all media to build deletion list.
foreach ($all_media_types as $value) {
if (isset($value['delete'])) {
if ($value['delete']) {
$bundle_to_delete[$value['media_type_id']] = $value['media_type_label'];
}
}
else {
if (!isset($value['target_source_type'])) {
$bundle_to_delete[$value['media_type_id']] = $value['media_type_label'];
}
}
}
return $bundle_to_delete;
}
/**
* Get update list of media types.
*
* @param array $stored_values
* @return array
*/
protected function getMediaTypeUpdateList(array $stored_values): array {
$bundle_to_update = [];
// Combine modern and legacy DAM media types from stored value.
$all_media_types = array_merge(
$stored_values['modern_dam_media_types'],
$stored_values['legacy_dam_media_types']
);
// Combine modern and legacy DAM media types from original value.
$all_media_types_original = array_merge(
$this->getMediaTypesBySourceField(MediaSourceField::SOURCE_FIELD_NAME),
$this->getMediaTypesBySourceField('field_acquiadam_asset_id')
);
// Iterate over all media to build deletion list.
foreach ($all_media_types as $value) {
$media = $all_media_types_original[$value['media_type_id']];
$is_deleted = $value['delete'] ?? 0;
if (!$is_deleted && $value['media_type_label'] != $media->label()) {
$bundle_to_update[$value['media_type_id']] = [
'old_media_label' => $media->label(),
'new_media_label' => $value['media_type_label'],
];
}
}
return $bundle_to_update;
}
/**
* Retrieves media counts for the given bundle IDs.
*
* @param array $bundle_ids
* The bundle IDs to get counts for.
*
* @return array
* An array of media counts keyed by bundle ID.
*/
protected function getMediaCounts(array $bundle_ids): array {
$media_counts = [];
if (!empty($bundle_ids)) {
try {
$query = $this->getDatabase()->select('media_field_data', 'm');
$query->addField('m', 'bundle');
$query->addExpression('COUNT(m.mid)', 'media_count');
$query->condition('m.bundle', $bundle_ids, 'IN');
$query->condition('m.status', 1);
$query->groupBy('m.bundle');
$query->orderBy('media_count', 'DESC');
$media_counts = $query->execute()->fetchAllKeyed();
}
catch (\Exception $e) {
$this->logger->error('Failed to load media counts: @message', ['@message' => $e->getMessage()]);
}
}
return $media_counts;
}
/**
* Process the stored values to get it in the form of array as key value pair.
*
* @param array $stored_values
* The array values.
*
* @return array
* An array values.
*/
protected function processStoredValues(array $stored_values): array {
$processed_stored_values = [];
if (isset($stored_values['legacy_dam_media_types'])) {
foreach ($stored_values['legacy_dam_media_types'] as $value) {
if (isset($value['media_type_id'])) {
$processed_stored_values[$value['media_type_id']] = $value;
}
}
$stored_values['legacy_dam_media_types'] = $processed_stored_values;
}
return $stored_values;
}
/**
* Retrieves legacy DAM media types.
*
* @return array
* An array of legacy DAM media types.
*/
protected function getLegacyDamMediaTypes(): array {
$media_types = $this->getMediaTypesBySourceField('field_acquiadam_asset_id');
$media_counts = $this->getMediaCounts(array_keys($media_types));
// Find media types that have no media items and set their count to 0.
$missing_media_types = array_diff_key($media_types, $media_counts);
$default_counts = array_fill_keys(array_keys($missing_media_types), "0");
// Combine the counts of media items with the default counts.
$combined_counts = $media_counts + $default_counts;
// Map the media types to an array with detailed information.
$legacy_dam_media_types = [];
foreach (array_keys($combined_counts) as $bundle_id) {
$legacy_dam_media_types[$bundle_id] = [
'machine_name' => $bundle_id,
'label' => $media_types[$bundle_id]->label(),
'count' => $combined_counts[$bundle_id],
'method' => 'sync',
'supported_extensions' => $this->getFileExtensions($bundle_id),
];
}
return $legacy_dam_media_types;
}
/**
* Retrieves modern DAM media types.
*
* @return array
* An array of modern DAM media types.
*/
protected function getModernDamMediaTypes(): array {
// Retrieve all media types with the specified source field.
$media_types = $this->getMediaTypesBySourceField(MediaSourceField::SOURCE_FIELD_NAME);
return array_map(function ($bundle_id) use ($media_types) {
return [
'machine_name' => $bundle_id,
'label' => $media_types[$bundle_id]->label(),
'supported_extensions' => $this->getFileExtensions($bundle_id, FALSE),
'source' => $media_types[$bundle_id]->get('source'),
];
}, array_keys($media_types));
}
/**
* Retrieves media types by source field.
*
* @param string $source_field
* The source field to filter media types.
*
* @return array
* An array of media types.
*/
protected function getMediaTypesBySourceField(string $source_field): array {
return $this->getEntityTypeManager()->getStorage('media_type')
->loadByProperties(['source_configuration.source_field' => $source_field]);
}
/**
* Retrieves file extensions for a given media bundle.
*
* @param string $mediaBundle
* The media bundle machine name.
* @param bool $legacyDam
* Whether to use legacy DAM logic.
*
* @return array
* An array of file extensions.
*/
protected function getFileExtensions(string $mediaBundle, bool $legacyDam = TRUE): array {
$fieldDefinitions = $this->getEntityFieldManager()->getFieldDefinitions('media', $mediaBundle);
return $legacyDam
? $this->getLegacyDamFileExtensions($fieldDefinitions, $mediaBundle)
: $this->getModernDamFileExtensions($fieldDefinitions);
}
/**
* Retrieves file extensions for legacy DAM.
*
* @param array $fieldDefinitions
* The field definitions for the media bundle.
* @param string $media_bundle
* The media bundle machine name.
*
* @return array
* An array of file extensions.
*/
protected function getLegacyDamFileExtensions(array $fieldDefinitions, string $media_bundle): array {
$fileExtensions = [];
$fieldToCheck = ($media_bundle == "acquia_dam_image") ? 'image' : 'file';
foreach ($fieldDefinitions as $definition) {
if ($definition->getType() === $fieldToCheck) {
$settings = $definition->getSettings();
if (!empty($settings['file_extensions'])) {
$fileExtensions = explode(' ', $settings['file_extensions']);
break;
}
}
}
return $fileExtensions;
}
/**
* Retrieves media types that support the given extensions.
*
* @param array $media_types
* The array of media types.
* @param array $extensions
* The array of extensions to filter by.
*
* @return array
* An array of media types that support the given extensions.
*/
protected function getMediaTypesSupportingExtensions(array $media_types, array $extensions): array {
return array_filter($media_types, function ($media_type) use ($extensions) {
return !empty(array_intersect($media_type['supported_extensions'], $extensions));
});
}
/**
* Get media options.
*/
protected function getMediaOptions(array $media_types): array {
return array_combine(
array_column($media_types, 'source'),
array_column($media_types, 'label')
);
}
/**
* Retrieves file extensions for modern DAM.
*
* @param array $fieldDefinitions
* The field definitions for the media bundle.
*
* @return array
* An array of file extensions.
*/
protected function getModernDamFileExtensions(array $fieldDefinitions): array {
$fileExtensions = [];
$fieldDefinition = $fieldDefinitions[ManagedImageField::MANAGED_IMAGE_FIELD_NAME] ?? $fieldDefinitions[ManagedFileField::MANAGED_FILE_FIELD_NAME];
if ($fieldDefinition instanceof BundleFieldDefinition) {
$fileExtensions = explode(" ", $fieldDefinition->getSetting("file_extensions"));
}
return $fileExtensions;
}
/**
* Get migration config for DAM.
*
* @return array
* An array of config data.
*/
protected function getMigrationConfig(): array {
return $this->getConfigFactory()->get(AcquiadamMigration::MODULE_SETTINGS_NAME)->get('stored_values') ?? [];
}
/**
* Gets the entity type manager service.
*
* @return \Drupal\Core\Entity\EntityTypeManagerInterface
* The config factory service.
*/
protected function getEntityTypeManager(): EntityTypeManagerInterface {
if (!$this->entityTypeManager) {
$this->entityTypeManager = \Drupal::service('entity_type.manager');
}
return $this->entityTypeManager;
}
/**
* Gets the config factory service.
*
* @return \Drupal\Core\Config\ConfigFactoryInterface
* The config factory service.
*/
protected function getConfigFactory(): ConfigFactoryInterface {
if (!$this->configFactory) {
$this->configFactory = \Drupal::service('config.factory');
}
return $this->configFactory;
}
/**
* Gets the logger factory service.
*
* @return \Drupal\Core\Logger\LoggerChannelInterface
* The config factory service.
*/
protected function getLoggerFactory(): LoggerChannelInterface {
if (!$this->logger) {
$this->logger = \Drupal::service('logger.factory');
}
return $this->logger;
}
/**
* Gets the database service.
*
* @return \Drupal\Core\Database\Connection
* The config factory service.
*/
protected function getDatabase(): Connection {
if (!$this->database) {
$this->database = \Drupal::service('database');
}
return $this->database;
}
/**
* Gets the entity field manager service.
*
* @return \Drupal\Core\Entity\EntityFieldManagerInterface
* The config factory service.
*/
protected function getEntityFieldManager(): EntityFieldManagerInterface {
if (!$this->entityFieldManager) {
$this->entityFieldManager = \Drupal::service('entity_field.manager');
}
return $this->entityFieldManager;
}
/**
* Gets the media source plugin manager service.
*
* @return \Drupal\Component\Plugin\PluginManagerInterface
* The media source plugin manager service.
*/
protected function getMediaSourcePluginManager(): PluginManagerInterface {
if (!$this->mediaSourcePluginManager) {
$this->mediaSourcePluginManager = \Drupal::service('plugin.manager.media.source');
}
return $this->mediaSourcePluginManager;
}
/**
* Gets the state service.
*
* @return \Drupal\Core\State\StateInterface
* The state service.
*/
protected function getState(): StateInterface {
if (!$this->state) {
$this->state = \Drupal::service('state');
}
return $this->state;
}
/**
* Get media source plugin options.
*
* @param array $media_types
* The media types.
*
* @return array
* An array of media source plugin options.
*/
protected function getMediaSourcePlugin(array $media_types): array {
// Get the acquia dam media source plugins.
$plugins = $this->getAcquiaDamPlugin();
$options = [];
// Filter the media types to include only those
// that are available in the plugin.
foreach ($media_types as $key => $value) {
if (isset($plugins[$key])) {
$options[$key] = (string) $plugins[$key]['label'];
}
}
return $options;
}
/**
* Get the Acquia DAM plugin.
*
* @return array
* An array of Acquia DAM plugin definitions.
*/
protected function getAcquiaDamPlugin(): array {
$plugin = $this->getMediaSourcePluginManager()->getDefinitions();
return array_filter($plugin, function ($plugin) {
return $plugin['provider'] === 'acquia_dam';
});
}
protected function getAcquiaDamPluginAsOptions() {
$plugin = $this->getAcquiaDamPlugin();
$options = [];
foreach ($plugin as $key => $value) {
if ($value['provider'] === 'acquia_dam') {
$options[$key] = (string) $value['label'];
}
}
return $options;
}
}
