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

Header   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 110
rs 10
c 0
b 0
f 0
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
    public function onInject(array $injectAnnotation)
68
    {
69
        $defaultInjectAnnotation = ['allowMethod' => null, 'contentType' => null];
70
        $this->injectAnnotation = array_merge($defaultInjectAnnotation, $injectAnnotation);
71
        $this->readAnnotation = [];
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function getAnnotationInfo(): array
78
    {
79
        return $this->readAnnotation;
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85
    public function onMethodInject(IAnnotatable $instance, \ReflectionMethod $method, Container $container)
86
    {
87
        $allowMethods = $this->injectAnnotation['allowMethod'];
88
        $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
        if ($allowMethods !== null) {
92
            if (!is_array($allowMethods)) {
93
                $allowMethods = [$allowMethods];
94
            }
95
96
            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
                if (!preg_match("/^(?:(?:P(?:OS|U)|GE)T|(?:p(?:os|u)|ge)t|DELETE|delete)$/", $allowMethods[$i])) {
98
                    $errorMsg = "Invalid value '" . $allowMethods[$i] . "' in 'allowMethod' attribute of @Header.";
99
                    throw new AnnotationException($errorMsg);
100
                }
101
                $allowMethods[$i] = strtoupper($allowMethods[$i]);
102
            }
103
104
            // 複数指定した場合、一つでも許可されていればOK
105
            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
                $errorMsg = "Not allowed request method '" . $container->requestMethod;
107
                throw new InvalidRequestException($errorMsg);
108
            }
109
110
            $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
        $ext = $this->injectAnnotation['contentType'] ?: 'html';
114
115
        if (!is_string($ext)) {
116
            $errorMsg = "contentType' attribute of @Header must be string.";
117
            throw new AnnotationException($errorMsg);
118
        }
119
120
        $contentType = null;
121
        if (array_key_exists($ext, $this->contentTypeList)) {
122
            $contentType = $this->contentTypeList[$ext];
123
        }
124
        if ($contentType === null) {
125
            $errorMsg = "Invalid value '$ext' in 'contentType' attribute of @Header.";
126
            throw new AnnotationException($errorMsg);
127
        }
128
129
        $this->readAnnotation['contentType'] = $ext;
130
        $logger->debug("Accepted contentType '$ext'");
131
    }
132
}
133