Passed
Push — main ( 221f6d...f8c128 )
by Siad
05:28
created

src/Phing/Filter/XincludeFilter.php (1 issue)

1
<?php
2
3
/**
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the LGPL. For more information please see
18
 * <http://phing.info>.
19
 */
20
21
namespace Phing\Filter;
22
23
use DOMDocument;
24
use Phing\Exception\BuildException;
25
use Phing\Io\File;
26
use Phing\Io\FilterReader;
27
use Phing\Io\IOException;
28
use Phing\Io\Reader;
29
use Phing\Project;
30
31
/**
32
 * Applies Xinclude parsing to incoming text.
33
 *
34
 * Uses PHP DOM XML support
35
 *
36
 * @author  Bill Karwin <[email protected]>
37
 *
38
 * @see     FilterReader
39
 */
40
class XincludeFilter extends BaseParamFilterReader implements ChainableReader
41
{
42
    /** @var File */
43
    private $basedir;
44
45
    /**
46
     * @var bool
47
     */
48
    private $processed = false;
49
50
    /**
51
     * Whether to resolve entities.
52
     *
53
     * @var bool
54
     *
55
     * @since 2.4
56
     */
57
    private $resolveExternals = false;
58
59
    /**
60
     * Whether to resolve entities.
61
     *
62
     * @param $resolveExternals
63
     *
64
     * @since 2.4
65
     */
66
    public function setResolveExternals(bool $resolveExternals)
67
    {
68
        $this->resolveExternals = $resolveExternals;
69
    }
70
71
    /**
72
     * @return bool
73
     *
74
     * @since 2.4
75
     */
76
    public function getResolveExternals()
77
    {
78
        return $this->resolveExternals;
79
    }
80
81
    public function setBasedir(File $dir)
82
    {
83
        $this->basedir = $dir;
84
    }
85
86
    /**
87
     * @return File
88
     */
89
    public function getBasedir()
90
    {
91
        return $this->basedir;
92
    }
93
94
    /**
95
     * Reads stream, applies XSLT and returns resulting stream.
96
     *
97
     * @param int $len
98
     *
99
     * @throws IOException
100
     * @throws BuildException
101
     *
102
     * @return string transformed buffer
103
     */
104
    public function read($len = null)
105
    {
106
        if (!class_exists('DOMDocument')) {
107
            throw new BuildException('Could not find the DOMDocument class. Make sure PHP has been compiled/configured to support DOM XML.');
108
        }
109
110
        if (true === $this->processed) {
111
            return -1; // EOF
112
        }
113
114
        // Read XML
115
        $_xml = null;
116
        while (($data = $this->in->read($len)) !== -1) {
117
            $_xml .= $data;
118
        }
119
120
        if (null === $_xml) { // EOF?
121
            return -1;
122
        }
123
124
        if (empty($_xml)) {
125
            $this->log('XML file is empty!', Project::MSG_WARN);
126
127
            return '';
128
        }
129
130
        $this->log('Transforming XML ' . $this->in->getResource() . ' using Xinclude ', Project::MSG_VERBOSE);
131
132
        $out = '';
0 ignored issues
show
The assignment to $out is dead and can be removed.
Loading history...
133
134
        try {
135
            $out = $this->process($_xml);
136
            $this->processed = true;
137
        } catch (IOException $e) {
138
            throw new BuildException($e);
139
        }
140
141
        return $out;
142
    }
143
144
    /**
145
     * Creates a new XincludeFilter using the passed in
146
     * Reader for instantiation.
147
     *
148
     * @param Reader A Reader object providing the underlying stream.
149
     *               Must not be <code>null</code>.
150
     *
151
     * @return XincludeFilter A new filter based on this configuration, but filtering
152
     *                        the specified reader
153
     */
154
    public function chain(Reader $reader): Reader
155
    {
156
        $newFilter = new self($reader);
157
        $newFilter->setProject($this->getProject());
158
        $newFilter->setBasedir($this->getBasedir());
159
160
        return $newFilter;
161
    }
162
163
    /**
164
     * Try to process the Xinclude transformation.
165
     *
166
     * @param string  XML to process
167
     * @param mixed $xml
168
     *
169
     * @return string
170
     */
171
    protected function process($xml)
172
    {
173
        if ($this->basedir) {
174
            $cwd = getcwd();
175
            chdir($this->basedir);
176
        }
177
178
        // Create and setup document.
179
        $xmlDom = new DOMDocument();
180
        $xmlDom->resolveExternals = $this->resolveExternals;
181
182
        $xmlDom->loadXML($xml);
183
184
        $xmlDom->xinclude();
185
186
        if ($this->basedir) {
187
            chdir($cwd);
188
        }
189
190
        return $xmlDom->saveXML();
191
    }
192
}
193