You are here

class DefaultMenuLinkContentHandler in CMS Content Sync 8

Same name and namespace in other branches
  1. 2.1.x src/Plugin/cms_content_sync/entity_handler/DefaultMenuLinkContentHandler.php \Drupal\cms_content_sync\Plugin\cms_content_sync\entity_handler\DefaultMenuLinkContentHandler
  2. 2.0.x src/Plugin/cms_content_sync/entity_handler/DefaultMenuLinkContentHandler.php \Drupal\cms_content_sync\Plugin\cms_content_sync\entity_handler\DefaultMenuLinkContentHandler

Class DefaultMenuLinkContentHandler, providing a minimalistic implementation for menu items, making sure they're referenced correctly by UUID.

Plugin annotation


@EntityHandler(
  id = "cms_content_sync_default_menu_link_content_handler",
  label = @Translation("Default Menu Link Content"),
  weight = 100
)

Hierarchy

Expanded class hierarchy of DefaultMenuLinkContentHandler

File

src/Plugin/cms_content_sync/entity_handler/DefaultMenuLinkContentHandler.php, line 23

Namespace

Drupal\cms_content_sync\Plugin\cms_content_sync\entity_handler
View source
class DefaultMenuLinkContentHandler extends EntityHandlerBase {
  public const USER_REVISION_PROPERTY = 'revision_user';
  protected $resolveDependent;

  /**
   * {@inheritdoc}
   */
  public static function supports($entity_type, $bundle) {
    return 'menu_link_content' == $entity_type;
  }

  /**
   * {@inheritdoc}
   */
  public function getAllowedPreviewOptions() {
    return [
      'table' => 'Table',
    ];
  }

