Completed
Push — issue/96 ( 542eb1...939878 )
by Alex
02:21
created

XmlParser::handleNode()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 2
nop 3
crap 3
1
<?php
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\Parser;
12
13
14
use DOMDocument;
15
use FeedIo\Parser;
16
use FeedIo\RuleSet;
17
use FeedIo\FeedInterface;
18
use FeedIo\Feed\ItemInterface;
19
use FeedIo\Feed\NodeInterface;
20
use FeedIo\ParserAbstract;
21
use FeedIo\Reader\Document;
22
use FeedIo\Parser\MissingFieldsException;
23
use FeedIo\Parser\UnsupportedFormatException;
24
use Psr\Log\LoggerInterface;
25
26
/**
27
 * Parses a DOM document if its format matches the parser's standard
28
 *
29
 * Depends on :
30
 *  - FeedIo\StandardAbstract
31
 *  - Psr\Log\LoggerInterface
32
 *
33
 */
34
class XmlParser extends ParserAbstract
35
{
36
37
    /**
38
     * @param $tagName
39
     * @return bool
40
     */
41 7
    public function isItem($tagName)
42
    {
43 7
        return (strtolower($this->standard->getItemNodeName()) === strtolower($tagName));
44
    }
45
46
    /**
47
     * @param  Document                       $document
48
     * @param  FeedInterface                     $feed
49
     * @return \FeedIo\FeedInterface
50
     * @throws Parser\MissingFieldsException
51
     * @throws Parser\UnsupportedFormatException
52
     */
53 9
    public function parse(Document $document, FeedInterface $feed)
54
    {
55 9
        if (!$this->standard->canHandle($document)) {
56 1
            throw new UnsupportedFormatException('this is not a supported format');
57
        }
58
59 8
        $this->checkBodyStructure($document, $this->standard->getMandatoryFields());
60 7
        $element = $this->standard->getMainElement($document->getDOMDocument());
61
62 7
        $this->parseNode($feed, $element, $this->standard->getFeedRuleSet());
63
64 7
        return $feed;
65
    }
66
67
    /**
68
     * @param  Document            $document
69
     * @param  array                  $mandatoryFields
70
     * @return $this
71
     * @throws MissingFieldsException
72
     */
73 10
    public function checkBodyStructure(Document $document, array $mandatoryFields)
74
    {
75 10
        $errors = array();
76
77 10
        $element = $document->getDOMDocument()->documentElement;
78 10
        foreach ($mandatoryFields as $field) {
79 6
            $list = $element->getElementsByTagName($field);
80 6
            if (0 === $list->length) {
81 2
                $errors[] = $field;
82 2
            }
83 10
        }
84
85 10
        if (!empty($errors)) {
86 2
            $message = "missing mandatory field(s) : ".implode(',', $errors);
87 2
            $this->logger->warning($message);
88 2
            throw new MissingFieldsException($message);
89
        }
90
91 8
        return $this;
92
    }
93
94
    /**
95
     * @param  NodeInterface $item
96
     * @param  \DOMElement   $element
97
     * @param  RuleSet       $ruleSet
98
     * @return NodeInterface
99
     */
100 8
    public function parseNode(NodeInterface $item, \DOMElement $element, RuleSet $ruleSet)
101
    {
102 8
        foreach ($element->childNodes as $node) {
103 7
            if ($node instanceof \DOMElement) {
104 7
                $this->handleNode($item, $node, $ruleSet);
105 7
            }
106 8
        }
107
108 8
        return $item;
109
    }
110
111
    /**
112
     * @param NodeInterface $item
113
     * @param \DOMElement $node
114
     * @param RuleSet $ruleSet
115
     * @return $this
116
     */
117 7
    protected function handleNode(NodeInterface $item, \DOMElement $node, RuleSet $ruleSet)
118
    {
119 7
        if ($this->isItem($node->tagName) && $item instanceof FeedInterface) {
120 6
            $newItem = $this->parseNode($item->newItem(), $node, $this->standard->getItemRuleSet());
121 6
            $this->addValidItem($item, $newItem);
122 6
        } else {
123 7
            $rule = $ruleSet->get($node->tagName);
124 7
            $rule->setProperty($item, $node);
125
        }
126
127 7
        return $this;
128
    }
129
130
131
}