Problem/Motivation

There is currently no way to unpublish BlockContent entities. Now with #2810381: Add generic status field to ContentEntityBase we have an easy way to do this.

Proposed resolution

Add EntityPublishedTrait to BlockContent

Remaining tasks

User interface changes

None.
Follow up: #2834546: UI for publishing/unpublishing block_content blocks

API changes

Data model changes

CommentFileSizeAuthor
#159 2820848-159.patch11.9 KBamateescu
#148 2820848-148-manual-interdiff.txt3.63 KBBerdir
#148 2820848-148.patch12.8 KBBerdir
#139 2820848-129.patch12.97 KBBerdir
#133 interdiff.txt917 bytesamateescu
#133 2820848-133.patch12.89 KBamateescu
#129 interdiff.txt796 bytesamateescu
#129 2820848-129.patch12.97 KBamateescu
#118 interdiff.txt1.71 KBamateescu
#118 2820848-118.patch12.2 KBamateescu
#113 interdiff.txt4.62 KBamateescu
#113 2820848-113.patch12.04 KBamateescu
#111 2820848-111.patch11.81 KBamateescu
#110 2820848-110-combined.patch21.07 KBamateescu
#110 2820848-110.patch11.81 KBamateescu
#109 2820848-109-combined.patch40.33 KBamateescu
#105 2820848-105-combined.patch432.88 KBamateescu
#105 2820848-105.patch11.81 KBamateescu
#103 interdiff.txt8.77 KBamateescu
#103 2820848-103-combined.patch446.15 KBamateescu
#103 2820848-103.patch11.89 KBamateescu
#98 2820848-98.patch12.74 KBjofitz
#98 interdiff-96-98.txt543 bytesjofitz
#96 updatedinterdif.txt511 bytesPavan B S
#96 2820848-97.patch12.74 KBPavan B S
#94 interdiff.txt653 bytesPavan B S
#94 2820848-95.patch12.75 KBPavan B S
#93 interdiff.txt1.04 KBamateescu
#93 2820848-93.patch12.74 KBamateescu
#91 2820848-91-combined.patch442.26 KBamateescu
#89 interdiff.txt9.85 KBamateescu
#89 2820848-89.patch12.81 KBamateescu
#80 interdiff.txt814 bytestimmillwood
#80 2820848-80.patch13.23 KBtimmillwood
#77 interdiff.txt1.55 KBtimmillwood
#77 2820848-77.patch13.18 KBtimmillwood
#74 interdiff.txt6.7 KBtimmillwood
#74 2820848-74.patch13.13 KBtimmillwood
#73 interdiff.txt5.17 KBtimmillwood
#73 2820848-73.patch12.28 KBtimmillwood
#68 interdiff.txt2.39 KBtimmillwood
#68 2820848-68.patch10.86 KBtimmillwood
#65 interdiff.txt1.72 KBtimmillwood
#65 2820848-65.patch10.62 KBtimmillwood
#62 interdiff.txt2.52 KBtimmillwood
#62 2820848-61.patch9.87 KBtimmillwood
#54 interdiff.txt2.45 KBtimmillwood
#54 2820848-54.patch9.22 KBtimmillwood
#43 interdiff.txt2.62 KBtimmillwood
#43 2820848-43.patch9.18 KBtimmillwood
#37 interdiff.txt1.04 KBGábor Hojtsy
#37 2820848-37.patch9.62 KBGábor Hojtsy
#35 interdiff.txt3.33 KBtimmillwood
#35 2820848-35.patch9.64 KBtimmillwood
#34 interdiff.txt1.77 KBtimmillwood
#34 2820848-34.patch8.12 KBtimmillwood
#31 interdiff.txt754 bytestimmillwood
#31 2820848-31.patch7.76 KBtimmillwood
#29 interdiff.txt1.68 KBamateescu
#29 2820848-29.patch7.74 KBamateescu
#26 interdiff.txt2.34 KBamateescu
#26 2820848-26.patch7.39 KBamateescu
#24 interdiff.txt1.55 KBtimmillwood
#24 2820848-24.patch6.29 KBtimmillwood
#21 interdiff.txt1.21 KBtimmillwood
#21 2820848-21.patch4.79 KBtimmillwood
#19 interdiff.txt2.43 KBtimmillwood
#19 2820848-19.patch4.92 KBtimmillwood
#15 2820848-10.patch2.54 KBtimmillwood
#12 interdiff.txt1.75 KBtimmillwood
#12 2820848-12.patch3.27 KBtimmillwood
#10 interdiff.txt1.01 KBtimmillwood
#10 2820848-10.patch2.54 KBtimmillwood
#5 interdiff.txt1.55 KBtimmillwood
#5 2820848-5.patch2.73 KBtimmillwood
#2 2820848-2.patch1.18 KBtimmillwood
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

timmillwood created an issue. See original summary.

timmillwood’s picture

Status: Active » Needs review
FileSize
1.18 KB

Initial patch to get the ball rolling, will fail due to upgrade path.

Status: Needs review » Needs work

The last submitted patch, 2: 2820848-2.patch, failed testing.

larowlan’s picture

+1 from my end

timmillwood’s picture

Status: Needs work » Needs review
FileSize
2.73 KB
1.55 KB

This should do the trick.

Will create a follow up patch to start making use of the status field on BlockContent entities.

googletorp’s picture

The patch looks good, but I can't see that the published status is actually being used for anything. Shouldn't we add some logic that unpublished blocks are invisible or is that handled by ContentEntityBase already?

timmillwood’s picture

@googletorp - You are correct, this patch does not make use of the publishing status, it just adds it. The default is published, so all BlockContent entities will continue to be published just as they are now. Once this is in I will work on a follow up patch, but that has a lot more complexities around it.

  • How do we unpublish a block? A radio button on the BlockContent entity form? a drop button on the BlockContent entity form?
  • Permissions? Who can unpublish BlockContent? Who can view unpublished BlockContent?
  • Views integration.
  • What happens when you unpublish an already placed block?
  • Can you place unpublished blocks in a region? But they just don't show up until published.
googletorp’s picture

Status: Needs review » Reviewed & tested by the community

@timmilwood Makes sense to split it up.

The patch itself looks good. Unless test bot finds something, this is good to go IMO.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 5: 2820848-5.patch, failed testing.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
2.54 KB
1.01 KB

$entity_type->getRevisionDataTable() returns null, but I think it's pretty safe to assume the table names are known.

