3 namespace Drupal\content_moderation\Form;
5 use Drupal\Core\Entity\ContentEntityInterface;
6 use Drupal\Core\Entity\RevisionLogInterface;
7 use Drupal\Core\Form\FormBase;
8 use Drupal\Core\Form\FormStateInterface;
9 use Drupal\content_moderation\ModerationInformationInterface;
10 use Drupal\content_moderation\StateTransitionValidation;
11 use Drupal\workflows\Transition;
12 use Symfony\Component\DependencyInjection\ContainerInterface;
15 * The EntityModerationForm provides a simple UI for changing moderation state.
17 class EntityModerationForm extends FormBase {
20 * The moderation information service.
22 * @var \Drupal\content_moderation\ModerationInformationInterface
24 protected $moderationInfo;
27 * The moderation state transition validation service.
29 * @var \Drupal\content_moderation\StateTransitionValidation
31 protected $validation;
34 * EntityModerationForm constructor.
36 * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
37 * The moderation information service.
38 * @param \Drupal\content_moderation\StateTransitionValidation $validation
39 * The moderation state transition validation service.
41 public function __construct(ModerationInformationInterface $moderation_info, StateTransitionValidation $validation) {
42 $this->moderationInfo = $moderation_info;
43 $this->validation = $validation;
49 public static function create(ContainerInterface $container) {
51 $container->get('content_moderation.moderation_information'),
52 $container->get('content_moderation.state_transition_validation')
59 public function getFormId() {
60 return 'content_moderation_entity_moderation_form';
66 public function buildForm(array $form, FormStateInterface $form_state, ContentEntityInterface $entity = NULL) {
67 $current_state = $entity->moderation_state->value;
68 $workflow = $this->moderationInfo->getWorkflowForEntity($entity);
70 /** @var \Drupal\workflows\Transition[] $transitions */
71 $transitions = $this->validation->getValidTransitions($entity, $this->currentUser());
73 // Exclude self-transitions.
74 $transitions = array_filter($transitions, function(Transition $transition) use ($current_state) {
75 return $transition->to()->id() != $current_state;
80 foreach ($transitions as $transition) {
81 $target_states[$transition->to()->id()] = $transition->to()->label();
84 if (!count($target_states)) {
91 '#title' => $this->t('Status'),
92 '#markup' => $workflow->getState($current_state)->label(),
96 // Persist the entity so we can access it in the submit handler.
97 $form_state->set('entity', $entity);
99 $form['new_state'] = [
101 '#title' => $this->t('Moderate'),
102 '#options' => $target_states,
105 $form['revision_log'] = [
106 '#type' => 'textfield',
107 '#title' => $this->t('Log message'),
113 '#value' => $this->t('Apply'),
116 $form['#theme'] = ['entity_moderation_form'];
124 public function submitForm(array &$form, FormStateInterface $form_state) {
125 /** @var ContentEntityInterface $entity */
126 $entity = $form_state->get('entity');
128 $new_state = $form_state->getValue('new_state');
130 $entity->set('moderation_state', $new_state);
132 if ($entity instanceof RevisionLogInterface) {
133 $entity->setRevisionLogMessage($form_state->getValue('revision_log'));
134 $entity->setRevisionUserId($this->currentUser()->id());
138 drupal_set_message($this->t('The moderation state has been updated.'));
140 $new_state = $this->moderationInfo->getWorkflowForEntity($entity)->getState($new_state);
141 // The page we're on likely won't be visible if we just set the entity to
142 // the default state, as we hide that latest-revision tab if there is no
143 // forward revision. Redirect to the canonical URL instead, since that will
145 if ($new_state->isDefaultRevisionState()) {
146 $form_state->setRedirectUrl($entity->toUrl('canonical'));