diff --git a/Controllers/AbstractRelatedEntityController.php b/Controllers/AbstractRelatedEntityController.php index 046824e..887db7b 100644 --- a/Controllers/AbstractRelatedEntityController.php +++ b/Controllers/AbstractRelatedEntityController.php @@ -80,6 +80,7 @@ protected function postSync(BaseModel $parent, Collection $children) * Override this method to provide custom pivot validation rules. * * @param null $entityId + * @param array $requestEntity * @return array */ protected function getValidationRules($entityId = null, array $requestEntity = []) diff --git a/Controllers/ChildEntityController.php b/Controllers/ChildEntityController.php index 2b691db..52bd8c9 100644 --- a/Controllers/ChildEntityController.php +++ b/Controllers/ChildEntityController.php @@ -311,6 +311,7 @@ public function deleteMany(Request $request, $id) /** * @param null $entityId + * @param array $requestEntity * @return array */ protected function getValidationRules($entityId = null, array $requestEntity = []) diff --git a/Controllers/EntityController.php b/Controllers/EntityController.php index 3dd49ec..f158659 100644 --- a/Controllers/EntityController.php +++ b/Controllers/EntityController.php @@ -523,6 +523,8 @@ protected function getModel() } /** + * @param null $entityId + * @param array $requestEntity * @return array */ protected function getValidationRules($entityKey = null, array $requestEntity = []) diff --git a/Model/Model/BaseModel.php b/Model/Model/BaseModel.php index 17eaf4d..297eda2 100644 --- a/Model/Model/BaseModel.php +++ b/Model/Model/BaseModel.php @@ -49,6 +49,7 @@ abstract class BaseModel extends Model /** * @param null $entityId + * @param array $requestEntity * @return array */ public static function getValidationRules($entityId = null, array $requestEntity = []) diff --git a/Providers/AppServiceProvider.php b/Providers/AppServiceProvider.php index 879e739..09035a3 100644 --- a/Providers/AppServiceProvider.php +++ b/Providers/AppServiceProvider.php @@ -33,6 +33,7 @@ public function boot() 'decoded_json' => 'The :attribute must be an object or an array', 'alpha_dash_space' => 'The :attribute may only contain letters, numbers, dashes and spaces.', 'supported_region' => 'The :attribute must be a supported region. Supported region codes are ('.implode(', ', array_pluck(config('regions.supported'), 'code')).')', + 'exists_morphed' => 'The :attribute must exists in corresponding table', ]; $this->app->extend('validator', function (Factory $validator) use ($spiraMessages) { diff --git a/Validation/SpiraValidator.php b/Validation/SpiraValidator.php index 9788827..1f8e388 100644 --- a/Validation/SpiraValidator.php +++ b/Validation/SpiraValidator.php @@ -17,6 +17,32 @@ class SpiraValidator extends Validator { + /** + * Rule for validation existance of morphed item + * Parameters are: column containing class or class name, column if primary key is not used, where conditions. + */ + public function validateExistsMorphed($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'exists_morphed'); + + if (! Uuid::isValid($value)) { + return false; + } + + $class = Arr::get($this->data, $parameters[0], $parameters[0]); + if (empty($class) || ! class_exists($class)) { + return false; + } + + $column = Arr::get($parameters, 1) ?: call_user_func_array("$class::getPrimaryKey", []); + $table = call_user_func_array("$class::getTableName", []); + + $parameters[0] = $table; + $parameters[1] = $column; + + return $this->validateExists($attribute, $value, $parameters); + } + public function validateDecimal($attribute, $value, $parameters) { return is_float($value) || is_int($value); diff --git a/composer.json b/composer.json index fba0b43..770df4b 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,8 @@ "barryvdh/laravel-ide-helper": "dev-master" }, "autoload": { - "psr-4": { "Spira\\Core\\": "" } + "psr-4": { "Spira\\Core\\": "" }, + "classmap": ["database/"] }, "config": { "preferred-install": "dist" diff --git a/tests/ValidatorTest.php b/tests/ValidatorTest.php index c18ffa1..115ffc3 100644 --- a/tests/ValidatorTest.php +++ b/tests/ValidatorTest.php @@ -12,6 +12,8 @@ use Illuminate\Validation\Factory; use Rhumsaa\Uuid\Uuid; +use Spira\Core\Model\Test\SecondTestEntity; +use Spira\Core\Model\Test\TestEntity; use Spira\Core\Validation\SpiraValidator; class ValidatorTest extends TestCase @@ -35,6 +37,37 @@ public function testSpiraValidator() $this->assertInstanceOf(SpiraValidator::class, $validation); } + /** + * @dataProvider dataExistsMorphedValidation + */ + public function testExistsMorphedValidation($rule, $passes = true) + { + $item = $this->getFactory(TestEntity::class)->customize(['integer' => 123])->create(); + $validator = $this->validator->make( + ['item_id' => $item->entity_id, 'item_type' => TestEntity::class], + ['item_id' => $rule] + ); + + $this->assertEquals($passes, $validator->passes()); + + if (! $passes) { + $this->assertEquals('The item id must exists in corresponding table', $validator->messages()->get('item_id')[0]); + } + } + + public function dataExistsMorphedValidation() + { + return [ + ['exists_morphed:item_type', true], + ['exists_morphed:item_type,entity_id', true], + ['exists_morphed:item_type,hash', false], + ['exists_morphed:item_type,,integer,123', true], + ['exists_morphed:item_type,entity_id,integer,321', false], + ['exists_morphed:'.TestEntity::class, true], + ['exists_morphed:'.SecondTestEntity::class, false], + ]; + } + public function testPassingDecimalValidation() { $data = ['decimal' => 12.042];