Completed
Push — master ( dd3331...582aec )
by Jan-Petter
01:57
created

Render::renderOutline()   D

Complexity

Conditions 9
Paths 11

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 25
rs 4.909
cc 9
eloc 15
nc 11
nop 2
1
<?php
2
namespace vipnytt\OPMLParser;
3
4
use SimpleXMLElement;
5
6
class Render implements OPMLInterface
7
{
8
    /**
9
     * Version to use for the build
10
     * 2.0 - `text` attribute is required
11
     * 1.0 - for legacy support
12
     * @var string
13
     */
14
    protected $version;
15
16
    /**
17
     * Rendered XML object
18
     * @var SimpleXMLElement
19
     */
20
    protected $object;
21
22
    /**
23
     * Constructor
24
     *
25
     * @param array $array is the array we want to render and must follow structure defined above
26
     * @param string $encoding character encoding to use
27
     * @param string $version '2.0' if `text` attribute is required, '1.0' for legacy
28
     * @throws Exceptions\RenderException
29
     */
30
    public function __construct($array, $encoding = self::ENCODING, $version = self::VERSION_DEFAULT)
31
    {
32
        $this->version = $version;
33
        if (!in_array($this->version, self::SUPPORTED_VERSIONS)) {
34
            throw new Exceptions\RenderException('OPML version `' . $this->version . '` not supported');
35
        }
36
        $opml = new SimpleXMLElement('<?xml version="1.0" encoding="' . $encoding . '"?><opml></opml>');
37
        $opml->addAttribute('version', (string)$this->version);
38
        // Create head element. It is optional but head element will exist in the final XML object.
39
        $head = $opml->addChild('head');
40
        if (isset($array['head'])) {
41
            foreach ($array['head'] as $key => $value) {
42
                if (in_array($key, self::OPTIONAL_HEAD_ELEMENTS, true)) {
43
                    $head->addChild($key, $value);
44
                }
45
            }
46
        }
47
        // Check body is set and contains at least one element
48
        if (!isset($array['body'])) {
49
            throw new Exceptions\RenderException('The body element is missing');
50
        }
51
        // Create outline elements
52
        $body = $opml->addChild('body');
53
        foreach ($array['body'] as $outline) {
54
            $this->renderOutline($body, $outline);
55
        }
56
        $this->object = $opml;
57
    }
58
59
    /**
60
     * Create a XML outline object in a parent object.
61
     *
62
     * @param SimpleXMLElement $parent is the parent object of current outline
63
     * @param array $outline array representing an outline object
64
     * @return void
65
     * @throws Exceptions\RenderException
66
     */
67
    protected function renderOutline($parent, $outline)
68
    {
69
        $outlineSub = $parent->addChild('outline');
70
        $textIsPresent = false;
71
        foreach ($outline as $key => $value) {
72
            // Only outlines can be an array and so we consider children are also outline elements.
73
            if ($key === '@outlines' && is_array($value)) {
74
                foreach ($value as $outlineChild) {
75
                    $this->renderOutline($outlineSub, $outlineChild);
76
                }
77
            } elseif (is_array($value)) {
78
                throw new Exceptions\RenderException('Type of outline elements cannot be array: ' . $key);
79
            } else {
80
                // Detect text attribute is present, that's good :)
81
                if ($key === 'text') {
82
                    $textIsPresent = true;
83
                }
84
85
                $outlineSub->addAttribute($key, $value);
86
            }
87
        }
88
        if (!$textIsPresent && $this->version == '2.0') {
89
            throw new Exceptions\RenderException('The text element must be present for all outlines (applies to version 2.0 only)');
90
        }
91
    }
92
93
    /**
94
     * Return as a XML object
95
     *
96
     * @return SimpleXMLElement
97
     */
98
    public function asXMLObject()
99
    {
100
        return $this->object;
101
    }
102
}
103