Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.5] Let the exception handler render Validation exceptions from ValidatesRequests #19929

Merged
merged 6 commits into from
Jul 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Illuminate/Foundation/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ protected function convertValidationExceptionToResponse(ValidationException $e,

return redirect()->back()->withInput(
$request->input()
)->withErrors($errors);
)->withErrors($errors, $e->errorBag);
}

/**
Expand Down
111 changes: 9 additions & 102 deletions src/Illuminate/Foundation/Validation/ValidatesRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,11 @@
namespace Illuminate\Foundation\Validation;

use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Contracts\Validation\Factory;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Validation\ValidationException;

trait ValidatesRequests
{
/**
* The default error bag.
*
* @var string
*/
protected $validatesRequestErrorBag;

/**
* Run the validation routine against the given validator.
*
Expand All @@ -33,9 +23,7 @@ public function validateWith($validator, Request $request = null)
$validator = $this->getValidationFactory()->make($request->all(), $validator);
}

if ($validator->fails()) {
$this->throwValidationException($request, $validator);
}
$validator->validate();

return $request->only(array_keys($validator->getRules()));
}
Expand All @@ -51,11 +39,9 @@ public function validateWith($validator, Request $request = null)
*/
public function validate(Request $request, array $rules, array $messages = [], array $customAttributes = [])
{
$validator = $this->getValidationFactory()->make($request->all(), $rules, $messages, $customAttributes);

if ($validator->fails()) {
$this->throwValidationException($request, $validator);
}
$this->getValidationFactory()
->make($request->all(), $rules, $messages, $customAttributes)
->validate();

return $request->only(array_keys($rules));
}
Expand All @@ -74,92 +60,13 @@ public function validate(Request $request, array $rules, array $messages = [], a
*/
public function validateWithBag($errorBag, Request $request, array $rules, array $messages = [], array $customAttributes = [])
{
$this->withErrorBag($errorBag, function () use ($request, $rules, $messages, $customAttributes) {
$this->validate($request, $rules, $messages, $customAttributes);
});
try {
return $this->validate($request, $rules, $messages, $customAttributes);
} catch (ValidationException $e) {
$e->errorBag = $errorBag;

return $request->only(array_keys($rules));
}

/**
* Execute a Closure within with a given error bag set as the default bag.
*
* @param string $errorBag
* @param callable $callback
* @return void
*/
protected function withErrorBag($errorBag, callable $callback)
{
$this->validatesRequestErrorBag = $errorBag;

call_user_func($callback);

$this->validatesRequestErrorBag = null;
}

/**
* Throw the failed validation exception.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Contracts\Validation\Validator $validator
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function throwValidationException(Request $request, $validator)
{
throw new ValidationException($validator, $this->buildFailedValidationResponse(
$request, $this->formatValidationErrors($validator)
));
}

/**
* Create the response for when a request fails validation.
*
* @param \Illuminate\Http\Request $request
* @param array $errors
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function buildFailedValidationResponse(Request $request, array $errors)
{
if ($request->expectsJson()) {
return new JsonResponse($errors, 422);
throw $e;
}

return redirect()->to($this->getRedirectUrl())
->withInput($request->input())
->withErrors($errors, $this->errorBag());
}

/**
* Format the validation errors to be returned.
*
* @param \Illuminate\Contracts\Validation\Validator $validator
* @return array
*/
protected function formatValidationErrors(Validator $validator)
{
return $validator->errors()->getMessages();
}

/**
* Get the key to be used for the view error bag.
*
* @return string
*/
protected function errorBag()
{
return $this->validatesRequestErrorBag ?: 'default';
}

/**
* Get the URL we should redirect to.
*
* @return string
*/
protected function getRedirectUrl()
{
return app(UrlGenerator::class)->previous();
}

/**
Expand Down
11 changes: 10 additions & 1 deletion src/Illuminate/Validation/ValidationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,28 @@ class ValidationException extends Exception
*/
public $response;

/**
* The default error bag.
*
* @var string
*/
public $errorBag;

/**
* Create a new exception instance.
*
* @param \Illuminate\Contracts\Validation\Validator $validator
* @param \Symfony\Component\HttpFoundation\Response $response
* @param string $errorBag
* @return void
*/
public function __construct($validator, $response = null)
public function __construct($validator, $response = null, $errorBag = 'default')
{
parent::__construct('The given data failed to pass validation.');

$this->response = $response;
$this->validator = $validator;
$this->errorBag = $errorBag;
}

/**
Expand Down