class MenuLinksController in Structure Sync 8
Same name and namespace in other branches
- 2.x src/Controller/MenuLinksController.php \Drupal\structure_sync\Controller\MenuLinksController
Controller for syncing menu links.
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\structure_sync\Controller\MenuLinksController
Expanded class hierarchy of MenuLinksController
1 file declares its use of MenuLinksController
File
- src/
Controller/ MenuLinksController.php, line 13
Namespace
Drupal\structure_sync\ControllerView source
class MenuLinksController extends ControllerBase {
private $config;
/**
* Constructor for menu links controller.
*/
public function __construct() {
$this->config = $this
->getEditableConfig();
$this
->entityTypeManager();
}
/**
* Gets the editable version of the config.
*/
private function getEditableConfig() {
$this
->config('structure_sync.data');
return $this->configFactory
->getEditable('structure_sync.data');
}
/**
* Function to export menu links.
*/
public function exportMenuLinks(array $form = NULL, FormStateInterface $form_state = NULL) {
StructureSyncHelper::logMessage('Menu links export started');
if (is_object($form_state) && $form_state
->hasValue('export_menu_list')) {
$menu_list = $form_state
->getValue('export_menu_list');
$menu_list = array_filter($menu_list, 'is_string');
}
$this->config
->clear('menus')
->save();
if (isset($menu_list)) {
$menuLinks = [];
foreach ($menu_list as $menu_name) {
$menuLinks = array_merge($this->entityTypeManager
->getStorage('menu_link_content')
->loadByProperties([
'menu_name' => $menu_name,
]), $menuLinks);
}
}
else {
$menuLinks = $this
->entityTypeManager()
->getStorage('menu_link_content')
->loadMultiple();
}
$customMenuLinks = [];
foreach ($menuLinks as $menuLink) {
$customMenuLinks[] = [
'menu_name' => $menuLink->menu_name->value,
'title' => $menuLink->title->value,
'parent' => $menuLink->parent->value,
'uri' => $menuLink->link->uri,
'link_title' => $menuLink->link->title,
'description' => $menuLink->description->value,
'enabled' => $menuLink->enabled->value,
'expanded' => $menuLink->expanded->value,
'weight' => $menuLink->weight->value,
'langcode' => $menuLink->langcode->value,
'uuid' => $menuLink
->uuid(),
];
if (array_key_exists('drush', $form) && $form['drush'] === TRUE) {
drush_log('Exported "' . $menuLink->title
->getValue()[0]['value'] . '" of menu "' . $menuLink->menu_name
->getValue()[0]['value'] . '"', 'ok');
}
StructureSyncHelper::logMessage('Exported "' . $menuLink->title->value . '" of menu "' . $menuLink->menu_name->value . '"');
}
$this->config
->set('menus', $customMenuLinks)
->save();
drupal_set_message($this
->t('The menu links have been successfully exported.'));
StructureSyncHelper::logMessage('Menu links exported');
}
/**
* Function to import menu links.
*
* When this function is used without the designated form, you should assign
* an array with a key value pair for form with key 'style' and value 'full',
* 'safe' or 'force' to apply that import style.
*/
public function importMenuLinks(array $form, FormStateInterface $form_state = NULL) {
StructureSyncHelper::logMessage('Menu links import started');
// Check if the there is a selection made in a form for what menus need to
// be imported.
if (is_object($form_state) && $form_state
->hasValue('import_menu_list')) {
$menusSelected = $form_state
->getValue('import_menu_list');
$menusSelected = array_filter($menusSelected, 'is_string');
}
if (array_key_exists('style', $form)) {
$style = $form['style'];
}
else {
StructureSyncHelper::logMessage('No style defined on menu links import', 'error');
return;
}
StructureSyncHelper::logMessage('Using "' . $style . '" style for menu links import');
// Get menu links from config.
$menusConfig = $this->config
->get('menus');
$menus = [];
if (isset($menusSelected)) {
foreach ($menusConfig as $menu) {
if (in_array($menu['menu_name'], array_keys($menusSelected))) {
$menus[] = $menu;
}
}
}
else {
$menus = $menusConfig;
}
if (array_key_exists('drush', $form) && $form['drush'] === TRUE) {
$context = [];
$context['drush'] = TRUE;
switch ($style) {
case 'full':
self::deleteDeletedMenuLinks($menus, $context);
self::importMenuLinksFull($menus, $context);
self::menuLinksImportFinishedCallback(NULL, NULL, NULL);
break;
case 'safe':
self::importMenuLinksSafe($menus, $context);
self::menuLinksImportFinishedCallback(NULL, NULL, NULL);
break;
case 'force':
self::deleteMenuLinks($context);
self::importMenuLinksForce($menus, $context);
self::menuLinksImportFinishedCallback(NULL, NULL, NULL);
break;
}
return;
}
// Import the menu links with the chosen style of importing.
switch ($style) {
case 'full':
$batch = [
'title' => $this
->t('Importing menu links...'),
'operations' => [
[
'\\Drupal\\structure_sync\\Controller\\MenuLinksController::deleteDeletedMenuLinks',
[
$menus,
],
],
[
'\\Drupal\\structure_sync\\Controller\\MenuLinksController::importMenuLinksFull',
[
$menus,
],
],
],
'finished' => '\\Drupal\\structure_sync\\Controller\\MenuLinksController::menuLinksImportFinishedCallback',
];
batch_set($batch);
break;
case 'safe':
$batch = [
'title' => $this
->t('Importing menu links...'),
'operations' => [
[
'\\Drupal\\structure_sync\\Controller\\MenuLinksController::importMenuLinksSafe',
[
$menus,
],
],
],
'finished' => '\\Drupal\\structure_sync\\Controller\\MenuLinksController::menuLinksImportFinishedCallback',
];
batch_set($batch);
break;
case 'force':
$batch = [
'title' => $this
->t('Importing menu links...'),
'operations' => [
[
'\\Drupal\\structure_sync\\Controller\\MenuLinksController::deleteMenuLinks',
[],
],
[
'\\Drupal\\structure_sync\\Controller\\MenuLinksController::importMenuLinksForce',
[
$menus,
],
],
],
'finished' => '\\Drupal\\structure_sync\\Controller\\MenuLinksController::menuLinksImportFinishedCallback',
];
batch_set($batch);
break;
default:
StructureSyncHelper::logMessage('Style not recognized', 'error');
break;
}
}
/**
* Function to delete the menu links that should be removed in this import.
*/
public static function deleteDeletedMenuLinks($menus, &$context) {
$uuidsInConfig = [];
foreach ($menus as $menuLink) {
$uuidsInConfig[] = $menuLink['uuid'];
}
if (!empty($uuidsInConfig)) {
$query = StructureSyncHelper::getEntityQuery('menu_link_content');
$query
->condition('uuid', $uuidsInConfig, 'NOT IN');
$ids = $query
->execute();
$controller = StructureSyncHelper::getEntityManager()
->getStorage('menu_link_content');
$entities = $controller
->loadMultiple($ids);
$controller
->delete($entities);
}
if (array_key_exists('drush', $context) && $context['drush'] === TRUE) {
drush_log('Deleted menu links that were not in config', 'ok');
}
StructureSyncHelper::logMessage('Deleted menu links that were not in config');
}
/**
* Function to fully import the menu links.
*
* Basically a safe import with update actions for already existing menu
* links.
*/
public static function importMenuLinksFull($menus, &$context) {
$uuidsInConfig = [];
foreach ($menus as $menuLink) {
$uuidsInConfig[] = $menuLink['uuid'];
}
$entities = [];
if (!empty($uuidsInConfig)) {
$query = StructureSyncHelper::getEntityQuery('menu_link_content');
$query
->condition('uuid', $uuidsInConfig, 'IN');
$ids = $query
->execute();
$controller = StructureSyncHelper::getEntityManager()
->getStorage('menu_link_content');
$entities = $controller
->loadMultiple($ids);
}
$parents = array_column($menus, 'parent');
foreach ($parents as &$parent) {
if (!is_null($parent)) {
if (($pos = strpos($parent, ":")) !== FALSE) {
$parent = substr($parent, $pos + 1);
}
else {
$parent = NULL;
}
}
}
$idsDone = [];
$idsLeft = [];
$firstRun = TRUE;
$context['sandbox']['max'] = count($menus);
$context['sandbox']['progress'] = 0;
while ($firstRun || count($idsLeft) > 0) {
foreach ($menus as $menuLink) {
$query = StructureSyncHelper::getEntityQuery('menu_link_content');
$query
->condition('uuid', $menuLink['uuid']);
$ids = $query
->execute();
$currentParent = $menuLink['parent'];
if (!is_null($currentParent)) {
if (($pos = strpos($currentParent, ":")) !== FALSE) {
$currentParent = substr($currentParent, $pos + 1);
}
}
if (!in_array($menuLink['uuid'], $idsDone) && ($menuLink['parent'] === NULL || !in_array($menuLink['parent'], $parents) || in_array($currentParent, $idsDone))) {
if (count($ids) <= 0) {
MenuLinkContent::create([
'title' => $menuLink['title'],
'link' => [
'uri' => $menuLink['uri'],
'title' => $menuLink['link_title'],
],
'menu_name' => $menuLink['menu_name'],
'expanded' => $menuLink['expanded'] === '1' ? TRUE : FALSE,
'enabled' => $menuLink['enabled'] === '1' ? TRUE : FALSE,
'parent' => $menuLink['parent'],
'description' => $menuLink['description'],
'weight' => $menuLink['weight'],
'langcode' => $menuLink['langcode'],
'uuid' => $menuLink['uuid'],
])
->save();
}
else {
foreach ($entities as $entity) {
if ($menuLink['uuid'] === $entity
->uuid()) {
$customMenuLink = MenuLinkContent::load($entity
->id());
if (!empty($customMenuLink)) {
$customMenuLink
->set('title', $menuLink['title'])
->set('link', [
'uri' => $menuLink['uri'],
'title' => $menuLink['link_title'],
])
->set('expanded', $menuLink['expanded'] === '1' ? TRUE : FALSE)
->set('enabled', $menuLink['enabled'] === '1' ? TRUE : FALSE)
->set('parent', $menuLink['parent'])
->set('description', $menuLink['description'])
->set('weight', $menuLink['weight'])
->save();
}
break;
}
}
}
$idsDone[] = $menuLink['uuid'];
if (in_array($menuLink['uuid'], $idsLeft)) {
unset($idsLeft[$menuLink['uuid']]);
}
if (array_key_exists('drush', $context) && $context['drush'] === TRUE) {
drush_log('Imported "' . $menuLink['title'] . '" into ' . $menuLink['menu_name'], 'ok');
}
StructureSyncHelper::logMessage('Imported "' . $menuLink['title'] . '" into ' . $menuLink['menu_name']);
$context['sandbox']['progress']++;
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
else {
$idsLeft[$menuLink['uuid']] = $menuLink['uuid'];
}
}
$firstRun = FALSE;
}
$context['finished'] = 1;
}
/**
* Function to import menu links safe (only adding what isn't already there).
*/
public static function importMenuLinksSafe($menus, &$context) {
$menusFiltered = $menus;
$entities = StructureSyncHelper::getEntityManager()
->getStorage('menu_link_content')
->loadMultiple();
foreach ($entities as $entity) {
for ($i = 0; $i < count($menus); $i++) {
if ($entity
->uuid() === $menus[$i]['uuid']) {
unset($menusFiltered[$i]);
}
}
}
foreach ($menusFiltered as $menuLink) {
MenuLinkContent::create([
'title' => $menuLink['title'],
'link' => [
'uri' => $menuLink['uri'],
'title' => $menuLink['link_title'],
],
'menu_name' => $menuLink['menu_name'],
'expanded' => $menuLink['expanded'] === '1' ? TRUE : FALSE,
'enabled' => $menuLink['enabled'] === '1' ? TRUE : FALSE,
'parent' => $menuLink['parent'],
'description' => $menuLink['description'],
'weight' => $menuLink['weight'],
'langcode' => $menuLink['langcode'],
'uuid' => $menuLink['uuid'],
])
->save();
if (array_key_exists('drush', $context) && $context['drush'] === TRUE) {
drush_log('Imported "' . $menuLink['title'] . '" into "' . $menuLink['menu_name'] . '" menu', 'ok');
}
StructureSyncHelper::logMessage('Imported "' . $menuLink['title'] . '" into "' . $menuLink['menu_name'] . '" menu');
}
}
/**
* Function to delete all menu links.
*/
public static function deleteMenuLinks(&$context) {
$entities = StructureSyncHelper::getEntityManager()
->getStorage('menu_link_content')
->loadMultiple();
StructureSyncHelper::getEntityManager()
->getStorage('menu_link_content')
->delete($entities);
if (array_key_exists('drush', $context) && $context['drush'] === TRUE) {
drush_log('Deleted all (content) menu links', 'ok');
}
StructureSyncHelper::logMessage('Deleted all (content) menu links');
}
/**
* Function to import (create) all menu links that need to be imported.
*/
public static function importMenuLinksForce($menus, &$context) {
foreach ($menus as $menuLink) {
MenuLinkContent::create([
'title' => $menuLink['title'],
'link' => [
'uri' => $menuLink['uri'],
'title' => $menuLink['link_title'],
],
'menu_name' => $menuLink['menu_name'],
'expanded' => $menuLink['expanded'] === '1' ? TRUE : FALSE,
'enabled' => $menuLink['enabled'] === '1' ? TRUE : FALSE,
'parent' => $menuLink['parent'],
'description' => $menuLink['description'],
'weight' => $menuLink['weight'],
'langcode' => $menuLink['langcode'],
'uuid' => $menuLink['uuid'],
])
->save();
if (array_key_exists('drush', $context) && $context['drush'] === TRUE) {
drush_log('Imported "' . $menuLink['title'] . '" into "' . $menuLink['menu_name'] . '" menu', 'ok');
}
StructureSyncHelper::logMessage('Imported "' . $menuLink['title'] . '" into "' . $menuLink['menu_name'] . '" menu');
}
}
/**
* Function that signals that the import of menu links has finished.
*/
public static function menuLinksImportFinishedCallback($success, $results, $operations) {
StructureSyncHelper::logMessage('Flushing all caches');
drupal_flush_all_caches();
StructureSyncHelper::logMessage('Successfully flushed caches');
StructureSyncHelper::logMessage('Successfully imported menu links');
drupal_set_message(t('Successfully imported menu links'));
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ControllerBase:: |
protected | property | The configuration factory. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity manager. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The module handler. | 2 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
public static | function |
Instantiates a new instance of this class. Overrides ContainerInjectionInterface:: |
40 |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity manager service. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
ControllerBase:: |
protected | function | Returns the state storage service. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MenuLinksController:: |
private | property | ||
MenuLinksController:: |
public static | function | Function to delete the menu links that should be removed in this import. | |
MenuLinksController:: |
public static | function | Function to delete all menu links. | |
MenuLinksController:: |
public | function | Function to export menu links. | |
MenuLinksController:: |
private | function | Gets the editable version of the config. | |
MenuLinksController:: |
public | function | Function to import menu links. | |
MenuLinksController:: |
public static | function | Function to import (create) all menu links that need to be imported. | |
MenuLinksController:: |
public static | function | Function to fully import the menu links. | |
MenuLinksController:: |
public static | function | Function to import menu links safe (only adding what isn't already there). | |
MenuLinksController:: |
public static | function | Function that signals that the import of menu links has finished. | |
MenuLinksController:: |
public | function | Constructor for menu links controller. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |