Completed
Pull Request — master (#25)
by Alexander
01:37
created

Message::withUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace alkemann\h2l;
4
5
use alkemann\h2l\util\Http;
6
7
/**
8
 * Class Message
9
 *
10
 * Container for requests and responses made with the Remote class
11
 *
12
 * @package alkemann\h2l
13
 */
14
class Message
15
{
16
17
    /**
18
     * @var int
19
     */
20
    protected $code;
21
    /**
22
     * @var string
23
     */
24
    protected $url = '';
25
    /**
26
     * Enum with Request::GET, Request::POST etc
27
     * @var string
28
     */
29
    protected $method = Http::GET;
30
    /**
31
     * @var string
32
     */
33
    protected $body;
34
    /**
35
     * @var array
36
     */
37
    protected $meta = [];
38
    /**
39
     * @var array
40
     */
41
    protected $headers = [];
42
    /**
43
     * @var array
44
     */
45
    protected $options = [];
46
    /**
47
     * @var string
48
     */
49
    protected $content_type = Http::CONTENT_HTML;
50
    /**
51
     * @var string
52
     */
53
    protected $content_charset = 'utf-8';
54
55
    /**
56
     * @return string
57
     */
58
    public function url(): string
59
    {
60
        return $this->url;
61
    }
62
63
    /**
64
     * @return string
65
     */
66
    public function method(): string
67
    {
68
        return $this->method;
69
    }
70
71
    /**
72
     * @return null|string
73
     */
74
    public function body(): ?string
75
    {
76
        return $this->body;
77
    }
78
79
    /**
80
     * @return null|string|array|\SimpleXMLElement body converted from raw format
81
     */
82
    public function content()
83
    {
84
        switch ($this->contentType()) {
85
            case Http::CONTENT_JSON:
86
                return json_decode($this->body, true);
87
            case Http::CONTENT_XML:
88
                return new \SimpleXMLElement($this->body);
89
            case Http::CONTENT_HTML:
90
                $doc = new \DOMDocument();
91
                $doc->loadHTML($this->body);
92
                return $doc;
93
            case null:
94
            default:
95
                return $this->body;
96
        }
97
    }
98
99
    /**
100
     * @return string
101
     */
102
    public function contentType(): string
103
    {
104
        return $this->content_type;
105
    }
106
107
    /**
108
     * @return string
109
     */
110
    public function charset(): string
111
    {
112
        return $this->content_charset;
113
    }
114
115
    /**
116
     * @param string $name
117
     * @return null|string
118
     */
119
    public function header(string $name): ?string
120
    {
121
        foreach ($this->headers as $key => $value) {
122
            if (strcasecmp($key, $name) === 0) {
123
                return $value;
124
            }
125
        }
126
        return null;
127
    }
128
129
    /**
130
     * @param string $class name of class that must take data array as constructor
131
     * @return object body json decoded and sent to constructor of $class
132
     */
133
    public function as(string $class)
134
    {
135
        return new $class($this->content());
136
    }
137
138
    /**
139
     * @return array
140
     */
141
    public function headers(): array
142
    {
143
        return $this->headers;
144
    }
145
146
    /**
147
     * @return array
148
     */
149
    public function meta(): array
150
    {
151
        return $this->meta;
152
    }
153
154
    /**
155
     * @return array
156
     */
157
    public function options(): array
158
    {
159
        return $this->options;
160
    }
161
162
    /**
163
     * @return int|null
164
     */
165
    public function code(): ?int
166
    {
167
        return $this->code;
168
    }
169
170
    /**
171
     * @param int $code
172
     * @return Message
173
     */
174
    public function withCode(int $code): Message
175
    {
176
        $new = clone $this;
177
        $new->code = $code;
178
        return $new;
179
    }
180
181
    /**
182
     * @param string $url
183
     * @return Message
184
     */
185
    public function withUrl(string $url): Message
186
    {
187
        $new = clone $this;
188
        $new->url = $url;
189
        return $new;
190
    }
191
192
    /**
193
     * @param string $method
194
     * @return Message
195
     */
196
    public function withMethod(string $method): Message
197
    {
198
        $new = clone $this;
199
        $new->method = $method;
200
        return $new;
201
    }
202
203
    /**
204
     * @param string $body
205
     * @return Message
206
     */
207
    public function withBody(string $body): Message
208
    {
209
        $new = clone $this;
210
        $new->body = $body;
211
        return $new;
212
    }
213
214
    /**
215
     * @param array $headers
216
     * @return Message
217
     */
218
    public function withHeaders(array $headers): Message
219
    {
220
        $new = clone $this;
221
        $new->headers = $headers;
222
        $new->setContentHeaderTypeAndCharset();
223
        return $new;
224
    }
225
226
    private function setContentHeaderTypeAndCharset(): void
227
    {
228
        $content_header = $this->header('Content-Type');
229
        if (is_string($content_header)) {
230
            if (strpos($content_header, ';') === false) {
231
                $this->content_type = trim(strtolower($content_header));
232
            } else {
233
                list($type, $other) = explode(';', $content_header, 2);
234
                $this->content_type = trim(strtolower($type));
235
                list($key, $charset) = explode('=', $other, 2);
236
                if ('charset' === strtolower(trim($key))) {
237
                    $this->content_charset = strtolower(trim(trim($charset, '"')));
238
                }
239
            }
240
        }
241
    }
242
243
    public function withHeader(string $name, string $value): Message
244
    {
245
        $new = clone $this;
246
        $new->headers[$name] = $value;
247
        if ($name === 'Content-Type') {
248
            $new->setContentHeaderTypeAndCharset();
249
        }
250
        return $new;
251
    }
252
253
    /**
254
     * @param array $options
255
     * @return Message
256
     */
257
    public function withOptions(array $options): Message
258
    {
259
        $new = clone $this;
260
        $new->options = $options;
261
        return $new;
262
    }
263
264
    /**
265
     * @param array $meta
266
     * @return Message
267
     */
268
    public function withMeta(array $meta): Message
269
    {
270
        $new = clone $this;
271
        $new->meta = $meta;
272
        return $new;
273
    }
274
275
    /**
276
     * @return string the raw body of the message
277
     */
278
    public function __toString(): string
279
    {
280
        return $this->body ?? '';
281
    }
282
}
283