googletorp’s picture

Status: Needs review » Needs work

@timmilwood

I think it would be a better option to add the revision data table to the entity type definition, that is why it's return null.

If you add

* revision_data_table = "block_content_field_revision",

to patch 5, it should work. Also has the benefits that other stuff can access the info if needed.

timmillwood’s picture

FileSize
3.27 KB
1.75 KB

That makes the update hook a little bit more complex, but should be ok.

timmillwood’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 12: 2820848-12.patch, failed testing.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
2.54 KB

The fails in #12 are due to "The SQL storage cannot change the schema for an existing entity type (block_content) with data." Therefore I think it's out of the scope of this issue to add the table name to the entity type annotation.

We should just go with the patch from #10.

Re-uploading.

timmillwood’s picture

googletorp’s picture

Status: Needs review » Reviewed & tested by the community

Patch is green and looks good. Ready to go imo.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Can't you set this via FieldableEntityInterface::set() once this patch lands? In which case code could do it and expect the block to not be shown?

Also not sure how this works between the content entity and the configuration entity for the block. Even if we don't add getters/setters, it feels in scope to sort out what actually happens once status = 0 here.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
4.92 KB
2.43 KB

In this update to the patch it prevents unpublished blocks from being rendered. There is also a simple test for this.

Berdir’s picture

