taxonomy.install
Same filename in other branches
Install, update and uninstall functions for the taxonomy module.
File
-
core/
modules/ taxonomy/ taxonomy.install
View source
<?php
/**
* @file
* Install, update and uninstall functions for the taxonomy module.
*/
use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Site\Settings;
/**
* Implements hook_requirements().
*/
function taxonomy_requirements($phase) {
$requirements = [];
if ($phase === 'update') {
// Check for invalid data before making terms revisionable.
/** @var \Drupal\Core\Update\UpdateRegistry $registry */
$registry = \Drupal::service('update.post_update_registry');
$update_name = 'taxonomy_post_update_make_taxonomy_term_revisionable';
if (in_array($update_name, $registry->getPendingUpdateFunctions(), TRUE)) {
// The 'name' field is non-NULL - if we get a NULL value that indicates a
// failure to join on taxonomy_term_field_data.
$is_broken = \Drupal::entityQuery('taxonomy_term')->condition('name', NULL, 'IS NULL')
->range(0, 1)
->accessCheck(FALSE)
->execute();
if ($is_broken) {
$requirements[$update_name] = [
'title' => t('Taxonomy term data'),
'value' => t('Integrity issues detected'),
'description' => t('The make_taxonomy_term_revisionable database update cannot be run until the data has been fixed. See the <a href=":change_record">change record</a> for more information.', [
':change_record' => 'https://www.drupal.org/node/3117753',
]),
'severity' => REQUIREMENT_ERROR,
];
}
}
}
return $requirements;
}
/**
* Convert the custom taxonomy term hierarchy storage to a default storage.
*/
function taxonomy_update_8501() {
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
/** @var \Drupal\Core\Field\BaseFieldDefinition $field_storage_definition */
$field_storage_definition = $definition_update_manager->getFieldStorageDefinition('parent', 'taxonomy_term');
$field_storage_definition->setCustomStorage(FALSE);
$definition_update_manager->updateFieldStorageDefinition($field_storage_definition);
}
/**
* Copy hierarchy from {taxonomy_term_hierarchy} to {taxonomy_term__parent}.
*/
function taxonomy_update_8502(&$sandbox) {
$database = \Drupal::database();
if (!isset($sandbox['current'])) {
// Set batch ops sandbox.
$sandbox['current'] = 0;
$sandbox['tid'] = -1;
$sandbox['delta'] = 0;
$sandbox['limit'] = Settings::get('entity_update_batch_size', 50);
// Count records using a join, as there might be orphans in the hierarchy
// table. See https://www.drupal.org/project/drupal/issues/2997982.
$select = $database->select('taxonomy_term_hierarchy', 'h');
$select->join('taxonomy_term_data', 'd', 'h.tid = d.tid');
$sandbox['max'] = $select->countQuery()
->execute()
->fetchField();
}
// Save the hierarchy.
$select = $database->select('taxonomy_term_hierarchy', 'h');
$select->join('taxonomy_term_data', 'd', 'h.tid = d.tid');
$hierarchy = $select->fields('h', [
'tid',
'parent',
])
->fields('d', [
'vid',
'langcode',
])
->range($sandbox['current'], $sandbox['limit'])
->orderBy('tid', 'ASC')
->orderBy('parent', 'ASC')
->execute()
->fetchAll();
// Restore data.
$insert = $database->insert('taxonomy_term__parent')
->fields([
'bundle',
'entity_id',
'revision_id',
'langcode',
'delta',
'parent_target_id',
]);
foreach ($hierarchy as $row) {
if ($row->tid !== $sandbox['tid']) {
$sandbox['delta'] = 0;
$sandbox['tid'] = $row->tid;
}
$insert->values([
'bundle' => $row->vid,
'entity_id' => $row->tid,
'revision_id' => $row->tid,
'langcode' => $row->langcode,
'delta' => $sandbox['delta'],
'parent_target_id' => $row->parent,
]);
$sandbox['delta']++;
$sandbox['current']++;
}
$insert->execute();
$sandbox['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['current'] / $sandbox['max'];
if ($sandbox['#finished'] >= 1) {
// Update the entity type because the 'taxonomy_term_hierarchy' table is no
// longer part of its shared tables schema.
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$definition_update_manager->updateEntityType($definition_update_manager->getEntityType('taxonomy_term'));
// \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::onEntityTypeUpdate()
// only deletes *known* entity tables (i.e. the base, data and revision
// tables), so we have to drop it manually.
$database->schema()
->dropTable('taxonomy_term_hierarchy');
return t('Taxonomy term hierarchy has been converted to default entity reference storage.');
}
}
/**
* Update views to use {taxonomy_term__parent} in relationships.
*/
function taxonomy_update_8503() {
$config_factory = \Drupal::configFactory();
foreach ($config_factory->listAll('views.view.') as $id) {
$view = $config_factory->getEditable($id);
foreach (array_keys($view->get('display')) as $display_id) {
$changed = FALSE;
foreach ([
'relationships',
'filters',
'arguments',
] as $handler_type) {
$base_path = "display.{$display_id}.display_options.{$handler_type}";
$handlers = $view->get($base_path);
if (!$handlers) {
continue;
}
foreach ($handlers as $handler_key => $handler_config) {
$table_path = "{$base_path}.{$handler_key}.table";
$field_path = "{$base_path}.{$handler_key}.field";
$table = $view->get($table_path);
$field = $view->get($field_path);
if ($table && $table === 'taxonomy_term_hierarchy' && ($field && $field === 'parent')) {
$view->set($table_path, 'taxonomy_term__parent');
$view->set($field_path, 'parent_target_id');
$changed = TRUE;
}
}
}
if ($changed) {
$view->save(TRUE);
}
}
}
}
/**
* Add the publishing status fields to taxonomy terms.
*/
function taxonomy_update_8601() {
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$entity_type = $definition_update_manager->getEntityType('taxonomy_term');
// Bail out early if a field named 'status' is already installed.
if ($definition_update_manager->getFieldStorageDefinition('status', 'taxonomy_term')) {
$message = \Drupal::state()->get('taxonomy_update_8601_skip_message', t('The publishing status field has <strong>not</strong> been added to taxonomy terms. See <a href=":link">this page</a> for more information on how to install it.', [
':link' => 'https://www.drupal.org/node/2985366',
]));
return $message;
}
// Add the 'published' entity key to the taxonomy_term entity type.
$entity_keys = $entity_type->getKeys();
$entity_keys['published'] = 'status';
$entity_type->set('entity_keys', $entity_keys);
$definition_update_manager->updateEntityType($entity_type);
// Add the status field.
$status = BaseFieldDefinition::create('boolean')->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating the published state.'))
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDefaultValue(TRUE);
$has_content_translation_status_field = $definition_update_manager->getFieldStorageDefinition('content_translation_status', 'taxonomy_term');
if ($has_content_translation_status_field) {
$status->setInitialValueFromField('content_translation_status', TRUE);
}
else {
$status->setInitialValue(TRUE);
}
$definition_update_manager->installFieldStorageDefinition('status', 'taxonomy_term', 'taxonomy_term', $status);
// Uninstall the 'content_translation_status' field if needed.
if ($has_content_translation_status_field) {
$content_translation_status = $definition_update_manager->getFieldStorageDefinition('content_translation_status', 'taxonomy_term');
$definition_update_manager->uninstallFieldStorageDefinition($content_translation_status);
}
return t('The publishing status field has been added to taxonomy terms.');
}
/**
* Add an index on the 'taxonomy_term__parent' field table.
*/
function taxonomy_update_8701() {
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$storage_definition = $entity_definition_update_manager->getFieldStorageDefinition('parent', 'taxonomy_term');
$entity_definition_update_manager->updateFieldStorageDefinition($storage_definition);
}
/**
* Fix the parent field langcode data.
*/
function taxonomy_update_8702(&$sandbox) {
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$field_storage_definition = $definition_update_manager->getFieldStorageDefinition('parent', 'taxonomy_term');
$entity_type = $definition_update_manager->getEntityType('taxonomy_term');
// Only perform the update if:
// - The field is not translatable. It's possible that custom or contrib code
// has overridden this.
// - The field is not revisionable. If it is then
// taxonomy_post_update_make_taxonomy_term_revisionable() has already run
// and this used to fix the parent field langcode data.
// - Terms are using a SQL-based storage class.
if (!$field_storage_definition->isTranslatable() && !$entity_type->isRevisionable() && is_subclass_of($entity_type->getStorageClass(), SqlEntityStorageInterface::class)) {
// taxonomy_update_8502() populated the langcode field of
// 'taxonomy_term__parent' using the term's langcode. However, the field is
// not translatable and, therefore, should use the term's default language.
$database = \Drupal::database();
$select = $database->select('taxonomy_term__parent', 'tp');
$select->join('taxonomy_term_field_data', 'tdf', 'tp.entity_id = tdf.tid AND tdf.langcode <> tp.langcode');
$select->fields('tp', [
'entity_id',
])
->fields('tdf', [
'tid',
'langcode',
])
->condition('tdf.default_langcode', 1);
if (!isset($sandbox['max'])) {
$count_query = clone $select;
$sandbox['max'] = $count_query->countQuery()
->execute()
->fetchField();
$sandbox['current'] = 0;
}
$result = $select->execute();
$processed = 0;
while ($row = $result->fetchAssoc()) {
$database->update('taxonomy_term__parent')
->condition('entity_id', $row['tid'])
->fields([
'langcode' => $row['langcode'],
])
->execute();
$sandbox['current']++;
$processed++;
if ($processed >= Settings::get('entity_update_batch_size', 50)) {
break;
}
}
}
$sandbox['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['current'] / $sandbox['max'];
}
Functions
Title | Deprecated | Summary |
---|---|---|
taxonomy_requirements | Implements hook_requirements(). | |
taxonomy_update_8501 | Convert the custom taxonomy term hierarchy storage to a default storage. | |
taxonomy_update_8502 | Copy hierarchy from {taxonomy_term_hierarchy} to {taxonomy_term__parent}. | |
taxonomy_update_8503 | Update views to use {taxonomy_term__parent} in relationships. | |
taxonomy_update_8601 | Add the publishing status fields to taxonomy terms. | |
taxonomy_update_8701 | Add an index on the 'taxonomy_term__parent' field table. | |
taxonomy_update_8702 | Fix the parent field langcode data. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.