summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Pott2016-12-02 22:18:44 +0000
committerAlex Pott2016-12-02 22:18:44 +0000
commit67c7387fd9de3e1c8de1add0c9945fbcf318b3e3 (patch)
tree5b03e42c7296ea0c3098e6a3b44d7ed6a2c235a1
parent740ccca37f6f3255e8afcf3246ce8cd7de05a12e (diff)
Issue #2789315 by amateescu, timmillwood, claudiu.cristea, sandervd, GroovyCarrot, catch, Wim Leers, Berdir, pfrenssen, twistor, xjm: Create EntityPublishedInterface and use for Node and Comment
-rw-r--r--core/lib/Drupal/Core/Entity/EntityPublishedInterface.php41
-rw-r--r--core/lib/Drupal/Core/Entity/EntityPublishedTrait.php61
-rw-r--r--core/lib/Drupal/Core/Entity/Exception/UnsupportedEntityTypeDefinitionException.php8
-rw-r--r--core/modules/comment/comment.install12
-rw-r--r--core/modules/comment/src/CommentInterface.php25
-rw-r--r--core/modules/comment/src/Entity/Comment.php11
-rw-r--r--core/modules/comment/src/Tests/Update/CommentUpdateTest.php18
-rw-r--r--core/modules/node/node.install21
-rw-r--r--core/modules/node/src/Entity/Node.php1
-rw-r--r--core/modules/node/src/NodeInterface.php24
-rw-r--r--core/modules/node/src/Tests/Update/NodeUpdateTest.php41
-rw-r--r--core/modules/rest/src/Plugin/rest/resource/EntityResource.php7
12 files changed, 203 insertions, 67 deletions
diff --git a/core/lib/Drupal/Core/Entity/EntityPublishedInterface.php b/core/lib/Drupal/Core/Entity/EntityPublishedInterface.php
new file mode 100644
index 0000000..4372008
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/EntityPublishedInterface.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\Core\Entity;
+
+/**
+ * Provides an interface for access to an entity's published state.
+ */
+interface EntityPublishedInterface {
+
+ /**
+ * Returns whether or not the entity is published.
+ *
+ * @return bool
+ * TRUE if the entity is published, FALSE otherwise.
+ */
+ public function isPublished();
+
+ /**
+ * Sets the entity as published.
+ *
+ * @param bool|null $published
+ * (optional and deprecated) TRUE to set this entity to published, FALSE to
+ * set it to unpublished. Defaults to NULL. This parameter is deprecated in
+ * Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use this method,
+ * without any parameter, to set the entity as published and
+ * setUnpublished() to set the entity as unpublished.
+ *
+ * @return $this
+ *
+ * @see \Drupal\Core\Entity\EntityPublishedInterface::setUnpublished()
+ */
+ public function setPublished($published = NULL);
+
+ /**
+ * Sets the entity as unpublished.
+ *
+ * @return $this
+ */
+ public function setUnpublished();
+
+}
diff --git a/core/lib/Drupal/Core/Entity/EntityPublishedTrait.php b/core/lib/Drupal/Core/Entity/EntityPublishedTrait.php
index 2145f4a..871aceb 100644
--- a/core/lib/Drupal/Core/Entity/EntityPublishedTrait.php
+++ b/core/lib/Drupal/Core/Entity/EntityPublishedTrait.php
@@ -2,6 +2,7 @@
namespace Drupal\Core\Entity;
+use Drupal\Core\Entity\Exception\UnsupportedEntityTypeDefinitionException;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
@@ -17,11 +18,21 @@ trait EntityPublishedTrait {
* The entity type to add the publishing status field to.
*
* @return \Drupal\Core\Field\BaseFieldDefinition[]
- * Array of base field definitions.
+ * An array of base field definitions.
+ *
+ * @throws \Drupal\Core\Entity\Exception\UnsupportedEntityTypeDefinitionException
+ * Thrown when the entity type does not implement EntityPublishedInterface
+ * or if it does not have a "published" entity key.
*/
public static function publishedBaseFieldDefinitions(EntityTypeInterface $entity_type) {
- $key = $entity_type->hasKey('status') ? $entity_type->getKey('status') : 'status';
- return [$key => BaseFieldDefinition::create('boolean')
+ if (!is_subclass_of($entity_type->getClass(), EntityPublishedInterface::class)) {
+ throw new UnsupportedEntityTypeDefinitionException('The entity type ' . $entity_type->id() . ' does not implement \Drupal\Core\Entity\EntityPublishedInterface.');
+ }
+ if (!$entity_type->hasKey('published')) {
+ throw new UnsupportedEntityTypeDefinitionException('The entity type ' . $entity_type->id() . ' does not have a "published" entity key.');
+ }
+
+ return [$entity_type->getKey('published') => BaseFieldDefinition::create('boolean')
->setLabel(new TranslatableMarkup('Publishing status'))
->setDescription(new TranslatableMarkup('A boolean indicating the published state.'))
->setRevisionable(TRUE)
@@ -30,31 +41,37 @@ trait EntityPublishedTrait {
}
/**
- * Returns the published status of the entity.
- *
- * @return bool
- * The published status of the entity.
+ * {@inheritdoc}
*/
public function isPublished() {
- $status = $this->getEntityKey('status');
- return (bool) (isset($status) ? $status : $this->get('status')->value);
+ $key = $this->getEntityType()->getKey('published');
+ return (bool) $this->get($key)->value;
}
/**
- * Sets the entity as published or not published.
- *
- * @param bool $published
- * A boolean value denoting the published status.
- *
- * @return \Drupal\Core\Entity\ContentEntityInterface $this
- * The Content Entity object.
+ * {@inheritdoc}
+ */
+ public function setPublished($published = NULL) {
+ if ($published !== NULL) {
+ @trigger_error('The $published parameter is deprecated since version 8.3.x and will be removed in 9.0.0.', E_USER_DEPRECATED);
+ $value = (bool) $published;
+ }
+ else {
+ $value = TRUE;
+ }
+ $key = $this->getEntityType()->getKey('published');
+ $this->set($key, $value);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
*/
- public function setPublished($published) {
- /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
- $key = $this->getEntityType()->getKey('status') ?: 'status';
- // @todo: Replace values with constants from EntityPublishedInterface or
- // similar when introduced. https://www.drupal.org/node/2811667
- $this->set($key, $published ? 1 : 0);
+ public function setUnpublished() {
+ $key = $this->getEntityType()->getKey('published');
+ $this->set($key, FALSE);
+
return $this;
}
diff --git a/core/lib/Drupal/Core/Entity/Exception/UnsupportedEntityTypeDefinitionException.php b/core/lib/Drupal/Core/Entity/Exception/UnsupportedEntityTypeDefinitionException.php
new file mode 100644
index 0000000..079b422
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Exception/UnsupportedEntityTypeDefinitionException.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Drupal\Core\Entity\Exception;
+
+/**
+ * Defines an exception thrown when an entity type definition is invalid.
+ */
+class UnsupportedEntityTypeDefinitionException extends \Exception { }
diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install
index 38958aa..895c039 100644
--- a/core/modules/comment/comment.install
+++ b/core/modules/comment/comment.install
@@ -194,5 +194,17 @@ function comment_update_8300() {
}
/**
+ * Set the 'published' entity key.
+ */
+function comment_update_8301() {
+ $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
+ $entity_type = $definition_update_manager->getEntityType('comment');
+ $keys = $entity_type->getKeys();
+ $keys['published'] = 'status';
+ $entity_type->set('entity_keys', $keys);
+ $definition_update_manager->updateEntityType($entity_type);
+}
+
+/**
* @} End of "addtogroup updates-8.3.x".
*/
diff --git a/core/modules/comment/src/CommentInterface.php b/core/modules/comment/src/CommentInterface.php
index 28318ee..9f3360c 100644
--- a/core/modules/comment/src/CommentInterface.php
+++ b/core/modules/comment/src/CommentInterface.php
@@ -3,13 +3,14 @@
namespace Drupal\comment;
use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\user\EntityOwnerInterface;
use Drupal\Core\Entity\EntityChangedInterface;
/**
* Provides an interface defining a comment entity.
*/
-interface CommentInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface {
+interface CommentInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface, EntityPublishedInterface {
/**
* Comment is awaiting approval.
@@ -192,31 +193,15 @@ interface CommentInterface extends ContentEntityInterface, EntityChangedInterfac
public function setCreatedTime($created);
/**
- * Checks if the comment is published.
- *
- * @return bool
- * TRUE if the comment is published.
- */
- public function isPublished();
-
- /**
* Returns the comment's status.
*
* @return int
* One of CommentInterface::PUBLISHED or CommentInterface::NOT_PUBLISHED
- */
- public function getStatus();
-
- /**
- * Sets the published status of the comment entity.
*
- * @param bool $status
- * Set to TRUE to publish the comment, FALSE to unpublish.
- *
- * @return \Drupal\comment\CommentInterface
- * The class instance that this method is called on.
+ * @deprecated in Drupal 8.3.0, will be removed before Drupal 9.0.0. Use
+ * \Drupal\Core\Entity\EntityPublishedInterface::isPublished() instead.
*/
- public function setPublished($status);
+ public function getStatus();
/**
* Returns the alphadecimal representation of the comment's place in a thread.
diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index a244163..d52f04d 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -50,7 +50,8 @@ use Drupal\user\UserInterface;
* "bundle" = "comment_type",
* "label" = "subject",
* "langcode" = "langcode",
- * "uuid" = "uuid"
+ * "uuid" = "uuid",
+ * "published" = "status",
* },
* links = {
* "canonical" = "/comment/{comment}",
@@ -81,8 +82,12 @@ class Comment extends ContentEntityBase implements CommentInterface {
parent::preSave($storage);
if (is_null($this->get('status')->value)) {
- $published = \Drupal::currentUser()->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED;
- $this->setPublished($published);
+ if (\Drupal::currentUser()->hasPermission('skip comment approval')) {
+ $this->setPublished();
+ }
+ else {
+ $this->setUnpublished();
+ }
}
if ($this->isNew()) {
// Add the comment to database. This next section builds the thread field.
diff --git a/core/modules/comment/src/Tests/Update/CommentUpdateTest.php b/core/modules/comment/src/Tests/Update/CommentUpdateTest.php
index 61d187d..1bf3bdc 100644
--- a/core/modules/comment/src/Tests/Update/CommentUpdateTest.php
+++ b/core/modules/comment/src/Tests/Update/CommentUpdateTest.php
@@ -50,4 +50,22 @@ class CommentUpdateTest extends UpdatePathTestBase {
$this->assertIdentical($config->get('content.comment_forum.settings.view_mode'), 'default');
}
+ /**
+ * Tests that the comment entity type has a 'published' entity key.
+ *
+ * @see comment_update_8301()
+ */
+ public function testPublishedEntityKey() {
+ // Check that the 'published' entity key does not exist prior to the update.
+ $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('comment');
+ $this->assertFalse($entity_type->getKey('published'));
+
+ // Run updates.
+ $this->runUpdates();
+
+ // Check that the entity key exists and it has the correct value.
+ $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('comment');
+ $this->assertEqual('status', $entity_type->getKey('published'));
+ }
+
}
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index 720a7e0..2751b2c 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -222,6 +222,11 @@ function node_update_8003() {
}
/**
+ * @addtogroup updates-8.3.x
+ * @{
+ */
+
+/**
* Change {node_access}.fallback from an int to a tinyint as it is a boolean.
*/
function node_update_8300() {
@@ -234,3 +239,19 @@ function node_update_8300() {
'size' => 'tiny',
]);
}
+
+/**
+ * Set the 'published' entity key.
+ */
+function node_update_8301() {
+ $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
+ $entity_type = $definition_update_manager->getEntityType('node');
+ $keys = $entity_type->getKeys();
+ $keys['published'] = 'status';
+ $entity_type->set('entity_keys', $keys);
+ $definition_update_manager->updateEntityType($entity_type);
+}
+
+/**
+ * @} End of "addtogroup updates-8.3.x".
+ */
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index d4e4715..f034957 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -56,6 +56,7 @@ use Drupal\user\UserInterface;
* "langcode" = "langcode",
* "uuid" = "uuid",
* "status" = "status",
+ * "published" = "status",
* "uid" = "uid",
* },
* bundle_entity_type = "node_type",
diff --git a/core/modules/node/src/NodeInterface.php b/core/modules/node/src/NodeInterface.php
index 980dacd..f3bcaea 100644
--- a/core/modules/node/src/NodeInterface.php
+++ b/core/modules/node/src/NodeInterface.php
@@ -2,6 +2,7 @@
namespace Drupal\node;
+use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\RevisionLogInterface;
use Drupal\user\EntityOwnerInterface;
use Drupal\Core\Entity\EntityChangedInterface;
@@ -10,7 +11,7 @@ use Drupal\Core\Entity\ContentEntityInterface;
/**
* Provides an interface defining a node entity.
*/
-interface NodeInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface, RevisionLogInterface {
+interface NodeInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface, RevisionLogInterface, EntityPublishedInterface {
/**
* Gets the node type.
@@ -97,27 +98,6 @@ interface NodeInterface extends ContentEntityInterface, EntityChangedInterface,
public function setSticky($sticky);
/**
- * Returns the node published status indicator.
- *
- * Unpublished nodes are only visible to their authors and to administrators.
- *
- * @return bool
- * TRUE if the node is published.
- */
- public function isPublished();
-
- /**
- * Sets the published status of a node..
- *
- * @param bool $published
- * TRUE to set this node to published, FALSE to set it to unpublished.
- *
- * @return \Drupal\node\NodeInterface
- * The called node entity.
- */
- public function setPublished($published);
-
- /**
* Gets the node revision creation timestamp.
*
* @return int
diff --git a/core/modules/node/src/Tests/Update/NodeUpdateTest.php b/core/modules/node/src/Tests/Update/NodeUpdateTest.php
new file mode 100644
index 0000000..b8b30be
--- /dev/null
+++ b/core/modules/node/src/Tests/Update/NodeUpdateTest.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\node\Tests\Update;
+
+use Drupal\system\Tests\Update\UpdatePathTestBase;
+
+/**
+ * Tests that node settings are properly updated during database updates.
+ *
+ * @group node
+ */
+class NodeUpdateTest extends UpdatePathTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setDatabaseDumpFiles() {
+ $this->databaseDumpFiles = [
+ __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz',
+ ];
+ }
+
+ /**
+ * Tests that the node entity type has a 'published' entity key.
+ *
+ * @see node_update_8301()
+ */
+ public function testPublishedEntityKey() {
+ // Check that the 'published' entity key does not exist prior to the update.
+ $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node');
+ $this->assertFalse($entity_type->getKey('published'));
+
+ // Run updates.
+ $this->runUpdates();
+
+ // Check that the entity key exists and it has the correct value.
+ $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node');
+ $this->assertEqual('status', $entity_type->getKey('published'));
+ }
+
+}
diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
index 55ce64a..a5cb361 100644
--- a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
+++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
@@ -213,6 +213,13 @@ class EntityResource extends ResourceBase implements DependentPluginInterface {
// them. However, rather than throwing an error, we just ignore them as
// long as their specified values match their current values.
if (in_array($field_name, $entity_keys, TRUE)) {
+ // @todo Work around the wrong assumption that entity keys need special
+ // treatment, when only read-only fields need it.
+ // This will be fixed in https://www.drupal.org/node/2824851.
+ if ($entity->getEntityTypeId() == 'comment' && $field_name == 'status' && !$original_entity->get($field_name)->access('edit')) {
+ throw new AccessDeniedHttpException("Access denied on updating field '$field_name'.");
+ }
+
// Unchanged values for entity keys don't need access checking.
if ($original_entity->get($field_name)->getValue() === $entity->get($field_name)->getValue()) {
continue;