1903abfac63dc7910801aa4f9a719a5b5a90834b
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Utility / Parser / ExtensionXmlPullParser.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Utility\Parser;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Parser for TYPO3's extension.xml file.
19 *
20 * Depends on PHP ext/xmlreader which should be available
21 * with PHP >= 5.1.0.
22 */
23 class ExtensionXmlPullParser extends AbstractExtensionXmlParser
24 {
25 /**
26 * Class constructor.
27 */
28 public function __construct()
29 {
30 $this->requiredPhpExtensions = 'xmlreader';
31 }
32
33 /**
34 * Create required parser
35 *
36 * @return void
37 */
38 protected function createParser()
39 {
40 $this->objXml = new \XMLReader();
41 }
42
43 /**
44 * Method parses an extensions.xml file.
45 *
46 * @param string $file GZIP stream resource
47 * @return void
48 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException in case of parser error
49 */
50 public function parseXml($file)
51 {
52 $this->createParser();
53 if (!(is_object($this->objXml) && get_class($this->objXml) == 'XMLReader')) {
54 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Unable to create XML parser.', 1342640540);
55 }
56 if ($this->objXml->open($file, 'utf-8') === false) {
57 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(
58 sprintf('Unable to open file resource %s.', $file),
59 1476108651
60 );
61 }
62 while ($this->objXml->read()) {
63 if ($this->objXml->nodeType == \XMLReader::ELEMENT) {
64 $this->startElement($this->objXml->name);
65 } else {
66 if ($this->objXml->nodeType == \XMLReader::END_ELEMENT) {
67 $this->endElement($this->objXml->name);
68 } else {
69 continue;
70 }
71 }
72 }
73 $this->objXml->close();
74 }
75
76 /**
77 * Method is invoked when parser accesses start tag of an element.
78 *
79 * @param string $elementName element name at parser's current position
80 * @return void
81 */
82 protected function startElement($elementName)
83 {
84 switch ($elementName) {
85 case 'extension':
86 $this->extensionKey = $this->objXml->getAttribute('extensionkey');
87 break;
88 case 'version':
89 $this->version = $this->objXml->getAttribute('version');
90 break;
91 case 'downloadcounter':
92 // downloadcounter could be a child node of
93 // extension or version
94 if ($this->version == null) {
95 $this->extensionDownloadCounter = $this->getElementValue($elementName);
96 } else {
97 $this->versionDownloadCounter = $this->getElementValue($elementName);
98 }
99 break;
100 case 'title':
101 $this->title = $this->getElementValue($elementName);
102 break;
103 case 'description':
104 $this->description = $this->getElementValue($elementName);
105 break;
106 case 'state':
107 $this->state = $this->getElementValue($elementName);
108 break;
109 case 'reviewstate':
110 $this->reviewstate = $this->getElementValue($elementName);
111 break;
112 case 'category':
113 $this->category = $this->getElementValue($elementName);
114 break;
115 case 'lastuploaddate':
116 $this->lastuploaddate = $this->getElementValue($elementName);
117 break;
118 case 'uploadcomment':
119 $this->uploadcomment = $this->getElementValue($elementName);
120 break;
121 case 'dependencies':
122 $this->dependencies = $this->convertDependencies($this->getElementValue($elementName));
123 break;
124 case 'authorname':
125 $this->authorname = $this->getElementValue($elementName);
126 break;
127 case 'authoremail':
128 $this->authoremail = $this->getElementValue($elementName);
129 break;
130 case 'authorcompany':
131 $this->authorcompany = $this->getElementValue($elementName);
132 break;
133 case 'ownerusername':
134 $this->ownerusername = $this->getElementValue($elementName);
135 break;
136 case 't3xfilemd5':
137 $this->t3xfilemd5 = $this->getElementValue($elementName);
138 break;
139 }
140 }
141
142 /**
143 * Method is invoked when parser accesses end tag of an element.
144 *
145 * @param string $elementName: element name at parser's current position
146 * @return void
147 */
148 protected function endElement($elementName)
149 {
150 switch ($elementName) {
151 case 'extension':
152 $this->resetProperties(true);
153 break;
154 case 'version':
155 $this->notify();
156 $this->resetProperties();
157 break;
158 }
159 }
160
161 /**
162 * Method returns the value of an element at XMLReader's current
163 * position.
164 *
165 * Method will read until it finds the end of the given element.
166 * If element has no value, method returns NULL.
167 *
168 * @param string $elementName: name of element to retrieve it's value from
169 * @return string an element's value if it has a value, otherwise NULL
170 */
171 protected function getElementValue(&$elementName)
172 {
173 $value = null;
174 if (!$this->objXml->isEmptyElement) {
175 $value = '';
176 while ($this->objXml->read()) {
177 if ($this->objXml->nodeType == \XMLReader::TEXT || $this->objXml->nodeType == \XMLReader::CDATA || $this->objXml->nodeType == \XMLReader::WHITESPACE || $this->objXml->nodeType == \XMLReader::SIGNIFICANT_WHITESPACE) {
178 $value .= $this->objXml->value;
179 } else {
180 if ($this->objXml->nodeType == \XMLReader::END_ELEMENT && $this->objXml->name === $elementName) {
181 break;
182 }
183 }
184 }
185 }
186 return $value;
187 }
188 }