+++ b/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php
@@ -158,7 +158,11 @@ protected function blockAccess(AccountInterface $account) {
   public function build() {
     if ($block = $this->getEntity()) {
-      return $this->entityManager->getViewBuilder($block->getEntityTypeId())->view($block, $this->configuration['view_mode']);
+      if ($block->isPublished()) {

shouldn't this be part of accessing checking instead?

timmillwood’s picture

FileSize
4.79 KB
1.21 KB

@Berdir I guess it should, good thinking!

amateescu’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me.

amateescu’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/block_content/block_content.install
@@ -61,3 +62,21 @@ function block_content_update_8003() {
+function block_content_update_8004() {

Actually, we need an update test that should check the existence of the new field and its default value.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
6.29 KB
1.55 KB

Adding test mentioned in #23.

timmillwood’s picture

Status: Needs review » Postponed
amateescu’s picture

Status: Postponed » Needs review
FileSize
7.39 KB
2.34 KB

That issue just got it so here's an updated patch that uses EntityPublishedInterface.

Status: Needs review » Needs work

The last submitted patch, 26: 2820848-26.patch, failed testing.

dawehner’s picture

+++ b/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php
@@ -147,7 +147,8 @@ public function blockSubmit($form, FormStateInterface $form_state) {
+    $block = $this->getEntity();
+    if ($block->isPublished()) {
       return $this->getEntity()->access('view', $account, TRUE);

Should we use $block->access() here? here?

+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -48,7 +49,8 @@
  *     "label" = "info",
  *     "langcode" = "langcode",
- *     "uuid" = "uuid"
+ *     "uuid" = "uuid",
+ *     "published" = "status",
  *   },

I would have also expected that we need to update the entity type: \Drupal\Core\Entity\EntityDefinitionUpdateManager::updateEntityType

amateescu’s picture

Status: Needs work » Needs review
FileSize
7.74 KB
1.68 KB

#28.1: Yup, we should :)
#28.2: Also yes, I was already on it when I saw the test failures.

Now there's one more thing to fix: since the new 'status' field is an entity key, it has to be created with an initial value that's not NULL, so we're bumping into #2346019: Handle initial values when creating a new field storage definition again :/

Status: Needs review » Needs work

The last submitted patch, 29: 2820848-29.patch, failed testing.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
7.76 KB
754 bytes

Fixing issue with \Drupal\block_content\Plugin\Block\BlockContentBlock::blockAccess returning boolean.

Status: Needs review » Needs work

The last submitted patch, 31: 2820848-31.patch, failed testing.

Berdir’s picture

Not very pretty but you can solve that with a custom storage schema class: http://cgit.drupalcode.org/file_entity/tree/src/FileEntityStorageSchema....

While adding that, we might also want to ensure we have an index on the status column so we can efficiently filter on that? Sites likely won't have a number of custom blocks where this will matter (or they will get in trouble with the amount of plugin derivatives..) but still..

timmillwood’s picture

Status: Needs work » Needs review
FileSize
8.12 KB
1.77 KB

Adding BlockContentStorageSchema.

timmillwood’s picture

Missing the storage schema, re-rolling.

The last submitted patch, 34: 2820848-34.patch, failed testing.

Gábor Hojtsy’s picture

Issue summary: View changes
FileSize
9.62 KB
1.04 KB

Reviewed this issue expecting a UI component. I see the reasons in #7, which I'm copying to the issue summary too.

Also found two nits. Instead of posting them here, I fixed them directly.

Berdir’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/block_content/src/BlockContentStorageSchema.php
    @@ -0,0 +1,41 @@
    +
    +    if ($storage_definition->getName() == 'status') {
    +      $schema['fields']['status']['initial'] = 1;
    

    can we add a comment for this?

  2. +++ b/core/modules/block_content/src/BlockContentStorageSchema.php
    @@ -0,0 +1,41 @@
    +
    +    $schema['block_content_field_data']['indexes'] += [
    +      'block_content__status' => ['status']
    +    ];
    +    $schema['block_content_field_revision']['indexes'] += [
    +      'block_content__status' => ['status']
    +    ];
    

    wondering if we even need to define that explicitly, actually. we get a not null constraint on it because it is an entity key, not sure if we also get an index automatically?

  3. +++ b/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php
    @@ -147,8 +147,8 @@ public function blockSubmit($form, FormStateInterface $form_state) {
       protected function blockAccess(AccountInterface $account) {
    -    if ($this->getEntity()) {
    -      return $this->getEntity()->access('view', $account, TRUE);
    +    if ($block = $this->getEntity()) {
    +      return AccessResult::allowedIf($block->isPublished() && $block->access('view', $account, TRUE));
         }
         return AccessResult::forbidden();
       }
    

    Actually looking at this, shouldn't the status check be inside BlockContentAccessControlHandler then?

    Right now we don't have the necessary cacheablity metadata on this.

amateescu’s picture

+++ b/core/modules/block_content/src/BlockContentStorageSchema.php
@@ -0,0 +1,41 @@
+  protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $storage_definition, $table_name, array $column_mapping) {
+    $schema = parent::getSharedTableFieldSchema($storage_definition, $table_name, $column_mapping);
+
+    if ($storage_definition->getName() == 'status') {
+      $schema['fields']['status']['initial'] = 1;
+    }
+
+    return $schema;
+  }

I don't think an index like this is useful on its own, instead we want one which also contains the bundle and ID keys, like Node has.

Opened #2834291: Add a SQL index for entity types that are using EntityPublishedInterface for that :)

heddn’s picture

Rather than assuming that unpublished should have access denied, I think node module adds a permission. Can we do similar? I can easily see where someone might want to assign this as a permission to certain roles of users.

Berdir’s picture

This is a bit different though. We're not denying access to anyone who can access them in the backend (there is only one administer-level permission for this anyway).

And most sites will have their node listings/views configured to not show unpublished, even if the current user has access. I think it is the same here, if you want to hide a block then it should be hidden for everyone.

heddn’s picture

Thanks for that clarification. I just got bitten by block module's rather restrictive access check and didn't want to see the same thing surfaced here.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
9.18 KB
2.62 KB

Quick update addressing items from #38.

heddn’s picture

+++ b/core/modules/block_content/src/BlockContentAccessControlHandler.php
@@ -19,7 +19,7 @@ class BlockContentAccessControlHandler extends EntityAccessControlHandler {
+      return AccessResult::allowedIf($entity->isPublished());

After looking at the code here, I still stand by my earlier comment. If I place the block unpublished on a page, I want to send that page's link to my editor and have them see the page, even the unpublished block. But still hide the block for anonymous users and even the node from anonymous users. From my looking at the code and what I'm facing with Block module, I do not think this is possible without overriding the access control handler and removing the status check. Basically reversing this logic.

dixon_’s picture

Issue summary: View changes
dixon_’s picture

If I place the block unpublished on a page, I want to send that page's link to my editor and have them see the page, even the unpublished block.

The idea with the Workflow Initiative is to introduce "workspaces" in order to more efficiently provide full site preview. This has several advantages over managing access control on a "live" page.
So the idea is that you'd be sending a link to a "stage" workspace where your block is published. After verification you'd then be publishing/replicating the stage workspace to the "live" workspace.

While workspaces aren't in core yet, you can use the Workspace contrib module to do this already.

timmillwood’s picture

I see this as a first step. As you see we're not even adding a UI to unpublish block content.

We could look at adding a view unpublished block content permission in a follow up.

heddn’s picture

I'm willing to not bikeshed, especially if the follow-up is created. Does this need a CR?

andypost’s picture

I'd better introduce the permission here because it looks incomplete to add feature without any way for user to get why the block is not displayed

Also why no changes in block listing? I suppose there should be a filter and column to display status/published (what about draft state?)

Maybe better to disallow placing unpublished block? Or just use some CSS like unpublished nodes using?

timmillwood’s picture

I'd really like to see all these as folllow up issues. Lets get the API change in, and make sure if if something uses the API to unpublish block content it doesn't get seen, then go through all the follow up items:

  • UI to unpublish blocks
  • UI to publish blocks
  • Permission to view unpublished block content
  • Views integration
  • Bulk operation to publish / unpublish blocks
  • Don't show unpublished blocks in the block listing?
  • Display the publishing status in the block listing?
  • Disallow placing unpublished blocks?
  • Show unpublished blocks with a red background?
  • etc
  • etc
Manuel Garcia’s picture

Although the permission could be added here, to me it would make more sense to do so on the issue for the UI, since that's where the permission would be checked, not if you do $block->setPublished(FALSE); in your code.

I agree this definitely needs followups, and it'd be great to open some of them.

To me it's fine if we get the patch in as is, because:

  • Since the default is published, all BlockContent entities will continue to work just as they are now, unless you execute code to unpublish it.
  • We can then work on all the follow ups in parallel, for example, views integration and UI to publish/unpublish + permissions could definitely be done at the same time.
dixon_’s picture

Status: Needs review » Reviewed & tested by the community

The code looks good, and all the review items are addressed. There's consensus about breaking out remaining bits into follow-up issues. So I created these issues:

claudiu.cristea’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/block_content/block_content.install
    @@ -61,3 +62,26 @@ function block_content_update_8003() {
    +function block_content_update_8004() {
    

    This cannot be 8004. According to hook_update_N() docs, should be 8300 as is the first for 8.3.x branch.

    Also, I think we should include the function in @addtogroup block, see system.install for an example.

  2. +++ b/core/modules/block_content/block_content.install
    @@ -61,3 +62,26 @@ function block_content_update_8003() {
    +  $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('block_content');
    ...
    +  \Drupal::entityDefinitionUpdateManager()->updateEntityType($entity_type);
    ...
    +  \Drupal::entityDefinitionUpdateManager()
    

    We call this service 3 times. Let's set it in variable $manager at the top and reuse it.

  3. +++ b/core/modules/block_content/block_content.install
    @@ -61,3 +62,26 @@ function block_content_update_8003() {
    +
    

    Extra new line.

  4. +++ b/core/modules/block_content/src/BlockContentAccessControlHandler.php
    @@ -19,7 +19,7 @@ class BlockContentAccessControlHandler extends EntityAccessControlHandler {
    -      return AccessResult::allowed();
    +      return AccessResult::allowedIf($entity->isPublished());
    

    Nice that is tested.

  5. +++ b/core/modules/block_content/src/Tests/Update/BlockContentUpdateTest.php
    @@ -0,0 +1,41 @@
    + */
    ...
    +    $this->assertIdentical(NULL, $field);
    

    $this->assertNull() ?

  6. +++ b/core/modules/block_content/src/Tests/Update/BlockContentUpdateTest.php
    @@ -0,0 +1,41 @@
    +   * @see block_content_update_8004()
    

    See ^^^

  7. +++ b/core/modules/block_content/tests/src/Functional/UnpublishedBlockTest.php
    @@ -0,0 +1,46 @@
    +class UnpublishedBlockTest extends BrowserTestBase {
    

    The test looks good by I wonder if we need a browser test (which is expensive) or we can just test this in a kernel test, by using only the renderer service. I'm not saying it works, just thinking...

timmillwood’s picture

Status: Needs work » Needs review
FileSize
9.22 KB
2.45 KB

Addressing all items in #53.

#53.7 - BrowserTestBase allows us to test BlockContentAccessControlHandler as it's called when rendering the page, so I think it gives the best coverage.

claudiu.cristea’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me if bot agrees.

claudiu.cristea’s picture

Assigned: timmillwood » Unassigned
Berdir’s picture

Status: Reviewed & tested by the community » Needs work

One thing that I just noticed, how does this interact with translation status? content_translation has some interesting dynamic logic around metadata fields like status, created/changed and so on. Basically, if it's not defined, then it defines custom content_translation fields automatically. So if you start to define it, then it affects those additional base fields.

Looking at \Drupal\content_translation\ContentTranslationHandler::getFieldDefinitions(), it actually looks at the status key, not the new published, despite actually calling it "hasPublishedStatus()" :)

That means multilingual sites end up with status and content_translation_status and that could lead to some fun problems/data duplication.

I think we should consider to add the status key as well and deal with that. That IMHO means writing an optional data migration/update function for the existing content_translation_status field if it exists. That said, is that a BC problem? I guess we also just found out that the status key *is* pre-exsting and *is* actually used for content entities, and adding a new published ey might not have been the best idea after all? :)

PS: Sorry.

PPS: This affects comment too. Sorry again. Edit: Not sure about comment actually, we didn't add the new status field, but it also didn't have the status key before. So on the plus side, likely not a regression of the EntityPublished trait issue, but likely broken/weird anyway.

timmillwood’s picture

I've been looking into the content_translation that @Berdir discovered and have some good news, and bad news.

Good news
It's not an issue for comments. This is because \Drupal\content_translation\ContentTranslationHandler::hasPublishedStatus doesn't look for the 'status' entity key, it just looks for a field called 'status'.

Bad news
This is an issue for block_content. The patch in #54 adds the 'published' entity key with a value 'status'. So block_content will get a field called 'status' and \Drupal\content_translation\ContentTranslationHandler::hasPublishedStatus will return TRUE. This means we will have a content_translation_status field on block_content that isn't used / needed anymore. What do we do?

Should we:

  • Set the value of 'status' to the value of 'content_translation_status' and remove the 'content_translation_status' field?
  • Set the value of 'status' to the value of 'content_translation_status' and leave the 'content_translation_status' field there?

Then, do we update \Drupal\content_translation\ContentTranslationHandler::hasPublishedStatus to use the 'published' entity key if it has one, or 'status' if it hasn't (just for BC reasons)?

Gábor Hojtsy’s picture

IMHO we should remove the now unneeded translation status field after data is moved over. Not sure how changing the logic in \Drupal\content_translation\ContentTranslationHandler::hasPublishedStatus change things for the future given that we are newly adding a publication status field here, so this problem would have shown up either way? It does not seem to be a related problem that that code does not check the entity key but hardcodes a name.

timmillwood’s picture

@Gabor - The logic in \Drupal\content_translation\ContentTranslationHandler::hasPublishedStatus only becomes an issue if the field is not called 'status' for example if the entity key was "published" = "published", then 'content_translation_status' would still get added, even though there was a published status field.

Gábor Hojtsy’s picture

Right, which is why its unrelated here IMHO.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
9.87 KB
2.52 KB

Using 'content_translation_status' as the initial from field if it exists, then dropping it once we're done.

Berdir’s picture

+++ b/core/modules/block_content/block_content.install
@@ -89,6 +89,13 @@ function block_content_update_8300() {
+  $db_schema = \Drupal::database()->schema();
+  if ($db_schema->fieldExists('block_content_field_data', 'content_translation_status')) {
+    $db_schema->dropField('block_content_field_data', 'content_translation_status');
+  }
+  if ($db_schema->fieldExists('block_content_field_revision', 'content_translation_status')) {
+    $db_schema->dropField('block_content_field_revision', 'content_translation_status');
+  }

Don't we need to do this with uninstallFieldStorageDefinition(), otherwise Drupal will think that they are still installed?

Berdir’s picture

Status: Needs review » Needs work

Applying this patch and running the updates without clearing the cache first results in this error:

Exception thrown while performing a schema update. SQLSTATE[22004]: Null value not allowed: 1138 Invalid use of NULL value: ALTER TABLE {block_content_field_data} CHANGE `status`[error]
`status` TINYINT NOT NULL; Array
(
)

That's because installing the field storage definition still uses the old cached entity entity type without the new storage schema class. We need to clear the cached entity type definitions first. We don't have this in the tests because our tests start with cold caches, which I think is wrong, we had this problem before.

Might not actually be true, see below.

After cache clear, I still get that error, but on the revision table now:

Do you wish to run all pending updates? (y/n): y
Exception thrown while performing a schema update. SQLSTATE[22004]: Null value not allowed: 1138 Invalid use of NULL value: ALTER TABLE {block_content_field_revision} CHANGE [error]
`status` `status` TINYINT NOT NULL; Array
(
)

I do have content_translation installed and enabled for block_content. It did run through on the second try. But that's just because it just failed on making the field not null. The reason why this happens is that content_translation_status is not "not null" and doesn't need initialization and also doesn't have it. So because I only enabled content translation after I already had blocks, I had NULL in there for an existing block. That was used as source for the new status field, and then it fails on that.

That''s a pretty annoying problem. I think we need to do a conditional update query to set it to 1 if it is NULL first if the content_translation_status field exists (this is probably a bug in content_translation, but we need to deal with that data now anyway unless we fix this first in a separate issue and block it on that)

Also, I do get this after it did run through:

$ drush entity-updates
The following updates are pending:

block_content entity type :
The Translation status field needs to be uninstalled.
The Publishing status field needs to be updated.

So as I assumed above, it thinks that the translation status is still there, we must use uninstallFieldStorageDefinition().

That said, the migration of the data seems to have worked as expected, I had a custom block with original language EN and an unpublished DE translation. The status there is now correct for that.

Another weird thing is that my pre-existing block that now has status NULL seems to be confused and doesn't even allow me to translate it, despite having a language set.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
10.62 KB
1.72 KB

This patch updates all NULL content_translation_status fields to 1, and uninstalls the field storage definition at the end.

claudiu.cristea’s picture

  1. +++ b/core/modules/block_content/block_content.install
    @@ -61,3 +62,59 @@ function block_content_update_8003() {
    +      ->where('content_translation_status', NULL)
    ...
    +      ->where('content_translation_status', NULL)
    

    We use isNull('content_translation_status') for such conditions.

  2. +++ b/core/modules/block_content/block_content.install
    @@ -61,3 +62,59 @@ function block_content_update_8003() {
    +  $entity_type->setHandlerClass('storage_schema', 'Drupal\block_content\BlockContentStorageSchema');
    

    Let's not hard-code the namespaced class name. Use BlockContentStorageSchema::class.

Status: Needs review » Needs work

The last submitted patch, 65: 2820848-65.patch, failed testing.

timmillwood’s picture

Fixing failing tests and items from #66

claudiu.cristea’s picture

Status: Needs work » Needs review
claudiu.cristea’s picture

Issue tags: +Needs manual testing

In #64, @Berdir has tested manually and found errors not reported by our update test. I would RTBC this again but we still need a confirmation from a manual test as long as this kind of errors are not poping-up in automated tests. Tagging with 'Needs manual testing'

Berdir’s picture

  1. +++ b/core/modules/block_content/block_content.install
    @@ -61,3 +64,61 @@ function block_content_update_8003() {
    +  if ($db_schema->fieldExists('block_content_field_data', 'content_translation_status')) {
    +    $db->update('block_content_field_data', 'bcfd')
    +      ->fields(['content_translation_status' => 1])
    +      ->isNull('content_translation_status')
    +      ->execute();
    +  }
    +  if ($db_schema->fieldExists('block_content_field_revision', 'content_translation_status')) {
    

    Can we add a comment to this?

    I also think that the 'bcfd' is not necessary and a bit confusing. We also afaik usually don't use $db but $database. On the other side, I'd be OK with just $schema.

  2. +++ b/core/modules/block_content/block_content.install
    @@ -61,3 +64,61 @@ function block_content_update_8003() {
    +  if ($db_schema->fieldExists('block_content_field_data', 'content_translation_status')) {
    +    $db_schema->dropField('block_content_field_data', 'content_translation_status');
    +  }
    +  if ($db_schema->fieldExists('block_content_field_revision', 'content_translation_status')) {
    +    $db_schema->dropField('block_content_field_revision', 'content_translation_status');
    +  }
    +}
    

    the uninstall above should take care of this.

Manually tested with the following steps:

1. new installation with EN
2. Created a custom block
3. Added DE and FR
4. Made custom blocks translatable.
5. Added a DE translation. Was forced to have it published, got this message: "Only this translation is published. You must publish at least one more translation to unpublish this one.". Except that's weird because the default translation is supposed to be published. This is what #2346019: Handle initial values when creating a new field storage definition should address by ensuring that the existing default translation is published when making something translatable and there is no existing status/published key. I think we should also have another follow-up to support the published entity key and not hardcode the "status" field in Content Translation. Of course that will be tricky if there is an existing entity type with published that is not status.
6. Added a FR translation, published. Still getting that message because I apparently need to have more than one existing published, I think this isn't working correctly for new translations at all :)
7. Created a second block, DE.
8. Created an EN translation. Now I can select unpublished, already on the first, because the original is published, this was cloned from it, so technically, with the new not yet saved translation, we *do* have two published translations. This is much fun ;) And I guess means that fixing the initial value will fix this bug too. So unpublished it is.
9. Created a FR translation, published.
10. Apply the patch, remove the explicit dropField() calls to ensure that I'm right there.
11. Run drush updb, BOOM. db_update() does not have an alias argument, So 1. above is not just unnecessary, it is clearly wrong.
12. Removed, executed again. next BOOM: Unable to delete a field (content_translation_status in block_content entity) with data that cannot be purged. That means we now actually need to explicitly set that column to NULL, so we can delete it.
13. Trying that, commenting out the installFieldStorageDefinition() call because that executed and would explode now.
14. Third time is a charm: drush updb did run through this time. Status is displayed correctly in the UI and is correct in the DB in both tables. content_translation_status field is gone in both tables.

You're going to .. not like me for that very much, but given all those pitfalls/bugs/complexities, I don't think we can get this in without actual test coverage for an existing site with custom block translations?

Berdir’s picture

Status: Needs review » Needs work
timmillwood’s picture

Status: Needs work » Needs review
Issue tags: -Needs manual testing
FileSize
12.28 KB
5.17 KB

Started looking at the items from #71 and how we can test this.

Still lots to do.

timmillwood’s picture

FileSize
13.13 KB
6.7 KB

Manually adding the content_translation_status field at the start of the test, then testing it is removed as part of the update.

This still doesn't test the full process from #71, this proved to be pretty complex to replicate, but I think this goes a good way towards testing the update path.

dawehner’s picture

This is just some quick review. IMHO its a bit confusing that block config entities aren't publish/unpublishable but the underlying custom content types are. That's a bit less obvious maybe for someone new who comes into the system.

  1. +++ b/core/modules/block_content/src/BlockContentStorageSchema.php
    @@ -0,0 +1,32 @@
    +
    +    if ($storage_definition->getName() == 'status') {
    +      if (\Drupal::database()->schema()->fieldExists('block_content_field_data', 'content_translation_status')) {
    +        $schema['fields']['status']['initial_from_field'] = 'content_translation_status';
    +      }
    +      else {
    +        // Set all block content as published.
    +        $schema['fields']['status']['initial'] = 1;
    +      }
    +    }
    +
    

    This IMHO needs some serious explanation of what is going on.

  2. +++ b/core/modules/block_content/src/Tests/Update/BlockContentUpdateTest.php
    @@ -0,0 +1,73 @@
    +    $this->databaseDumpFiles = [
    +      __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz',
    +    ];
    

    Isn't it funny how we still migrate starting from a 8.0-rc1 instance?

timmillwood’s picture

#75.1 - ah yes, I'll add some comments.
#75.2 - is it, but not something to fix in this issue.

timmillwood’s picture

FileSize
13.18 KB
1.55 KB

Updating comments in BlockContentStorageSchema

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

This looks rocksolid for me now. I wondered for a while whether removing the field is the right idea, but indeed that's totally fine due to

  if (!$this->hasPublishedStatus()) {
      $definitions['content_translation_status'] = BaseFieldDefinition::create('boolean')
        ->setLabel(t('Translation status'))
        ->setDescription(t('A boolean indicating whether the translation is visible to non-translators.'))
        ->setDefaultValue(TRUE)
        ->setRevisionable(TRUE)
        ->setTranslatable(TRUE);
    }

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 77: 2820848-77.patch, failed testing.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
13.23 KB
814 bytes

Allowing users with the "Administer blocks" permission to view unpublished block content. This kinda makes sense seeing as they need to administer them. It also fixes the failing test in #77 from \Drupal\content_moderation\Tests\ModerationStateBlockTest::testCustomBlockModeration which assumes a "root user" can view unpublished blocks.

Manuel Garcia’s picture

Status: Needs review » Reviewed & tested by the community

#80 makes sense, back to RTBC

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 80: 2820848-80.patch, failed testing.

timmillwood’s picture

Status: Needs work » Reviewed & tested by the community

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 80: 2820848-80.patch, failed testing.

timmillwood’s picture

Status: Needs work » Reviewed & tested by the community

Unrelated fail.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

amateescu’s picture

Status: Reviewed & tested by the community » Needs review

The update function makes a few risky assumptions: that the block_content entity is translatable, stored in SQL and that it is using the default table names.

I'd like to take a closer look at the content_translation_status situation before this gets in..

amateescu’s picture

Title: Add a publishing status field to BlockContent » [PP-3] Add a publishing status field to BlockContent
Status: Needs review » Postponed

Ok, I posted #2854732: Use initial values for content translation metadata fields and fix existing data for handling the 'content_translation_status' problem generically, so I'm afraid this will need to be postponed on that one and its chain of dependencies :(

amateescu’s picture

amateescu’s picture

Title: [PP-6] Make BlockContent entities publishable » [PP-5] Make BlockContent entities publishable

Counted an issue twice :/

amateescu’s picture

Status: Postponed » Needs review
FileSize
442.26 KB

All the dependencies have patches that are passing tests, so let's try a combined patch here as well.

This is #89 + the combined patch from #2854732-9: Use initial values for content translation metadata fields and fix existing data and #2825973-31: Introduce a EditorialContentEntityBase class for revisionable and publishable entity types.

Status: Needs review » Needs work

The last submitted patch, 91: 2820848-91-combined.patch, failed testing.

amateescu’s picture

Title: [PP-5] Make BlockContent entities publishable » [PP-6] Make BlockContent entities publishable
Status: Needs work » Needs review
FileSize
12.74 KB
1.04 KB

One of the problems is #2858109: The BlockContent entity type does not specify its revision data table, another one is fixed in the patch attached (there's no reason to update a field that we just installed) and there's one more bug that will probably need to be fixed in #2346019: Handle initial values when creating a new field storage definition, still investigating that one.

Pavan B S’s picture

+++ b/core/modules/block_content/src/Tests/Update/BlockContentUpdateTest.php
@@ -0,0 +1,73 @@
+ * Tests that block content settings are properly updated during database updates.

Line contain more than 80 characters

There is one minor of "line containing more than 80 characters" please review.

timmillwood’s picture

Status: Needs review » Needs work
+++ b/core/modules/block_content/src/Tests/Update/BlockContentUpdateTest.php
@@ -7,8 +7,9 @@
+ * ¶

Extra white space on this line.

Pavan B S’s picture

Status: Needs work » Needs review
FileSize
12.74 KB
511 bytes

Applying patch for comment #95, please review

timmillwood’s picture

Status: Needs review » Needs work
+++ b/core/modules/block_content/src/Tests/Update/BlockContentUpdateTest.php
@@ -0,0 +1,73 @@
+ * Tests that block content settings are properly updated during database
+ * updates.
+ * @group block_content

We still need the new line between the description and @group. Just no extra spaces.

jofitz’s picture

Status: Needs work » Needs review
FileSize
543 bytes
12.74 KB

Added new line between the description and @group.

The last submitted patch, 94: 2820848-95.patch, failed testing.

The last submitted patch, 96: 2820848-97.patch, failed testing.

amateescu’s picture

There is a reason why I didn't set the patch from #93 to be tested, and that's because it won't work without all the issues listed in #89.

Can we please stop making cosmetic changes like this to a patch when they really are not necessary? A one-line review would have been more than welcome..

Status: Needs review » Needs work

The last submitted patch, 98: 2820848-98.patch, failed testing.

amateescu’s picture

Status: Needs work » Needs review
FileSize
11.89 KB
446.15 KB
8.77 KB

Let's see how far this gets us. It includes the latest patch from #2346019-43: Handle initial values when creating a new field storage definition and also fixes the tests that were added here previously, some of which didn't make sense at all.

The last submitted patch, 103: 2820848-103.patch, failed testing.

amateescu’s picture

Title: [PP-6] Make BlockContent entities publishable » [PP-5] Make BlockContent entities publishable
FileSize
11.81 KB
432.88 KB

One of the dependencies was committed: #2858109: The BlockContent entity type does not specify its revision data table. We're... "getting there" :)

Status: Needs review » Needs work

The last submitted patch, 105: 2820848-105-combined.patch, failed testing.

jibran’s picture

Title: [PP-5] Make BlockContent entities publishable » [PP-4] Make BlockContent entities publishable
amateescu’s picture

Title: [PP-4] Make BlockContent entities publishable » [PP-3] Make BlockContent entities publishable
amateescu’s picture

Title: [PP-3] Make BlockContent entities publishable » [PP-2] Make BlockContent entities publishable
Status: Needs work » Needs review
FileSize
40.33 KB
amateescu’s picture

Title: [PP-2] Make BlockContent entities publishable » [PP-1] Make BlockContent entities publishable
FileSize
11.81 KB
21.07 KB

There's only one dependency left.

amateescu’s picture

Title: [PP-1] Make BlockContent entities publishable » Make BlockContent entities publishable
FileSize
11.81 KB

#2854732: Use initial values for content translation metadata fields and fix existing data is in now, so this is finally unblocked!

@Berdir, note that the issue mentioned above is the one that fixed the problem(s) you outlined in the manual testing from #64 / #71! You're more than welcome to take a look at the test coverage added in there and see if it addresses all your concerns :)

timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

I think this is good to go.

It doesn't yet add any UI for publishing / unpublishing blocks. I guess this needs to fall in line with the new checkbox on NodeForm. However it does work nicely with Content Moderation.

amateescu’s picture

Assigned: Unassigned » tim.plunkett
Status: Reviewed & tested by the community » Needs review
Issue tags: +Needs subsystem maintainer review
FileSize
12.04 KB
4.62 KB

Whoa, hold on there :) I didn't get to review the entire patch myself yet until now, so here's some fixes for what I could find.

Also, the most important part is that I think we need a review from a block system maintainer. We need to be sure that the new concept of a custom block being un/publishable in the API works well together with the rest of the block system - block plugins, disabled regions or whatever mechanism exist these days for disabling a block on a page. Trying @tim.plunkett first :)

Status: Needs review » Needs work

The last submitted patch, 113: 2820848-113.patch, failed testing. View results

jibran’s picture

FWIW in #4 @larowlan already +1 the idea. He is a maintainer for block content.

We need to be sure that the new concept of a custom block being un/publishable in the API works well together with the rest of the block system - block plugins, disabled regions or whatever mechanism exist these days for disabling a block on a page.

I think this is worth exploring.

Manuel Garcia’s picture

re #112 the UI side of this will be done over at #2834546: UI for publishing/unpublishing block_content blocks - I got started on that a while back, but postponed until we get this =)

Wim Leers’s picture

Issue tags: +D8 cacheability
+++ b/core/modules/block_content/src/BlockContentAccessControlHandler.php
@@ -19,7 +19,7 @@ class BlockContentAccessControlHandler extends EntityAccessControlHandler {
-      return AccessResult::allowed();
+      return AccessResult::allowedIf($entity->isPublished() || $account->hasPermission('administer blocks'));

This is missing cacheability metadata.

I suggest:

return AccessResult::allowedIfHasPermission($account, 'administer blocks')
  ->orIf(AccessResult::allowedIf($entity->isPublished())->addCacheableDependency($entity));

EDIT: or this, which puts the more likely thing first, hence slightly faster for the common case:

return AccessResult::allowedIf($entity->isPublished())->addCacheableDependency($entity)
  ->orIf(AccessResult::allowedIfHasPermission($account, 'administer blocks'));
amateescu’s picture

Status: Needs work » Needs review
FileSize
12.2 KB
1.71 KB

@Wim Leers, I was also looking at that access handler and wondered about cacheability metadata but then I got distracted and went on to fix something else. Glad you were vigilant though :)

@jibran, it's great that @larowlan +1`ed the idea initially, but we still need a careful review for the API-facing parts of this patch.

amateescu’s picture

+++ b/core/modules/block_content/src/BlockContentAccessControlHandler.php
@@ -19,7 +19,8 @@ class BlockContentAccessControlHandler extends EntityAccessControlHandler {
-      return AccessResult::allowed();
+      return AccessResult::allowedIf($entity->isPublished())->addCacheableDependency($entity)
+        ->orIf(AccessResult::allowedIfHasPermission($account, 'administer blocks'));

However, looking at the diff again, where did the new 'administer blocks' permission requirement come from? And why wasn't it needed before this patch?

Status: Needs review » Needs work

The last submitted patch, 118: 2820848-118.patch, failed testing. View results

Wim Leers’s picture

Oh, that I have no idea about. I was just reviewing #113 :)

tim.plunkett’s picture

core/modules/block_content/src/Entity/BlockContent.php line 34 has * admin_permission = "administer blocks",

\Drupal\Core\Entity\EntityAccessControlHandler::checkAccess() has this line:
return AccessResult::allowedIfHasPermission($account, $this->entityType->getAdminPermission());

+++ b/core/modules/block_content/src/BlockContentAccessControlHandler.php
@@ -19,7 +19,8 @@ class BlockContentAccessControlHandler extends EntityAccessControlHandler {
     if ($operation === 'view') {
-      return AccessResult::allowed();
...
     return parent::checkAccess($entity, $operation, $account);

In HEAD, this skipped the permission check for $operation == 'view', which was correct (anyone could view a content block)
Now this is allowing those with admin perms to bypass the publish check. Which is good.

This whole thing could be rewritten to:

$access = parent::checkAccess($entity, $operation, $account);
if ($operation === 'view') {
  $access->orIf(AccessResult::allowedIf($entity->isPublished())->addCacheableDependency($entity));
}
return $access;
Berdir’s picture

This was added in #80.

However, I'm wondering if we really want that? That means if I unpublish a block_content entity then I will not be able to see a difference to me as an admin, it will still be displayed.

Yes, we do the same with nodes, but only if you specifically view them, the default /node view excludes unpublished content. And I'm sure practially all public lists of content are configured like that. And /node/ID has a background to indicate that it is unpublished (yeah, it is ugly but that's another story).

andypost’s picture

Berdir’s picture

No, I'm saying don't add anything. At least not here. Unpublished fields still show up in the block content overview and can be seen and edited by anyone with administer blocks just fine, which is IMHO enough for this issue.

Manuel Garcia’s picture

Re permissions, there's this ongoing effort fyi: #2809177: Introduce entity permission providers

timmillwood’s picture

We could add a class similar to .node--unpublished for unpublished block and / or change permissions, but I wonder if we should focus on this in a follow up because I fear it'll spark a lot of bike shedding.

I am more concerned about the test fails in #118, these seem to be related to #2854732: Use initial values for content translation metadata fields and fix existing data, but not related to block_content, so a little confused.

timmillwood’s picture

After doing it a little digging into the failing test it seems with this patch applied $content_translation_manager->getSupportedEntityTypes() does return entity_test_update entity type in content_translation_update_8400.

Not really sure why, so moving on to another issue for now.

amateescu’s picture

Status: Needs work » Needs review
FileSize
12.97 KB
796 bytes

@timmillwood, on the contrary, with this patch applied $content_translation_manager->getSupportedEntityTypes() does not return entity_test_update entity type in content_translation_update_8400(), even though it is very much supposed to do so.

The problem stems from the new block_content_update_dependencies() function, which seems to make the entity manager use some stale definitions. I tried a lot to debug what is going on but the call stacks are way too high to be understandable. It can be easily fixed by clearing the entity type definitions cache though :)

timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

Sorry, if I caused any inconvenience, I meant "does not".

Patch in #129 looks good, as long as it gets into 8.4. Otherwise we won't be able to update content_translation_update_8400().

RTBC as long as tests pass.

tim.plunkett’s picture

Assigned: tim.plunkett » Unassigned

👍

Berdir’s picture

+++ 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'));
     }

We still have this part now, as commented, my recommendation would be to remove that.

There are various options, like visually marking unpublished blocks for admins, but for now, we don't offer a UI for this anyway, so it seems like the safest option is to just not change it here?

amateescu’s picture

That's what I thought as well, we don't need this until we figure out the UI bits.

timmillwood’s picture

Just to clarify, no matter the permissions, no one will see unpublished blocks. The only way to unpublish a block (for now) will be via Content Moderation.

This seems fine for now.

+1 to still being RTBC.

Wim Leers’s picture

Berdir++ for simplifying access control handler/keeping scope tight.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 133: 2820848-133.patch, failed testing. View results

Berdir’s picture

So \Drupal\Tests\content_moderation\Functional\ModerationStateBlockTest::testCustomBlockModeration() is on purpose creating a draft/unpublished block_content entity and then expects that the user can see it.

Which why @timmillwood added the permission check there.

So 1 million dollar question is... is that really what you expect to happen or not? :)

tim.plunkett’s picture

In #122 I agreed that the permission check is good. I think the test is correct.

Berdir’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
12.97 KB

Discussed a bit with @timplunkett a bit about that. Lets keep the check to keep the test passing for now, and then we can figure out something that makes sense in #2834546: UI for publishing/unpublishing block_content blocks. For now, creating a new draft custom block and then immediately doing a block placement of that seems like a very edge-cache situation either way.

Also when you add workspaces to the mix and you are looking at a future draft revision of a block...

Back to RTBC for the patch in #129, just re-uploading to make it clear for testbot.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 139: 2820848-129.patch, failed testing. View results

amateescu’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs subsystem maintainer review

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

timmillwood’s picture

Version: 8.5.x-dev » 8.4.x-dev

As this is already RTBC it should be fine for 8.4.x

xjm’s picture

Version: 8.4.x-dev » 8.5.x-dev

Similarly to #2880154-26: Convert comments to be revisionable, we'll evaluate it for backport after commit. This is another strategic priority for workflow so assuming we don't identify any risks during review, I'd definitely consider this for backport if it lands in time for the beta freeze deadline.

timmillwood’s picture

Cross post from #2880154-28: Convert comments to be revisionable

Making BlockContent entities will really help Content Moderation, because it will be possible to archive a block and it will not be visible to users. Currently when BlockContent Entity is archived it is still visible on the site.

timmillwood’s picture

I've just been doing a quick risk assessment on this issue, and it seems good:

  • There is no UI for this yet, so publishing / unpublishing can only be done by Content Moderation (or contrib).
  • The default state is published, so no change in use experience.
  • When using Content Moderation, setting a BlockContent entity to "Archived" will unpublish it, although it is still visable for anyone who has the "Administer blocks" permission. Then those who have the "use
    " permissions from Content Moderation will see the Moderation Form within the block which denotes the current state and allows the state to be changed.

Still +1 from me for 8.4.0.

larowlan’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/block_content/src/BlockContentAccessControlHandler.php
@@ -19,7 +19,8 @@ class BlockContentAccessControlHandler extends EntityAccessControlHandler {
+      return AccessResult::allowedIf($entity->isPublished())->addCacheableDependency($entity)
+        ->orIf(AccessResult::allowedIfHasPermission($account, 'administer blocks'));

I think we're missing explicit coverage for the admin portion of this

Other than that, agree - this is low risk.

Note: needs reroll, no longer applies

Berdir’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
12.8 KB
3.63 KB

This conflicted with #2896845: Provide the 'revision_translation_affected' base field by default for all revisionable and translatable entity types, which removed more stuff in BlockContent.

Attached a manual diff of the two patches to make it clear that we only have some context patches, the patch is otherwise identical. Therefore back to RTBC.

Also, discussed with @larowlan that we do have explicit test coverage, see #133 which failed without that snippet and the comments after that explain what the test is doing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 148: 2820848-148.patch, failed testing. View results

timmillwood’s picture

Status: Needs work » Reviewed & tested by the community
larowlan’s picture

One minor question:

  1. +  // 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);

    Any reason we don't reuse \Drupal\Core\Entity\EntityPublishedTrait::publishedBaseFieldDefinitions to provide this definition?

amateescu’s picture

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 148: 2820848-148.patch, failed testing. View results

amateescu’s picture

Status: Needs work » Reviewed & tested by the community

That was a random fail.

@larowlan, we can not use "live" field definitions in update functions because those definitions can change over time, so we need to provide a field definition that remains the same at any given point in time in order to have a predictable update function.

larowlan’s picture

ah of course - thanks!

vijaycs85’s picture

+1 to RTBC. Shame, didn't make to to 8.4.x as it's been RTBC for a month (since #141)

Anonymous’s picture

+++ 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);
   }

This will also be useful for #2835845: EntityResource: Provide comprehensive test coverage for BlockContent entity. Because we can use this super soft access restriction (#146) like workaround for the requirements of the rest-tests.

timmillwood’s picture

Issue summary: View changes
amateescu’s picture

larowlan’s picture

Status: Reviewed & tested by the community » Needs review

Can we get a change record here - thanks

amateescu’s picture

Not really sure what to write in the CR, but here it is: https://www.drupal.org/node/2908665 :)

Wim Leers’s picture

Status: Needs review » Reviewed & tested by the community

👍

larowlan’s picture

Updating issue credits- adding @claudiu.cristea for reviews

  • larowlan committed 9271178 on 8.5.x
    Issue #2820848 by timmillwood, amateescu, Pavan B S, Berdir, Jo...
larowlan’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +8.5.0 release notes

Committed as 9271178 and pushed to 8.5.x

Published change record.

Unpostponed follow-up.

hass’s picture

Is this getting backported to 8.4 or do we need to wait another year for a usable Drupal 8?

jibran’s picture

No, this is not going to be backported and 8.5.0 will be out in 6 months not in a year. You can use 8.5.x-dev if you want to use this feature now. :)

I am very grateful to for everyone who worked on this issue and all the blockers. This took a long time and a lot of hardwork so thank you all.

kattekrab’s picture

Yes indeed!

Well said @jibran

Deep thanks too all who contributed their time, their effort - whether writing, reviewing, or testing and committing.

It really is testament to Drupal that something like this can be so truly collaborative!

Thankyou @timmillwood, @amateescu, @Pavan B S, @Berdir, @Jo Fitzgerald, @claudiu.cristea and @larowlan

hass’s picture

@jibran: I do not expect 8.5 is released without bugs or is stable. Is this an experimental (no upgrade path) or a currently stable feature in 8.5-dev with a supported upgrade path?

jibran’s picture

Block content is a stable module and there is an upgrade path with tests so yes this is stable and fully supported.

For the differences between 8.5 and 8.4 please read https://www.drupal.org/core/d8-allowed-changes#minor and https://www.drupal.org/core/d8-allowed-changes#patch.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

xjm’s picture

I don't think there's anything here that is must-have feature information, so changing to the highlights tag.