98f6fdf2b9a09f47d997177efd2c143d98ebcebc
[yaffs-website] / web / core / modules / content_moderation / src / Form / EntityModerationForm.php
1 <?php
2
3 namespace Drupal\content_moderation\Form;
4
5 use Drupal\Component\Datetime\Time;
6 use Drupal\Core\Entity\ContentEntityInterface;
7 use Drupal\Core\Entity\RevisionLogInterface;
8 use Drupal\Core\Form\FormBase;
9 use Drupal\Core\Form\FormStateInterface;
10 use Drupal\content_moderation\ModerationInformationInterface;
11 use Drupal\content_moderation\StateTransitionValidationInterface;
12 use Drupal\workflows\Transition;
13 use Symfony\Component\DependencyInjection\ContainerInterface;
14
15 /**
16  * The EntityModerationForm provides a simple UI for changing moderation state.
17  *
18  * @internal
19  */
20 class EntityModerationForm extends FormBase {
21
22   /**
23    * The moderation information service.
24    *
25    * @var \Drupal\content_moderation\ModerationInformationInterface
26    */
27   protected $moderationInfo;
28
29   /**
30    * The time service.
31    *
32    * @var \Drupal\Component\Datetime\Time
33    */
34   protected $time;
35
36   /**
37    * The moderation state transition validation service.
38    *
39    * @var \Drupal\content_moderation\StateTransitionValidationInterface
40    */
41   protected $validation;
42
43   /**
44    * EntityModerationForm constructor.
45    *
46    * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
47    *   The moderation information service.
48    * @param \Drupal\content_moderation\StateTransitionValidationInterface $validation
49    *   The moderation state transition validation service.
50    * @param \Drupal\Component\Datetime\Time $time
51    *   The time service.
52    */
53   public function __construct(ModerationInformationInterface $moderation_info, StateTransitionValidationInterface $validation, Time $time) {
54     $this->moderationInfo = $moderation_info;
55     $this->validation = $validation;
56     $this->time = $time;
57   }
58
59   /**
60    * {@inheritdoc}
61    */
62   public static function create(ContainerInterface $container) {
63     return new static(
64       $container->get('content_moderation.moderation_information'),
65       $container->get('content_moderation.state_transition_validation'),
66       $container->get('datetime.time')
67     );
68   }
69
70   /**
71    * {@inheritdoc}
72    */
73   public function getFormId() {
74     return 'content_moderation_entity_moderation_form';
75   }
76
77   /**
78    * {@inheritdoc}
79    */
80   public function buildForm(array $form, FormStateInterface $form_state, ContentEntityInterface $entity = NULL) {
81     $current_state = $entity->moderation_state->value;
82     $workflow = $this->moderationInfo->getWorkflowForEntity($entity);
83
84     /** @var \Drupal\workflows\Transition[] $transitions */
85     $transitions = $this->validation->getValidTransitions($entity, $this->currentUser());
86
87     // Exclude self-transitions.
88     $transitions = array_filter($transitions, function (Transition $transition) use ($current_state) {
89       return $transition->to()->id() != $current_state;
90     });
91
92     $target_states = [];
93
94     foreach ($transitions as $transition) {
95       $target_states[$transition->to()->id()] = $transition->to()->label();
96     }
97
98     if (!count($target_states)) {
99       return $form;
100     }
101
102     if ($current_state) {
103       $form['current'] = [
104         '#type' => 'item',
105         '#title' => $this->t('Moderation state'),
106         '#markup' => $workflow->getTypePlugin()->getState($current_state)->label(),
107       ];
108     }
109
110     // Persist the entity so we can access it in the submit handler.
111     $form_state->set('entity', $entity);
112
113     $form['new_state'] = [
114       '#type' => 'select',
115       '#title' => $this->t('Change to'),
116       '#options' => $target_states,
117     ];
118
119     $form['revision_log'] = [
120       '#type' => 'textfield',
121       '#title' => $this->t('Log message'),
122       '#size' => 30,
123     ];
124
125     $form['submit'] = [
126       '#type' => 'submit',
127       '#value' => $this->t('Apply'),
128     ];
129
130     $form['#theme'] = ['entity_moderation_form'];
131
132     return $form;
133   }
134
135   /**
136    * {@inheritdoc}
137    */
138   public function submitForm(array &$form, FormStateInterface $form_state) {
139     /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
140     $entity = $form_state->get('entity');
141     /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
142     $storage = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId());
143     $entity = $storage->createRevision($entity, $entity->isDefaultRevision());
144
145     $new_state = $form_state->getValue('new_state');
146
147     $entity->set('moderation_state', $new_state);
148
149     if ($entity instanceof RevisionLogInterface) {
150       $entity->setRevisionCreationTime($this->time->getRequestTime());
151       $entity->setRevisionLogMessage($form_state->getValue('revision_log'));
152       $entity->setRevisionUserId($this->currentUser()->id());
153     }
154     $entity->save();
155
156     drupal_set_message($this->t('The moderation state has been updated.'));
157
158     $new_state = $this->moderationInfo->getWorkflowForEntity($entity)->getTypePlugin()->getState($new_state);
159     // The page we're on likely won't be visible if we just set the entity to
160     // the default state, as we hide that latest-revision tab if there is no
161     // pending revision. Redirect to the canonical URL instead, since that will
162     // still exist.
163     if ($new_state->isDefaultRevisionState()) {
164       $form_state->setRedirectUrl($entity->toUrl('canonical'));
165     }
166   }
167
168 }