BaRequest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <?php
  2. namespace Dingo\Api\Http;
  3. use Illuminate\Http\Request;
  4. use Illuminate\Http\JsonResponse;
  5. use Illuminate\Contracts\Container\Container;
  6. use Illuminate\Contracts\Validation\Validator;
  7. use Dingo\Api\Exception\ValidationHttpException;
  8. use Illuminate\Validation\ValidatesWhenResolvedTrait;
  9. use Symfony\Component\HttpKernel\Exception\HttpException;
  10. use Illuminate\Contracts\Validation\ValidatesWhenResolved;
  11. use Illuminate\Contracts\Validation\Factory as ValidationFactory;
  12. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  13. class BaRequest extends Request implements ValidatesWhenResolved
  14. {
  15. use ValidatesWhenResolvedTrait;
  16. /**
  17. * The container instance.
  18. *
  19. * @var \Illuminate\Contracts\Container\Container
  20. */
  21. protected $container;
  22. /**
  23. * The redirector instance.
  24. *
  25. * @var \Illuminate\Routing\Redirector
  26. */
  27. protected $redirector;
  28. /**
  29. * The URI to redirect to if validation fails.
  30. *
  31. * @var string
  32. */
  33. protected $redirect;
  34. /**
  35. * The route to redirect to if validation fails.
  36. *
  37. * @var string
  38. */
  39. protected $redirectRoute;
  40. /**
  41. * The controller action to redirect to if validation fails.
  42. *
  43. * @var string
  44. */
  45. protected $redirectAction;
  46. /**
  47. * The key to be used for the view error bag.
  48. *
  49. * @var string
  50. */
  51. protected $errorBag = 'default';
  52. /**
  53. * The input keys that should not be flashed on redirect.
  54. *
  55. * @var array
  56. */
  57. protected $dontFlash = [
  58. 'password',
  59. 'password_confirmation',
  60. ];
  61. /**
  62. * Validate the request.
  63. */
  64. public function validate()
  65. {
  66. if ($this->authorize() === false) {
  67. throw new AccessDeniedHttpException();
  68. }
  69. $validator = app('validator')->make($this->all(), $this->rules(), $this->messages());
  70. if ($validator->fails()) {
  71. throw new ValidationHttpException($validator->errors());
  72. }
  73. }
  74. /**
  75. * Get the validator instance for the request.
  76. *
  77. * @return \Illuminate\Contracts\Validation\Validator
  78. *
  79. * @SuppressWarnings(PHPMD.ElseExpression)
  80. */
  81. protected function getValidatorInstance()
  82. {
  83. $factory = $this->container->make(ValidationFactory::class);
  84. if (method_exists($this, 'validator')) {
  85. $validator = $this->container->call([$this, 'validator'], compact('factory'));
  86. } else {
  87. $validator = $this->createDefaultValidator($factory);
  88. }
  89. if (method_exists($this, 'withValidator')) {
  90. $this->withValidator($validator);
  91. }
  92. return $validator;
  93. }
  94. /**
  95. * Create the default validator instance.
  96. *
  97. * @param \Illuminate\Contracts\Validation\Factory $factory
  98. *
  99. * @return \Illuminate\Contracts\Validation\Validator
  100. */
  101. protected function createDefaultValidator(ValidationFactory $factory)
  102. {
  103. return $factory->make(
  104. $this->validationData(),
  105. $this->container->call([$this, 'rules']),
  106. $this->messages(),
  107. $this->attributes()
  108. );
  109. }
  110. /**
  111. * Get data to be validated from the request.
  112. *
  113. * @return array
  114. */
  115. protected function validationData()
  116. {
  117. return $this->all();
  118. }
  119. /**
  120. * Handle a failed validation attempt.
  121. *
  122. * @param \Illuminate\Contracts\Validation\Validator $validator
  123. *
  124. * @return void
  125. */
  126. protected function failedValidation(Validator $validator)
  127. {
  128. if ($this->container['request'] instanceof Request) {
  129. throw new ValidationHttpException($validator->errors());
  130. }
  131. parent::failedValidation($validator);
  132. }
  133. /**
  134. * Get the proper failed validation response for the request.
  135. *
  136. * @param array $errors
  137. *
  138. * @return \Symfony\Component\HttpFoundation\Response
  139. */
  140. public function response(array $errors)
  141. {
  142. if ($this->expectsJson()) {
  143. return new JsonResponse($errors, 422);
  144. }
  145. return $this->redirector->to($this->getRedirectUrl())
  146. ->withInput($this->except($this->dontFlash))
  147. ->withErrors($errors, $this->errorBag);
  148. }
  149. /**
  150. * Format the errors from the given Validator instance.
  151. *
  152. * @param \Illuminate\Contracts\Validation\Validator $validator
  153. *
  154. * @return array
  155. */
  156. protected function formatErrors(Validator $validator)
  157. {
  158. return $validator->getMessageBag()->toArray();
  159. }
  160. /**
  161. * Get the URL to redirect to on a validation error.
  162. *
  163. * @return string
  164. */
  165. protected function getRedirectUrl()
  166. {
  167. $url = $this->redirector->getUrlGenerator();
  168. if ($this->redirect) {
  169. return $url->to($this->redirect);
  170. } elseif ($this->redirectRoute) {
  171. return $url->route($this->redirectRoute);
  172. } elseif ($this->redirectAction) {
  173. return $url->action($this->redirectAction);
  174. }
  175. return $url->previous();
  176. }
  177. /**
  178. * Determine if the request passes the authorization check.
  179. *
  180. * @return bool
  181. */
  182. protected function passesAuthorization()
  183. {
  184. if (method_exists($this, 'authorize')) {
  185. return $this->container->call([$this, 'authorize']);
  186. }
  187. return false;
  188. }
  189. /**
  190. * Handle a failed authorization attempt.
  191. *
  192. * @return void
  193. */
  194. protected function failedAuthorization()
  195. {
  196. if ($this->container['request'] instanceof Request) {
  197. throw new HttpException(403);
  198. }
  199. parent::failedAuthorization();
  200. }
  201. /**
  202. * Get custom messages for validator errors.
  203. *
  204. * @return array
  205. */
  206. public function messages()
  207. {
  208. return [];
  209. }
  210. /**
  211. * Get custom attributes for validator errors.
  212. *
  213. * @return array
  214. */
  215. public function attributes()
  216. {
  217. return [];
  218. }
  219. /**
  220. * Set the Redirector instance.
  221. *
  222. * @param \Laravel\Lumen\Http\Redirector|\Illuminate\Routing\Redirector $redirector
  223. *
  224. * @return $this
  225. */
  226. public function setRedirector($redirector)
  227. {
  228. $this->redirector = $redirector;
  229. return $this;
  230. }
  231. /**
  232. * Set the container implementation.
  233. *
  234. * @param \Illuminate\Contracts\Container\Container $container
  235. *
  236. * @return $this
  237. */
  238. public function setContainer(Container $container)
  239. {
  240. $this->container = $container;
  241. return $this;
  242. }
  243. }