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.