Passed
Push — feature/0.7.0 ( 0c7d59...ae5b22 )
by Ryuichi
78:01 queued 33:04
created

Validate   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 102
rs 10
c 0
b 0
f 0
wmc 28

2 Methods

Rating   Name   Duplication   Size   Complexity  
A onInject() 0 3 1
D onMethodInject() 0 84 27
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
    public function onInject(array $injectAnnotation)
33
    {
34
        $this->injectAnnotation = $injectAnnotation;
35
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40
    public function onMethodInject(IAnnotatable $instance, \ReflectionMethod $method, Container $container)
41
    {
42
        $key = $this->injectAnnotation['key'];
43
        $rule = $this->injectAnnotation['rule'];
44
        $method = $this->injectAnnotation['method'];
45
46
        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
        if (preg_match('/^([a-zA-Z]{1}[a-zA-Z0-9_]{1,})(?:$|\[(.+?)\]$)/', $rule, $matches)) {
52
            $className = ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($matches) {
53
                return ucfirst($matches[1]);
54
            }, $matches[1]));
55
            $classpath = null;
56
            $classLoader = new ClassLoader($container->applicationInfo->applicationRoot);
0 ignored issues
show
Bug Best Practice introduced by
The property applicationInfo does not exist on WebStream\Container\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
57
            $classLoader->inject('logger', $container->logger);
0 ignored issues
show
Bug Best Practice introduced by
The property logger does not exist on WebStream\Container\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
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) {
0 ignored issues
show
Bug introduced by
The type WebStream\Annotation\Att...ream\Validate\IValidate was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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') {
0 ignored issues
show
Bug Best Practice introduced by
The property request does not exist on WebStream\Container\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
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