77use Illuminate \Validation \Rules \Unique ;
88use Illuminate \Validation \ValidationException ;
99use Illuminate \Validation \Validator ;
10+ use StevenFox \LaravelModelValidation \Contracts \ValidatesWhenSaving ;
1011use StevenFox \LaravelModelValidation \Exceptions \ModelValidationException ;
1112use StevenFox \LaravelModelValidation \Listeners \ValidateModel ;
1213
@@ -36,11 +37,6 @@ trait ValidatesAttributes
3637 */
3738 protected ?Validator $ validator = null ;
3839
39- /**
40- * Indicates if the validation listeners have been registered.
41- */
42- private static bool $ validationListenersRegistered = false ;
43-
4440 public static function bootValidatesAttributes (): void
4541 {
4642 self ::registerValidatingEventListeners ();
@@ -54,24 +50,22 @@ protected function initializeValidatesAttributes(): void
5450 ]);
5551 }
5652
57- private static function registerValidatingEventListeners (): void
53+ protected static function registerValidatingEventListeners (): void
5854 {
59- if (static ::$ validationListenersRegistered ) {
60- return ;
61- }
62-
6355 foreach (static ::validatingListeners () as $ event => $ listener ) {
6456 static ::{$ event }($ listener );
6557 }
66-
67- static ::$ validationListenersRegistered = true ;
6858 }
6959
7060 /**
7161 * @return array<array-key, class-string|\Illuminate\Events\QueuedClosure|\Closure|array>
7262 */
7363 protected static function validatingListeners (): array
7464 {
65+ if (! is_a (static ::class, ValidatesWhenSaving::class, true )) {
66+ return [];
67+ }
68+
7569 // We specifically use the 'creating' and 'updating' events
7670 // over the more general 'saving' event so that we don't
7771 // redundantly validate a model that is "saved" without
@@ -91,13 +85,12 @@ public static function disableValidationWhenSaving(): void
9185 public static function reactivateValidationWhenSaving (): void
9286 {
9387 static ::$ validateWhenSaving = true ;
94-
95- static ::registerValidatingEventListeners ();
9688 }
9789
9890 public static function shouldValidateWhenSaving (): bool
9991 {
100- return static ::$ validateWhenSaving ;
92+ return static ::$ validateWhenSaving
93+ && is_a (static ::class, ValidatesWhenSaving::class, true );
10194 }
10295
10396 public static function shouldNotValidateWhenSaving (): bool
@@ -121,15 +114,15 @@ public static function whileValidationDisabled(callable $callback): mixed
121114 }
122115
123116 /**
124- * @param class-string|\Illuminate\Events\QueuedClosure|\Closure($this, Validator): void|array $callback
117+ * @param class-string|\Illuminate\Events\QueuedClosure|\Closure($this, Validator): void|array $callback
125118 */
126119 public static function validating (mixed $ callback ): void
127120 {
128121 static ::registerModelEvent ('validating ' , $ callback );
129122 }
130123
131124 /**
132- * @param class-string|\Illuminate\Events\QueuedClosure|\Closure($this, Validator): void|array $callback
125+ * @param class-string|\Illuminate\Events\QueuedClosure|\Closure($this, Validator): void|array $callback
133126 */
134127 public static function validated (mixed $ callback ): void
135128 {
@@ -244,18 +237,28 @@ public function validationRules(): array
244237 return array_merge ($ rules , $ this ->getMixinValidationRules ());
245238 }
246239
240+ /**
241+ * Get the superseding validation rules.
242+ */
247243 public function getSupersedingValidationRules (): ?array
248244 {
249245 return $ this ->supersedingValidationRules ?? null ;
250246 }
251247
248+ /**
249+ * Set validation rules that will supersede (replace) all other rules
250+ * for the model.
251+ */
252252 public function setSupersedingValidationRules (array $ rules ): static
253253 {
254254 $ this ->supersedingValidationRules = $ rules ;
255255
256256 return $ this ;
257257 }
258258
259+ /**
260+ * Remove all superseding validation rules on the model.
261+ */
259262 public function clearSupersedingValidationRules (): static
260263 {
261264 unset($ this ->supersedingValidationRules );
0 commit comments