Passed
Push — master ( 51dcfe...4ee661 )
by Ryuichi
02:30
created

Header   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 110
rs 10
c 0
b 0
f 0
ccs 34
cts 34
cp 1
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
D onMethodInject() 0 46 10
A onInject() 0 5 1
A getAnnotationInfo() 0 3 1
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\Annotation\Base\IRead;
8
use WebStream\Container\Container;
9
use WebStream\Exception\Extend\AnnotationException;
10
use WebStream\Exception\Extend\InvalidRequestException;
11
12
/**
13
 * Header
14
 * @author Ryuichi TANAKA.
15
 * @since 2013/10/20
16
 * @version 0.4
17
 *
18
 * @Annotation
19
 * @Target("METHOD")
20
 */
21
class Header extends Annotation implements IMethod, IRead
22
{
23
    /**
24
     * @var array<string> 注入アノテーション情報
25
     */
26
    private $injectAnnotation;
27
28
    /**
29
     * @var array<string> 読み込みアノテーション情報
30
     */
31
    private $readAnnotation;
32
33
    /**
34
     * @var array<string, string> mimeタイプリスト
35
     */
36
    private $contentTypeList = [
37
        'txt'   => 'text/plain',
38
        'jpeg'  => 'image/jpeg',
39
        'jpg'   => 'image/jpeg',
40
        'gif'   => 'image/gif',
41
        'png'   => 'image/png',
42
        'tiff'  => 'image/tiff',
43
        'tif'   => 'image/tiff',
44
        'bmp'   => 'image/bmp',
45
        'ico'   => 'image/x-icon',
46
        'svg'   => 'image/svg+xml',
47
        'xml'   => 'application/xml',
48
        'xsl'   => 'application/xml',
49
        'rss'   => 'application/rss+xml',
50
        'rdf'   => 'application/rdf+xml',
51
        'atom'  => 'application/atom+xml',
52
        'zip'   => 'application/zip',
53
        'html'  => 'text/html',
54
        'htm'   => 'text/html',
55
        'css'   => 'text/css',
56
        'csv'   => 'text/csv',
57
        'js'    => 'text/javascript',
58
        'jsonp' => 'text/javascript',
59
        'json'  => 'application/json',
60
        'pdf'   => 'application/pdf',
61
        'file'  => 'application/octet-stream'
62
    ];
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 16
    public function onInject(array $injectAnnotation)
68
    {
69 16
        $defaultInjectAnnotation = ['allowMethod' => null, 'contentType' => null];
70 16
        $this->injectAnnotation = array_merge($defaultInjectAnnotation, $injectAnnotation);
71 16
        $this->readAnnotation = [];
72 16
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 5
    public function getAnnotationInfo(): array
78
    {
79 5
        return $this->readAnnotation;
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85 11
    public function onMethodInject(IAnnotatable $instance, \ReflectionMethod $method, Container $container)
86
    {
87 11
        $allowMethods = $this->injectAnnotation['allowMethod'];
88 11
        $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...
89
90
        // 指定無しの場合はチェックしない(すべてのメソッドを許可する)
91 11
        if ($allowMethods !== null) {
92 8
            if (!is_array($allowMethods)) {
93 6
                $allowMethods = [$allowMethods];
94
            }
95
96 8
            for ($i = 0; $i < count($allowMethods); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
97 8
                if (!preg_match("/^(?:(?:P(?:OS|U)|GE)T|(?:p(?:os|u)|ge)t|DELETE|delete)$/", $allowMethods[$i])) {
98 1
                    $errorMsg = "Invalid value '" . $allowMethods[$i] . "' in 'allowMethod' attribute of @Header.";
99 1
                    throw new AnnotationException($errorMsg);
100
                }
101 7
                $allowMethods[$i] = strtoupper($allowMethods[$i]);
102
            }
103
104
            // 複数指定した場合、一つでも許可されていればOK
105 7
            if (!array_key_exists($container->requestMethod, array_flip($allowMethods))) {
0 ignored issues
show
Bug Best Practice introduced by
The property requestMethod does not exist on WebStream\Container\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
106 3
                $errorMsg = "Not allowed request method '" . $container->requestMethod;
107 3
                throw new InvalidRequestException($errorMsg);
108
            }
109
110 4
            $logger->debug("Accepted method '" . implode(',', $allowMethods) . "'");
0 ignored issues
show
Bug introduced by
The method debug() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
            $logger->/** @scrutinizer ignore-call */ 
111
                     debug("Accepted method '" . implode(',', $allowMethods) . "'");

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
111
        }
112
113 7
        $ext = $this->injectAnnotation['contentType'] ?: 'html';
114
115 7
        if (!is_string($ext)) {
116 1
            $errorMsg = "contentType' attribute of @Header must be string.";
117 1
            throw new AnnotationException($errorMsg);
118
        }
119
120 6
        $contentType = null;
121 6
        if (array_key_exists($ext, $this->contentTypeList)) {
122 5
            $contentType = $this->contentTypeList[$ext];
123
        }
124 6
        if ($contentType === null) {
125 1
            $errorMsg = "Invalid value '$ext' in 'contentType' attribute of @Header.";
126 1
            throw new AnnotationException($errorMsg);
127
        }
128
129 5
        $this->readAnnotation['contentType'] = $ext;
130 5
        $logger->debug("Accepted contentType '$ext'");
131 5
    }
132
}
133