1
|
|
|
<?php |
2
|
|
|
namespace WebStream\Annotation\Attributes; |
3
|
|
|
|
4
|
|
|
use WebStream\Annotation\Base\Annotation; |
5
|
|
|
use WebStream\Annotation\Base\IAnnotatable; |
6
|
|
|
use WebStream\Annotation\Base\IMethod; |
7
|
|
|
use WebStream\ClassLoader\ClassLoader; |
8
|
|
|
use WebStream\Container\Container; |
9
|
|
|
use WebStream\Exception\Extend\AnnotationException; |
10
|
|
|
use WebStream\Exception\Extend\InvalidRequestException; |
11
|
|
|
use WebStream\Exception\Extend\ValidateException; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Validate |
15
|
|
|
* @author Ryuichi TANAKA. |
16
|
|
|
* @since 2015/03/30 |
17
|
|
|
* @version 0.4 |
18
|
|
|
* |
19
|
|
|
* @Annotation |
20
|
|
|
* @Target("METHOD") |
21
|
|
|
*/ |
22
|
|
|
class Validate extends Annotation implements IMethod |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* @var array<string> 注入アノテーション情報 |
26
|
|
|
*/ |
27
|
|
|
private $injectAnnotation; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* {@inheritdoc} |
31
|
|
|
*/ |
32
|
72 |
|
public function onInject(array $injectAnnotation) |
33
|
|
|
{ |
34
|
72 |
|
$this->injectAnnotation = $injectAnnotation; |
35
|
72 |
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* {@inheritdoc} |
39
|
|
|
*/ |
40
|
72 |
|
public function onMethodInject(IAnnotatable $instance, \ReflectionMethod $method, Container $container) |
41
|
|
|
{ |
42
|
72 |
|
$key = $this->injectAnnotation['key']; |
43
|
72 |
|
$rule = $this->injectAnnotation['rule']; |
44
|
72 |
|
$method = $this->injectAnnotation['method']; |
45
|
|
|
|
46
|
72 |
|
if ($method !== null && !array_key_exists($method, array_flip(["get", "post", "put", "delete"]))) { |
47
|
|
|
throw new ValidateException("Invalid method attribute is specified: " . $method); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
// パラメータの有無にかかわらずルール定義が間違っている場合はエラー |
51
|
72 |
|
if (preg_match('/^([a-zA-Z]{1}[a-zA-Z0-9_]{1,})(?:$|\[(.+?)\]$)/', $rule, $matches)) { |
52
|
72 |
|
$className = ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($matches) { |
53
|
16 |
|
return ucfirst($matches[1]); |
54
|
72 |
|
}, $matches[1])); |
55
|
|
|
$classpath = null; |
56
|
|
|
$classLoader = new ClassLoader($container->applicationInfo->applicationRoot); |
57
|
|
|
$classLoader->inject('logger', $container->logger); |
58
|
|
|
|
59
|
|
|
// デフォルトバリデーションルールのパス |
60
|
|
|
$filepath = $className . '.php'; |
61
|
|
|
if (!$classLoader->import($filepath)) { |
62
|
|
|
$loadList = $classLoader->load($className); |
63
|
|
|
// バリデーションルールのクラス名が複数指定されている場合は適用判断不可能なのでエラー |
64
|
|
|
if (count($loadList) >= 2) { |
65
|
|
|
$errorMsg = "Class load failed because the same class name has been identified: " . $className . ""; |
66
|
|
|
throw new ValidateException($errorMsg); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
if (count($loadList) === 0) { |
70
|
|
|
$errorMsg = "Invalid Validate class filepath: " . $filepath . ""; |
71
|
|
|
throw new ValidateException($errorMsg); |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
$namespaces = $classLoader->getNamespaces($filepath); |
76
|
|
|
if (count($namespaces) > 0) { |
77
|
|
|
$classpath = array_shift($namespaces) . "\\" . $className; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
if (!class_exists($classpath)) { |
81
|
|
|
$errorMsg = "Invalid Validate class's classpath: " . $classpath; |
82
|
|
|
throw new AnnotationException($errorMsg); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
$validateInstance = new $classpath(); |
86
|
|
|
if ($validateInstance instanceof WebStream\Validate\IValidate) { |
|
|
|
|
87
|
|
|
$errorMsg = get_class($validateInstance) . " must be IValidate instance."; |
88
|
|
|
throw new AnnotationException($errorMsg); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
$params = null; |
92
|
|
|
if ($container->request->requestMethod === 'GET') { |
93
|
|
|
if ($method === null || "get" === mb_strtolower($method)) { |
94
|
|
|
$params = $container->request->get; |
95
|
|
|
} |
96
|
|
|
} elseif ($container->request->requestMethod === 'POST') { |
97
|
|
|
if ($method === null || "post" === mb_strtolower($method)) { |
98
|
|
|
$params = $container->request->post; |
99
|
|
|
} |
100
|
|
|
} elseif ($container->request->requestMethod === 'PUT') { |
101
|
|
|
if ($method === null || "put" === mb_strtolower($method)) { |
102
|
|
|
$params = $container->request->put; |
103
|
|
|
} |
104
|
|
|
} elseif ($container->request->requestMethod === 'DELETE') { |
105
|
|
|
if ($method === null || "delete" === mb_strtolower($method)) { |
106
|
|
|
$params = $container->request->delete; |
107
|
|
|
} |
108
|
|
|
} else { |
109
|
|
|
$errorMsg = "Unsupported method is specified: " . $method; |
110
|
|
|
throw new InvalidRequestException($errorMsg); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
// パラメータの指定なしの場合、value=null |
114
|
|
|
// パラメータの指定ありあつ値の指定なしの場合、value="" |
115
|
|
|
$value = is_array($params) && array_key_exists($key, $params) ? $params[$key] : null; |
116
|
|
|
|
117
|
|
|
if (!$validateInstance->isValid($value, $rule)) { |
118
|
|
|
$errorMsg = "Validation rule error. Rule is '$rule', value is " . ($value === null || $value === '' ? "empty" : "'${value}'"); |
119
|
|
|
throw new ValidateException($errorMsg); |
120
|
|
|
} |
121
|
|
|
} else { |
122
|
|
|
$errorMsg = "Invalid validation rule definition: " . $rule; |
123
|
|
|
throw new ValidateException($errorMsg); |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
} |
127
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.