graphql_core_schema-1.0.x-dev/src/Plugin/GraphQL/DataProducer/Menu/EntityMenuLink.php
src/Plugin/GraphQL/DataProducer/Menu/EntityMenuLink.php
<?php
namespace Drupal\graphql_core_schema\Plugin\GraphQL\DataProducer\Menu;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Menu\MenuLinkInterface;
use Drupal\Core\Menu\MenuLinkManagerInterface;
use Drupal\Core\Menu\MenuLinkTreeElement;
use Drupal\Core\Menu\MenuLinkTreeInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\graphql\GraphQL\Execution\FieldContext;
use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase;
use Drupal\system\Entity\Menu;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Return the menu link of an entity.
*
* @DataProducer(
* id = "entity_menu_link",
* name = @Translation("Entity Menu Link"),
* description = @Translation("Returns the menu link for an entity."),
* produces = @ContextDefinition("any",
* label = @Translation("Menu link"),
* ),
* consumes = {
* "entity" = @ContextDefinition("entity",
* label = @Translation("Entity")
* ),
* "menu_name" = @ContextDefinition("string",
* label = @Translation("The menu name."),
* required = FALSE
* )
* }
* )
*/
class EntityMenuLink extends DataProducerPluginBase implements ContainerFactoryPluginInterface {
public function __construct(
array $configuration,
$pluginId,
$pluginDefinition,
protected MenuLinkManagerInterface $menuLinkManager,
protected MenuLinkTreeInterface $menuLinkTree,
) {
parent::__construct($configuration, $pluginId, $pluginDefinition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
return new static(
$configuration,
$pluginId,
$pluginDefinition,
$container->get('plugin.manager.menu.link'),
$container->get('menu.link_tree')
);
}
/**
* Resolves the menu link for an entity.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity for which to resolve a menu link.
* @param string|null $menuName
* Optional menu name to restrict the search to.
* @param \Drupal\graphql\GraphQL\Execution\FieldContext|null $fieldContext
* The GraphQL field context.
*/
public function resolve(EntityInterface $entity, ?string $menuName = NULL, ?FieldContext $fieldContext = NULL) {
$url = $entity->toUrl();
/** @var \Drupal\Core\Menu\MenuLinkInterface[] $links */
$links = array_values(
$this->menuLinkManager->loadLinksByRoute(
$url->getRouteName(),
$url->getRouteParameters(),
$menuName
)
);
$link = $links[0] ?? NULL;
if (!$link) {
return;
}
$menu = Menu::load($link->getMenuName());
$fieldContext->addCacheableDependency($menu);
$fieldContext->addCacheableDependency($link);
$menuTreeParameters = new MenuTreeParameters();
$menuTreeParameters->setRoot($link->getPluginId());
$tree = $this->menuLinkTree->load($link->getMenuName(), $menuTreeParameters);
$manipulators = [
['callable' => 'menu.default_tree_manipulators:checkAccess'],
['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
];
$treeElements = array_filter($this->menuLinkTree->transform($tree, $manipulators), function (MenuLinkTreeElement $item) {
return $item->link instanceof MenuLinkInterface && $item->link->isEnabled();
});
/** @var \Drupal\Core\Menu\MenuLinkTreeElement $element */
$element = array_values($treeElements)[0] ?? NULL;
if ($element) {
if ($element->access) {
$fieldContext->addCacheableDependency($element->access);
}
if ($element->link) {
$fieldContext->addCacheableDependency($element->link);
}
}
return $element;
}
}
