Completed
Pull Request — master (#257)
by
unknown
01:57
created

XmlFormatter::setItems()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 7
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 6
1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of the feed-io package.
4
 *
5
 * (c) Alexandre Debril <[email protected]>
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
namespace FeedIo\Formatter;
12
13
use FeedIo\Feed\NodeInterface;
14
use FeedIo\FeedInterface;
15
use FeedIo\Rule\OptionalField;
16
use FeedIo\RuleSet;
17
use FeedIo\Standard\XmlAbstract;
18
use FeedIo\FormatterInterface;
19
20
/**
21
 * Turns a FeedInterface instance into a XML document.
22
 *
23
 * Depends on :
24
 *  - FeedIo\StandardAbstract
25
 *
26
 */
27
class XmlFormatter implements FormatterInterface
28
{
29
30
    /**
31
     * @var XmlAbstract
32
     */
33
    protected $standard;
34
35
    /**
36
     * @param XmlAbstract $standard
37
     */
38
    public function __construct(XmlAbstract $standard)
39
    {
40
        $this->standard = $standard;
41
    }
42
43
    /**
44
     * @param  \DOMDocument  $document
45
     * @param  FeedInterface $feed
46
     * @return XmlFormatter
47
     */
48
    public function setHeaders(\DOMDocument $document, FeedInterface $feed) : XmlFormatter
49
    {
50
        $rules = $this->standard->getFeedRuleSet();
51
        $mainElement = $this->standard->getMainElement($document);
52
        $this->buildElements($rules, $document, $mainElement, $feed);
53
54
        return $this;
55
    }
56
57
    /**
58
     * @param  \DOMDocument  $document
59
     * @param  NodeInterface $node
60
     * @return XmlFormatter
61
     */
62
    public function addItem(\DOMDocument $document, NodeInterface $node) : XmlFormatter
63
    {
64
        $domItem = $document->createElement($this->standard->getItemNodeName());
65
        $rules = $this->standard->getItemRuleSet();
66
        $this->buildElements($rules, $document, $domItem, $node);
67
68
        $this->standard->getMainElement($document)->appendChild($domItem);
69
70
        return $this;
71
    }
72
73
    /**
74
     * @param RuleSet $ruleSet
75
     * @param \DOMDocument $document
76
     * @param \DOMElement $rootElement
77
     * @param NodeInterface $node
78
     */
79
    public function buildElements(RuleSet $ruleSet, \DOMDocument $document, \DOMElement $rootElement, NodeInterface $node) : void
80
    {
81
        $rules = $this->getAllRules($ruleSet, $node);
82
83
        foreach ($rules as $rule) {
84
            $rule->apply($document, $rootElement, $node);
85
        }
86
    }
87
88
    /**
89
     * @param  RuleSet              $ruleSet
90
     * @param  NodeInterface        $node
91
     * @return iterable
92
     */
93
    public function getAllRules(RuleSet $ruleSet, NodeInterface $node) : iterable
94
    {
95
        $rules = $ruleSet->getRules();
96
        $optionalFields = $node->listElements();
97
        foreach ($optionalFields as $optionalField) {
98
            $rules[$optionalField] = new OptionalField($optionalField);
99
        }
100
101
        return $rules;
102
    }
103
104
    /**
105
     * @return \DOMDocument
106
     */
107
    public function getEmptyDocument() : \DOMDocument
108
    {
109
        return new \DOMDocument('1.0', 'utf-8');
110
    }
111
112
    /**
113
     * @return \DOMDocument
114
     */
115
    public function getDocument() : \DOMDocument
116
    {
117
        $document = $this->getEmptyDocument();
118
119
        return $this->standard->format($document);
120
    }
121
122
    /**
123
     * @param  FeedInterface $feed
124
     * @return string
125
     */
126
    public function toString(FeedInterface $feed) : string
127
    {
128
        $document = $this->toDom($feed);
129
130
        return $document->saveXML();
131
    }
132
133
    /**
134
     * @param  FeedInterface $feed
135
     * @return \DomDocument
136
     */
137
    public function toDom(FeedInterface $feed) : \DOMDocument
138
    {
139
        $document = $this->getDocument();
140
141
        $this->setHeaders($document, $feed);
142
        $this->setItems($document, $feed);
143
        $this->setNS($document, $feed);
144
145
        return $document;
146
    }
147
148
    public function setNS(\DOMDocument $document, FeedInterface $feed)
149
    {
150
        $firstChild = $document->firstChild;
151
        foreach ($feed->getNS() as $namespace => $dtd) {
152
            $firstChild->setAttributeNS(
153
                'http://www.w3.org/2000/xmlns/', // xmlns namespace URI
154
                'xmlns:'.$namespace,
155
                $dtd
156
            );
157
        }
158
    }
159
160
    /**
161
     * @param  \DOMDocument  $document
162
     * @param  FeedInterface $feed
163
     * @return XmlFormatter
164
     */
165
    public function setItems(\DOMDocument $document, FeedInterface $feed) : XmlFormatter
166
    {
167
        foreach ($feed as $item) {
168
            $this->addItem($document, $item);
169
        }
170
171
        return $this;
172
    }
173
}
174