eac1913fcae56dfacffd2011455cf3fdf78685cb
[yaffs-website] / web / core / modules / content_moderation / src / ParamConverter / EntityRevisionConverter.php
1 <?php
2
3 namespace Drupal\content_moderation\ParamConverter;
4
5 use Drupal\Core\Entity\EntityInterface;
6 use Drupal\Core\Entity\EntityManagerInterface;
7 use Drupal\Core\ParamConverter\EntityConverter;
8 use Drupal\Core\TypedData\TranslatableInterface;
9 use Drupal\content_moderation\ModerationInformationInterface;
10 use Symfony\Component\Routing\Route;
11
12 /**
13  * Defines a class for making sure the edit-route loads the current draft.
14  */
15 class EntityRevisionConverter extends EntityConverter {
16
17   /**
18    * Moderation information service.
19    *
20    * @var \Drupal\content_moderation\ModerationInformationInterface
21    */
22   protected $moderationInformation;
23
24   /**
25    * EntityRevisionConverter constructor.
26    *
27    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
28    *   The entity manager, needed by the parent class.
29    * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
30    *   The moderation info utility service.
31    *
32    * @todo: If the parent class is ever cleaned up to use EntityTypeManager
33    *   instead of Entity manager, this method will also need to be adjusted.
34    */
35   public function __construct(EntityManagerInterface $entity_manager, ModerationInformationInterface $moderation_info) {
36     parent::__construct($entity_manager);
37     $this->moderationInformation = $moderation_info;
38   }
39
40   /**
41    * {@inheritdoc}
42    */
43   public function applies($definition, $name, Route $route) {
44     return $this->hasForwardRevisionFlag($definition) || $this->isEditFormPage($route);
45   }
46
47   /**
48    * Determines if the route definition includes a forward-revision flag.
49    *
50    * This is a custom flag defined by the Content Moderation module to load
51    * forward revisions rather than the default revision on a given route.
52    *
53    * @param array $definition
54    *   The parameter definition provided in the route options.
55    *
56    * @return bool
57    *   TRUE if the forward revision flag is set, FALSE otherwise.
58    */
59   protected function hasForwardRevisionFlag(array $definition) {
60     return (isset($definition['load_forward_revision']) && $definition['load_forward_revision']);
61   }
62
63   /**
64    * Determines if a given route is the edit-form for an entity.
65    *
66    * @param \Symfony\Component\Routing\Route $route
67    *   The route definition.
68    *
69    * @return bool
70    *   Returns TRUE if the route is the edit form of an entity, FALSE otherwise.
71    */
72   protected function isEditFormPage(Route $route) {
73     if ($default = $route->getDefault('_entity_form')) {
74       // If no operation is provided, use 'default'.
75       $default .= '.default';
76       list($entity_type_id, $operation) = explode('.', $default);
77       if (!$this->entityManager->hasDefinition($entity_type_id)) {
78         return FALSE;
79       }
80       $entity_type = $this->entityManager->getDefinition($entity_type_id);
81       return $operation == 'edit' && $entity_type && $entity_type->isRevisionable();
82     }
83   }
84
85   /**
86    * {@inheritdoc}
87    */
88   public function convert($value, $definition, $name, array $defaults) {
89     $entity = parent::convert($value, $definition, $name, $defaults);
90
91     if ($entity && $this->moderationInformation->isModeratedEntity($entity) && !$this->moderationInformation->isLatestRevision($entity)) {
92       $entity_type_id = $this->getEntityTypeFromDefaults($definition, $name, $defaults);
93       $latest_revision = $this->moderationInformation->getLatestRevision($entity_type_id, $value);
94
95       // If the entity type is translatable, ensure we return the proper
96       // translation object for the current context.
97       if ($latest_revision instanceof EntityInterface && $entity instanceof TranslatableInterface) {
98         $latest_revision = $this->entityManager->getTranslationFromContext($latest_revision, NULL, ['operation' => 'entity_upcast']);
99       }
100
101       if ($latest_revision instanceof EntityInterface && $latest_revision->isRevisionTranslationAffected()) {
102         $entity = $latest_revision;
103       }
104     }
105
106     return $entity;
107   }
108
109 }