<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\Validator;

/**
 * 检测json数组
 * 
 * @author 刘相欣
 * 
 */
class JsonArray implements Rule
{

    protected $rules    = [];
    protected $errMsg   = '';

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct($rules=[])
    {
        $this->rules        =   $rules;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        // 解析数据
        $list = json_decode($value, true);
        // 递归验证
        $result = $this->validatorJsonArray($list,$attribute);
        // 验证结果
        return  $result;
    }

    /**
     * 递归处理json验证
     * @param   Mixed  $data    待验证数据
     * @return bool
     */
    public function validatorJsonArray($data)
    {
        // 获取规则
        $rules                  = $this->rules;
        // 如果验证规则为空
        if( !$rules )           return true;
        // 如果不是数组
        if ( !is_array($data) ) {
            // 告知格式错误
            $this->errMsg       = 'json数据格式错误';
            // 返回结果
            return              false;
        }
        // 如果是关联数组，进行验证
        if ( count(array_filter(array_keys($data), 'is_string')) > 0 ){
            // 进行字段验证
            $validator          = Validator::make($data, $rules);
            // 如果失败
            if ( $validator->fails() ) {
                // 获取错误信息
                $errors  = $validator->errors()->getMessages();
                // 获取一条信息
                $errors  = array_shift($errors);
                $errors  = array_shift($errors);
                // 如果不是json错误
                if ($errors != 'validation.j_s_o_n') $this->errMsg = $errors;
                // 返回错误
                return false;
            }
        }else {
            // 如果是索引数组，循环进行递归验证
            foreach ($data as $item) {
                // 如果不是数组
                if( !is_array($item) ) continue;
                // 递归验证
                $result = $this->validatorJsonArray($item);
                // 验证失败，返回失败
                if ($result === false)  return false;
            }
        }
        // 验证成功返回
        return true;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return $this->errMsg;
    }
}
