@amazeelabs/silverback-gutenberg 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/CHANGELOG.md +983 -0
  2. package/drupal/silverback_gutenberg/README.md +439 -0
  3. package/drupal/silverback_gutenberg/composer.json +20 -0
  4. package/drupal/silverback_gutenberg/config/install/silverback_gutenberg.settings.yml +1 -0
  5. package/drupal/silverback_gutenberg/config/schema/silverback_gutenberg.schema.yml +13 -0
  6. package/drupal/silverback_gutenberg/css/gutenberg-tweaks.css +46 -0
  7. package/drupal/silverback_gutenberg/directives.gql +40 -0
  8. package/drupal/silverback_gutenberg/directives.graphql +46 -0
  9. package/drupal/silverback_gutenberg/js/base.js +24 -0
  10. package/drupal/silverback_gutenberg/js/gutenberg-tweaks.js +154 -0
  11. package/drupal/silverback_gutenberg/silverback_gutenberg.api.php +76 -0
  12. package/drupal/silverback_gutenberg/silverback_gutenberg.info.yml +8 -0
  13. package/drupal/silverback_gutenberg/silverback_gutenberg.libraries.yml +14 -0
  14. package/drupal/silverback_gutenberg/silverback_gutenberg.module +97 -0
  15. package/drupal/silverback_gutenberg/silverback_gutenberg.services.yml +29 -0
  16. package/drupal/silverback_gutenberg/src/Annotation/GutenbergBlockMutator.php +39 -0
  17. package/drupal/silverback_gutenberg/src/Annotation/GutenbergValidator.php +37 -0
  18. package/drupal/silverback_gutenberg/src/Annotation/GutenbergValidatorRule.php +37 -0
  19. package/drupal/silverback_gutenberg/src/Attribute/GutenbergBlockMutator.php +29 -0
  20. package/drupal/silverback_gutenberg/src/BlockMutator/BlockMutatorBase.php +24 -0
  21. package/drupal/silverback_gutenberg/src/BlockMutator/BlockMutatorInterface.php +41 -0
  22. package/drupal/silverback_gutenberg/src/BlockMutator/BlockMutatorManager.php +114 -0
  23. package/drupal/silverback_gutenberg/src/BlockMutator/BlockMutatorManagerInterface.php +30 -0
  24. package/drupal/silverback_gutenberg/src/BlockMutator/EntityBlockMutatorBase.php +189 -0
  25. package/drupal/silverback_gutenberg/src/BlockSerializer.php +84 -0
  26. package/drupal/silverback_gutenberg/src/Controller/LinkitAutocomplete.php +84 -0
  27. package/drupal/silverback_gutenberg/src/Directives.php +74 -0
  28. package/drupal/silverback_gutenberg/src/EditorBlocksProcessor.php +53 -0
  29. package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergCardinalityValidatorInterface.php +19 -0
  30. package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergCardinalityValidatorTrait.php +221 -0
  31. package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorBase.php +24 -0
  32. package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorInterface.php +65 -0
  33. package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorManager.php +37 -0
  34. package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorRuleInterface.php +20 -0
  35. package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorRuleManager.php +37 -0
  36. package/drupal/silverback_gutenberg/src/LinkProcessor.php +405 -0
  37. package/drupal/silverback_gutenberg/src/LinkedContentExtractor.php +35 -0
  38. package/drupal/silverback_gutenberg/src/Normalizer/GutenbergContentEntityNormalizer.php +123 -0
  39. package/drupal/silverback_gutenberg/src/Plugin/EntityUsage/Track/GutenbergContentTrackTrait.php +51 -0
  40. package/drupal/silverback_gutenberg/src/Plugin/EntityUsage/Track/GutenbergLinkedContent.php +96 -0
  41. package/drupal/silverback_gutenberg/src/Plugin/EntityUsage/Track/GutenbergMediaEmbed.php +63 -0
  42. package/drupal/silverback_gutenberg/src/Plugin/EntityUsage/Track/GutenbergReferencedContent.php +101 -0
  43. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockAttribute.php +42 -0
  44. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockChildren.php +32 -0
  45. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockHtml.php +30 -0
  46. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockMedia.php +159 -0
  47. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockType.php +29 -0
  48. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlocks.php +127 -0
  49. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockAttribute.php +29 -0
  50. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockChildren.php +21 -0
  51. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockMarkup.php +21 -0
  52. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockMedia.php +21 -0
  53. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockType.php +21 -0
  54. package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlocks.php +36 -0
  55. package/drupal/silverback_gutenberg/src/Plugin/GutenbergBlockMutator/MediaBlockMutator.php +30 -0
  56. package/drupal/silverback_gutenberg/src/Plugin/GutenbergBlockMutator/NodeBlockMutator.php +25 -0
  57. package/drupal/silverback_gutenberg/src/Plugin/GutenbergBlockMutator/TermReferenceBlockMutator.php +104 -0
  58. package/drupal/silverback_gutenberg/src/Plugin/Linkit/Matcher/SilverbackMatcherTrait.php +69 -0
  59. package/drupal/silverback_gutenberg/src/Plugin/Linkit/Matcher/SilverbackMediaMatcher.php +53 -0
  60. package/drupal/silverback_gutenberg/src/Plugin/Linkit/Matcher/SilverbackNodeMatcher.php +19 -0
  61. package/drupal/silverback_gutenberg/src/Plugin/Validation/Constraint/Gutenberg.php +15 -0
  62. package/drupal/silverback_gutenberg/src/Plugin/Validation/Constraint/GutenbergValidator.php +210 -0
  63. package/drupal/silverback_gutenberg/src/Plugin/Validation/GutenbergValidatorRule/Email.php +28 -0
  64. package/drupal/silverback_gutenberg/src/Plugin/Validation/GutenbergValidatorRule/Required.php +29 -0
  65. package/drupal/silverback_gutenberg/src/ReferencedContentExtractor.php +67 -0
  66. package/drupal/silverback_gutenberg/src/Routing/RouteSubscriber.php +17 -0
  67. package/drupal/silverback_gutenberg/src/Service/MediaService.php +27 -0
  68. package/drupal/silverback_gutenberg/src/SilverbackGutenbergServiceProvider.php +28 -0
  69. package/drupal/silverback_gutenberg/src/Utils.php +30 -0
  70. package/drupal/silverback_gutenberg/src/WebformMessageManager.php +29 -0
  71. package/drupal/silverback_gutenberg/tests/graphql/.graphqlrc.json +5 -0
  72. package/drupal/silverback_gutenberg/tests/graphql/queries/editor.gql +30 -0
  73. package/drupal/silverback_gutenberg/tests/graphql/schema.graphqls +37 -0
  74. package/drupal/silverback_gutenberg/tests/modules/silverback_gutenberg_test_validator/silverback_gutenberg_test_validator.info.yml +9 -0
  75. package/drupal/silverback_gutenberg/tests/modules/silverback_gutenberg_test_validator/src/Plugin/Validation/GutenbergValidator/ColumnValidator.php +42 -0
  76. package/drupal/silverback_gutenberg/tests/modules/silverback_gutenberg_test_validator/src/Plugin/Validation/GutenbergValidator/GroupValidator.php +50 -0
  77. package/drupal/silverback_gutenberg/tests/modules/silverback_gutenberg_test_validator/src/Plugin/Validation/GutenbergValidator/LinkValidator.php +43 -0
  78. package/drupal/silverback_gutenberg/tests/src/Kernel/BlockValidationRuleTest.php +194 -0
  79. package/drupal/silverback_gutenberg/tests/src/Kernel/EditorDirectivesTest.php +255 -0
  80. package/drupal/silverback_gutenberg/tests/src/Kernel/GutenbergLinkedContentEUTrackTest.php +133 -0
  81. package/drupal/silverback_gutenberg/tests/src/Kernel/GutenbergReferencedContentEUTrackTest.php +225 -0
  82. package/drupal/silverback_gutenberg/tests/src/Kernel/LinkProcessorTest.php +284 -0
  83. package/drupal/silverback_gutenberg/tests/src/Kernel/MediaNormalizerTest.php +174 -0
  84. package/drupal/silverback_gutenberg/tests/src/Traits/SampleAssetTrait.php +15 -0
  85. package/drupal/silverback_gutenberg/tests/src/Unit/BlockSerializerTest.php +27 -0
  86. package/drupal/silverback_gutenberg/tests/src/Unit/BlockValidatorCardinalityTest.php +1537 -0
  87. package/drupal/silverback_gutenberg/tests/src/Unit/EditorBlocksProcessorTest.php +159 -0
  88. package/drupal/silverback_gutenberg/tests/src/Unit/LinkedContentExtractorTest.php +65 -0
  89. package/drupal/silverback_gutenberg/tests/src/Unit/ReferencedContentExtractorTest.php +248 -0
  90. package/drupal/silverback_gutenberg/tests/src/assets/media/data.json +4 -0
  91. package/drupal/silverback_gutenberg/tests/src/assets/media/source.html +71 -0
  92. package/drupal/silverback_gutenberg/tests/src/assets/media/target.html +71 -0
  93. package/package.json +16 -0
  94. package/turbo.json +15 -0
