Tagged union FormRequest Rule Validation #54880
Unanswered
brianferri
asked this question in
Ideas
Replies: 2 comments
-
Update on potential implementation: <?php
namespace App\Http\Requests;
use App\Util\OpenAPIGenerator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use OpenAPI\Client\Model\ModelServices;
use OpenAPI\Client\Model\Params;
class StoreWorkflowServices extends FormRequest
{
public static function list(): array
{
$modelServiceValues = array_map(fn($case) => $case->value, ModelServices::cases());
$classCases = [];
foreach ($modelServiceValues as $modelService) {
$paramsRules = [];
$modelClass = '\\OpenAPI\\Client\\Model\\' . $modelService . 'Params';
/** @var Params */
$params = new $modelClass();
$formats = $params->openAPIFormats();
foreach ($params->openAPITypes() as $key => $type) {
$paramsRules[$key] = match ($key) {
Params::DISCRIMINATOR => ['required', Rule::in($params->getServiceAllowableValues())],
default => OpenAPIGenerator::mapTypeToRule($type, $formats[$key])
};
}
array_push($classCases, $paramsRules);
}
return $classCases;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
Params::DISCRIMINATOR => ['required', Rule::enum(\OpenAPI\Client\Model\ModelServices::class)],
'params' => ['required', Rule::in($this::list())] // <-- This won't work for obvious reasons
];
}
} Currently |
Beta Was this translation helpful? Give feedback.
0 replies
-
Prototype <?php
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Validator;
class OneOf implements ValidationRule
{
/** @var ValidationRule[] */
private array $rules;
/** @param ValidationRule[] $rules */
public function __construct(array $rules)
{
$this->rules = $rules;
}
/**
* Run the validation rule.
*
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (!is_array($value)) {
$fail("The :attribute field must be an array.");
return;
}
foreach ($this->rules as $ruleSet) {
$validator = Validator::make($value, $ruleSet);
// At least one type is valid, so pass validation
if ($validator->passes()) return;
}
$fail("The :attribute field does not match any of the allowed structures.");
}
} Which in the context of my use case: // ...
public function rules(): array
{
return [
Params::DISCRIMINATOR => ['required', Rule::enum(\OpenAPI\Client\Model\ModelServices::class)],
'params' => ['required', new OneOf($this::list())]
];
}
// ... |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Track: #54946
As the title suggests, the feature would implement
Tagged Unions
in a form request context, a possible way would be to follow the OpenAPI Specification for Discriminator Objectscurrently, the way I've found to do something ""Similar"", but Isn't right, is the following:
Using the PHPNextGen generator from OpenAPIGenerator
Example: OpenAPITools/openapi-generator#20343
Untitled-1.json
https://dpaste.org/k2Qoe
openapitools.config.yml
Beta Was this translation helpful? Give feedback.
All reactions