We have a large number of updates that do something for a group of configuration entities of a particular type. All of these functions should use the batch system because generally there are n amount of configuration entities present.
It will also reduce the amount of boilerplate code that is needed to run these updates, since all follow the same general pattern. Using a standardised way of running these updates will help reduce the chance of little mistakes getting into this boilerplate code.
Before:
function views_post_update_table_display_cache_max_age(&$sandbox = NULL) {
$storage = \Drupal::entityTypeManager()->getStorage('view');
if (!isset($sandbox['views'])) {
$sandbox['views'] = $storage->getQuery()->accessCheck(FALSE)->execute();
$sandbox['count'] = count($sandbox['views']);
}
for ($i = 0; $i < 10 && count($sandbox['views']); $i++) {
$view_id = array_shift($sandbox['views']);
if ($view = $storage->load($view_id)) {
$displays = $view->get('display');
foreach ($displays as $display_name => &$display) {
if (isset($display['display_options']['style']['type']) && $display['display_options']['style']['type'] === 'table') {
$view->save();
}
}
}
}
$sandbox['#finished'] = empty($sandbox['views']) ? 1 : ($sandbox['count'] - count($sandbox['views'])) / $sandbox['count'];
}
After:
function views_post_update_table_display_cache_max_age(&$sandbox = NULL) {
\Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'view', function ($view) {
/** @var \Drupal\views\ViewEntityInterface $view */
$displays = $view->get('display');
foreach ($displays as $display_name => &$display) {
if (isset($display['display_options']['style']['type']) && $display['display_options']['style']['type'] === 'table') {
return TRUE;
}
}
return FALSE;
});
}
The new service has one method update
that takes the batch $sandbox
, the config entity type, and a callback that evaluates if the config entity needs to be saved. This callback can also be used to make any needed changes to the entity.