function _menu_link_content_post_update_make_menu_link_content_revisionable__fix_default_langcode

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 _menu_link_content_post_update_make_menu_link_content_revisionable__fix_default_langcode()
menu_link_content_post_update_make_menu_link_content_revisionable in core/modules/menu_link_content/menu_link_content.post_update.php
Update custom menu links to be revisionable.

File

core/modules/menu_link_content/menu_link_content.post_update.php, line 146

Code

function _menu_link_content_post_update_make_menu_link_content_revisionable__fix_default_langcode(array &$sandbox) {
  if (!empty($sandbox['data_fix']['default_langcode']['finished'])) {
    return TRUE;
  }
  $storage = \Drupal::entityTypeManager()->getStorage('menu_link_content');
  if (!$storage instanceof MenuLinkContentStorage) {
    return TRUE;
  }
  elseif (!isset($sandbox['data_fix']['default_langcode']['last_id'])) {
    $sandbox['data_fix']['default_langcode'] = [
      'last_id' => 0,
      'processed' => 0,
    ];
  }
  $database = \Drupal::database();
  $data_table_name = 'menu_link_content_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('menu_link_content', 'b', 'd.id = b.id AND d.langcode = b.langcode AND d.default_langcode = 0');
  $result = $query->fields('d', [
    'id',
    'langcode',
  ])
    ->condition('d.id', $last_id, '>')
    ->isNotNull('b.id')
    ->orderBy('d.id')
    ->range(0, $limit)
    ->execute();
  foreach ($result as $record) {
    $sandbox['data_fix']['default_langcode']['last_id'] = $record->id;
    // We need to exclude any menu link 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', [
      'id',
    ])
      ->condition('d.id', $record->id)
      ->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('id', $record->id)
      ->condition('langcode', $record->langcode)
      ->execute();
    $sandbox['data_fix']['default_langcode']['processed']++;
    \Drupal::logger('update')->warning('The menu link with ID @id had data integrity issues and was restored.', [
      '@id' => $record->id,
    ]);
  }
  $finished = $sandbox['data_fix']['default_langcode']['last_id'] === $last_id;
  $sandbox['data_fix']['default_langcode']['finished'] = $finished;
  return $finished;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.