Skip to content

Instantly share code, notes, and snippets.

@adamzimmermann
Last active March 21, 2022 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamzimmermann/680b25d465bcfec6571e7d999e8be91a to your computer and use it in GitHub Desktop.
Save adamzimmermann/680b25d465bcfec6571e7d999e8be91a to your computer and use it in GitHub Desktop.
Update hooks to convert menu paths to entity routes
/**
* @file
* This gist supports the following article:
* https://chromatichq.com/insights/managing-large-menus-memory-usage-during-drupal-cache-clears
*/
/**
* Converts menu content links to the new format that avoids the need to rebuild
* them during a cache rebuild.
*
* @see https://www.drupal.org/project/drupal/issues/2417423
*/
function example_module_update_8010() {
$menu_link_content_storage = \Drupal::service('entity_type.manager')
->getStorage('menu_link_content');
// Get a list of all menu link content items with an `internal:/node` URI.
/** @var \Drupal\Core\Entity\Query\QueryInterface $query */
$query = $menu_link_content_storage->getQuery();
$query->condition('link.uri', 'internal:/node/%', 'LIKE');
$results = $query->execute();
// Loop through the items and adapt them to the new entity format.
foreach ($results as $entity_id) {
/** @var \Drupal\menu_link_content\Entity\MenuLinkContent $menu_link_content_entity */
$menu_link_content_entity = $menu_link_content_storage->load($entity_id);
// Get the current link URI.
$link_uri = $menu_link_content_entity->get('link')->uri;
// Check for invalid paths.
if ($link_uri == 'internal:/node/') {
\Drupal::logger('example_module')->warning('Unable to convert %uri for link %title.', [
'%uri' => $link_uri,
'%title' => $menu_link_content_entity->getTitle(),
]);
continue;
}
// Convert "internal:/node/123" to "entity:node/123".
$link_uri_new = str_replace('internal:/', 'entity:', $link_uri);
// Save the changes.
$menu_link_content_entity->set('link', [['uri' => $link_uri_new]]);
$menu_link_content_entity->save();
}
}
/**
* Converts internal alias menu content links to entity links where possible.
*/
function example_module_update_8011() {
$menu_link_content_storage = \Drupal::service('entity_type.manager')
->getStorage('menu_link_content');
// Get a list of all menu link content items with an `internal:/` URI.
/** @var \Drupal\Core\Entity\Query\QueryInterface $query */
$query = $menu_link_content_storage->getQuery();
$query->condition('link.uri', 'internal:/%', 'LIKE');
$results = $query->execute();
// Loop through the items and adapt them to the new entity format.
foreach ($results as $entity_id) {
/** @var \Drupal\menu_link_content\Entity\MenuLinkContent $menu_link_content_entity */
$menu_link_content_entity = $menu_link_content_storage->load($entity_id);
// Get the current link URI.
$link_uri = $menu_link_content_entity->get('link')->uri;
/** @var \Drupal\path_alias\AliasManager $alias_manager */
$alias_manager = \Drupal::service('path_alias.manager');
$link_alias = str_replace('internal:', '', $link_uri);
$link_path = $alias_manager->getPathByAlias($link_alias);
// Some paths are not associated with an entity and should be skipped.
if ($link_alias == $link_path) {
\Drupal::logger('example_module')->warning('Unable to find internal path for %uri for link %title.', [
'%uri' => $link_uri,
'%title' => $menu_link_content_entity->getTitle(),
]);
continue;
}
// Build the new path with the entity format.
$link_uri_new = sprintf('entity:%s', trim($link_path, '/'));
// Save the changes.
$menu_link_content_entity->set('link', [['uri' => $link_uri_new]]);
$menu_link_content_entity->save();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment