XmlTemplate::setXmlDocument()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
/*
4
 * Copyright (c) 2011-2015, Celestino Diaz <[email protected]>
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
25
namespace Brickoo\Component\Template;
26
27
use Brickoo\Component\Template\Exception;
28
use Brickoo\Component\Template\Exception\RenderingException;
29
use Brickoo\Component\Template\Exception\UnableToLoadFileException;
30
use Brickoo\Component\Template\Exception\XmlTransformationException;
31
use Brickoo\Component\Common\Assert;
32
use DOMDocument;
33
use LibXMLError;
34
use XSLTProcessor;
35
36
/**
37
 * XmlTemplate
38
 *
39
 * Implements a xml template with the
40
 * usage of the xslt processor.
41
 */
42
class XmlTemplate implements Template {
43
44
    /** @var string */
45
    private $xsltFilename;
46
47
    /** @var \DOMDocument */
48
    private $xmlDocument;
49
50
    /**
51
     * Class constructor.
52
     * @param \DOMDocument $xmlDocument
53
     * @param null|string $xsltFilename
54
     * @throws \InvalidArgumentException
55
     */
56 3
    public function __construct(DOMDocument $xmlDocument, $xsltFilename = null) {
57 3
        if ($xsltFilename !== null) {
58 2
            Assert::isString($xsltFilename);
59 1
        }
60 2
        $this->xsltFilename = $xsltFilename;
61 2
        $this->xmlDocument = $xmlDocument;
62 2
    }
63
64
    /**
65
     * Set XSLT filename.
66
     * @param string $xsltFilename
67
     * @throws \InvalidArgumentException
68
     * @return \Brickoo\Component\Template\XmlTemplate
69
     */
70 1
    public function setXsltFilename($xsltFilename) {
71 1
        Assert::isString($xsltFilename);
72 1
        $this->xsltFilename = $xsltFilename;
73 1
        return $this;
74
    }
75
76
    /**
77
     * Set the xml template document.
78
     * @param \DOMDocument $xmlDocument
79
     * @return \Brickoo\Component\Template\XmlTemplate
80
     */
81 1
    public function setXmlDocument(DOMDocument $xmlDocument) {
82 1
        $this->xmlDocument = $xmlDocument;
83 1
        return $this;
84
    }
85
86
    /** {@inheritdoc} */
87 4
    public function render() {
88 4
        if ($this->xsltFilename === null) {
89 1
            return $this->xmlDocument->saveXML();
90
        }
91
92 3
        $lastErrorsState = libxml_use_internal_errors(true);
93
        try {
94 3
            $processor = $this->createXsltProcessor();
95 2
            if (($output = @$processor->transformToXml($this->xmlDocument)) === false) {
96 1
                throw new XmlTransformationException($this->getLibXmlErrorMessage());
97
            }
98 1
            libxml_use_internal_errors($lastErrorsState);
99
        }
100 3
        catch (\Exception $exception) {
101 2
            libxml_use_internal_errors($lastErrorsState);
102 2
            throw new RenderingException($exception);
103
        }
104 1
        return $output;
105
    }
106
107
    /**
108
     * Create the XSLT processor.
109
     * @throws \Brickoo\Component\Template\Exception\XmlTransformationException
110
     * @return \XSLTProcessor
111
     */
112 2
    private function createXsltProcessor() {
113 2
        $xsltProcessor = new XSLTProcessor();
114 2
        $xsltProcessor->registerPHPFunctions();
115 2
        $xsltProcessor->importStylesheet($this->createStylesheet());
116 1
        return $xsltProcessor;
117
    }
118
119
    /**
120
     * Create the xslt processor stylesheet equal the xml document version and encoding.
121
     * @throws \Brickoo\Component\Template\Exception\UnableToLoadFileException
122
     * @return \DOMDocument
123
     */
124 2
    private function createStylesheet() {
125 2
        $stylesheet = new DOMDocument(
126 2
            $this->xmlDocument->xmlVersion, $this->xmlDocument->xmlEncoding
127 2
        );
128
129 2
        if (empty($this->xsltFilename)
130 2
            || (!file_exists($this->xsltFilename))
131 2
            || (!$stylesheet->load($this->xsltFilename))) {
132 1
                throw new UnableToLoadFileException($this->xsltFilename);
133
        }
134 1
        return $stylesheet;
135
    }
136
137
    /**
138
     * Return the concatenated error messages.
139
     * @return string the concatenated libXml messages
140
     */
141 1
    private function getLibXmlErrorMessage() {
142 1
        $errorMessage = "";
143 1
        foreach (libxml_get_errors() as $index => $error) {
144 1
            $errorMessage .= $this->getErrorMessage($index, $error);
145 1
        }
146 1
        libxml_clear_errors();
147 1
        return $errorMessage;
148
    }
149
150
    /**
151
     * Return a formatted error message.
152
     * @param integer $index
153
     * @param LibXMLError $error
154
     * @return string the formatted error message
155
     */
156 1
    private function getErrorMessage($index, LibXMLError $error) {
157 1
        return sprintf("%s%s", ($index > 0 ? "\n\t-> " : ""), rtrim($error->message, "\r\n"));
158
    }
159
160
}
161