class DomainMenuLinkTreeManipulators in Domain Menu Access 8
Provides a couple of menu link tree manipulators.
This class provides menu link tree manipulators to:
- apply unmatching domain restriction
 
Hierarchy
- class \Drupal\domain_menu_access\Menu\DomainMenuLinkTreeManipulators
 
Expanded class hierarchy of DomainMenuLinkTreeManipulators
1 string reference to 'DomainMenuLinkTreeManipulators'
1 service uses DomainMenuLinkTreeManipulators
File
- src/
Menu/ DomainMenuLinkTreeManipulators.php, line 21  
Namespace
Drupal\domain_menu_access\MenuView source
class DomainMenuLinkTreeManipulators {
  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;
  /**
   * The domain negotiator.
   *
   * @var \Drupal\domain\DomainNegotiator
   */
  protected $domainNegotiator;
  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;
  /**
   * @var array
   */
  protected static $entityIdsToLoad = [];
  /**
   * Constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\domain\DomainNegotiator $domain_negotiator
   *   The domain negotiator.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, DomainNegotiator $domain_negotiator, LanguageManagerInterface $language_manager) {
    $this->entityTypeManager = $entity_type_manager;
    $this->domainNegotiator = $domain_negotiator;
    $this->languageManager = $language_manager;
  }
  /**
   * Performs access checking for menu link content in an optimized way.
   *
   * This manipulator should be added after the generic ::checkAccess().
   *
   * @param \Drupal\Core\Menu\MenuLinkTreeElement[] $tree
   *   The menu link tree to manipulate.
   *
   * @return \Drupal\Core\Menu\MenuLinkTreeElement[]
   *   The manipulated menu link tree.
   */
  public function checkDomain(array $tree) {
    $current_language = $this->languageManager
      ->getCurrentLanguage();
    foreach ($tree as $key => $element) {
      // Other menu tree manipulators may already have calculated access, do not
      // overwrite the existing value in that case if already forbidden.
      if (!isset($element->access) || $tree[$key]->access
        ->isAllowed()) {
        if ($access = $this
          ->menuLinkCheckAccess($element->link, $current_language)) {
          if ($access
            ->isForbidden()) {
            $tree[$key]->access = $access;
            // Secure unavailable menu link.
            $tree[$key]->link = new InaccessibleMenuLink($tree[$key]->link);
            $tree[$key]->subtree = [];
          }
          elseif ($tree[$key]->subtree) {
            $tree[$key]->subtree = $this
              ->checkDomain($tree[$key]->subtree);
          }
        }
      }
      if (isset($tree[$key]->access)) {
        $tree[$key]->access
          ->addCacheContexts([
          'url.site',
        ]);
      }
    }
    return $tree;
  }
  /**
   * Checks access for one menu link instance.
   *
   * @param \Drupal\Core\Menu\MenuLinkInterface $instance
   *   The menu link instance.
   * @param \Drupal\Core\Language\LanguageInterface $current_language
   *   The current language.
   *
   * @return \Drupal\Core\Access\AccessResultInterface|NULL
   *   The access result.
   */
  protected function menuLinkCheckAccess(MenuLinkInterface $instance, LanguageInterface $current_language) {
    // Default access.
    $access_result = AccessResult::allowed();
    /** @var MenuLinkContent $entity */
    if ($entity = $this
      ->loadMenuLinkContentEntity($instance)) {
      if ($entity
        ->hasTranslation($current_language
        ->getId())) {
        $entity = $entity
          ->getTranslation($current_language
          ->getId());
      }
      if (!$this
        ->isAvailableOnAllAffiliates($entity)) {
        $domain_access = [];
        foreach ($entity
          ->get(DOMAIN_ACCESS_FIELD)
          ->getValue() as $reference) {
          $domain_access[] = $reference['target_id'];
        }
        $active_domain = $this->domainNegotiator
          ->getActiveDomain();
        if ($active_domain instanceof DomainInterface && !in_array($active_domain
          ->getOriginalId(), $domain_access)) {
          $access_result = AccessResult::forbidden();
        }
      }
    }
    return $access_result
      ->cachePerPermissions();
  }
  /**
   * Check if menu link content is allowed on all affiliates.
   *
   * @param \Drupal\menu_link_content\Entity\MenuLinkContent $entity
   *   Menu link content.
   *
   * @return bool
   */
  protected function isAvailableOnAllAffiliates(MenuLinkContent $entity) {
    if ($entity
      ->get(DOMAIN_ACCESS_ALL_FIELD)
      ->isEmpty()) {
      return FALSE;
    }
    $all_affiliates = $entity
      ->get(DOMAIN_ACCESS_ALL_FIELD)
      ->first()
      ->getString();
    return !empty($all_affiliates);
  }
  /**
   * Load menu link content from menu link entry.
   *
   * @param \Drupal\Core\Menu\MenuLinkInterface $instance
   *   The menu link instance.
   *
   * @return \Drupal\menu_link_content\Entity\MenuLinkContent
   *   The menu link entity.
   */
  protected function loadMenuLinkContentEntity(MenuLinkInterface $instance) {
    $storage = $this->entityTypeManager
      ->getStorage('menu_link_content');
    $entity = NULL;
    if (!empty($instance
      ->getPluginDefinition()['metadata']['entity_id'])) {
      $entity_id = $instance
        ->getPluginDefinition()['metadata']['entity_id'];
      // Make sure the current ID is in the list, since each plugin empties
      // the list after calling loadMultiple(). Note that the list may include
      // multiple IDs added earlier in each plugin's constructor.
      static::$entityIdsToLoad[$entity_id] = $entity_id;
      $entities = $storage
        ->loadMultiple(array_values(static::$entityIdsToLoad));
      $entity = isset($entities[$entity_id]) ? $entities[$entity_id] : NULL;
      static::$entityIdsToLoad = [];
    }
    if (!$entity) {
      // Fallback to the loading by the UUID.
      if ($uuid = $instance
        ->getDerivativeId()) {
        $loaded_entities = $storage
          ->loadByProperties([
          'uuid' => $uuid,
        ]);
        $entity = reset($loaded_entities);
      }
    }
    return $entity;
  }
}Members
| 
            Name | 
                  Modifiers | Type | Description | Overrides | 
|---|---|---|---|---|
| 
            DomainMenuLinkTreeManipulators:: | 
                  protected | property | The domain negotiator. | |
| 
            DomainMenuLinkTreeManipulators:: | 
                  protected static | property | ||
| 
            DomainMenuLinkTreeManipulators:: | 
                  protected | property | The entity type manager. | |
| 
            DomainMenuLinkTreeManipulators:: | 
                  protected | property | The language manager. | |
| 
            DomainMenuLinkTreeManipulators:: | 
                  public | function | Performs access checking for menu link content in an optimized way. | |
| 
            DomainMenuLinkTreeManipulators:: | 
                  protected | function | Check if menu link content is allowed on all affiliates. | |
| 
            DomainMenuLinkTreeManipulators:: | 
                  protected | function | Load menu link content from menu link entry. | |
| 
            DomainMenuLinkTreeManipulators:: | 
                  protected | function | Checks access for one menu link instance. | |
| 
            DomainMenuLinkTreeManipulators:: | 
                  public | function | Constructor. |