updated core to 8.6.1 via composer
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- content_moderation
|
||||
id: editorial
|
||||
label: 'Editorial'
|
||||
type: content_moderation
|
||||
type_settings:
|
||||
states:
|
||||
archived:
|
||||
label: Archived
|
||||
weight: 5
|
||||
published: false
|
||||
default_revision: true
|
||||
draft:
|
||||
label: Draft
|
||||
published: false
|
||||
default_revision: false
|
||||
weight: -5
|
||||
published:
|
||||
label: Published
|
||||
published: true
|
||||
default_revision: true
|
||||
weight: 0
|
||||
transitions:
|
||||
archive:
|
||||
label: Archive
|
||||
from:
|
||||
- published
|
||||
to: archived
|
||||
weight: 2
|
||||
archived_draft:
|
||||
label: 'Restore to Draft'
|
||||
from:
|
||||
- archived
|
||||
to: draft
|
||||
weight: 3
|
||||
archived_published:
|
||||
label: Restore
|
||||
from:
|
||||
- archived
|
||||
to: published
|
||||
weight: 4
|
||||
create_new_draft:
|
||||
label: 'Create New Draft'
|
||||
to: draft
|
||||
weight: 0
|
||||
from:
|
||||
- draft
|
||||
- published
|
||||
publish:
|
||||
label: Publish
|
||||
to: published
|
||||
weight: 1
|
||||
from:
|
||||
- draft
|
||||
- published
|
||||
entity_types: { }
|
||||
@@ -6,4 +6,4 @@ core: 8.x
|
||||
package: Core
|
||||
configure: entity.workflow.collection
|
||||
dependencies:
|
||||
- workflows
|
||||
- drupal:workflows
|
||||
|
||||
@@ -5,6 +5,21 @@
|
||||
* Install, update and uninstall functions for the Content Moderation module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function content_moderation_requirements($phase) {
|
||||
$requirements = [];
|
||||
if ($phase === 'install' && \Drupal::moduleHandler()->moduleExists('workspaces')) {
|
||||
$requirements['workspaces_incompatibility'] = [
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
'description' => t('Content Moderation can not be installed when Workspaces is also installed.'),
|
||||
];
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the 'content_revision_tracker' table.
|
||||
*/
|
||||
|
||||
@@ -196,7 +196,7 @@ function content_moderation_entity_access(EntityInterface $entity, $operation, A
|
||||
$transition_validation = \Drupal::service('content_moderation.state_transition_validation');
|
||||
|
||||
$valid_transition_targets = $transition_validation->getValidTransitions($entity, $account);
|
||||
$access_result = $valid_transition_targets ? AccessResult::neutral() : AccessResult::forbidden();
|
||||
$access_result = $valid_transition_targets ? AccessResult::neutral() : AccessResult::forbidden('No valid transitions exist for given account.');
|
||||
|
||||
$access_result->addCacheableDependency($entity);
|
||||
$access_result->addCacheableDependency($account);
|
||||
@@ -224,7 +224,7 @@ function content_moderation_entity_field_access($operation, FieldDefinitionInter
|
||||
|
||||
// Deny edit access to the published field if the entity is being moderated.
|
||||
if ($entity_type->hasKey('published') && $moderation_info->isModeratedEntity($entity) && $entity->moderation_state && $field_definition->getName() == $entity_type->getKey('published')) {
|
||||
return AccessResult::forbidden();
|
||||
return AccessResult::forbidden('Cannot edit the published field of moderated entities.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ function content_moderation_post_update_update_cms_default_revisions(&$sandbox)
|
||||
$entity_type_id = &$sandbox['entity_type_id'];
|
||||
if (!isset($entity_type_id)) {
|
||||
$sandbox['bundles'] = [];
|
||||
$sandbox['entity_type_ids'] = [];
|
||||
/** @var \Drupal\workflows\WorkflowInterface $workflow */
|
||||
foreach (Workflow::loadMultipleByType('content_moderation') as $workflow) {
|
||||
/** @var \Drupal\content_moderation\Plugin\WorkflowType\ContentModeration $plugin */
|
||||
|
||||
@@ -68,7 +68,7 @@ class LatestRevisionCheck implements AccessInterface {
|
||||
return $access_result->addCacheableDependency($entity);
|
||||
}
|
||||
|
||||
return AccessResult::forbidden()->addCacheableDependency($entity);
|
||||
return AccessResult::forbidden('No pending revision for moderated entity.')->addCacheableDependency($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,12 +25,16 @@ class ContentModerationStateStorageSchema extends SqlContentEntityStorageSchema
|
||||
'workflow',
|
||||
'langcode',
|
||||
];
|
||||
$schema['content_moderation_state_field_data']['unique keys'] += [
|
||||
'content_moderation_state__lookup' => $unique_keys,
|
||||
];
|
||||
$schema['content_moderation_state_field_revision']['unique keys'] += [
|
||||
'content_moderation_state__lookup' => $unique_keys,
|
||||
];
|
||||
if ($data_table = $this->storage->getDataTable()) {
|
||||
$schema[$data_table]['unique keys'] += [
|
||||
'content_moderation_state__lookup' => $unique_keys,
|
||||
];
|
||||
}
|
||||
if ($revision_data_table = $this->storage->getRevisionDataTable()) {
|
||||
$schema[$revision_data_table]['unique keys'] += [
|
||||
'content_moderation_state__lookup' => $unique_keys,
|
||||
];
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ class ModeratedContentController extends ControllerBase {
|
||||
* Provides the listing page for moderated nodes.
|
||||
*
|
||||
* @return array
|
||||
* A render array as expected by drupal_render().
|
||||
* A render array as expected by
|
||||
* \Drupal\Core\Render\RendererInterface::render().
|
||||
*/
|
||||
public function nodeListing() {
|
||||
$entity_type = $this->entityTypeManager()->getDefinition('node');
|
||||
|
||||
@@ -54,7 +54,7 @@ class NodeModerationHandler extends ModerationHandler {
|
||||
*/
|
||||
public function enforceRevisionsBundleFormAlter(array &$form, FormStateInterface $form_state, $form_id) {
|
||||
// Force the revision checkbox on.
|
||||
$form['workflow']['options']['#default_value']['revision'] = 'revision';
|
||||
$form['workflow']['options']['#value']['revision'] = 'revision';
|
||||
$form['workflow']['options']['revision']['#disabled'] = TRUE;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ class EntityModerationRouteProvider implements EntityRouteProviderInterface, Ent
|
||||
'_title_callback' => '\Drupal\Core\Entity\Controller\EntityController::title',
|
||||
])
|
||||
// If the entity type is a node, unpublished content will be visible
|
||||
// if the user has the "view all unpublished content" permission.
|
||||
// if the user has the "view any unpublished content" permission.
|
||||
->setRequirement('_entity_access', "{$entity_type_id}.view")
|
||||
->setRequirement('_content_moderation_latest_version', 'TRUE')
|
||||
->setOption('_content_moderation_entity_type', $entity_type_id)
|
||||
|
||||
@@ -5,8 +5,10 @@ namespace Drupal\content_moderation;
|
||||
use Drupal\content_moderation\Entity\ContentModerationState as ContentModerationStateEntity;
|
||||
use Drupal\content_moderation\Entity\ContentModerationStateInterface;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityPublishedInterface;
|
||||
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
@@ -203,7 +205,6 @@ class EntityOperations implements ContainerInjectionInterface {
|
||||
$moderation_state = $workflow->getTypePlugin()->getInitialState($entity)->id();
|
||||
}
|
||||
|
||||
// @todo what if $entity->moderation_state is null at this point?
|
||||
$content_moderation_state->set('content_entity_revision_id', $entity_revision_id);
|
||||
$content_moderation_state->set('moderation_state', $moderation_state);
|
||||
ContentModerationStateEntity::updateOrCreateFromEntity($content_moderation_state);
|
||||
@@ -279,17 +280,39 @@ class EntityOperations implements ContainerInjectionInterface {
|
||||
// The moderation form should be displayed only when viewing the latest
|
||||
// (translation-affecting) revision, unless it was created as published
|
||||
// default revision.
|
||||
if (!$entity->isLatestRevision() && !$entity->isLatestTranslationAffectedRevision()) {
|
||||
if (($entity->isDefaultRevision() || $entity->wasDefaultRevision()) && $this->isPublished($entity)) {
|
||||
return;
|
||||
}
|
||||
if (($entity->isDefaultRevision() || $entity->wasDefaultRevision()) && ($moderation_state = $entity->get('moderation_state')->value)) {
|
||||
$workflow = $this->moderationInfo->getWorkflowForEntity($entity);
|
||||
if ($workflow->getTypePlugin()->getState($moderation_state)->isPublishedState()) {
|
||||
return;
|
||||
}
|
||||
if (!$entity->isLatestRevision() && !$entity->isLatestTranslationAffectedRevision()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$build['content_moderation_control'] = $this->formBuilder->getForm(EntityModerationForm::class, $entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity is published.
|
||||
*
|
||||
* This method is optimized to not have to unnecessarily load the moderation
|
||||
* state and workflow if it is not required.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
|
||||
* The entity to check.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the entity is published, FALSE otherwise.
|
||||
*/
|
||||
protected function isPublished(ContentEntityInterface $entity) {
|
||||
// If the entity implements EntityPublishedInterface directly, check that
|
||||
// first, otherwise fall back to check through the workflow state.
|
||||
if ($entity instanceof EntityPublishedInterface) {
|
||||
return $entity->isPublished();
|
||||
}
|
||||
if ($moderation_state = $entity->get('moderation_state')->value) {
|
||||
$workflow = $this->moderationInfo->getWorkflowForEntity($entity);
|
||||
return $workflow->getTypePlugin()->getState($moderation_state)->isPublishedState();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -119,7 +119,6 @@ class EntityTypeInfo implements ContainerInjectionInterface {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds Moderation configuration to appropriate entity types.
|
||||
*
|
||||
@@ -131,7 +130,7 @@ class EntityTypeInfo implements ContainerInjectionInterface {
|
||||
public function entityTypeAlter(array &$entity_types) {
|
||||
foreach ($entity_types as $entity_type_id => $entity_type) {
|
||||
// The ContentModerationState entity type should never be moderated.
|
||||
if ($entity_type->isRevisionable() && $entity_type_id != 'content_moderation_state') {
|
||||
if ($entity_type->isRevisionable() && !$entity_type->isInternal()) {
|
||||
$entity_types[$entity_type_id] = $this->addModerationToEntityType($entity_type);
|
||||
}
|
||||
}
|
||||
|
||||
+25
-2
@@ -9,8 +9,10 @@ use Drupal\Core\Ajax\CloseDialogCommand;
|
||||
use Drupal\Core\Ajax\HtmlCommand;
|
||||
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\workflows\WorkflowInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
@@ -57,6 +59,13 @@ class ContentModerationConfigureEntityTypesForm extends FormBase {
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* The Messenger service.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -64,17 +73,19 @@ class ContentModerationConfigureEntityTypesForm extends FormBase {
|
||||
return new static(
|
||||
$container->get('entity_type.manager'),
|
||||
$container->get('entity_type.bundle.info'),
|
||||
$container->get('content_moderation.moderation_information')
|
||||
$container->get('content_moderation.moderation_information'),
|
||||
$container->get('messenger')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $bundle_info, ModerationInformationInterface $moderation_information) {
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $bundle_info, ModerationInformationInterface $moderation_information, MessengerInterface $messenger) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->bundleInfo = $bundle_info;
|
||||
$this->moderationInformation = $moderation_information;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,6 +119,7 @@ class ContentModerationConfigureEntityTypesForm extends FormBase {
|
||||
// Add the bundle to the options if it's not enabled on a workflow,
|
||||
// unless the workflow it's enabled on is this one.
|
||||
$options[$bundle_id] = [
|
||||
'title' => ['data' => ['#title' => $bundle['label']]],
|
||||
'type' => $bundle['label'],
|
||||
];
|
||||
// Add the bundle to the list of default values if it's enabled on this
|
||||
@@ -132,6 +144,17 @@ class ContentModerationConfigureEntityTypesForm extends FormBase {
|
||||
];
|
||||
}
|
||||
|
||||
// Get unsupported features for this entity type.
|
||||
$warnings = $this->moderationInformation->getUnsupportedFeatures($this->entityType);
|
||||
// Display message into the Ajax form returned.
|
||||
if ($this->getRequest()->get(MainContentViewSubscriber::WRAPPER_FORMAT) == 'drupal_modal' && !empty($warnings)) {
|
||||
$form['warnings'] = ['#type' => 'status_messages', '#weight' => -1];
|
||||
}
|
||||
// Set warning message.
|
||||
foreach ($warnings as $warning) {
|
||||
$this->messenger->addWarning($warning);
|
||||
}
|
||||
|
||||
$form['actions'] = ['#type' => 'actions'];
|
||||
$form['actions']['submit'] = [
|
||||
'#type' => 'submit',
|
||||
|
||||
@@ -68,7 +68,7 @@ class ContentModerationConfigureForm extends WorkflowTypeConfigureFormBase imple
|
||||
|
||||
$header = [
|
||||
'type' => $this->t('Items'),
|
||||
'operations' => $this->t('Operations')
|
||||
'operations' => $this->t('Operations'),
|
||||
];
|
||||
$form['entity_types_container'] = [
|
||||
'#type' => 'details',
|
||||
@@ -108,7 +108,7 @@ class ContentModerationConfigureForm extends WorkflowTypeConfigureFormBase imple
|
||||
'label' => $this->t('@bundle types', ['@bundle' => $entity_type->getLabel()]),
|
||||
'entity_type_id' => $entity_type->id(),
|
||||
'selected_bundles' => $selected_bundles_list,
|
||||
]
|
||||
],
|
||||
],
|
||||
'operations' => [
|
||||
'#type' => 'operations',
|
||||
|
||||
@@ -128,6 +128,7 @@ class EntityModerationForm extends FormBase {
|
||||
];
|
||||
|
||||
$form['#theme'] = ['entity_moderation_form'];
|
||||
$form['#attached']['library'][] = 'content_moderation/content_moderation';
|
||||
|
||||
return $form;
|
||||
}
|
||||
@@ -153,7 +154,7 @@ class EntityModerationForm extends FormBase {
|
||||
}
|
||||
$entity->save();
|
||||
|
||||
drupal_set_message($this->t('The moderation state has been updated.'));
|
||||
$this->messenger()->addStatus($this->t('The moderation state has been updated.'));
|
||||
|
||||
$new_state = $this->moderationInfo->getWorkflowForEntity($entity)->getTypePlugin()->getState($new_state);
|
||||
// The page we're on likely won't be visible if we just set the entity to
|
||||
|
||||
@@ -4,16 +4,20 @@ namespace Drupal\content_moderation;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityPublishedInterface;
|
||||
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\TypedData\TranslatableInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* General service for moderation-related questions about Entity API.
|
||||
*/
|
||||
class ModerationInformation implements ModerationInformationInterface {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* The entity type manager.
|
||||
*
|
||||
@@ -171,6 +175,10 @@ class ModerationInformation implements ModerationInformationInterface {
|
||||
public function isDefaultRevisionPublished(ContentEntityInterface $entity) {
|
||||
$workflow = $this->getWorkflowForEntity($entity);
|
||||
$default_revision = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId())->load($entity->id());
|
||||
// If no default revision could be loaded, the entity has not yet been
|
||||
// saved. In this case the moderation_state of the unsaved entity can be
|
||||
// used, since once saved it will become the default.
|
||||
$default_revision = $default_revision ?: $entity;
|
||||
|
||||
// Ensure we are checking all translations of the default revision.
|
||||
if ($default_revision instanceof TranslatableInterface && $default_revision->isTranslatable()) {
|
||||
@@ -205,4 +213,16 @@ class ModerationInformation implements ModerationInformationInterface {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUnsupportedFeatures(EntityTypeInterface $entity_type) {
|
||||
$features = [];
|
||||
// Test if entity is publishable.
|
||||
if (!$entity_type->entityClassImplements(EntityPublishedInterface::class)) {
|
||||
$features['publishing'] = $this->t("@entity_type_plural_label do not support publishing statuses. For example, even after transitioning from a published workflow state to an unpublished workflow state they will still be visible to site visitors.", ['@entity_type_plural_label' => $entity_type->getCollectionLabel()]);
|
||||
}
|
||||
return $features;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -163,4 +163,15 @@ interface ModerationInformationInterface {
|
||||
*/
|
||||
public function getWorkflowForEntity(ContentEntityInterface $entity);
|
||||
|
||||
/**
|
||||
* Gets unsupported features for a given entity type.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type to get the unsupported features for.
|
||||
*
|
||||
* @return array
|
||||
* An array of unsupported features for this entity type.
|
||||
*/
|
||||
public function getUnsupportedFeatures(EntityTypeInterface $entity_type);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Action\Plugin\Action\PublishAction;
|
||||
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\content_moderation\ModerationInformationInterface;
|
||||
@@ -32,6 +33,13 @@ class ModerationOptOutPublish extends PublishAction implements ContainerFactoryP
|
||||
*/
|
||||
protected $bundleInfo;
|
||||
|
||||
/**
|
||||
* Messenger service.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* ModerationOptOutPublish constructor.
|
||||
*
|
||||
@@ -47,11 +55,14 @@ class ModerationOptOutPublish extends PublishAction implements ContainerFactoryP
|
||||
* The moderation information service.
|
||||
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info
|
||||
* Bundle info service.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* Messenger service.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_info, EntityTypeBundleInfoInterface $bundle_info) {
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_info, EntityTypeBundleInfoInterface $bundle_info, MessengerInterface $messenger) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
|
||||
$this->moderationInfo = $moderation_info;
|
||||
$this->bundleInfo = $bundle_info;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +73,8 @@ class ModerationOptOutPublish extends PublishAction implements ContainerFactoryP
|
||||
$configuration, $plugin_id, $plugin_definition,
|
||||
$container->get('entity_type.manager'),
|
||||
$container->get('content_moderation.moderation_information'),
|
||||
$container->get('entity_type.bundle.info')
|
||||
$container->get('entity_type.bundle.info'),
|
||||
$container->get('messenger')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -74,8 +86,11 @@ class ModerationOptOutPublish extends PublishAction implements ContainerFactoryP
|
||||
if ($entity && $this->moderationInfo->isModeratedEntity($entity)) {
|
||||
$bundle_info = $this->bundleInfo->getBundleInfo($entity->getEntityTypeId());
|
||||
$bundle_label = $bundle_info[$entity->bundle()]['label'];
|
||||
drupal_set_message($this->t("@bundle @label were skipped as they are under moderation and may not be directly published.", ['@bundle' => $bundle_label, '@label' => $entity->getEntityType()->getPluralLabel()]), 'warning');
|
||||
$result = AccessResult::forbidden();
|
||||
$this->messenger->addWarning($this->t("@bundle @label were skipped as they are under moderation and may not be directly published.", [
|
||||
'@bundle' => $bundle_label,
|
||||
'@label' => $entity->getEntityType()->getPluralLabel(),
|
||||
]));
|
||||
$result = AccessResult::forbidden('Cannot directly publish moderated entities.');
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
return parent::access($entity, $account, $return_as_object);
|
||||
|
||||
@@ -6,6 +6,7 @@ use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Action\Plugin\Action\UnpublishAction;
|
||||
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\content_moderation\ModerationInformationInterface;
|
||||
@@ -32,6 +33,13 @@ class ModerationOptOutUnpublish extends UnpublishAction implements ContainerFact
|
||||
*/
|
||||
protected $bundleInfo;
|
||||
|
||||
/**
|
||||
* Messenger service.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* ModerationOptOutUnpublish constructor.
|
||||
*
|
||||
@@ -47,11 +55,14 @@ class ModerationOptOutUnpublish extends UnpublishAction implements ContainerFact
|
||||
* The moderation information service.
|
||||
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info
|
||||
* Bundle info service.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* Messenger service.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_info, EntityTypeBundleInfoInterface $bundle_info) {
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_info, EntityTypeBundleInfoInterface $bundle_info, MessengerInterface $messenger) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
|
||||
$this->moderationInfo = $moderation_info;
|
||||
$this->bundleInfo = $bundle_info;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +73,8 @@ class ModerationOptOutUnpublish extends UnpublishAction implements ContainerFact
|
||||
$configuration, $plugin_id, $plugin_definition,
|
||||
$container->get('entity_type.manager'),
|
||||
$container->get('content_moderation.moderation_information'),
|
||||
$container->get('entity_type.bundle.info')
|
||||
$container->get('entity_type.bundle.info'),
|
||||
$container->get('messenger')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -74,8 +86,11 @@ class ModerationOptOutUnpublish extends UnpublishAction implements ContainerFact
|
||||
if ($entity && $this->moderationInfo->isModeratedEntity($entity)) {
|
||||
$bundle_info = $this->bundleInfo->getBundleInfo($entity->getEntityTypeId());
|
||||
$bundle_label = $bundle_info[$entity->bundle()]['label'];
|
||||
drupal_set_message($this->t("@bundle @label were skipped as they are under moderation and may not be directly unpublished.", ['@bundle' => $bundle_label, '@label' => $entity->getEntityType()->getPluralLabel()]), 'warning');
|
||||
$result = AccessResult::forbidden();
|
||||
$this->messenger->addWarning($this->t("@bundle @label were skipped as they are under moderation and may not be directly unpublished.", [
|
||||
'@bundle' => $bundle_label,
|
||||
'@label' => $entity->getEntityType()->getPluralLabel(),
|
||||
]));
|
||||
$result = AccessResult::forbidden('Cannot directly unpublish moderated entities.');
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
return parent::access($entity, $account, $return_as_object);
|
||||
|
||||
@@ -131,6 +131,9 @@ class ModerationStateWidget extends OptionsSelectWidget implements ContainerFact
|
||||
foreach ($transitions as $transition) {
|
||||
$transition_to_state = $transition->to();
|
||||
$transition_labels[$transition_to_state->id()] = $transition_to_state->label();
|
||||
if ($default->id() === $transition_to_state->id()) {
|
||||
$default_value = $default->id();
|
||||
}
|
||||
}
|
||||
|
||||
$element += [
|
||||
|
||||
@@ -88,7 +88,7 @@ class ModerationStateFieldItemList extends FieldItemList {
|
||||
$moderation_info = \Drupal::service('content_moderation.moderation_information');
|
||||
$content_moderation_storage = \Drupal::entityTypeManager()->getStorage('content_moderation_state');
|
||||
|
||||
$revisions = \Drupal::service('entity.query')->get('content_moderation_state')
|
||||
$revisions = $content_moderation_storage->getQuery()
|
||||
->condition('content_entity_type_id', $entity->getEntityTypeId())
|
||||
->condition('content_entity_id', $entity->id())
|
||||
// Ensure the correct revision is loaded in scenarios where a revision is
|
||||
@@ -141,11 +141,13 @@ class ModerationStateFieldItemList extends FieldItemList {
|
||||
public function setValue($values, $notify = TRUE) {
|
||||
parent::setValue($values, $notify);
|
||||
|
||||
if (isset($this->list[0])) {
|
||||
$this->valueComputed = TRUE;
|
||||
}
|
||||
// If the parent created a field item and if the parent should be notified
|
||||
// about the change (e.g. this is not initialized with the current value),
|
||||
// update the moderated entity.
|
||||
if (isset($this->list[0]) && $notify) {
|
||||
$this->valueComputed = TRUE;
|
||||
$this->updateModeratedEntity($this->list[0]->value);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ class ModerationStateConstraintValidator extends ConstraintValidator implements
|
||||
if (!$original_state->canTransitionTo($new_state->id())) {
|
||||
$this->context->addViolation($constraint->message, [
|
||||
'%from' => $original_state->label(),
|
||||
'%to' => $new_state->label()
|
||||
'%to' => $new_state->label(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{{ attach_library('content_moderation/content_moderation') }}
|
||||
<ul class="entity-moderation-form">
|
||||
<li class="entity-moderation-form__item">{{ form.current }}</li>
|
||||
<li class="entity-moderation-form__item">{{ form.new_state }}</li>
|
||||
|
||||
+2
-2
@@ -5,5 +5,5 @@ package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- content_moderation
|
||||
- node
|
||||
- drupal:content_moderation
|
||||
- drupal:node
|
||||
|
||||
-1
@@ -258,4 +258,3 @@ display:
|
||||
- user.permissions
|
||||
tags:
|
||||
- 'config:workflow_list'
|
||||
|
||||
|
||||
-1
@@ -220,4 +220,3 @@ display:
|
||||
- user.permissions
|
||||
tags:
|
||||
- 'config:workflow_list'
|
||||
|
||||
|
||||
-1
@@ -165,4 +165,3 @@ display:
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
tags: { }
|
||||
|
||||
|
||||
-1
@@ -215,4 +215,3 @@ display:
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
tags: { }
|
||||
|
||||
|
||||
+4
-4
@@ -5,7 +5,7 @@ package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- content_moderation
|
||||
- node
|
||||
- views
|
||||
- entity_test
|
||||
- drupal:content_moderation
|
||||
- drupal:node
|
||||
- drupal:views
|
||||
- drupal:entity_test
|
||||
|
||||
+7
-1
@@ -19,6 +19,7 @@ class ContentModerationWorkflowTypeTest extends BrowserTestBase {
|
||||
public static $modules = [
|
||||
'content_moderation',
|
||||
'node',
|
||||
'entity_test',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -92,10 +93,15 @@ class ContentModerationWorkflowTypeTest extends BrowserTestBase {
|
||||
$session->fieldDisabled('type_settings[default_revision]');
|
||||
|
||||
$this->drupalGet('admin/config/workflow/workflows/manage/test/type/node');
|
||||
$session->pageTextContains('Select the content type entities for the Test workflow');
|
||||
$session->pageTextContains('Select the content types for the Test workflow');
|
||||
foreach ($types as $type) {
|
||||
$session->pageTextContains($type->label());
|
||||
$session->elementContains('css', sprintf('.form-item-bundles-%s label', $type->id()), sprintf('Update %s', $type->label()));
|
||||
}
|
||||
|
||||
// Ensure warning message are displayed for unsupported features.
|
||||
$this->drupalGet('admin/config/workflow/workflows/manage/test/type/entity_test_rev');
|
||||
$this->assertSession()->pageTextContains('Test entity - revisions entities do not support publishing statuses. For example, even after transitioning from a published workflow state to an unpublished workflow state they will still be visible to site visitors.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-1
@@ -9,6 +9,7 @@ use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
* Test updating the ContentModerationState entity default revisions.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
* @see content_moderation_post_update_update_cms_default_revisions
|
||||
*/
|
||||
class DefaultContentModerationStateRevisionUpdateTest extends UpdatePathTestBase {
|
||||
@@ -20,7 +21,6 @@ class DefaultContentModerationStateRevisionUpdateTest extends UpdatePathTestBase
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.4.0.bare.standard.php.gz',
|
||||
__DIR__ . '/../../fixtures/update/drupal-8.4.0-content_moderation_installed.php',
|
||||
__DIR__ . '/../../fixtures/update/drupal-8.default-cms-entity-id-2941736.php',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -28,6 +28,11 @@ class DefaultContentModerationStateRevisionUpdateTest extends UpdatePathTestBase
|
||||
* Test updating the default revision.
|
||||
*/
|
||||
public function testUpdateDefaultRevision() {
|
||||
// Include the database fixture required to test updating the default
|
||||
// revision. This is excluded from ::setDatabaseDumpFiles so that we can
|
||||
// test the same post_update hook with no test content enabled.
|
||||
require __DIR__ . '/../../fixtures/update/drupal-8.default-cms-entity-id-2941736.php';
|
||||
|
||||
$this->runUpdates();
|
||||
|
||||
foreach (['node', 'block_content'] as $entity_type_id) {
|
||||
@@ -45,6 +50,14 @@ class DefaultContentModerationStateRevisionUpdateTest extends UpdatePathTestBase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the post_update hook when no entity types are being moderated.
|
||||
*/
|
||||
public function testNoEntitiesUnderModeration() {
|
||||
// If any errors occur during the post_update hook, the test case will fail.
|
||||
$this->runUpdates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert for the given entity, the default revision ID matches.
|
||||
*
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Drupal\Tests\content_moderation\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Tests moderated content administration page functionality.
|
||||
@@ -12,6 +12,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ModeratedContentViewTest extends BrowserTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* A user with permission to bypass access content.
|
||||
*
|
||||
@@ -34,7 +36,7 @@ class ModeratedContentViewTest extends BrowserTestBase {
|
||||
$this->drupalCreateContentType(['type' => 'article', 'name' => 'Article'])->save();
|
||||
$this->drupalCreateContentType(['type' => 'unmoderated_type', 'name' => 'Unmoderated type'])->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'page');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'article');
|
||||
$workflow->save();
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Drupal\Tests\content_moderation\Functional;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\simpletest\ContentTypeCreationTrait;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Test the content moderation actions.
|
||||
@@ -15,6 +15,7 @@ use Drupal\workflows\Entity\Workflow;
|
||||
class ModerationActionsTest extends BrowserTestBase {
|
||||
|
||||
use ContentTypeCreationTrait;
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
@@ -38,7 +39,7 @@ class ModerationActionsTest extends BrowserTestBase {
|
||||
$standard_bundle = $this->createContentType(['type' => 'standard_bundle']);
|
||||
$standard_bundle->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated_bundle');
|
||||
$workflow->save();
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Drupal\Tests\content_moderation\Functional;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
@@ -107,6 +106,10 @@ class ModerationFormTest extends ModerationStateTestBase {
|
||||
'moderation_state[0][state]' => 'published',
|
||||
], t('Save'));
|
||||
|
||||
// Check widget default value.
|
||||
$this->drupalGet($edit_path);
|
||||
$this->assertFieldByName('moderation_state[0][state]', 'published', 'The moderation default value is set correctly.');
|
||||
|
||||
// The published view should not have a moderation form, because it is the
|
||||
// live revision.
|
||||
$this->drupalGet($canonical_path);
|
||||
@@ -153,9 +156,8 @@ class ModerationFormTest extends ModerationStateTestBase {
|
||||
*/
|
||||
public function testNonBundleModerationForm() {
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_mulrevpub', 'entity_test_mulrevpub');
|
||||
$workflow->save();
|
||||
$this->workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_mulrevpub', 'entity_test_mulrevpub');
|
||||
$this->workflow->save();
|
||||
|
||||
// Create new moderated content in draft.
|
||||
$this->drupalPostForm('entity_test_mulrevpub/add', ['moderation_state[0][state]' => 'draft'], t('Save'));
|
||||
@@ -469,7 +471,7 @@ class ModerationFormTest extends ModerationStateTestBase {
|
||||
'edit own moderated_content content',
|
||||
'use editorial transition create_new_draft',
|
||||
'use editorial transition publish',
|
||||
'use editorial transition archive'
|
||||
'use editorial transition archive',
|
||||
]);
|
||||
$this->drupalLogin($user);
|
||||
$paths = [
|
||||
|
||||
@@ -482,6 +482,9 @@ class ModerationLocaleTest extends ModerationStateTestBase {
|
||||
protected function loadTranslation(NodeInterface $node, $langcode) {
|
||||
/** @var \Drupal\node\NodeStorageInterface $storage */
|
||||
$storage = $this->container->get('entity_type.manager')->getStorage('node');
|
||||
// Explicitly invalidate the cache for that node, as the call below is
|
||||
// statically cached.
|
||||
$storage->resetCache([$node->id()]);
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$node = $storage->loadRevision($storage->getLatestRevisionId($node->id()));
|
||||
return $node->getTranslation($langcode);
|
||||
|
||||
+3
-2
@@ -4,7 +4,7 @@ namespace Drupal\Tests\content_moderation\Functional;
|
||||
|
||||
use Drupal\simpletest\ContentTypeCreationTrait;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Test revision revert.
|
||||
@@ -14,6 +14,7 @@ use Drupal\workflows\Entity\Workflow;
|
||||
class ModerationRevisionRevertTest extends BrowserTestBase {
|
||||
|
||||
use ContentTypeCreationTrait;
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
@@ -34,7 +35,7 @@ class ModerationRevisionRevertTest extends BrowserTestBase {
|
||||
$moderated_bundle = $this->createContentType(['type' => 'moderated_bundle']);
|
||||
$moderated_bundle->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated_bundle');
|
||||
$workflow->save();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Drupal\Tests\content_moderation\Functional;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the view access control handler for moderation state entities.
|
||||
@@ -14,6 +14,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ModerationStateAccessTest extends BrowserTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -99,7 +101,7 @@ class ModerationStateAccessTest extends BrowserTestBase {
|
||||
]);
|
||||
$node_type->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', $machine_name);
|
||||
$workflow->save();
|
||||
return $node_type;
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
namespace Drupal\Tests\content_moderation\Functional;
|
||||
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
use Drupal\user\Entity\Role;
|
||||
|
||||
/**
|
||||
@@ -11,6 +13,8 @@ use Drupal\user\Entity\Role;
|
||||
*/
|
||||
abstract class ModerationStateTestBase extends BrowserTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Profile to use.
|
||||
*
|
||||
@@ -45,6 +49,13 @@ abstract class ModerationStateTestBase extends BrowserTestBase {
|
||||
'use editorial transition archived_published',
|
||||
];
|
||||
|
||||
/**
|
||||
* The editorial workflow entity.
|
||||
*
|
||||
* @var \Drupal\workflows\Entity\Workflow
|
||||
*/
|
||||
protected $workflow;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
@@ -63,6 +74,7 @@ abstract class ModerationStateTestBase extends BrowserTestBase {
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->workflow = $this->createEditorialWorkflow();
|
||||
$this->adminUser = $this->drupalCreateUser($this->permissions);
|
||||
$this->drupalPlaceBlock('local_tasks_block', ['id' => 'tabs_block']);
|
||||
$this->drupalPlaceBlock('page_title_block');
|
||||
@@ -110,6 +122,9 @@ abstract class ModerationStateTestBase extends BrowserTestBase {
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save content type'));
|
||||
|
||||
// Check the content type has been set to create new revisions.
|
||||
$this->assertTrue(NodeType::load($content_type_id)->isNewRevision());
|
||||
|
||||
if ($moderated) {
|
||||
$this->enableModerationThroughUi($content_type_id, $workflow_id);
|
||||
}
|
||||
|
||||
+7
-2
@@ -3,6 +3,7 @@
|
||||
namespace Drupal\Tests\content_moderation\Functional;
|
||||
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Views;
|
||||
@@ -17,6 +18,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ViewsModerationStateFilterTest extends ViewTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -45,6 +48,8 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
||||
'type' => 'example_b',
|
||||
])->save();
|
||||
|
||||
$this->createEditorialWorkflow();
|
||||
|
||||
$new_workflow = Workflow::create([
|
||||
'type' => 'content_moderation',
|
||||
'id' => 'new_workflow',
|
||||
@@ -201,11 +206,11 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
||||
return [
|
||||
'view on base table, filter on base table' => [
|
||||
'test_content_moderation_state_filter_base_table',
|
||||
'Content: Moderation state'
|
||||
'Content: Moderation state',
|
||||
],
|
||||
'view on base table, filter on revision table' => [
|
||||
'test_content_moderation_state_filter_base_table_filter_on_revision',
|
||||
'Content revision: Moderation state'
|
||||
'Content revision: Moderation state',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ class ContentModerationPermissionsTest extends KernelTestBase {
|
||||
],
|
||||
],
|
||||
],
|
||||
[]
|
||||
[],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
+4
-2
@@ -6,7 +6,7 @@ use Drupal\content_moderation\Entity\ContentModerationState;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Test the ContentModerationState storage schema.
|
||||
@@ -16,6 +16,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ContentModerationStateStorageSchemaTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -45,7 +47,7 @@ class ContentModerationStateStorageSchemaTest extends KernelTestBase {
|
||||
NodeType::create([
|
||||
'type' => 'example',
|
||||
])->save();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
|
||||
/**
|
||||
@@ -21,6 +22,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ContentModerationStateTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -275,7 +278,7 @@ class ContentModerationStateTest extends KernelTestBase {
|
||||
]);
|
||||
$node_type->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
@@ -388,7 +391,7 @@ class ContentModerationStateTest extends KernelTestBase {
|
||||
'type' => 'test_type',
|
||||
])->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'test_type');
|
||||
$workflow->save();
|
||||
|
||||
@@ -415,7 +418,7 @@ class ContentModerationStateTest extends KernelTestBase {
|
||||
* Tests that entities with special languages can be moderated.
|
||||
*/
|
||||
public function testModerationWithSpecialLanguages() {
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
|
||||
$workflow->save();
|
||||
|
||||
@@ -436,7 +439,7 @@ class ContentModerationStateTest extends KernelTestBase {
|
||||
* Tests that a non-translatable entity type with a langcode can be moderated.
|
||||
*/
|
||||
public function testNonTranslatableEntityTypeModeration() {
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
|
||||
$workflow->save();
|
||||
|
||||
@@ -470,7 +473,7 @@ class ContentModerationStateTest extends KernelTestBase {
|
||||
// Update the entity type in order to remove the 'langcode' field.
|
||||
\Drupal::entityDefinitionUpdateManager()->applyUpdates();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
|
||||
$workflow->save();
|
||||
|
||||
@@ -500,7 +503,7 @@ class ContentModerationStateTest extends KernelTestBase {
|
||||
]);
|
||||
$node_type->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
// Test both a config and non-config based bundle and entity type.
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
|
||||
@@ -520,7 +523,7 @@ class ContentModerationStateTest extends KernelTestBase {
|
||||
$this->assertEquals([
|
||||
'entity_test_no_bundle',
|
||||
'entity_test_rev',
|
||||
'node'
|
||||
'node',
|
||||
], $workflow->getTypePlugin()->getEntityTypes());
|
||||
|
||||
// Delete the node type and ensure it is removed from the workflow.
|
||||
@@ -543,7 +546,7 @@ class ContentModerationStateTest extends KernelTestBase {
|
||||
// Create a bundle not based on any particular configuration.
|
||||
entity_test_create_bundle('test_bundle');
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test', 'test_bundle');
|
||||
$workflow->save();
|
||||
|
||||
@@ -653,7 +656,7 @@ class ContentModerationStateTest extends KernelTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle($entity_type_id, $bundle_id);
|
||||
$workflow->save();
|
||||
|
||||
|
||||
+7
-5
@@ -6,7 +6,7 @@ use Drupal\Core\Config\ConfigImporterException;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Tests how Content Moderation handles workflow config changes.
|
||||
@@ -15,6 +15,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ContentModerationWorkflowConfigTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -57,13 +59,13 @@ class ContentModerationWorkflowConfigTest extends KernelTestBase {
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('content_moderation_state');
|
||||
$this->installConfig('content_moderation');
|
||||
$this->installConfig(['system', 'content_moderation']);
|
||||
|
||||
NodeType::create([
|
||||
'type' => 'example',
|
||||
])->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()
|
||||
->addState('test1', 'Test one')
|
||||
->addState('test2', 'Test two')
|
||||
@@ -118,7 +120,7 @@ class ContentModerationWorkflowConfigTest extends KernelTestBase {
|
||||
$this->fail('ConfigImporterException not thrown, invalid import was not stopped due to deleted state.');
|
||||
}
|
||||
catch (ConfigImporterException $e) {
|
||||
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
|
||||
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.' . PHP_EOL . 'The moderation state Test two is being used, but is not in the source storage.');
|
||||
$error_log = $this->configImporter->getErrors();
|
||||
$expected = ['The moderation state Test two is being used, but is not in the source storage.'];
|
||||
$this->assertEqual($expected, $error_log);
|
||||
@@ -132,7 +134,7 @@ class ContentModerationWorkflowConfigTest extends KernelTestBase {
|
||||
$this->fail('ConfigImporterException not thrown, invalid import was not stopped due to deleted workflow.');
|
||||
}
|
||||
catch (ConfigImporterException $e) {
|
||||
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
|
||||
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.' . PHP_EOL . 'The moderation state Test two is being used, but is not in the source storage.' . PHP_EOL . 'The workflow Editorial is being used, and cannot be deleted.');
|
||||
$error_log = $this->configImporter->getErrors();
|
||||
$expected = [
|
||||
'The moderation state Test two is being used, but is not in the source storage.',
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ class ContentModerationWorkflowTypeApiTest extends KernelTestBase {
|
||||
/**
|
||||
* A workflow for testing.
|
||||
*
|
||||
* @var \Drupal\workflows\Entity\Workflow;
|
||||
* @var \Drupal\workflows\Entity\Workflow
|
||||
*/
|
||||
protected $workflow;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the correct default revision is set.
|
||||
@@ -15,6 +15,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class DefaultRevisionStateTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -68,7 +70,7 @@ class DefaultRevisionStateTest extends KernelTestBase {
|
||||
|
||||
$this->container->get('content_translation.manager')->setEnabled('node', 'example', TRUE);
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Drupal\Tests\content_moderation\Kernel;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\content_moderation\EntityOperations
|
||||
@@ -14,6 +14,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class EntityOperationsTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -48,7 +50,7 @@ class EntityOperationsTest extends KernelTestBase {
|
||||
'label' => 'Page',
|
||||
]);
|
||||
$node_type->save();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'page');
|
||||
$workflow->save();
|
||||
}
|
||||
|
||||
+10
-8
@@ -6,7 +6,7 @@ use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\content_moderation\Plugin\Validation\Constraint\ModerationStateConstraintValidator
|
||||
@@ -14,6 +14,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class EntityStateChangeValidationTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -50,7 +52,7 @@ class EntityStateChangeValidationTest extends KernelTestBase {
|
||||
'type' => 'example',
|
||||
]);
|
||||
$node_type->save();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
@@ -78,7 +80,7 @@ class EntityStateChangeValidationTest extends KernelTestBase {
|
||||
'type' => 'example',
|
||||
]);
|
||||
$node_type->save();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
@@ -104,7 +106,7 @@ class EntityStateChangeValidationTest extends KernelTestBase {
|
||||
'type' => 'example',
|
||||
]);
|
||||
$node_type->save();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
@@ -136,7 +138,7 @@ class EntityStateChangeValidationTest extends KernelTestBase {
|
||||
|
||||
// Enable moderation to test validation on existing content, with no
|
||||
// explicit state.
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addState('deleted_state', 'Deleted state');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
@@ -169,7 +171,7 @@ class EntityStateChangeValidationTest extends KernelTestBase {
|
||||
]);
|
||||
$node_type->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
@@ -232,7 +234,7 @@ class EntityStateChangeValidationTest extends KernelTestBase {
|
||||
$nid = $node->id();
|
||||
|
||||
// Enable moderation for our node type.
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
@@ -278,7 +280,7 @@ class EntityStateChangeValidationTest extends KernelTestBase {
|
||||
$node_fr->save();
|
||||
|
||||
// Enable moderation for our node type.
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
|
||||
@@ -61,4 +61,34 @@ class EntityTypeInfoTest extends KernelTestBase {
|
||||
$this->assertTrue($base_fields['moderation_state']->isTranslatable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the correct entity types have moderation added.
|
||||
*
|
||||
* @covers ::entityTypeAlter
|
||||
*
|
||||
* @dataProvider providerTestEntityTypeAlter
|
||||
*/
|
||||
public function testEntityTypeAlter($entity_type_id, $moderatable) {
|
||||
$entity_types = $this->entityTypeManager->getDefinitions();
|
||||
$this->assertSame($moderatable, $entity_types[$entity_type_id]->hasHandlerClass('moderation'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides test data for testEntityTypeAlter().
|
||||
*
|
||||
* @return array
|
||||
* An array of test cases, where each test case is an array with the
|
||||
* following values:
|
||||
* - An entity type ID.
|
||||
* - Whether the entity type is moderatable or not.
|
||||
*/
|
||||
public function providerTestEntityTypeAlter() {
|
||||
$tests = [];
|
||||
$tests['non_internal_non_revisionable'] = ['entity_test', FALSE];
|
||||
$tests['non_internal_revisionable'] = ['entity_test_rev', TRUE];
|
||||
$tests['internal_non_revisionable'] = ['entity_test_no_label', FALSE];
|
||||
$tests['internal_revisionable'] = ['content_moderation_state', FALSE];
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use Drupal\entity_test\Entity\EntityTestRev;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the correct initial states are set on install.
|
||||
@@ -15,6 +15,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class InitialStateTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -66,7 +68,7 @@ class InitialStateTest extends KernelTestBase {
|
||||
$entity_test->save();
|
||||
|
||||
\Drupal::service('module_installer')->install(['content_moderation'], TRUE);
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
|
||||
$workflow->save();
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
namespace Drupal\Tests\content_moderation\Kernel;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestMulRevPub;
|
||||
use Drupal\entity_test\Entity\EntityTestRev;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\content_moderation\ModerationInformation
|
||||
@@ -12,10 +14,26 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ModerationInformationTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['content_moderation', 'entity_test', 'user', 'workflows'];
|
||||
public static $modules = [
|
||||
'content_moderation',
|
||||
'entity_test',
|
||||
'user',
|
||||
'workflows',
|
||||
'language',
|
||||
'content_translation',
|
||||
];
|
||||
|
||||
/**
|
||||
* The moderation information service.
|
||||
*
|
||||
* @var \Drupal\content_moderation\ModerationInformationInterface
|
||||
*/
|
||||
protected $moderationInformation;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -24,8 +42,20 @@ class ModerationInformationTest extends KernelTestBase {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('entity_test_rev');
|
||||
$this->installEntitySchema('entity_test_mulrevpub');
|
||||
$this->installEntitySchema('content_moderation_state');
|
||||
$this->installConfig(['content_moderation']);
|
||||
|
||||
$this->moderationInformation = $this->container->get('content_moderation.moderation_information');
|
||||
|
||||
ConfigurableLanguage::createFromLangcode('de')->save();
|
||||
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_mulrevpub', 'entity_test_mulrevpub');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
|
||||
$workflow->save();
|
||||
|
||||
$this->container->get('content_translation.manager')->setEnabled('entity_test_mulrevpub', 'entity_test_mulrevpub', TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,10 +63,6 @@ class ModerationInformationTest extends KernelTestBase {
|
||||
* @covers ::getLatestRevisionId
|
||||
*/
|
||||
public function testDefaultAndLatestRevisionId() {
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
|
||||
$workflow->save();
|
||||
|
||||
$entity_test_rev = EntityTestRev::create([
|
||||
'name' => 'Default Revision',
|
||||
'moderation_state' => 'published',
|
||||
@@ -47,18 +73,85 @@ class ModerationInformationTest extends KernelTestBase {
|
||||
$entity_test_rev->moderation_state = 'draft';
|
||||
$entity_test_rev->save();
|
||||
|
||||
/** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */
|
||||
$moderation_info = \Drupal::service('content_moderation.moderation_information');
|
||||
|
||||
// Check that moderation information service returns the correct default
|
||||
// revision ID.
|
||||
$default_revision_id = $moderation_info->getDefaultRevisionId('entity_test_rev', $entity_test_rev->id());
|
||||
$default_revision_id = $this->moderationInformation->getDefaultRevisionId('entity_test_rev', $entity_test_rev->id());
|
||||
$this->assertSame(1, $default_revision_id);
|
||||
|
||||
// Check that moderation information service returns the correct latest
|
||||
// revision ID.
|
||||
$latest_revision_id = $moderation_info->getLatestRevisionId('entity_test_rev', $entity_test_rev->id());
|
||||
$latest_revision_id = $this->moderationInformation->getLatestRevisionId('entity_test_rev', $entity_test_rev->id());
|
||||
$this->assertSame(2, $latest_revision_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isDefaultRevisionPublished
|
||||
* @dataProvider isDefaultRevisionPublishedTestCases
|
||||
*/
|
||||
public function testIsDefaultRevisionPublished($initial_state, $final_state, $initial_is_default_published, $final_is_default_published) {
|
||||
$entity = EntityTestMulRevPub::create([
|
||||
'moderation_state' => $initial_state,
|
||||
]);
|
||||
$entity->save();
|
||||
$this->assertEquals($initial_is_default_published, $this->moderationInformation->isDefaultRevisionPublished($entity));
|
||||
|
||||
$entity->moderation_state = $final_state;
|
||||
$entity->save();
|
||||
$this->assertEquals($final_is_default_published, $this->moderationInformation->isDefaultRevisionPublished($entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test cases for ::testIsDefaultRevisionPublished.
|
||||
*/
|
||||
public function isDefaultRevisionPublishedTestCases() {
|
||||
return [
|
||||
'Draft to draft' => [
|
||||
'draft',
|
||||
'draft',
|
||||
FALSE,
|
||||
FALSE,
|
||||
],
|
||||
'Draft to published' => [
|
||||
'draft',
|
||||
'published',
|
||||
FALSE,
|
||||
TRUE,
|
||||
],
|
||||
'Published to published' => [
|
||||
'published',
|
||||
'published',
|
||||
TRUE,
|
||||
TRUE,
|
||||
],
|
||||
'Published to draft' => [
|
||||
'published',
|
||||
'draft',
|
||||
TRUE,
|
||||
TRUE,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isDefaultRevisionPublished
|
||||
*/
|
||||
public function testIsDefaultRevisionPublishedMultilingual() {
|
||||
$entity = EntityTestMulRevPub::create([
|
||||
'moderation_state' => 'draft',
|
||||
]);
|
||||
$entity->save();
|
||||
$this->assertEquals('draft', $entity->moderation_state->value);
|
||||
|
||||
$translated = $entity->addTranslation('de');
|
||||
$translated->moderation_state = 'published';
|
||||
$translated->save();
|
||||
$this->assertEquals('published', $translated->moderation_state->value);
|
||||
|
||||
// Test a scenario where the default revision exists with the default
|
||||
// language in a draft state and a non-default language in a published
|
||||
// state. The method returns TRUE if any of the languages for the default
|
||||
// revision are in a published state.
|
||||
$this->assertEquals(TRUE, $this->moderationInformation->isDefaultRevisionPublished($entity));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+116
-19
@@ -5,7 +5,7 @@ namespace Drupal\Tests\content_moderation\Kernel;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\content_moderation\Plugin\Field\ModerationStateFieldItemList
|
||||
@@ -14,6 +14,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ModerationStateFieldItemListTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -51,7 +53,7 @@ class ModerationStateFieldItemListTest extends KernelTestBase {
|
||||
'type' => 'example',
|
||||
]);
|
||||
$node_type->save();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
@@ -111,6 +113,9 @@ class ModerationStateFieldItemListTest extends KernelTestBase {
|
||||
|
||||
unset($this->testNode->moderation_state);
|
||||
$this->assertEquals('draft', $this->testNode->moderation_state->value);
|
||||
|
||||
$this->testNode->moderation_state = NULL;
|
||||
$this->assertEquals('draft', $this->testNode->moderation_state->value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,22 +135,58 @@ class ModerationStateFieldItemListTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Tests that moderation state changes also change the related entity state.
|
||||
*
|
||||
* @dataProvider moderationStateChangesTestCases
|
||||
*/
|
||||
public function testModerationStateChanges() {
|
||||
// Change the moderation state and check that the entity's
|
||||
// 'isDefaultRevision' flag and the publishing status have also been
|
||||
// updated.
|
||||
$this->testNode->moderation_state->value = 'published';
|
||||
|
||||
$this->assertTrue($this->testNode->isPublished());
|
||||
$this->assertTrue($this->testNode->isDefaultRevision());
|
||||
|
||||
public function testModerationStateChanges($initial_state, $final_state, $first_published, $first_is_default, $second_published, $second_is_default) {
|
||||
$this->testNode->moderation_state->value = $initial_state;
|
||||
$this->assertEquals($first_published, $this->testNode->isPublished());
|
||||
$this->assertEquals($first_is_default, $this->testNode->isDefaultRevision());
|
||||
$this->testNode->save();
|
||||
|
||||
// Repeat the checks using an 'unpublished' state.
|
||||
$this->testNode->moderation_state->value = 'draft';
|
||||
$this->assertFalse($this->testNode->isPublished());
|
||||
$this->assertFalse($this->testNode->isDefaultRevision());
|
||||
$this->testNode->moderation_state->value = $final_state;
|
||||
$this->assertEquals($second_published, $this->testNode->isPublished());
|
||||
$this->assertEquals($second_is_default, $this->testNode->isDefaultRevision());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for ::testModerationStateChanges
|
||||
*/
|
||||
public function moderationStateChangesTestCases() {
|
||||
return [
|
||||
'Draft to draft' => [
|
||||
'draft',
|
||||
'draft',
|
||||
FALSE,
|
||||
TRUE,
|
||||
FALSE,
|
||||
TRUE,
|
||||
],
|
||||
'Draft to published' => [
|
||||
'draft',
|
||||
'published',
|
||||
FALSE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
],
|
||||
'Published to published' => [
|
||||
'published',
|
||||
'published',
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
],
|
||||
'Published to draft' => [
|
||||
'published',
|
||||
'draft',
|
||||
TRUE,
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,13 +216,69 @@ class ModerationStateFieldItemListTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Test the moderation_state field after an entity has been serialized.
|
||||
*
|
||||
* @dataProvider entityUnserializeTestCases
|
||||
*/
|
||||
public function testEntityUnserialize() {
|
||||
$this->testNode->moderation_state->value = 'draft';
|
||||
public function testEntityUnserialize($state, $default, $published) {
|
||||
$this->testNode->moderation_state->value = $state;
|
||||
|
||||
$this->assertEquals($state, $this->testNode->moderation_state->value);
|
||||
$this->assertEquals($default, $this->testNode->isDefaultRevision());
|
||||
$this->assertEquals($published, $this->testNode->isPublished());
|
||||
|
||||
$unserialized = unserialize(serialize($this->testNode));
|
||||
|
||||
$this->assertEquals('Test title', $unserialized->title->value);
|
||||
$this->assertEquals('draft', $unserialized->moderation_state->value);
|
||||
$this->assertEquals($state, $unserialized->moderation_state->value);
|
||||
$this->assertEquals($default, $unserialized->isDefaultRevision());
|
||||
$this->assertEquals($published, $unserialized->isPublished());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test cases for ::testEntityUnserialize.
|
||||
*/
|
||||
public function entityUnserializeTestCases() {
|
||||
return [
|
||||
'Default draft state' => [
|
||||
'draft',
|
||||
TRUE,
|
||||
FALSE,
|
||||
],
|
||||
'Non-default published state' => [
|
||||
'published',
|
||||
TRUE,
|
||||
TRUE,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test saving a moderated node with an existing ID.
|
||||
*
|
||||
* @dataProvider moderatedEntityWithExistingIdTestCases
|
||||
*/
|
||||
public function testModeratedEntityWithExistingId($state) {
|
||||
$node = Node::create([
|
||||
'title' => 'Test title',
|
||||
'type' => 'example',
|
||||
'nid' => 999,
|
||||
'moderation_state' => $state,
|
||||
]);
|
||||
$node->save();
|
||||
$this->assertEquals($state, $node->moderation_state->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test cases for ::testModeratedEntityWithExistingId.
|
||||
*/
|
||||
public function moderatedEntityWithExistingIdTestCases() {
|
||||
return [
|
||||
'Draft non-default state' => [
|
||||
'draft',
|
||||
],
|
||||
'Published default state' => [
|
||||
'published',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use Drupal\Core\Form\FormState;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\content_moderation\Plugin\Field\FieldWidget\ModerationStateWidget
|
||||
@@ -16,6 +16,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ModerationStateWidgetTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
@@ -46,7 +48,7 @@ class ModerationStateWidgetTest extends KernelTestBase {
|
||||
'type' => 'unmoderated',
|
||||
])->save();
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated');
|
||||
$workflow->save();
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ namespace Drupal\Tests\content_moderation\Kernel;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
use Drupal\Tests\node\Traits\NodeCreationTrait;
|
||||
use Drupal\Tests\user\Traits\UserCreationTrait;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
|
||||
/**
|
||||
* Tests with node access enabled.
|
||||
@@ -17,6 +17,7 @@ class NodeAccessTest extends KernelTestBase {
|
||||
|
||||
use NodeCreationTrait;
|
||||
use UserCreationTrait;
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* The moderation information service.
|
||||
@@ -58,7 +59,7 @@ class NodeAccessTest extends KernelTestBase {
|
||||
'label' => 'Page',
|
||||
]);
|
||||
$node_type->save();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'page');
|
||||
$workflow->save();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Drupal\Tests\content_moderation\Kernel;
|
||||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\entity_test\Entity\EntityTestRev;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Test the state field formatter.
|
||||
@@ -14,6 +14,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class StateFormatterTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
@@ -36,7 +38,7 @@ class StateFormatterTest extends KernelTestBase {
|
||||
$this->installEntitySchema('content_moderation_state');
|
||||
$this->installConfig('content_moderation');
|
||||
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
|
||||
$workflow->save();
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ namespace Drupal\Tests\content_moderation\Kernel;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
|
||||
/**
|
||||
* Tests the views integration of content_moderation.
|
||||
@@ -15,6 +15,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ViewsDataIntegrationTest extends ViewsKernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -44,7 +46,7 @@ class ViewsDataIntegrationTest extends ViewsKernelTestBase {
|
||||
'type' => 'page',
|
||||
]);
|
||||
$node_type->save();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'page');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_mulrevpub', 'entity_test_mulrevpub');
|
||||
$workflow->save();
|
||||
|
||||
@@ -6,6 +6,7 @@ use Drupal\entity_test\Entity\EntityTestNoBundle;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
@@ -19,6 +20,8 @@ use Drupal\workflows\Entity\Workflow;
|
||||
*/
|
||||
class ViewsModerationStateFilterTest extends ViewsKernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -69,7 +72,7 @@ class ViewsModerationStateFilterTest extends ViewsKernelTestBase {
|
||||
* Tests the content moderation state filter.
|
||||
*/
|
||||
public function testStateFilterViewsRelationship() {
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->getTypePlugin()->addState('translated_draft', 'Bar');
|
||||
$configuration = $workflow->getTypePlugin()->getConfiguration();
|
||||
@@ -156,7 +159,7 @@ class ViewsModerationStateFilterTest extends ViewsKernelTestBase {
|
||||
* Test the moderation filter with a non-translatable entity type.
|
||||
*/
|
||||
public function testNonTranslatableEntityType() {
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_no_bundle', 'entity_test_no_bundle');
|
||||
$workflow->save();
|
||||
|
||||
@@ -182,7 +185,7 @@ class ViewsModerationStateFilterTest extends ViewsKernelTestBase {
|
||||
|
||||
// Adding a content type to the editorial workflow will enable all of the
|
||||
// editorial states.
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
$this->assertPluginStates([
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\content_moderation\Traits;
|
||||
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
|
||||
/**
|
||||
* Trait ContentModerationTestTraint.
|
||||
*/
|
||||
trait ContentModerationTestTrait {
|
||||
|
||||
/**
|
||||
* Creates the editorial workflow.
|
||||
*
|
||||
* @return \Drupal\workflows\Entity\Workflow
|
||||
* The editorial workflow entity.
|
||||
*/
|
||||
protected function createEditorialWorkflow() {
|
||||
$workflow = Workflow::create([
|
||||
'type' => 'content_moderation',
|
||||
'id' => 'editorial',
|
||||
'label' => 'Editorial',
|
||||
'type_settings' => [
|
||||
'states' => [
|
||||
'archived' => [
|
||||
'label' => 'Archived',
|
||||
'weight' => 5,
|
||||
'published' => FALSE,
|
||||
'default_revision' => TRUE,
|
||||
],
|
||||
'draft' => [
|
||||
'label' => 'Draft',
|
||||
'published' => FALSE,
|
||||
'default_revision' => FALSE,
|
||||
'weight' => -5,
|
||||
],
|
||||
'published' => [
|
||||
'label' => 'Published',
|
||||
'published' => TRUE,
|
||||
'default_revision' => TRUE,
|
||||
'weight' => 0,
|
||||
],
|
||||
],
|
||||
'transitions' => [
|
||||
'archive' => [
|
||||
'label' => 'Archive',
|
||||
'from' => ['published'],
|
||||
'to' => 'archived',
|
||||
'weight' => 2,
|
||||
],
|
||||
'archived_draft' => [
|
||||
'label' => 'Restore to Draft',
|
||||
'from' => ['archived'],
|
||||
'to' => 'draft',
|
||||
'weight' => 3,
|
||||
],
|
||||
'archived_published' => [
|
||||
'label' => 'Restore',
|
||||
'from' => ['archived'],
|
||||
'to' => 'published',
|
||||
'weight' => 4,
|
||||
],
|
||||
'create_new_draft' => [
|
||||
'label' => 'Create New Draft',
|
||||
'to' => 'draft',
|
||||
'weight' => 0,
|
||||
'from' => [
|
||||
'draft',
|
||||
'published',
|
||||
],
|
||||
],
|
||||
'publish' => [
|
||||
'label' => 'Publish',
|
||||
'to' => 'published',
|
||||
'weight' => 1,
|
||||
'from' => [
|
||||
'draft',
|
||||
'published',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$workflow->save();
|
||||
return $workflow;
|
||||
}
|
||||
|
||||
}
|
||||
+7
-7
@@ -78,7 +78,7 @@ class ContentModerationRouteSubscriberTest extends UnitTestCase {
|
||||
],
|
||||
'Entity parameter on an entity form' => [
|
||||
[
|
||||
'_entity_form' => 'entity_test_rev.edit'
|
||||
'_entity_form' => 'entity_test_rev.edit',
|
||||
],
|
||||
[
|
||||
'entity_test_rev' => [
|
||||
@@ -94,7 +94,7 @@ class ContentModerationRouteSubscriberTest extends UnitTestCase {
|
||||
],
|
||||
'Entity form with no operation' => [
|
||||
[
|
||||
'_entity_form' => 'entity_test_rev'
|
||||
'_entity_form' => 'entity_test_rev',
|
||||
],
|
||||
[
|
||||
'entity_test_rev' => [
|
||||
@@ -110,7 +110,7 @@ class ContentModerationRouteSubscriberTest extends UnitTestCase {
|
||||
],
|
||||
'Non-moderated entity form' => [
|
||||
[
|
||||
'_entity_form' => 'entity_test_mulrev'
|
||||
'_entity_form' => 'entity_test_mulrev',
|
||||
],
|
||||
[
|
||||
'entity_test_mulrev' => [
|
||||
@@ -120,7 +120,7 @@ class ContentModerationRouteSubscriberTest extends UnitTestCase {
|
||||
],
|
||||
'Multiple entity parameters on an entity form' => [
|
||||
[
|
||||
'_entity_form' => 'entity_test_rev.edit'
|
||||
'_entity_form' => 'entity_test_rev.edit',
|
||||
],
|
||||
[
|
||||
'entity_test_rev' => [
|
||||
@@ -142,7 +142,7 @@ class ContentModerationRouteSubscriberTest extends UnitTestCase {
|
||||
],
|
||||
'Overridden load_latest_revision flag does not change' => [
|
||||
[
|
||||
'_entity_form' => 'entity_test_rev.edit'
|
||||
'_entity_form' => 'entity_test_rev.edit',
|
||||
],
|
||||
[
|
||||
'entity_test_rev' => [
|
||||
@@ -153,7 +153,7 @@ class ContentModerationRouteSubscriberTest extends UnitTestCase {
|
||||
],
|
||||
'Non-revisionable entity type will not change' => [
|
||||
[
|
||||
'_entity_form' => 'entity_test.edit'
|
||||
'_entity_form' => 'entity_test.edit',
|
||||
],
|
||||
[
|
||||
'entity_test' => [
|
||||
@@ -165,7 +165,7 @@ class ContentModerationRouteSubscriberTest extends UnitTestCase {
|
||||
],
|
||||
'Overridden load_latest_revision flag does not change with multiple parameters' => [
|
||||
[
|
||||
'_entity_form' => 'entity_test_rev.edit'
|
||||
'_entity_form' => 'entity_test_rev.edit',
|
||||
],
|
||||
[
|
||||
'entity_test_rev' => [
|
||||
|
||||
Reference in New Issue
Block a user