Completed
Push — master ( 752264...caff68 )
by Mārtiņš
7s
created

RequestBuilder::applyContentParsers()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 18
ccs 12
cts 12
cp 1
rs 9.2
cc 4
eloc 9
nc 4
nop 1
crap 4
1
<?php
2
3
namespace Fracture\Http;
4
5
class RequestBuilder
6
{
7
8
    private $defaults = [
9
        'get'    => [],
10
        'post'   => [],
11
        'server' => [],
12
        'files'  => [],
13
        'cookies'=> [],
14
    ];
15
16
    private $parsers = [];
17
18
19
    /**
20
     * @param array[] $params
21
     * @return \Fracture\Routing\Routable
22
     */
23 14
    public function create($params)
24
    {
25 14
        $params += $this->defaults;
26
27 14
        $instance = $this->buildInstance();
28 14
        $this->applyHeaders($instance, $params['server']);
29 14
        $this->applyParams($instance, $params);
30 14
        if ($instance->getMethod() !== 'get') {
31 13
            $this->applyContentParsers($instance);
32 12
        }
33 13
        $instance->prepare();
34
35 13
        return $instance;
36
    }
37
38
39
    /**
40
     * @param string $type
41
     * @param callback $parser
42
     */
43 4
    public function addContentParser($type, $parser)
44
    {
45 4
        $this->parsers[$type] = $parser;
46 4
    }
47
48
49 2
    protected function buildInstance()
50
    {
51 2
        $fileBuilder = new UploadedFileBuilder;
52 2
        $fileBagBuilder = new FileBagBuilder($fileBuilder);
53
54 2
        return new Request($fileBagBuilder);
55
    }
56
57
58
    /**
59
     * @param Request $instance
60
     */
61 6
    protected function applyContentParsers($instance)
62
    {
63 6
        $parameters = [];
64
65 6
        $header = $instance->getContentTypeHeader();
66
67 6
        if ($header === null) {
68 2
            return;
69
        }
70
71 4
        foreach ($this->parsers as $value => $parser) {
72 3
            if ($header->contains($value)) {
73 3
                $parameters = $this->alterParameters($parameters, $parser, $value);
74 2
            }
75 3
        }
76
77 3
        $instance->setParameters($parameters, true);
78 3
    }
79
80
81 3
    private function alterParameters($parameters, $parser, $value)
82
    {
83 3
        $result = call_user_func($parser);
84
85 3
        if (false === is_array($result)) {
86 1
            $message = "Parser for '$value' did not return a 'name => value' array of parameters";
87 1
            trigger_error($message, \E_USER_WARNING);
88
        }
89
90 2
        $parameters += $result;
91 2
        return $parameters;
92
    }
93
94
95
    /**
96
     * @param Request $instance
97
     * @param array[] $params
98
     */
99 3
    protected function applyParams($instance, $params)
100
    {
101 3
        $instance->setParameters($params['get']);
102 3
        $instance->setParameters($params['post']);
103 3
        $instance->setUploadedFiles($params['files']);
104
105 3
        $this->applyWebContext($instance, $params['server']);
106
107 3
        foreach ($params['cookies'] as $name => $value) {
108 1
            $instance->addCookie(new Cookie($name, $value));
109 3
        }
110 3
    }
111
112
113
    /**
114
     * @param Request $instance
115
     * @param array[] $params
116
     */
117 1
    protected function applyWebContext($instance, $params)
118
    {
119 1
        if (isset($params['REQUEST_METHOD'])) {
120 1
            $instance->setMethod($params['REQUEST_METHOD']);
121 1
        }
122 1
        if (isset($params['REMOTE_ADDR'])) {
123 1
            $instance->setAddress($params['REMOTE_ADDR']);
0 ignored issues
show
Documentation introduced by
$params['REMOTE_ADDR'] is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
124 1
        }
125 1
    }
126
127
128
    /**
129
     * @param Request $instance
130
     * @param array $params
131
     */
132 2
    public function applyHeaders($instance, $params)
133
    {
134 2
        if (array_key_exists('HTTP_ACCEPT', $params)) {
135 1
            $header = new Headers\Accept($params['HTTP_ACCEPT']);
136 1
            $header->prepare();
137 1
            $instance->setAcceptHeader($header);
138 1
        }
139
140 2
        if (array_key_exists('CONTENT_TYPE', $params)) {
141 1
            $header = new Headers\ContentType($params['CONTENT_TYPE']);
142 1
            $header->prepare();
143 1
            $instance->setContentTypeHeader($header);
144 1
        }
145 2
    }
146
}
147