Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
1,902 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"name": "hyperf-plus/validate", | ||
"type": "library", | ||
"keywords": [ | ||
"php", | ||
"hyperf-plus", | ||
"validate", | ||
"hyperf" | ||
], | ||
"description": "hyperf-plus validate 支持request 和方法场景验证,兼容tp5写法 支持控制器注解验证、方法注解验证", | ||
"license": "Apache-2.0", | ||
"require": { | ||
"php": ">=7.2", | ||
"hyperf/di": "~2.0.1", | ||
"hyperf/http-message": "~2.0.0", | ||
"hyperf/utils": "~2.0.0" | ||
}, | ||
"require-dev": { | ||
"friendsofphp/php-cs-fixer": "^2.14" | ||
}, | ||
"suggest": { | ||
"ext-json": "Required to use JSON." | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"HPlus\\Validate\\": "src/" | ||
} | ||
}, | ||
"extra": { | ||
"hyperf": { | ||
"config": "HPlus\\Validate\\ConfigProvider" | ||
} | ||
}, | ||
"config": { | ||
"sort-packages": true | ||
}, | ||
"prefer-stable": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
namespace HPlus\Validate\Annotations; | ||
|
||
use Hyperf\Di\Annotation\AbstractAnnotation; | ||
|
||
/** | ||
* @Annotation | ||
* @Target("METHOD") | ||
*/ | ||
class RequestValidation extends AbstractAnnotation | ||
{ | ||
/** | ||
* 规则类 | ||
* @var string | ||
*/ | ||
public $mode = ''; | ||
/** | ||
* 验证器 | ||
* @var string | ||
*/ | ||
public $validate = ''; | ||
/** | ||
* 场景 | ||
* @var string | ||
*/ | ||
public $scene = ''; | ||
/** | ||
* 场景 | ||
* @var string | ||
*/ | ||
public $value = ''; | ||
/** | ||
* 是否过滤多余字段 | ||
* @var bool | ||
*/ | ||
public $filter = false; | ||
/** | ||
* delete | ||
* 过滤是否抛出异常 | ||
* @var bool | ||
*/ | ||
public $throw = false; | ||
|
||
/** | ||
* 安全模式严格按照规则字段,如果多字段会抛出异常 | ||
* @var bool | ||
*/ | ||
public $security = false; | ||
|
||
/** | ||
* 是否批量验证 | ||
* @var bool | ||
*/ | ||
public $batch = false; | ||
|
||
public function __construct($value = null) | ||
{ | ||
parent::__construct($value); | ||
$this->bindMainProperty('scene', $value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?php | ||
|
||
namespace HPlus\Validate\Annotations; | ||
|
||
use Hyperf\Di\Annotation\AbstractAnnotation; | ||
|
||
/** | ||
* @Annotation | ||
* @Target("METHOD") | ||
*/ | ||
class Validation extends AbstractAnnotation | ||
{ | ||
/** | ||
* 模块 | ||
* @var string | ||
*/ | ||
public $mode = ''; | ||
/** | ||
* 验证器 | ||
* @var string | ||
*/ | ||
public $validate = ''; | ||
/** | ||
* 场景 | ||
* @var string | ||
*/ | ||
public $value = ''; | ||
/** | ||
* 场景 | ||
* @var string | ||
*/ | ||
public $scene = ''; | ||
/** | ||
* 是否过滤多余字段 | ||
* @var bool | ||
*/ | ||
public $filter = false; | ||
/** | ||
* 过滤是否抛出异常 | ||
* @var bool | ||
*/ | ||
public $throw = false; | ||
|
||
/** | ||
* 安全模式严格按照规则字段,如果多字段会抛出异常 | ||
* @var bool | ||
*/ | ||
public $security = false; | ||
|
||
/** | ||
* 是否批量验证 | ||
* @var bool | ||
*/ | ||
public $batch = false; | ||
/** | ||
* 验证哪个参数 | ||
* @var string | ||
*/ | ||
public $field = "data"; | ||
|
||
public function __construct($value = null) | ||
{ | ||
parent::__construct($value); | ||
$this->bindMainProperty('scene', $value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace HPlus\Validate; | ||
|
||
use HPlus\Validate\Annotations\RequestValidation; | ||
use HPlus\Validate\Annotations\Validation; | ||
use Hyperf\Di\Annotation\Aspect; | ||
use Hyperf\Di\Aop\AbstractAspect; | ||
use Hyperf\Di\Aop\ProceedingJoinPoint; | ||
use Hyperf\Di\Exception\Exception; | ||
use Hyperf\Utils\Context; | ||
use Psr\Container\ContainerInterface; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
|
||
/** | ||
* @Aspect | ||
*/ | ||
class ValidationAspect extends AbstractAspect | ||
{ | ||
protected $container; | ||
protected $request; | ||
|
||
// 要切入的类,可以多个,亦可通过 :: 标识到具体的某个方法,通过 * 可以模糊匹配 | ||
public $annotations = [ | ||
Validation::class, | ||
RequestValidation::class | ||
]; | ||
|
||
public function __construct(ContainerInterface $container, ServerRequestInterface $Request) | ||
{ | ||
$this->container = $container; | ||
$this->request = $this->container->get(ServerRequestInterface::class); | ||
} | ||
|
||
/** | ||
* @param ProceedingJoinPoint $proceedingJoinPoint | ||
* @return mixed | ||
* @throws Exception | ||
* @throws ValidateException | ||
*/ | ||
public function process(ProceedingJoinPoint $proceedingJoinPoint) | ||
{ | ||
foreach ($proceedingJoinPoint->getAnnotationMetadata()->method as $validation) { | ||
/** | ||
* @var Validation $validation | ||
*/ | ||
switch (true) { | ||
case $validation instanceof RequestValidation: | ||
$verData = $this->request->all(); | ||
$this->validationData($validation, $verData, $validation->validate, $proceedingJoinPoint, true); | ||
break; | ||
case $validation instanceof Validation: | ||
$verData = $proceedingJoinPoint->arguments['keys'][$validation->field]; | ||
$this->validationData($validation, $verData, $validation->validate, $proceedingJoinPoint); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
return $proceedingJoinPoint->process(); | ||
} | ||
|
||
/** | ||
* @param $validation | ||
* @param $verData | ||
* @param $class | ||
* @param $proceedingJoinPoint | ||
* @param $isRequest | ||
* @throws ValidateException | ||
*/ | ||
private function validationData($validation, $verData, $class, $proceedingJoinPoint, $isRequest = false) | ||
{ | ||
/** | ||
* @var RequestValidation $validation | ||
*/ | ||
/** | ||
* @var Validate $validate | ||
*/ | ||
if (class_exists($class)) { | ||
$validate = new $class; | ||
} else { | ||
throw new ValidateException('class not exists:' . $class); | ||
} | ||
if ($validation->scene == '') { | ||
$validation->scene = $proceedingJoinPoint->methodName; | ||
} | ||
$rules = $validate->getSceneRule($validation->scene); | ||
|
||
if ($validate->batch($validation->batch)->check($verData, $rules,$validation->scene) === false) { | ||
throw new ValidateException($validate->getError()); | ||
} | ||
|
||
if ($validation->security) { | ||
$fields = []; | ||
foreach ($rules as $field => $rule) { | ||
if (is_numeric($field)) { | ||
$field = $rule; | ||
} | ||
$fields[$field] = 1; | ||
} | ||
foreach ($verData as $key => $item) { | ||
if (!isset($fields[$key])) { | ||
throw new ValidateException('params ' . $key . ' invalid'); | ||
} | ||
} | ||
}; | ||
|
||
if ($validation->filter) { | ||
foreach ($rules as $key => $item) { | ||
if (isset($verData[$key]) && $verData[$key] === null) { | ||
unset($verData[$key]); | ||
} | ||
} | ||
|
||
switch ($isRequest) { | ||
case true: | ||
Context::override(ServerRequestInterface::class, function (ServerRequestInterface $request) use ($verData) { | ||
return $request->withParsedBody($verData); | ||
}); | ||
break; | ||
default: | ||
$proceedingJoinPoint->arguments['keys'][$validation->field] = $verData; | ||
break; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace HPlus\Validate; | ||
|
||
|
||
class ConfigProvider | ||
{ | ||
public function __invoke(): array | ||
{ | ||
return [ | ||
'annotations' => [ | ||
'scan' => [ | ||
'paths' => [ | ||
__DIR__, | ||
] | ||
] | ||
] | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace HPlus\Validate; | ||
|
||
class ValidateException extends \Exception | ||
{ | ||
|
||
} |
Oops, something went wrong.