3 namespace Drupal\Core\ParamConverter;
5 use Drupal\Core\Config\Entity\ConfigEntityInterface;
6 use Drupal\Core\Routing\AdminContext;
7 use Symfony\Component\Routing\Route;
8 use Drupal\Core\Config\ConfigFactoryInterface;
9 use Drupal\Core\Entity\EntityManagerInterface;
12 * Makes sure the unmodified ConfigEntity is loaded on admin pages.
14 * Converts entity route arguments to unmodified entities as opposed to
15 * converting to entities with overrides, such as the negotiated language.
17 * This converter applies only if the path is an admin path, the entity is
18 * a config entity, and the "with_config_overrides" element is not set to TRUE
19 * on the parameter definition.
21 * Due to this converter having a higher weight than the default
22 * EntityConverter, every time this applies, it takes over the conversion duty
23 * from EntityConverter. As we only allow a single converter per route
24 * argument, EntityConverter is ignored when this converter applies.
26 class AdminPathConfigEntityConverter extends EntityConverter {
31 * @var \Drupal\Core\Config\ConfigFactoryInterface
33 protected $configFactory;
36 * The route admin context to determine whether a route is an admin one.
38 * @var \Drupal\Core\Routing\AdminContext
40 protected $adminContext;
43 * Constructs a new EntityConverter.
45 * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
47 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
49 * @param \Drupal\Core\Routing\AdminContext $admin_context
50 * The route admin context service.
52 public function __construct(EntityManagerInterface $entity_manager, ConfigFactoryInterface $config_factory, AdminContext $admin_context) {
53 parent::__construct($entity_manager);
55 $this->configFactory = $config_factory;
56 $this->adminContext = $admin_context;
62 public function convert($value, $definition, $name, array $defaults) {
63 $entity_type_id = $this->getEntityTypeFromDefaults($definition, $name, $defaults);
65 // If the entity type is dynamic, confirm it to be a config entity. Static
66 // entity types will have performed this check in self::applies().
67 if (strpos($definition['type'], 'entity:{') === 0) {
68 $entity_type = $this->entityManager->getDefinition($entity_type_id);
69 if (!$entity_type->entityClassImplements(ConfigEntityInterface::class)) {
70 return parent::convert($value, $definition, $name, $defaults);
74 if ($storage = $this->entityManager->getStorage($entity_type_id)) {
75 // Make sure no overrides are loaded.
76 return $storage->loadOverrideFree($value);
83 public function applies($definition, $name, Route $route) {
84 if (isset($definition['with_config_overrides']) && $definition['with_config_overrides']) {
88 if (parent::applies($definition, $name, $route)) {
89 $entity_type_id = substr($definition['type'], strlen('entity:'));
90 // If the entity type is dynamic, defer checking to self::convert().
91 if (strpos($entity_type_id, '{') === 0) {
94 // As we only want to override EntityConverter for ConfigEntities, find
95 // out whether the current entity is a ConfigEntity.
96 $entity_type = $this->entityManager->getDefinition($entity_type_id);
97 if ($entity_type->entityClassImplements(ConfigEntityInterface::class)) {
98 return $this->adminContext->isAdminRoute($route);