Completed
Push — master ( a1a386...b15fa9 )
by arto
04:17
created

Request::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4286
cc 1
eloc 5
nc 1
nop 4
1
<?php
2
/**
3
 * @author: stev leibelt <[email protected]>
4
 * @since: 2015-12-09
5
 */
6
7
namespace Net\Bazzline\Component\Curl\Request;
8
9
use Net\Bazzline\Component\Curl\Dispatcher\DispatcherInterface;
10
use Net\Bazzline\Component\Curl\HeaderLine\HeaderLineInterface;
11
use Net\Bazzline\Component\Curl\Option\OptionInterface;
12
use Net\Bazzline\Component\Curl\Response\Response;
13
use Net\Bazzline\Component\Toolbox\HashMap\Merge;
14
15
class Request
16
{
17
    //@see: http://developer.sugarcrm.com/2013/08/30/doing-put-and-delete-with-curl-in-php/
18
    const HTTP_METHOD_DELETE    = 'DELETE';
19
    const HTTP_METHOD_GET       = 'GET';
20
    const HTTP_METHOD_PATCH     = 'PATCH';
21
    const HTTP_METHOD_POST      = 'POST';
22
    const HTTP_METHOD_PUT       = 'PUT';
23
24
    /** @var array */
25
    private $defaultHeaderLines = array();
26
27
    /** @var array */
28
    private $defaultOptions = array();
29
30
    /** @var DispatcherInterface */
31
    private $dispatcher;
32
33
    /** @var array */
34
    private $headerLines = array();
35
36
    /** @var Merge */
37
    private $merge;
38
39
    /** @var array */
40
    private $options = array();
41
42
    /**
43
     * @param DispatcherInterface $dispatcher
44
     * @param Merge $merge
45
     * @param array $defaultHeaderLines
46
     * @param array $defaultOptions
47
     */
48
    public function __construct(DispatcherInterface $dispatcher, Merge $merge, array $defaultHeaderLines = array(), array $defaultOptions = array())
49
    {
50
        $this->defaultHeaderLines   = $defaultHeaderLines;
51
        $this->defaultOptions       = $defaultOptions;
52
        $this->dispatcher           = $dispatcher;
53
        $this->merge                = $merge;
54
    }
55
56
    /**
57
     * @return Request
58
     */
59
    public function __clone()
60
    {
61
        return new self(
62
            $this->dispatcher,
63
            $this->merge,
64
            $this->defaultHeaderLines,
65
            $this->defaultOptions
66
        );
67
    }
68
69
    /**
70
     * @param HeaderLineInterface $line
71
     */
72
    public function addHeaderLine(HeaderLineInterface $line)
73
    {
74
        $this->headerLines[] = $line->line();
75
    }
76
77
    /**
78
     * @param OptionInterface $option
79
     */
80
    public function addOption(OptionInterface $option)
81
    {
82
        $this->options[$option->identifier()] = $option->value();
83
    }
84
85
    /**
86
     * @param string $line - CURLOPT_* - see: http://php.net/manual/en/function.curl-setopt.php
87
     */
88
    public function addRawHeaderLine($line)
89
    {
90
        $this->headerLines[] = $line;
91
    }
92
93
    /**
94
     * @param string $key - CURLOPT_* - see: http://php.net/manual/en/function.curl-setopt.php
95
     * @param mixed $value
96
     */
97
    public function addRawOption($key, $value)
98
    {
99
        $this->options[$key] = $value;
100
    }
101
102
    /**
103
     * @param string $url
104
     * @param array $parameters
105
     * @return Response
106
     */
107
    public function get($url, array $parameters = array())
108
    {
109
        return $this->execute(
110
            $url,
111
            self::HTTP_METHOD_GET,
112
            $parameters,
113
            array()
114
        );
115
    }
116
117
    /**
118
     * @param string $url
119
     * @param array $parameters
120
     * @param null|string|array $data
121
     * @return Response
122
     */
123
    public function post($url, array $parameters = array(), $data = null)
124
    {
125
        return $this->execute(
126
            $url,
127
            self::HTTP_METHOD_POST,
128
            $parameters,
129
            $data
130
        );
131
    }
132
133
    /**
134
     * @param string $url
135
     * @param array $parameters
136
     * @param null|string|array $data
137
     * @return Response
138
     */
139
    public function put($url, array $parameters = array(), $data = null)
140
    {
141
        return $this->execute(
142
            $url,
143
            self::HTTP_METHOD_PUT,
144
            $parameters,
145
            $data
146
        );
147
    }
148
149
    /**
150
     * @param string $url
151
     * @param array $parameters
152
     * @param null|string|array $data
153
     * @return Response
154
     */
155
    public function patch($url, array $parameters = array(), $data = null)
156
    {
157
        return $this->execute(
158
            $url,
159
            self::HTTP_METHOD_PATCH,
160
            $parameters,
161
            $data
162
        );
163
    }
164
165
    /**
166
     * @param string $url
167
     * @param array $parameters
168
     * @return Response
169
     */
170
    public function delete($url, array $parameters = array())
171
    {
172
        return $this->execute(
173
            $url,
174
            self::HTTP_METHOD_DELETE,
175
            $parameters,
176
            array()
177
        );
178
    }
179
180
    /**
181
     * @see: https://de.wikipedia.org/wiki/Representational_State_Transfer
182
    public function head($url)
183
    {
184
    }
185
    public function options($url)
186
    {
187
    }
188
    public function trace($url)
189
    {
190
    }
191
     */
192
193
    /**
194
     * @param bool|false $alsoTheDefaults
195
     */
196
    public function reset($alsoTheDefaults = false)
197
    {
198
        $this->headerLines  = array();
199
        $this->options      = array();
200
201
        if ($alsoTheDefaults) {
202
            $this->defaultHeaderLines   = array();
203
            $this->defaultOptions       = array();
204
        }
205
    }
206
207
    /**
208
     * @param string $url
209
     * @param string $method
210
     * @param null|array $parameters
211
     * @param null|string|array $data
212
     * @return Response
213
     */
214
    private function execute($url, $method, array $parameters = array(), $data = null)
215
    {
216
        $areParametersProvided  = (!empty($parameters));
217
        $dispatcher             = $this->dispatcher;
218
        $merge                  = $this->merge;
219
        $headerLines            = $merge($this->headerLines, $this->defaultHeaderLines);
220
        $isDataProvided         = (!is_null($data));
221
        $options                = $merge($this->options, $this->defaultOptions);
222
        $headerLines[]          = 'X-HTTP-Method-Override: ' . $method; //@see: http://tr.php.net/curl_setopt#109634
223
224
        $options[CURLOPT_CUSTOMREQUEST]     = $method; //@see: http://tr.php.net/curl_setopt#109634
225
        $options[CURLOPT_HTTPHEADER]        = $headerLines;
226
        //@todo what about binary transfer?
227
228
        if ($isDataProvided) {
229
            $dataIsNotFromTypeScalar   = (!is_scalar($data));
230
231
            if ($dataIsNotFromTypeScalar) {
232
                $data = http_build_query($data);
233
            }
234
235
            $dataStringContainsContent = (strlen($data) > 0);
236
237
            if ($dataStringContainsContent) {
238
                $options[CURLOPT_POSTFIELDS] = $data; //@see: http://www.lornajane.net/posts/2009/putting-data-fields-with-php-curl
239
            }
240
        }
241
242
        if ($areParametersProvided) {
243
            $parametersAsString     = http_build_query($parameters);
244
            $isParameterStringValid = (strlen($parametersAsString) > 0);
245
246
            if ($isParameterStringValid) {
247
                $urlWithParameters = $url . '?' . http_build_query($parameters);
248
            } else {
249
                $urlWithParameters = $url;
250
            }
251
        } else {
252
            $urlWithParameters = $url;
253
        }
254
255
        $response = $dispatcher->dispatch($urlWithParameters, $options);
256
257
        return $response;
258
    }
259
}
260