|
2 | 2 |
|
3 | 3 | namespace Backpack\CRUD\app\Library\CrudPanel\Traits; |
4 | 4 |
|
| 5 | +use Illuminate\Foundation\Http\FormRequest; |
5 | 6 | use Illuminate\Support\Str; |
6 | 7 |
|
7 | 8 | trait Validation |
@@ -98,7 +99,7 @@ private function getValidationMessagesFromFieldsAndSubfields($fields) |
98 | 99 | }); |
99 | 100 |
|
100 | 101 | foreach ($subfieldsWithValidationMessages as $subfield) { |
101 | | - foreach ($subfield['validationMessages'] as $rule => $message) { |
| 102 | + foreach ($subfield['validationMessages'] ?? [] as $rule => $message) { |
102 | 103 | $messages[$item['name'].'.*.'.$subfield['name'].'.'.$rule] = $message; |
103 | 104 | } |
104 | 105 | } |
@@ -133,7 +134,7 @@ public function setValidation($classOrRulesArray = false, $messages = []) |
133 | 134 | $this->setValidationFromFields(); |
134 | 135 | } elseif (is_array($classOrRulesArray)) { |
135 | 136 | $this->setValidationFromArray($classOrRulesArray, $messages); |
136 | | - } elseif (is_string($classOrRulesArray) || is_class($classOrRulesArray)) { |
| 137 | + } elseif (is_string($classOrRulesArray) && class_exists($classOrRulesArray) && is_a($classOrRulesArray, FormRequest::class, true)) { |
137 | 138 | $this->setValidationFromRequest($classOrRulesArray); |
138 | 139 | } else { |
139 | 140 | abort(500, 'Please pass setValidation() nothing, a rules array or a FormRequest class.'); |
@@ -202,55 +203,71 @@ public function validateRequest() |
202 | 203 | return app($formRequest); |
203 | 204 | } |
204 | 205 |
|
205 | | - // create an alias of the provided FormRequest so we can create a new class that extends it. |
206 | | - // we can't use $variables to extend classes. |
207 | | - class_alias(get_class(new $formRequest), 'DeveloperProvidedFormRequest'); |
| 206 | + $formRequest = (new $formRequest)->createFrom($this->getRequest()); |
| 207 | + $extendedRules = $this->mergeRules($formRequest, $rules); |
| 208 | + $extendedMessages = array_merge($messages, $formRequest->messages()); |
208 | 209 |
|
209 | | - // create a new anonymous class that will extend the provided developer FormRequest |
210 | | - // in this class we will merge the FormRequest rules() and messages() with the ones provided by developer in fields. |
211 | | - $extendedRequest = new class($rules, $messages) extends \DeveloperProvidedFormRequest |
212 | | - { |
213 | | - private $_rules; |
214 | | - |
215 | | - private $_messages; |
| 210 | + // validate the complete request with FormRequest + controller validation + field validation (our anonymous class) |
| 211 | + return $this->checkRequestValidity($extendedRules, $extendedMessages, $formRequest); |
| 212 | + } |
216 | 213 |
|
217 | | - public function __construct($rules, $messages) |
218 | | - { |
219 | | - parent::__construct(); |
220 | | - $this->_rules = $rules; |
221 | | - $this->_messages = $messages; |
222 | | - } |
| 214 | + return ! empty($rules) ? $this->checkRequestValidity($rules, $messages) : $this->getRequest(); |
| 215 | + } |
223 | 216 |
|
224 | | - public function rules() |
225 | | - { |
226 | | - return array_merge(parent::rules(), $this->_rules); |
227 | | - } |
| 217 | + /** |
| 218 | + * Return an array containing the request rules and the field/controller rules merged. |
| 219 | + * The rules in request will take precedence over the ones in controller/fields. |
| 220 | + * |
| 221 | + * @param \Illuminate\Http\Request $request |
| 222 | + * @param array $rules |
| 223 | + * @return array |
| 224 | + */ |
| 225 | + private function mergeRules($request, $rules) |
| 226 | + { |
| 227 | + $extendedRules = []; |
| 228 | + $requestRules = $this->getRequestRulesAsArray($request); |
| 229 | + $rules = array_map(function ($ruleDefinition) { |
| 230 | + return is_array($ruleDefinition) ? $ruleDefinition : explode('|', $ruleDefinition); |
| 231 | + }, $rules); |
| 232 | + |
| 233 | + foreach ($requestRules as $ruleKey => $rule) { |
| 234 | + $extendedRules[$ruleKey] = array_key_exists($ruleKey, $rules) ? array_merge($rule, $rules[$ruleKey]) : $rule; |
| 235 | + unset($rules[$ruleKey]); |
| 236 | + } |
228 | 237 |
|
229 | | - public function messages() |
230 | | - { |
231 | | - return array_merge(parent::messages(), $this->_messages); |
232 | | - } |
233 | | - }; |
| 238 | + return array_merge($rules, $extendedRules); |
| 239 | + } |
234 | 240 |
|
235 | | - // validate the complete request with FormRequest + controller validation + field validation (our anonymous class) |
236 | | - return app(get_class($extendedRequest), ['rules' => $rules, 'messages' => $messages]); |
| 241 | + /** |
| 242 | + * Return the request rules as an array of rules if developer provided a rule string configuration. |
| 243 | + * |
| 244 | + * @param \Illuminate\Http\Request $request |
| 245 | + * @return array |
| 246 | + */ |
| 247 | + private function getRequestRulesAsArray($request) |
| 248 | + { |
| 249 | + $requestRules = []; |
| 250 | + foreach ($request->rules() as $ruleKey => $rule) { |
| 251 | + $requestRules[$ruleKey] = is_array($rule) ? $rule : explode('|', $rule); |
237 | 252 | } |
238 | 253 |
|
239 | | - return ! empty($rules) ? $this->checkRequestValidity($rules, $messages) : $this->getRequest(); |
| 254 | + return $requestRules; |
240 | 255 | } |
241 | 256 |
|
242 | 257 | /** |
243 | | - * Checks if the current crud request is valid against the provided rules. |
| 258 | + * Checks if the request is valid against the rules. |
244 | 259 | * |
245 | 260 | * @param array $rules |
246 | 261 | * @param array $messages |
| 262 | + * @param \Illuminate\Http\Request|null $request |
247 | 263 | * @return \Illuminate\Http\Request |
248 | 264 | */ |
249 | | - private function checkRequestValidity($rules, $messages) |
| 265 | + private function checkRequestValidity($rules, $messages, $request = null) |
250 | 266 | { |
251 | | - $this->getRequest()->validate($rules, $messages); |
| 267 | + $request = $request ?? $this->getRequest(); |
| 268 | + $request->validate($rules, $messages); |
252 | 269 |
|
253 | | - return $this->getRequest(); |
| 270 | + return $request; |
254 | 271 | } |
255 | 272 |
|
256 | 273 | /** |
|
0 commit comments