Passed
Push — master ( ddf6f5...2e933f )
by Nicolas
03:42 queued 28s
created

Message::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 9
cts 9
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Puzzle\AMQP\Messages;
4
5
use Psr\Log\InvalidArgumentException;
6
use Puzzle\AMQP\WritableMessage;
7
use Puzzle\AMQP\Messages\Bodies\NullBody;
8
use Puzzle\Pieces\ConvertibleToString;
9
10
class Message implements WritableMessage, ConvertibleToString
11
{
12
    const
13
        ATTRIBUTE_CONTENT_TYPE = 'content_type';
14
15
    use BodySetter;
16
17
    private
18
        $body,
19
        $canBeDroppedSilently,
20
        $allowCompression,
21
        $userContentType,
22
        $headers,
23
        $attributes;
24
25 40
    public function __construct($routingKey = '')
26
    {
27 40
        $this->body = new NullBody();
28
29 40
        $this->canBeDroppedSilently = true;
30 40
        $this->allowCompression = false;
31 40
        $this->userContentType = null;
32 40
        $this->headers = array();
33 40
        $this->initializeAttributes();
34
35 40
        $this->changeRoutingKey($routingKey);
36 40
    }
37
38 40
    public function changeRoutingKey($routingKey)
39
    {
40 40
        $this->setAttribute('routing_key', $routingKey);
41 40
    }
42
43 40
    private function initializeAttributes()
44
    {
45 40
        $this->attributes = array(
46 40
            'routing_key' => null,
47 40
            self::ATTRIBUTE_CONTENT_TYPE=> $this->getContentType(),
48 40
            'content_encoding' => 'utf8',
49
            'message_id' => function($timestamp) {
50 16
                return sha1($this->getRoutingKey() . $timestamp . $this->generateBodyId() . mt_rand());
51 40
            },
52 40
            'user_id' => null,
53 40
            'app_id' => null,
54 40
            'delivery_mode' => self::PERSISTENT,
55 40
            'priority' => null,
56
            'timestamp' => function($timestamp) {
57 17
                return $timestamp;
58 40
            },
59 40
            'expiration' => null,
60 40
            'type' => null,
61 40
            'reply_to' => null,
62 40
            'correlation_id' => null,
63
            'headers' => function($timestamp) {
64 18
                return $this->packHeaders($timestamp);
65 40
            },
66
        );
67 40
    }
68
69 16
    private function generateBodyId()
70
    {
71 16
        if($this->body instanceof Footprintable)
72 16
        {
73 3
            return $this->body->footprint();
74
        }
75
76 13
        return uniqid(true);
77
    }
78
79 1
    public function canBeDroppedSilently()
80
    {
81 1
        return $this->canBeDroppedSilently;
82
    }
83
84 1
    public function disallowSilentDropping()
85
    {
86 1
        $this->canBeDroppedSilently = false;
87
88 1
        return $this;
89
    }
90
91 40
    public function getContentType()
92
    {
93 40
        if($this->userContentType === null)
94 40
        {
95 40
            return $this->body->getContentType();
96
        }
97
98 3
        return $this->userContentType;
99
    }
100
101 34
    public function getRoutingKey()
102
    {
103 34
        return $this->getAttribute('routing_key');
104
    }
105
106 8
    public function getBodyInTransportFormat()
107
    {
108 8
        return $this->body->asTransported();
109
    }
110
111 15
    public function setBody(Body $body)
112
    {
113 15
        $this->body = $body;
114 15
        $this->updateContentType();
115
116 15
        return $this;
117
    }
118
119 24
    private function updateContentType()
120
    {
121 24
        $this->attributes[self::ATTRIBUTE_CONTENT_TYPE] = $this->getContentType();
122 24
    }
123
124 26
    public function addHeader($headerName, $value)
125
    {
126 26
        $this->headers[$headerName] = $value;
127
128 26
        return $this;
129
    }
130
131 9
    public function addHeaders(array $headers)
132
    {
133 9
        foreach($headers as $name => $value)
134
        {
135 9
            $this->addHeader($name, $value);
136 9
        }
137
138 9
        return $this;
139
    }
140
141 1
    public function setAuthor($author)
142
    {
143 1
        $this->addHeader('author', $author);
144
145 1
        return $this;
146
    }
147
148 18
    public function packAttributes($timestamp = false)
149
    {
150 18
        $this->updateContentType();
151
152 18
        if($timestamp === false)
153 18
        {
154 16
            $timestamp = (new \DateTime("now"))->getTimestamp();
155 16
        }
156
157 18
        return array_map(function($value) use($timestamp) {
158
159 18
            if($value instanceof \Closure)
160 18
            {
161 18
                $value = $value($timestamp);
162 18
            }
163
164 18
            return $value;
165
166 18
        }, $this->attributes);
167
    }
168
169 18
    private function packHeaders($timestamp)
170
    {
171 18
        $this->headers['message_datetime'] = date('Y-m-d H:i:s', $timestamp);
172
173 18
        return $this->headers;
174
    }
175
176 40
    public function setAttribute($attributeName, $value)
177
    {
178 40
        if($attributeName !== 'headers')
179 40
        {
180 40
            if(array_key_exists($attributeName, $this->attributes))
181 40
            {
182 40
                $this->attributes[$attributeName] = $value;
183
184 40
                if($attributeName === self::ATTRIBUTE_CONTENT_TYPE)
185 40
                {
186 3
                    $this->userContentType = $value;
187 3
                }
188 40
            }
189 40
        }
190
191 40
        return $this;
192
    }
193
194 10
    public function getHeaders()
195
    {
196 10
        $attributes = $this->packAttributes();
197
198 10
        return $attributes['headers'];
199
    }
200
201 36
    public function getAttribute($attributeName)
202
    {
203 36
        if(array_key_exists($attributeName, $this->attributes))
204 36
        {
205 35
            return $this->attributes[$attributeName];
206
        }
207
208 1
        throw new InvalidArgumentException(sprintf('Property "%s" is unknown or is not a message property', $attributeName));
209
    }
210
211 2
    public function __toString()
212
    {
213 2
        return json_encode(array(
214 2
            'routing_key' => $this->getRoutingKey(),
215 2
            'body' => (string) $this->body,
216 2
            'attributes' => $this->attributes,
217 2
            'can be dropped silently' => $this->canBeDroppedSilently
218 2
        ));
219
    }
220
221 1
    public function setExpiration($expirationInSeconds)
222
    {
223 1
        $ttlInMs = 1000 * (int) $expirationInSeconds;
224
225 1
        $this->setAttribute('expiration', (string) $ttlInMs);
226
227 1
        return $this;
228
    }
229
230 6
    public function isCompressionAllowed()
231
    {
232 6
        return $this->allowCompression;
233
    }
234
235 5
    public function allowCompression($allow = true)
236
    {
237 5
        $this->allowCompression = (bool) $allow;
238
239 5
        return $this;
240
    }
241
242 7
    public function isChunked()
243
    {
244 7
        return $this->body->isChunked();
245
    }
246
}
247