Completed
Pull Request — master (#51)
by
unknown
05:38
created

XMLAdapter::getXmlErrors()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 19
ccs 15
cts 15
cp 1
rs 9.2
cc 4
eloc 13
nc 2
nop 1
crap 4
1
<?php
2
namespace Goetas\Twital\SourceAdapter;
3
4
use Goetas\Twital\SourceAdapter;
5
use Goetas\Twital\Template;
6
7
/**
8
 *
9
 * @author Asmir Mustafic <[email protected]>
10
 *
11
 */
12
class XMLAdapter implements SourceAdapter
13
{
14
    /**
15
     * {@inheritdoc}
16
     */
17 300
    public function load($source)
18
    {
19 300
        $dom = $this->createDom($source);
20
21 299
        return new Template($dom, $this->collectMetadata($dom, $source));
22
    }
23
24
    /**
25
     * Collect some metadata about $dom and $source
26
     * @param \DOMDocument $dom
27
     * @param string $source
28
     * @return mixed
29
     */
30 299
    protected function collectMetadata(\DOMDocument $dom, $source)
31
    {
32 299
        $metadata = array();
33
34 299
        $metadata['xmldeclaration'] = strpos(rtrim($source), '<?xml ') === 0;
35 299
        $metadata['doctype'] = !!$dom->doctype;
36
37 299
        return $metadata;
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 166
    public function dump(Template $template)
44
    {
45 166
        $metadata = $template->getMetadata();
46 166
        $dom = $template->getDocument();
47 166
        $dom->preserveWhiteSpace = true;
48 166
        $dom->formatOutput = false;
49
50 166
        if ($metadata['xmldeclaration']) {
51 1
            return $dom->saveXML();
52
        } else {
53 165
            $xml = '';
54 165
            foreach ($dom->childNodes as $node) {
55 165
                $xml .= $dom->saveXML($node);
56 165
                if ($node instanceof \DOMDocumentType) {
57 1
                    $xml .= PHP_EOL;
58 1
                }
59 165
            }
60
61 165
            return $xml;
62
        }
63
    }
64
65 300
    protected function createDom($source)
66
    {
67 300
        $internalErrors = libxml_use_internal_errors(true);
68 300
        $disableEntities = libxml_disable_entity_loader(true);
69 300
        libxml_clear_errors();
70
71 300
        $dom = new \DOMDocument('1.0', 'UTF-8');
72 300
        if (!$dom->loadXML($source, LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
73 1
            libxml_disable_entity_loader($disableEntities);
74
75 1
            throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($internalErrors)));
76
        }
77
78 299
        libxml_use_internal_errors($internalErrors);
79 299
        libxml_disable_entity_loader($disableEntities);
80
81 299
        return $dom;
82
    }
83
84 1
    protected function getXmlErrors($internalErrors)
85
    {
86 1
        $errors = array();
87 1
        foreach (libxml_get_errors() as $error) {
88 1
            $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
89 1
                LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
90 1
                $error->code,
91 1
                trim($error->message),
92 1
                $error->file ? $error->file : 'n/a',
93 1
                $error->line,
94 1
                $error->column
95 1
            );
96 1
        }
97
98 1
        libxml_clear_errors();
99 1
        libxml_use_internal_errors($internalErrors);
100
101 1
        return $errors;
102
    }
103
}
104