我正在处理一个带有多个日期输入的表单,它不在A.D.中。出于验证目的,我正在使用表单请求。
在验证和插入数据库之前,日期输入必须转换为a.d,这样我才能进行正确的验证&如果验证成功,则日期输入将存储在a.d中。
这是我转换公元日期输入的代码
<?php
abstract class Request extends FormRequest
{
public function all()
{
$input = parent::all()
foreach ($input as $key=>$value)
{
if (substr($key, -5) == "_date")
{
$input[$key] = Helper::convert_in_ad($value);
}
}
return $input;
}
}
现在的问题是假设验证失败并重定向回上一个操作,然后使用old()或其他方法访问会话中的请求数据,它将被修改,而我无法获取原始数据。
如何在验证前更改a.d中的日期输入,以便在a.d中正确验证,然后通过解决修改输入后验证失败的问题,将所有的日期输入存储在a.d中。
编辑问题
更新:
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Repositories\Contracts\CourseInterface;
use App\Repositories\Contracts\ClassInterface;
use App\Http\Requests\ClassRequest;
use App\Helpers\Helper;
class ClassController extends Controller
{
public function __construct(ClassInterface $class, CourseInterface $course)
{
$this->class = $class;
$this->course = $course;
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$classes = $this->class->paginate();
return view('backend.class.index')->with([
'classes' => $classes
]);
/*return view('backend.class.index')->with([
'classes' => $classes
]);*/
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$courses = $this->course->all();
return view('backend.class.create')->with([
'courses' => $courses
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(ClassRequest $request)
{
// dd($request->all());
$this->class->create($request->all());
return redirect()->route('classes.index');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$class = $this->class->find($id);
$courses = $this->course->all();
return view('backend.class.edit')->with([
'class' => $class,
'courses' => $courses
]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(ClassRequest $request, $id)
{
$class = $this->class->update($request->all(), $id);
return redirect()->back();
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->class->delete($id);
return redirect()->route('classes.index');
}
public function delete($id)
{
$class = $this->class->find($id);
return view('backend.class.delete')->with([
'class' => $class
]);
}
}
我的类请求文件
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use App\Helpers\Helper;
class ClassRequest extends Request
{
public function all()
{
$input = parent::all();
foreach ($input as $key=>$value)
{
if (substr($key, -5) == "_date")
{
$input[$key] = Helper::convert_in_ad($value);
}
}
return $input;
}
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
//$this->sanitize();
switch($this->method())
{
case 'GET':
case 'DELETE':
{
return [];
}
case 'POST':
{
return [
'name' => 'required',
'course_id' => 'required',
'start_date' => 'required|date',
'end_date' => 'date|after:start_date',
];
}
case 'PUT':
case 'PATCH':
{
return [
'name' => 'required',
'course_id' => 'required',
'start_date' => 'required|date',
'end_date' => 'date|after:start_date',
];
}
default:break;
}
}
}
为了验证,我需要从公元B.S更改日期,因为拉瓦拉验证不识别B.S日期。如果我在请求文件中转换日期,问题是如果验证失败,我会在重定向后将修改后的请求返回到表单中。
因此,如何将数据转换为a.d.数据库表中的数据必须以a.d格式存储,以便使用访问器和转换器主要问题是如何验证用户以b.s格式输入的数据。
在我得到建议后编辑
谢谢大家的建议,非常感谢你们的帮助。我可以验证的一种方法是按照建议创建自定义验证规则。现在我有另一个办法让这个工作。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Helpers\Helper;
abstract class Request extends FormRequest
{
/**
* Sanitize input before validation
*
* @return array
*/
public function validator($factory)
{
return $factory->make(
$this->sanitizeInput(), $this->container->call([$this, 'rules']), $this->messages()
);
}
protected function sanitizeInput()
{
if (method_exists($this, 'sanitize'))
{
return $this->container->call([$this, 'sanitize']);
}
return $this->all();
}
/**
* Check for input having _date for converting it into AD
*
* @return array
*/
public function sanitize()
{
$input = $this->all();
foreach ($input as $key=>$value)
{
if (substr($key, -5) == "_date")
{
$input[$key] = Helper::convert_in_ad($value);
}
}
return $input;
}
}
通过使用以下代码,请求数据不会更改。而且不需要创建自定义验证,如果我以后决定从用户那里获取日期,那么就很容易了,然后就不需要更改每个请求文件来更新验证规则了。
你觉得这个怎么样?
最佳答案
正如评论中提到的,您应该尽量避免编辑FormRequest
中的数据。
您可以为此定义一个新的验证规则:https://laravel.com/docs/5.3/validation#custom-validation-rules
因此,在您的app/Providers/AppServiceProvider
(或另一个已注册的ServiceProvider
)中,您可以有如下内容:
Validator::extend('bs_date', function ($attribute, $value, $parameters, $validator) {
$date = date_parse(Helper::convert_in_ad($value));
return checkdate($date['month'], $date['day'], $date['year']);
}, 'Your error message');
Validator::extend('bs_after', function ($attribute, $value, $parameters, $validator) {
$data = $validator->getData();
$before = Helper::convert_in_ad($data[$parameters['0']]);
$after = Helper::convert_in_ad($value);
return (new \DateTime($before)) < (new \DateTime($after));
}, 'Your error message');
规则
'start_date' => 'required|bs_date',
'end_date' => 'date|bs_after:start_date',
显然,不要忘记在
Validator
中导入Helper
和ServiceProvider
。这意味着你不必再编辑你的输入了。
希望这有帮助!