From 81908398231a8d9f08f7557ea4009b0ae76d50d6 Mon Sep 17 00:00:00 2001 From: James Collins Date: Mon, 8 May 2023 10:40:04 +1000 Subject: [PATCH] added new rules --- app/Providers/AppServiceProvider.php | 16 +++++ app/Rules/RequiredIfAny.php | 71 ++++++++++++++++++++++ app/Rules/Uniqueish.php | 90 ++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 app/Rules/RequiredIfAny.php create mode 100644 app/Rules/Uniqueish.php diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index ea06d11..3284a8c 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,11 +2,15 @@ namespace App\Providers; +use App\Rules\RequiredIfAny; +use App\Rules\Uniqueish; use Illuminate\Support\ServiceProvider; use Exception; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; use PDOException; +use Illuminate\Validation\Rule; +use Illuminate\Support\Facades\Validator; class AppServiceProvider extends ServiceProvider { @@ -31,5 +35,17 @@ class AppServiceProvider extends ServiceProvider $public = config("filesystems.disks.{$diskName}.public", false); return $public; }); + + Validator::extend('uniqueish', function ($attribute, $value, $parameters, $validator) { + $table = $parameters[0]; + $column = isset($parameters[1]) === true ? $parameters[1] : null; + + $rule = new Uniqueish($table, $column); + return $rule->passes($attribute, $value); + }); + + Rule::macro('requiredIfAny', function ($table, ...$columns) { + return new RequiredIfAny($table, ...$columns); + }); } } diff --git a/app/Rules/RequiredIfAny.php b/app/Rules/RequiredIfAny.php new file mode 100644 index 0000000..52dd095 --- /dev/null +++ b/app/Rules/RequiredIfAny.php @@ -0,0 +1,71 @@ +table = $table; + $this->columns = $columns; + } + + /** + * Determine if the validation rule passes. + * + * @param mixed $attribute Not used. + * @param mixed $value The value to compare. + * @return boolean + */ + public function passes(mixed $attribute, mixed $value) + { + foreach ($this->columns as $column) { + $result = DB::table($this->table) + ->where($column, '!=', '') + ->where($column, '!=', null) + ->where($attribute, '=', '') + ->exists(); + + if ($result !== null) { + return false; + } + } + + return true; + } + + /** + * Get the validation error message. + * + * @return string + */ + public function message() + { + return 'The :attribute field is required if any of the following fields are not empty: ' . implode(', ', $this->columns); + } +} diff --git a/app/Rules/Uniqueish.php b/app/Rules/Uniqueish.php new file mode 100644 index 0000000..9cdd660 --- /dev/null +++ b/app/Rules/Uniqueish.php @@ -0,0 +1,90 @@ +table = $table; + $this->column = $column; + } + + /** + * Set the ID of the record to be ignored. + * + * @param integer $id + * @return $this + */ + public function ignore($id) + { + $this->ignoreId = $id; + return $this; + } + + /** + * Determine if the validation rule passes. + * + * @param mixed $attribute Not used. + * @param mixed $value The value to compare. + * @return boolean + */ + public function passes(mixed $attribute, mixed $value) + { + $columnName = ($this->column ?? $attribute); + $similarValue = preg_replace('/[^A-Za-z]/', '', strtolower($value)); + + $query = DB::table($this->table) + ->whereRaw('LOWER(REGEXP_REPLACE(' . $columnName . ', \'[^A-Za-z]\', \'\')) = ?', [$similarValue]); + + if ($this->ignoreId !== null) { + $query->where('id', '<>', $this->ignoreId); + } + + $result = $query->first(); + + return $result === null; + } + + /** + * Get the validation error message. + * + * @return string + */ + public function message() + { + return 'The :attribute is similar to an existing value in the database.'; + } +}