Skip to content

Commit a25b317

Browse files
author
Stephen Lucero
committed
Issue #3511525 by slucero, firewaller, minsharm, bladwin, johnle: Remove the derivatives for loading reusable patterns
1 parent 6e60dc7 commit a25b317

22 files changed

Lines changed: 952 additions & 120 deletions

‎composer.json‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"symfony/serializer": "^6 || ^7",
3131
"symfony/property-access": "^5.4 || ^6 || ^7",
3232
"symfony/yaml": "^5.4 || ^6 || ^7",
33-
"webmozart/assert": "^1.0"
33+
"webmozart/assert": "^1.0",
34+
"symfony/polyfill-php84": "^1.31"
3435
},
3536
"require-dev": {
3637
"dms/phpunit-arraysubset-asserts": "^0.5.0",
@@ -44,7 +45,8 @@
4445
"phpstan/phpstan-phpunit": "@stable",
4546
"slowprog/composer-copy-file": "^0.3.3",
4647
"drush/drush": "^12.4.3 | ^13",
47-
"palantirnet/drupal-rector": "^0.20.3"
48+
"palantirnet/drupal-rector": "^0.20.3",
49+
"symfony/phpunit-bridge": "@stable"
4850
},
4951
"conflict": {
5052
"drush/drush": "<12.4.3"

‎patternkit.install‎

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
1515
use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema;
1616
use Drupal\Core\Field\BaseFieldDefinition;
1717
use Drupal\Core\Field\FieldStorageDefinitionInterface;
18+
use Drupal\Core\Utility\UpdateException;
1819
use Drupal\patternkit\BulkOperations\LayoutUpdateBatchManager;
1920
use Drupal\patternkit\Entity\Pattern;
2021
use Drupal\patternkit\Entity\PatternRouteProvider;
2122
use Drupal\patternkit\Form\PatternLibraryJSONForm;
23+
use Drupal\patternkit\Hook\ReusableBlockHooks;
24+
use Drupal\patternkit\Plugin\Block\PatternkitBlock as BlockPatternkitBlock;
25+
use Drupal\patternkit\Plugin\Derivative\PatternkitBlock as DerivativePatternkitBlock;
2226
use Drupal\user\Entity\Role;
2327
use Drupal\user\RoleInterface;
2428
use Drupal\views\EntityViewsData;
@@ -32,6 +36,20 @@ function patternkit_uninstall(bool $is_syncing): void {
3236
->deleteAll();
3337
}
3438

39+
/**
40+
* Implements hook_requirements().
41+
*/
42+
function patternkit_requirements($phase): array {
43+
$requirements = [];
44+
if ($phase === 'runtime') {
45+
/** @var \Drupal\patternkit\Hook\ReusableBlockHooks $hooks */
46+
$hooks = \Drupal::classResolver(ReusableBlockHooks::class);
47+
$requirements = $hooks->requirements($phase);
48+
}
49+
50+
return $requirements;
51+
}
52+
3553
/**
3654
* Allows upgrading from dev version automatically.
3755
*
@@ -524,3 +542,91 @@ function patternkit_update_10306(): string {
524542

525543
return $message;
526544
}
545+
546+
/**
547+
* Update patternkit block records to correctly reference pattern ids.
548+
*/
549+
function patternkit_update_10307(): string {
550+
$storage = \Drupal::entityTypeManager()->getStorage('patternkit_block');
551+
$query = $storage->getQuery();
552+
$matches = $query->condition('pattern_id', '@%', 'NOT LIKE')
553+
->accessCheck()
554+
->execute();
555+
/** @var \Drupal\patternkit\Entity\PatternkitBlock[] $entities */
556+
$entities = $storage->loadMultiple($matches);
557+
558+
$updated = 0;
559+
foreach ($entities as $block) {
560+
$derivative_id = $block->get('pattern_id')->value;
561+
$asset_id = DerivativePatternkitBlock::derivativeToAssetId($derivative_id);
562+
$block->set('pattern_id', $asset_id, FALSE);
563+
$block->save();
564+
$updated++;
565+
566+
\Drupal::logger('patternkit')->notice('Updated Patternkit block ID @id to correct pattern asset ID from "@old" to "@new".',
567+
[
568+
'@id' => $block->id(),
569+
'@old' => $derivative_id,
570+
'@new' => $asset_id,
571+
]);
572+
}
573+
574+
if ($updated > 0) {
575+
return \Drupal::translation()
576+
->formatPlural($updated, 'Fixed asset IDs for 1 block.', 'Fixed asset IDs for @count blocks.');
577+
}
578+
else {
579+
return t('No invalid asset IDs were found.');
580+
}
581+
}
582+
583+
/**
584+
* Capture unsaved changes in Patternkit blocks.
585+
*/
586+
function patternkit_update_10308(): string {
587+
// Identify all patternkit blocks with serialized changes.
588+
$block_storage = \Drupal::entityTypeManager()->getStorage('block');
589+
$query = $block_storage->getQuery();
590+
$matches = $query->condition('settings.provider', 'patternkit')
591+
->condition('settings.block_serialized', operator: 'IS NOT NULL')
592+
->execute();
593+
$entities = $block_storage->loadMultiple($matches);
594+
595+
$message = \Drupal::translation()
596+
->formatPlural(count($entities),
597+
'Identified 1 Patternkit Block with unsaved changes.',
598+
'Identified @count Patternkit blocks with unsaved changes.'
599+
);
600+
\Drupal::logger('patternkit')->notice($message);
601+
602+
// Save serialized content changes.
603+
$updated = 0;
604+
foreach ($entities as $block) {
605+
$plugin = $block->getPlugin();
606+
607+
if (!($plugin instanceof BlockPatternkitBlock)) {
608+
$message = 'Unable to successfully load Patternkit Block plugin for config block "@id". Looking for Patternkit Block ID "@block_id".';
609+
$context = [
610+
'@id' => $block->id(),
611+
'@block_id' => $block->getPluginId(),
612+
];
613+
\Drupal::logger('patternkit')->error($message, $context);
614+
throw new UpdateException('Failed to load a block plugin for updating.');
615+
}
616+
617+
$plugin->cachePatternEntity();
618+
$plugin->saveBlockContent(TRUE);
619+
$post_save_configuration = $plugin->getConfiguration();
620+
$block->set('settings', $post_save_configuration);
621+
$block->save();
622+
$updated++;
623+
}
624+
625+
if ($updated > 0) {
626+
return \Drupal::translation()
627+
->formatPlural($updated, 'Saved updated configuration for 1 block.', 'Saved updated configuration for @count blocks.');
628+
}
629+
else {
630+
return t('No invalid blocks were found.');
631+
}
632+
}

‎patternkit.links.action.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
12
patternkit_add_action:
23
route_name: patternkit.add_page
34
title: 'Add Patternkit block'

‎patternkit.links.contextual.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
12
patternkit.block_edit:
23
title: 'Edit'
34
group: patternkit

‎patternkit.links.task.yml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
1+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
12
entity.patternkit_block.collection:
23
title: 'Patternkit library'
34
route_name: entity.patternkit_block.collection
45
base_route: block.admin_display
6+
7+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
58
entity.patternkit_block.canonical:
69
title: Edit
710
route_name: entity.patternkit_block.canonical
811
base_route: entity.patternkit_block.canonical
12+
13+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
914
entity.patternkit_block.delete_form:
1015
title: Delete
1116
route_name: entity.patternkit_block.delete_form
1217
base_route: entity.patternkit_block.canonical
18+
19+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
1320
patternkit.list_sub:
1421
title: Blocks
1522
route_name: entity.patternkit_block.collection
1623
parent_id: entity.patternkit_block.collection
24+
1725
patternkit.settings:
1826
title: 'Patternkit Settings'
1927
route_name: patternkit.settings

‎patternkit.module‎

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
*/
77

88
use Drupal\Core\Entity\EntityInterface;
9+
use Drupal\Core\Hook\Attribute\LegacyHook;
910
use Drupal\Core\Routing\RouteMatchInterface;
1011
use Drupal\Core\Url;
12+
use Drupal\patternkit\Hook\ReusableBlockHooks;
1113
use Drupal\patternkit\PatternkitBlockEntityOperations;
1214

1315
/**
@@ -58,18 +60,58 @@ function patternkit_theme($existing, $type, $theme, $path): array {
5860
/**
5961
* Implements hook_entity_presave().
6062
*/
61-
function patternkit_entity_presave(EntityInterface $entity) {
63+
function patternkit_entity_presave(EntityInterface $entity): void {
6264
if (\Drupal::moduleHandler()->moduleExists('layout_builder')) {
6365
/** @var \Drupal\patternkit\PatternkitBlockEntityOperations $entity_operations */
6466
$entity_operations = \Drupal::classResolver(PatternkitBlockEntityOperations::class);
6567
$entity_operations->handlePreSave($entity);
6668
}
6769
}
6870

71+
/**
72+
* Implements hook_entity_type_alter().
73+
*/
74+
#[LegacyHook]
75+
function patternkit_entity_type_alter(array &$entity_types): void {
76+
/** @var \Drupal\patternkit\Hook\ReusableBlockHooks $reusable_block_hooks */
77+
$reusable_block_hooks = \Drupal::classResolver(ReusableBlockHooks::class);
78+
$reusable_block_hooks->entityTypeAlter($entity_types);
79+
}
80+
81+
/**
82+
* Implements hook_contextual_links_alter().
83+
*/
84+
#[LegacyHook]
85+
function patternkit_contextual_links_alter(array &$links, $group, array $route_parameters): void {
86+
/** @var \Drupal\patternkit\Hook\ReusableBlockHooks $reusable_block_hooks */
87+
$reusable_block_hooks = \Drupal::classResolver(ReusableBlockHooks::class);
88+
$reusable_block_hooks->contextualLinksAlter($links, $group, $route_parameters);
89+
}
90+
91+
/**
92+
* Implements hook_local_tasks_alter().
93+
*/
94+
#[LegacyHook]
95+
function patternkit_local_tasks_alter(&$local_tasks): void {
96+
/** @var \Drupal\patternkit\Hook\ReusableBlockHooks $reusable_block_hooks */
97+
$reusable_block_hooks = \Drupal::classResolver(ReusableBlockHooks::class);
98+
$reusable_block_hooks->localTasksAlter($local_tasks);
99+
}
100+
101+
/**
102+
* Implements hook_menu_local_actions_alter().
103+
*/
104+
#[LegacyHook]
105+
function patternkit_menu_local_actions_alter(&$local_actions): void {
106+
/** @var \Drupal\patternkit\Hook\ReusableBlockHooks $reusable_block_hooks */
107+
$reusable_block_hooks = \Drupal::classResolver(ReusableBlockHooks::class);
108+
$reusable_block_hooks->menuLocalActionsAlter($local_actions);
109+
}
110+
69111
/**
70112
* Implements hook_rebuild().
71113
*/
72-
function patternkit_rebuild() {
114+
function patternkit_rebuild(): void {
73115
// Rebuild the library definitions cache.
74116
\Drupal::service('patternkit.library.namespace_resolver')
75117
->rebuild();

‎patternkit.routing.yml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
12
entity.patternkit_block.collection:
23
path: '/admin/structure/block/patternkit'
34
defaults:
@@ -6,6 +7,7 @@ entity.patternkit_block.collection:
67
requirements:
78
_permission: 'administer blocks'
89

10+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
911
entity.patternkit_block.canonical:
1012
path: '/patternkit_block/{patternkit_block}'
1113
defaults:
@@ -16,6 +18,7 @@ entity.patternkit_block.canonical:
1618
_permission: 'administer blocks'
1719
patternkit_block: \d+
1820

21+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
1922
entity.patternkit_block.edit_form:
2023
path: '/patternkit_block/{patternkit_block}'
2124
defaults:
@@ -26,6 +29,7 @@ entity.patternkit_block.edit_form:
2629
_permission: 'administer blocks'
2730
patternkit_block: \d+
2831

32+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
2933
entity.patternkit_block.delete_form:
3034
path: '/patternkit_block/{patternkit_block}/delete'
3135
defaults:
@@ -37,6 +41,7 @@ entity.patternkit_block.delete_form:
3741
_permission: 'administer blocks'
3842
patternkit_block: \d+
3943

44+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
4045
patternkit.add_form:
4146
path: '/patternkit_block/add/{pattern_id}'
4247
defaults:
@@ -46,7 +51,9 @@ patternkit.add_form:
4651
_admin_route: TRUE
4752
requirements:
4853
_permission: 'administer blocks'
54+
pattern_id: ^[a-zA-Z][a-zA-Z0-9_-]*$
4955

56+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
5057
patternkit.add_page:
5158
path: '/patternkit_block/add'
5259
defaults:

‎patternkit.services.yml‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ parameters:
1616
# the pattern directly from the available parser definition instead.
1717
bypass_database_cache: false
1818

19+
# Support for reusable blocks has been deprecated and will be removed in
20+
# the Patternkit 9.1.3 release. Patternkit versions 9.1.1 and earlier
21+
# included support for reusable blocks by default. To continue using them
22+
# on a site, enable this setting in your sites "services.yml" file.
23+
# Before upgrading to the 9.1.3 or later release, existing reusable
24+
# blocks will need to be removed.
25+
enable_reusable_blocks: false
26+
1927
services:
2028
_defaults:
2129
autoconfigure: true
@@ -146,6 +154,12 @@ services:
146154
class: Drupal\patternkit\EventSubscriber\RenderFailureErrorDisplaySubscriber
147155
tags:
148156
- { name: event_subscriber }
157+
# @todo Remove once reusable blocks are no longer supported. https://www.drupal.org/i/3516918
158+
patternkit.subscriber.route.reusable_blocks:
159+
class: Drupal\patternkit\EventSubscriber\PatternkitReusableBlocksRouteSubscriber
160+
arguments: ['@config.factory']
161+
tags:
162+
- { name: event_subscriber }
149163
patternkit.environment:
150164
class: Drupal\patternkit\PatternkitEnvironment
151165
arguments: ['%patternkit.config%']

‎phpstan-baseline.neon‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,65 @@ parameters:
1313
count: 1
1414
path: src/Plugin/PatternLibrary/PatternLibraryFile.php
1515

16+
#########################
17+
# Ignore internal deprecation warnings for reusable block support.
18+
#########################
19+
- message: """
20+
#^Fetching class constant class of deprecated class Drupal\\\\patternkit\\\\Hook\\\\ReusableBlockHooks\\:
21+
in patternkit\\:9\\.1\\.2 and is removed from patternkit\\:9\\.2\\.0\\.
22+
Reusable blocks should be removed or replaced before updating\\.$#
23+
"""
24+
count: 1
25+
path: patternkit.install
26+
27+
- message: """
28+
#^Fetching class constant class of deprecated class Drupal\\\\patternkit\\\\Hook\\\\ReusableBlockHooks\\:
29+
in patternkit\\:9\\.1\\.2 and is removed from patternkit\\:9\\.2\\.0\\.
30+
Reusable blocks should be removed or replaced before updating\\.$#
31+
"""
32+
count: 4
33+
path: patternkit.module
34+
35+
- message: """
36+
#^Fetching deprecated class constant FEATURE_ENABLE_REUSABLE_BLOCKS of class Drupal\\\\patternkit\\\\PatternkitEnvironment\\:
37+
in patternkit\\:9\\.1\\.2 and is removed from patternkit\\:9\\.2\\.0\\.
38+
Reusable blocks should be removed or replaced before updating\\.$#
39+
"""
40+
count: 1
41+
path: src/Plugin/Block/PatternkitBlock.php
42+
43+
- message: """
44+
#^Call to deprecated method getReusableBlockDerivatives\\(\\) of class Drupal\\\\patternkit\\\\Plugin\\\\Derivative\\\\PatternkitBlock\\:
45+
in patternkit\\:9\\.1\\.2 and is removed from patternkit\\:9\\.2\\.0\\.
46+
Reusable blocks should be removed or replaced before updating\\.$#
47+
"""
48+
count: 1
49+
path: src/Plugin/Derivative/PatternkitBlock.php
50+
51+
- message: """
52+
#^Fetching deprecated class constant FEATURE_ENABLE_REUSABLE_BLOCKS of class Drupal\\\\patternkit\\\\PatternkitEnvironment\\:
53+
in patternkit\\:9\\.1\\.2 and is removed from patternkit\\:9\\.2\\.0\\.
54+
Reusable blocks should be removed or replaced before updating\\.$#
55+
"""
56+
count: 1
57+
path: src/Plugin/Derivative/PatternkitBlock.php
58+
59+
- message: """
60+
#^Fetching class constant class of deprecated class Drupal\\\\patternkit\\\\Hook\\\\ReusableBlockHooks\\:
61+
in patternkit\\:9\\.1\\.2 and is removed from patternkit\\:9\\.2\\.0\\.
62+
Reusable blocks should be removed or replaced before updating\\.$#
63+
"""
64+
count: 1
65+
path: tests/src/Functional/ReusableBlocksDisabledTest.php
66+
67+
- message: """
68+
#^Fetching class constant class of deprecated class Drupal\\\\patternkit\\\\Hook\\\\ReusableBlockHooks\\:
69+
in patternkit\\:9\\.1\\.2 and is removed from patternkit\\:9\\.2\\.0\\.
70+
Reusable blocks should be removed or replaced before updating\\.$#
71+
"""
72+
count: 1
73+
path: tests/src/Functional/ReusableBlocksEnabledTest.php
74+
1675
#########################
1776
# PHPStan type stubs needed.
1877
#########################

0 commit comments

Comments
 (0)