Skip to content

Commit 1422535

Browse files
gazbenthilanga
authored andcommitted
Fix FormRequests missing class error (dingo#1534)
* Fix FormRequests missing class error * Fix styleCI * Fix Style ci * Fix style ci * Add missing use statements
1 parent aa16043 commit 1422535

File tree

2 files changed

+294
-3
lines changed

2 files changed

+294
-3
lines changed

src/Http/FormRequest.php

Lines changed: 243 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,145 @@
22

33
namespace Dingo\Api\Http;
44

5+
use Illuminate\Http\Request;
6+
use Illuminate\Http\JsonResponse;
7+
use Laravel\Lumen\Http\Redirector;
8+
use Illuminate\Contracts\Container\Container;
59
use Illuminate\Contracts\Validation\Validator;
610
use Dingo\Api\Exception\ValidationHttpException;
11+
use Illuminate\Validation\ValidatesWhenResolvedTrait;
712
use Symfony\Component\HttpKernel\Exception\HttpException;
8-
use Illuminate\Foundation\Http\FormRequest as IlluminateFormRequest;
13+
use Illuminate\Contracts\Validation\ValidatesWhenResolved;
14+
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
15+
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
916

10-
class FormRequest extends IlluminateFormRequest
17+
class FormRequest extends Request implements ValidatesWhenResolved
1118
{
19+
use ValidatesWhenResolvedTrait;
20+
21+
/**
22+
* The container instance.
23+
*
24+
* @var \Illuminate\Contracts\Container\Container
25+
*/
26+
protected $container;
27+
28+
/**
29+
* The redirector instance.
30+
*
31+
* @var \Illuminate\Routing\Redirector
32+
*/
33+
protected $redirector;
34+
35+
/**
36+
* The URI to redirect to if validation fails.
37+
*
38+
* @var string
39+
*/
40+
protected $redirect;
41+
42+
/**
43+
* The route to redirect to if validation fails.
44+
*
45+
* @var string
46+
*/
47+
protected $redirectRoute;
48+
49+
/**
50+
* The controller action to redirect to if validation fails.
51+
*
52+
* @var string
53+
*/
54+
protected $redirectAction;
55+
56+
/**
57+
* The key to be used for the view error bag.
58+
*
59+
* @var string
60+
*/
61+
protected $errorBag = 'default';
62+
63+
/**
64+
* The input keys that should not be flashed on redirect.
65+
*
66+
* @var array
67+
*/
68+
protected $dontFlash = [
69+
'password',
70+
'password_confirmation',
71+
];
72+
73+
/**
74+
* Validate the request.
75+
*/
76+
public function validate()
77+
{
78+
if ($this->authorize() === false) {
79+
throw new AccessDeniedHttpException();
80+
}
81+
82+
$validator = app('validator')->make($this->all(), $this->rules(), $this->messages());
83+
84+
if ($validator->fails()) {
85+
throw new ValidationHttpException($validator->errors());
86+
}
87+
}
88+
89+
/**
90+
* Get the validator instance for the request.
91+
*
92+
* @return \Illuminate\Contracts\Validation\Validator
93+
*
94+
* @SuppressWarnings(PHPMD.ElseExpression)
95+
*/
96+
protected function getValidatorInstance()
97+
{
98+
$factory = $this->container->make(ValidationFactory::class);
99+
100+
if (method_exists($this, 'validator')) {
101+
$validator = $this->container->call([$this, 'validator'], compact('factory'));
102+
} else {
103+
$validator = $this->createDefaultValidator($factory);
104+
}
105+
106+
if (method_exists($this, 'withValidator')) {
107+
$this->withValidator($validator);
108+
}
109+
110+
return $validator;
111+
}
112+
113+
/**
114+
* Create the default validator instance.
115+
*
116+
* @param \Illuminate\Contracts\Validation\Factory $factory
117+
*
118+
* @return \Illuminate\Contracts\Validation\Validator
119+
*/
120+
protected function createDefaultValidator(ValidationFactory $factory)
121+
{
122+
return $factory->make(
123+
$this->validationData(),
124+
$this->container->call([$this, 'rules']),
125+
$this->messages(),
126+
$this->attributes()
127+
);
128+
}
129+
130+
/**
131+
* Get data to be validated from the request.
132+
*
133+
* @return array
134+
*/
135+
protected function validationData()
136+
{
137+
return $this->all();
138+
}
139+
12140
/**
13141
* Handle a failed validation attempt.
14142
*
15-
* @param \Illuminate\Contracts\Validation\Validator $validator
143+
* @param \Illuminate\Contracts\Validation\Validator $validator
16144
*
17145
* @return void
18146
*/
@@ -25,6 +153,70 @@ protected function failedValidation(Validator $validator)
25153
parent::failedValidation($validator);
26154
}
27155

156+
/**
157+
* Get the proper failed validation response for the request.
158+
*
159+
* @param array $errors
160+
*
161+
* @return \Symfony\Component\HttpFoundation\Response
162+
*/
163+
public function response(array $errors)
164+
{
165+
if ($this->expectsJson()) {
166+
return new JsonResponse($errors, 422);
167+
}
168+
169+
return $this->redirector->to($this->getRedirectUrl())
170+
->withInput($this->except($this->dontFlash))
171+
->withErrors($errors, $this->errorBag);
172+
}
173+
174+
/**
175+
* Format the errors from the given Validator instance.
176+
*
177+
* @param \Illuminate\Contracts\Validation\Validator $validator
178+
*
179+
* @return array
180+
*/
181+
protected function formatErrors(Validator $validator)
182+
{
183+
return $validator->getMessageBag()->toArray();
184+
}
185+
186+
/**
187+
* Get the URL to redirect to on a validation error.
188+
*
189+
* @return string
190+
*/
191+
protected function getRedirectUrl()
192+
{
193+
$url = $this->redirector->getUrlGenerator();
194+
195+
if ($this->redirect) {
196+
return $url->to($this->redirect);
197+
} elseif ($this->redirectRoute) {
198+
return $url->route($this->redirectRoute);
199+
} elseif ($this->redirectAction) {
200+
return $url->action($this->redirectAction);
201+
}
202+
203+
return $url->previous();
204+
}
205+
206+
/**
207+
* Determine if the request passes the authorization check.
208+
*
209+
* @return bool
210+
*/
211+
protected function passesAuthorization()
212+
{
213+
if (method_exists($this, 'authorize')) {
214+
return $this->container->call([$this, 'authorize']);
215+
}
216+
217+
return false;
218+
}
219+
28220
/**
29221
* Handle a failed authorization attempt.
30222
*
@@ -38,4 +230,52 @@ protected function failedAuthorization()
38230

39231
parent::failedAuthorization();
40232
}
233+
234+
/**
235+
* Get custom messages for validator errors.
236+
*
237+
* @return array
238+
*/
239+
public function messages()
240+
{
241+
return [];
242+
}
243+
244+
/**
245+
* Get custom attributes for validator errors.
246+
*
247+
* @return array
248+
*/
249+
public function attributes()
250+
{
251+
return [];
252+
}
253+
254+
/**
255+
* Set the Redirector instance.
256+
*
257+
* @param Redirector $redirector
258+
*
259+
* @return $this
260+
*/
261+
public function setRedirector(Redirector $redirector)
262+
{
263+
$this->redirector = $redirector;
264+
265+
return $this;
266+
}
267+
268+
/**
269+
* Set the container implementation.
270+
*
271+
* @param \Illuminate\Contracts\Container\Container $container
272+
*
273+
* @return $this
274+
*/
275+
public function setContainer(Container $container)
276+
{
277+
$this->container = $container;
278+
279+
return $this;
280+
}
41281
}

