From 40e7a1d4097a25091b3c16c924eeabbb7ed603b6 Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:29:41 -0500 Subject: [PATCH 01/13] Implement `TagUpdateRequest` for tag store action validations --- app/Http/Controllers/TagsController.php | 4 ++-- resources/views/tags/create.blade.php | 9 +++++---- resources/views/tags/edit.blade.php | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/TagsController.php b/app/Http/Controllers/TagsController.php index b9c2c9db..7ff59b13 100644 --- a/app/Http/Controllers/TagsController.php +++ b/app/Http/Controllers/TagsController.php @@ -73,9 +73,9 @@ public function create(): View|ViewContract /** * Save the tag in the database. */ - public function store(Request $request): RedirectResponse + public function store(TagUpdateRequest $request): RedirectResponse { - Tag::findOrCreate(preg_split('/\r\n|\r|\n/', $request->tag_name ?? ''), $request->tag_type); + Tag::findOrCreate(preg_split('/\r\n|\r|\n/', $request->name ?? ''), $request->type); return redirect()->route('tags.table') ->with('flash_message', 'Added tags'); diff --git a/resources/views/tags/create.blade.php b/resources/views/tags/create.blade.php index d9b3ba5b..884a8cc6 100644 --- a/resources/views/tags/create.blade.php +++ b/resources/views/tags/create.blade.php @@ -22,17 +22,18 @@

Add Tags

+ @include('errors/list') {!! Form::open(['route' => 'tags.store']) !!}
- {!! Form::label('tag_name', 'Tag name(s)', ['class' => 'form-label']) !!} + {!! Form::label('name', 'Tag name(s)', ['class' => 'form-label']) !!} One tag per line - {!! Form::textarea('tag_name', null, ['class' => 'form-control', 'required']) !!} + {!! Form::textarea('name', null, ['class' => 'form-control', 'required']) !!}
- {!! Form::label('tag_type', 'Tag type', ['class' => 'form-label']) !!} + {!! Form::label('type', 'Tag type', ['class' => 'form-label']) !!} e.g. App\Profile, App\Student, and etc. - {!! Form::text('tag_type', null, ['class' => 'form-control', 'required']) !!} + {!! Form::text('type', null, ['class' => 'form-control', 'required']) !!}
diff --git a/resources/views/tags/edit.blade.php b/resources/views/tags/edit.blade.php index faf96c78..0b0556ce 100644 --- a/resources/views/tags/edit.blade.php +++ b/resources/views/tags/edit.blade.php @@ -22,7 +22,7 @@

Edit Tag {{ $tag->name }}

- @include('errors/has') + @include('errors/list') {!! Form::model($tag, ['method' => 'PATCH','route' => ['tags.updateTag', $tag], 'class' => 'form-horizontal' ]) !!} From 3953611e90165b1fd3845d3e1567ebaafe292ba1 Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:22:58 -0500 Subject: [PATCH 02/13] Adds TagUniquenessName custom rule for both, store and edit tag form request. --- app/Http/Requests/TagUpdateRequest.php | 10 +--- app/Rules/TagNameUniqueness.php | 75 ++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 app/Rules/TagNameUniqueness.php diff --git a/app/Http/Requests/TagUpdateRequest.php b/app/Http/Requests/TagUpdateRequest.php index d27b73f5..475a743a 100644 --- a/app/Http/Requests/TagUpdateRequest.php +++ b/app/Http/Requests/TagUpdateRequest.php @@ -2,6 +2,7 @@ namespace App\Http\Requests; +use App\Rules\TagNameUniqueness; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; @@ -24,17 +25,13 @@ public function authorize() */ public function rules() { - $locale = app()->getLocale(); return [ 'type' => 'required', 'name' => [ 'required', 'string', - 'max:100', - Rule::unique('tags', 'name->'.$locale) - ->where('type', $this->input('type')) - ->ignore($this->input('id')) + new TagNameUniqueness, ], ]; } @@ -42,9 +39,6 @@ public function rules() public function messages() { return [ - 'name.required' => 'The tag name is required.', - 'name.unique' => 'The tag name provided already exists.', - 'name.max' => 'The tag name provided exceeds maximum length of 100 characters.', ]; } diff --git a/app/Rules/TagNameUniqueness.php b/app/Rules/TagNameUniqueness.php new file mode 100644 index 00000000..6ad67d7b --- /dev/null +++ b/app/Rules/TagNameUniqueness.php @@ -0,0 +1,75 @@ + + */ + protected $data = []; + + /** + * Run the validation rule. + * + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail + */ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $locale = app()->getLocale(); + $errors = []; + + if (is_string($value)) { + $value = preg_split('/\r\n|\r|\n/', $value); + } + + foreach ($value as $tag_entry) { + + if (strlen($tag_entry) > 100) { + $errors[] = 'The maximum characters allowed for a tag is 100. Please correct the :input entry.'; + } + + $current_tag = Route::current()->parameter('tag'); + + $uniqueness_query = Tag::whereRaw("LOWER(JSON_UNQUOTE(name->'$.{$locale}')) = ?", [strtolower($tag_entry)]) + ->where('type', $this->data['type']); + + if ($current_tag) { + $uniqueness_query->where('id', '!=', $current_tag->id); + } + + $exists = $uniqueness_query->exists(); + + if ($exists) { + $errors[] = "The {$tag_entry} tag already exists for the {$this->data['type']} type."; + } + } + + if (!empty($errors)) { + foreach ($errors as $error) { + $fail($error); + } + } + + } + + /** + * Set the data under validation. + * + * @param array $data + */ + public function setData(array $data): static + { + $this->data = $data; + + return $this; + } +} From 1ab74801b4ffaa3f805863b0639de8433fb3887a Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:24:26 -0500 Subject: [PATCH 03/13] Adds tag type `in` rule to to accept only allowed types for new tags --- app/Http/Requests/TagUpdateRequest.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/Http/Requests/TagUpdateRequest.php b/app/Http/Requests/TagUpdateRequest.php index 475a743a..e52fa873 100644 --- a/app/Http/Requests/TagUpdateRequest.php +++ b/app/Http/Requests/TagUpdateRequest.php @@ -3,11 +3,14 @@ namespace App\Http\Requests; use App\Rules\TagNameUniqueness; +use App\Student; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; class TagUpdateRequest extends FormRequest { + public $tag_types = []; + /** * Determine if the user is authorized to make this request. * @@ -25,11 +28,18 @@ public function authorize() */ public function rules() { + $this->tag_types[] = "App\\Profile"; + + foreach (Student::participatingSchools() as $shortname => $name) { + $this->tag_types[]= "App\\Student\\{$shortname}"; + } return [ - 'type' => 'required', - 'name' => [ + 'type' => [ 'required', + Rule::in($this->tag_types), + ], + 'name' => [ 'string', new TagNameUniqueness, ], @@ -38,7 +48,10 @@ public function rules() public function messages() { + $types_allowed = implode(', ', $this->tag_types); + return [ + 'type.in' => "The tag types allowed are: {$types_allowed}", ]; } From fa3f16477ed190799f921d4884621373cd0abcab Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Tue, 5 Nov 2024 07:48:26 -0600 Subject: [PATCH 04/13] Refactor custom rule EachIsUnique to implement validator as a generic validation rule --- app/Http/Requests/TagUpdateRequest.php | 16 ++++- app/Rules/EachIsUnique.php | 85 ++++++++++++++++++++++++++ app/Rules/TagNameUniqueness.php | 75 ----------------------- 3 files changed, 99 insertions(+), 77 deletions(-) create mode 100644 app/Rules/EachIsUnique.php delete mode 100644 app/Rules/TagNameUniqueness.php diff --git a/app/Http/Requests/TagUpdateRequest.php b/app/Http/Requests/TagUpdateRequest.php index e52fa873..7caa1c5e 100644 --- a/app/Http/Requests/TagUpdateRequest.php +++ b/app/Http/Requests/TagUpdateRequest.php @@ -2,7 +2,7 @@ namespace App\Http\Requests; -use App\Rules\TagNameUniqueness; +use App\Rules\EachIsUnique; use App\Student; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; @@ -29,6 +29,7 @@ public function authorize() public function rules() { $this->tag_types[] = "App\\Profile"; + $locale = app()->getLocale(); foreach (Student::participatingSchools() as $shortname => $name) { $this->tag_types[]= "App\\Student\\{$shortname}"; @@ -37,11 +38,14 @@ public function rules() return [ 'type' => [ 'required', + 'string', Rule::in($this->tag_types), ], 'name' => [ + 'required', 'string', - new TagNameUniqueness, + 'max:100', + new EachIsUnique('/\r\n|\r|\n/', 'tags', 'name->'.$locale, ['type', $this->input('type')], $this->route()->parameters['tag'] ?? null), ], ]; } @@ -55,4 +59,12 @@ public function messages() ]; } + + public function split($value) + { + if (is_string($value)) { + return preg_split($this->delimeter, $value); + } + } + } diff --git a/app/Rules/EachIsUnique.php b/app/Rules/EachIsUnique.php new file mode 100644 index 00000000..50b6b783 --- /dev/null +++ b/app/Rules/EachIsUnique.php @@ -0,0 +1,85 @@ + + */ + protected $data = []; + protected string $delimiter; + protected string $table; + protected string $column; + protected array $constraint; + protected $ignore; + + + public function __construct($delimiter, $table, $column, $constraint, $ignore) + { + $this->delimiter = $delimiter; + $this->table = $table; + $this->column = $column; + $this->constraint = $constraint; + $this->ignore = $ignore; + } + + /** + * Run the validation rule. + * + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail + */ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $values = $errors = []; + + $values = $this->split($value); + + foreach ($values as $value) { + + $rule = Rule::unique($this->table, $this->column) + ->where($this->constraint[0], $this->constraint[1]) + ->ignore($this->ignore); + + $valid = !validator([$attribute => $value], [$attribute => $rule])->fails(); + + if (!$valid) { + $errors[] = "The {$value} tag already exists for the {$this->constraint[1]} {$this->constraint[0]}."; + } + } + + if (!empty($errors)) { + foreach ($errors as $error) { + $fail($error); + } + } + } + + public function split($value) + { + if (is_string($value)) { + return preg_split($this->delimiter, $value); + } + } + + /** + * Set the data under validation. + * + * @param array $data + */ + public function setData(array $data): static + { + $this->data = $data; + + return $this; + } +} diff --git a/app/Rules/TagNameUniqueness.php b/app/Rules/TagNameUniqueness.php deleted file mode 100644 index 6ad67d7b..00000000 --- a/app/Rules/TagNameUniqueness.php +++ /dev/null @@ -1,75 +0,0 @@ - - */ - protected $data = []; - - /** - * Run the validation rule. - * - * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail - */ - public function validate(string $attribute, mixed $value, Closure $fail): void - { - $locale = app()->getLocale(); - $errors = []; - - if (is_string($value)) { - $value = preg_split('/\r\n|\r|\n/', $value); - } - - foreach ($value as $tag_entry) { - - if (strlen($tag_entry) > 100) { - $errors[] = 'The maximum characters allowed for a tag is 100. Please correct the :input entry.'; - } - - $current_tag = Route::current()->parameter('tag'); - - $uniqueness_query = Tag::whereRaw("LOWER(JSON_UNQUOTE(name->'$.{$locale}')) = ?", [strtolower($tag_entry)]) - ->where('type', $this->data['type']); - - if ($current_tag) { - $uniqueness_query->where('id', '!=', $current_tag->id); - } - - $exists = $uniqueness_query->exists(); - - if ($exists) { - $errors[] = "The {$tag_entry} tag already exists for the {$this->data['type']} type."; - } - } - - if (!empty($errors)) { - foreach ($errors as $error) { - $fail($error); - } - } - - } - - /** - * Set the data under validation. - * - * @param array $data - */ - public function setData(array $data): static - { - $this->data = $data; - - return $this; - } -} From 284e9d7818a7e43c968234511502e457bc2061f7 Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:23:42 -0600 Subject: [PATCH 05/13] Add doc block to custom rule constructor --- app/Rules/EachIsUnique.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/Rules/EachIsUnique.php b/app/Rules/EachIsUnique.php index 50b6b783..a7d0cb21 100644 --- a/app/Rules/EachIsUnique.php +++ b/app/Rules/EachIsUnique.php @@ -23,8 +23,17 @@ class EachIsUnique implements ValidationRule, DataAwareRule protected array $constraint; protected $ignore; - - public function __construct($delimiter, $table, $column, $constraint, $ignore) + /** + * Create a new validation rule instance. + * + * @param string $delimiter Delimiter to split the field under validation into individual elements. + * @param string $table Table where the uniqueness check will be performed. + * @param string $column Column in the table where uniqueness will be checked. + * @param array $constraint Constraint for the where method to apply when checking uniqueness in the format of ['column', 'value']. + * @param mixed $ignore Value to ignore in the uniqueness check if the request is an update (id by deafult). It can receive an array in the format of [value, p_key] + * if the primary key is different than the 'id'. + */ + public function __construct($delimiter, $table, $column, $constraint = null, $ignore = null) { $this->delimiter = $delimiter; $this->table = $table; From 09dc26d8ea2b9dffaf7f1560dfa17f74ebfa5614 Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:52:32 -0600 Subject: [PATCH 06/13] Remove unnecessary DataAwareRule implementation --- app/Rules/EachIsUnique.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/app/Rules/EachIsUnique.php b/app/Rules/EachIsUnique.php index a7d0cb21..1e6235a2 100644 --- a/app/Rules/EachIsUnique.php +++ b/app/Rules/EachIsUnique.php @@ -9,7 +9,7 @@ use Illuminate\Validation\Rule; use Spatie\Tags\Tag; -class EachIsUnique implements ValidationRule, DataAwareRule +class EachIsUnique implements ValidationRule { /** * All of the data under validation. @@ -80,15 +80,4 @@ public function split($value) } } - /** - * Set the data under validation. - * - * @param array $data - */ - public function setData(array $data): static - { - $this->data = $data; - - return $this; - } } From 3973c174486f142720b2955479acce367fed1d7e Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:55:14 -0600 Subject: [PATCH 07/13] Add second param to ignore() method for when p_key is other than id --- app/Http/Requests/TagUpdateRequest.php | 3 ++- app/Rules/EachIsUnique.php | 22 ++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/app/Http/Requests/TagUpdateRequest.php b/app/Http/Requests/TagUpdateRequest.php index 7caa1c5e..e3c8018f 100644 --- a/app/Http/Requests/TagUpdateRequest.php +++ b/app/Http/Requests/TagUpdateRequest.php @@ -45,7 +45,8 @@ public function rules() 'required', 'string', 'max:100', - new EachIsUnique('/\r\n|\r|\n/', 'tags', 'name->'.$locale, ['type', $this->input('type')], $this->route()->parameters['tag'] ?? null), + 'ignore_case', + new EachIsUnique('/\r\n|\r|\n/', 'tags', 'name->'.$locale, ['type', $this->input('type')], $this->route()->parameters['tag']), ], ]; } diff --git a/app/Rules/EachIsUnique.php b/app/Rules/EachIsUnique.php index 1e6235a2..271b98c3 100644 --- a/app/Rules/EachIsUnique.php +++ b/app/Rules/EachIsUnique.php @@ -53,11 +53,25 @@ public function validate(string $attribute, mixed $value, Closure $fail): void $values = $this->split($value); - foreach ($values as $value) { + $rule = Rule::unique($this->table, $this->column); + + if (isset($this->constraint)) { + $rule->where($this->constraint[0], $this->constraint[1]); + } - $rule = Rule::unique($this->table, $this->column) - ->where($this->constraint[0], $this->constraint[1]) - ->ignore($this->ignore); + if (isset($this->ignore)) { + if (is_array($this->ignore)) { + if (isset($this->ignore[1])) { // If the array has two values (value to ignore and p_key column name if p_key is other than the id) + $rule->ignore($this->ignore[0], $this->ignore[1]); // Ignore the value for the specified column + } else { + $rule->ignore($this->ignore[0]); // If there's only one value, ignore just the first (likely the ID) + } + } elseif (is_object($this->ignore) || is_string($this->ignore)) { // If ignore is a string or an object (likely the ID), ignore this value + $rule->ignore($this->ignore); + } + } + + foreach ($values as $value) { $valid = !validator([$attribute => $value], [$attribute => $rule])->fails(); From de0084c3f2e6922caed6d7cec3b4a1f293e82bab Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:56:23 -0600 Subject: [PATCH 08/13] Remove unnecessary split() method definition --- app/Http/Requests/TagUpdateRequest.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/Http/Requests/TagUpdateRequest.php b/app/Http/Requests/TagUpdateRequest.php index e3c8018f..e14b213c 100644 --- a/app/Http/Requests/TagUpdateRequest.php +++ b/app/Http/Requests/TagUpdateRequest.php @@ -60,12 +60,4 @@ public function messages() ]; } - - public function split($value) - { - if (is_string($value)) { - return preg_split($this->delimeter, $value); - } - } - } From ba84d96f57aacc400cab1b8ab720b633b3d65c35 Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:56:56 -0600 Subject: [PATCH 09/13] Add return type to split() method --- app/Rules/EachIsUnique.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Rules/EachIsUnique.php b/app/Rules/EachIsUnique.php index 271b98c3..fe18427d 100644 --- a/app/Rules/EachIsUnique.php +++ b/app/Rules/EachIsUnique.php @@ -5,6 +5,7 @@ use Closure; use Illuminate\Contracts\Validation\DataAwareRule; use Illuminate\Contracts\Validation\ValidationRule; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\Route; use Illuminate\Validation\Rule; use Spatie\Tags\Tag; @@ -87,7 +88,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void } } - public function split($value) + public function split($value) : array { if (is_string($value)) { return preg_split($this->delimiter, $value); From 549c9d616cb589ceca42d1ae9bde15ef8951cfc5 Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Thu, 14 Nov 2024 13:19:01 -0600 Subject: [PATCH 10/13] Refactor: Remove unnecessary references and inline the split() method call --- app/Http/Requests/TagUpdateRequest.php | 3 +-- app/Rules/EachIsUnique.php | 17 ++++------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/app/Http/Requests/TagUpdateRequest.php b/app/Http/Requests/TagUpdateRequest.php index e14b213c..c2043e7f 100644 --- a/app/Http/Requests/TagUpdateRequest.php +++ b/app/Http/Requests/TagUpdateRequest.php @@ -45,8 +45,7 @@ public function rules() 'required', 'string', 'max:100', - 'ignore_case', - new EachIsUnique('/\r\n|\r|\n/', 'tags', 'name->'.$locale, ['type', $this->input('type')], $this->route()->parameters['tag']), + new EachIsUnique('/\r\n|\r|\n/', 'tags', 'name->'.$locale, ['type', $this->input('type')], $this->route()->parameters['tag'] ?? null), ], ]; } diff --git a/app/Rules/EachIsUnique.php b/app/Rules/EachIsUnique.php index fe18427d..4e160122 100644 --- a/app/Rules/EachIsUnique.php +++ b/app/Rules/EachIsUnique.php @@ -3,12 +3,9 @@ namespace App\Rules; use Closure; -use Illuminate\Contracts\Validation\DataAwareRule; use Illuminate\Contracts\Validation\ValidationRule; -use Illuminate\Support\Arr; -use Illuminate\Support\Facades\Route; use Illuminate\Validation\Rule; -use Spatie\Tags\Tag; +use Illuminate\Support\Str; class EachIsUnique implements ValidationRule { @@ -52,9 +49,10 @@ public function validate(string $attribute, mixed $value, Closure $fail): void { $values = $errors = []; - $values = $this->split($value); + $values = is_string($value) ? preg_split($this->delimiter, $value) : []; - $rule = Rule::unique($this->table, $this->column); + $rule = Rule::unique($this->table, "lower($this->column)"); + // return $query->where('lower(email)', DB::raw('lower(?)'), $this->input('email')); if (isset($this->constraint)) { $rule->where($this->constraint[0], $this->constraint[1]); @@ -88,11 +86,4 @@ public function validate(string $attribute, mixed $value, Closure $fail): void } } - public function split($value) : array - { - if (is_string($value)) { - return preg_split($this->delimiter, $value); - } - } - } From 8fd296ed5abfd21e3d6c4b87bd52c454c88bcf25 Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:48:07 -0600 Subject: [PATCH 11/13] Refactor ignore method --- app/Http/Requests/TagUpdateRequest.php | 3 ++- app/Rules/EachIsUnique.php | 35 ++++++++++++++++---------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/app/Http/Requests/TagUpdateRequest.php b/app/Http/Requests/TagUpdateRequest.php index c2043e7f..752723d6 100644 --- a/app/Http/Requests/TagUpdateRequest.php +++ b/app/Http/Requests/TagUpdateRequest.php @@ -45,7 +45,8 @@ public function rules() 'required', 'string', 'max:100', - new EachIsUnique('/\r\n|\r|\n/', 'tags', 'name->'.$locale, ['type', $this->input('type')], $this->route()->parameters['tag'] ?? null), + (new EachIsUnique('/\r\n|\r|\n/', 'tags', 'name->'.$locale, ['type', $this->input('type')])) + ->ignore($this->route()->parameters['tag'] ?? null), ], ]; } diff --git a/app/Rules/EachIsUnique.php b/app/Rules/EachIsUnique.php index 4e160122..900f0238 100644 --- a/app/Rules/EachIsUnique.php +++ b/app/Rules/EachIsUnique.php @@ -19,7 +19,8 @@ class EachIsUnique implements ValidationRule protected string $table; protected string $column; protected array $constraint; - protected $ignore; + protected $ignore_id; + protected $ignore_column; /** * Create a new validation rule instance. @@ -31,13 +32,12 @@ class EachIsUnique implements ValidationRule * @param mixed $ignore Value to ignore in the uniqueness check if the request is an update (id by deafult). It can receive an array in the format of [value, p_key] * if the primary key is different than the 'id'. */ - public function __construct($delimiter, $table, $column, $constraint = null, $ignore = null) + public function __construct($delimiter, $table, $column, $constraint = null) { $this->delimiter = $delimiter; $this->table = $table; $this->column = $column; $this->constraint = $constraint; - $this->ignore = $ignore; } /** @@ -58,16 +58,17 @@ public function validate(string $attribute, mixed $value, Closure $fail): void $rule->where($this->constraint[0], $this->constraint[1]); } - if (isset($this->ignore)) { - if (is_array($this->ignore)) { - if (isset($this->ignore[1])) { // If the array has two values (value to ignore and p_key column name if p_key is other than the id) - $rule->ignore($this->ignore[0], $this->ignore[1]); // Ignore the value for the specified column - } else { - $rule->ignore($this->ignore[0]); // If there's only one value, ignore just the first (likely the ID) - } - } elseif (is_object($this->ignore) || is_string($this->ignore)) { // If ignore is a string or an object (likely the ID), ignore this value - $rule->ignore($this->ignore); - } + if (isset($this->ignore_id)) { + $rule->ignore($this->ignore_id, $this->ignore_column); + // if (is_array($this->ignore)) { + // if (isset($this->ignore[1])) { // If the array has two values (value to ignore and p_key column name if p_key is other than the id) + // $rule->ignore($this->ignore[0], $this->ignore[1]); // Ignore the value for the specified column + // } else { + // $rule->ignore($this->ignore[0]); // If there's only one value, ignore just the first (likely the ID) + // } + // } elseif (is_object($this->ignore) || is_string($this->ignore)) { // If ignore is a string or an object (likely the ID), ignore this value + // $rule->ignore($this->ignore); + // } } foreach ($values as $value) { @@ -86,4 +87,12 @@ public function validate(string $attribute, mixed $value, Closure $fail): void } } + public function ignore($id, $idColumn = null) + { + $this->ignore_id = $id; + $this->ignore_column = $idColumn; + + return $this; + } + } From 2ace1d9a0254c8b4707abc675e03bcda41aefb84 Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:25:36 -0600 Subject: [PATCH 12/13] Add setter method for ignore values for EachIsUnique class --- app/Rules/EachIsUnique.php | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/app/Rules/EachIsUnique.php b/app/Rules/EachIsUnique.php index 900f0238..038f2759 100644 --- a/app/Rules/EachIsUnique.php +++ b/app/Rules/EachIsUnique.php @@ -9,12 +9,6 @@ class EachIsUnique implements ValidationRule { - /** - * All of the data under validation. - * - * @var array - */ - protected $data = []; protected string $delimiter; protected string $table; protected string $column; @@ -29,8 +23,6 @@ class EachIsUnique implements ValidationRule * @param string $table Table where the uniqueness check will be performed. * @param string $column Column in the table where uniqueness will be checked. * @param array $constraint Constraint for the where method to apply when checking uniqueness in the format of ['column', 'value']. - * @param mixed $ignore Value to ignore in the uniqueness check if the request is an update (id by deafult). It can receive an array in the format of [value, p_key] - * if the primary key is different than the 'id'. */ public function __construct($delimiter, $table, $column, $constraint = null) { @@ -51,8 +43,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void $values = is_string($value) ? preg_split($this->delimiter, $value) : []; - $rule = Rule::unique($this->table, "lower($this->column)"); - // return $query->where('lower(email)', DB::raw('lower(?)'), $this->input('email')); + $rule = Rule::unique($this->table, $this->column); if (isset($this->constraint)) { $rule->where($this->constraint[0], $this->constraint[1]); @@ -60,19 +51,9 @@ public function validate(string $attribute, mixed $value, Closure $fail): void if (isset($this->ignore_id)) { $rule->ignore($this->ignore_id, $this->ignore_column); - // if (is_array($this->ignore)) { - // if (isset($this->ignore[1])) { // If the array has two values (value to ignore and p_key column name if p_key is other than the id) - // $rule->ignore($this->ignore[0], $this->ignore[1]); // Ignore the value for the specified column - // } else { - // $rule->ignore($this->ignore[0]); // If there's only one value, ignore just the first (likely the ID) - // } - // } elseif (is_object($this->ignore) || is_string($this->ignore)) { // If ignore is a string or an object (likely the ID), ignore this value - // $rule->ignore($this->ignore); - // } } foreach ($values as $value) { - $valid = !validator([$attribute => $value], [$attribute => $rule])->fails(); if (!$valid) { @@ -80,13 +61,17 @@ public function validate(string $attribute, mixed $value, Closure $fail): void } } - if (!empty($errors)) { - foreach ($errors as $error) { - $fail($error); - } + foreach ($errors as $error) { + $fail($error); } } + /** + * Set values to be excluded or ignored by the unique checks. + * + * @param mixed $id - the ID or model instance of the record to ignore + * @param string|null $id_column - The column name of the primary key, if it's other than the ID + */ public function ignore($id, $idColumn = null) { $this->ignore_id = $id; From 48412c2ad0e67a3ed66c9e3c4bcc63d6be2b46e5 Mon Sep 17 00:00:00 2001 From: Betsy Castro <5490820+betsyecastro@users.noreply.github.com> Date: Wed, 5 Mar 2025 15:16:06 -0600 Subject: [PATCH 13/13] Fixes psalm errors --- app/Rules/EachIsUnique.php | 44 +++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/app/Rules/EachIsUnique.php b/app/Rules/EachIsUnique.php index 038f2759..a48d6924 100644 --- a/app/Rules/EachIsUnique.php +++ b/app/Rules/EachIsUnique.php @@ -9,20 +9,44 @@ class EachIsUnique implements ValidationRule { - protected string $delimiter; - protected string $table; - protected string $column; - protected array $constraint; + /** Delimiter to split the field under validation into individual elements. + * @var string + * */ + protected $delimiter; + + /** Table where the uniqueness check will be performed. + * @var string + * */ + protected $table; + + /** Column in the table where uniqueness will be checked. + * @var string + * */ + protected $column; + + /** Constraint for the where method to apply when checking uniqueness in the format of ['column', 'value']. + * @var array|null + * */ + protected $constraint; + + /** The ID or model instance of the record to ignore. + * @var mixed|null + * */ protected $ignore_id; + + /** The column name of the primary key, if it's other than the ID. + * @var string|null + * */ protected $ignore_column; + /** * Create a new validation rule instance. * - * @param string $delimiter Delimiter to split the field under validation into individual elements. - * @param string $table Table where the uniqueness check will be performed. - * @param string $column Column in the table where uniqueness will be checked. - * @param array $constraint Constraint for the where method to apply when checking uniqueness in the format of ['column', 'value']. + * @param string $delimiter + * @param string $table + * @param string $column + * @param array $constraint */ public function __construct($delimiter, $table, $column, $constraint = null) { @@ -69,8 +93,8 @@ public function validate(string $attribute, mixed $value, Closure $fail): void /** * Set values to be excluded or ignored by the unique checks. * - * @param mixed $id - the ID or model instance of the record to ignore - * @param string|null $id_column - The column name of the primary key, if it's other than the ID + * @param mixed|null $id + * @param string|null $id_column */ public function ignore($id, $idColumn = null) {