  /**
   * @param \EdgeBox\SyncCore\Interfaces\Configuration\IDefineEntityType $definition
   */
  public function updateEntityTypeDefinition(&$definition) {
    parent::updateEntityTypeDefinition($definition);
    $module_handler = \Drupal::service('module_handler');
    if ($module_handler
      ->moduleExists('menu_token')) {
      $definition
        ->addObjectProperty('menu_token_options', false);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getHandlerSettings($current_values, $type = 'both') {
    $menus = menu_ui_get_menus();
    return [
      'ignore_unpublished' => [
        '#type' => 'checkbox',
        '#title' => 'Ignore disabled',
        '#default_value' => isset($current_values['ignore_unpublished']) && 0 === $current_values['ignore_unpublished'] ? 0 : 1,
      ],
      'restrict_menus' => [
        '#type' => 'checkboxes',
        '#title' => 'Restrict to menus',
        '#default_value' => isset($current_values['restrict_menus']) ? $current_values['restrict_menus'] : [],
        '#options' => $menus,
        '#description' => t('When no checkbox is set, menu items from all menus will be pushed/pulled.'),
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function push(PushIntent $intent, EntityInterface $entity = null) {
    $result = parent::push($intent, $entity);
    if ($result && SyncIntent::ACTION_DELETE != $intent
      ->getAction()) {
      $module_handler = \Drupal::service('module_handler');
      if ($module_handler
        ->moduleExists('menu_token')) {
        $uuid = $intent
          ->getUuid();
        $config_menu = \Drupal::entityTypeManager()
          ->getStorage('link_configuration_storage')
          ->load($uuid);
        if (!empty($config_menu)) {
          $config_array = unserialize($config_menu
            ->get('configurationSerialized'));
          $intent
            ->setProperty('menu_token_options', $config_array);
        }
      }
    }
    return $result;
  }

  /**
   * {@inheritdoc}
   */
  public function ignorePull(PullIntent $intent) {
    $action = $intent
      ->getAction();
    if (SyncIntent::ACTION_DELETE == $action) {
      return parent::ignorePull($intent);
    }
    if (empty($this->resolveDependent)) {
      if (empty($intent
        ->getProperty('enabled'))) {
        $enabled = true;
      }
      else {
        $enabled = $intent
          ->getProperty('enabled')[0]['value'];
      }
    }
    else {
      $enabled = $this->resolveDependent['data']['enabled'];
    }

    // Not published? Ignore this revision then.
    if (!$enabled && $this->settings['handler_settings']['ignore_unpublished']) {

      // Unless it's a delete, then it won't have a status and is independent.
      return true;
    }
    if ($this
      ->shouldRestrictMenuUsage()) {
      $menu = $intent
        ->getProperty('menu_name')[0]['value'];
      if (empty($this->settings['handler_settings']['restrict_menus'][$menu])) {
        return true;
      }
    }
    return parent::ignorePull($intent);
  }

  /**
   * {@inheritdoc}
   */
  public function pull(PullIntent $intent) {
    $link = $intent
      ->getProperty('link');
    if (isset($link[0]['uri'])) {
      $uri = $link[0]['uri'];
      preg_match('@^internal:/([a-z_0-9]+)\\/([a-z0-9-]+)$@', $uri, $found);
      if (!empty($found)) {
        $referenced = \Drupal::service('entity.repository')
          ->loadEntityByUuid($found[1], $found[2]);
        if (!$referenced) {
          $this->resolveDependent = [
            Entity::ENTITY_TYPE_KEY => $found[1],
            Entity::UUID_KEY => $found[2],
            'data' => [
              'enabled' => (bool) $intent
                ->getProperty('enabled')[0]['value'],
            ],
          ];
          $intent
            ->overwriteProperty('enabled', [
            [
              'value' => 0,
            ],
          ]);
        }
      }
    }
    elseif (!empty($link[0][Entity::ENTITY_TYPE_KEY]) && !empty($link[0][Entity::UUID_KEY])) {
      $referenced = $intent
        ->loadEmbeddedEntity($link[0]);
      if (!$referenced) {
        $this->resolveDependent = array_merge($link[0], [
          'data' => [
            'enabled' => (bool) $intent
              ->getProperty('enabled')[0]['value'],
          ],
        ]);
        $intent
          ->overwriteProperty('enabled', [
          [
            'value' => 0,
          ],
        ]);
      }
    }
    if (!parent::pull($intent)) {
      return false;
    }
    if ($this->resolveDependent) {
      $intent
        ->saveUnresolvedDependency($this->resolveDependent, 'link', $this->resolveDependent['data']);
    }
    return true;
  }

  /**
   * {@inheritdoc}
   */
  public function ignorePush(PushIntent $intent) {

    /**
     * @var \Drupal\menu_link_content\Entity\MenuLinkContent $entity
     */
    $entity = $intent
      ->getEntity();
    if (!$entity
      ->isEnabled() && $this->settings['handler_settings']['ignore_unpublished']) {
      return true;
    }
    if ($this
      ->shouldRestrictMenuUsage()) {
      $menu = $entity
        ->getMenuName();
      if (empty($this->settings['handler_settings']['restrict_menus'][$menu])) {
        return true;
      }
    }
    $uri = $entity
      ->get('link')
      ->getValue()[0]['uri'];
    if ('entity:' == substr($uri, 0, 7)) {
      preg_match('/^entity:(.*)\\/(\\d*)$/', $uri, $found);

      // This means we're already dealing with a UUID that has not been resolved
      // locally yet. So there's no sense in pushing this back to the pool.
      if (empty($found)) {
        return true;
      }
      $link_entity_type = $found[1];
      $link_entity_id = $found[2];
      $entity_manager = \Drupal::entityTypeManager();
      $reference = $entity_manager
        ->getStorage($link_entity_type)
        ->load($link_entity_id);

      // Dead reference > ignore.
      if (empty($reference)) {
        return true;
      }
    }
    return parent::ignorePush($intent);
  }

  /**
   * {@inheritdoc}
   */
  protected function setEntityValues(PullIntent $intent, FieldableEntityInterface $entity = null) {
    $result = parent::setEntityValues($intent, $entity);
    if (SyncIntent::ACTION_DELETE != $intent
      ->getAction()) {
      $module_handler = \Drupal::service('module_handler');
      if ($module_handler
        ->moduleExists('menu_token')) {
        $config_array = $intent
          ->getProperty('menu_token_options');
        if (!empty($config_array)) {
          $uuid = $intent
            ->getUuid();
          $config_menu = \Drupal::entityTypeManager()
            ->getStorage('link_configuration_storage')
            ->load($uuid);
          if (empty($config_menu)) {
            $config_menu = \Drupal::entityTypeManager()
              ->getStorage('link_configuration_storage')
              ->create([
              'id' => $uuid,
              'label' => 'Menu token link configuration',
              'linkid' => (string) $intent
                ->getProperty('link')[0]['uri'],
              'configurationSerialized' => serialize($config_array),
            ]);
          }
          else {
            $config_menu
              ->set('linkid', (string) $intent
              ->getProperty('link')[0]['uri']);
            $config_menu
              ->set('configurationSerialized', serialize($config_array));
          }
          $config_menu
            ->save();
        }
      }
    }
    return $result;
  }
  protected function shouldRestrictMenuUsage() {
    return !empty(array_diff(array_values($this->settings['handler_settings']['restrict_menus']), [
      0,
    ]));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DefaultMenuLinkContentHandler::$resolveDependent protected property
DefaultMenuLinkContentHandler::getAllowedPreviewOptions public function Overrides EntityHandlerInterface::getAllowedPreviewOptions
DefaultMenuLinkContentHandler::getHandlerSettings public function Get the handler settings. Overrides EntityHandlerBase::getHandlerSettings
DefaultMenuLinkContentHandler::ignorePull public function Check if the pull should be ignored. Overrides EntityHandlerBase::ignorePull
DefaultMenuLinkContentHandler::ignorePush public function Check if the entity should not be ignored from the push. Overrides EntityHandlerBase::ignorePush
DefaultMenuLinkContentHandler::pull public function Pull the remote entity. Overrides EntityHandlerBase::pull
DefaultMenuLinkContentHandler::push public function Overrides EntityHandlerBase::push
DefaultMenuLinkContentHandler::setEntityValues protected function Set the values for the pulled entity. Overrides EntityHandlerBase::setEntityValues
DefaultMenuLinkContentHandler::shouldRestrictMenuUsage protected function
DefaultMenuLinkContentHandler::supports public static function Check if this handler supports the given entity type. Overrides EntityHandlerInterface::supports
DefaultMenuLinkContentHandler::updateEntityTypeDefinition public function Overrides EntityHandlerBase::updateEntityTypeDefinition
DefaultMenuLinkContentHandler::USER_REVISION_PROPERTY public constant Overrides EntityHandlerBase::USER_REVISION_PROPERTY
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
EntityHandlerBase::$bundleName protected property
EntityHandlerBase::$entityTypeName protected property
EntityHandlerBase::$flow protected property A sync instance.
EntityHandlerBase::$logger protected property A logger instance.
EntityHandlerBase::$settings protected property
EntityHandlerBase::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
EntityHandlerBase::createNew protected function 1
EntityHandlerBase::deleteEntity protected function Delete a entity.
EntityHandlerBase::getAllowedPullOptions public function Get the allowed pull options. Overrides EntityHandlerInterface::getAllowedPullOptions 2
EntityHandlerBase::getAllowedPushOptions public function Get the allowed push options. Overrides EntityHandlerInterface::getAllowedPushOptions 4
EntityHandlerBase::getForbiddenFields public function Provide a list of fields that are not allowed to be pushed or pulled. These fields typically contain all label fields that are pushed separately anyway (we don't want to set IDs and revision IDs of entities for example, but only use the UUID for… Overrides EntityHandlerInterface::getForbiddenFields 4
EntityHandlerBase::getStaticFields protected function Get a list of fields that can't be updated.
EntityHandlerBase::hasLabelProperty protected function Check whether the entity type supports having a label. 2
EntityHandlerBase::isEntityTypeTranslatable protected function
EntityHandlerBase::pushReferencedMenuItems protected function Whether or not menu item references should be pushed.
EntityHandlerBase::REVISION_TRANSLATION_AFFECTED_PROPERTY public constant 2
EntityHandlerBase::saveEntity protected function 1
EntityHandlerBase::setSourceUrl protected function
EntityHandlerBase::USER_PROPERTY public constant 2
EntityHandlerBase::validateHandlerSettings public function Validate the settings defined above. $form and $form_state are the same as in the Form API. $settings_key is the index at $form['sync_entities'] for this handler instance. Overrides EntityHandlerInterface::validateHandlerSettings
EntityHandlerBase::__construct public function Constructs a Drupal\rest\Plugin\ResourceBase object. Overrides PluginBase::__construct
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.