Completed
Push — 1.x ( a96e7a...db1b0e )
by Akihito
9s
created

HttpMethodParams::getParams()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 13
ccs 6
cts 6
cp 1
rs 9.2
cc 4
eloc 6
nc 3
nop 3
crap 4
1
<?php
2
/**
3
 * This file is part of the BEAR.Sunday package
4
 *
5
 * @license http://opensource.org/licenses/MIT MIT
6
 */
7
namespace BEAR\Package\Provide\Router;
8
9
use BEAR\Package\Annotation\StdIn;
10
use Ray\Di\Di\Inject;
11
12
final class HttpMethodParams implements HttpMethodParamsInterface
13
{
14
    const CONTENT_TYPE = 'CONTENT_TYPE';
15
16
    const HTTP_CONTENT_TYPE = 'HTTP_CONTENT_TYPE';
17
18
    const FORM_URL_ENCODE = 'application/x-www-form-urlencoded';
19
20
    const APPLICATION_JSON = 'application/json';
21
22
    /**
23
     * @var string
24
     */
25
    private $stdIn = 'php://input';
26
27
    /**
28
     * @param string $stdIn
29
     *
30
     * @Inject(optional=true)
31
     * @StdIn
32
     */
33 17
    public function setStdIn($stdIn)
34
    {
35 17
        $this->stdIn = $stdIn;
36 17
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41 27
    public function get(array $server, array $get, array $post)
42
    {
43
44
        // set the original value
45 27
        $method = strtolower($server['REQUEST_METHOD']);
46
47
        // early return on GET
48 27
        if ($method === 'get') {
49 4
            return ['get', $get];
50
        }
51
52 23
        return $this->unsafeMethod($method, $server, $post);
53
    }
54
55
    /**
56
     * @param string $method
57
     * @param array  $server
58
     * @param array  $post
59
     *
60
     * @return array
61
     */
62 23
    private function unsafeMethod($method, array $server, array $post)
63
    {
64 23
        $params = $this->getParams($method, $server, $post);
65
66 23
        if ($method === 'post') {
67 12
            list($method, $params) = $this->getOverrideMethod($method, $server, $params);
68
        }
69
70 23
        return [$method, $params];
71
    }
72
73
    /**
74
     * HTTP Method override
75
     *
76
     * @param string $method
77
     * @param array  $server
78
     * @param array  $params
79
     *
80
     * @return array
81
     */
82 12
    private function getOverrideMethod($method, array $server, array $params)
83
    {
84
        // must be a POST to do an override
85
86
        // look for override in post data
87 12
        if (isset($params['_method'])) {
88 3
            $method = strtolower($params['_method']);
89 3
            unset($params['_method']);
90
91 3
            return [$method, $params];
92
        }
93
94
        // look for override in headers
95 9
        if (isset($server['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
96 3
            $method = strtolower($server['HTTP_X_HTTP_METHOD_OVERRIDE']);
97
        }
98
99 9
        return [$method, $params];
100
    }
101
102
    /**
103
     * Return request parameters
104
     *
105
     * @param string $method
106
     * @param array  $server
107
     * @param array  $post
108
     *
109
     * @return array
110
     */
111 23
    private function getParams($method, array $server, array $post)
112
    {
113
        // post data exists
114 23
        if ($method === 'post' && ! empty($post)) {
115 8
            return $post;
116
        }
117
118 15
        if (in_array($method, ['post', 'put', 'patch', 'delete'])) {
119 14
            return $this->phpInput($server);
120
        }
121
122 1
        return $post;
123
    }
124
125
    /**
126
     * Take 'php://input' as input in form-urlencoded or json
127
     *
128
     * @param array $server
129
     *
130
     * @return array
131
     */
132 14
    private function phpInput(array $server)
133
    {
134 14
        $contentType = $this->getContentType($server);
135 14
        if (! $contentType) {
136 2
            return [];
137
        }
138 12
        $isFormUrlEncoded = strpos($contentType, self::FORM_URL_ENCODE) !== false;
139 12
        if ($isFormUrlEncoded) {
140 6
            parse_str(rtrim(file_get_contents($this->stdIn)), $put);
141
142 6
            return $put;
143
        }
144 6
        $isApplicationJson = strpos($contentType, self::APPLICATION_JSON) !== false;
145 6
        if ($isApplicationJson) {
146 4
            $content =  json_decode(file_get_contents($this->stdIn), true);
147
148 4
            return $content;
149
        }
150
151 2
        return [];
152
    }
153
154
    /**
155
     * Return content-type
156
     *
157
     * @param array $server
158
     *
159
     * @return string '' if no "content" header
160
     */
161 14
    private function getContentType(array $server)
162
    {
163 14
        if (isset($server[self::CONTENT_TYPE])) {
164 6
            return $server[self::CONTENT_TYPE];
165
        }
166 8
        if (isset($server[self::HTTP_CONTENT_TYPE])) {
167 6
            return $server[self::HTTP_CONTENT_TYPE];
168
        }
169
170 2
        return '';
171
    }
172
}
173