Frame::setHeaders()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 3
eloc 6
nc 3
nop 1
1
<?php
2
3
/**
4
 * \AppserverIo\Stomp\Frame
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Lars Roettig <[email protected]>
15
 * @copyright 2016 TechDivision GmbH - <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      http://www.appserver.io/
18
 */
19
20
namespace AppserverIo\Stomp;
21
22
use AppserverIo\Stomp\Protocol\CommonValues;
23
use AppserverIo\Stomp\Protocol\Headers;
24
use AppserverIo\Stomp\Protocol\ServerCommands;
25
use AppserverIo\Stomp\Interfaces\FrameInterface;
26
27
/**
28
 * This class for stomp frame implementations.
29
 *
30
 * @author    Lars Roettig <[email protected]>
31
 * @copyright 2016 TechDivision GmbH - <[email protected]>
32
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
33
 * @link      http://www.appserver.io/
34
 * @link      https://github.com/stomp/stomp-spec/blob/master/src/stomp-specification-1.1.md
35
 */
36
class Frame implements FrameInterface
37
{
38
    /**
39
     * Holds the const for stomp frame colon.
40
     *
41
     * @var string
42
     */
43
    const COLON = ':';
44
45
    /**
46
     * Holds the const for stomp frame escape.
47
     *
48
     * @var string
49
     */
50
    const ESCAPE = '\\';
51
52
    /**
53
     * Holds the const for stomp frame newline.
54
     *
55
     * @var string
56
     */
57
    const NEWLINE = "\n";
58
59
    /**
60
     * Holds the const for stomp frame null.
61
     *
62
     * @var string
63
     */
64
    const NULL = "\x00";
65
66
    /**
67
     * Holds the message command.
68
     *
69
     * @var string
70
     */
71
    protected $command;
72
73
    /**
74
     * Holds the message headers.
75
     *
76
     * @var array
77
     */
78
    protected $headers;
79
80
    /**
81
     * Holds the message body.
82
     *
83
     * @var string
84
     */
85
    protected $body;
86
87
    /**
88
     * Create new stomp protocol frame.
89
     *
90
     * @param string $command The message command.
91
     * @param array  $headers The message headers.
92
     * @param string $body    The message body.
93
     */
94
    public function __construct($command = null, array $headers = array(), $body = "")
95
    {
96
        $this->setCommand($command);
97
        $this->setHeaders($headers);
98
        $this->setBody($body);
99
    }
100
101
    /**
102
     * Returns the message headers.
103
     *
104
     * @return array
105
     */
106
    public function getHeaders()
107
    {
108
        return $this->headers;
109
    }
110
111
    /**
112
     * Set the headers.
113
     *
114
     * @param array $headers The headers to set.
115
     *
116
     * @return void
117
     *
118
     * @link http://stomp.github.io/stomp-specification-1.1.html#Repeated_Header_Entries
119
     */
120
    public function setHeaders(array $headers)
121
    {
122
        // prevents override all ready set header key
123
        if (is_array($this->headers)) {
124
            foreach ($headers as $key => $value) {
125
                // set the value for the given header key.
126
                $this->setHeaderValueByKey($key, $value);
127
            }
128
        } else {
129
            $this->headers = $headers;
130
        }
131
    }
132
133
    /**
134
     * Returns the value for the given header key.
135
     *
136
     * @param string $key The header to find the value
137
     *
138
     * @return string|null
139
     */
140
    public function getHeaderValueByKey($key)
141
    {
142
        return isset($this->headers[$key]) ? $this->headers[$key] : null;
143
    }
144
145
    /**
146
     * Set the value for the given header key.
147
     *
148
     * @param string $key   The header to find the value
149
     * @param string $value The value to set
150
     *
151
     * @return void
152
     */
153
    public function setHeaderValueByKey($key, $value)
154
    {
155
        // ignore already set header element
156
        if (isset($this->headers[$key])) {
157
            return;
158
        }
159
160
        $this->headers[$key] = $value;
161
    }
162
163
    /**
164
     * Returns the message body.
165
     *
166
     * @return string
167
     */
168
    public function getBody()
169
    {
170
        return $this->body;
171
    }
172
173
    /**
174
     * Set the body for the frame.
175
     *
176
     * @param string $body The body to set.
177
     *
178
     * @return void
179
     */
180
    public function setBody($body)
181
    {
182
        $this->body = $body;
183
184
        if (strlen($body) > 0) {
185
            $this->setHeaderValueByKey(Headers::CONTENT_TYPE, CommonValues::TEXT_PLAIN);
186
            $this->setHeaderValueByKey(Headers::CONTENT_LENGTH, strlen($body));
187
        }
188
    }
189
190
    /**
191
     * Returns the frame object as string.
192
     *
193
     * @return string
194
     */
195
    public function __toString()
196
    {
197
        return $this->command .
198
        Frame::NEWLINE .
199
        $this->headersToString() .
200
        Frame::NEWLINE .
201
        $this->body .
202
        Frame::NULL .
203
        Frame::NEWLINE;
204
    }
205
206
    /**
207
     * Convert the frame headers to string.
208
     *
209
     * @return string
210
     */
211
    protected function headersToString()
212
    {
213
        $headerString = "";
214
215
        foreach ($this->headers as $key => $value) {
216
            $name = $this->encodeHeaderString($key);
217
            $value = $this->encodeHeaderString($value);
218
219
            $headerString .= $name . Frame::COLON . $value . Frame::NEWLINE;
220
        }
221
222
        return $headerString;
223
    }
224
225
    /**
226
     * Encode the header string as stomp header string.
227
     *
228
     * @param string $value The value to convert
229
     *
230
     * @return string
231
     */
232
    protected function encodeHeaderString($value)
233
    {
234
        // encode the header if encode header required.
235
        if ($this->getHeaderEncodingRequired()) {
236
            // escape "\n , : , \\" in value
237
            $value = strtr($value, array(
238
                Frame::NEWLINE => '\n',
239
                Frame::COLON   => '\c',
240
                Frame::ESCAPE  => '\\\\'
241
            ));
242
        }
243
244
        return $value;
245
    }
246
247
    /**
248
     * Returns is for the current frame encode header required.
249
     *
250
     * @return bool
251
     */
252
    protected function getHeaderEncodingRequired()
253
    {
254
        /*
255
         * CONNECTED frames do not escape the colon or newline octets
256
         * in order to remain backward compatible with STOMP 1.0.
257
         */
258
        if ($this->getCommand() === ServerCommands::CONNECTED) {
259
            return false;
260
        }
261
        return true;
262
    }
263
264
    /**
265
     * Returns the message command.
266
     *
267
     * @return string
268
     */
269
    public function getCommand()
270
    {
271
        return $this->command;
272
    }
273
274
    /**
275
     * Set the command for the frame.
276
     *
277
     * @param string $command The Command to set.
278
     *
279
     * @return void
280
     */
281
    public function setCommand($command)
282
    {
283
        $this->command = $command;
284
    }
285
}
286