summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Pott2018-01-09 08:47:01 (GMT)
committerAlex Pott2018-01-09 08:47:01 (GMT)
commitcbd3299e685662f28fc18f28fdd950f3857d06f5 (patch)
treef52aa09dbac5d4824921e3274c6a50dda55bd350
parentc9ca954cb94a328cc12470480fe8e47ffcbd2cd6 (diff)
Issue #2916740 by chr.fritsch, xjm, Manuel Garcia, tstoeckler, alexpott, seanB, Sam152, amateescu, tim.plunkett, dawehner, larowlan, Berdir: Add generic entity actions
-rw-r--r--core/config/schema/core.entity.schema.yml5
-rw-r--r--core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityActionDeriverBase.php89
-rw-r--r--core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityChangedActionDeriver.php22
-rw-r--r--core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityPublishedActionDeriver.php23
-rw-r--r--core/lib/Drupal/Core/Action/Plugin/Action/EntityActionBase.php62
-rw-r--r--core/lib/Drupal/Core/Action/Plugin/Action/PublishAction.php38
-rw-r--r--core/lib/Drupal/Core/Action/Plugin/Action/SaveAction.php79
-rw-r--r--core/lib/Drupal/Core/Action/Plugin/Action/UnpublishAction.php38
-rw-r--r--core/modules/action/migrations/d6_action.yml6
-rw-r--r--core/modules/action/migrations/d7_action.yml6
-rw-r--r--core/modules/comment/config/install/system.action.comment_publish_action.yml2
-rw-r--r--core/modules/comment/config/install/system.action.comment_save_action.yml2
-rw-r--r--core/modules/comment/config/install/system.action.comment_unpublish_action.yml2
-rw-r--r--core/modules/comment/config/schema/comment.schema.yml6
-rw-r--r--core/modules/comment/src/Plugin/Action/PublishComment.php29
-rw-r--r--core/modules/comment/src/Plugin/Action/SaveComment.php26
-rw-r--r--core/modules/comment/src/Plugin/Action/UnpublishComment.php29
-rw-r--r--core/modules/comment/tests/src/Functional/CommentActionsTest.php2
-rw-r--r--core/modules/content_moderation/content_moderation.module22
-rw-r--r--core/modules/content_moderation/src/Plugin/Action/ModerationOptOutPublish.php84
-rw-r--r--core/modules/content_moderation/src/Plugin/Action/ModerationOptOutPublishNode.php61
-rw-r--r--core/modules/content_moderation/src/Plugin/Action/ModerationOptOutUnpublish.php84
-rw-r--r--core/modules/content_moderation/src/Plugin/Action/ModerationOptOutUnpublishNode.php61
-rw-r--r--core/modules/node/config/install/system.action.node_publish_action.yml2
-rw-r--r--core/modules/node/config/install/system.action.node_save_action.yml2
-rw-r--r--core/modules/node/config/install/system.action.node_unpublish_action.yml2
-rw-r--r--core/modules/node/config/schema/node.schema.yml6
-rw-r--r--core/modules/node/src/Plugin/Action/PublishNode.php17
-rw-r--r--core/modules/node/src/Plugin/Action/SaveNode.php29
-rw-r--r--core/modules/node/src/Plugin/Action/UnpublishNode.php17
-rw-r--r--core/modules/system/system.post_update.php23
-rw-r--r--core/modules/system/tests/src/Functional/Update/UpdateActionsWithEntityPluginsTest.php56
-rw-r--r--core/tests/Drupal/KernelTests/Core/Action/PublishActionTest.php80
-rw-r--r--core/tests/Drupal/KernelTests/Core/Action/SaveActionTest.php62
-rw-r--r--core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php6
35 files changed, 892 insertions, 188 deletions
diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml
index f58db9e..73d84bc 100644
--- a/core/config/schema/core.entity.schema.yml
+++ b/core/config/schema/core.entity.schema.yml
@@ -374,3 +374,8 @@ block.settings.field_block:*:*:
mapping:
formatter:
type: field_formatter
+
+# Schema for entity actions.
+action.configuration.entity:*:*:
+ type: action_configuration_default
+ label: 'Entity action'
diff --git a/core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityActionDeriverBase.php b/core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityActionDeriverBase.php
new file mode 100644
index 0000000..29159c2
--- /dev/null
+++ b/core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityActionDeriverBase.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Drupal\Core\Action\Plugin\Action\Derivative;
+
+use Drupal\Component\Plugin\Derivative\DeriverBase;
+use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a base action for each entity type with specific interfaces.
+ */
+abstract class EntityActionDeriverBase extends DeriverBase implements ContainerDeriverInterface {
+
+ /**
+ * The entity type manager.
+ *
+ * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+ */
+ protected $entityTypeManager;
+
+ /**
+ * Constructs a new EntityActionDeriverBase object.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+ * The entity type manager.
+ */
+ public function __construct(EntityTypeManagerInterface $entity_type_manager) {
+ $this->entityTypeManager = $entity_type_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, $base_plugin_id) {
+ return new static($container->get('entity_type.manager'));
+ }
+
+ /**
+ * Indicates whether the deriver can be used for the provided entity type.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type.
+ *
+ * @return bool
+ * TRUE if the entity type can be used, FALSE otherwise.
+ */
+ abstract protected function isApplicable(EntityTypeInterface $entity_type);
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDerivativeDefinitions($base_plugin_definition) {
+ if (empty($this->derivatives)) {
+ $definitions = [];
+ foreach ($this->getApplicableEntityTypes() as $entity_type_id => $entity_type) {
+ $definition = $base_plugin_definition;
+ $definition['type'] = $entity_type_id;
+ $definition['label'] = sprintf('%s %s', $base_plugin_definition['action_label'], $entity_type->getSingularLabel());
+ $definitions[$entity_type_id] = $definition;
+ }
+ $this->derivatives = $definitions;
+ }
+
+ return parent::getDerivativeDefinitions($base_plugin_definition);
+ }
+
+ /**
+ * Gets a list of applicable entity types.
+ *
+ * The list consists of all entity types which match the conditions for the
+ * given deriver.
+ * For example, if the action applies to entities that are publishable,
+ * this method will find all entity types that are publishable.
+ *
+ * @return \Drupal\Core\Entity\EntityTypeInterface[]
+ * The applicable entity types, keyed by entity type ID.
+ */
+ protected function getApplicableEntityTypes() {
+ $entity_types = $this->entityTypeManager->getDefinitions();
+ $entity_types = array_filter($entity_types, function (EntityTypeInterface $entity_type) {
+ return $this->isApplicable($entity_type);
+ });
+
+ return $entity_types;
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityChangedActionDeriver.php b/core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityChangedActionDeriver.php
new file mode 100644
index 0000000..2df090b
--- /dev/null
+++ b/core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityChangedActionDeriver.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\Core\Action\Plugin\Action\Derivative;
+
+use Drupal\Core\Entity\EntityChangedInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+
+/**
+ * Provides an action deriver that finds entity types of EntityChangedInterface.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\SaveAction
+ */
+class EntityChangedActionDeriver extends EntityActionDeriverBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function isApplicable(EntityTypeInterface $entity_type) {
+ return $entity_type->entityClassImplements(EntityChangedInterface::class);
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityPublishedActionDeriver.php b/core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityPublishedActionDeriver.php
new file mode 100644
index 0000000..05548ee
--- /dev/null
+++ b/core/lib/Drupal/Core/Action/Plugin/Action/Derivative/EntityPublishedActionDeriver.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Drupal\Core\Action\Plugin\Action\Derivative;
+
+use Drupal\Core\Entity\EntityPublishedInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+
+/**
+ * Provides an action deriver that finds publishable entity types.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\PublishAction
+ * @see \Drupal\Core\Action\Plugin\Action\UnpublishAction
+ */
+class EntityPublishedActionDeriver extends EntityActionDeriverBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function isApplicable(EntityTypeInterface $entity_type) {
+ return $entity_type->entityClassImplements(EntityPublishedInterface::class);
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Action/Plugin/Action/EntityActionBase.php b/core/lib/Drupal/Core/Action/Plugin/Action/EntityActionBase.php
new file mode 100644
index 0000000..2624024
--- /dev/null
+++ b/core/lib/Drupal/Core/Action/Plugin/Action/EntityActionBase.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Drupal\Core\Action\Plugin\Action;
+
+use Drupal\Component\Plugin\DependentPluginInterface;
+use Drupal\Core\Action\ActionBase;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Base class for entity-based actions.
+ */
+abstract class EntityActionBase extends ActionBase implements DependentPluginInterface, ContainerFactoryPluginInterface {
+
+ /**
+ * The entity type manager.
+ *
+ * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+ */
+ protected $entityTypeManager;
+
+ /**
+ * Constructs a EntityActionBase object.
+ *
+ * @param mixed[] $configuration
+ * A configuration array containing information about the plugin instance.
+ * @param string $plugin_id
+ * The plugin ID for the plugin instance.
+ * @param mixed $plugin_definition
+ * The plugin implementation definition.
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+ * The entity type manager.
+ */
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition);
+ $this->entityTypeManager = $entity_type_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container->get('entity_type.manager')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function calculateDependencies() {
+ $module_name = $this->entityTypeManager
+ ->getDefinition($this->getPluginDefinition()['type'])
+ ->getProvider();
+ return ['module' => [$module_name]];
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Action/Plugin/Action/PublishAction.php b/core/lib/Drupal/Core/Action/Plugin/Action/PublishAction.php
new file mode 100644
index 0000000..8d0cf75
--- /dev/null
+++ b/core/lib/Drupal/Core/Action/Plugin/Action/PublishAction.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\Core\Action\Plugin\Action;
+
+use Drupal\Core\Session\AccountInterface;
+
+/**
+ * Publishes an entity.
+ *
+ * @Action(
+ * id = "entity:publish_action",
+ * action_label = @Translation("Publish"),
+ * deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver",
+ * )
+ */
+class PublishAction extends EntityActionBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function execute($entity = NULL) {
+ $entity->setPublished()->save();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
+ $key = $object->getEntityType()->getKey('published');
+
+ /** @var \Drupal\Core\Entity\EntityInterface $object */
+ $result = $object->access('update', $account, TRUE)
+ ->andIf($object->$key->access('edit', $account, TRUE));
+
+ return $return_as_object ? $result : $result->isAllowed();
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Action/Plugin/Action/SaveAction.php b/core/lib/Drupal/Core/Action/Plugin/Action/SaveAction.php
new file mode 100644
index 0000000..fc63e5c
--- /dev/null
+++ b/core/lib/Drupal/Core/Action/Plugin/Action/SaveAction.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Drupal\Core\Action\Plugin\Action;
+
+use Drupal\Component\Datetime\TimeInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides an action that can save any entity.
+ *
+ * @Action(
+ * id = "entity:save_action",
+ * action_label = @Translation("Save"),
+ * deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityChangedActionDeriver",
+ * )
+ */
+class SaveAction extends EntityActionBase {
+
+ /**
+ * The time service.
+ *
+ * @var \Drupal\Component\Datetime\TimeInterface
+ */
+ protected $time;
+
+ /**
+ * Constructs a SaveAction object.
+ *
+ * @param mixed[] $configuration
+ * A configuration array containing information about the plugin instance.
+ * @param string $plugin_id
+ * The plugin ID for the plugin instance.
+ * @param mixed $plugin_definition
+ * The plugin implementation definition.
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+ * The entity type manager.
+ * @param \Drupal\Component\Datetime\TimeInterface $time
+ * The time service.
+ */
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
+ $this->time = $time;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container->get('entity_type.manager'),
+ $container->get('datetime.time')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function execute($entity = NULL) {
+ $entity->setChangedTime($this->time->getRequestTime())->save();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
+ // It's not necessary to check the changed field access here, because
+ // Drupal\Core\Field\ChangedFieldItemList would anyway return 'not allowed'.
+ // Also changing the changed field value is only a workaround to trigger an
+ // entity resave. Without a field change, this would not be possible.
+ /** @var \Drupal\Core\Entity\EntityInterface $object */
+ return $object->access('update', $account, $return_as_object);
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Action/Plugin/Action/UnpublishAction.php b/core/lib/Drupal/Core/Action/Plugin/Action/UnpublishAction.php
new file mode 100644
index 0000000..bb3f6c2
--- /dev/null
+++ b/core/lib/Drupal/Core/Action/Plugin/Action/UnpublishAction.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\Core\Action\Plugin\Action;
+
+use Drupal\Core\Session\AccountInterface;
+
+/**
+ * Unpublishes an entity.
+ *
+ * @Action(
+ * id = "entity:unpublish_action",
+ * action_label = @Translation("Unpublish"),
+ * deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver",
+ * )
+ */
+class UnpublishAction extends EntityActionBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function execute($entity = NULL) {
+ $entity->setUnpublished()->save();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
+ $key = $object->getEntityType()->getKey('published');
+
+ /** @var \Drupal\Core\Entity\EntityInterface $object */
+ $result = $object->access('update', $account, TRUE)
+ ->andIf($object->$key->access('edit', $account, TRUE));
+
+ return $return_as_object ? $result : $result->isAllowed();
+ }
+
+}
diff --git a/core/modules/action/migrations/d6_action.yml b/core/modules/action/migrations/d6_action.yml
index 592ed18..38b7fb9 100644
--- a/core/modules/action/migrations/d6_action.yml
+++ b/core/modules/action/migrations/d6_action.yml
@@ -23,6 +23,12 @@ process:
imagecache_flush_action: 0
imagecache_generate_all_action: 0
imagecache_generate_action: 0
+ comment_publish_action: entity:publish_action:comment
+ comment_unpublish_action: entity:unpublish_action:comment
+ comment_save_action: entity:save_action:comment
+ node_publish_action: entity:publish_action:node
+ node_unpublish_action: entity:unpublish_action:node
+ node_save_action: entity:save_action:node
bypass: true
-
plugin: skip_on_empty
diff --git a/core/modules/action/migrations/d7_action.yml b/core/modules/action/migrations/d7_action.yml
index 03b869a..ccafcaf 100644
--- a/core/modules/action/migrations/d7_action.yml
+++ b/core/modules/action/migrations/d7_action.yml
@@ -20,6 +20,12 @@ process:
system_send_email_action: action_send_email_action
system_message_action: action_message_action
system_block_ip_action: 0
+ comment_publish_action: entity:publish_action:comment
+ comment_unpublish_action: entity:unpublish_action:comment
+ comment_save_action: entity:save_action:comment
+ node_publish_action: entity:publish_action:node
+ node_unpublish_action: entity:unpublish_action:node
+ node_save_action: entity:save_action:node
bypass: true
-
plugin: skip_on_empty
diff --git a/core/modules/comment/config/install/system.action.comment_publish_action.yml b/core/modules/comment/config/install/system.action.comment_publish_action.yml
index 8fbd48d..7a47b2d 100644
--- a/core/modules/comment/config/install/system.action.comment_publish_action.yml
+++ b/core/modules/comment/config/install/system.action.comment_publish_action.yml
@@ -6,5 +6,5 @@ dependencies:
id: comment_publish_action
label: 'Publish comment'
type: comment
-plugin: comment_publish_action
+plugin: entity:publish_action:comment
configuration: { }
diff --git a/core/modules/comment/config/install/system.action.comment_save_action.yml b/core/modules/comment/config/install/system.action.comment_save_action.yml
index 640d281..614cf4b 100644
--- a/core/modules/comment/config/install/system.action.comment_save_action.yml
+++ b/core/modules/comment/config/install/system.action.comment_save_action.yml
@@ -6,5 +6,5 @@ dependencies:
id: comment_save_action
label: 'Save comment'
type: comment
-plugin: comment_save_action
+plugin: entity:save_action:comment
configuration: { }
diff --git a/core/modules/comment/config/install/system.action.comment_unpublish_action.yml b/core/modules/comment/config/install/system.action.comment_unpublish_action.yml
index 99902e8..a1800b4 100644
--- a/core/modules/comment/config/install/system.action.comment_unpublish_action.yml
+++ b/core/modules/comment/config/install/system.action.comment_unpublish_action.yml
@@ -6,5 +6,5 @@ dependencies:
id: comment_unpublish_action
label: 'Unpublish comment'
type: comment
-plugin: comment_unpublish_action
+plugin: entity:unpublish_action:comment
configuration: { }
diff --git a/core/modules/comment/config/schema/comment.schema.yml b/core/modules/comment/config/schema/comment.schema.yml
index e4a5b75..c29088b 100644
--- a/core/modules/comment/config/schema/comment.schema.yml
+++ b/core/modules/comment/config/schema/comment.schema.yml
@@ -15,10 +15,14 @@ field.widget.settings.comment_default:
type: mapping
label: 'Comment display format settings'
+# @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+# @see https://www.drupal.org/node/2919303
action.configuration.comment_publish_action:
type: action_configuration_default
label: 'Publish comment configuration'
+# @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+# @see https://www.drupal.org/node/2919303
action.configuration.comment_save_action:
type: action_configuration_default
label: 'Save comment configuration'
@@ -34,6 +38,8 @@ action.configuration.comment_unpublish_by_keyword_action:
type: string
label: 'Keyword'
+# @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+# @see https://www.drupal.org/node/2919303
action.configuration.comment_unpublish_action:
type: action_configuration_default
label: 'Unpublish comment configuration'
diff --git a/core/modules/comment/src/Plugin/Action/PublishComment.php b/core/modules/comment/src/Plugin/Action/PublishComment.php
index 14f5605..9aa1e4a 100644
--- a/core/modules/comment/src/Plugin/Action/PublishComment.php
+++ b/core/modules/comment/src/Plugin/Action/PublishComment.php
@@ -2,37 +2,32 @@
namespace Drupal\comment\Plugin\Action;
-use Drupal\Core\Action\ActionBase;
-use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Action\Plugin\Action\PublishAction;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Publishes a comment.
*
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Action\Plugin\Action\PublishAction instead.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\PublishAction
+ * @see https://www.drupal.org/node/2919303
+ *
* @Action(
* id = "comment_publish_action",
* label = @Translation("Publish comment"),
* type = "comment"
* )
*/
-class PublishComment extends ActionBase {
-
- /**
- * {@inheritdoc}
- */
- public function execute($comment = NULL) {
- $comment->setPublished(TRUE);
- $comment->save();
- }
+class PublishComment extends PublishAction {
/**
* {@inheritdoc}
*/
- public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
- /** @var \Drupal\comment\CommentInterface $object */
- $result = $object->status->access('edit', $account, TRUE)
- ->andIf($object->access('update', $account, TRUE));
-
- return $return_as_object ? $result : $result->isAllowed();
+ public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
+ @trigger_error(__NAMESPACE__ . '\PublishComment is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\PublishAction instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
diff --git a/core/modules/comment/src/Plugin/Action/SaveComment.php b/core/modules/comment/src/Plugin/Action/SaveComment.php
index fdab65d..c197112 100644
--- a/core/modules/comment/src/Plugin/Action/SaveComment.php
+++ b/core/modules/comment/src/Plugin/Action/SaveComment.php
@@ -2,33 +2,33 @@
namespace Drupal\comment\Plugin\Action;
-use Drupal\Core\Action\ActionBase;
-use Drupal\Core\Session\AccountInterface;
+use Drupal\Component\Datetime\TimeInterface;
+use Drupal\Core\Action\Plugin\Action\SaveAction;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Saves a comment.
*
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Action\Plugin\Action\SaveAction instead.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\SaveAction
+ * @see https://www.drupal.org/node/2919303
+ *
* @Action(
* id = "comment_save_action",
* label = @Translation("Save comment"),
* type = "comment"
* )
*/
-class SaveComment extends ActionBase {
-
- /**
- * {@inheritdoc}
- */
- public function execute($comment = NULL) {
- $comment->save();
- }
+class SaveComment extends SaveAction {
/**
* {@inheritdoc}
*/
- public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
- /** @var \Drupal\comment\CommentInterface $object */
- return $object->access('update', $account, $return_as_object);
+ public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $time);
+ @trigger_error(__NAMESPACE__ . '\SaveComment is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\SaveAction instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
diff --git a/core/modules/comment/src/Plugin/Action/UnpublishComment.php b/core/modules/comment/src/Plugin/Action/UnpublishComment.php
index 6accccc..7e867c0 100644
--- a/core/modules/comment/src/Plugin/Action/UnpublishComment.php
+++ b/core/modules/comment/src/Plugin/Action/UnpublishComment.php
@@ -2,37 +2,32 @@
namespace Drupal\comment\Plugin\Action;
-use Drupal\Core\Action\ActionBase;
-use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Action\Plugin\Action\UnpublishAction;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Unpublishes a comment.
*
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Action\Plugin\Action\UnpublishAction instead.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\UnpublishAction
+ * @see https://www.drupal.org/node/2919303
+ *
* @Action(
* id = "comment_unpublish_action",
* label = @Translation("Unpublish comment"),
* type = "comment"
* )
*/
-class UnpublishComment extends ActionBase {
-
- /**
- * {@inheritdoc}
- */
- public function execute($comment = NULL) {
- $comment->setPublished(FALSE);
- $comment->save();
- }
+class UnpublishComment extends UnpublishAction {
/**
* {@inheritdoc}
*/
- public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
- /** @var \Drupal\comment\CommentInterface $object */
- $result = $object->status->access('edit', $account, TRUE)
- ->andIf($object->access('update', $account, TRUE));
-
- return $return_as_object ? $result : $result->isAllowed();
+ public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
+ @trigger_error(__NAMESPACE__ . '\UnpublishComment is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\UnpublishAction instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
diff --git a/core/modules/comment/tests/src/Functional/CommentActionsTest.php b/core/modules/comment/tests/src/Functional/CommentActionsTest.php
index 79786fc..326749b 100644
--- a/core/modules/comment/tests/src/Functional/CommentActionsTest.php
+++ b/core/modules/comment/tests/src/Functional/CommentActionsTest.php
@@ -32,7 +32,7 @@ class CommentActionsTest extends CommentTestBase {
$action = Action::load('comment_unpublish_action');
$action->execute([$comment]);
$this->assertTrue($comment->isPublished() === FALSE, 'Comment was unpublished');
-
+ $this->assertArraySubset(['module' => ['comment']], $action->getDependencies());
// Publish a comment.
$action = Action::load('comment_publish_action');
$action->execute([$comment]);
diff --git a/core/modules/content_moderation/content_moderation.module b/core/modules/content_moderation/content_moderation.module
index 5a7af0e..2ae1e0d 100644
--- a/core/modules/content_moderation/content_moderation.module
+++ b/core/modules/content_moderation/content_moderation.module
@@ -8,8 +8,8 @@
use Drupal\content_moderation\EntityOperations;
use Drupal\content_moderation\EntityTypeInfo;
use Drupal\content_moderation\ContentPreprocess;
-use Drupal\content_moderation\Plugin\Action\ModerationOptOutPublishNode;
-use Drupal\content_moderation\Plugin\Action\ModerationOptOutUnpublishNode;
+use Drupal\content_moderation\Plugin\Action\ModerationOptOutPublish;
+use Drupal\content_moderation\Plugin\Action\ModerationOptOutUnpublish;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
@@ -21,8 +21,8 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\workflows\WorkflowInterface;
-use Drupal\node\Plugin\Action\PublishNode;
-use Drupal\node\Plugin\Action\UnpublishNode;
+use Drupal\Core\Action\Plugin\Action\PublishAction;
+use Drupal\Core\Action\Plugin\Action\UnpublishAction;
use Drupal\workflows\Entity\Workflow;
/**
@@ -227,13 +227,15 @@ function content_moderation_action_info_alter(&$definitions) {
// The publish/unpublish actions are not valid on moderated entities. So swap
// their implementations out for alternates that will become a no-op on a
- // moderated node. If another module has already swapped out those classes,
+ // moderated entity. If another module has already swapped out those classes,
// though, we'll be polite and do nothing.
- if (isset($definitions['node_publish_action']['class']) && $definitions['node_publish_action']['class'] == PublishNode::class) {
- $definitions['node_publish_action']['class'] = ModerationOptOutPublishNode::class;
- }
- if (isset($definitions['node_unpublish_action']['class']) && $definitions['node_unpublish_action']['class'] == UnpublishNode::class) {
- $definitions['node_unpublish_action']['class'] = ModerationOptOutUnpublishNode::class;
+ foreach ($definitions as &$definition) {
+ if ($definition['id'] === 'entity:publish_action' && $definition['class'] == PublishAction::class) {
+ $definition['class'] = ModerationOptOutPublish::class;
+ }
+ if ($definition['id'] === 'entity:unpublish_action' && $definition['class'] == UnpublishAction::class) {
+ $definition['class'] = ModerationOptOutUnpublish::class;
+ }
}
}
diff --git a/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutPublish.php b/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutPublish.php
new file mode 100644
index 0000000..6a707e8
--- /dev/null
+++ b/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutPublish.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace Drupal\content_moderation\Plugin\Action;
+
+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\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\content_moderation\ModerationInformationInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Alternate action plugin that can opt-out of modifying moderated entities.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\PublishAction
+ */
+class ModerationOptOutPublish extends PublishAction implements ContainerFactoryPluginInterface {
+
+ /**
+ * Moderation information service.
+ *
+ * @var \Drupal\content_moderation\ModerationInformationInterface
+ */
+ protected $moderationInfo;
+
+ /**
+ * Bundle info service.
+ *
+ * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+ */
+ protected $bundleInfo;
+
+ /**
+ * ModerationOptOutPublish constructor.
+ *
+ * @param array $configuration
+ * A configuration array containing information about the plugin instance.
+ * @param string $plugin_id
+ * The plugin_id for the plugin instance.
+ * @param mixed $plugin_definition
+ * The plugin implementation definition.
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+ * The entity type manager.
+ * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
+ * The moderation information service.
+ * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info
+ * Bundle info service.
+ */
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_info, EntityTypeBundleInfoInterface $bundle_info) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
+ $this->moderationInfo = $moderation_info;
+ $this->bundleInfo = $bundle_info;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration, $plugin_id, $plugin_definition,
+ $container->get('entity_type.manager'),
+ $container->get('content_moderation.moderation_information'),
+ $container->get('entity_type.bundle.info')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function access($entity, AccountInterface $account = NULL, $return_as_object = FALSE) {
+ /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
+ 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();
+ return $return_as_object ? $result : $result->isAllowed();
+ }
+ return parent::access($entity, $account, $return_as_object);
+ }
+
+}
diff --git a/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutPublishNode.php b/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutPublishNode.php
index b2d8533..e1c5ce9 100644
--- a/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutPublishNode.php
+++ b/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutPublishNode.php
@@ -2,65 +2,28 @@
namespace Drupal\content_moderation\Plugin\Action;
-use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\node\Plugin\Action\PublishNode;
use Drupal\content_moderation\ModerationInformationInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Alternate action plugin that can opt-out of modifying moderated entities.
*
- * @see \Drupal\node\Plugin\Action\PublishNode
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\content_moderation\Plugin\Action\ModerationOptOutPublish
+ * instead.
+ *
+ * @see \Drupal\content_moderation\Plugin\Action\ModerationOptOutPublish
+ * @see https://www.drupal.org/node/2919303
*/
-class ModerationOptOutPublishNode extends PublishNode implements ContainerFactoryPluginInterface {
-
- /**
- * Moderation information service.
- *
- * @var \Drupal\content_moderation\ModerationInformationInterface
- */
- protected $moderationInfo;
-
- /**
- * ModerationOptOutPublishNode constructor.
- *
- * @param array $configuration
- * A configuration array containing information about the plugin instance.
- * @param string $plugin_id
- * The plugin_id for the plugin instance.
- * @param mixed $plugin_definition
- * The plugin implementation definition.
- * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
- * The moderation information service.
- */
- public function __construct(array $configuration, $plugin_id, $plugin_definition, ModerationInformationInterface $moderation_info) {
- parent::__construct($configuration, $plugin_id, $plugin_definition);
- $this->moderationInfo = $moderation_info;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
- return new static(
- $configuration, $plugin_id, $plugin_definition,
- $container->get('content_moderation.moderation_information')
- );
- }
+class ModerationOptOutPublishNode extends ModerationOptOutPublish {
/**
* {@inheritdoc}
*/
- public function access($entity, AccountInterface $account = NULL, $return_as_object = FALSE) {
- /** @var \Drupal\node\NodeInterface $entity */
- if ($entity && $this->moderationInfo->isModeratedEntity($entity)) {
- drupal_set_message($this->t("@bundle @label were skipped as they are under moderation and may not be directly published.", ['@bundle' => node_get_type_label($entity), '@label' => $entity->getEntityType()->getPluralLabel()]), 'warning');
- $result = AccessResult::forbidden();
- return $return_as_object ? $result : $result->isAllowed();
- }
- return parent::access($entity, $account, $return_as_object);
+ public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_info, EntityTypeBundleInfoInterface $bundle_info) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $moderation_info, $bundle_info);
+ @trigger_error(__NAMESPACE__ . '\ModerationOptOutPublishNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\content_moderation\Plugin\Action\ModerationOptOutPublish instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
diff --git a/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutUnpublish.php b/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutUnpublish.php
new file mode 100644
index 0000000..5a46b3e
--- /dev/null
+++ b/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutUnpublish.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace Drupal\content_moderation\Plugin\Action;
+
+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\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\content_moderation\ModerationInformationInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Alternate action plugin that can opt-out of modifying moderated entities.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\UnpublishAction
+ */
+class ModerationOptOutUnpublish extends UnpublishAction implements ContainerFactoryPluginInterface {
+
+ /**
+ * Moderation information service.
+ *
+ * @var \Drupal\content_moderation\ModerationInformationInterface
+ */
+ protected $moderationInfo;
+
+ /**
+ * Bundle info service.
+ *
+ * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+ */
+ protected $bundleInfo;
+
+ /**
+ * ModerationOptOutUnpublish constructor.
+ *
+ * @param array $configuration
+ * A configuration array containing information about the plugin instance.
+ * @param string $plugin_id
+ * The plugin_id for the plugin instance.
+ * @param mixed $plugin_definition
+ * The plugin implementation definition.
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+ * The entity type manager.
+ * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
+ * The moderation information service.
+ * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info
+ * Bundle info service.
+ */
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_info, EntityTypeBundleInfoInterface $bundle_info) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
+ $this->moderationInfo = $moderation_info;
+ $this->bundleInfo = $bundle_info;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration, $plugin_id, $plugin_definition,
+ $container->get('entity_type.manager'),
+ $container->get('content_moderation.moderation_information'),
+ $container->get('entity_type.bundle.info')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function access($entity, AccountInterface $account = NULL, $return_as_object = FALSE) {
+ /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
+ 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();
+ return $return_as_object ? $result : $result->isAllowed();
+ }
+ return parent::access($entity, $account, $return_as_object);
+ }
+
+}
diff --git a/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutUnpublishNode.php b/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutUnpublishNode.php
index ee36169..d76d3f1 100644
--- a/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutUnpublishNode.php
+++ b/core/modules/content_moderation/src/Plugin/Action/ModerationOptOutUnpublishNode.php
@@ -2,65 +2,28 @@
namespace Drupal\content_moderation\Plugin\Action;
-use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\node\Plugin\Action\UnpublishNode;
use Drupal\content_moderation\ModerationInformationInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Alternate action plugin that can opt-out of modifying moderated entities.
*
- * @see \Drupal\node\Plugin\Action\UnpublishNode
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\content_moderation\Plugin\Action\ModerationOptOutUnpublish
+ * instead.
+ *
+ * @see \Drupal\content_moderation\Plugin\Action\ModerationOptOutPublish
+ * @see https://www.drupal.org/node/2919303
*/
-class ModerationOptOutUnpublishNode extends UnpublishNode implements ContainerFactoryPluginInterface {
-
- /**
- * Moderation information service.
- *
- * @var \Drupal\content_moderation\ModerationInformationInterface
- */
- protected $moderationInfo;
-
- /**
- * ModerationOptOutUnpublishNode constructor.
- *
- * @param array $configuration
- * A configuration array containing information about the plugin instance.
- * @param string $plugin_id
- * The plugin_id for the plugin instance.
- * @param mixed $plugin_definition
- * The plugin implementation definition.
- * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
- * The moderation information service.
- */
- public function __construct(array $configuration, $plugin_id, $plugin_definition, ModerationInformationInterface $moderation_info) {
- parent::__construct($configuration, $plugin_id, $plugin_definition);
- $this->moderationInfo = $moderation_info;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
- return new static(
- $configuration, $plugin_id, $plugin_definition,
- $container->get('content_moderation.moderation_information')
- );
- }
+class ModerationOptOutUnpublishNode extends ModerationOptOutUnpublish {
/**
* {@inheritdoc}
*/
- public function access($entity, AccountInterface $account = NULL, $return_as_object = FALSE) {
- /** @var \Drupal\node\NodeInterface $entity */
- if ($entity && $this->moderationInfo->isModeratedEntity($entity)) {
- drupal_set_message($this->t("@bundle @label were skipped as they are under moderation and may not be directly unpublished.", ['@bundle' => node_get_type_label($entity), '@label' => $entity->getEntityType()->getPluralLabel()]), 'warning');
- $result = AccessResult::forbidden();
- return $return_as_object ? $result : $result->isAllowed();
- }
- return parent::access($entity, $account, $return_as_object);
+ public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_info, EntityTypeBundleInfoInterface $bundle_info) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $moderation_info, $bundle_info);
+ @trigger_error(__NAMESPACE__ . '\ModerationOptOutUnpublishNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\content_moderation\Plugin\Action\ModerationOptOutUnpublish instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
diff --git a/core/modules/node/config/install/system.action.node_publish_action.yml b/core/modules/node/config/install/system.action.node_publish_action.yml
index 20ed19b..3e139bb 100644
--- a/core/modules/node/config/install/system.action.node_publish_action.yml
+++ b/core/modules/node/config/install/system.action.node_publish_action.yml
@@ -6,5 +6,5 @@ dependencies:
id: node_publish_action
label: 'Publish content'
type: node
-plugin: node_publish_action
+plugin: entity:publish_action:node
configuration: { }
diff --git a/core/modules/node/config/install/system.action.node_save_action.yml b/core/modules/node/config/install/system.action.node_save_action.yml
index 887ff43..1759c35 100644
--- a/core/modules/node/config/install/system.action.node_save_action.yml
+++ b/core/modules/node/config/install/system.action.node_save_action.yml
@@ -6,5 +6,5 @@ dependencies:
id: node_save_action
label: 'Save content'
type: node
-plugin: node_save_action
+plugin: entity:save_action:node
configuration: { }
diff --git a/core/modules/node/config/install/system.action.node_unpublish_action.yml b/core/modules/node/config/install/system.action.node_unpublish_action.yml
index 1e778c0..0d5e35e 100644
--- a/core/modules/node/config/install/system.action.node_unpublish_action.yml
+++ b/core/modules/node/config/install/system.action.node_unpublish_action.yml
@@ -6,5 +6,5 @@ dependencies:
id: node_unpublish_action
label: 'Unpublish content'
type: node
-plugin: node_unpublish_action
+plugin: entity:unpublish_action:node
configuration: { }
diff --git a/core/modules/node/config/schema/node.schema.yml b/core/modules/node/config/schema/node.schema.yml
index 11a93c5..50b3f3e 100644
--- a/core/modules/node/config/schema/node.schema.yml
+++ b/core/modules/node/config/schema/node.schema.yml
@@ -62,14 +62,20 @@ action.configuration.node_promote_action:
type: action_configuration_default
label: 'Promote selected content from front page configuration'
+# @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+# @see https://www.drupal.org/node/2919303
action.configuration.node_publish_action:
type: action_configuration_default
label: 'Publish selected content configuration'
+# @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+# @see https://www.drupal.org/node/2919303
action.configuration.node_unpublish_action:
type: action_configuration_default
label: 'Unpublish selected content configuration'
+# @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+# @see https://www.drupal.org/node/2919303
action.configuration.node_save_action:
type: action_configuration_default
label: 'Save content configuration'
diff --git a/core/modules/node/src/Plugin/Action/PublishNode.php b/core/modules/node/src/Plugin/Action/PublishNode.php
index 2fa8c01..adecc7d 100644
--- a/core/modules/node/src/Plugin/Action/PublishNode.php
+++ b/core/modules/node/src/Plugin/Action/PublishNode.php
@@ -2,25 +2,32 @@
namespace Drupal\node\Plugin\Action;
-use Drupal\Core\Field\FieldUpdateActionBase;
-use Drupal\node\NodeInterface;
+use Drupal\Core\Action\Plugin\Action\PublishAction;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Publishes a node.
*
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Action\Plugin\Action\PublishAction instead.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\PublishAction
+ * @see https://www.drupal.org/node/2919303
+ *
* @Action(
* id = "node_publish_action",
* label = @Translation("Publish selected content"),
* type = "node"
* )
*/
-class PublishNode extends FieldUpdateActionBase {
+class PublishNode extends PublishAction {
/**
* {@inheritdoc}
*/
- protected function getFieldsToUpdate() {
- return ['status' => NodeInterface::PUBLISHED];
+ public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
+ @trigger_error(__NAMESPACE__ . '\PublishNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\PublishAction instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
diff --git a/core/modules/node/src/Plugin/Action/SaveNode.php b/core/modules/node/src/Plugin/Action/SaveNode.php
index e358fef..d9eea0c 100644
--- a/core/modules/node/src/Plugin/Action/SaveNode.php
+++ b/core/modules/node/src/Plugin/Action/SaveNode.php
@@ -2,36 +2,33 @@
namespace Drupal\node\Plugin\Action;
-use Drupal\Core\Action\ActionBase;
-use Drupal\Core\Session\AccountInterface;
+use Drupal\Component\Datetime\TimeInterface;
+use Drupal\Core\Action\Plugin\Action\SaveAction;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Provides an action that can save any entity.
*
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Action\Plugin\Action\SaveAction instead.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\SaveAction
+ * @see https://www.drupal.org/node/2919303
+ *
* @Action(
* id = "node_save_action",
* label = @Translation("Save content"),
* type = "node"
* )
*/
-class SaveNode extends ActionBase {
-
- /**
- * {@inheritdoc}
- */
- public function execute($entity = NULL) {
- // We need to change at least one value, otherwise the changed timestamp
- // will not be updated.
- $entity->changed = 0;
- $entity->save();
- }
+class SaveNode extends SaveAction {
/**
* {@inheritdoc}
*/
- public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
- /** @var \Drupal\node\NodeInterface $object */
- return $object->access('update', $account, $return_as_object);
+ public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $time);
+ @trigger_error(__NAMESPACE__ . '\SaveNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\SaveAction instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
diff --git a/core/modules/node/src/Plugin/Action/UnpublishNode.php b/core/modules/node/src/Plugin/Action/UnpublishNode.php
index 7c286e2..bb188d7 100644
--- a/core/modules/node/src/Plugin/Action/UnpublishNode.php
+++ b/core/modules/node/src/Plugin/Action/UnpublishNode.php
@@ -2,25 +2,32 @@
namespace Drupal\node\Plugin\Action;
-use Drupal\Core\Field\FieldUpdateActionBase;
-use Drupal\node\NodeInterface;
+use Drupal\Core\Action\Plugin\Action\UnpublishAction;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Unpublishes a node.
*
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Action\Plugin\Action\UnpublishAction instead.
+ *
+ * @see \Drupal\Core\Action\Plugin\Action\UnpublishAction
+ * @see https://www.drupal.org/node/2919303
+ *
* @Action(
* id = "node_unpublish_action",
* label = @Translation("Unpublish selected content"),
* type = "node"
* )
*/
-class UnpublishNode extends FieldUpdateActionBase {
+class UnpublishNode extends UnpublishAction {
/**
* {@inheritdoc}
*/
- protected function getFieldsToUpdate() {
- return ['status' => NodeInterface::NOT_PUBLISHED];
+ public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
+ @trigger_error(__NAMESPACE__ . '\UnpublishNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\UnpublishAction instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php
index eb11a19..da13077 100644
--- a/core/modules/system/system.post_update.php
+++ b/core/modules/system/system.post_update.php
@@ -88,3 +88,26 @@ function system_post_update_field_type_plugins() {
function system_post_update_field_formatter_entity_schema() {
// Empty post-update hook.
}
+
+/**
+ * Change plugin IDs of actions.
+ */
+function system_post_update_change_action_plugins() {
+ $old_new_action_id_map = [
+ 'comment_publish_action' => 'entity:publish_action:comment',
+ 'comment_unpublish_action' => 'entity:unpublish_action:comment',
+ 'comment_save_action' => 'entity:save_action:comment',
+ 'node_publish_action' => 'entity:publish_action:node',
+ 'node_unpublish_action' => 'entity:unpublish_action:node',
+ 'node_save_action' => 'entity:save_action:node',
+ ];
+
+ /** @var \Drupal\system\Entity\Action[] $actions */
+ $actions = \Drupal::entityTypeManager()->getStorage('action')->loadMultiple();
+ foreach ($actions as $action) {
+ if (isset($old_new_action_id_map[$action->getPlugin()->getPluginId()])) {
+ $action->setPlugin($old_new_action_id_map[$action->getPlugin()->getPluginId()]);
+ $action->save();
+ }
+ }
+}
diff --git a/core/modules/system/tests/src/Functional/Update/UpdateActionsWithEntityPluginsTest.php b/core/modules/system/tests/src/Functional/Update/UpdateActionsWithEntityPluginsTest.php
new file mode 100644
index 0000000..4094d00
--- /dev/null
+++ b/core/modules/system/tests/src/Functional/Update/UpdateActionsWithEntityPluginsTest.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Drupal\Tests\system\Functional\Update;
+
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+use Drupal\system\Entity\Action;
+
+/**
+ * Tests upgrading comment and node actions to generic entity ones.
+ *
+ * @group Update
+ */
+class UpdateActionsWithEntityPluginsTest extends UpdatePathTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setDatabaseDumpFiles() {
+ $this->databaseDumpFiles = [__DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz'];
+ }
+
+ /**
+ * Tests upgrading comment and node actions to generic entity ones.
+ *
+ * @see system_post_update_change_action_plugins()
+ */
+ public function testUpdateActionsWithEntityPlugins() {
+ $old_new_action_id_map = [
+ 'comment_publish_action' => ['comment_publish_action', 'entity:publish_action:comment'],
+ 'comment_unpublish_action' => ['comment_unpublish_action', 'entity:unpublish_action:comment'],
+ 'comment_save_action' => ['comment_save_action', 'entity:save_action:comment'],
+ 'node_publish_action' => ['node_publish_action', 'entity:publish_action:node'],
+ 'node_unpublish_action' => ['node_unpublish_action', 'entity:unpublish_action:node'],
+ 'node_save_action' => ['node_save_action', 'entity:save_action:node'],
+ ];
+
+ foreach ($old_new_action_id_map as $key => list($before, $after)) {
+ $config = \Drupal::configFactory()->get('system.action.' . $key);
+ $this->assertSame($before, $config->get('plugin'));
+ }
+
+ $this->runUpdates();
+
+ foreach ($old_new_action_id_map as $key => list($before, $after)) {
+ /** @var \Drupal\system\Entity\Action $action */
+ $action = Action::load($key);
+ $this->assertSame($after, $action->getPlugin()->getPluginId());
+ $config = \Drupal::configFactory()->get('system.action.' . $key);
+ $this->assertSame($after, $config->get('plugin'));
+
+ // Check that the type the action is based on will be a module dependency.
+ $this->assertArraySubset(['module' => [$action->getPluginDefinition()['type']]], $action->getDependencies());
+ }
+ }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Action/PublishActionTest.php b/core/tests/Drupal/KernelTests/Core/Action/PublishActionTest.php
new file mode 100644
index 0000000..04bf1c0
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Action/PublishActionTest.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Action;
+
+use Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver;
+use Drupal\entity_test\Entity\EntityTestMulRevPub;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\system\Entity\Action;
+
+/**
+ * @group Action
+ */
+class PublishActionTest extends KernelTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['system', 'entity_test', 'user'];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+ $this->installEntitySchema('entity_test_mulrevpub');
+ }
+
+ /**
+ * @covers \Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver::getDerivativeDefinitions
+ */
+ public function testGetDerivativeDefinitions() {
+ $deriver = new EntityPublishedActionDeriver(\Drupal::entityTypeManager());
+ $this->assertArraySubset([
+ 'entity_test_mulrevpub' => [
+ 'type' => 'entity_test_mulrevpub',
+ 'label' => 'Save test entity - revisions, data table, and published interface',
+ 'action_label' => 'Save',
+ ],
+ ], $deriver->getDerivativeDefinitions([
+ 'action_label' => 'Save',
+ ]));
+ }
+
+ /**
+ * @covers \Drupal\Core\Action\Plugin\Action\PublishAction::execute
+ */
+ public function testPublishAction() {
+ $entity = EntityTestMulRevPub::create(['name' => 'test']);
+ $entity->setUnpublished()->save();
+
+ $action = Action::create([
+ 'id' => 'entity_publish_action',
+ 'plugin' => 'entity:publish_action:entity_test_mulrevpub',
+ ]);
+ $action->save();
+ $this->assertFalse($entity->isPublished());
+ $action->execute([$entity]);
+ $this->assertTrue($entity->isPublished());
+ $this->assertArraySubset(['module' => ['entity_test']], $action->getDependencies());
+ }
+
+ /**
+ * @covers \Drupal\Core\Action\Plugin\Action\UnpublishAction::execute
+ */
+ public function testUnpublishAction() {
+ $entity = EntityTestMulRevPub::create(['name' => 'test']);
+ $entity->setPublished()->save();
+
+ $action = Action::create([
+ 'id' => 'entity_unpublish_action',
+ 'plugin' => 'entity:unpublish_action:entity_test_mulrevpub',
+ ]);
+ $action->save();
+ $this->assertTrue($entity->isPublished());
+ $action->execute([$entity]);
+ $this->assertFalse($entity->isPublished());
+ $this->assertArraySubset(['module' => ['entity_test']], $action->getDependencies());
+ }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Action/SaveActionTest.php b/core/tests/Drupal/KernelTests/Core/Action/SaveActionTest.php
new file mode 100644
index 0000000..118f542
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Action/SaveActionTest.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Action;
+
+use Drupal\Core\Action\Plugin\Action\Derivative\EntityChangedActionDeriver;
+use Drupal\entity_test\Entity\EntityTestMulChanged;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\system\Entity\Action;
+
+/**
+ * @group Action
+ */
+class SaveActionTest extends KernelTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['system', 'entity_test', 'user'];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+ $this->installEntitySchema('entity_test_mul_changed');
+ }
+
+ /**
+ * @covers \Drupal\Core\Action\Plugin\Action\Derivative\EntityChangedActionDeriver::getDerivativeDefinitions
+ */
+ public function testGetDerivativeDefinitions() {
+ $deriver = new EntityChangedActionDeriver(\Drupal::entityTypeManager());
+ $this->assertArraySubset([
+ 'entity_test_mul_changed' => [
+ 'type' => 'entity_test_mul_changed',
+ 'label' => 'Save test entity - data table',
+ 'action_label' => 'Save',
+ ],
+ ], $deriver->getDerivativeDefinitions([
+ 'action_label' => 'Save',
+ ]));
+ }
+
+ /**
+ * @covers \Drupal\Core\Action\Plugin\Action\SaveAction::execute
+ */
+ public function testSaveAction() {
+ $entity = EntityTestMulChanged::create(['name' => 'test']);
+ $entity->save();
+ $saved_time = $entity->getChangedTime();
+
+ $action = Action::create([
+ 'id' => 'entity_save_action',
+ 'plugin' => 'entity:save_action:entity_test_mul_changed',
+ ]);
+ $action->save();
+ $action->execute([$entity]);
+ $this->assertNotSame($saved_time, $entity->getChangedTime());
+ $this->assertArraySubset(['module' => ['entity_test']], $action->getDependencies());
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
index 9ec5430..2eecec9 100644
--- a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
+++ b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
@@ -135,6 +135,12 @@ trait DeprecationListenerTrait {
'drupal_get_message() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Messenger\MessengerInterface::all() or \Drupal\Core\Messenger\MessengerInterface::messagesByType() instead. See https://www.drupal.org/node/2774931',
'Adding or retrieving messages prior to the container being initialized was deprecated in Drupal 8.5.0 and this functionality will be removed before Drupal 9.0.0. Please report this usage at https://www.drupal.org/node/2928994.',
'The "serializer.normalizer.file_entity.hal" normalizer service is deprecated: it is obsolete, it only remains available for backwards compatibility.',
+ 'Drupal\comment\Plugin\Action\PublishComment is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\PublishAction instead. See https://www.drupal.org/node/2919303.',
+ 'Drupal\comment\Plugin\Action\SaveComment is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\SaveAction instead. See https://www.drupal.org/node/2919303.',
+ 'Drupal\comment\Plugin\Action\UnpublishComment is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\UnpublishAction instead. See https://www.drupal.org/node/2919303.',
+ 'Drupal\node\Plugin\Action\PublishNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\PublishAction instead. See https://www.drupal.org/node/2919303.',
+ 'Drupal\node\Plugin\Action\SaveNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\SaveAction instead. See https://www.drupal.org/node/2919303.',
+ 'Drupal\node\Plugin\Action\UnpublishNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\UnpublishAction instead. See https://www.drupal.org/node/2919303.',
];
}