44
55use Drupal \Component \EventDispatcher \Event ;
66use Drupal \patternkit \Entity \PatternInterface ;
7- use Drupal \patternkit \Exception \ SchemaValidationException ;
7+ use Drupal \patternkit \PatternValidationTrait ;
88use Drupal \patternkit \Plugin \Block \PatternkitBlock ;
9- use Swaggest \JsonSchema \InvalidValue ;
109
1110/**
1211 * An event triggered when a pattern in use is being updated.
1312 *
1413 * @event
1514 *
1615 * @see \Drupal\patternkit\PatternkitEvents::PATTERN_UPDATE
16+ * @see \Drupal\patternkit\EventSubscriber\PatternUpdateEventSubscriberBase
1717 */
1818class PatternUpdateEvent extends Event {
1919
20+ use PatternValidationTrait {
21+ validateContent as traitValidateContent;
22+ }
23+
2024 /**
2125 * Content for the pattern instance at the time of updating.
2226 *
2327 * @var array
2428 */
25- protected array $ originalContent ;
29+ protected readonly array $ originalContent ;
2630
2731 /**
2832 * Content for the pattern instance that may have been altered.
@@ -38,6 +42,13 @@ class PatternUpdateEvent extends Event {
3842 */
3943 protected bool $ isAltered = FALSE ;
4044
45+ /**
46+ * A flag to track whether the contained pattern content is valid.
47+ *
48+ * @var bool
49+ */
50+ protected bool $ isValid ;
51+
4152 /**
4253 * Create a new PatternUpdateEvent instance.
4354 *
@@ -91,24 +102,61 @@ public function isAltered(): bool {
91102 return $ this ->isAltered ;
92103 }
93104
105+ /**
106+ * Determine if content for a component is valid for the pattern schema.
107+ *
108+ * @return bool
109+ * True if the content is valid, false otherwise.
110+ */
111+ public function isValid (): bool {
112+ if (!isset ($ this ->isValid )) {
113+ $ this ->isValid = $ this ->validateContent ($ this ->getContent ());
114+ }
115+
116+ return $ this ->isValid ;
117+ }
118+
94119 /**
95120 * Assign new content for the component.
96121 *
97122 * @param array $content
98123 * Content values to be assigned to the pattern component.
124+ * @param bool $allowInvalid
125+ * (Optional) A flag to allow invalid content to be set and validation to be
126+ * ignored. Defaults to FALSE. The primary use case for this is when
127+ * supporting sequential content updates that may produce invalid content
128+ * along the way, but the final result after all updates have been executed
129+ * is expected to be valid.
99130 *
100131 * @throws \Drupal\patternkit\Exception\SchemaValidationException
101132 * Throws an exception when the provided content does not validate
102- * against the updated pattern schema.
133+ * against the updated pattern schema. This is only thrown if $allowInvalid
134+ * remains FALSE.
135+ *
136+ * @see \Drupal\patternkit\Event\PatternUpdateEvent::getExceptions()
137+ *
138+ * @return $this
103139 */
104- public function setContent (array $ content ): void {
105- if ($ this ->validateContent ($ content )) {
140+ public function setContent (array $ content , bool $ allowInvalid = FALSE ): self {
141+ $ isValid = $ this ->validateContent ($ content );
142+
143+ // Only throw the exceptions if invalid content is not allowed.
144+ if (!$ isValid && !$ allowInvalid ) {
145+ $ encountered_exceptions = $ this ->getExceptions ();
146+ assert (count ($ encountered_exceptions ) > 0 );
147+
148+ // Throw the exception before content assignment if invalid content is not
149+ // allowed.
150+ throw $ encountered_exceptions [0 ];
151+ }
152+
153+ if ($ isValid || $ allowInvalid ) {
106154 $ this ->content = $ content ;
107155 $ this ->isAltered = TRUE ;
156+ $ this ->isValid = $ isValid ;
108157 }
109- else {
110- throw new SchemaValidationException ('Assigned content does not validate successfully. ' );
111- }
158+
159+ return $ this ;
112160 }
113161
114162 /**
@@ -121,6 +169,46 @@ public function getPattern(): PatternInterface {
121169 return $ this ->newPattern ;
122170 }
123171
172+ /**
173+ * Get the label for the updated pattern entity from schema data.
174+ *
175+ * @return string
176+ * The label for the updated pattern entity.
177+ */
178+ public function getPatternName (): string {
179+ return $ this ->newPattern ->getName ();
180+ }
181+
182+ /**
183+ * Get the asset ID for the updated pattern entity.
184+ *
185+ * @return string
186+ * The pattern asset ID for the updated pattern entity.
187+ */
188+ public function getPatternAssetId (): string {
189+ return $ this ->newPattern ->getAssetId ();
190+ }
191+
192+ /**
193+ * Get the label for the pre-update pattern entity from schema data.
194+ *
195+ * @return string
196+ * The label for the pre-update pattern entity.
197+ */
198+ public function getOriginalPatternName (): string {
199+ return $ this ->oldPattern ->getName ();
200+ }
201+
202+ /**
203+ * Get the asset ID for the pre-update pattern entity.
204+ *
205+ * @return string
206+ * The pattern asset ID for the pre-update pattern entity.
207+ */
208+ public function getOriginalPatternAssetId (): string {
209+ return $ this ->oldPattern ->getAssetId ();
210+ }
211+
124212 /**
125213 * Get the original pattern entity.
126214 *
@@ -149,28 +237,11 @@ public function getPlugin(): PatternkitBlock {
149237 *
150238 * @return bool
151239 * True if the content validates successfully. False otherwise.
152- *
153- * @todo Expose this somewhere as a standard validation solution.
154240 */
155- protected function validateContent (array $ content ): bool {
156- $ schema_string = $ this ->newPattern ->getSchema ();
157-
158- /** @var \Drupal\patternkit\Schema\SchemaFactory $schema_factory */
159- $ schema_factory = \Drupal::service ('patternkit.schema.schema_factory ' );
160- $ schema = $ schema_factory ->createInstance ($ schema_string );
161-
162- /** @var \Drupal\patternkit\Schema\ContextBuilder $context_builder */
163- $ context_builder = \Drupal::service ('patternkit.schema.context_builder ' );
164- $ context = $ context_builder ->getDefaultContext ();
165-
166- try {
167- $ schema ->in ($ content , $ context );
168- }
169- catch (InvalidValue $ exception ) {
170- return FALSE ;
171- }
172-
173- return TRUE ;
241+ public function validateContent (array $ content ): bool {
242+ // This is overridden for convenience to automatically pass in the updated
243+ // pattern for reference.
244+ return $ this ->traitValidateContent ($ this ->newPattern , $ content );
174245 }
175246
176247}
0 commit comments