Test Failed
Push — master ( e258e4...a626ba )
by Zaahid
15:25
created

ContainerPart   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 15
eloc 33
c 2
b 0
f 0
dl 0
loc 97
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getChildParts() 0 3 1
B filterIgnoredSpaces() 0 25 8
A getErrorBagChildren() 0 3 1
A getValueFromParts() 0 3 1
A getComments() 0 5 2
A __construct() 0 13 2
1
<?php
2
/**
3
 * This file is part of the ZBateson\MailMimeParser project.
4
 *
5
 * @license http://opensource.org/licenses/bsd-license.php BSD
6
 */
7
8
namespace ZBateson\MailMimeParser\Header\Part;
9
10
use Psr\Log\LoggerInterface;
11
use ZBateson\MbWrapper\MbWrapper;
12
use ZBateson\MailMimeParser\ErrorBag;
13
14
/**
15
 * Base HeaderPart for a part that consists of other parts.
16
 *
17
 * @author Zaahid Bateson
18
 */
19
class ContainerPart extends HeaderPart
20
{
21
    /**
22
     * @var HeaderPart[] parts that were used to create this part, collected for
23
     *      proper error reporting and validation.
24
     */
25
    protected $children = [];
26
27
    public function __construct(
28
        LoggerInterface $logger,
29
        MbWrapper $charsetConverter,
30
        array $children
31
    ) {
32
        ErrorBag::__construct($logger);
33
        $this->charsetConverter = $charsetConverter;
34
        $this->children = $children;
35
        $str = (!empty($children)) ? $this->getValueFromParts($children) : '';
36
        parent::__construct(
37
            $logger,
38
            $this->charsetConverter,
39
            $str
40
        );
41
    }
42
43
    /**
44
     * Filters out ignorable space tokens.
45
     *
46
     * Spaces are removed if parts on either side of it have their
47
     * canIgnoreSpaceAfter/canIgnoreSpaceBefore properties set to true.
48
     *
49
     * @param HeaderPart[] $parts
50
     * @return HeaderPart[]
51
     */
52
    protected function filterIgnoredSpaces(array $parts) : array
53
    {
54
        $ends = (object) ['isSpace' => true, 'canIgnoreSpacesAfter' => true, 'canIgnoreSpacesBefore' => true, 'value' => ''];
55
56
        $spaced = \array_merge($parts, [$ends]);
57
        $filtered = \array_slice(\array_reduce(
58
            \array_slice(\array_keys($spaced), 0, -1),
59
            function ($carry, $key) use ($spaced, $ends) {
60
                $p = $spaced[$key];
61
                $l = \end($carry);
62
                $a = $spaced[$key + 1];
63
                if ($p->isSpace && $a === $ends) {
64
                    // trim
65
                    if ($l->isSpace) {
66
                        \array_pop($carry);
67
                    }
68
                    return $carry;
69
                } elseif ($p->isSpace && ($l->isSpace || ($l->canIgnoreSpacesAfter && $a->canIgnoreSpacesBefore))) {
70
                    return $carry;
71
                }
72
                return \array_merge($carry, [$p]);
73
            },
74
            [$ends]
75
        ), 1);
76
        return $filtered;
77
    }
78
79
    /**
80
     * Creates the string value representation of this part constructed from the
81
     * child parts passed to it.
82
     *
83
     * @param HeaderParts[] $parts
84
     */
85
    protected function getValueFromParts(array $parts) : string
86
    {
87
        return \array_reduce($this->filterIgnoredSpaces($parts), fn ($c, $p) => $c . $p->getValue(), '');
88
    }
89
90
    /**
91
     * Returns the child parts this container part consists of.
92
     *
93
     * @return IHeaderPart[]
94
     */
95
    public function getChildParts() : array
96
    {
97
        return $this->children;
98
    }
99
100
    public function getComments() : array
101
    {
102
        return \array_merge(...\array_filter(\array_map(
103
            fn ($p) => ($p instanceof CommentPart) ? [$p] : $p->getComments(),
104
            $this->children
105
        )));
106
    }
107
108
    /**
109
     * Returns this part's children, same as getChildParts().
110
     *
111
     * @return ErrorBag
112
     */
113
    protected function getErrorBagChildren() : array
114
    {
115
        return $this->children;
116
    }
117
}
118