entity_usage.install in Entity Usage 8.3
Same filename and directory in other branches
Install, update and uninstall functions for entity_usage module.
File
entity_usage.installView source
<?php
/**
* @file
* Install, update and uninstall functions for entity_usage module.
*/
use Drupal\Core\Site\Settings;
use Drupal\Core\Url;
use Drupal\entity_usage\Controller\ListUsageController;
use Drupal\entity_usage\EntityUsageSourceLevel;
/**
* Implements hook_schema().
*/
function entity_usage_schema() {
$schema['entity_usage'] = [
'description' => 'Track entities that reference other entities.',
'fields' => [
'target_id' => [
'description' => 'The target entity ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'target_id_string' => [
'description' => 'The target ID, when the entity uses string IDs.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'target_type' => [
'description' => 'The target entity type.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'source_id' => [
'description' => 'The source entity ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'source_id_string' => [
'description' => 'The source ID, when the entity uses string IDs.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => FALSE,
],
'source_type' => [
'description' => 'The source entity type.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'source_langcode' => [
'description' => 'The source entity language code.',
'type' => 'varchar_ascii',
'length' => 12,
'not null' => TRUE,
'default' => '',
],
'source_vid' => [
'description' => 'The source entity revision ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
],
'primary key' => [
'target_id',
'target_id_string',
'target_type',
'source_id',
'source_type',
'source_langcode',
'source_vid',
],
'indexes' => [
'target_entity' => [
'target_type',
'target_id',
],
'target_entity_string' => [
'target_type',
'target_id_string',
],
'source_entity' => [
'source_type',
'source_id',
],
'source_entity_string' => [
'source_type',
'source_id_string',
],
],
];
return $schema;
}
/**
* Implements hook_install().
*/
function entity_usage_install() {
// Start with 'node' and 'media' entities having the usage tabs enabled.
$entity_usage_config = \Drupal::configFactory()
->getEditable('entity_usage.settings');
$tabs_enabled = $entity_usage_config
->get('local_task_enabled_entity_types');
$module_handler = \Drupal::moduleHandler();
$modified = FALSE;
if ($module_handler
->moduleExists('node') && !in_array('node', $tabs_enabled)) {
$tabs_enabled[] = 'node';
$modified = TRUE;
}
if ($module_handler
->moduleExists('media') && !in_array('media', $tabs_enabled)) {
$tabs_enabled[] = 'media';
$modified = TRUE;
}
if ($modified) {
$entity_usage_config
->set('local_task_enabled_entity_types', $tabs_enabled)
->save(TRUE);
}
// Start with all top-level types being tracked as source.
$top_level_types = EntityUsageSourceLevel::getTopLevelEntityTypes();
if (!empty($top_level_types)) {
$entity_usage_config
->set('track_enabled_source_entity_types', $top_level_types)
->save(TRUE);
}
}
/**
* Implements hook_requirements().
*/
function entity_usage_requirements($phase) {
$requirements = [];
if ($phase === 'runtime') {
$needs_regenaration = \Drupal::state()
->get('entity_usage_needs_regeneration');
if ($needs_regenaration) {
$requirements['entity_usage_needs_regeneration'] = [
'title' => t('Entity Usage'),
'description' => t('Entity Usage has detected that usage statistics may be stale. Please visit the <a href="@batch_url">batch update</a> page and regenerate your statistics.', [
'@batch_url' => Url::fromRoute('entity_usage.batch_update')
->toString(),
]),
'severity' => REQUIREMENT_ERROR,
];
}
}
return $requirements;
}
/**
* Include "method" also as primary key for the {entity_usage} table.
*/
function entity_usage_update_8001(&$sandbox) {
$database = \Drupal::database();
$database
->schema()
->dropPrimaryKey('entity_usage');
$new_primary_keys = [
't_id',
't_type',
're_id',
're_type',
'method',
];
$database
->schema()
->addPrimaryKey('entity_usage', $new_primary_keys);
}
/**
* Recreate the entity usage table with the new schema.
*/
function entity_usage_update_8201(&$sandbox) {
$schema = \Drupal::database()
->schema();
$schema
->dropTable('entity_usage');
$new_table_schema = entity_usage_schema();
$schema
->createTable('entity_usage', $new_table_schema['entity_usage']);
}
/**
* Trigger entity usage statistics in the new schema.
*/
function entity_usage_update_8202(&$sandbox) {
// This flag is here only to ensure that sites that have already executed
// update 8202 will not run entity_usage_post_update_regenerate_2x() again.
\Drupal::state()
->set('entity_usage_2x_regenerate', TRUE);
}
/**
* Re-generate entity_usage statistics.
*/
function entity_usage_post_update_regenerate_2x(&$sandbox) {
if (!\Drupal::state()
->get('entity_usage_2x_regenerate')) {
return;
}
// First pass.
if (empty($sandbox['total'])) {
$sandbox['current_key'] = 0;
$sandbox['total'] = 0;
$sandbox['entities'] = [];
$to_track = \Drupal::config('entity_usage.settings')
->get('track_enabled_source_entity_types');
foreach (\Drupal::entityTypeManager()
->getDefinitions() as $entity_type_id => $entity_type) {
// Only look for entities enabled for tracking on the settings form.
$track_this_entity_type = FALSE;
if (!is_array($to_track) && $entity_type
->entityClassImplements('\\Drupal\\Core\\Entity\\ContentEntityInterface')) {
// When no settings are defined, track all content entities by default,
// except for Files and Users.
if (!in_array($entity_type_id, [
'file',
'user',
])) {
$track_this_entity_type = TRUE;
}
}
elseif (is_array($to_track) && in_array($entity_type_id, $to_track, TRUE)) {
$track_this_entity_type = TRUE;
}
if ($track_this_entity_type) {
// Delete current usage statistics for these entities.
\Drupal::service('entity_usage.usage')
->bulkDeleteSources($entity_type_id);
// Add all existing ids to be tracked again.
$ids = \Drupal::entityQuery($entity_type_id)
->accessCheck(FALSE)
->execute();
if (!empty($ids)) {
$sandbox['total'] += count($ids);
foreach ($ids as $id) {
$sandbox['entities'][] = [
'entity_type' => $entity_type_id,
'entity_id' => $id,
];
}
}
}
}
}
// Abort the batch process if the site is big enough for this process to be
// a very long-running process.
$limit = Settings::get('entity_usage_2x_regenerate_limit', 2000);
if ($sandbox['total'] > $limit) {
$sandbox = [];
return t('The automatic regeneration of usage statistics was skipped because it could be potentially slow on this site. Make sure you visit the <a href="@batch_url">batch update</a> page and trigger the update manually.', [
'@batch_url' => Url::fromRoute('entity_usage.batch_update')
->toString(),
]);
}
// Worker.
$batch_size = 1;
for ($i = $sandbox['current_key']; $i < $sandbox['current_key'] + $batch_size; $i++) {
if (empty($sandbox['entities'][$i])) {
break;
}
$entity_type = $sandbox['entities'][$i]['entity_type'];
$entity_id = $sandbox['entities'][$i]['entity_id'];
if ($entity_type && $entity_id) {
$entity_storage = \Drupal::entityTypeManager()
->getStorage($entity_type);
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $entity_storage
->load($entity_id);
if ($entity
->getEntityType()
->isRevisionable()) {
// Track all revisions and translations of the source entity. Sources
// are tracked as if they were new entities.
$result = $entity_storage
->getQuery()
->allRevisions()
->condition($entity
->getEntityType()
->getKey('id'), $entity
->id())
->sort($entity
->getEntityType()
->getKey('revision'), 'DESC')
->execute();
$revision_ids = array_keys($result);
foreach ($revision_ids as $revision_id) {
/** @var \Drupal\Core\Entity\EntityInterface $entity_revision */
if (!($entity_revision = $entity_storage
->loadRevision($revision_id))) {
continue;
}
\Drupal::service('entity_usage.entity_update_manager')
->trackUpdateOnCreation($entity_revision);
}
}
else {
// Sources are tracked as if they were new entities.
\Drupal::service('entity_usage.entity_update_manager')
->trackUpdateOnCreation($entity);
}
}
$sandbox['current_key']++;
}
$sandbox['#finished'] = empty($sandbox['total']) ? 1 : $sandbox['current_key'] / $sandbox['total'];
return t('Finished generating statistics for @total_count entities.', [
'@total_count' => $sandbox['total'],
]);
}
/**
* Include "target_id_string" also as primary key in schema.
*/
function entity_usage_update_8203(&$sandbox) {
// Left empty on purpose.
}
/**
* Add source entity index to the entity_usage table.
*/
function entity_usage_update_8204(&$sandbox) {
// This is deliberately duplicated, instead of calling hook_schema() to
// obtain it.
$spec = [
'description' => 'Track entities that reference other entities.',
'fields' => [
'target_id' => [
'description' => 'The target entity ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'target_id_string' => [
'description' => 'The target ID, when the entity uses string IDs.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'target_type' => [
'description' => 'The target entity type.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'source_id' => [
'description' => 'The source entity ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'source_id_string' => [
'description' => 'The source ID, when the entity uses string IDs.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => FALSE,
],
'source_type' => [
'description' => 'The source entity type.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'source_langcode' => [
'description' => 'The source entity language code.',
'type' => 'varchar_ascii',
'length' => 12,
'not null' => TRUE,
'default' => '',
],
'source_vid' => [
'description' => 'The source entity revision ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'method' => [
'description' => 'The method used to track the target, generally the plugin ID.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'field_name' => [
'description' => 'The field in the source entity containing the target entity.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'count' => [
'description' => 'The number of times the target entity is referenced in this case.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
],
'primary key' => [
'target_id',
'target_id_string',
'target_type',
'source_id',
'source_type',
'source_langcode',
'source_vid',
'method',
'field_name',
],
'indexes' => [
'target_entity' => [
'target_type',
'target_id',
],
'target_entity_string' => [
'target_type',
'target_id_string',
],
'source_entity' => [
'source_type',
'source_id',
],
'source_entity_string' => [
'source_type',
'source_id_string',
],
],
];
$schema = \Drupal::database()
->schema();
if (!$schema
->indexExists('entity_usage', 'source_entity')) {
$schema
->addIndex('entity_usage', 'source_entity', [
'source_type',
'source_id',
], $spec);
}
if (!$schema
->indexExists('entity_usage', 'source_entity_string')) {
$schema
->addIndex('entity_usage', 'source_entity_string', [
'source_type',
'source_id_string',
], $spec);
}
}
/**
* Initialize the new "usage_controller_items_per_page" config value to 25.
*/
function entity_usage_update_8205(&$sandbox) {
$config = \Drupal::configFactory()
->getEditable('entity_usage.settings');
$items_per_page = $config
->get('usage_controller_items_per_page');
if (empty($items_per_page)) {
$config
->set('usage_controller_items_per_page', ListUsageController::ITEMS_PER_PAGE_DEFAULT)
->save(TRUE);
}
}
/**
* Rename items_per_page into items_per_group.
*/
function entity_usage_update_8300(&$sandbox) {
$config = \Drupal::configFactory()
->getEditable('entity_usage.settings');
$previous_setting = $config
->get('usage_controller_items_per_page');
if (!empty($previous_setting)) {
$config
->set('usage_controller_items_per_page', NULL)
->set('usage_controller_items_per_group', $previous_setting)
->save(TRUE);
}
}
/**
* Recreate the entity usage table with the new schema.
*/
function entity_usage_update_8301(&$sandbox) {
$schema = \Drupal::database()
->schema();
$schema
->dropTable('entity_usage');
// This is deliberately duplicated instead of calling entity_usage_schema().
$new_spec = [
'description' => 'Track entities that reference other entities.',
'fields' => [
'target_id' => [
'description' => 'The target entity ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'target_id_string' => [
'description' => 'The target ID, when the entity uses string IDs.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'target_type' => [
'description' => 'The target entity type.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'source_id' => [
'description' => 'The source entity ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'source_id_string' => [
'description' => 'The source ID, when the entity uses string IDs.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => FALSE,
],
'source_type' => [
'description' => 'The source entity type.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'source_langcode' => [
'description' => 'The source entity language code.',
'type' => 'varchar_ascii',
'length' => 12,
'not null' => TRUE,
'default' => '',
],
'source_vid' => [
'description' => 'The source entity revision ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
],
'primary key' => [
'target_id',
'target_id_string',
'target_type',
'source_id',
'source_type',
'source_langcode',
'source_vid',
],
'indexes' => [
'target_entity' => [
'target_type',
'target_id',
],
'target_entity_string' => [
'target_type',
'target_id_string',
],
'source_entity' => [
'source_type',
'source_id',
],
'source_entity_string' => [
'source_type',
'source_id_string',
],
],
];
$schema
->createTable('entity_usage', $new_spec);
}
Functions
Name | Description |
---|---|
entity_usage_install | Implements hook_install(). |
entity_usage_post_update_regenerate_2x | Re-generate entity_usage statistics. |
entity_usage_requirements | Implements hook_requirements(). |
entity_usage_schema | Implements hook_schema(). |
entity_usage_update_8001 | Include "method" also as primary key for the {entity_usage} table. |
entity_usage_update_8201 | Recreate the entity usage table with the new schema. |
entity_usage_update_8202 | Trigger entity usage statistics in the new schema. |
entity_usage_update_8203 | Include "target_id_string" also as primary key in schema. |
entity_usage_update_8204 | Add source entity index to the entity_usage table. |
entity_usage_update_8205 | Initialize the new "usage_controller_items_per_page" config value to 25. |
entity_usage_update_8300 | Rename items_per_page into items_per_group. |
entity_usage_update_8301 | Recreate the entity usage table with the new schema. |