Completed
Branch master (389090)
by Ryuichi
04:54 queued 02:16
created

Header::onInject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 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);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($defaultInje...ion, $injectAnnotation) of type array is incompatible with the declared type array<integer,string> of property $injectAnnotation.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
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;
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))) {
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) . "'");
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