it-swarm.com.de

So aktualisieren Sie ein Feld in der Entität menu_link_content (hinzugefügt mit dem Modul menu_item_extras) aus dem Knotenformular

Ich habe ein Kontrollkästchen zu einem der Menüs mit dem Modul Menüelement Extras hinzugefügt. Standardmäßig ist das Kontrollkästchen aktiviert und funktioniert wie erwartet, wenn ich einen Menüpunkt über die Benutzeroberfläche des Menüadministrators erstelle. Wenn ich jedoch einen Menüpunkt über einen Knoten erstelle, erhält das Feld nicht das Standardverhalten (Kontrollkästchen aktiviert). Ich habe auch die Tabelle überprüft (menu_link_content__[field_name]) und es gibt keinen Eintrag für den über node/add bilden.

2
vijaycs85

Hier gibt es einige Probleme:

  1. In der Knotenform sind die Menüfelder fest codiert. Weitere Informationen finden Sie unter menu_ui_form_node_form_alter() und menu_ui_form_node_form_submit().

  2. Es stellt sich heraus, dass die Hauptursache für das Feldproblem darin besteht, dass das Modul Menu Item Extras Den Bundle-Wert auf den Menünamen aktualisiert, der beim pre_save-Hook der Entität menu_link_content auftritt. Ohne menu_name als Bundle wären der Entität keine Felder zugeordnet.

Eine Möglichkeit, dieses Problem zu lösen, besteht darin, einen hook_form_node_form_alter() - Hook zu implementieren und die Bundle-Details zu aktualisieren, bevor Sie versuchen, das benutzerdefinierte Feld zu aktualisieren. Hier ist der Code:

1. mymodule/mymodule.module


/**
 * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
 */
function mymodule_form_node_form_alter(&$form, FormStateInterface $form_state) {
  foreach (array_keys($form['actions']) as $action) {
    if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
      $form['actions'][$action]['#submit'][] = [
        \Drupal::service('mymodule.menu_link_content_helper'),
        'nodeSubmit',
      ];
    }
  }
}

2. mymodule/src/MenuLinkContentService.php

<?php

namespace Drupal\mymodule\Services;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\menu_link_content\Entity\MenuLinkContent;

/**
 * Class MenuLinkContentService
 *
 * @package Drupal\mymodule\Service
 */
class MenuLinkContentService  {

  /**
   * Entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * MenuLinkContentHelper constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   */
  public function __construct(EntityTypeManagerInterface $entityTypeManager) {
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * Form submission handler for menu item field on the node form.
   *
   * @param array $form
   *   Form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   Form state object.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function nodeSubmit(array $form, FormStateInterface $form_state) {
    if (!$form_state->isValueEmpty('menu')) {
      $values = $form_state->getValue('menu');
      if (!empty($values['entity_id'])) {
        // There is no bundle by default for menu_link_content entity.
        $menu_name = 'menu_link_content';
        if (!empty($values['menu_parent'])) {
          list($menu_name) = explode(':', $values['menu_parent'], 2);
        }
        $entity = $this->nodeSaveMenuLinkContent($values['entity_id'], $menu_name);
        // If no  menu item with given bundle, load and update bundle.
        if (!$entity) {
          $entity = MenuLinkContent::load($values['entity_id']);
          $entity->set('bundle', $menu_name)->save();
          $this->nodeSaveMenuLinkContent($entity->id(), $menu_name);
        }
      }
    }
  }

  /**
   * Updates additional field on menu link content entity.
   *
   * @param int $entity_id
   *   Entity ID.
   * @param string $menu_name
   *   Menu name.
   *
   * @return \Drupal\Core\Entity\EntityInterface|mixed|null
   *   An Entity. NULL, if no entity with given ID and bundle found.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  protected function nodeSaveMenuLinkContent($entity_id, $menu_name) {
    $storage = $this->entityTypeManager->getStorage('menu_link_content');
    // Using loadByProperties() as loading without bundle wouldn't bring the
    // custom field.
    $entities = $storage->loadByProperties([
      'bundle' => $menu_name,
      'id' => $entity_id,
    ]);
    $entity = reset($entities);
    if ($entity) {
      $entity->set('field_searchable', TRUE);
      $entity->save();
      return $entity;
    }
    else {
      return NULL;
    }
  }

}

Hinweis: Mein Kontrollkästchen ist field_searchable.

2
vijaycs85