taxonomy_menu_sync-1.0.4/taxonomy_menu_sync.module
taxonomy_menu_sync.module
<?php
/**
* @file
* This module create config for terms - menu sync.
*/
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\menu_link_content\Form\MenuLinkContentForm;
use Drupal\menu_link_content\Plugin\Menu\MenuLinkContent;
use Drupal\menu_ui\MenuForm;
/**
* Implements hook_help().
*/
function taxonomy_menu_sync_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.taxonomy_menu_sync':
$variables = [
':menu' => Url::fromRoute('taxonomy_menu_sync.settings')->toString(),
':collection' => Url::fromRoute('entity.taxonomy_menu_sync.collection')->toString(),
];
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The taxonomy menu sync module provide options to <a href=":menu">configure</a> dataset, which can be used to restrict update of menu item synced.', $variables) . '</p>';
$output .= '<p>' . t('This module also provide options to <a href=":collection">add</a> dataset, which will be used to sync taxonomy terms to menu.', $variables) . '</p>';
return $output;
}
}
/**
* Implements hook_form_alter().
*/
function taxonomy_menu_sync_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if ($form_id === 'menu_edit_form') {
/** @var \Drupal\menu_ui\MenuForm $form_object */
$form_object = $form_state->getFormObject();
if (!$form_object instanceof MenuForm) {
return;
}
$user_access = taxonomy_menu_sync_user_restrict();
$menu = $form_object->getEntity()->id();
$menu_content_ids = taxonomy_menu_sync_get_mapping($menu);
if (empty($menu_content_ids)) {
return;
}
$form['#attached']['library'][] = 'taxonomy_menu_sync/taxonomy_menu_sync.styling';
[$title_access, $parent_access, $delete_access] = taxonomy_menu_sync_get_config();
foreach ($form['links']['links'] as $key => &$link) {
if (str_contains($key, 'menu_plugin_id:menu_link_content:') && $link['#item']->link instanceof MenuLinkContent) {
$menu_content_id = $link['#item']->link->getEntity()->id();
if (!in_array($menu_content_id, $menu_content_ids)) {
continue;
}
if (!empty($link['title'][1]['#title'])) {
$attach_string = ' (auto-gen)';
$link['title'][1]['#suffix'] = isset($link['title'][1]['#suffix']) ? $link['title'][1]['#suffix'] . $attach_string : $attach_string;
}
if ($user_access) {
continue;
}
if ($parent_access) {
$link['#attributes']['class'][] = 'taxonomy-menu-sync-non-draggable';
}
if ($delete_access) {
unset($link['operations']['#links']['delete']);
}
}
}
}
if (str_contains($form_id, 'menu_link_content_')) {
/** @var \Drupal\menu_link_content\Form\MenuLinkContentForm $form_object */
$form_object = $form_state->getFormObject();
if (!$form_object instanceof MenuLinkContentForm || taxonomy_menu_sync_user_restrict()) {
return;
}
/** @var \Drupal\menu_link_content\MenuLinkContentInterface $menu_entity */
$menu_entity = $form_object->getEntity();
$menu_content_id = $menu_entity->id();
$menu = $menu_entity->getMenuName();
$menu_content_ids = taxonomy_menu_sync_get_mapping($menu);
if (!in_array($menu_content_id, $menu_content_ids)) {
return;
}
[$title_access, $parent_access, $delete_access] = taxonomy_menu_sync_get_config();
if ($title_access) {
$form['title']['#access'] = FALSE;
}
if ($parent_access) {
$form['menu_parent']['#access'] = FALSE;
}
if ($delete_access) {
$form['actions']['delete']['#access'] = FALSE;
}
}
}
/**
* Check whether user id is 1 or administrator.
*/
function taxonomy_menu_sync_user_restrict() {
$current_user = \Drupal::currentUser();
return $current_user->id() == 1 || in_array('administrator', $current_user->getRoles());
}
/**
* Lists of menu content ids associated with menu id.
*
* @param string $menu
* A string of menu machine name.
*
* @return array
* An array of menu content ids.
*
* @throws \Exception
*/
function taxonomy_menu_sync_get_mapping(string $menu) {
$mapping = [];
$select = \Drupal::database()->select('taxonomy_menu_sync', 'a')
->fields('a', ['mapping'])
->condition('target_menu', $menu)
->isNotNull('mapping')
->execute()->fetchCol();
foreach ($select as $item) {
if (!empty($json_data = json_decode($item, TRUE))) {
$mapping = array_merge($mapping, array_column($json_data, 'mlid'));
}
}
return array_unique($mapping);
}
/**
* Get taxonomy_menu_sync settings.
*/
function taxonomy_menu_sync_get_config() {
$taxonomy_menu_sync_config = &drupal_static(__FUNCTION__, []);
if (empty($taxonomy_menu_sync_config)) {
$config = \Drupal::config('taxonomy_menu_sync.settings');
$taxonomy_menu_sync_config = [
$config->get('disable_menu_title'),
$config->get('disable_menu_parent'),
$config->get('disable_menu_delete'),
];
}
return $taxonomy_menu_sync_config;
}
/**
* Implements hook_ENTITY_TYPE_delete().
*/
function taxonomy_menu_sync_taxonomy_menu_sync_delete(EntityInterface $entity) {
/** @var \Drupal\taxonomy_menu_sync\Entity\TaxonomyMenuSync $entity */
if (!empty($mappings = $entity->getMapping())) {
if (!empty($menu_ids = array_column($mappings, 'mlid'))) {
/** @var \Drupal\menu_link_content\MenuLinkContentStorageInterface $menu_link_storage */
$menu_link_storage = \Drupal::entityTypeManager()->getStorage('menu_link_content');
if (!empty($loaded_entities = $menu_link_storage->loadMultiple($menu_ids))) {
$menu_link_storage->delete($loaded_entities);
}
}
}
}
