diff --git a/core/modules/block_content/block_content.install b/core/modules/block_content/block_content.install index 6af2ac4..c6556e7 100644 --- a/core/modules/block_content/block_content.install +++ b/core/modules/block_content/block_content.install @@ -6,6 +6,23 @@ */ use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Implements hook_update_dependencies(). + */ +function block_content_update_dependencies() { + // The update function that adds the status field must run after + // content_translation_update_8400() which fixes NULL values for the + // 'content_translation_status' field. + if (\Drupal::moduleHandler()->moduleExists('content_translation')) { + $dependencies['block_content'][8400] = [ + 'content_translation' => 8400, + ]; + + return $dependencies; + } +} /** * Add 'revision_translation_affected' field to 'block_content' entities. @@ -70,5 +87,54 @@ function block_content_update_8300() { $entity_type = $definition_update_manager->getEntityType('block_content'); $entity_type->set('revision_data_table', 'block_content_field_revision'); $definition_update_manager->updateEntityType($entity_type); +} + +/** + * Add a publishing status field for block_content entities. + */ +function block_content_update_8400() { + $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + + // Add the published entity key to the block_content entity type. + $entity_type = $definition_update_manager->getEntityType('block_content'); + $entity_keys = $entity_type->getKeys(); + $entity_keys['published'] = 'status'; + $entity_type->set('entity_keys', $entity_keys); + $definition_update_manager->updateEntityType($entity_type); + + // Add the publishing status field to the block_content entity type. + $status = BaseFieldDefinition::create('boolean') + ->setLabel(new TranslatableMarkup('Publishing status')) + ->setDescription(new TranslatableMarkup('A boolean indicating the published state.')) + ->setRevisionable(TRUE) + ->setTranslatable(TRUE) + ->setDefaultValue(TRUE); + + $has_content_translation_status_field = \Drupal::moduleHandler()->moduleExists('content_translation') && $definition_update_manager->getFieldStorageDefinition('content_translation_status', 'block_content'); + if ($has_content_translation_status_field) { + $status->setInitialValueFromField('content_translation_status'); + } + else { + $status->setInitialValue(TRUE); + } + $definition_update_manager->installFieldStorageDefinition('status', 'block_content', 'block_content', $status); + + // Uninstall the 'content_translation_status' field if needed. + $database = \Drupal::database(); + if ($has_content_translation_status_field) { + // First we have to remove the field data. + $database->update($entity_type->getDataTable()) + ->fields(['content_translation_status' => NULL]) + ->execute(); + + // A site may have disabled revisionability for this entity type. + if ($entity_type->isRevisionable()) { + $database->update($entity_type->getRevisionDataTable()) + ->fields(['content_translation_status' => NULL]) + ->execute(); + } + $content_translation_status = $definition_update_manager->getFieldStorageDefinition('content_translation_status', 'block_content'); + $definition_update_manager->uninstallFieldStorageDefinition($content_translation_status); + } } diff --git a/core/modules/block_content/src/BlockContentAccessControlHandler.php b/core/modules/block_content/src/BlockContentAccessControlHandler.php index d0c19c5..7079ef4 100644 --- a/core/modules/block_content/src/BlockContentAccessControlHandler.php +++ b/core/modules/block_content/src/BlockContentAccessControlHandler.php @@ -19,7 +19,8 @@ class BlockContentAccessControlHandler extends EntityAccessControlHandler { */ protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { if ($operation === 'view') { - return AccessResult::allowed(); + return AccessResult::allowedIf($entity->isPublished())->addCacheableDependency($entity) + ->orIf(AccessResult::allowedIfHasPermission($account, 'administer blocks')); } return parent::checkAccess($entity, $operation, $account); } diff --git a/core/modules/block_content/src/BlockContentInterface.php b/core/modules/block_content/src/BlockContentInterface.php index 130cae1..75fdc59 100644 --- a/core/modules/block_content/src/BlockContentInterface.php +++ b/core/modules/block_content/src/BlockContentInterface.php @@ -4,12 +4,13 @@ use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityChangedInterface; +use Drupal\Core\Entity\EntityPublishedInterface; use Drupal\Core\Entity\RevisionLogInterface; /** * Provides an interface defining a custom block entity. */ -interface BlockContentInterface extends ContentEntityInterface, EntityChangedInterface, RevisionLogInterface { +interface BlockContentInterface extends ContentEntityInterface, EntityChangedInterface, RevisionLogInterface, EntityPublishedInterface { /** * Returns the block revision log message. diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php index 76071df..7430fd9 100644 --- a/core/modules/block_content/src/Entity/BlockContent.php +++ b/core/modules/block_content/src/Entity/BlockContent.php @@ -2,8 +2,7 @@ namespace Drupal\block_content\Entity; -use Drupal\Core\Entity\ContentEntityBase; -use Drupal\Core\Entity\EntityChangedTrait; +use Drupal\Core\Entity\EditorialContentEntityBase; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; @@ -51,7 +50,8 @@ * "bundle" = "type", * "label" = "info", * "langcode" = "langcode", - * "uuid" = "uuid" + * "uuid" = "uuid", + * "published" = "status", * }, * revision_metadata_keys = { * "revision_user" = "revision_user", @@ -68,9 +68,7 @@ * caching. * See https://www.drupal.org/node/2284917#comment-9132521 for more information. */ -class BlockContent extends ContentEntityBase implements BlockContentInterface { - - use EntityChangedTrait; +class BlockContent extends EditorialContentEntityBase implements BlockContentInterface { /** * The theme the block is being created in. @@ -174,6 +172,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['type']->setLabel(t('Block type')) ->setDescription(t('The block type.')); + $fields['revision_log']->setDescription(t('The log entry explaining the changes in this revision.')); + $fields['info'] = BaseFieldDefinition::create('string') ->setLabel(t('Block description')) ->setDescription(t('A brief description of your block.')) @@ -187,35 +187,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDisplayConfigurable('form', TRUE) ->addConstraint('UniqueField', []); - $fields['revision_log'] = BaseFieldDefinition::create('string_long') - ->setLabel(t('Revision log message')) - ->setDescription(t('The log entry explaining the changes in this revision.')) - ->setRevisionable(TRUE) - ->setDisplayOptions('form', [ - 'type' => 'string_textarea', - 'weight' => 25, - 'settings' => [ - 'rows' => 4, - ], - ]); - $fields['changed'] = BaseFieldDefinition::create('changed') ->setLabel(t('Changed')) ->setDescription(t('The time that the custom block was last edited.')) ->setTranslatable(TRUE) ->setRevisionable(TRUE); - $fields['revision_created'] = BaseFieldDefinition::create('created') - ->setLabel(t('Revision create time')) - ->setDescription(t('The time that the current revision was created.')) - ->setRevisionable(TRUE); - - $fields['revision_user'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('Revision user')) - ->setDescription(t('The user ID of the author of the current revision.')) - ->setSetting('target_type', 'user') - ->setRevisionable(TRUE); - $fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean') ->setLabel(t('Revision translation affected')) ->setDescription(t('Indicates if the last edit of a translation belongs to current revision.')) diff --git a/core/modules/block_content/src/Tests/BlockContentUpdateTest.php b/core/modules/block_content/src/Tests/Update/BlockContentUpdateTest.php similarity index 57% rename from core/modules/block_content/src/Tests/BlockContentUpdateTest.php rename to core/modules/block_content/src/Tests/Update/BlockContentUpdateTest.php index 77c12c6..888607e 100644 --- a/core/modules/block_content/src/Tests/BlockContentUpdateTest.php +++ b/core/modules/block_content/src/Tests/Update/BlockContentUpdateTest.php @@ -1,6 +1,6 @@ databaseDumpFiles = [ - __DIR__ . '/../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz', ]; } @@ -43,4 +44,27 @@ public function testSimpleUpdates() { $this->assertEqual('block_content_field_revision', $entity_type->getRevisionDataTable()); } + /** + * Tests adding a status field to the block content entity type. + * + * @see block_content_update_8400() + */ + public function testStatusFieldAddition() { + $schema = \Drupal::database()->schema(); + $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + + // Run updates. + $this->runUpdates(); + + // Check that the field exists and has the correct label. + $updated_field = $entity_definition_update_manager->getFieldStorageDefinition('status', 'block_content'); + $this->assertEqual('Publishing status', $updated_field->getLabel()); + + $content_translation_status = $entity_definition_update_manager->getFieldStorageDefinition('content_translation_status', 'block_content'); + $this->assertNull($content_translation_status); + + $this->assertFalse($schema->fieldExists('block_content_field_revision', 'content_translation_status')); + $this->assertFalse($schema->fieldExists('block_content_field_data', 'content_translation_status')); + } + } diff --git a/core/modules/block_content/tests/src/Functional/UnpublishedBlockTest.php b/core/modules/block_content/tests/src/Functional/UnpublishedBlockTest.php new file mode 100644 index 0000000..026b0e5 --- /dev/null +++ b/core/modules/block_content/tests/src/Functional/UnpublishedBlockTest.php @@ -0,0 +1,47 @@ + 'Test block', + 'type' => 'basic', + ]); + $block_content->save(); + + $this->placeBlock('block_content:' . $block_content->uuid()); + + $this->drupalGet(''); + $page = $this->getSession()->getPage(); + $this->assertTrue($page->has('css', '.block-block-content' . $block_content->uuid())); + + $block_content->setPublished(FALSE); + $block_content->save(); + + $this->drupalGet(''); + $page = $this->getSession()->getPage(); + $this->assertFalse($page->has('css', '.block-block-content' . $block_content->uuid())); + } + +}