Upgraded drupal core with security updates
[yaffs-website] / web / core / modules / content_moderation / src / ViewsData.php
1 <?php
2
3 namespace Drupal\content_moderation;
4
5 use Drupal\Core\Entity\EntityTypeInterface;
6 use Drupal\Core\Entity\EntityTypeManagerInterface;
7 use Drupal\Core\StringTranslation\StringTranslationTrait;
8
9 /**
10  * Provides the content_moderation views integration.
11  */
12 class ViewsData {
13
14   use StringTranslationTrait;
15
16   /**
17    * The entity type manager.
18    *
19    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
20    */
21   protected $entityTypeManager;
22
23   /**
24    * The moderation information.
25    *
26    * @var \Drupal\content_moderation\ModerationInformationInterface
27    */
28   protected $moderationInformation;
29
30   /**
31    * Creates a new ViewsData instance.
32    *
33    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
34    *   The entity type manager.
35    * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_information
36    *   The moderation information.
37    */
38   public function __construct(EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_information) {
39     $this->entityTypeManager = $entity_type_manager;
40     $this->moderationInformation = $moderation_information;
41   }
42
43   /**
44    * Returns the views data.
45    *
46    * @return array
47    *   The views data.
48    */
49   public function getViewsData() {
50     $data = [];
51
52     $data['content_revision_tracker']['table']['group'] = $this->t('Content moderation (tracker)');
53
54     $data['content_revision_tracker']['entity_type'] = [
55       'title' => $this->t('Entity type'),
56       'field' => [
57         'id' => 'standard',
58       ],
59       'filter' => [
60         'id' => 'string',
61       ],
62       'argument' => [
63         'id' => 'string',
64       ],
65       'sort' => [
66         'id' => 'standard',
67       ],
68     ];
69
70     $data['content_revision_tracker']['entity_id'] = [
71       'title' => $this->t('Entity ID'),
72       'field' => [
73         'id' => 'standard',
74       ],
75       'filter' => [
76         'id' => 'numeric',
77       ],
78       'argument' => [
79         'id' => 'numeric',
80       ],
81       'sort' => [
82         'id' => 'standard',
83       ],
84     ];
85
86     $data['content_revision_tracker']['langcode'] = [
87       'title' => $this->t('Entity language'),
88       'field' => [
89         'id' => 'standard',
90       ],
91       'filter' => [
92         'id' => 'language',
93       ],
94       'argument' => [
95         'id' => 'language',
96       ],
97       'sort' => [
98         'id' => 'standard',
99       ],
100     ];
101
102     $data['content_revision_tracker']['revision_id'] = [
103       'title' => $this->t('Latest revision ID'),
104       'field' => [
105         'id' => 'standard',
106       ],
107       'filter' => [
108         'id' => 'numeric',
109       ],
110       'argument' => [
111         'id' => 'numeric',
112       ],
113       'sort' => [
114         'id' => 'standard',
115       ],
116     ];
117
118     $entity_types_with_moderation = array_filter($this->entityTypeManager->getDefinitions(), function (EntityTypeInterface $type) {
119       return $this->moderationInformation->canModerateEntitiesOfEntityType($type);
120     });
121
122     // Add a join for each entity type to the content_revision_tracker table.
123     foreach ($entity_types_with_moderation as $entity_type_id => $entity_type) {
124       /** @var \Drupal\views\EntityViewsDataInterface $views_data */
125       // We need the views_data handler in order to get the table name later.
126       if ($this->entityTypeManager->hasHandler($entity_type_id, 'views_data') && $views_data = $this->entityTypeManager->getHandler($entity_type_id, 'views_data')) {
127         // Add a join from the entity base table to the revision tracker table.
128         $base_table = $views_data->getViewsTableForEntityType($entity_type);
129         $data['content_revision_tracker']['table']['join'][$base_table] = [
130           'left_field' => $entity_type->getKey('id'),
131           'field' => 'entity_id',
132           'extra' => [
133             [
134               'field' => 'entity_type',
135               'value' => $entity_type_id,
136             ],
137           ],
138         ];
139
140         // Some entity types might not be translatable.
141         if ($entity_type->hasKey('langcode')) {
142           $data['content_revision_tracker']['table']['join'][$base_table]['extra'][] = [
143             'field' => 'langcode',
144             'left_field' => $entity_type->getKey('langcode'),
145             'operation' => '=',
146           ];
147         }
148
149         // Add a relationship between the revision tracker table to the latest
150         // revision on the entity revision table.
151         $data['content_revision_tracker']['latest_revision__' . $entity_type_id] = [
152           'title' => $this->t('@label latest revision', ['@label' => $entity_type->getLabel()]),
153           'group' => $this->t('@label revision', ['@label' => $entity_type->getLabel()]),
154           'relationship' => [
155             'id' => 'standard',
156             'label' => $this->t('@label latest revision', ['@label' => $entity_type->getLabel()]),
157             'base' => $this->getRevisionViewsTableForEntityType($entity_type),
158             'base field' => $entity_type->getKey('revision'),
159             'relationship field' => 'revision_id',
160             'extra' => [
161               [
162                 'left_field' => 'entity_type',
163                 'value' => $entity_type_id,
164               ],
165             ],
166           ],
167         ];
168
169         // Some entity types might not be translatable.
170         if ($entity_type->hasKey('langcode')) {
171           $data['content_revision_tracker']['latest_revision__' . $entity_type_id]['relationship']['extra'][] = [
172             'left_field' => 'langcode',
173             'field' => $entity_type->getKey('langcode'),
174             'operation' => '=',
175           ];
176         }
177       }
178     }
179
180     // Provides a relationship from moderated entity to its moderation state
181     // entity.
182     $content_moderation_state_entity_type = \Drupal::entityTypeManager()->getDefinition('content_moderation_state');
183     $content_moderation_state_entity_base_table = $content_moderation_state_entity_type->getDataTable() ?: $content_moderation_state_entity_type->getBaseTable();
184     $content_moderation_state_entity_revision_base_table = $content_moderation_state_entity_type->getRevisionDataTable() ?: $content_moderation_state_entity_type->getRevisionTable();
185     foreach ($entity_types_with_moderation as $entity_type_id => $entity_type) {
186       $table = $entity_type->getDataTable() ?: $entity_type->getBaseTable();
187
188       $data[$table]['moderation_state'] = [
189         'title' => t('Moderation state'),
190         'relationship' => [
191           'id' => 'standard',
192           'label' => $this->t('@label moderation state', ['@label' => $entity_type->getLabel()]),
193           'base' => $content_moderation_state_entity_base_table,
194           'base field' => 'content_entity_id',
195           'relationship field' => $entity_type->getKey('id'),
196           'extra' => [
197             [
198               'field' => 'content_entity_type_id',
199               'value' => $entity_type_id,
200             ],
201           ],
202         ],
203         'field' => ['default_formatter' => 'content_moderation_state'],
204       ];
205
206       $revision_table = $entity_type->getRevisionDataTable() ?: $entity_type->getRevisionTable();
207       $data[$revision_table]['moderation_state'] = [
208         'title' => t('Moderation state'),
209         'relationship' => [
210           'id' => 'standard',
211           'label' => $this->t('@label moderation state', ['@label' => $entity_type->getLabel()]),
212           'base' => $content_moderation_state_entity_revision_base_table,
213           'base field' => 'content_entity_revision_id',
214           'relationship field' => $entity_type->getKey('revision'),
215           'extra' => [
216             [
217               'field' => 'content_entity_type_id',
218               'value' => $entity_type_id,
219             ],
220           ],
221         ],
222         'field' => ['default_formatter' => 'content_moderation_state'],
223       ];
224     }
225
226     return $data;
227   }
228
229   /**
230    * Alters the table and field information from hook_views_data().
231    *
232    * @param array $data
233    *   An array of all information about Views tables and fields, collected from
234    *   hook_views_data(), passed by reference.
235    *
236    * @see hook_views_data()
237    */
238   public function alterViewsData(array &$data) {
239     $entity_types_with_moderation = array_filter($this->entityTypeManager->getDefinitions(), function (EntityTypeInterface $type) {
240       return $this->moderationInformation->canModerateEntitiesOfEntityType($type);
241     });
242     foreach ($entity_types_with_moderation as $type) {
243       $data[$type->getRevisionTable()]['latest_revision'] = [
244         'title' => t('Is Latest Revision'),
245         'help' => t('Restrict the view to only revisions that are the latest revision of their entity.'),
246         'filter' => ['id' => 'latest_revision'],
247       ];
248     }
249   }
250
251   /**
252    * Gets the table of an entity type to be used as revision table in views.
253    *
254    * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
255    *   The entity type.
256    *
257    * @return string
258    *   The revision base table.
259    */
260   protected function getRevisionViewsTableForEntityType(EntityTypeInterface $entity_type) {
261     return $entity_type->getRevisionDataTable() ?: $entity_type->getRevisionTable();
262   }
263
264 }