@@ -0,0 +1,221 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gutenberg\GutenbergValidation;
4
+
5
+ use Drupal\Core\StringTranslation\TranslatableMarkup;
6
+
7
+ /**
8
+ * Cardinality validator helper.
9
+ */
10
+ trait GutenbergCardinalityValidatorTrait {
11
+
12
+ /**
13
+ * Validates the cardinality of the inner blocks of a block.
14
+ *
15
+ * This helper can be called from the validateContent() method of a validator.
16
+ *
17
+ * Example to validate the cardinality of all inner blocks (any, no matter the name).
18
+ * @code
19
+ * [
20
+ * 'validationType' => GutenbergCardinalityValidatorInterface::CARDINALITY_ANY,
21
+ * 'min' => 0,
22
+ * 'max' => 3,
23
+ * ]
24
+ * @endcode
25
+ *
26
+ * Example to validate by block name:
27
+ * @code
28
+ * [
29
+ * [
30
+ * 'blockName' => 'core/paragraph',
31
+ * 'blockLabel' => $this->t('Paragraph'),
32
+ * 'min' => 0,
33
+ * 'max' => 3,
34
+ * ],
35
+ * [
36
+ * 'blockName' => 'core/embed',
37
+ * 'blockLabel' => $this->t('Embed'),
38
+ * 'min' => 1,
39
+ * 'max' => 2,
40
+ * ],
41
+ * [
42
+ * 'blockName' => 'core/block',
43
+ * 'blockLabel' => $this->t('Reusable block'),
44
+ * 'min' => 1,
45
+ * 'max' => GutenbergCardinalityValidatorInterface::CARDINALITY_UNLIMITED,
46
+ * ],
47
+ * ];
48
+ * @endcode
49
+ *
50
+ * @param array $block
51
+ * @param array $expected_children
52
+ *
53
+ * @return array
54
+ */
55
+ public function validateCardinality(array $block, array $expected_children): array {
56
+ // Nothing to validate.
57
+ if (empty($expected_children)) {
58
+ return [
59
+ 'is_valid' => TRUE,
60
+ 'message' => '',
61
+ ];
62
+ }
63
+
64
+ // Check if the quantity validation is any block, no matter the name.
65
+ if (
66
+ !empty($expected_children['validationType']) &&
67
+ $expected_children['validationType'] === GutenbergCardinalityValidatorInterface::CARDINALITY_ANY) {
68
+ return $this->validateAnyInnerBlocks($block, $expected_children);
69
+ }
70
+
71
+ // Exit early if there are no inner blocks.
72
+ if (empty($block['innerBlocks'])) {
73
+ return $this->validateEmptyInnerBlocks($expected_children);
74
+ }
75
+
76
+ // Count blocks, then check if the quantity for each is correct.
77
+ $countInnerBlockInstances = [];
78
+ foreach ($block['innerBlocks'] as $innerBlock) {
79
+ if (!isset($countInnerBlockInstances[$innerBlock['blockName']])) {
80
+ $countInnerBlockInstances[$innerBlock['blockName']] = 0;
81
+ }
82
+ $countInnerBlockInstances[$innerBlock['blockName']]++;
83
+ }
84
+
85
+ foreach ($expected_children as $child) {
86
+ if (!isset($countInnerBlockInstances[$child['blockName']]) && $child['min'] > 0) {
87
+ $message = $this->getExpectedQuantityErrorMessage($child);
88
+ return [
89
+ 'is_valid' => FALSE,
90
+ 'message' => $message,
91
+ ];
92
+ }
93
+ // Minimum is set to 0, so we don't care if the block is not present.
94
+ if (!isset($countInnerBlockInstances[$child['blockName']]) && $child['min'] === 0) {
95
+ return [
96
+ 'is_valid' => TRUE,
97
+ 'message' => '',
98
+ ];
99
+ }
100
+ if ($countInnerBlockInstances[$child['blockName']] < $child['min']) {
101
+ return [
102
+ 'is_valid' => FALSE,
103
+ 'message' => \Drupal::translation()->formatPlural($child['min'],
104
+ '%label: at least @min block is required.',
105
+ '%label: at least @min blocks are required.',
106
+ [
107
+ '%label' => $child['blockLabel'],
108
+ '@min' => $child['min'],
109
+ ]),
110
+ ];
111
+ }
112
+ if ($child['max'] !== GutenbergCardinalityValidatorInterface::CARDINALITY_UNLIMITED && $countInnerBlockInstances[$child['blockName']] > $child['max']) {
113
+ return [
114
+ 'is_valid' => FALSE,
115
+ 'message' => \Drupal::translation()->formatPlural($child['max'],
116
+ '%label: at most @max block is allowed.',
117
+ '%label: at most @max blocks are allowed.',
118
+ [
119
+ '%label' => $child['blockLabel'],
120
+ '@max' => $child['max'],
121
+ ]),
122
+ ];
123
+ }
124
+ }
125
+
126
+ return [
127
+ 'is_valid' => TRUE,
128
+ 'message' => '',
129
+ ];
130
+ }
131
+
132
+ /**
133
+ * Check if it's fine to not have any inner blocks.
134
+ *
135
+ * Returns a message with all expected children blocks if needed.
136
+ *
137
+ * @param array $expected_children
138
+ *
139
+ * @return array|void
140
+ */
141
+ private function validateEmptyInnerBlocks (array $expected_children): array {
142
+ $missingBlocksMessages = [];
143
+ foreach ($expected_children as $child) {
144
+ if ($child['min'] > 0) {
145
+ $message = $this->getExpectedQuantityErrorMessage($child);
146
+ $missingBlocksMessages[] = $message;
147
+ }
148
+ }
149
+ if (!empty($missingBlocksMessages)) {
150
+ $errorMessage = t('Required blocks are missing.');
151
+ $errorMessage .= ' ' . implode(' ', $missingBlocksMessages);
152
+ return [
153
+ 'is_valid' => FALSE,
154
+ 'message' => $errorMessage,
155
+ ];
156
+ }
157
+
158
+ return [
159
+ 'is_valid' => TRUE,
160
+ 'message' => '',
161
+ ];
162
+ }
163
+
164
+ /**
165
+ * Validates the cardinality of any inner blocks.
166
+ *
167
+ * @param array $inner_blocks
168
+ * @param array $expected_children
169
+ *
170
+ * @return array
171
+ */
172
+ private function validateAnyInnerBlocks(array $inner_blocks, array $expected_children): array {
173
+ $min = $expected_children['min'];
174
+ $max = $expected_children['max'];
175
+ $count = count($inner_blocks['innerBlocks']);
176
+ if ($count < $min) {
177
+ return [
178
+ 'is_valid' => FALSE,
179
+ 'message' => \Drupal::translation()->formatPlural($min,
180
+ 'At least @min block is required.',
181
+ 'At least @min blocks are required.',
182
+ [
183
+ '@min' => $min,
184
+ ]),
185
+ ];
186
+ }
187
+ if ($max !== GutenbergCardinalityValidatorInterface::CARDINALITY_UNLIMITED && $count > $max) {
188
+ return [
189
+ 'is_valid' => FALSE,
190
+ 'message' => \Drupal::translation()->formatPlural($max,
191
+ 'At most @max block is allowed.',
192
+ 'At most @max blocks are allowed.',
193
+ [
194
+ '@max' => $max,
195
+ ]),
196
+ ];
197
+ }
198
+
199
+ return [
200
+ 'is_valid' => TRUE,
201
+ 'message' => '',
202
+ ];
203
+ }
204
+
205
+ private function getExpectedQuantityErrorMessage(array $child_block): string|TranslatableMarkup {
206
+ $messageParams = [
207
+ '%label' => $child_block['blockLabel'],
208
+ '@min' => $child_block['min'],
209
+ '@max' => $child_block['max'] > 0 ? $child_block['max'] : t('unlimited'),
210
+ ];
211
+ $result = t('%label: there should be between @min and @max blocks.', $messageParams);
212
+ if ($child_block['min'] === $child_block['max']) {
213
+ $result = \Drupal::translation()->formatPlural($child_block['min'],
214
+ '%label: there should be exactly @min block.',
215
+ '%label: there should be exactly @min blocks.',
216
+ $messageParams);
217
+ }
218
+ return $result;
219
+ }
220
+
221
+ }
@@ -0,0 +1,24 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gutenberg\GutenbergValidation;
4
+
5
+ /**
6
+ * Base class for all the Gutenberg validators.
7
+ */
8
+ abstract class GutenbergValidatorBase implements GutenbergValidatorInterface {
9
+
10
+ /**
11
+ * {@inheritDoc}
12
+ */
13
+ public function validateContent(array $block = []): array {
14
+ return [];
15
+ }
16
+
17
+ /**
18
+ * {@inheritDoc}
19
+ */
20
+ public function validatedFields(array $block = []): array {
21
+ return [];
22
+ }
23
+
24
+ }
@@ -0,0 +1,65 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gutenberg\GutenbergValidation;
4
+
5
+ /**
6
+ * Gutenberg validator plugins interface
7
+ */
8
+ interface GutenbergValidatorInterface {
9
+
10
+ /**
11
+ * Checks if the validator should apply on a block.
12
+ *
13
+ * @param array $block
14
+ * A gutenberg block (generated for example by the Gutenberg BlockParser
15
+ * class).
16
+ *
17
+ * @return bool
18
+ */
19
+ public function applies(array $block): bool;
20
+
21
+ /**
22
+ * Returns an array with the validation rules for each field that should be
23
+ * performed on the Gutenberg block. The keys of the array represent the block
24
+ * properties (field names) and the values are arrays with validation rule
25
+ * plugins that should be applied for that field, as well as, optionally, the
26
+ * human-readable label of the field.
27
+ *
28
+ * Example:
29
+ * @code
30
+ * array(
31
+ * 'title' => array(
32
+ * 'field_label' => t('Title'),
33
+ * 'rules' => array('gutenberg_rule_required'),
34
+ * ),
35
+ * 'caption' => array(
36
+ * 'field_label' => t('Caption'),
37
+ * 'rules' => array('gutenberg_rule_required_caption', 'some_other_rule_plugin'),
38
+ * ),
39
+ * );
40
+ * @endcode
41
+ *
42
+ * @return array
43
+ */
44
+ public function validatedFields(array $block = []): array;
45
+
46
+ /**
47
+ * Validates the content of a block. Useful in case the validator should
48
+ * perform a more complex validation logic, on the entire block, which cannot
49
+ * be covered by the existing validation rules.
50
+ *
51
+ * Use isValid and message keys in the array to display a message
52
+ *
53
+ * Example:
54
+ * @code
55
+ * array(
56
+ * 'is_valid' => FALSE,
57
+ * 'message' => 'Field name is not valid'
58
+ * );
59
+ * @endcode
60
+ *
61
+ * @return array
62
+ */
63
+ public function validateContent(array $block = []): array;
64
+
65
+ }
@@ -0,0 +1,37 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gutenberg\GutenbergValidation;
4
+
5
+ use Drupal\Core\Cache\CacheBackendInterface;
6
+ use Drupal\Core\Extension\ModuleHandlerInterface;
7
+ use Drupal\Core\Plugin\DefaultPluginManager;
8
+
9
+ /**
10
+ * Provides a Gutenberg Validator plugin manager.
11
+ */
12
+ class GutenbergValidatorManager extends DefaultPluginManager {
13
+
14
+ /**
15
+ * Constructs a GutenbergValidatorManager object.
16
+ *
17
+ * @param \Traversable $namespaces
18
+ * An object that implements \Traversable which contains the root paths
19
+ * keyed by the corresponding namespace to look for plugin implementations.
20
+ * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
21
+ * Cache backend instance to use.
22
+ * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
23
+ * The module handler to invoke the alter hook with.
24
+ */
25
+ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
26
+ parent::__construct(
27
+ 'Plugin/Validation/GutenbergValidator',
28
+ $namespaces,
29
+ $module_handler,
30
+ 'Drupal\silverback_gutenberg\GutenbergValidation\GutenbergValidatorInterface',
31
+ 'Drupal\silverback_gutenberg\Annotation\GutenbergValidator'
32
+ );
33
+ $this->alterInfo('gutenberg_validator_info');
34
+ $this->setCacheBackend($cache_backend, 'gutenberg_validator_info_plugins');
35
+ }
36
+
37
+ }
@@ -0,0 +1,20 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gutenberg\GutenbergValidation;
4
+
5
+ /**
6
+ * Gutenberg validator rule plugins interface.
7
+ */
8
+ interface GutenbergValidatorRuleInterface {
9
+
10
+ /**
11
+ * Validates a value.
12
+ *
13
+ * @param $value
14
+ * @param $fieldLabel
15
+ *
16
+ * @return bool
17
+ */
18
+ public function validate($value, $fieldLabel): bool|string;
19
+
20
+ }
@@ -0,0 +1,37 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gutenberg\GutenbergValidation;
4
+
5
+ use Drupal\Core\Cache\CacheBackendInterface;
6
+ use Drupal\Core\Extension\ModuleHandlerInterface;
7
+ use Drupal\Core\Plugin\DefaultPluginManager;
8
+
9
+ /**
10
+ * Provides a Gutenberg Validator Rule plugin manager.
11
+ */
12
+ class GutenbergValidatorRuleManager extends DefaultPluginManager {
13
+
14
+ /**
15
+ * Constructs a GutenbergValidatorRuleManager object.
16
+ *
17
+ * @param \Traversable $namespaces
18
+ * An object that implements \Traversable which contains the root paths
19
+ * keyed by the corresponding namespace to look for plugin implementations.
20
+ * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
21
+ * Cache backend instance to use.
22
+ * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
23
+ * The module handler to invoke the alter hook with.
24
+ */
25
+ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
26
+ parent::__construct(
27
+ 'Plugin/Validation/GutenbergValidatorRule',
28
+ $namespaces,
29
+ $module_handler,
30
+ 'Drupal\silverback_gutenberg\GutenbergValidation\GutenbergValidatorRuleInterface',
31
+ 'Drupal\silverback_gutenberg\Annotation\GutenbergValidatorRule'
32
+ );
33
+ $this->alterInfo('gutenberg_validator_rule_info');
34
+ $this->setCacheBackend($cache_backend, 'gutenberg_validator_rule_info_plugins');
35
+ }
36
+
37
+ }