workbench_access-8.x-1.x-dev/src/WorkbenchAccessTokens.php

src/WorkbenchAccessTokens.php
<?php

namespace Drupal\workbench_access;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Utility\Token;
use Drupal\node\NodeInterface;
use Drupal\user\UserInterface;
use Drupal\workbench_access\Entity\AccessSchemeInterface;

/**
 * Token handler for Workbench Access.
 *
 * TokenAPI still uses procedural code, but we have moved it to a class for
 * easier refactoring.
 */
class WorkbenchAccessTokens {

  use StringTranslationTrait;

  /**
   * The core token service.
   *
   * @var \Drupal\Core\Utility\Token
   */
  protected $tokenService;

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

  /**
   * The core module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The workbench access user section storage service.
   *
   * @var \Drupal\workbench_access\UserSectionStorageInterface
   */
  protected $userSectionStorage;

  /**
   * Constructs a WorkbenchAccessTokens object.
   *
   * @param \Drupal\Core\Utility\Token $token_service
   *   The core token service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The core module handler.
   * @param \Drupal\workbench_access\UserSectionStorageInterface $user_section_storage
   *   The workbench access user section storage service.
   */
  public function __construct(Token $token_service, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, UserSectionStorageInterface $user_section_storage) {
    $this->tokenService = $token_service;
    $this->entityTypeManager = $entity_type_manager;
    $this->moduleHandler = $module_handler;
    $this->userSectionStorage = $user_section_storage;
  }

  /**
   * Implements hook_token_info().
   */
  public function getTokenInfo() {
    $info['tokens'] = [
      'user' => [
        'workbench-access-sections' => [
          'name' => $this->t('Workbench access sections'),
          'description' => $this->t('Section assignments for the user account.'),
          // Optionally use token module's array type which gives users greater
          // control on output.
          'type' => $this->moduleHandler->moduleExists('token') ? 'array' : '',
        ],
      ],
      'node' => [
        'workbench-access-sections' => [
          'name' => $this->t('Workbench access sections'),
          'description' => $this->t('Section assignments for content.'),
          // Optionally use token module's array type which gives users greater
          // control on output.
          'type' => $this->moduleHandler->moduleExists('token') ? 'array' : '',
        ],
      ],
    ];

    return $info;
  }

  /**
   * Implements hook_tokens().
   */
  public function getTokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
    $replacements = [];

    // User tokens.
    if ($type === 'user' && !empty($data['user'])) {
      /** @var \Drupal\user\UserInterface $user */
      $user = $data['user'];

      foreach ($tokens as $name => $original) {
        switch ($name) {
          case 'workbench-access-sections':
            if ($sections = $this->getUserSectionNames($user, $bubbleable_metadata)) {
              if (function_exists('token_render_array')) {
                $replacements[$original] = token_render_array($sections, $options);
              }
              else {
                $replacements[$original] = implode(', ', $sections);
              }
            }
            break;
        }
      }

      // Chained token relationships.
      if ($section_tokens = $this->tokenService->findWithPrefix($tokens, 'workbench-access-sections')) {
        if ($sections = $this->getUserSectionNames($user, $bubbleable_metadata)) {
          $replacements += $this->tokenService->generate('array', $section_tokens, ['array' => $sections], $options, $bubbleable_metadata);
        }
      }
    }
    // Node tokens.
    if ($type === 'node' && !empty($data['node'])) {
      /** @var \Drupal\node\NodeInterface $node */
      $node = $data['node'];

      foreach ($tokens as $name => $original) {
        switch ($name) {
          case 'workbench-access-sections':
            if ($sections = $this->getNodeSectionNames($node, $bubbleable_metadata)) {
              if (function_exists('token_render_array')) {
                $replacements[$original] = token_render_array($sections, $options);
              }
              else {
                $replacements[$original] = implode(', ', $sections);
              }
            }
            break;
        }
      }

      // Chained token relationships.
      if ($section_tokens = $this->tokenService->findWithPrefix($tokens, 'workbench-access-sections')) {
        if ($sections = $this->getNodeSectionNames($node, $bubbleable_metadata)) {
          $replacements += $this->tokenService->generate('array', $section_tokens, ['array' => $sections], $options, $bubbleable_metadata);
        }
      }
    }

    return $replacements;
  }

  /**
   * Generates an array of section names for a given account.
   *
   * @param \Drupal\user\UserInterface $user
   *   The user account.
   * @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata
   *   The cache metadata.
   *
   * @return array
   *   An array of section names.
   */
  private function getUserSectionNames(UserInterface $user, BubbleableMetadata $bubbleable_metadata) {
    $schemes = $this->entityTypeManager->getStorage('access_scheme')->loadMultiple();
    return array_reduce($schemes, function (array $carry, AccessSchemeInterface $scheme) use ($user, $bubbleable_metadata) {
      if (!$sections = $this->userSectionStorage->getUserSections($scheme, $user)) {
        return $carry;
      }
      $bubbleable_metadata->addCacheableDependency($scheme);

      return array_merge($carry, array_reduce($scheme->getAccessScheme()->getTree(), function ($inner, $info) use ($sections) {
        $user_in_sections = array_intersect_key($info, array_combine($sections, $sections));
        return array_merge($inner, array_column($user_in_sections, 'label'));
      }, []));
    }, []);
  }

  /**
   * Generates an array of section names for a given node.
   *
   * @param \Drupal\node\NodeInterface $node
   *   The user account.
   * @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata
   *   The cache metadata.
   *
   * @return array
   *   An array of section names.
   */
  private function getNodeSectionNames(NodeInterface $node, BubbleableMetadata $bubbleable_metadata) {
    $schemes = $this->entityTypeManager->getStorage('access_scheme')->loadMultiple();
    return array_reduce($schemes, function (array $carry, AccessSchemeInterface $scheme) use ($node, $bubbleable_metadata) {
      if (!$sections = $scheme->getAccessScheme()->getEntityValues($node)) {
        return $carry;
      }
      $bubbleable_metadata->addCacheableDependency($scheme);

      return array_merge($carry, array_reduce($scheme->getAccessScheme()->getTree(), function ($inner, $info) use ($sections) {
        $node_in_sections = array_intersect_key($info, array_combine($sections, $sections));
        return array_merge($inner, array_column($node_in_sections, 'label'));
      }, []));
    }, []);
  }

}

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

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