PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.4.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.4.1
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / vendor / openspout / openspout / src / Reader / Wrapper / XMLReader.php

XMLReader.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.4.1, at vendor/openspout/openspout/src/Reader/Wrapper/XMLReader.php

168 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\OpenSpout\Reader\Wrapper;
4
5 /**
6 * Wrapper around the built-in XMLReader.
7 *
8 * @see \XMLReader
9 */
10 class XMLReader extends \XMLReader
11 {
12 use XMLInternalErrorsHelper;
13 public const ZIP_WRAPPER = 'zip://';
14 /**
15 * Opens the XML Reader to read a file located inside a ZIP file.
16 *
17 * @param string $zipFilePath Path to the ZIP file
18 * @param string $fileInsideZipPath Relative or absolute path of the file inside the zip
19 *
20 * @return bool TRUE on success or FALSE on failure
21 */
22 public function openFileInZip($zipFilePath, $fileInsideZipPath)
23 {
24 $wasOpenSuccessful = \false;
25 $realPathURI = $this->getRealPathURIForFileInZip($zipFilePath, $fileInsideZipPath);
26 // We need to check first that the file we are trying to read really exist because:
27 // - PHP emits a warning when trying to open a file that does not exist.
28 // - HHVM does not check if file exists within zip file (@link https://github.com/facebook/hhvm/issues/5779)
29 if ($this->fileExistsWithinZip($realPathURI)) {
30 $wasOpenSuccessful = $this->open($realPathURI, null, \LIBXML_NONET);
31 }
32 return $wasOpenSuccessful;
33 }
34 /**
35 * Returns the real path for the given path components.
36 * This is useful to avoid issues on some Windows setup.
37 *
38 * @param string $zipFilePath Path to the ZIP file
39 * @param string $fileInsideZipPath Relative or absolute path of the file inside the zip
40 *
41 * @return string The real path URI
42 */
43 public function getRealPathURIForFileInZip($zipFilePath, $fileInsideZipPath)
44 {
45 // The file path should not start with a '/', otherwise it won't be found
46 $fileInsideZipPathWithoutLeadingSlash = \ltrim($fileInsideZipPath, '/');
47 return self::ZIP_WRAPPER . \realpath($zipFilePath) . '#' . $fileInsideZipPathWithoutLeadingSlash;
48 }
49 /**
50 * Move to next node in document.
51 *
52 * @see \XMLReader::read
53 *
54 * @throws \OpenSpout\Reader\Exception\XMLProcessingException If an error/warning occurred
55 *
56 * @return bool TRUE on success or FALSE on failure
57 */
58 #[\ReturnTypeWillChange]
59 public function read()
60 {
61 $this->useXMLInternalErrors();
62 $wasReadSuccessful = parent::read();
63 $this->resetXMLInternalErrorsSettingAndThrowIfXMLErrorOccured();
64 return $wasReadSuccessful;
65 }
66 /**
67 * Read until the element with the given name is found, or the end of the file.
68 *
69 * @param string $nodeName Name of the node to find
70 *
71 * @throws \OpenSpout\Reader\Exception\XMLProcessingException If an error/warning occurred
72 *
73 * @return bool TRUE on success or FALSE on failure
74 */
75 public function readUntilNodeFound($nodeName)
76 {
77 do {
78 $wasReadSuccessful = $this->read();
79 $isNotPositionedOnStartingNode = !$this->isPositionedOnStartingNode($nodeName);
80 } while ($wasReadSuccessful && $isNotPositionedOnStartingNode);
81 return $wasReadSuccessful;
82 }
83 /**
84 * Move cursor to next node skipping all subtrees.
85 *
86 * @see \XMLReader::next
87 *
88 * @param null|string $localName The name of the next node to move to
89 *
90 * @throws \OpenSpout\Reader\Exception\XMLProcessingException If an error/warning occurred
91 *
92 * @return bool TRUE on success or FALSE on failure
93 */
94 #[\ReturnTypeWillChange]
95 public function next($localName = null)
96 {
97 $this->useXMLInternalErrors();
98 $wasNextSuccessful = parent::next($localName);
99 $this->resetXMLInternalErrorsSettingAndThrowIfXMLErrorOccured();
100 return $wasNextSuccessful;
101 }
102 /**
103 * @param string $nodeName
104 *
105 * @return bool Whether the XML Reader is currently positioned on the starting node with given name
106 */
107 public function isPositionedOnStartingNode($nodeName)
108 {
109 return $this->isPositionedOnNode($nodeName, self::ELEMENT);
110 }
111 /**
112 * @param string $nodeName
113 *
114 * @return bool Whether the XML Reader is currently positioned on the ending node with given name
115 */
116 public function isPositionedOnEndingNode($nodeName)
117 {
118 return $this->isPositionedOnNode($nodeName, self::END_ELEMENT);
119 }
120 /**
121 * @return string The name of the current node, un-prefixed
122 */
123 public function getCurrentNodeName()
124 {
125 return $this->localName;
126 }
127 /**
128 * Returns whether the file at the given location exists.
129 *
130 * @param string $zipStreamURI URI of a zip stream, e.g. "zip://file.zip#path/inside.xml"
131 *
132 * @return bool TRUE if the file exists, FALSE otherwise
133 */
134 protected function fileExistsWithinZip($zipStreamURI)
135 {
136 $doesFileExists = \false;
137 $pattern = '/zip:\\/\\/([^#]+)#(.*)/';
138 if (\preg_match($pattern, $zipStreamURI, $matches)) {
139 $zipFilePath = $matches[1];
140 $innerFilePath = $matches[2];
141 $zip = new \ZipArchive();
142 if (\true === $zip->open($zipFilePath)) {
143 $doesFileExists = \false !== $zip->locateName($innerFilePath);
144 $zip->close();
145 }
146 }
147 return $doesFileExists;
148 }
149 /**
150 * @param string $nodeName
151 * @param int $nodeType
152 *
153 * @return bool Whether the XML Reader is currently positioned on the node with given name and type
154 */
155 private function isPositionedOnNode($nodeName, $nodeType)
156 {
157 /**
158 * In some cases, the node has a prefix (for instance, "<sheet>" can also be "<x:sheet>").
159 * So if the given node name does not have a prefix, we need to look at the unprefixed name ("localName").
160 *
161 * @see https://github.com/box/spout/issues/233
162 */
163 $hasPrefix = \false !== \strpos($nodeName, ':');
164 $currentNodeName = $hasPrefix ? $this->name : $this->localName;
165 return $this->nodeType === $nodeType && $currentNodeName === $nodeName;
166 }
167 }
168