Completed
Push — 5.x ( 158fb7...5eecd4 )
by Lars
06:12
created

Swift_Mime_SimpleHeaderSet::_storeHeader()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 4
nop 3
dl 0
loc 14
ccs 10
cts 10
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of SwiftMailer.
5
 * (c) 2004-2009 Chris Corbyn
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
/**
12
 * A collection of MIME headers.
13
 *
14
 * @author Chris Corbyn
15
 */
16
class Swift_Mime_SimpleHeaderSet implements Swift_Mime_HeaderSet
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
17
{
18
    /**
19
     * HeaderFactory
20
     *
21
     * @var Swift_Mime_HeaderFactory
22
     */
23
    private $_factory;
24
25
    /**
26
     * Collection of set Headers
27
     *
28
     * @var array[]
29
     */
30
    private $_headers = array();
31
32
    /**
33
     * Field ordering details
34
     *
35
     * @var array
36
     */
37
    private $_order = array();
38
39
    /**
40
     * List of fields which are required to be displayed
41
     *
42
     * @var array
43
     */
44
    private $_required = array();
45
46
    /**
47
     * The charset used by Headers
48
     */
49
    private $_charset;
50
51
    /**
52
     * Create a new SimpleHeaderSet with the given $factory.
53
     *
54
     * @param Swift_Mime_HeaderFactory $factory
55
     * @param string                   $charset
56
     */
57 226
    public function __construct(Swift_Mime_HeaderFactory $factory, $charset = null)
58
    {
59 226
        $this->_factory = $factory;
60 226
        if (isset($charset)) {
61 80
            $this->setCharset($charset);
62 80
        }
63 226
    }
64
65
    /**
66
     * Set the charset used by these headers.
67
     *
68
     * @param string $charset
69
     */
70 108
    public function setCharset($charset)
71
    {
72 108
        if ($charset) {
73 108
            $this->_charset = $charset;
74 108
            $this->_factory->charsetChanged($charset);
75 108
            $this->_notifyHeadersOfCharset($charset);
76 108
        }
77 108
    }
78
79
    /**
80
     * Add a new Mailbox Header with a list of $addresses.
81
     *
82
     * @param string       $name
83
     * @param array|string $addresses
84
     */
85 147
    public function addMailboxHeader($name, $addresses = null)
86
    {
87 147
        $this->_storeHeader($name, $this->_factory->createMailboxHeader($name, $addresses));
88 147
    }
89
90
    /**
91
     * Add a new Date header using $timestamp (UNIX time).
92
     *
93
     * @param string $name
94
     * @param int    $timestamp
95
     */
96 147
    public function addDateHeader($name, $timestamp = null)
97
    {
98 147
        $this->_storeHeader($name, $this->_factory->createDateHeader($name, $timestamp));
99 147
    }
100
101
    /**
102
     * Add a new basic text header with $name and $value.
103
     *
104
     * @param string $name
105
     * @param string $value
106
     */
107 188
    public function addTextHeader($name, $value = null)
108
    {
109 188
        $this->_storeHeader($name, $this->_factory->createTextHeader($name, $value));
110 188
    }
111
112
    /**
113
     * Add a new ParameterizedHeader with $name, $value and $params.
114
     *
115
     * @param string $name
116
     * @param string $value
117
     * @param array  $params
118
     */
119 181
    public function addParameterizedHeader($name, $value = null, $params = array())
120
    {
121 181
        $this->_storeHeader($name, $this->_factory->createParameterizedHeader($name, $value, $params));
122 181
    }
123
124
    /**
125
     * Add a new ID header for Message-ID or Content-ID.
126
     *
127
     * @param string       $name
128
     * @param string|array $ids
129
     */
130 176
    public function addIdHeader($name, $ids = null)
131
    {
132 176
        $this->_storeHeader($name, $this->_factory->createIdHeader($name, $ids));
133 176
    }
134
135
    /**
136
     * Add a new Path header with an address (path) in it.
137
     *
138
     * @param string $name
139
     * @param string $path
140
     */
141 47
    public function addPathHeader($name, $path = null)
142 1
    {
143 47
        $this->_storeHeader($name, $this->_factory->createPathHeader($name, $path));
144 47
    }
145
146
    /**
147
     * Returns true if at least one header with the given $name exists.
148
     *
149
     * If multiple headers match, the actual one may be specified by $index.
150
     *
151
     * @param string $name
152
     * @param int    $index
153
     *
154
     * @return bool
155
     */
156 202
    public function has($name, $index = 0)
157
    {
158 202
        $lowerName = Swift::strtolowerWithStaticCache($name);
159
160 202
        if (!array_key_exists($lowerName, $this->_headers)) {
161 183
            return false;
162
        }
163
164 198
        if (func_num_args() < 2) {
165
            // index was not specified, so we only need to check that there is at least one header value set
166 193
            return (bool) count($this->_headers[$lowerName]);
167 1
        }
168
169 6
        if (isset($this->_headers[$lowerName][$index])) {
170 5
            return true;
171
        } else {
172 2
            return false;
173
        }
174
    }
175
176
    /**
177
     * Set a header in the HeaderSet.
178
     *
179
     * The header may be a previously fetched header via {@link get()} or it may
180
     * be one that has been created separately.
181
     *
182
     * If $index is specified, the header will be inserted into the set at this
183
     * offset.
184
     *
185
     * @param Swift_Mime_Header $header
186
     * @param int               $index
187
     */
188 5
    public function set(Swift_Mime_Header $header, $index = 0)
189
    {
190 5
        $this->_storeHeader($header->getFieldName(), $header, $index);
191 5
    }
192
193
    /**
194
     * Get the header with the given $name.
195
     *
196
     * If multiple headers match, the actual one may be specified by $index.
197
     * Returns NULL if none present.
198
     *
199
     * @param string $name
200
     * @param int    $index
201
     *
202
     * @return Swift_Mime_Header
203
     */
204 183
    public function get($name, $index = 0)
205
    {
206 183
        $name = Swift::strtolowerWithStaticCache($name);
207
208 183
        if (func_num_args() < 2) {
209 181
            if ($this->has($name)) {
210 181
                $values = array_values($this->_headers[$name]);
211
212 181
                return array_shift($values);
213
            }
214
        } else {
215 2
            if ($this->has($name, $index)) {
216 1
                return $this->_headers[$name][$index];
217
            }
218
        }
219 1
    }
220
221
    /**
222
     * Get all headers with the given $name.
223
     *
224
     * @param string $name
225
     *
226
     * @return array
227
     */
228 16
    public function getAll($name = null)
229
    {
230 16
        if (!isset($name)) {
231 1
            $headers = array();
232 1
            foreach ($this->_headers as $collection) {
233 1
                $headers = array_merge($headers, $collection);
234 1
            }
235
236 1
            return $headers;
237
        }
238
239 15
        $lowerName = Swift::strtolowerWithStaticCache($name);
240 15
        if (!isset($this->_headers[$lowerName])) {
241 10
            return array();
242
        }
243
244 14
        return $this->_headers[$lowerName];
245
    }
246
247
    /**
248
     * Return the name of all Headers.
249
     *
250
     * @return array
251
     */
252
    public function listAll()
253
    {
254
        $headers = $this->_headers;
255
        if ($this->_canSort()) {
256
            uksort($headers, array($this, '_sortHeaders'));
257
        }
258
259
        return array_keys($headers);
260
    }
261
262
    /**
263
     * Remove the header with the given $name if it's set.
264
     *
265
     * If multiple headers match, the actual one may be specified by $index.
266
     *
267
     * @param string $name
268
     * @param int    $index
269
     */
270 58
    public function remove($name, $index = 0)
271
    {
272 58
        $lowerName = Swift::strtolowerWithStaticCache($name);
273 58
        unset($this->_headers[$lowerName][$index]);
274 58
    }
275
276
    /**
277
     * Remove all headers with the given $name.
278
     *
279
     * @param string $name
280
     */
281 6
    public function removeAll($name)
282
    {
283 6
        $lowerName = Swift::strtolowerWithStaticCache($name);
284 6
        unset($this->_headers[$lowerName]);
285 6
    }
286
287
    /**
288
     * Create a new instance of this HeaderSet.
289
     *
290
     * @return self
291
     */
292 32
    public function newInstance()
293
    {
294 32
        return new self($this->_factory);
295
    }
296
297
    /**
298
     * Define a list of Header names as an array in the correct order.
299
     *
300
     * These Headers will be output in the given order where present.
301
     *
302
     * @param array $sequence
303
     */
304 181
    public function defineOrdering(array $sequence)
305
    {
306 181
        $this->_order = array_flip(array_map(array('Swift', 'strtolowerWithStaticCache'), $sequence));
307 181
    }
308
309
    /**
310
     * Set a list of header names which must always be displayed when set.
311
     *
312
     * Usually headers without a field value won't be output unless set here.
313
     *
314
     * @param array $names
315
     */
316 146
    public function setAlwaysDisplayed(array $names)
317
    {
318 146
        $this->_required = array_flip(array_map(array('Swift', 'strtolowerWithStaticCache'), $names));
319 146
    }
320
321
    /**
322
     * Notify this observer that the entity's charset has changed.
323
     *
324
     * @param string $charset
325
     */
326 94
    public function charsetChanged($charset)
327
    {
328 94
        $this->setCharset($charset);
329 94
    }
330
331
    /**
332
     * Returns a string with a representation of all headers.
333
     *
334
     * @return string
335
     */
336 171
    public function toString()
337
    {
338 171
        $string = '';
339 171
        $headers = $this->_headers;
340 171
        if ($this->_canSort()) {
341 168
            uksort($headers, array($this, '_sortHeaders'));
342 168
        }
343 171
        foreach ($headers as $collection) {
344 171
            foreach ($collection as $header) {
345
                /* @var $header Swift_Mime_Header */
346 171
                if ($this->_isDisplayed($header) || $header->getFieldBody() != '') {
347 171
                    $string .= $header->toString();
348 171
                }
349 171
            }
350 171
        }
351
352 171
        return $string;
353
    }
354
355
    /**
356
     * Returns a string representation of this object.
357
     *
358
     * @return string
359
     *
360
     * @see toString()
361
     */
362
    public function __toString()
363
    {
364
        return $this->toString();
365
    }
366
367
    /**
368
     * Save a Header to the internal collection
369
     *
370
     * @param string            $name
371
     * @param Swift_Mime_Header $header
372
     * @param null|int          $offset
373
     */
374 216
    private function _storeHeader($name, Swift_Mime_Header $header, $offset = null)
375
    {
376 216
        $lowerName = Swift::strtolowerWithStaticCache($name);
377
378 216
        if (!isset($this->_headers[$lowerName])) {
379 216
            $this->_headers[$lowerName] = array();
380 216
        }
381
382 216
        if (!isset($offset)) {
383 215
            $this->_headers[$lowerName][] = $header;
384 215
        } else {
385 5
            $this->_headers[$lowerName][$offset] = $header;
386
        }
387 216
    }
388
389
    /** Test if the headers can be sorted */
390 171
    private function _canSort()
391
    {
392 171
        return count($this->_order) > 0;
393
    }
394
395
    /**
396
     * uksort() algorithm for Header ordering
397
     *
398
     * @param string $a
399
     * @param string $b
400
     *
401
     * @return int
402
     */
403 168
    private function _sortHeaders($a, $b)
404
    {
405 168
        $lowerA = Swift::strtolowerWithStaticCache($a);
406 168
        $lowerB = Swift::strtolowerWithStaticCache($b);
407 168
        $aPos = isset($this->_order[$lowerA]) ? $this->_order[$lowerA] : -1;
408 168
        $bPos = isset($this->_order[$lowerB]) ? $this->_order[$lowerB] : -1;
409
410 168
        if (-1 === $aPos && -1 === $bPos) {
411
            // just be sure to be determinist here
412 27
            return $a > $b ? -1 : 1;
413
        }
414
415 168
        if ($aPos === -1) {
416 57
            return 1;
417 168
        } elseif ($bPos === -1) {
418 53
            return -1;
419
        }
420
421 168
        return $aPos < $bPos ? -1 : 1;
422
    }
423
424
    /**
425
     * Test if the given Header is always displayed
426
     *
427
     * @param Swift_Mime_Header $header
428
     *
429
     * @return bool
430
     */
431 171
    private function _isDisplayed(Swift_Mime_Header $header)
432
    {
433 171
        if (isset($this->_required[Swift::strtolowerWithStaticCache($header->getFieldName())])) {
434 133
            return true;
435
        } else {
436 170
            return false;
437
        }
438
    }
439
440
    /**
441
     * Notify all Headers of the new charset
442
     *
443
     * @param $charset
444
     */
445 108
    private function _notifyHeadersOfCharset($charset)
446
    {
447 108
        foreach ($this->_headers as $headerGroup) {
448 95
            foreach ($headerGroup as $header) {
449
                /* @var $header Swift_Mime_Header */
450 95
                $header->setCharset($charset);
451 95
            }
452 108
        }
453 108
    }
454
455
    /**
456
     * Make a deep copy of object.
457
     */
458 4
    public function __clone()
459
    {
460 4
        $this->_factory = clone $this->_factory;
461
462 4
        foreach ($this->_headers as $groupKey => $headerGroup) {
463 4
            foreach ($headerGroup as $key => $header) {
464 4
                $this->_headers[$groupKey][$key] = clone $header;
465 4
            }
466 4
        }
467 4
    }
468
}
469