Completed
Push — master ( 50f7e2...ff7682 )
by arto
02:34
created

Request::execute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 22
rs 9.2
cc 1
eloc 12
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 array $options
209
     * @param mixed $data
210
     * @return array
211
     */
212
    private function addDataToTheOptionsIfDataIsValid(array $options, $data)
213
    {
214
        $isDataProvided = (!is_null($data));
215
216
        if ($isDataProvided) {
217
            $dataIsNotFromTypeScalar   = (!is_scalar($data));
218
219
            if ($dataIsNotFromTypeScalar) {
220
                $data = http_build_query($data);
221
            }
222
223
            $dataStringContainsContent = (strlen($data) > 0);
224
225
            if ($dataStringContainsContent) {
226
                $options[CURLOPT_POSTFIELDS] = $data; //@see: http://www.lornajane.net/posts/2009/putting-data-fields-with-php-curl
227
            }
228
        }
229
230
        return $options;
231
    }
232
233
    /**
234
     * @param array $parameters
235
     * @param string $url
236
     * @return string
237
     */
238
    private function addParametersToTheUrlIfParametersAreProvided(array $parameters, $url)
239
    {
240
        $areParametersProvided = (!empty($parameters));
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
        return $urlWithParameters;
256
    }
257
258
    /**
259
     * @param string $url
260
     * @param string $method
261
     * @param null|array $parameters
262
     * @param null|string|array $data
263
     * @return Response
264
     */
265
    private function execute($url, $method, array $parameters = array(), $data = null)
266
    {
267
        //begin of dependencies
268
        $dispatcher             = $this->dispatcher;
269
        $merge                  = $this->merge;
270
        $headerLines            = $merge($this->headerLines, $this->defaultHeaderLines);
271
        $options                = $merge($this->options, $this->defaultOptions);
272
        $headerLines[]          = 'X-HTTP-Method-Override: ' . $method; //@see: http://tr.php.net/curl_setopt#109634
273
        //end of dependencies
274
275
        //begin of business logic
276
        $options[CURLOPT_CUSTOMREQUEST] = $method; //@see: http://tr.php.net/curl_setopt#109634
277
        $options[CURLOPT_HTTPHEADER]    = $headerLines;
278
        //@todo what about binary transfer?
279
280
        $options            = $this->addDataToTheOptionsIfDataIsValid($options, $data);
281
        $urlWithParameters  = $this->addParametersToTheUrlIfParametersAreProvided($parameters, $url);
282
        $response           = $dispatcher->dispatch($urlWithParameters, $options);
283
        //end of business logic
284
285
        return $response;
286
    }
287
}
288