You are here

function _taxonomy_post_update_make_taxonomy_term_revisionable__fix_default_langcode in Drupal 8

Fixes recoverable data integrity issues in the "default_langcode" field.

@internal

Parameters

array $sandbox: The update sandbox array.

Return value

bool TRUE if the operation was finished, FALSE otherwise.

1 call to _taxonomy_post_update_make_taxonomy_term_revisionable__fix_default_langcode()
taxonomy_post_update_make_taxonomy_term_revisionable in core/modules/taxonomy/taxonomy.post_update.php
Update taxonomy terms to be revisionable.

File

core/modules/taxonomy/taxonomy.post_update.php, line 278
Post update functions for Taxonomy.

Code

function _taxonomy_post_update_make_taxonomy_term_revisionable__fix_default_langcode(array &$sandbox) {
  if (!empty($sandbox['data_fix']['default_langcode']['finished'])) {
    return TRUE;
  }
  $storage = \Drupal::entityTypeManager()
    ->getStorage('taxonomy_term');
  if (!$storage instanceof TermStorage) {
    $sandbox['data_fix']['default_langcode']['finished'] = TRUE;
    return TRUE;
  }
  elseif (!isset($sandbox['data_fix']['default_langcode'])) {
    $sandbox['data_fix']['default_langcode'] = [
      'last_id' => 0,
      'processed' => 0,
    ];
  }
  $database = \Drupal::database();
  $data_table_name = 'taxonomy_term_field_data';
  $last_id = $sandbox['data_fix']['default_langcode']['last_id'];
  $limit = Settings::get('update_sql_batch_size', 200);

  // Detect records in the data table matching the base table language, but
  // having the "default_langcode" flag set to with 0, which is not supported.
  $query = $database
    ->select($data_table_name, 'd');
  $query
    ->leftJoin('taxonomy_term_data', 'b', 'd.tid = b.tid AND d.langcode = b.langcode AND d.default_langcode = 0');
  $result = $query
    ->fields('d', [
    'tid',
    'langcode',
  ])
    ->condition('d.tid', $last_id, '>')
    ->isNotNull('b.tid')
    ->orderBy('d.tid')
    ->range(0, $limit)
    ->execute();
  foreach ($result as $record) {
    $sandbox['data_fix']['default_langcode']['last_id'] = $record->tid;

    // We need to exclude any term already having also a data table record with
    // the "default_langcode" flag set to 1, because this is a data integrity
    // issue that cannot be fixed automatically. However the latter will not
    // make the update fail.
    $has_default_langcode = (bool) $database
      ->select($data_table_name, 'd')
      ->fields('d', [
      'tid',
    ])
      ->condition('d.tid', $record->tid)
      ->condition('d.default_langcode', 1)
      ->range(0, 1)
      ->execute()
      ->fetchField();
    if ($has_default_langcode) {
      continue;
    }
    $database
      ->update($data_table_name)
      ->fields([
      'default_langcode' => 1,
    ])
      ->condition('tid', $record->tid)
      ->condition('langcode', $record->langcode)
      ->execute();
    $sandbox['data_fix']['default_langcode']['processed']++;
    \Drupal::logger('update')
      ->warning('The term with ID @id had data integrity issues and was restored.', [
      '@id' => $record->tid,
    ]);
  }
  $finished = $sandbox['data_fix']['default_langcode']['last_id'] === $last_id;
  $sandbox['data_fix']['default_langcode']['finished'] = $finished;
  return $finished;
}