external_entities-8.x-2.x-dev/external_entities.install
external_entities.install
<?php
/**
* @file
* Install, update and uninstall functions for the external_entities module.
*/
use Drupal\Core\Database\Database;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\external_entities\Plugin\ExternalEntities\DataAggregator\GroupAggregator;
use Drupal\external_entities\Plugin\ExternalEntities\StorageClient\FileClientInterface;
use Drupal\user\UserInterface;
use JsonPath\JsonObject;
/**
* Implements hook_requirements().
*/
function external_entities_requirements($phase) {
$requirements = [];
if ($phase === 'install' || $phase === 'runtime') {
if (!class_exists(JsonObject::class)) {
$requirements['external_entities_jsonpath'] = [
'title' => t('Galbar JSONPath library'),
'description' => t("External entities requires the galbar/jsonpath library."),
'severity' => REQUIREMENT_ERROR,
];
}
}
return $requirements;
}
/**
* Implements hook_uninstall().
*/
function external_entities_uninstall() {
$db_connection = \Drupal::database();
$db_connection->schema()->dropTable('xntt_rest_queries');
}
/**
* Implements hook_schema().
*/
function external_entities_schema() {
$schema['xntt_rest_queries'] = [
'description' => 'Stores REST queries to handle limitations.',
'fields' => [
'qid' => [
'description' => 'The primary identifier for a query set.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
'endpoint' => [
'description' => 'Holds the endpoint URL',
'type' => 'varchar',
'length' => 2083,
'not null' => TRUE,
],
// MD5 hash added for issue #3475768 as unique key on long string is not
// supported by all databases.
'ephash' => [
'description' => 'MD5 hash of the endpoint URL. Used as a unique key for query limiting and upserts.',
'type' => 'char',
'length' => 32,
'not null' => TRUE,
],
'qtimes' => [
'description' => 'Sorted array of query times',
'type' => 'text',
'not null' => TRUE,
],
'xntt_type' => [
'description' => 'Holds used external entity type for the query',
'type' => 'varchar',
'length' => EntityTypeInterface::ID_MAX_LENGTH,
'not null' => TRUE,
],
'username' => [
'description' => 'Holds name of the user which issued the query',
'type' => 'varchar',
'length' => UserInterface::USERNAME_MAX_LENGTH,
'not null' => TRUE,
],
],
'primary key' => ['qid'],
'unique keys' => ['ephash' => ['ephash']],
];
return $schema;
}
/**
* Create the database schema for external entity types.
*/
function external_entities_update_8201() {
// Prior to https://www.drupal.org/project/external_entities/issues/3056426
// the database schema for external entity types was not created. This update
// script creates the database schema for all existing external entity types.
$external_entity_type_config = \Drupal::entityTypeManager()->getDefinition('external_entity_type');
$external_entity_types = \Drupal::entityTypeManager()->createHandlerInstance(
$external_entity_type_config->getHandlerClass('storage'),
$external_entity_type_config
)->loadMultiple();
foreach ($external_entity_types as $id => $entity_type) {
$entity_type = \Drupal::entityTypeManager()->getDefinition($id);
\Drupal::service('entity_type.listener')
->onEntityTypeCreate($entity_type);
}
}
/**
* Enable submodule for installations that were relying on it.
*/
function external_entities_update_8202() {
\Drupal::service('module_installer')->install(['external_entities_pathauto']);
}
/**
* Migrate (simple) field mappings to the new pluggable field mapper.
*/
function external_entities_update_8203() {
$external_entity_type_config = \Drupal::entityTypeManager()->getDefinition('external_entity_type');
$external_entity_types = \Drupal::entityTypeManager()->createHandlerInstance(
$external_entity_type_config->getHandlerClass('storage'),
$external_entity_type_config
)->loadMultiple();
foreach ($external_entity_types as $entity_type_id => $entity_type) {
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$field_mappings = $config->get('field_mappings');
if (!empty($field_mappings)) {
$config->set('field_mapper_id', 'simple');
$config->set('field_mapper_config.field_mappings', $field_mappings);
}
$config->clear('field_mappings');
$config->save();
}
}
/**
* Upgrades REST storage client settings.
*/
function external_entities_update_9304(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
// Loop on external entity types to check the ones using REST clients.
foreach ($xntt_types as $entity_type_id) {
// This will only update native modules. Other derived modules or xnttmulti
// configs will not be updated but it is not a big deal since editing and
// saving the config from the UI will do the job and the system will work
// with not updated configs anyway.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$storage_client_id = $config->get('storage_client_id') ?? '';
if (in_array($storage_client_id, ['rest', 'wiki', 'jsonapi'])) {
$storage_config = $config->get('storage_client_config');
// Upgrade authentication settings.
if (!isset($storage_config['api_key']['type'])) {
if (!empty($storage_config['api_key']['key'])
&& !empty($storage_config['api_key']['header_name'])) {
$storage_config['api_key']['type'] = 'custom';
}
else {
$storage_config['api_key']['type'] = 'none';
}
$config->set('storage_client_config', $storage_config);
$config->save();
}
}
}
return t('REST, Wiki and JsonAPI external entity storage client configs were updated. If you have external entities using other REST-derivative storage clients, consider manually re-saving their config from the UI for update.');
}
/**
* Add query limiting table.
*/
function external_entities_update_9305(&$sandbox) {
// We don't call external_entities_schema() on purpose.
$xntt_rest_queries = [
'description' => 'Stores REST queries to handle limitations.',
'fields' => [
'qid' => [
'description' => 'The primary identifier for a query set.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
'endpoint' => [
'description' => 'Holds the endpoint URL',
'type' => 'varchar',
'length' => 2083,
'not null' => TRUE,
],
// MD5 hash added for issue #3475768 as unique key on long string is not
// supported by all databases.
'ephash' => [
'description' => 'MD5 hash of the endpoint URL. Used as a unique key for query limiting and upserts.',
'type' => 'char',
'length' => 32,
'not null' => TRUE,
],
'qtimes' => [
'description' => 'Sorted array of query times',
'type' => 'text',
'not null' => TRUE,
],
'xntt_type' => [
'description' => 'Holds used external entity type for the query',
'type' => 'varchar',
'length' => EntityTypeInterface::ID_MAX_LENGTH,
'not null' => TRUE,
],
'username' => [
'description' => 'Holds name of the user which issued the query',
'type' => 'varchar',
'length' => UserInterface::USERNAME_MAX_LENGTH,
'not null' => TRUE,
],
],
'primary key' => ['qid'],
'unique keys' => ['ephash' => ['ephash']],
];
$schema = Database::getConnection()->schema();
// If the table exists, remove it.
if ($schema->tableExists('xntt_rest_queries')) {
$schema->dropTable('xntt_rest_queries');
}
// Create table.
$schema->createTable('xntt_rest_queries', $xntt_rest_queries);
}
/**
* Update field mapper configs to new structure.
*/
function external_entities_update_9306(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Upgrade field mapper configs.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$fm_id = $config->get('field_mapper_id');
if (in_array($fm_id, ['simple', 'jsonpath'])) {
$fm_config = $config->get('field_mapper_config');
foreach ($fm_config['field_mappings'] as &$properties) {
foreach ($properties as &$mapping) {
if (is_string($mapping)) {
$mapping_type = 4;
if ('+' == $mapping[0]) {
$mapping = substr($mapping, 1);
$mapping_type = 1;
}
elseif ('simple' == $fm_id) {
$mapping_type = 2;
}
elseif ('jsonpath' == $fm_id) {
$mapping_type = 4;
}
$mapping = [
'type' => $mapping_type,
'mapping' => $mapping,
];
}
}
}
$config->set('field_mapper_config', $fm_config);
$config->save();
}
}
}
/**
* Update external entity settings to support multiple plugins by type.
*/
function external_entities_update_9307(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Upgrade storage client settings.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$sc_id = $config->get('storage_client_id');
$sc_config = $config->get('storage_client_config') ?? [];
if (!empty($sc_id)) {
$config->set('storage_clients', [['id' => $sc_id, 'config' => $sc_config]]);
$config->clear('storage_client_id');
$config->clear('storage_client_config');
$config->save();
}
$fm_id = $config->get('field_mapper_id');
$fm_config = $config->get('field_mapper_config') ?? [];
if (!empty($fm_id)) {
$config->set('field_mappers', [['id' => $fm_id, 'config' => $fm_config]]);
$config->clear('field_mapper_id');
$config->clear('field_mapper_config');
$config->save();
}
}
}
/**
* Install external entity language field definition.
*/
function external_entities_update_9308(&$sandbox) {
$entity_field_manager = \Drupal::service('entity_field.manager');
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
$schema_repo = \Drupal::service('entity.last_installed_schema.repository');
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Get field definitions.
$field_defs = $entity_field_manager
->getFieldDefinitions($entity_type_id, $entity_type_id);
foreach (['langcode', 'default_langcode'] as $field_id) {
// Update last installed field storage definition to remove warnings on
// site report page.
$fsd = $field_defs[$field_id]->getFieldStorageDefinition();
$schema_repo->setLastInstalledFieldStorageDefinition($fsd);
// We don't trigger listeners as ExternalEntityType is not an
// EntityType but a ConfigEntityBase.
}
}
}
/**
* Upgrade file storage clients.
*/
function external_entities_update_93010(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Upgrade file storage client ids.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$scs = $config->get('storage_clients');
$need_update = FALSE;
foreach ($scs as &$sc) {
if ($sc['id'] == 'xnttfiles') {
$sc['id'] = 'files';
$need_update = TRUE;
$sc['config']['performances']['use_index'] = $sc['config']['use_index'];
unset($sc['config']['use_index']);
$sc['config']['performances']['index_file'] = $sc['config']['index_file'];
unset($sc['config']['index_file']);
$sc['config']['data_fields']['index_file'] = $sc['config']['field_list'];
unset($sc['config']['field_list']);
}
}
if ($need_update) {
$config->set('storage_clients', $scs);
$config->save();
}
}
}
/**
* Upgrade field mapping config.
*/
function external_entities_update_93011(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
$messages = '';
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$fms = $config->get('field_mappers');
// Check if already up-to-date.
if (!array_key_exists('id', $fms)
&& !empty($fms[0]['config']['field_mappings'])
) {
$fms_new = [];
$field_definitions = \Drupal::service('entity_field.manager')
->getFieldDefinitions($entity_type_id, $entity_type_id);
foreach ($fms[0]['config']['field_mappings'] as $field_name => $fm) {
if (empty($field_definitions[$field_name])) {
// Warn.
$messages .= t(
"WARNING: Missing field definition for external entity type '@xntt', field '@field' (not updated). Edit the external entity type manually to fix the mapping.<br/>\n",
[
'@xntt' => $entity_type_id,
'@field' => $field_name,
]
);
continue;
}
$fms_new[$field_name] = [
'id' => 'generic',
'config' => [
'property_mappings' => [],
],
];
$main_property = $field_definitions[$field_name]->getFieldStorageDefinition()->getMainPropertyName();
foreach ($fm as $property_name => $pm) {
if (is_string($pm)) {
$pm = [
'type' => 3,
'mapping' => $pm,
];
}
$required = in_array($property_name, ['id', 'title']);
$main = ($property_name == $main_property);
switch ($pm['type']) {
case 1:
// Mapping type "MAPPING_CONSTANT".
$fms_new[$field_name]['config']['property_mappings'][$property_name] = [
'id' => 'constant',
'config' => [
'mapping' => $pm['mapping'] ?? '',
'required_field' => $required,
'main_property' => $main,
],
];
break;
case 2:
// Mapping type "MAPPING_DIRECT".
$fms_new[$field_name]['config']['property_mappings'][$property_name] = [
'id' => 'direct',
'config' => [
'mapping' => $pm['mapping'] ?? '',
'required_field' => $required,
'main_property' => $main,
'data_processors' => [
[
'id' => 'default',
'config' => [],
],
],
],
];
break;
case 3:
// Mapping type "MAPPING_SIMPLE".
$fms_new[$field_name]['config']['property_mappings'][$property_name] = [
'id' => 'simple',
'config' => [
'mapping' => $pm['mapping'] ?? '',
'required_field' => $required,
'main_property' => $main,
'data_processors' => [
[
'id' => 'default',
'config' => [],
],
],
],
];
break;
case 4:
// Mapping type "MAPPING_EXPRESSION".
$mapper_id = $fms[0]['id'];
// Only use supported mappers.
if (!in_array($mapper_id, ['simple', 'jsonpath', 'stringjsonpath'])) {
// Warn.
$messages .= t(
"WARNING: Unsupported field mapper (@fm) for external entity type '@xntt', field '@field', and property '@property'. Using 'Simple' property mapper instead. Edit the external entity type manually to adjust the mapping.<br/>\n",
[
'@xntt' => $entity_type_id,
'@field' => $field_name,
'@property' => $property_name,
'@fm' => $mapper_id,
]
);
$mapper_id = 'simple';
}
$fms_new[$field_name]['config']['property_mappings'][$property_name] = [
'id' => $mapper_id,
'config' => [
'mapping' => $pm['mapping'] ?? '',
'required_field' => $required,
'main_property' => $main,
'data_processors' => [
[
'id' => 'default',
'config' => [],
],
],
],
];
break;
default:
// Warn.
$messages .= t(
"WARNING: Unsupported mapping type (@type) for external entity type '@xntt', field '@field', and property '@property' (not updated). Edit the external entity type manually to fix the mapping.<br/>\n",
[
'@xntt' => $entity_type_id,
'@field' => $field_name,
'@property' => $property_name,
'@type' => $pm['type'],
]
);
}
}
}
$config->set('field_mappers', $fms_new);
$config->save();
}
}
return $messages;
}
/**
* Upgrade database storage clients.
*/
function external_entities_update_93012(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
$updated = [];
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Upgrade database storage client ids.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$field_definitions = \Drupal::service('entity_field.manager')
->getFieldDefinitions($entity_type_id, $entity_type_id);
$scs = $config->get('storage_clients');
$fms = $config->get('field_mappers');
$need_update = FALSE;
foreach ($scs as &$sc) {
if ($sc['id'] == 'xnttdb') {
$need_update = TRUE;
$sc['id'] = 'sql';
$sc['config']['queries']['create'] = $sc['config']['qcreate'];
unset($sc['config']['qcreate']);
$sc['config']['queries']['read'] = $sc['config']['qread'];
unset($sc['config']['qread']);
$sc['config']['queries']['update'] = $sc['config']['qupdate'];
unset($sc['config']['qupdate']);
$sc['config']['queries']['delete'] = $sc['config']['qdelete'];
unset($sc['config']['qdelete']);
$sc['config']['queries']['list'] = $sc['config']['qlist'];
unset($sc['config']['qlist']);
$sc['config']['queries']['count'] = $sc['config']['qcount'];
unset($sc['config']['qcount']);
$filter_mappings = [];
foreach (($sc['config']['filter_mappings'] ?? []) as $field_name => $expression) {
if (empty($field_definitions[$field_name])) {
continue;
}
$main_property = $field_definitions[$field_name]->getFieldStorageDefinition()->getMainPropertyName();
$alias = $fms[$field_name]['config']['property_mappings'][$main_property]['config']['mapping'] ?? '';
if (!empty($alias) && !empty($expression)) {
$filter_mappings[] = [
'alias' => $alias,
'expression' => $expression,
];
}
}
$sc['config']['filter_mappings'] = $filter_mappings;
}
}
if ($need_update) {
$config->set('storage_clients', $scs);
$config->save();
$updated[] = $entity_type_id;
}
}
if (!empty($updated)) {
return t(
'You may need to review the SQL storage client configs for the following external entity types: @types',
['@types' => implode(', ', $updated)]
);
}
}
/**
* Upgrade data aggregation settings.
*/
function external_entities_update_93013(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Upgrade storage client aggregation settings.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$scs = $config->get('storage_clients') ?? [];
$multi = (1 < count($scs));
$ag = $config->get('data_aggregator') ?? ['id' => ($multi ? 'group' : 'single'), 'config' => []];
unset($ag['config']['global_config']);
if ($multi || ('group' == $ag['id'])) {
$ag['id'] = 'group';
foreach ($scs as $sc_index => &$storage_client) {
$storage_client['aggr'] =
($ag['config']['storage_client_config'][$sc_index] ?? [])
+ [
'groups' => [],
'group_prefix_strip' => FALSE,
'id_field' => '',
'merge' => 'keep',
'merge_as_member' => '',
'merge_join' => '',
'readonly' => TRUE,
];
}
}
else {
$ag['id'] = 'single';
}
unset($ag['config']['storage_client_config']);
$ag['config']['storage_clients'] = $scs;
$config->set('data_aggregator', $ag);
$config->clear('storage_clients');
$config->save();
}
}
/**
* Change simple property mapper separator from slash to dot.
*/
function external_entities_update_93014(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Upgrade field mapper settings.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$fms = $config->get('field_mappers');
$need_update = FALSE;
foreach ($fms as &$fm) {
foreach ($fm['config']['property_mappings'] as &$property_mapping) {
if ('simple' == ($property_mapping['id'] ?? '')) {
$need_update = TRUE;
$property_mapping['config']['mapping'] =
str_replace('/', '.', $property_mapping['config']['mapping']);
}
}
}
if ($need_update) {
$config->set('field_mappers', $fms);
$config->save();
}
}
}
/**
* Add hash column to endpoint limitation table (issue #3475768).
*/
function external_entities_update_93015(&$sandbox) {
$connection = Database::getConnection();
$schema = $connection->schema();
if ($schema->fieldExists('xntt_rest_queries', 'ephash')) {
return;
}
$ephash = [
'description' => 'MD5 hash of the endpoint URL. Used as a unique key for query limiting and upserts.',
'type' => 'char',
'length' => 32,
'not null' => TRUE,
];
// First we get all current entries and remove them from the table to allow
// adding a new column with a "NOT NULL" constraint.
$qtimes = $connection
->select('xntt_rest_queries', 'q')
->fields('q')
->execute()
->fetchAll(PDO::FETCH_ASSOC);
$connection->delete('xntt_rest_queries')->execute();
// Add the new column.
$schema->addField('xntt_rest_queries', 'ephash', $ephash);
// Remove previous constraint (if one).
$schema->dropUniqueKey('xntt_rest_queries', 'endpoint');
// Add constraint on epash column.
$schema->addUniqueKey('xntt_rest_queries', 'ephash', ['ephash']);
// Put back entries.
foreach ($qtimes as $qtime) {
$qtime['ephash'] = md5($qtime['endpoint']);
$connection
->insert('xntt_rest_queries')
->fields($qtime)
->execute();
}
}
/**
* Turn group data aggregator readonly setting into a mode setting.
*/
function external_entities_update_93016(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Upgrade storage client aggregation settings.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$need_update = FALSE;
$ag = $config->get('data_aggregator') ?? [];
if ('group' == ($ag['id'] ?? '')) {
$ag['config']['storage_clients'] ??= [];
foreach ($ag['config']['storage_clients'] as &$sc) {
if (is_array($sc['aggr'])
&& !array_key_exists('mode', $sc['aggr'])
) {
$sc['aggr']['mode'] = $sc['aggr']['readonly']
? GroupAggregator::STORAGE_CLIENT_MODE_READONLY
: GroupAggregator::STORAGE_CLIENT_MODE_READWRITE;
unset($sc['aggr']['readonly']);
$need_update = TRUE;
}
}
}
if ($need_update) {
$config->set('data_aggregator', $ag);
$config->save();
}
}
}
/**
* Upgrade file storage client settings.
*/
function external_entities_update_93017(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
$storage_client_manager = \Drupal::service('plugin.manager.external_entities.storage_client');
$storage_clients = $storage_client_manager->getDefinitions();
$file_storage_client_ids = [];
foreach ($storage_clients as $storage_client_id => $definition) {
$config = [];
$storage_client = $storage_client_manager
->createInstance($storage_client_id, $config);
if ($storage_client instanceof FileClientInterface) {
$file_storage_client_ids[] = $storage_client_id;
}
}
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Upgrade file storage client settings.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$need_update = FALSE;
$ag = $config->get('data_aggregator') ?? [];
if (!empty($ag['id'])) {
$ag['config']['storage_clients'] ??= [];
foreach ($ag['config']['storage_clients'] as &$sc) {
if (in_array($sc['id'], $file_storage_client_ids)
&& !empty($sc['config'])
&& !isset($sc['config']['record_type'])
) {
if (empty($sc['config']['multi_records'])) {
$sc['config']['record_type'] = FileClientInterface::RECORD_TYPE_SINGLE;
}
else {
$sc['config']['record_type'] = FileClientInterface::RECORD_TYPE_MULTI;
}
unset($sc['config']['multi_records']);
unset($sc['config']['info']);
$need_update = TRUE;
}
}
}
if ($need_update) {
$config->set('data_aggregator', $ag);
$config->save();
}
}
}
/**
* Convert "inherits_annotation_fields" to "annotation_inherited_fields".
*/
function external_entities_update_93018(&$sandbox) {
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
$entity_field_manager = \Drupal::service('entity_field.manager');
/** @var \Drupal\external_entities\Entity\ExternalEntityTypeInterface[] $external_entity_types */
$external_entity_types = \Drupal::entityTypeManager()
->getStorage('external_entity_type')
->loadMultiple();
foreach ($external_entity_types as $external_entity_type) {
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$external_entity_type->id()}");
if (empty($config->get('annotation_inherited_fields'))) {
$config->set('annotation_inherited_fields', []);
if ($config->get('inherits_annotation_fields')
&& $config->get('annotation_entity_type_id')
&& $config->get('annotation_bundle_id')
) {
$field_definitions = $entity_field_manager->getFieldDefinitions($config->get('annotation_entity_type_id'), $config->get('annotation_bundle_id'));
$config->set('annotation_inherited_fields', array_keys($field_definitions));
}
}
$config->clear('inherits_annotation_fields');
$config->save();
}
}
/**
* Remove 'generate_aliases' settings if not external_entities_pathauto module.
*/
function external_entities_update_93019(&$sandbox) {
// Check if external_entities_pathauto sub-module is disabled.
$module_handler = \Drupal::moduleHandler();
if (!$module_handler->moduleExists('external_entities_pathauto')) {
// Module is disabled, remove 'generate_aliases' setting.
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$generate_aliases = $config->get('generate_aliases');
if (isset($generate_aliases)) {
$config->clear('generate_aliases');
$config->save();
}
}
}
}
/**
* Re-apply update 9305 if needed. See Issue #3526917.
*/
function external_entities_update_93020(&$sandbox) {
external_entities_update_9305($sandbox);
}
/**
* Adds "base_path" property.
*/
function external_entities_update_93021(&$sandbox) {
/** @var \Drupal\external_entities\Entity\ExternalEntityTypeInterface[] $external_entity_types */
$external_entity_types = \Drupal::entityTypeManager()
->getStorage('external_entity_type')
->loadMultiple();
foreach ($external_entity_types as $external_entity_type) {
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$external_entity_type->id()}");
if (empty($config->get('base_path'))) {
$config->set('base_path', $external_entity_type->id());
$config->save();
}
}
}
/**
* Move lock settings from state to config.
*/
function external_entities_update_93022(&$sandbox) {
$locked = \Drupal::state()->get('external_entities.type.locked');
if (!empty($locked) && is_array($locked)) {
foreach ($locked as $xntt_type_id => $lock_settings) {
$external_entity_type = \Drupal::entityTypeManager()
->getStorage('external_entity_type')
->load($xntt_type_id);
if (!$external_entity_type) {
continue;
}
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$external_entity_type->id()}");
$config->set('locks', $lock_settings);
$config->save();
}
\Drupal::state()->delete('external_entities.type.locked');
}
}
/**
* Turn group data aggregator id_field setting into a property mapping.
*/
function external_entities_update_93023(&$sandbox) {
$xntt_storage = \Drupal::entityTypeManager()
->getStorage('external_entity_type');
$xntt_types = $xntt_storage
->getQuery()
->accessCheck(FALSE)
->execute();
// Loop on external entity types.
foreach ($xntt_types as $entity_type_id) {
// Upgrade storage client aggregation settings.
/** @var \Drupal\Core\Config\Config $config */
$config = \Drupal::configFactory()->getEditable("external_entities.external_entity_type.{$entity_type_id}");
$need_update = FALSE;
$ag = $config->get('data_aggregator') ?? [];
if (in_array(($ag['id'] ?? ''), ['group', 'horizontal', 'vertical'])) {
$ag['config']['storage_clients'] ??= [];
foreach ($ag['config']['storage_clients'] as &$sc) {
if (is_array($sc['aggr'])
&& array_key_exists('id_field', $sc['aggr'])
) {
if (empty($sc['aggr']['id_field'])) {
$sc['aggr']['id_mapper'] = [
'id' => '',
'config' => [],
];
}
else {
$sc['aggr']['id_mapper'] = [
'id' => 'direct',
'config' => [
'field_name' => 'id',
'property_name' => 'value',
'main_property' => TRUE,
'required_field' => TRUE,
'mapping' => $sc['aggr']['id_field'],
],
];
$sc['aggr']['join_mapper'] = [
'id' => 'direct',
'config' => [
'field_name' => 'title',
'property_name' => 'value',
'main_property' => TRUE,
'required_field' => TRUE,
'mapping' => $sc['aggr']['id_field'],
],
];
}
unset($sc['aggr']['id_field']);
$need_update = TRUE;
}
}
}
if ($need_update) {
$config->set('data_aggregator', $ag);
$config->save();
}
}
}
