讓你的 validate 支援場景驗證

seebyyu發表於2019-12-17

目前的 validate 是不支援 scene 類似的策略的,這使我在開發中是相當不便利。

在業務編寫的過程中 總結出了 一套目前為止我比較滿意的解決方案 分享給大家。

  1. 該方法建立在基類(FormRequest)基礎之上
  2. 方法提交時增加類似 token 或者 method 這樣的欄位_scene標記場景,當然你也可以不標記,因為他支援預設的。
  3. 預設場景會把 當前 路由名稱 當做驗證場景名稱,當 request 出現了_scene時才會被替換
  4. 匹配子類 scene 場景陣列 返回特定的 驗證規則 rule
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;

class Base extends FormRequest
{

    /**
     * 驗證場景
     *
     * @var string
     */
    public $scene = [];

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Create the default validator instance.
     *
     * @param  \Illuminate\Contracts\Validation\Factory  $factory
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function createDefaultValidator(ValidationFactory $factory)
    {

        return $factory->make(
            $this->validationData(), $this->getSceneRules(),
            $this->messages(), $this->attributes()
        );
    }

    /**
     * 獲取場景驗證規則
     *
     * @return array
     */
    protected function getSceneRules()
    {
        return $this->handleScene($this->container->call([$this, 'rules']));
    }

    /***
     * 基於路由名稱的場景驗證
     *
     * @param array $rule
     * @return array
     */
    public function handleScene(array $rule)
    {

        $arr = [];

        foreach (($scene = $this->scene[$this->getSceneName()] ?? []) as $item){
            if( isset($rule[$item])){
                $arr[$item] = $rule[$item];
            }
        }

        return  $arr ?: $rule;
    }

    /**
     * 獲取場景名稱
     *
     * @return string
     */
    public function getSceneName()
    {
        return $this->input('_scene', $this->route()->getName());
    }

    /**
     * Get data to be validated from the request.
     *
     * @return array
     */
    public function validationData()
    {
        return $this->all();
    }
}
<?php
// +----------------------------------------------------------------------
// | Do what we can do
// +----------------------------------------------------------------------
// | Date  : 2019/12/10 - 4:46 PM
// +----------------------------------------------------------------------
// | Author: seebyyu <seebyyu@gmail.com> :)
// +----------------------------------------------------------------------

namespace App\Http\Requests;

class RoleRequest extends Base
{

    public $scene = [
        'user.role.update' => ['id', 'name', 'status'],
        'user.role.store' => ['name', 'status'],
        'state' => ['status']
    ];

    public function rules()
    {
        return [
            'id' => 'required',
            'name' => 'required',
            'status' => 'required',
        ];
    }

    public function messages()
    {
        return [
            'id.required' =>  '請選擇角色',
            'name.required' =>  '請填寫角色名稱',
            'status.required' =>  '請選擇啟用狀態',
        ];
    }
本作品採用《CC 協議》,轉載必須註明作者和本文連結
seebyyu

相關文章