diff --git a/system/HTTP/FormRequest.php b/system/HTTP/FormRequest.php index c9c26ec29d16..dc736b945187 100644 --- a/system/HTTP/FormRequest.php +++ b/system/HTTP/FormRequest.php @@ -178,7 +178,7 @@ protected function failedAuthorization(): ResponseInterface * * @return array */ - public function validated(): array + public function getValidated(): array { return $this->validatedData; } @@ -186,41 +186,11 @@ public function validated(): array /** * Returns the validated data as a typed input object. */ - public function validatedInput(): ValidatedInput + public function getValidatedInput(): ValidatedInput { return service('inputdatafactory')->createValidated($this->validatedData); } - /** - * Returns a single validated field value by name, or the default value - * if the field is not present in the validated data. - * - * Supports dot-array syntax for nested validated data. - */ - public function getValidated(string $key, mixed $default = null): mixed - { - helper('array'); - - if (! dot_array_has($key, $this->validatedData)) { - return $default; - } - - return dot_array_search($key, $this->validatedData); - } - - /** - * Returns true when the named field exists in the validated data, even if - * its value is null. - * - * Supports dot-array syntax for nested validated data. - */ - public function hasValidated(string $key): bool - { - helper('array'); - - return dot_array_has($key, $this->validatedData); - } - /** * Returns the data to be validated. * diff --git a/tests/_support/Controllers/FormRequestController.php b/tests/_support/Controllers/FormRequestController.php index 58859e6e0499..bdc3670a8c6a 100644 --- a/tests/_support/Controllers/FormRequestController.php +++ b/tests/_support/Controllers/FormRequestController.php @@ -28,7 +28,7 @@ class FormRequestController extends Controller */ public function index(string $id, ValidPostFormRequest $request, string $format = 'json'): string { - return json_encode(['id' => $id, 'format' => $format, 'data' => $request->validated()]); + return json_encode(['id' => $id, 'format' => $format, 'data' => $request->getValidated()]); } /** @@ -36,7 +36,7 @@ public function index(string $id, ValidPostFormRequest $request, string $format */ public function store(ValidPostFormRequest $request): string { - return json_encode($request->validated()); + return json_encode($request->getValidated()); } /** @@ -44,7 +44,7 @@ public function store(ValidPostFormRequest $request): string */ public function update(string $id, ValidPostFormRequest $request): string { - return json_encode(['id' => $id, 'data' => $request->validated()]); + return json_encode(['id' => $id, 'data' => $request->getValidated()]); } /** @@ -61,7 +61,7 @@ public function show(string $id): string */ public function search(ValidPostFormRequest $request, string ...$tags): string { - return json_encode(['tags' => $tags, 'data' => $request->validated()]); + return json_encode(['tags' => $tags, 'data' => $request->getValidated()]); } /** diff --git a/tests/system/HTTP/FormRequestTest.php b/tests/system/HTTP/FormRequestTest.php index ee6af1a28e19..1378a69f0eaa 100644 --- a/tests/system/HTTP/FormRequestTest.php +++ b/tests/system/HTTP/FormRequestTest.php @@ -146,11 +146,11 @@ public function rules(): array }; } - public function testValidatedReturnsEmptyArrayBeforeResolution(): void + public function testGetValidatedReturnsEmptyArrayBeforeResolution(): void { $formRequest = $this->makeFormRequest($this->makeRequest()); - $this->assertSame([], $formRequest->validated()); + $this->assertSame([], $formRequest->getValidated()); } // ------------------------------------------------------------------------- @@ -167,11 +167,11 @@ public function testResolveRequestPassesWithValidData(): void $this->assertSame( ['title' => 'Hello World', 'body' => 'Some body text'], - $formRequest->validated(), + $formRequest->getValidated(), ); } - public function testValidatedReturnsOnlyFieldsCoveredByRules(): void + public function testGetValidatedReturnsOnlyFieldsCoveredByRules(): void { service('superglobals')->setPost('title', 'Hello World'); service('superglobals')->setPost('body', 'Some body text'); @@ -180,81 +180,14 @@ public function testValidatedReturnsOnlyFieldsCoveredByRules(): void $formRequest = $this->makeFormRequest($this->makeRequest()); $formRequest->resolveRequest(); - $validated = $formRequest->validated(); + $validated = $formRequest->getValidated(); $this->assertArrayHasKey('title', $validated); $this->assertArrayHasKey('body', $validated); $this->assertArrayNotHasKey('extra_field', $validated); } - // ------------------------------------------------------------------------- - // Explicit access to validated fields - // ------------------------------------------------------------------------- - - public function testGetValidatedReturnsValidatedFieldValue(): void - { - service('superglobals')->setPost('title', 'Hello World'); - service('superglobals')->setPost('body', 'Some body text'); - - $formRequest = new ValidPostFormRequest($this->makeRequest()); - $formRequest->resolveRequest(); - - $this->assertSame('Hello World', $formRequest->getValidated('title')); - $this->assertSame('Some body text', $formRequest->getValidated('body')); - } - - public function testGetValidatedReturnsNullForMissingField(): void - { - service('superglobals')->setPost('title', 'Hello World'); - service('superglobals')->setPost('body', 'Some body text'); - - $formRequest = new ValidPostFormRequest($this->makeRequest()); - $formRequest->resolveRequest(); - - $this->assertNull($formRequest->getValidated('nonexistent')); - } - - public function testGetValidatedReturnsDefaultForMissingField(): void - { - service('superglobals')->setPost('title', 'Hello World'); - service('superglobals')->setPost('body', 'Some body text'); - - $formRequest = new ValidPostFormRequest($this->makeRequest()); - $formRequest->resolveRequest(); - - $this->assertSame('fallback', $formRequest->getValidated('nonexistent', 'fallback')); - } - - public function testGetValidatedReturnsNullBeforeValidationRuns(): void - { - $formRequest = new ValidPostFormRequest($this->makeRequest()); - - $this->assertNull($formRequest->getValidated('title')); - } - - public function testHasValidatedReturnsTrueForValidatedField(): void - { - service('superglobals')->setPost('title', 'Hello World'); - service('superglobals')->setPost('body', 'Some body text'); - - $formRequest = new ValidPostFormRequest($this->makeRequest()); - $formRequest->resolveRequest(); - - $this->assertTrue($formRequest->hasValidated('title')); - } - - public function testHasValidatedReturnsFalseForMissingField(): void - { - service('superglobals')->setPost('title', 'Hello World'); - service('superglobals')->setPost('body', 'Some body text'); - - $formRequest = new ValidPostFormRequest($this->makeRequest()); - $formRequest->resolveRequest(); - - $this->assertFalse($formRequest->hasValidated('nonexistent')); - } - - public function testGetValidatedAndHasValidatedSupportDotSyntax(): void + public function testGetValidatedReturnsNestedValidatedData(): void { service('superglobals')->setPost('post', [ 'title' => 'Hello World', @@ -275,12 +208,20 @@ public function rules(): array $formRequest->resolveRequest(); - $this->assertSame('Hello World', $formRequest->getValidated('post.title')); - $this->assertSame('hello-world', $formRequest->getValidated('post.meta.slug')); - $this->assertTrue($formRequest->hasValidated('post.meta.slug')); + $this->assertSame( + [ + 'post' => [ + 'title' => 'Hello World', + 'meta' => [ + 'slug' => 'hello-world', + ], + ], + ], + $formRequest->getValidated(), + ); } - public function testHasValidatedReturnsTrueForNullValidatedField(): void + public function testGetValidatedReturnsNullValidatedField(): void { service('superglobals')->setServer('CONTENT_TYPE', 'application/json'); @@ -293,13 +234,10 @@ public function rules(): array $formRequest->resolveRequest(); - $this->assertSame(['note' => null], $formRequest->validated()); - $this->assertNull($formRequest->getValidated('note')); - $this->assertNull($formRequest->getValidated('note', 'fallback')); - $this->assertTrue($formRequest->hasValidated('note')); + $this->assertSame(['note' => null], $formRequest->getValidated()); } - public function testValidatedInputReturnsValidatedInputObject(): void + public function testGetValidatedInputReturnsValidatedInputObject(): void { service('superglobals')->setPost('title', 'Hello World'); service('superglobals')->setPost('body', 'Some body text'); @@ -307,7 +245,7 @@ public function testValidatedInputReturnsValidatedInputObject(): void $formRequest = new ValidPostFormRequest($this->makeRequest()); $formRequest->resolveRequest(); - $input = $formRequest->validatedInput(); + $input = $formRequest->getValidatedInput(); $this->assertInstanceOf(ValidatedInput::class, $input); $this->assertSame('Hello World', $input->get('title')); @@ -343,7 +281,7 @@ protected function prepareForValidation(array $data): array $this->assertNotInstanceOf(ResponseInterface::class, $formRequest->resolveRequest()); $this->assertTrue($formRequest::$prepareCalled); - $this->assertSame('Hi extended', $formRequest->validated()['title']); + $this->assertSame('Hi extended', $formRequest->getValidated()['title']); } // ------------------------------------------------------------------------- @@ -499,7 +437,7 @@ protected function validationData(): array $this->assertNotInstanceOf(ResponseInterface::class, $formRequest->resolveRequest()); - $this->assertSame('Injected Title', $formRequest->validated()['title']); + $this->assertSame('Injected Title', $formRequest->getValidated()['title']); } public function testCustomFailedValidationIsRespected(): void @@ -708,7 +646,7 @@ public function testClosureRouteWithFormRequestIsInjected(): void $routes = service('routes'); $routes->setAutoRoute(false); - $routes->add('closure/(:segment)', static fn (string $id, ValidPostFormRequest $request): string => json_encode(['id' => $id, 'data' => $request->validated()])); + $routes->add('closure/(:segment)', static fn (string $id, ValidPostFormRequest $request): string => json_encode(['id' => $id, 'data' => $request->getValidated()])); $router = service('router', $routes, service('incomingrequest')); Services::injectMock('router', $router); @@ -781,7 +719,7 @@ public function testUnauthorizedFormRequestReturns403(): void } // ------------------------------------------------------------------------- - // Integration: validated() only returns fields declared in rules() + // Integration: getValidated() only returns fields declared in rules() // ------------------------------------------------------------------------- #[RunInSeparateProcess] diff --git a/user_guide_src/source/incoming/form_requests.rst b/user_guide_src/source/incoming/form_requests.rst index 79aa1522bfde..65f1f7363696 100644 --- a/user_guide_src/source/incoming/form_requests.rst +++ b/user_guide_src/source/incoming/form_requests.rst @@ -49,16 +49,16 @@ JSON/AJAX requests - the method body is never reached. Accessing Validated Data ************************ -``validated()`` returns an array containing only the fields that were declared +``getValidated()`` returns an array containing only the fields that were declared in ``rules()``. Fields submitted by the client that are not covered by a rule are silently discarded, protecting against mass-assignment. .. literalinclude:: form_requests/009.php :lines: 2- -Use ``getValidated()`` to read a single validated field and ``hasValidated()`` -to check whether a validated key exists, including keys whose value is -``null``. Both methods support dot-array syntax for nested validated data: +Use ``getValidatedInput()`` when you want to read a single validated field or +check whether a validated key exists, including keys whose value is ``null``. +The input object supports dot-array syntax for nested validated data: .. literalinclude:: form_requests/014.php :lines: 2- @@ -66,9 +66,9 @@ to check whether a validated key exists, including keys whose value is Typed Validated Input ===================== -``validatedInput()`` returns the same validated data as a typed input object. -This keeps the array-based APIs unchanged while making common controller values -easier to read after validation has succeeded. +``getValidatedInput()`` returns the same validated data as a typed input object. +This complements ``getValidated()`` by making common controller values easier +to read after validation has succeeded. After the FormRequest has been validated, read the successful values in the controller: @@ -83,7 +83,7 @@ for the full behavior of the typed input methods. Accessing Other Request Data ============================ -For anything not covered by ``validated()`` - uploaded files, request headers, +For anything not covered by ``getValidated()`` - uploaded files, request headers, the client IP address, raw input, and so on - use ``$this->request`` as usual. It is the same :doc:`IncomingRequest ` instance that the FormRequest uses internally: @@ -171,7 +171,7 @@ normalized phone numbers, or trimmed strings. :lines: 2- .. note:: ``old()`` returns the original submitted input, not the normalized - values. Use ``validated()`` to access the processed data after a successful + values. Use ``getValidated()`` to access the processed data after a successful request. If you need ``old()`` to reflect normalized values, see :ref:`form-request-flash-normalized`. @@ -245,8 +245,8 @@ whose type extends ``FormRequest``: rules are applied. #. ``run()`` executes the validation rules. If it fails, ``failedValidation()`` is called, and its response is returned to the client. -#. The validated data is stored internally and available via ``validated()``, - ``validatedInput()``, ``getValidated()``, and ``hasValidated()``. +#. The validated data is stored internally and available via ``getValidated()`` + and ``getValidatedInput()``. #. The resolved FormRequest object is injected into the controller method or closure. diff --git a/user_guide_src/source/incoming/form_requests/002.php b/user_guide_src/source/incoming/form_requests/002.php index 8f3a2115bc76..0e9ba8baba2b 100644 --- a/user_guide_src/source/incoming/form_requests/002.php +++ b/user_guide_src/source/incoming/form_requests/002.php @@ -8,8 +8,8 @@ class Posts extends BaseController { public function store(StorePostRequest $request): string { - // $request->validated() returns only the fields declared in rules(). - $data = $request->validated(); + // $request->getValidated() returns only the fields declared in rules(). + $data = $request->getValidated(); // save to database diff --git a/user_guide_src/source/incoming/form_requests/003.php b/user_guide_src/source/incoming/form_requests/003.php index e653af09f526..3d7015c865bd 100644 --- a/user_guide_src/source/incoming/form_requests/003.php +++ b/user_guide_src/source/incoming/form_requests/003.php @@ -9,7 +9,7 @@ class Posts extends BaseController // Route parameters come first; FormRequest follows. public function update(int $id, UpdatePostRequest $request): string { - $data = $request->validated(); + $data = $request->getValidated(); // update post $id with $data diff --git a/user_guide_src/source/incoming/form_requests/009.php b/user_guide_src/source/incoming/form_requests/009.php index f6feedacb799..6df129fb7705 100644 --- a/user_guide_src/source/incoming/form_requests/009.php +++ b/user_guide_src/source/incoming/form_requests/009.php @@ -1,4 +1,4 @@ validated(); +$data = $request->getValidated(); // ['title' => 'My post title', 'body' => 'Body text'] diff --git a/user_guide_src/source/incoming/form_requests/010.php b/user_guide_src/source/incoming/form_requests/010.php index 0da8f97e9d3e..7fd1bf365507 100644 --- a/user_guide_src/source/incoming/form_requests/010.php +++ b/user_guide_src/source/incoming/form_requests/010.php @@ -8,7 +8,7 @@ class Posts extends BaseController { public function store(StorePostRequest $request): string { - $data = $request->validated(); + $data = $request->getValidated(); $files = $this->request->getFiles(); // ... diff --git a/user_guide_src/source/incoming/form_requests/011.php b/user_guide_src/source/incoming/form_requests/011.php index 4d700dd5ad86..b482c5f245f5 100644 --- a/user_guide_src/source/incoming/form_requests/011.php +++ b/user_guide_src/source/incoming/form_requests/011.php @@ -7,7 +7,7 @@ // FormRequest only - no route parameters. $routes->post('posts', static function (StorePostRequest $request): string { - $data = $request->validated(); + $data = $request->getValidated(); // save to database @@ -16,7 +16,7 @@ // Route parameter before a FormRequest - same convention as controller methods. $routes->post('posts/(:num)', static function (int $id, UpdatePostRequest $request): string { - $data = $request->validated(); + $data = $request->getValidated(); // update post $id with $data diff --git a/user_guide_src/source/incoming/form_requests/012.php b/user_guide_src/source/incoming/form_requests/012.php index ed3cb835414b..42732295dd77 100644 --- a/user_guide_src/source/incoming/form_requests/012.php +++ b/user_guide_src/source/incoming/form_requests/012.php @@ -28,7 +28,7 @@ public function _remap(string $method, string ...$params): mixed private function update(UpdatePostRequest $request, string $id): string { - $data = $request->validated(); + $data = $request->getValidated(); // update post $id with $data diff --git a/user_guide_src/source/incoming/form_requests/014.php b/user_guide_src/source/incoming/form_requests/014.php index c3bd3c034649..ca2a733e563a 100644 --- a/user_guide_src/source/incoming/form_requests/014.php +++ b/user_guide_src/source/incoming/form_requests/014.php @@ -1,8 +1,10 @@ getValidated('title'); -$slug = $request->getValidated('post.meta.slug', 'draft'); +$input = $request->getValidatedInput(); -if ($request->hasValidated('note')) { +$title = $input->get('title'); +$slug = $input->get('post.meta.slug', 'draft'); + +if ($input->has('note')) { // 'note' was validated, even if its value is null } diff --git a/user_guide_src/source/incoming/form_requests/015.php b/user_guide_src/source/incoming/form_requests/015.php index 12d76e1b8d46..8010bbf7107c 100644 --- a/user_guide_src/source/incoming/form_requests/015.php +++ b/user_guide_src/source/incoming/form_requests/015.php @@ -2,7 +2,7 @@ use App\Enums\PostStatus; -$input = $request->validatedInput(); +$input = $request->getValidatedInput(); $page = $input->integer('page', 1); $rating = $input->float('rating', 0.0);