src/Provider/LumenServiceProvider.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
namespace Dingo\Api\Provider;
44

55
use ReflectionClass;
6+
use Laravel\Lumen\Application;
7+
use Dingo\Api\Http\FormRequest;
8+
use Laravel\Lumen\Http\Redirector;
69
use Dingo\Api\Http\Middleware\Auth;
710
use Dingo\Api\Http\Middleware\Request;
811
use Dingo\Api\Http\Middleware\RateLimit;
@@ -11,13 +14,16 @@
1114
use FastRoute\RouteParser\Std as StdRouteParser;
1215
use Illuminate\Http\Request as IlluminateRequest;
1316
use Dingo\Api\Routing\Adapter\Lumen as LumenAdapter;
17+
use Illuminate\Contracts\Validation\ValidatesWhenResolved;
1418
use FastRoute\DataGenerator\GroupCountBased as GcbDataGenerator;
1519

1620
class LumenServiceProvider extends DingoServiceProvider
1721
{
1822
/**
1923
* Boot the service provider.
2024
*
25+
* @throws \ReflectionException
26+
*
2127
* @return void
2228
*/
2329
public function boot()
@@ -48,6 +54,16 @@ public function boot()
4854
});
4955
});
5056

57+
$this->app->afterResolving(ValidatesWhenResolved::class, function ($resolved) {
58+
$resolved->validate();
59+
});
60+
61+
$this->app->resolving(FormRequest::class, function (FormRequest $request, Application $app) {
62+
$this->initializeRequest($request, $app['request']);
63+
64+
$request->setContainer($app)->setRedirector($app->make(Redirector::class));
65+
});
66+
5167
$this->app->routeMiddleware([
5268
'api.auth' => Auth::class,
5369
'api.throttle' => RateLimit::class,
@@ -131,4 +147,39 @@ protected function gatherAppMiddleware(ReflectionClass $reflection)
131147

132148
return $middleware;
133149
}
150+
151+
/**
152+
* Initialize the form request with data from the given request.
153+
*
154+
* @param FormRequest $form
155+
* @param IlluminateRequest $current
156+
*
157+
* @return void
158+
*/
159+
protected function initializeRequest(FormRequest $form, IlluminateRequest $current)
160+
{
161+
$files = $current->files->all();
162+
163+
$files = is_array($files) ? array_filter($files) : $files;
164+
165+
$form->initialize(
166+
$current->query->all(),
167+
$current->request->all(),
168+
$current->attributes->all(),
169+
$current->cookies->all(),
170+
$files,
171+
$current->server->all(),
172+
$current->getContent()
173+
);
174+
175+
$form->setJson($current->json());
176+
177+
if ($session = $current->getSession()) {
178+
$form->setLaravelSession($session);
179+
}
180+
181+
$form->setUserResolver($current->getUserResolver());
182+
183+
$form->setRouteResolver($current->getRouteResolver());
184+
}
134185
}

0 commit comments

Comments
 (0)