You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
4.9 KiB
PHP
211 lines
4.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Helper;
|
|
|
|
use App\Annotation\Validation\After;
|
|
use App\Exception\BusinessException;
|
|
use App\Exception\ValidationException;
|
|
use Hyperf\Contract\ValidatorInterface;
|
|
use Hyperf\Di\Annotation\Inject;
|
|
use Hyperf\Utils\Contracts\MessageBag;
|
|
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
|
|
|
|
class Form implements Logic
|
|
{
|
|
/**
|
|
* @Inject
|
|
* @var ValidatorFactoryInterface
|
|
*/
|
|
protected $validationFactory;
|
|
|
|
protected $_data = [];
|
|
|
|
protected $scene;
|
|
|
|
protected $isCheckScene;
|
|
|
|
protected $scenes = [];
|
|
|
|
/**
|
|
* @var ValidatorInterface $validator
|
|
*/
|
|
protected $validator;
|
|
|
|
/**
|
|
* @param array $data 表单数据
|
|
*/
|
|
public function __construct(array $data = [])
|
|
{
|
|
foreach ($this->defaults() as $key => $value) {
|
|
if (isset($data[$key])) {
|
|
if (empty($value) && empty($data[$key])) {
|
|
$data[$key] = $value;
|
|
}
|
|
} else {
|
|
$data[$key] = $value;
|
|
}
|
|
}
|
|
$this->_data = $data;
|
|
}
|
|
|
|
/**
|
|
* 设置表单参数默认值,暂不支持多维数组
|
|
* @return array
|
|
*/
|
|
public function defaults(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function rules(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function messages(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function attributes(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
protected function before()
|
|
{
|
|
|
|
}
|
|
|
|
protected final function handleBefore()
|
|
{
|
|
$this->before();
|
|
$this->checkScene();
|
|
}
|
|
|
|
protected function getRules()
|
|
{
|
|
$rules = $this->rules();
|
|
$scene = $this->getScene();
|
|
if ($scene && isset($this->scenes[$scene]) && is_array($this->scenes[$scene])) {
|
|
$newRules = [];
|
|
foreach ($this->scenes[$scene] as $field) {
|
|
if (array_key_exists($field, $rules)) {
|
|
$newRules[$field] = $rules[$field];
|
|
}
|
|
}
|
|
return $newRules;
|
|
}
|
|
return $rules;
|
|
}
|
|
|
|
public final function validate($throwException = true)
|
|
{
|
|
$this->handleBefore();
|
|
$this->validator = $this->validationFactory->make($this->_data, $this->getRules(), $this->messages(), $this->attributes());
|
|
$this->handleAfter();
|
|
|
|
$fails = $this->validator->fails();
|
|
if ($throwException && $fails) {
|
|
throw new BusinessException($this->getErrorMessage());
|
|
}
|
|
|
|
return !$fails;
|
|
}
|
|
|
|
protected function after()
|
|
{
|
|
|
|
}
|
|
|
|
protected final function handleAfter()
|
|
{
|
|
$this->validator->after(function ($validator) {
|
|
$items = Annotation::getMethodsByAnnotationAndClass(After::class, static::class);
|
|
foreach ($items as $item) {
|
|
if (empty($item['annotation']->scenes) || in_array($this->scene, $item['annotation']->scenes)) {
|
|
$this->{$item['method']}();
|
|
}
|
|
}
|
|
});
|
|
|
|
$this->after();
|
|
}
|
|
|
|
public function addError($field, $message)
|
|
{
|
|
$this->validator->errors()->add($field, $message);
|
|
}
|
|
|
|
public function errors(): MessageBag
|
|
{
|
|
return $this->validator->errors();
|
|
}
|
|
|
|
public function getErrorMessage($isAll = false): string
|
|
{
|
|
if ($this->errors()->count() > 0) {
|
|
$messages = $this->errors()->all();
|
|
return $isAll ? implode('', $messages) : $messages[0];
|
|
}
|
|
return '';
|
|
}
|
|
|
|
public final function getData()
|
|
{
|
|
return $this->_data;
|
|
}
|
|
|
|
public final function getSceneData()
|
|
{
|
|
$scene = $this->getScene();
|
|
if ($scene && isset($this->scenes[$scene]) && is_array($this->scenes[$scene])) {
|
|
$newData = [];
|
|
foreach ($this->scenes[$scene] as $field) {
|
|
if (array_key_exists($field, $this->_data)) {
|
|
$newData[$field] = $this->_data[$field];
|
|
}
|
|
}
|
|
return $newData;
|
|
}
|
|
return $this->_data;
|
|
}
|
|
|
|
/**
|
|
* @param string $scene 场景名称
|
|
* @param bool $isCheckScene 是否检查场景是否存在
|
|
*/
|
|
public final function setScene(string $scene, bool $isCheckScene = true): void
|
|
{
|
|
$this->scene = $scene;
|
|
$this->isCheckScene = $isCheckScene;
|
|
}
|
|
|
|
protected final function checkScene()
|
|
{
|
|
if ($this->getScene() && $this->isCheckScene && !isset($this->scenes[$this->scene])) {
|
|
throw new BusinessException('Scene undefined!');
|
|
}
|
|
}
|
|
|
|
public final function getScene()
|
|
{
|
|
return $this->scene;
|
|
}
|
|
|
|
public function __get($key)
|
|
{
|
|
return isset($this->_data[$key]) ? $this->_data[$key] : null;
|
|
}
|
|
|
|
public function __set($key, $value)
|
|
{
|
|
$this->_data[$key] = $value;
|
|
}
|
|
|
|
public function __isset($key)
|
|
{
|
|
return $this->__get($key);
|
|
}
|
|
} |