Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / modules / content_moderation / src / EntityTypeInfo.php
index 666ee2647ff59518f6b6dd1aaa44ecb0d744cd46..c03cf4922036a6bf5afdb619aaf66924b41e7c2b 100644 (file)
@@ -7,10 +7,12 @@ use Drupal\Core\Entity\BundleEntityFormBase;
 use Drupal\Core\Entity\ContentEntityFormInterface;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Entity\ContentEntityTypeInterface;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\Form\FormInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
@@ -268,6 +270,40 @@ class EntityTypeInfo implements ContainerInjectionInterface {
     return $fields;
   }
 
+  /**
+   * Replaces the entity form entity object with a proper revision object.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity being edited.
+   * @param string $operation
+   *   The entity form operation.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The form state.
+   *
+   * @see hook_entity_prepare_form()
+   */
+  public function entityPrepareForm(EntityInterface $entity, $operation, FormStateInterface $form_state) {
+    /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */
+    $form_object = $form_state->getFormObject();
+
+    if ($this->isModeratedEntityEditForm($form_object) && !$entity->isNew()) {
+      // Generate a proper revision object for the current entity. This allows
+      // to correctly handle translatable entities having pending revisions.
+      /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
+      $storage = $this->entityTypeManager->getStorage($entity->getEntityTypeId());
+      /** @var \Drupal\Core\Entity\ContentEntityInterface $new_revision */
+      $new_revision = $storage->createRevision($entity, FALSE);
+
+      // Restore the revision ID as other modules may expect to find it still
+      // populated. This will reset the "new revision" flag, however the entity
+      // object will be marked as a new revision again on submit.
+      // @see \Drupal\Core\Entity\ContentEntityForm::buildEntity()
+      $revision_key = $new_revision->getEntityType()->getKey('revision');
+      $new_revision->set($revision_key, $new_revision->getLoadedRevisionId());
+      $form_object->setEntity($new_revision);
+    }
+  }
+
   /**
    * Alters bundle forms to enforce revision handling.
    *
@@ -291,57 +327,15 @@ class EntityTypeInfo implements ContainerInjectionInterface {
         $this->entityTypeManager->getHandler($config_entity_type->getBundleOf(), 'moderation')->enforceRevisionsBundleFormAlter($form, $form_state, $form_id);
       }
     }
-    elseif ($form_object instanceof ContentEntityFormInterface && in_array($form_object->getOperation(), ['edit', 'default'])) {
+    elseif ($this->isModeratedEntityEditForm($form_object)) {
+      /** @var \Drupal\Core\Entity\ContentEntityFormInterface $form_object */
+      /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
       $entity = $form_object->getEntity();
       if ($this->moderationInfo->isModeratedEntity($entity)) {
         $this->entityTypeManager
           ->getHandler($entity->getEntityTypeId(), 'moderation')
           ->enforceRevisionsEntityFormAlter($form, $form_state, $form_id);
 
-        if (!$this->moderationInfo->isPendingRevisionAllowed($entity)) {
-          $latest_revision = $this->moderationInfo->getLatestRevision($entity->getEntityTypeId(), $entity->id());
-          if ($entity->bundle()) {
-            $bundle_type_id = $entity->getEntityType()->getBundleEntityType();
-            $bundle = $this->entityTypeManager->getStorage($bundle_type_id)->load($entity->bundle());
-            $type_label = $bundle->label();
-          }
-          else {
-            $type_label = $entity->getEntityType()->getLabel();
-          }
-
-          $translation = $this->moderationInfo->getAffectedRevisionTranslation($latest_revision);
-          $args = [
-            '@type_label' => $type_label,
-            '@latest_revision_edit_url' => $translation->toUrl('edit-form', ['language' => $translation->language()])->toString(),
-            '@latest_revision_delete_url' => $translation->toUrl('delete-form', ['language' => $translation->language()])->toString(),
-          ];
-          $label = $this->t('Unable to save this @type_label.', $args);
-          $message = $this->t('<a href="@latest_revision_edit_url">Publish</a> or <a href="@latest_revision_delete_url">delete</a> the latest revision to allow all workflow transitions.', $args);
-          $full_message = $this->t('Unable to save this @type_label. <a href="@latest_revision_edit_url">Publish</a> or <a href="@latest_revision_delete_url">delete</a> the latest revision to allow all workflow transitions.', $args);
-          drupal_set_message($full_message, 'error');
-
-          $form['moderation_state']['#access'] = FALSE;
-          $form['actions']['#access'] = FALSE;
-          $form['invalid_transitions'] = [
-            'label' => [
-              '#type' => 'item',
-              '#prefix' => '<strong class="label">',
-              '#markup' => $label,
-              '#suffix' => '</strong>',
-            ],
-            'message' => [
-              '#type' => 'item',
-              '#markup' => $message,
-            ],
-            '#weight' => 999,
-            '#no_valid_transitions' => TRUE,
-          ];
-
-          if ($form['footer']) {
-            $form['invalid_transitions']['#group'] = 'footer';
-          }
-        }
-
         // Submit handler to redirect to the latest version, if available.
         $form['actions']['submit']['#submit'][] = [EntityTypeInfo::class, 'bundleFormRedirect'];
 
@@ -351,15 +345,30 @@ class EntityTypeInfo implements ContainerInjectionInterface {
           $form['moderation_state']['#group'] = 'footer';
         }
 
-        // Duplicate the label of the current moderation state to the meta
-        // region, if available.
+        // If the publishing status exists in the meta region, replace it with
+        // the current state instead.
         if (isset($form['meta']['published'])) {
-          $form['meta']['published']['#markup'] = $form['moderation_state']['widget'][0]['current']['#markup'];
+          $form['meta']['published']['#markup'] = $this->moderationInfo->getWorkflowForEntity($entity)->getTypePlugin()->getState($entity->moderation_state->value)->label();
         }
       }
     }
   }
 
+  /**
+   * Checks whether the specified form allows to edit a moderated entity.
+   *
+   * @param \Drupal\Core\Form\FormInterface $form_object
+   *   The form object.
+   *
+   * @return bool
+   *   TRUE if the form should get form moderation, FALSE otherwise.
+   */
+  protected function isModeratedEntityEditForm(FormInterface $form_object) {
+    return $form_object instanceof ContentEntityFormInterface &&
+      in_array($form_object->getOperation(), ['edit', 'default'], TRUE) &&
+      $this->moderationInfo->isModeratedEntity($form_object->getEntity());
+  }
+
   /**
    * Redirect content entity edit forms on save, if there is a pending revision.
    *