From 4b5138e6c32060f9568e9758769c186cd0771e14 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Mon, 15 Jan 2024 15:35:13 +1000 Subject: [PATCH] Issue #3397493 by borisson_, phenaproxima, Wim Leers: Add validation constraints to block_content.type.* --- .../block_content.post_update.php | 12 +++++++++ .../config/schema/block_content.schema.yml | 10 +++++-- .../src/BlockContentTypeForm.php | 12 +++++++++ .../src/Entity/BlockContentType.php | 8 +++--- .../Rest/BlockContentTypeResourceTestBase.php | 2 +- .../Update/BlockContentUpdateTest.php | 27 +++++++++++++++++++ .../Kernel/BlockContentTypeValidationTest.php | 5 ++++ .../src/Functional/BlockContentTypeTest.php | 2 +- .../block_content.type.banner_block.yml | 2 +- .../install/block_content.type.basic.yml | 2 +- .../block_content.type.disclaimer_block.yml | 2 +- .../block_content.type.footer_promo_block.yml | 2 +- .../install/block_content.type.basic.yml | 2 +- 13 files changed, 75 insertions(+), 13 deletions(-) diff --git a/core/modules/block_content/block_content.post_update.php b/core/modules/block_content/block_content.post_update.php index 994da07c9a0b..3955a7033bd5 100644 --- a/core/modules/block_content/block_content.post_update.php +++ b/core/modules/block_content/block_content.post_update.php @@ -5,6 +5,7 @@ * Post update functions for Content Block. */ +use Drupal\block_content\BlockContentTypeInterface; use Drupal\Core\Config\Entity\ConfigEntityUpdater; use Drupal\user\Entity\Role; use Drupal\views\Entity\View; @@ -80,3 +81,14 @@ function block_content_post_update_sort_permissions(&$sandbox = NULL) { return FALSE; }); } + +/** + * Update configuration for revision type. + */ +function block_content_post_update_revision_type(&$sandbox = NULL) { + \Drupal::classResolver(ConfigEntityUpdater::class) + ->update($sandbox, 'block_content_type', function (BlockContentTypeInterface $block_content_type) { + $block_content_type->set('revision', (bool) $block_content_type->get('revision')); + return TRUE; + }); +} diff --git a/core/modules/block_content/config/schema/block_content.schema.yml b/core/modules/block_content/config/schema/block_content.schema.yml index b8508e5c3769..0e683d8a1d60 100644 --- a/core/modules/block_content/config/schema/block_content.schema.yml +++ b/core/modules/block_content/config/schema/block_content.schema.yml @@ -11,8 +11,14 @@ block_content.type.*: type: required_label label: 'Label' revision: - type: integer - label: 'Create new revision' + type: boolean + label: 'Whether a new revision should be created by default' description: type: text label: 'Description' + nullable: true + constraints: + NotBlank: + allowNull: true + constraints: + FullyValidatable: ~ diff --git a/core/modules/block_content/src/BlockContentTypeForm.php b/core/modules/block_content/src/BlockContentTypeForm.php index 6044917f16b3..7d82eeec6794 100644 --- a/core/modules/block_content/src/BlockContentTypeForm.php +++ b/core/modules/block_content/src/BlockContentTypeForm.php @@ -3,6 +3,7 @@ namespace Drupal\block_content; use Drupal\Core\Entity\BundleEntityFormBase; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\language\Entity\ContentLanguageSettings; @@ -91,6 +92,17 @@ class BlockContentTypeForm extends BundleEntityFormBase { return $this->protectBundleIdElement($form); } + /** + * {@inheritdoc} + */ + protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { + // An empty description violates config schema. + if (trim($form_state->getValue('description', '')) === '') { + $form_state->unsetValue('description'); + } + parent::copyFormValuesToEntity($entity, $form, $form_state); + } + /** * {@inheritdoc} */ diff --git a/core/modules/block_content/src/Entity/BlockContentType.php b/core/modules/block_content/src/Entity/BlockContentType.php index cfbd58cb6bb3..c2f22e7fbb54 100644 --- a/core/modules/block_content/src/Entity/BlockContentType.php +++ b/core/modules/block_content/src/Entity/BlockContentType.php @@ -74,20 +74,20 @@ class BlockContentType extends ConfigEntityBundleBase implements BlockContentTyp * * @var bool */ - protected $revision; + protected $revision = FALSE; /** * The description of the block type. * - * @var string + * @var string|null */ - protected $description; + protected $description = NULL; /** * {@inheritdoc} */ public function getDescription() { - return $this->description; + return $this->description ?? ''; } /** diff --git a/core/modules/block_content/tests/src/Functional/Rest/BlockContentTypeResourceTestBase.php b/core/modules/block_content/tests/src/Functional/Rest/BlockContentTypeResourceTestBase.php index 01d79c71bee2..1122282c9339 100644 --- a/core/modules/block_content/tests/src/Functional/Rest/BlockContentTypeResourceTestBase.php +++ b/core/modules/block_content/tests/src/Functional/Rest/BlockContentTypeResourceTestBase.php @@ -55,7 +55,7 @@ abstract class BlockContentTypeResourceTestBase extends ConfigEntityResourceTest 'id' => 'pascal', 'label' => 'Pascal', 'langcode' => 'en', - 'revision' => 0, + 'revision' => FALSE, 'status' => TRUE, 'uuid' => $this->entity->uuid(), ]; diff --git a/core/modules/block_content/tests/src/Functional/Update/BlockContentUpdateTest.php b/core/modules/block_content/tests/src/Functional/Update/BlockContentUpdateTest.php index 0819e9709809..438df9675677 100644 --- a/core/modules/block_content/tests/src/Functional/Update/BlockContentUpdateTest.php +++ b/core/modules/block_content/tests/src/Functional/Update/BlockContentUpdateTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\block_content\Functional\Update; +use Drupal\block_content\Entity\BlockContentType; use Drupal\FunctionalTests\Update\UpdatePathTestBase; use Drupal\user\Entity\User; use Drupal\views\Entity\View; @@ -22,6 +23,32 @@ class BlockContentUpdateTest extends UpdatePathTestBase { ]; } + /** + * Tests converting block types' `revision` flag to boolean. + */ + public function testConvertBlockContentTypeRevisionFlagToBoolean(): void { + $no_new_revisions = BlockContentType::create([ + 'id' => 'no_new_revisions', + 'label' => 'Does not create new revisions', + 'revision' => 0, + ]); + $no_new_revisions->trustData()->save(); + $new_revisions = BlockContentType::create([ + 'id' => 'new_revisions', + 'label' => 'Creates new revisions', + 'revision' => 1, + ]); + $new_revisions->trustData()->save(); + // Ensure that an integer was stored, so we can be sure that the update + // path converts it to a boolean. + $this->assertSame(0, $no_new_revisions->get('revision')); + $this->assertSame(1, $new_revisions->get('revision')); + + $this->runUpdates(); + $this->assertFalse(BlockContentType::load('no_new_revisions')->get('revision')); + $this->assertTrue(BlockContentType::load('new_revisions')->get('revision')); + } + /** * Tests moving the content block library to Content. * diff --git a/core/modules/block_content/tests/src/Kernel/BlockContentTypeValidationTest.php b/core/modules/block_content/tests/src/Kernel/BlockContentTypeValidationTest.php index dd3683fd20c4..5234e499a460 100644 --- a/core/modules/block_content/tests/src/Kernel/BlockContentTypeValidationTest.php +++ b/core/modules/block_content/tests/src/Kernel/BlockContentTypeValidationTest.php @@ -17,6 +17,11 @@ class BlockContentTypeValidationTest extends ConfigEntityValidationTestBase { */ protected static $modules = ['block_content']; + /** + * {@inheritdoc} + */ + protected static array $propertiesWithOptionalValues = ['description']; + /** * {@inheritdoc} */ diff --git a/core/modules/jsonapi/tests/src/Functional/BlockContentTypeTest.php b/core/modules/jsonapi/tests/src/Functional/BlockContentTypeTest.php index 1ecdc78a371c..5aba0234f5c1 100644 --- a/core/modules/jsonapi/tests/src/Functional/BlockContentTypeTest.php +++ b/core/modules/jsonapi/tests/src/Functional/BlockContentTypeTest.php @@ -91,7 +91,7 @@ class BlockContentTypeTest extends ConfigEntityResourceTestBase { 'description' => 'Provides a competitive alternative to the "basic" type', 'label' => 'Pascal', 'langcode' => 'en', - 'revision' => 0, + 'revision' => FALSE, 'status' => TRUE, 'drupal_internal__id' => 'pascal', ], diff --git a/core/profiles/demo_umami/config/install/block_content.type.banner_block.yml b/core/profiles/demo_umami/config/install/block_content.type.banner_block.yml index e48b05bdad35..90b3f0a2f6fd 100644 --- a/core/profiles/demo_umami/config/install/block_content.type.banner_block.yml +++ b/core/profiles/demo_umami/config/install/block_content.type.banner_block.yml @@ -3,5 +3,5 @@ status: true dependencies: { } id: banner_block label: 'Banner block' -revision: 0 +revision: false description: 'A banner block contains a title, summary, link to content and a background image. The background image is scaled to fill the browser''s width.' diff --git a/core/profiles/demo_umami/config/install/block_content.type.basic.yml b/core/profiles/demo_umami/config/install/block_content.type.basic.yml index f01ced96bc23..52ee48424101 100644 --- a/core/profiles/demo_umami/config/install/block_content.type.basic.yml +++ b/core/profiles/demo_umami/config/install/block_content.type.basic.yml @@ -3,5 +3,5 @@ status: true dependencies: { } id: basic label: 'Basic block' -revision: 0 +revision: false description: 'A basic block contains a title and a body.' diff --git a/core/profiles/demo_umami/config/install/block_content.type.disclaimer_block.yml b/core/profiles/demo_umami/config/install/block_content.type.disclaimer_block.yml index d4e08a36e433..65e99ed776bc 100644 --- a/core/profiles/demo_umami/config/install/block_content.type.disclaimer_block.yml +++ b/core/profiles/demo_umami/config/install/block_content.type.disclaimer_block.yml @@ -3,5 +3,5 @@ status: true dependencies: { } id: disclaimer_block label: 'Disclaimer block' -revision: 0 +revision: false description: 'A disclaimer block contains disclaimer and copyright text.' diff --git a/core/profiles/demo_umami/config/install/block_content.type.footer_promo_block.yml b/core/profiles/demo_umami/config/install/block_content.type.footer_promo_block.yml index 3c4df9748062..0e7c60204b7d 100644 --- a/core/profiles/demo_umami/config/install/block_content.type.footer_promo_block.yml +++ b/core/profiles/demo_umami/config/install/block_content.type.footer_promo_block.yml @@ -3,5 +3,5 @@ status: true dependencies: { } id: footer_promo_block label: 'Footer promo block' -revision: 0 +revision: false description: 'A footer promo block contains a title, promo text, and a "find out more" link.' diff --git a/core/profiles/standard/config/install/block_content.type.basic.yml b/core/profiles/standard/config/install/block_content.type.basic.yml index f01ced96bc23..52ee48424101 100644 --- a/core/profiles/standard/config/install/block_content.type.basic.yml +++ b/core/profiles/standard/config/install/block_content.type.basic.yml @@ -3,5 +3,5 @@ status: true dependencies: { } id: basic label: 'Basic block' -revision: 0 +revision: false description: 'A basic block contains a title and a body.'