improvements-2.x-dev/modules/improvements_menu/improvements_menu.link_advanced_settings.inc

modules/improvements_menu/improvements_menu.link_advanced_settings.inc
<?php

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Menu\MenuLinkInterface;
use Drupal\Core\Render\Element\Checkboxes;
use Drupal\Core\Url;
use Drupal\druhels\DrupalHelper;
use Drupal\menu_link_content\Form\MenuLinkContentForm;
use Drupal\menu_link_content\MenuLinkContentInterface;
use Drupal\menu_ui\Form\MenuLinkEditForm;
use Drupal\menu_ui\MenuForm;
use Drupal\system\Entity\Menu;
use Drupal\system\MenuInterface;

/**
 * Add advanced settings to menu link form.
 */
function improvements_menu_link_advanced_settings_form_alter(array &$form, FormStateInterface $form_state): void {
  $form_object = $form_state->getFormObject();

  if ($form_object instanceof MenuLinkContentForm) {
    $menu_link = $form_object->getEntity(); /** @var MenuLinkContentInterface $menu_link */
  }
  elseif ($form_object instanceof MenuLinkEditForm) {
    $menu_link = $form_state->getBuildInfo()['args'][0]; /** @var MenuLinkInterface $menu_link */
  }
  else {
    return;
  }

  $menu_link_advanced_options = improvements_menu_get_menu_link_advanced_options($menu_link);

  $form['advanced'] = [
    '#type' => 'details',
    '#title' => t('Advanced settings'),
    '#weight' => 20,
  ];

  $form['advanced'] += \Drupal::moduleHandler()->invokeAll('menu_link_third_party_settings_form', [$menu_link, $menu_link_advanced_options]);

  $form_state->set('menu_link', $menu_link);

  // Content menu link
  if ($menu_link instanceof MenuLinkContentInterface) {
    $form['actions']['submit']['#submit'][] = 'improvements_menu_link_form_advanced_settings_submit';
  }
  // Module menu link
  else {
    $form['#submit'][] = 'improvements_menu_link_form_advanced_settings_submit';
  }
}

/**
 * Return menu link advanced options.
 */
function improvements_menu_get_menu_link_advanced_options(MenuLinkContentInterface|MenuLinkInterface $menu_link, array $menu_links_advanced_options = NULL): array {
  if ($menu_links_advanced_options === NULL) {
    $menu = Menu::load($menu_link->getMenuName()); /** @var MenuInterface $menu */
    $menu_links_advanced_options = $menu->getThirdPartySetting('improvements', 'links_options', []);
  }

  $menu_link_options_key = str_replace('.', '_', $menu_link->getPluginId());
  return $menu_links_advanced_options[$menu_link_options_key] ?? [];
}

/**
 * Implements hook_menu_link_third_party_settings_form().
 *
 * @see improvements_menu_link_advanced_settings_form_alter()
 */
