有没有办法在验证发生之前修改表单请求类中的输入字段?
我想修改一些输入日期字段,如下所示,但它似乎不起作用。
当我将$this->start_dt
输入字段设置为2016-02-06 12:00:00
而$this->end_dt
设置为2016-02-06 13:00:00
时,我仍然会收到验证错误“end_dt必须位于start_dt之后”。这意味着当您在$this->start_dt
函数中更新$this->end_dt
和rules()
时,输入请求值不会发生变化。
public function rules()
{
if ($this->start_dt){
$this->start_dt = Carbon::createFromFormat('d M Y H:i:s', $this->start_dt . ' ' . $this->start_hr . ':'. $this->start_min . ':00');
}
if ($this->end_dt){
$this->end_dt = Carbon::createFromFormat('d M Y H:i:s', $this->end_dt . ' ' . $this->end_hr . ':'. $this->end_min . ':00');
}
return [
'start_dt' => 'required|date|after:yesterday',
'end_dt' => 'required|date|after:start_dt|before:' . Carbon::parse($this->start_dt)->addDays(30)
];
}
注意: start_dt
和end_dt
是日期选择器字段,start_hr
,start_min
是下拉字段。因此,我需要通过组合所有字段来创建日期时间,以便我可以进行比较。
答案 0 :(得分:15)
从laravel 5.4开始,您可以覆盖prepareForValidation
的{{1}}方法来修改任何输入。 laravel 5.1应该有类似的东西。
您的请求中的示例
ValidatesWhenResolvedTrait
答案 1 :(得分:5)
FormRequest有一个方法validationData(),它返回要验证的数据,所以我在表单请求中覆盖它:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyClassRequest extends FormRequest
{
...
/**
* Get data to be validated from the request.
*
* @return array
*/
public function validationData() {
return array_merge(
$this->all(),
[
'number' => preg_replace("/[^0-9]/", "", $this->number)
]
);
}
...
}
它正常使用Laravel 5.4:)
答案 2 :(得分:1)
您可以执行以下操作:
public function rules(Request $request)
{
if ($request->has('start_dt')){
$request->replace('start_dt', Carbon::createFromFormat('d M Y H:i:s', $request->start_dt . ' ' . $request->start_hr . ':'. $request->start_min . ':00'));
}
if ($request->has('end_dt')){
$request->replace('end_dt' ,Carbon::createFromFormat('d M Y H:i:s', $request->end_dt . ' ' . $request->end_hr . ':'. $request->end_min . ':00'));
}
return [
'start_dt' => 'required|date|after:yesterday',
'end_dt' => 'required|date|after:start_dt|before:' . Carbon::parse($request->start_dt)->addDays(30)
];
}
答案 3 :(得分:1)
尝试以下步骤:
首先,您应该在app/Http/Middleware
中创建一个中间件:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TransformsRequest;
class DateTimeMiddleware extends TransformsRequest
{
protected $fields = [
'birth_date' => 'toGregorian',
'created_at' => 'toDateTime',
];
protected function transform($key, $value)
{
if (!array_key_exists($key, $this->fields)) {
return $value;
}
$function = $this->fields[$key];
return call_user_func($function, $value);
}
}
使用此中间件,您可以在调用验证之前定义要操作它们的字段,并调用特定的函数来对其进行操作。
注释:我在自己的帮助函数中定义了toGregorian
和toDateTime
。您可以使用自己的函数进行处理
然后像下面这样修改Http/Kernel.php
:
protected $middlewareGroups = [
'web' => [
...
\App\Http\Middleware\EnglishStrings::class,
],
'api' => [
...
],
];
答案 4 :(得分:0)
我采用了另一种方法,因为我希望能够在控制器中使用$model->fill($validated);
。因此,我需要确保复选框已作为false
包含在内,否则它们将从数组中排除。
因此,我在app \ Traits \ ConvertBoolean.php中创建了一个特征,如下所示:
<?php
namespace App\Traits;
trait ConvertBoolean
{
// protected $boolean_attributes = [];
/**
* Override the FormRequest prepareForValidation() method to
* add boolean attributes specified to the request data, setting
* their value to the presence of the data in the original request.
*
* @return void
*/
protected function prepareForValidation() {
if (isset($this->boolean_attributes) && is_array($this->boolean_attributes)) {
$attrs_to_add = [];
foreach ($this->boolean_attributes as $attribute) {
$attrs_to_add[$attribute] = $this->has($attribute);
}
$this->merge($attrs_to_add);
}
}
}
此特征寻找请求中是否存在数组$this->boolean_attributes
。如果找到它,它将遍历每个对象,并将属性添加到请求数据中,并将值设置为原始请求数据中该属性的存在。
它忽略了HTML表单的复选框值。在大多数情况下,这不会有问题,但是如果需要,您可以更改特征中的逻辑以查找特定值。
现在我有了这个特质,然后可以在任何请求中使用它,就像这样:
use App\Traits\ConvertBoolean;
class MyUpdateRequest extends FormRequest
{
use ConvertBoolean;
protected $boolean_attributes = ['my_checkbox'];
// ... other class code
public function rules()
{
// Note that the data is added to the request data,
// so you still need a validation rule for it, in
// order to receive it in the validated data.
return [
'my_checkbox' => 'boolean',
// other rules
];
}
}
如果您想在请求中使用$this->prepareForValidation()
,仍然可以。
如下更改MyRequest:
use App\Traits\ConvertBoolean;
class MyUpdateRequest extends FormRequest
{
use ConvertBoolean {
prepareForValidation as traitPrepareForValidation;
}
protected function prepareForValidation() {
// the stuff you want to do in MyRequest
// ...
$this->traitPrepareForValidation();
}
// ...
}