Skip to content
Snippets Groups Projects

Issue #3515114: Create a drush command for menu links importation

1 file
+ 200
0
Compare changes
  • Side-by-side
  • Inline
+ 200
0
<?php
declare(strict_types=1);
namespace Drupal\menu_export\Drush\Commands;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\menu_link_content\Entity\MenuLinkContent;
use Drupal\system\Entity\Menu;
use Drush\Attributes as CLI;
use Drush\Commands\AutowireTrait;
use Drush\Commands\DrushCommands;
/**
* A Drush commandfile for importing menus from Menu Export module.
*/
final class MenuImportCommands extends DrushCommands {
use AutowireTrait;
/**
* Constructs a MenuImportCommands object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The configuration factory service.
*/
public function __construct(
private readonly EntityTypeManagerInterface $entityTypeManager,
private readonly ConfigFactoryInterface $configFactory,
) {
parent::__construct();
}
/**
* Import menus from Menu Export configuration.
*/
#[CLI\Command(name: 'menu_export:menu-import', aliases: ['me-menu-import'])]
#[CLI\Usage(name: 'menu_export:menu-import', description: 'Import menus from Menu Export configuration.')]
public function importMenus(): void {
if (!$this->validateMenuExportConfig()) {
return;
}
$this->displayMenusTable();
$menu_links = $this->configFactory->get('menu_export.export_data')->get();
if (empty($menu_links)) {
$this->logger()->warning(dt('No menu links found to import.'));
return;
}
if (!$this->confirmImport(count($menu_links))) {
return;
}
$this->processMenuImport($menu_links);
}
/**
* Validates that Menu Export module is properly configured.
*
* @return bool
* TRUE if configuration is valid, FALSE otherwise.
*/
private function validateMenuExportConfig(): bool {
$menus = $this->configFactory->get('menu_export.settings')->get('menus');
if (empty($menus)) {
$this->logger()->warning(dt('No menus configured for export/import in Menu Export module.'));
return FALSE;
}
return TRUE;
}
/**
* Displays a table of menus configured for import.
*/
private function displayMenusTable(): void {
$menus = $this->configFactory->get('menu_export.settings')->get('menus');
$menu_entities = Menu::loadMultiple($menus);
$rows = [];
foreach ($menu_entities as $menu_name => $menu_entity) {
$rows[] = [
'name' => $menu_name,
'label' => $menu_entity->label(),
'description' => $menu_entity->getDescription(),
];
}
$this->io()->title(dt('Menus configured for import:'));
$this->io()->table(
['Machine Name', 'Label', 'Description'],
$rows
);
}
/**
* Asks for confirmation before proceeding with import.
*
* @param int $count
* The number of menu links to import.
*
* @return bool
* TRUE if confirmed, FALSE otherwise.
*/
private function confirmImport(int $count): bool {
return $this->io()->confirm(dt('Do you want to proceed with the import of @count menu links?', [
'@count' => $count,
]));
}
/**
* Process the menu links import.
*
* @param array $menu_links
* The menu links to import.
*/
private function processMenuImport(array $menu_links): void {
$import_count = 0;
$invalid_menus = [];
$total_links = count($menu_links);
// Set up progress bar.
$this->io()->title(dt('Importing menu links:'));
$progress_bar = $this->io()->createProgressBar($total_links);
$progress_bar->setFormat(
' %current%/%max% [%bar%] %percent:3s%% %message%'
);
$progress_bar->setMessage('Starting import...');
$progress_bar->start();
foreach ($menu_links as $menu) {
$menu_name = $menu['menu_name']['value'];
$progress_bar->setMessage("Processing link from menu '$menu_name'");
if (!$this->entityTypeManager->getStorage('menu')->load($menu_name)) {
$invalid_menus[] = $menu_name;
$progress_bar->advance();
continue;
}
unset($menu['id']);
unset($menu['revision_id']);
$menu_link_entity = \Drupal::entityQuery('menu_link_content')
->accessCheck(FALSE)
->condition('uuid', (!empty($menu['uuid']['value']) ? $menu['uuid']['value'] : $menu['uuid']))
->execute();
if (!$menu_link_entity) {
$menu_link_entity = MenuLinkContent::create();
}
else {
$menu_link_entity = MenuLinkContent::load(reset($menu_link_entity));
}
foreach ($menu as $field_name => $items) {
$menu_link_entity->set($field_name, $items);
}
$menu_link_entity->save();
$import_count++;
$progress_bar->advance();
}
$progress_bar->setMessage('Import completed');
$progress_bar->finish();
$this->io()->newLine(2);
$this->displayImportResults($import_count, $invalid_menus);
}
/**
* Displays import results.
*
* @param int $import_count
* The number of successfully imported menu links.
* @param array $invalid_menus
* The list of invalid menu names.
*/
private function displayImportResults(int $import_count, array $invalid_menus): void {
if (count($invalid_menus)) {
$this->logger()->warning(dt('Menu(s) not found: @menus', [
'@menus' => implode(', ', $invalid_menus),
]));
}
$this->logger()->success(dt('Successfully imported @count menu links.', [
'@count' => $import_count,
]));
}
}
Loading