function improvements_menu_menu_link_third_party_settings_form($menu_link, array $menu_link_advanced_options): array {
  $form['open_in_dialog'] = [
    '#type' => 'checkbox',
    '#title' => t('Open in dialog'),
    '#default_value' => $menu_link_advanced_options['open_in_dialog'] ?? FALSE,
  ];

  $form['hide_href'] = [
    '#type' => 'checkbox',
    '#title' => t('Hide href attribute'),
    '#default_value' => $menu_link_advanced_options['hide_href'] ?? FALSE,
    '#states' => [
      'visible' => [
        ':input[name="open_in_dialog"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];

  $form['target_blank'] = [
    '#type' => 'checkbox',
    '#title' => t('Open in new tab'),
    '#default_value' => $menu_link_advanced_options['target_blank'] ?? FALSE,
  ];

  $form['item_class'] = [
    '#type' => 'textfield',
    '#title' => t('Item class'),
    '#default_value' => $menu_link_advanced_options['item_class'] ?? '',
  ];

  $form['link_class'] = [
    '#type' => 'textfield',
    '#title' => t('Link class'),
    '#default_value' => $menu_link_advanced_options['link_class'] ?? '',
  ];

  $language_filter_options = [];
  foreach (\Drupal::languageManager()->getLanguages() as $language) {
    $language_filter_options[$language->getId()] = $language->getName();
  }

  $form['language_filter'] = [
    '#type' => 'checkboxes',
    '#title' => t('Language'),
    '#description' => t('Show menu item only for checked langauges'),
    '#options' => $language_filter_options,
    '#default_value' => $menu_link_advanced_options['language_filter'] ?? [],
  ];

  return $form;
}

/**
 * Menu link form submit callback.
 */
function improvements_menu_link_form_advanced_settings_submit(array &$form, FormStateInterface $form_state): void {
  // Save advanced options
  $menu_link = $form_state->get('menu_link'); /** @var MenuLinkContentInterface|MenuLinkInterface $menu_link */
  $menu_link_advanced_options = \Drupal::moduleHandler()->invokeAll('menu_link_third_party_settings_form_submit', [$menu_link, $form_state]);
  improvements_menu_save_menu_link_advanced_options($menu_link, $menu_link_advanced_options);
}

/**
 * Implements hook_menu_link_third_party_settings_form_submit().
 *
 * @see improvements_menu_link_form_advanced_settings_submit()
 */
function improvements_menu_link_third_party_settings_form_submit($menu_link, FormStateInterface $form_state): array {
  $menu_link_advanced_options = [];

  if ($form_state->getValue('open_in_dialog')) {
    $menu_link_advanced_options['open_in_dialog'] = TRUE;
  }
  if ($form_state->getValue('hide_href')) {
    $menu_link_advanced_options['hide_href'] = TRUE;
  }
  if ($form_state->getValue('target_blank')) {
    $menu_link_advanced_options['target_blank'] = TRUE;
  }
  if ($item_class = $form_state->getValue('item_class')) {
    $menu_link_advanced_options['item_class'] = $item_class;
  }
  if ($link_class = $form_state->getValue('link_class')) {
    $menu_link_advanced_options['link_class'] = $link_class;
  }
  if ($language_filter = $form_state->getValue('language_filter')) {
    $menu_link_advanced_options['language_filter'] = Checkboxes::getCheckedCheckboxes($language_filter);
  }

  return $menu_link_advanced_options;
}

/**
 * Save menu links advanced options.
 *
 * @param MenuLinkContentInterface|MenuLinkInterface $menu_link
 * @param array|null $menu_link_advanced_options
 */
function improvements_menu_save_menu_link_advanced_options($menu_link, array $menu_link_advanced_options = []): void {
  $menu = Menu::load($menu_link->getMenuName()); /** @var MenuInterface $menu */
  $menu_link_id = $menu_link->getPluginId();
  $menu_link_key = str_replace('.', '_', $menu_link_id);
  $menu_links_advanced_options = $menu->getThirdPartySetting('improvements', 'links_options', []);

  if ($menu_link_advanced_options) {
    $menu_links_advanced_options[$menu_link_key] = $menu_link_advanced_options;
  }
  elseif (isset($menu_links_advanced_options[$menu_link_key])) {
    unset($menu_links_advanced_options[$menu_link_key]);
  }

  $menu->setThirdPartySetting('improvements', 'links_options', $menu_links_advanced_options);
  $menu->save();
}

/**
 * Implements hook_ENTITY_TYPE_delete(): menu_link_content.
 */
function improvements_menu_link_content_delete(MenuLinkContentInterface $menu_link): void {
  improvements_menu_save_menu_link_advanced_options($menu_link);
}

/**
 * Preprocess menu item.
 *
 * @see improvements_preprocess_menu_items()
 */
function improvements_menu_link_advanced_settings_preprocess_menu_item(array &$menu_item, array &$menu_vars, array $menu_links_advanced_options): void {
  $menu_link = $menu_item['original_link']; /** @var MenuLinkContentInterface|MenuLinkInterface $menu_link */
  $menu_link_advanced_options = improvements_menu_get_menu_link_advanced_options($menu_link, $menu_links_advanced_options);
  $menu_item_url = $menu_item['url']; /** @var Url $menu_item_url */
  $menu_link_attributes = [];

  if (!$menu_link_advanced_options) {
    return;
  }

  // Option "Language"
  if (!empty($menu_link_advanced_options['language_filter'])) {
    if (!in_array(DrupalHelper::getCurrentLangcode(), $menu_link_advanced_options['language_filter'], TRUE)) {
      $menu_item['access'] = FALSE;
      return;
    }
  }
  // Option "Open in dialog"
  if (!empty($menu_link_advanced_options['open_in_dialog'])) {
    $menu_link_attributes['class'][] = 'use-ajax';
    $menu_link_attributes['data-dialog-type'] = 'modal';
    $menu_vars['#attached']['library'][] = 'core/drupal.ajax';
  }
  // Option "Hide href attribute"
  if (!empty($menu_link_advanced_options['hide_href'])) {
    $menu_link_attributes['data-ajax-url'] = $menu_item_url->toString();

    // Replace url
    $new_menu_item_url = Url::fromUri('internal:#<none>');
    $new_menu_item_url->setOption('attributes', $menu_item_url->getOption('attributes'));
    $menu_item['url'] = $new_menu_item_url;
    $menu_item_url = $menu_item['url'];
  }
  // Option "Target blank"
  if (!empty($menu_link_advanced_options['target_blank'])) {
    $menu_link_attributes['target'] = '_blank';
  }
  // Option "Item class"
  if (!empty($menu_link_advanced_options['item_class'])) {
    $menu_item['attributes']->addClass($menu_link_advanced_options['item_class']);
  }
  // Option "Link class"
  if (!empty($menu_link_advanced_options['link_class'])) {
    $menu_link_attributes['class'][] = $menu_link_advanced_options['link_class'];
  }

  // Merge url attributes
  if ($menu_link_attributes) {
    $menu_item_url->mergeOptions(['attributes' => $menu_link_attributes]);
  }

  $menu_item['advanced_options'] = $menu_link_advanced_options;
}

/**
 * Implements hook_form_FORM_ID_alter(): menu_edit_form.
 *
 * @see improvements_form_menu_edit_form_alter()
 */
function improvements_menu_link_advanced_form_menu_edit_form_alter(array &$form, FormStateInterface $form_state): void {
  $form['#entity_builders'][] = 'improvements_menu_link_advanced_menu_edit_form_entity_builder';
}

/**
 * Menu form #entity_builders callback.
 *
 * @see improvements_menu_link_advanced_form_menu_edit_form_alter()
 */
function improvements_menu_link_advanced_menu_edit_form_entity_builder(string $entity_type, MenuInterface $menu, array &$form, FormStateInterface $form_state): void {
  // Fix bug when other modules remove all third_party_settings data
  if ($form_state->hasValue('third_party_settings')) {
    $menu_form_object = $form_state->getFormObject(); /** @var MenuForm $menu_form_object */
    $old_menu = $menu_form_object->getEntity(); /** @var MenuInterface $old_menu */
    $menu_improvements_module_third_party_settings = $old_menu->getThirdPartySettings('improvements');

    foreach ($menu_improvements_module_third_party_settings as $setting_name => $setting_value) {
      $menu->setThirdPartySetting('improvements', $setting_name, $setting_value);
    }
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc