acquia_dam-1.0.0-rc1/acquia_dam.install
acquia_dam.install
<?php
/**
* @file
* Install, update and uninstall functions for the Acquia DAM module.
*/
declare(strict_types=1);
use Drupal\acquia_dam\Entity\ImageAltTextField;
use Drupal\acquia_dam\Entity\MediaExpiryDateField;
use Drupal\acquia_dam\Entity\MediaSourceField;
use Drupal\acquia_dam\FormatAllowedHtmlModifier;
use Drupal\acquia_dam\Plugin\media\Source\Asset;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Database\Database;
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
use Drupal\Core\Entity\Sql\SqlContentEntityStorageException;
use Drupal\Core\Url;
use Drupal\filter\Entity\FilterFormat;
use Drupal\media\MediaTypeInterface;
/**
* Implements hook_schema().
*/
function acquia_dam_schema() {
$schema = [];
$schema['acquia_dam_integration_link_tracking'] = [
'description' => 'Table for tracking DAM integration link IDs.',
'fields' => [
'entity_uuid' => [
'type' => 'char',
'description' => 'Parent entity UUID.',
'length' => 36,
'not null' => TRUE,
'default' => '',
],
'entity_type' => [
'type' => 'varchar',
'description' => 'Parent entity type.',
'default' => '',
'not null' => FALSE,
'length' => 36,
],
'asset_uuid' => [
'type' => 'char',
'description' => 'Asset UUID.',
'length' => 36,
'not null' => TRUE,
'default' => '',
],
'integration_link_id' => [
'type' => 'varchar',
'description' => 'Integration link UUID generated by DAM.',
'default' => '',
'not null' => TRUE,
'length' => 36,
],
'path' => [
'type' => 'varchar',
'description' => 'The path for the integration link.',
'default' => '',
'not null' => TRUE,
'length' => 255,
],
'created' => [
'type' => 'varchar',
'description' => "The integration created.",
'default' => '',
'not null' => TRUE,
'length' => 36,
],
],
'primary key' => ['integration_link_id'],
'indexes' => [
'entity' => ['entity_uuid', 'integration_link_id'],
],
'unique keys' => [
'integration_link_id' => ['integration_link_id'],
'entity_uuid_entity_type_asset_uuid' => [
'entity_uuid',
'entity_type',
'asset_uuid',
],
],
];
$schema['acquia_dam_integration_link_aggregate'] = [
'fields' => [
'asset_uuid' => [
'type' => 'char',
'description' => 'Asset UUID.',
'length' => 36,
'not null' => TRUE,
'default' => '',
],
'usage_count' => [
'type' => 'int',
'not null' => TRUE,
'default' => 0,
],
],
'primary key' => ['asset_uuid'],
];
return $schema;
}
/**
* Implements hook_install().
*/
function acquia_dam_install($is_syncing) {
$state = \Drupal::state();
$state->set('acquia_dam.last_update_check', \Drupal::time()->getCurrentTime());
if (!$is_syncing) {
\Drupal::messenger()->addStatus(t('The Acquia DAM module has been installed. You need to <a href=":link">configure the module</a> for others to make use of it.', [':link' => Url::fromRoute('acquia_dam.config')->toString()]));
foreach (FilterFormat::loadMultiple() as $filter_format) {
\Drupal::classResolver()
->getInstanceFromDefinition(FormatAllowedHtmlModifier::class)
->process($filter_format);
$filter_format->save();
}
}
$module_handler = \Drupal::service('module_handler');
$config_factory = \Drupal::configFactory();
if (!$module_handler->moduleExists('media_acquiadam')) {
return;
}
// Zeroing in on the schema data check of the domain key as it contain
// only in the 2.x version.
$media_acquidam_config = \Drupal::service('config.typed')->getDefinition('media_acquiadam.settings');
if (array_key_exists('domain', $media_acquidam_config['mapping'])) {
$media_acquiadam_settings = $config_factory->get('media_acquiadam.settings');
$acquia_dam_settings = $config_factory->getEditable('acquia_dam.settings');
// Setting the domain.
$domain_url = $media_acquiadam_settings->get('domain');
$acquia_dam_settings->set('domain', $domain_url);
$acquia_dam_settings->save();
// Pushing token into the state.
$token = $media_acquiadam_settings->get('token');
$state->set('acquia_dam_token', $token);
// Handling the user data.
$user_data = \Drupal::service('user.data');
$auth_service = \Drupal::service('acquia_dam.authentication_service');
$user_ids = \Drupal::entityQuery('user')->accessCheck(FALSE)->execute();
foreach ($user_ids as $user_id) {
$account = $user_data->get('media_acquiadam', $user_id, 'account');
if (isset($account['acquiadam_username']) && isset($account['acquiadam_token'])) {
$auth_service->setUserData(
(int) $user_id,
[
'acquia_dam_username' => $account['acquiadam_username'],
'acquia_dam_token' => $account['acquiadam_token'],
]
);
}
}
}
}
/**
* Implements hook_uninstall().
*/
function acquia_dam_uninstall() {
$keys_to_delete = [
'acquia_dam_token',
'acquia_dam_username',
'acquia_dam.last_update_check',
'acquia_dam_refresh_token',
];
$state = \Drupal::state();
foreach ($keys_to_delete as $key) {
if ($state->get($key)) {
$state->delete($key);
}
}
}
/**
* Imports configuration changes since RC1.
*/
function acquia_dam_update_9001() {
$configuration_map = [
'media_type' => [
'media.type.acquia_dam_image_asset',
'media.type.acquia_dam_spinset_asset',
'media.type.acquia_dam_documents_asset',
],
'entity_view_display' => [
'core.entity_view_display.media.acquia_dam_image_asset.default',
'core.entity_view_display.media.acquia_dam_image_asset.media_library',
'core.entity_view_display.media.acquia_dam_spinset_asset.default',
'core.entity_view_display.media.acquia_dam_spinset_asset.media_library',
'core.entity_view_display.media.acquia_dam_documents_asset.default',
'core.entity_view_display.media.acquia_dam_documents_asset.media_library',
],
];
$source = new FileStorage(__DIR__ . '/config/install');
foreach ($configuration_map as $config_type => $configs) {
$entity_storage = \Drupal::entityTypeManager()->getStorage($config_type);
foreach ($configs as $config) {
$entity = $entity_storage->createFromStorageRecord($source->read($config));
$entity->save();
}
}
}
/**
* Update config schema for settings and set last update check in state storage.
*/
function acquia_dam_update_9002() {
$config_factory = \Drupal::configFactory();
$config = $config_factory->getEditable('acquia_dam.settings');
$config->set('allowed_image_styles', []);
$config->save(TRUE);
$state = \Drupal::state();
$state->set('acquia_dam.last_update_check', \Drupal::time()->getCurrentTime());
}
/**
* Update database schema and configuration.
*/
function acquia_dam_update_9003() {
_acquia_dam_add_dam_content_views();
$config = [
'fields' => [
'asset_uuid' => [
'type' => 'char',
'description' => 'Asset UUID.',
'length' => 36,
'not null' => TRUE,
'default' => '',
],
'usage_count' => [
'type' => 'int',
'not null' => TRUE,
'default' => 0,
],
],
'primary key' => ['asset_uuid'],
];
$schema = Database::getConnection()->schema();
$schema->createTable('acquia_dam_integration_link_aggregate', $config);
_acquia_dam_populate_integration_link_aggregate_table();
}
/**
* Imports configuration changes.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
function _acquia_dam_add_dam_content_views() {
$configuration_map = [
'views.view.dam_content_overview',
'views.view.acquia_dam_links',
];
$source = new FileStorage(__DIR__ . '/config/install');
$entity_storage = \Drupal::entityTypeManager()->getStorage('view');
foreach ($configuration_map as $config) {
$entity = $entity_storage->createFromStorageRecord($source->read($config));
$entity->save();
}
}
/**
* Updates asset library configuration.
*/
function acquia_dam_update_9004() {
$configs = [
'acquia_dam_asset_library' => 'views.view.acquia_dam_asset_library',
'dam_content_overview' => 'views.view.dam_content_overview',
];
$source = new FileStorage(__DIR__ . '/config/install');
$entity_storage = \Drupal::entityTypeManager()->getStorage('view');
$view_configs = $entity_storage->loadMultiple(array_keys($configs));
foreach ($view_configs as $view_config) {
$entity = $entity_storage
->updateFromStorageRecord(
$view_config,
$source->read($configs[$view_config->id()])
);
$entity->save();
}
$field_storage_definition = MediaExpiryDateField::getStorageDefinition('media');
$update_manager = \Drupal::entityDefinitionUpdateManager();
$update_manager->installFieldStorageDefinition(
MediaExpiryDateField::EXPIRY_DATE_FIELD_NAME,
'media',
'acquia_dam',
$field_storage_definition
);
}
/**
* Install field storage for image alt text field.
*/
function acquia_dam_update_9005() {
$field_storage_definition = ImageAltTextField::getStorageDefinition('media');
$update_manager = \Drupal::entityDefinitionUpdateManager();
$update_manager->installFieldStorageDefinition(
ImageAltTextField::IMAGE_ALT_TEXT_FIELD_NAME,
'media',
'acquia_dam',
$field_storage_definition
);
}
/**
* Uninstalls the acquia_dam_embeds field from the media entity.
*/
function acquia_dam_update_9006() {
$entity_definition_update = \Drupal::entityDefinitionUpdateManager();
if ($storage_definition = $entity_definition_update->getFieldStorageDefinition('acquia_dam_embeds', 'media')) {
$entity_definition_update->uninstallFieldStorageDefinition($storage_definition);
}
}
/**
* Add the external_id column to the acquia_dam_asset media field.
*/
function acquia_dam_update_9007() {
$processed_fields = [];
$columns_to_add = ['external_id'];
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
$asset_field_definition = $field_type_manager->getDefinition('acquia_dam_asset');
/** @var \Drupal\acquia_dam\Plugin\Field\FieldType\AssetItem $asset_item_class */
$asset_item_class = $asset_field_definition['class'];
$schema = \Drupal::database()->schema();
$entity_type_manager = \Drupal::entityTypeManager();
$entity_field_manager = \Drupal::service('entity_field.manager');
// We can't use $entity_field_manager->getFieldMapByFieldType()
// since it won't display the fields that are added via the
// hook_entity_field_storage_info().
$entity_field_map = [
'media' => [
MediaSourceField::SOURCE_FIELD_NAME => [
'type' => "acquia_dam_asset",
'bundles' => [
'acquia_dam_documents_asset' => 'acquia_dam_documents_asset',
'acquia_dam_image_asset' => 'acquia_dam_image_asset',
'acquia_dam_pdf_asset' => 'acquia_dam_pdf_asset',
'acquia_dam_spinset_asset' => 'acquia_dam_spinset_asset',
'acquia_dam_video_asset' => 'acquia_dam_video_asset',
],
],
],
];
// The key-value collection for tracking installed storage schema.
$entity_storage_schema_sql = \Drupal::keyValue('entity.storage_schema.sql');
$entity_definitions_installed = \Drupal::keyValue('entity.definitions.installed');
foreach ($entity_field_map as $entity_type_id => $field_map) {
$entity_storage = $entity_type_manager->getStorage($entity_type_id);
// Only SQL storage based entities are supported / throw known exception.
if (!($entity_storage instanceof SqlContentEntityStorage)) {
continue;
}
$entity_type = $entity_type_manager->getDefinition($entity_type_id);
$field_storage_definitions = $entity_field_manager->getFieldStorageDefinitions($entity_type_id);
/** @var Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = $entity_storage->getTableMapping($field_storage_definitions);
// Only need field storage definitions of asset fields.
/** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage_definition */
foreach (array_intersect_key($field_storage_definitions, $field_map) as $field_storage_definition) {
$field_name = $field_storage_definition->getName();
try {
$table = $table_mapping->getFieldTableName($field_name);
}
catch (SqlContentEntityStorageException $e) {
// If there is no table or column, there's little we can do.
continue;
}
// Get the revision table.
if ($table_mapping->requiresDedicatedTableStorage($field_storage_definition)) {
$revision_table = $table_mapping->getDedicatedRevisionTableName($field_storage_definition);
}
elseif ($table_mapping->allowsSharedTableStorage($field_storage_definition)) {
$revision_table = $entity_type->getRevisionDataTable() ?: $entity_type->getRevisionTable();
}
// Load the installed field schema so that it can be updated.
$schema_key = "$entity_type_id.field_schema_data.$field_name";
$field_schema_data = $entity_storage_schema_sql->get($schema_key);
$processed_fields[] = [$entity_type_id, $field_name];
// Loop over each new column and add it as a schema column change.
foreach ($columns_to_add as $column_id) {
$column = $table_mapping->getFieldColumnName($field_storage_definition, $column_id);
// Add `initial_from_field` to the new spec, as this will copy over
// the entire data.
$field_schema = $asset_item_class::schema($field_storage_definition);
$spec = $field_schema['columns'][$column_id];
// Add the new column.
$schema->addField($table, $column, $spec);
if ($revision_table) {
$schema->addField($revision_table, $column, $spec);
}
// Add the new column to the installed field schema.
if ($field_schema_data) {
$field_schema_data[$table]['fields'][$column] = $field_schema['columns'][$column_id];
$field_schema_data[$table]['fields'][$column]['not null'] = FALSE;
if ($revision_table) {
$field_schema_data[$revision_table]['fields'][$column] = $field_schema['columns'][$column_id];
$field_schema_data[$revision_table]['fields'][$column]['not null'] = FALSE;
}
}
}
// Save changes to the installed field schema.
if ($field_schema_data) {
$entity_storage_schema_sql->set($schema_key, $field_schema_data);
}
$key = "$entity_type_id.field_storage_definitions";
if ($definitions = $entity_definitions_installed->get($key)) {
$definitions[$field_name] = $field_storage_definition;
$entity_definitions_installed->set($key, $definitions);
}
}
}
}
/**
* Checks if tracking table is not empty then populate aggregate table.
*
* @throws \Exception
*/
function _acquia_dam_populate_integration_link_aggregate_table() {
$database = \Drupal::database();
$count_query = $database
->select('acquia_dam_integration_link_tracking')
->countQuery();
// If tracking table is empty, do nothing.
if (!$count_query->execute()->fetchField()) {
return;
}
$select = \Drupal::database()->select('acquia_dam_integration_link_tracking', 't');
$select->addExpression('COUNT(t.asset_uuid)');
$select = $select
->fields('t', ['asset_uuid'])
->groupBy('t.asset_uuid');
$insert = $database
->insert('acquia_dam_integration_link_aggregate')
->fields(['asset_uuid', 'usage_count']);
foreach ($select->execute()->fetchAll() as $result) {
$insert->values([
'asset_uuid' => $result->asset_uuid,
'usage_count' => $result->expression,
]);
}
$insert->execute();
}
/**
* Updates existing `media_library` view mode definitions to use the `asset_id`
* field with the `remotely_referenced_thumbnail_image` embed style instead the
* locally stored thumbnails.
*/
function acquia_dam_update_9010() {
$dam_media_types = array_filter(\Drupal::entityTypeManager()->getStorage('media_type')->loadMultiple(), static function (MediaTypeInterface $media_type) {
return $media_type->getSource() instanceof Asset;
});
foreach ($dam_media_types as $media_type) {
$config = \Drupal::configFactory()->getEditable('core.entity_view_display.media.' . $media_type->id() . '.media_library');
// Interfere only when necessary to reserve any customization administrators might have made.
if ($config->get('content.thumbnail.type') !== 'acquia_dam_thumbnail') {
continue;
}
// A field might have any extra information (eg. third party settings) we
// cannot prepare for. Thus handling the entire value set as a complete
// block to preserve as much value as possible, overwrite only the minimum.
$field_attributes = $config->get('content.thumbnail');
$field_attributes['type'] = 'acquia_dam_embed_code';
$field_attributes['settings']['embed_style'] = 'remotely_referenced_thumbnail_image';
$field_attributes['settings']['thumbnail_width'] = (int) preg_replace('/^(\d+)px$/i', '$1', $config->get('content.thumbnail.settings.thumbnail_size'));
unset($field_attributes['settings']['thumbnail_size']);
// First set the new field with all the necessary information copied over.
$config->clear('hidden.acquia_dam_asset_id');
$config->set('content.acquia_dam_asset_id', $field_attributes);
// Then delete the old field.
$config->clear('content.thumbnail');
$config->set('hidden.thumbnail', TRUE);
// Finally save the config object.
$config->save(TRUE);
}
}
