class MenuTreeResource in REST Menu Tree 8
Same name and namespace in other branches
- 2.x src/Plugin/rest/resource/MenuTreeResource.php \Drupal\rest_menu_tree\Plugin\rest\resource\MenuTreeResource
Provides a resource to get view modes by entity and bundle.
Plugin annotation
@RestResource(
id = "menu_tree",
label = @Translation("Menu Tree"),
serialization_class = "Drupal\system\Entity\Menu",
uri_paths = {
"canonical" = "/entity/menu/{menu}/tree"
}
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\rest\Plugin\ResourceBase implements ContainerFactoryPluginInterface, ResourceInterface
- class \Drupal\rest_menu_tree\Plugin\rest\resource\MenuTreeResource
- class \Drupal\rest\Plugin\ResourceBase implements ContainerFactoryPluginInterface, ResourceInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of MenuTreeResource
File
- src/
Plugin/ rest/ resource/ MenuTreeResource.php, line 32
Namespace
Drupal\rest_menu_tree\Plugin\rest\resourceView source
class MenuTreeResource extends ResourceBase {
/**
* Menu Tree.
*
* @var \Drupal\Core\Menu\MenuLinkTreeInterface
*/
protected $menuTree;
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, LoggerInterface $logger, MenuLinkTreeInterface $menu_tree, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->menuTree = $menu_tree;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->getParameter('serializer.formats'), $container
->get('logger.factory')
->get('rest'), $container
->get('menu.link_tree'), $container
->get('entity_type.manager'));
}
/**
* {@inheritdoc}
*/
public function get(MenuInterface $menu) {
$params = new MenuTreeParameters();
$tree = $this->menuTree
->load($menu
->id(), $params);
// Transform the tree using manipulators.
$manipulators = [
[
'callable' => 'menu.default_tree_manipulators:generateIndexAndSort',
],
];
$tree = $this->menuTree
->transform($tree, $manipulators);
// Ensure that every item has an access response, if possible.
$this
->addAccess($tree);
// Maintain a clean version of the tree for adding cache metadata to the
// response.
$clean = $tree;
// Remove items the user does not have access to.
$this
->checkAccess($tree);
// Remove the keys to prevent reordering.
$this
->removeKeys($tree);
$response = new ResourceResponse($tree);
// First add every item to the cache.
$response
->addCacheableDependency($menu);
// Always use the clean version of the tree so every link is cached,
// regardless of whether it's accessible to the current user or not.
$this
->addCacheDependencies($clean, $response);
return $response;
}
/**
* Remove array keys.
*
* Javascript will re-sort the array based on the key. To prevent this, we'll
* remove the array keys.
*/
protected function removeKeys(array &$data) {
$tree = [];
foreach ($data as $value) {
if ($value->subtree) {
$this
->removeKeys($value->subtree);
}
$tree[] = $value;
}
$data = $tree;
}
/**
* Add Access.
*
* Ensure that every item has an access result, if possible.
*/
protected function addAccess(array $data) {
foreach ($data as $value) {
if ($value->access === NULL && $value->link instanceof AccessibleInterface) {
$value->access = $value->link
->access('view', NULL, TRUE);
}
if ($value->subtree) {
$this
->addAccess($value->subtree);
}
}
}
/**
* Check Access.
*
* Remove items the user does not have access to from the response.
*/
protected function checkAccess(array &$data) {
foreach ($data as $key => $value) {
// Use the menu links' access result.
if ($value->access instanceof AccessResultInterface) {
if (!$value->access
->isAllowed()) {
unset($data[$key]);
continue;
}
}
elseif (!$value->link
->isEnabled()) {
unset($data[$key]);
continue;
}
if ($value->subtree) {
$this
->checkAccess($value->subtree);
}
}
}
/**
* Add Cache Tags.
*/
protected function addCacheDependencies(array $data, CacheableResponseInterface $response) {
foreach ($data as $value) {
// Gather the access cacheability of every item in the menu link tree,
// including inaccessible items. This allows us to render cache the menu
// tree, yet still automatically vary the rendered menu by the same cache
// contexts that the access results vary by.
// However, if $value->access is not an AccessResultInterface object, this
// will still render the menu link, because this method does not want to
// require access checking to be able to render a menu tree.
if ($value->access instanceof AccessResultInterface) {
$response
->addCacheableDependency($value->access);
}
// Gather the cacheability of every item in the menu link tree. Some links
// may be dynamic: they may have a dynamic text (e.g. a "Hi, <user>" link
// text, which would vary by 'user' cache context), or a dynamic route
// name or route parameters.
$response
->addCacheableDependency($value->link);
// There may be additional dependencies that must be manually determined.
$this
->addLinkCacheDependencies($value->link, $response);
if ($value->subtree) {
$this
->addCacheDependencies($value->subtree, $response);
}
}
}
/**
* Add Cache Tags.
*/
protected function addLinkCacheDependencies(MenuLinkInterface $link, CacheableResponseInterface $response) {
$entity_type = NULL;
$entity_type_id = $link
->getBaseId();
$uuid = $link
->getDerivativeId();
if ($link instanceof EntityInterface) {
$entity_type = $link
->getEntityType();
}
else {
try {
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
} catch (\Exception $e) {
// Silence is golden.
}
}
if (!$entity_type) {
return;
}
// Add the list cache tags.
$cache = new CacheableMetadata();
$cache
->addCacheTags($entity_type
->getListCacheTags());
$response
->addCacheableDependency($cache);
// If the link is an entity already, the cache tags were added in
// ::addCacheDependencies().
if ($link instanceof EntityInterface) {
return;
}
// Get the entity.
$entity = NULL;
$storage = $this->entityTypeManager
->getStorage($entity_type_id);
$metadata = $link
->getMetaData();
if (!empty($metadata['entity_id'])) {
$entity = $storage
->load($metadata['entity_id']);
}
else {
$entities = $storage
->loadByProperties([
$entity_type
->getKey('uuid') => $uuid,
]);
$entity = reset($entities);
}
if (!$entity) {
return;
}
$response
->addCacheableDependency($entity);
}
/**
* {@inheritdoc}
*/
protected function getBaseRoute($canonical_path, $method) {
$route = parent::getBaseRoute($canonical_path, $method);
$parameters = $route
->getOption('parameters') ?: array();
$parameters['menu']['type'] = 'entity:menu';
$route
->setOption('parameters', $parameters);
return $route;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
MenuTreeResource:: |
protected | property | The entity manager. | |
MenuTreeResource:: |
protected | property | Menu Tree. | |
MenuTreeResource:: |
protected | function | Add Access. | |
MenuTreeResource:: |
protected | function | Add Cache Tags. | |
MenuTreeResource:: |
protected | function | Add Cache Tags. | |
MenuTreeResource:: |
protected | function | Check Access. | |
MenuTreeResource:: |
public static | function |
Creates an instance of the plugin. Overrides ResourceBase:: |
|
MenuTreeResource:: |
public | function | ||
MenuTreeResource:: |
protected | function |
Gets the base route for a particular method. Overrides ResourceBase:: |
|
MenuTreeResource:: |
protected | function | Remove array keys. | |
MenuTreeResource:: |
public | function |
Constructs a Drupal\rest\Plugin\ResourceBase object. Overrides ResourceBase:: |
|
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
ResourceBase:: |
protected | property | A logger instance. | |
ResourceBase:: |
protected | property | The available serialization formats. | |
ResourceBase:: |
public | function |
Returns the available HTTP request methods on this plugin. Overrides ResourceInterface:: |
1 |
ResourceBase:: |
protected | function | Gets the base route requirements for a particular method. | 1 |
ResourceBase:: |
public | function |
Implements ResourceInterface::permissions(). Overrides ResourceInterface:: |
2 |
ResourceBase:: |
protected | function | Provides predefined HTTP request methods. | |
ResourceBase:: |
public | function |
Returns a collection of routes with URL path information for the resource. Overrides ResourceInterface:: |
|
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |