"Fossies" - the Fresh Open Source Software Archive

Member "drupal-9.1.0-rc1/core/lib/Drupal/Core/Menu/LocalActionManager.php" (18 Nov 2020, 7275 Bytes) of package /linux/www/drupal-9.1.0-rc1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "LocalActionManager.php" see the Fossies "Dox" file reference documentation.

    1 <?php
    2 
    3 namespace Drupal\Core\Menu;
    4 
    5 use Drupal\Core\Access\AccessManagerInterface;
    6 use Drupal\Core\Cache\CacheableMetadata;
    7 use Drupal\Core\Cache\CacheBackendInterface;
    8 use Drupal\Core\Extension\ModuleHandlerInterface;
    9 use Drupal\Core\Language\LanguageManagerInterface;
   10 use Drupal\Core\Plugin\DefaultPluginManager;
   11 use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
   12 use Drupal\Core\Plugin\Discovery\YamlDiscovery;
   13 use Drupal\Core\Plugin\Factory\ContainerFactory;
   14 use Drupal\Core\Routing\RouteMatchInterface;
   15 use Drupal\Core\Routing\RouteProviderInterface;
   16 use Drupal\Core\Url;
   17 use Symfony\Component\HttpFoundation\RequestStack;
   18 use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
   19 use Drupal\Core\Session\AccountInterface;
   20 
   21 /**
   22  * Provides the default local action manager using YML as primary definition.
   23  */
   24 class LocalActionManager extends DefaultPluginManager implements LocalActionManagerInterface {
   25 
   26   /**
   27    * Provides some default values for all local action plugins.
   28    *
   29    * @var array
   30    */
   31   protected $defaults = [
   32     // The plugin id. Set by the plugin system based on the top-level YAML key.
   33     'id' => NULL,
   34     // The static title for the local action.
   35     'title' => '',
   36     // The weight of the local action.
   37     'weight' => NULL,
   38     // (Required) the route name used to generate a link.
   39     'route_name' => NULL,
   40     // Default route parameters for generating links.
   41     'route_parameters' => [],
   42     // Associative array of link options.
   43     'options' => [],
   44     // The route names where this local action appears.
   45     'appears_on' => [],
   46     // Default class for local action implementations.
   47     'class' => 'Drupal\Core\Menu\LocalActionDefault',
   48   ];
   49 
   50   /**
   51    * An argument resolver object.
   52    *
   53    * @var \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface
   54    */
   55   protected $argumentResolver;
   56 
   57   /**
   58    * The request stack.
   59    *
   60    * @var \Symfony\Component\HttpFoundation\RequestStack
   61    */
   62   protected $requestStack;
   63 
   64   /**
   65    * The current route match.
   66    *
   67    * @var \Drupal\Core\Routing\RouteMatchInterface
   68    */
   69   protected $routeMatch;
   70 
   71   /**
   72    * The route provider to load routes by name.
   73    *
   74    * @var \Drupal\Core\Routing\RouteProviderInterface
   75    */
   76   protected $routeProvider;
   77 
   78   /**
   79    * The access manager.
   80    *
   81    * @var \Drupal\Core\Access\AccessManagerInterface
   82    */
   83   protected $accessManager;
   84 
   85   /**
   86    * The current user.
   87    *
   88    * @var \Drupal\Core\Session\AccountInterface
   89    */
   90   protected $account;
   91 
   92   /**
   93    * The plugin instances.
   94    *
   95    * @var \Drupal\Core\Menu\LocalActionInterface[]
   96    */
   97   protected $instances = [];
   98 
   99   /**
  100    * Constructs a LocalActionManager object.
  101    *
  102    * @param \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface $argument_resolver
  103    *   An object to use in resolving route arguments.
  104    * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
  105    *   The request stack.
  106    * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  107    *   The current route match.
  108    * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
  109    *   The route provider.
  110    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
  111    *   The module handler.
  112    * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
  113    *   Cache backend instance to use.
  114    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
  115    *   The language manager.
  116    * @param \Drupal\Core\Access\AccessManagerInterface $access_manager
  117    *   The access manager.
  118    * @param \Drupal\Core\Session\AccountInterface $account
  119    *   The current user.
  120    */
  121   public function __construct(ArgumentResolverInterface $argument_resolver, RequestStack $request_stack, RouteMatchInterface $route_match, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, AccessManagerInterface $access_manager, AccountInterface $account) {
  122     // Skip calling the parent constructor, since that assumes annotation-based
  123     // discovery.
  124     $this->factory = new ContainerFactory($this, 'Drupal\Core\Menu\LocalActionInterface');
  125     $this->argumentResolver = $argument_resolver;
  126     $this->requestStack = $request_stack;
  127     $this->routeMatch = $route_match;
  128     $this->routeProvider = $route_provider;
  129     $this->accessManager = $access_manager;
  130     $this->moduleHandler = $module_handler;
  131     $this->account = $account;
  132     $this->alterInfo('menu_local_actions');
  133     $this->setCacheBackend($cache_backend, 'local_action_plugins:' . $language_manager->getCurrentLanguage()->getId(), ['local_action']);
  134   }
  135 
  136   /**
  137    * {@inheritdoc}
  138    */
  139   protected function getDiscovery() {
  140     if (!isset($this->discovery)) {
  141       $yaml_discovery = new YamlDiscovery('links.action', $this->moduleHandler->getModuleDirectories());
  142       $yaml_discovery->addTranslatableProperty('title', 'title_context');
  143       $this->discovery = new ContainerDerivativeDiscoveryDecorator($yaml_discovery);
  144     }
  145     return $this->discovery;
  146   }
  147 
  148   /**
  149    * {@inheritdoc}
  150    */
  151   public function getTitle(LocalActionInterface $local_action) {
  152     $controller = [$local_action, 'getTitle'];
  153     $arguments = $this->argumentResolver->getArguments($this->requestStack->getCurrentRequest(), $controller);
  154     return call_user_func_array($controller, $arguments);
  155   }
  156 
  157   /**
  158    * {@inheritdoc}
  159    */
  160   public function getActionsForRoute($route_appears) {
  161     if (!isset($this->instances[$route_appears])) {
  162       $route_names = [];
  163       $this->instances[$route_appears] = [];
  164       // @todo - optimize this lookup by compiling or caching.
  165       foreach ($this->getDefinitions() as $plugin_id => $action_info) {
  166         if (in_array($route_appears, $action_info['appears_on'])) {
  167           $plugin = $this->createInstance($plugin_id);
  168           $route_names[] = $plugin->getRouteName();
  169           $this->instances[$route_appears][$plugin_id] = $plugin;
  170         }
  171       }
  172       // Pre-fetch all the action route objects. This reduces the number of SQL
  173       // queries that would otherwise be triggered by the access manager.
  174       if (!empty($route_names)) {
  175         $this->routeProvider->getRoutesByNames($route_names);
  176       }
  177     }
  178     $links = [];
  179     $cacheability = new CacheableMetadata();
  180     $cacheability->addCacheContexts(['route']);
  181     /** @var $plugin \Drupal\Core\Menu\LocalActionInterface */
  182     foreach ($this->instances[$route_appears] as $plugin_id => $plugin) {
  183       $route_name = $plugin->getRouteName();
  184       $route_parameters = $plugin->getRouteParameters($this->routeMatch);
  185       $access = $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account, TRUE);
  186       $links[$plugin_id] = [
  187         '#theme' => 'menu_local_action',
  188         '#link' => [
  189           'title' => $this->getTitle($plugin),
  190           'url' => Url::fromRoute($route_name, $route_parameters),
  191           'localized_options' => $plugin->getOptions($this->routeMatch),
  192         ],
  193         '#access' => $access,
  194         '#weight' => $plugin->getWeight(),
  195       ];
  196       $cacheability->addCacheableDependency($access)->addCacheableDependency($plugin);
  197     }
  198     $cacheability->applyTo($links);
  199 
  200     return $links;
  201   }
  202 
  203 }