Skip to content
Snippets Groups Projects
Verified Commit 8672c435 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3053881 by Luke.Leber, bkosborne, tyler-paavola, Sam152, Rishi...

Issue #3053881 by Luke.Leber, bkosborne, tyler-paavola, Sam152, Rishi Kulshreshtha, Odai Atieh, chrisolof, acbramley, ethomas08, Oscaner, kyberman, aarti zikre, joshua1234511, larowlan, catch: Reverting entity revisions that contain custom blocks erroneously triggers EntityChangedConstraint

(cherry picked from commit 7362bc50)
parent 24dc4ef8
Branches
Tags
24 merge requests!8506Draft: Issue #3456536 by ibrahim tameme,!5646Issue #3350972 by nod_: [random test failure]...,!5600Issue #3350972 by nod_: [random test failure]...,!5343Issue #3305066 by quietone, Rename RedirectLeadingSlashesSubscriber,!4350Issue #3307718: Implement xxHash for non-cryptographic use-cases,!3603#ISSUE 3346218 Add a different message on edit comment,!3555Issue #2473873: Views entity operations lack cacheability support, resulting in incorrect dropbuttons,!3494Issue #3327018 by Spokje, longwave, xjm, mondrake: Update PHPStan to 1.9.3 and...,!3410Issue #3340128: UserLoginForm::submitForm has some dead code,!3389Issue #3325184 by Spokje, andypost, xjm, smustgrave: $this->configFactory is...,!3381Issue #3332363: Refactor Claro's menus-and-lists stylesheet,!3307Issue #3326193: CKEditor 5 can grow past the viewport when there is a lot of content,!3236Issue #3332419: Refactor Claro's messages stylesheet,!3231Draft: Issue #3049525 by longwave, fougere, larowlan, kim.pepper, AaronBauman, Wim...,!3212Issue #3294003: Refactor Claro's entity-meta stylesheet,!3194Issue #3330981: Fix PHPStan L1 error "Relying on entity queries to check access by default is deprecated...",!3143Issue #3313342: [PHP 8.1] Deprecated function: strpos(): Passing null to parameter #1 LayoutBuilderUiCacheContext.php on line 28,!3024Issue #3307509: Empty option for views bulk form,!2972Issue #1845004: Replace custom password hashing library with PHP 5.5 password_hash(),!2719Issue #3110137: Remove Classy from core.,!2688Issue #3261452: [PP-1] Remove tracker module from core,!2437Issue #3238257 by hooroomoo, Wim Leers: Fragment link pointing to <textarea>...,!2296Issue #3100732: Allow specifying `meta` data on JSON:API objects,!1626Issue #3256642: Make life better for database drivers that extend another database driver
......@@ -66,6 +66,13 @@ function block_content_entity_type_alter(array &$entity_types) {
$translation['block_content'] = TRUE;
$entity_types['block_content']->set('translation', $translation);
}
// Swap out the default EntityChanged constraint with a custom one with
// different logic for inline blocks.
$constraints = $entity_types['block_content']->getConstraints();
unset($constraints['EntityChanged']);
$constraints['BlockContentEntityChanged'] = NULL;
$entity_types['block_content']->setConstraints($constraints);
}
/**
......
......@@ -13,3 +13,10 @@ function block_content_removed_post_updates() {
'block_content_post_update_add_views_reusable_filter' => '9.0.0',
];
}
/**
* Clear the entity type cache.
*/
function block_content_post_update_entity_changed_constraint() {
// Empty post_update hook.
}
<?php
namespace Drupal\block_content\Plugin\Validation\Constraint;
use Drupal\Core\Entity\Plugin\Validation\Constraint\EntityChangedConstraint;
/**
* Validation constraint for the block content entity changed timestamp.
*
* @Constraint(
* id = "BlockContentEntityChanged",
* label = @Translation("Block content entity changed", context = "Validation"),
* type = {"entity"}
* )
*/
class BlockContentEntityChangedConstraint extends EntityChangedConstraint {
}
<?php
namespace Drupal\block_content\Plugin\Validation\Constraint;
use Drupal\block_content\BlockContentInterface;
use Drupal\Core\Entity\Plugin\Validation\Constraint\EntityChangedConstraintValidator;
use Symfony\Component\Validator\Constraint;
/**
* Validates the BlockContentEntityChanged constraint.
*/
class BlockContentEntityChangedConstraintValidator extends EntityChangedConstraintValidator {
/**
* {@inheritdoc}
*/
public function validate($entity, Constraint $constraint) {
// This prevents saving an update to the block via a host entity's form if
// the host entity has had other changes made via the API instead of the
// entity form, such as a revision revert. This is safe, for example, in the
// Layout Builder the inline blocks are not saved until the whole layout is
// saved, in which case Layout Builder forces a new revision for the block.
// @see \Drupal\layout_builder\InlineBlockEntityOperations::handlePreSave.
if ($entity instanceof BlockContentInterface && !$entity->isReusable()) {
return;
}
parent::validate($entity, $constraint);
}
}
......@@ -669,4 +669,43 @@ public function testEditInlineBlocksPermission() {
$assert($permissions, TRUE);
}
/**
* Test editing inline blocks when the parent has been reverted.
*/
public function testInlineBlockParentRevert() {
$this->drupalLogin($this->drupalCreateUser([
'access contextual links',
'configure any layout',
'administer node display',
'administer node fields',
'administer nodes',
'bypass node access',
'create and edit custom blocks',
]));
$display = \Drupal::service('entity_display.repository')->getViewDisplay('node', 'bundle_with_section_field');
$display->enableLayoutBuilder()->setOverridable()->save();
$test_node = $this->createNode([
'title' => 'test node',
'type' => 'bundle_with_section_field',
]);
$this->drupalGet("node/{$test_node->id()}/layout");
$this->addInlineBlockToLayout('Example block', 'original content');
$this->assertSaveLayout();
$original_content_revision_id = Node::load($test_node->id())->getLoadedRevisionId();
$this->drupalGet("node/{$test_node->id()}/layout");
$this->configureInlineBlock('original content', 'updated content');
$this->assertSaveLayout();
$this->drupalGet("node/{$test_node->id()}/revisions/$original_content_revision_id/revert");
$this->submitForm([], 'Revert');
$this->drupalGet("node/{$test_node->id()}/layout");
$this->configureInlineBlock('original content', 'second updated content');
$this->assertSaveLayout();
$this->drupalGet($test_node->toUrl());
$this->assertSession()->pageTextContains('second updated content');
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment