Completed
Push — master ( 5db245...cdc2ed )
by Markus
17s queued 14s
created

Component::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * This file is part of the eluceo/iCal package.
5
 *
6
 * (c) Markus Poerschke <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Eluceo\iCal;
13
14
use Eluceo\iCal\Util\ComponentUtil;
15
16
/**
17
 * Abstract Calender Component.
18
 */
19
abstract class Component
20
{
21
    /**
22
     * Array of Components.
23
     *
24
     * @var Component[]
25
     */
26
    protected $components = [];
27
28
    /**
29
     * The order in which the components will be rendered during build.
30
     *
31
     * Not defined components will be appended at the end.
32
     *
33
     * @var array
34
     */
35
    private $componentsBuildOrder = ['VTIMEZONE', 'DAYLIGHT', 'STANDARD'];
36
37
    /**
38
     * The type of the concrete Component.
39
     *
40
     * @abstract
41
     *
42
     * @return string
43
     */
44
    abstract public function getType();
45
46
    /**
47
     * Building the PropertyBag.
48
     *
49
     * @abstract
50
     *
51
     * @return PropertyBag
52
     */
53
    abstract public function buildPropertyBag();
54
55
    /**
56
     * Adds a Component.
57
     *
58
     * If $key is given, the component at $key will be replaced else the component will be append.
59
     *
60
     * @param Component $component The Component that will be added
61
     * @param null      $key       The key of the Component
62
     */
63 8
    public function addComponent(self $component, $key = null)
64
    {
65 8
        if (null == $key) {
66 7
            $this->components[] = $component;
67
        } else {
68 1
            $this->components[$key] = $component;
69
        }
70 8
    }
71
72
    /**
73
     * Renders an array containing the lines of the iCal file.
74
     *
75
     * @return array
76
     */
77 17
    public function build()
78
    {
79 17
        $lines = [];
80
81 17
        $lines[] = sprintf('BEGIN:%s', $this->getType());
82
83
        /** @var $property Property */
84 17
        foreach ($this->buildPropertyBag() as $property) {
85 17
            foreach ($property->toLines() as $l) {
86 17
                $lines[] = $l;
87
            }
88
        }
89
90 17
        $this->buildComponents($lines);
91
92 17
        $lines[] = sprintf('END:%s', $this->getType());
93
94 17
        $ret = [];
95
96 17
        foreach ($lines as $line) {
97 17
            foreach (ComponentUtil::fold($line) as $l) {
98 17
                $ret[] = $l;
99
            }
100
        }
101
102 17
        return $ret;
103
    }
104
105
    /**
106
     * Renders the output.
107
     *
108
     * @return string
109
     */
110 17
    public function render()
111
    {
112 17
        return implode("\r\n", $this->build());
113
    }
114
115
    /**
116
     * Renders the output when treating the class as a string.
117
     *
118
     * @return string
119
     */
120 1
    public function __toString()
121
    {
122 1
        return $this->render();
123
    }
124
125
    /**
126
     * @param $lines
127
     *
128
     * @return array
129
     */
130 17
    private function buildComponents(array &$lines)
131
    {
132 17
        $componentsByType = [];
133
134
        /** @var $component Component */
135 17
        foreach ($this->components as $component) {
136 8
            $type = $component->getType();
137 8
            if (!isset($componentsByType[$type])) {
138 8
                $componentsByType[$type] = [];
139
            }
140 8
            $componentsByType[$type][] = $component;
141
        }
142
143
        // render ordered components
144 17
        foreach ($this->componentsBuildOrder as $type) {
145 17
            if (!isset($componentsByType[$type])) {
146 17
                continue;
147
            }
148 2
            foreach ($componentsByType[$type] as $component) {
149 2
                $this->addComponentLines($lines, $component);
150
            }
151 2
            unset($componentsByType[$type]);
152
        }
153
154
        // render all other
155 17
        foreach ($componentsByType as $components) {
156 6
            foreach ($components as $component) {
157 6
                $this->addComponentLines($lines, $component);
158
            }
159
        }
160 17
    }
161
162
    /**
163
     * @param array     $lines
164
     * @param Component $component
165
     */
166 8
    private function addComponentLines(array &$lines, self $component)
167
    {
168 8
        foreach ($component->build() as $l) {
169 8
            $lines[] = $l;
170
        }
171 8
    }
172
}
173