X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=web%2Fcore%2Fmodules%2Fcontent_moderation%2Fcontent_moderation.module;fp=web%2Fcore%2Fmodules%2Fcontent_moderation%2Fcontent_moderation.module;h=5a7af0e2c9e2c2640dae1590bb8e58a23dc3fdd0;hp=77d822be28ae6b49b284aa9f2387259f249a553c;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hpb=aea91e65e895364e460983b890e295aa5d5540a5 diff --git a/web/core/modules/content_moderation/content_moderation.module b/web/core/modules/content_moderation/content_moderation.module index 77d822be2..5a7af0e2c 100644 --- a/web/core/modules/content_moderation/content_moderation.module +++ b/web/core/modules/content_moderation/content_moderation.module @@ -13,12 +13,14 @@ use Drupal\content_moderation\Plugin\Action\ModerationOptOutUnpublishNode; use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityPublishedInterface; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; use Drupal\workflows\WorkflowInterface; -use Drupal\node\NodeInterface; use Drupal\node\Plugin\Action\PublishNode; use Drupal\node\Plugin\Action\UnpublishNode; use Drupal\workflows\Entity\Workflow; @@ -62,15 +64,6 @@ function content_moderation_entity_type_alter(array &$entity_types) { ->entityTypeAlter($entity_types); } -/** - * Implements hook_entity_operation(). - */ -function content_moderation_entity_operation(EntityInterface $entity) { - return \Drupal::service('class_resolver') - ->getInstanceFromDefinition(EntityTypeInfo::class) - ->entityOperation($entity); -} - /** * Implements hook_entity_presave(). */ @@ -98,6 +91,33 @@ function content_moderation_entity_update(EntityInterface $entity) { ->entityUpdate($entity); } +/** + * Implements hook_entity_delete(). + */ +function content_moderation_entity_delete(EntityInterface $entity) { + return \Drupal::service('class_resolver') + ->getInstanceFromDefinition(EntityOperations::class) + ->entityDelete($entity); +} + +/** + * Implements hook_entity_revision_delete(). + */ +function content_moderation_entity_revision_delete(EntityInterface $entity) { + return \Drupal::service('class_resolver') + ->getInstanceFromDefinition(EntityOperations::class) + ->entityRevisionDelete($entity); +} + +/** + * Implements hook_entity_translation_delete(). + */ +function content_moderation_entity_translation_delete(EntityInterface $translation) { + return \Drupal::service('class_resolver') + ->getInstanceFromDefinition(EntityOperations::class) + ->entityTranslationDelete($translation); +} + /** * Implements hook_form_alter(). */ @@ -109,9 +129,6 @@ function content_moderation_form_alter(&$form, FormStateInterface $form_state, $ /** * Implements hook_preprocess_HOOK(). - * - * Many default node templates rely on $page to determine whether to output the - * node title as part of the node content. */ function content_moderation_preprocess_node(&$variables) { \Drupal::service('class_resolver') @@ -138,34 +155,34 @@ function content_moderation_entity_view(array &$build, EntityInterface $entity, } /** - * Implements hook_node_access(). + * Implements hook_entity_access(). * - * Nodes in particular should be viewable if unpublished and the user has - * the appropriate permission. This permission is therefore effectively - * mandatory for any user that wants to moderate things. + * Entities should be viewable if unpublished and the user has the appropriate + * permission. This permission is therefore effectively mandatory for any user + * that wants to moderate things. */ -function content_moderation_node_access(NodeInterface $node, $operation, AccountInterface $account) { +function content_moderation_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { /** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */ $moderation_info = Drupal::service('content_moderation.moderation_information'); $access_result = NULL; if ($operation === 'view') { - $access_result = (!$node->isPublished()) + $access_result = (($entity instanceof EntityPublishedInterface) && !$entity->isPublished()) ? AccessResult::allowedIfHasPermission($account, 'view any unpublished content') : AccessResult::neutral(); - $access_result->addCacheableDependency($node); + $access_result->addCacheableDependency($entity); } - elseif ($operation === 'update' && $moderation_info->isModeratedEntity($node) && $node->moderation_state) { + elseif ($operation === 'update' && $moderation_info->isModeratedEntity($entity) && $entity->moderation_state) { /** @var \Drupal\content_moderation\StateTransitionValidation $transition_validation */ $transition_validation = \Drupal::service('content_moderation.state_transition_validation'); - $valid_transition_targets = $transition_validation->getValidTransitions($node, $account); + $valid_transition_targets = $transition_validation->getValidTransitions($entity, $account); $access_result = $valid_transition_targets ? AccessResult::neutral() : AccessResult::forbidden(); - $access_result->addCacheableDependency($node); + $access_result->addCacheableDependency($entity); $access_result->addCacheableDependency($account); - $workflow = \Drupal::service('content_moderation.moderation_information')->getWorkflowForEntity($node); + $workflow = $moderation_info->getWorkflowForEntity($entity); $access_result->addCacheableDependency($workflow); foreach ($valid_transition_targets as $valid_transition_target) { $access_result->addCacheableDependency($valid_transition_target); @@ -175,6 +192,27 @@ function content_moderation_node_access(NodeInterface $node, $operation, Account return $access_result; } +/** + * Implements hook_entity_field_access(). + */ +function content_moderation_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) { + if ($items && $operation === 'edit') { + /** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */ + $moderation_info = Drupal::service('content_moderation.moderation_information'); + + $entity_type = \Drupal::entityTypeManager()->getDefinition($field_definition->getTargetEntityTypeId()); + + $entity = $items->getEntity(); + + // 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::neutral(); +} + /** * Implements hook_theme(). */ @@ -217,6 +255,20 @@ function content_moderation_entity_bundle_info_alter(&$bundles) { } } +/** + * Implements hook_entity_bundle_delete(). + */ +function content_moderation_entity_bundle_delete($entity_type_id, $bundle_id) { + // Remove non-configuration based bundles from content moderation based + // workflows when they are removed. + foreach (Workflow::loadMultipleByType('content_moderation') as $workflow) { + if ($workflow->getTypePlugin()->appliesToEntityTypeAndBundle($entity_type_id, $bundle_id)) { + $workflow->getTypePlugin()->removeEntityTypeAndBundle($entity_type_id, $bundle_id); + $workflow->save(); + } + } +} + /** * Implements hook_ENTITY_TYPE_insert(). */ @@ -232,5 +284,19 @@ function content_moderation_workflow_insert(WorkflowInterface $entity) { * Implements hook_ENTITY_TYPE_update(). */ function content_moderation_workflow_update(WorkflowInterface $entity) { - content_moderation_workflow_insert($entity); + // Clear bundle cache so workflow gets added or removed from the bundle + // information. + \Drupal::service('entity_type.bundle.info')->clearCachedBundles(); + // Clear field cache so extra field is added or removed. + \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions(); +} + +/** + * Implements hook_rest_resource_alter(). + */ +function content_moderation_rest_resource_alter(&$definitions) { + // ContentModerationState is an internal entity type. Therefore it should not + // be exposed via REST. + // @see \Drupal\content_moderation\ContentModerationStateAccessControlHandler + unset($definitions['entity:content_moderation_state']); }