Passed
Branch master (507aab)
by Alexander
01:48
created

Message::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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