[BUGFIX] Remote extensions aren't displayed
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Utility / Parser / MirrorXmlPushParser.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Utility\Parser;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
8 * Steffen Kamper <info@sk-typo3.de>
9 * All rights reserved
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Parser for TYPO3's mirrors.xml file.
29 *
30 * Depends on PHP ext/xml which should be available
31 * with PHP 4+. This is the parser used in TYPO3
32 * Core <= 4.3 (without the "collect all data in one
33 * array" behaviour).
34 * Notice: ext/xml has proven to be buggy with entities.
35 * Use at least PHP 5.2.9+ and libxml2 2.7.3+!
36 *
37 * @author Marcus Krause <marcus#exp2010@t3sec.info>
38 * @author Steffen Kamper <info@sk-typo3.de>
39 * @since 2010-11-17
40 * @package Extension Manager
41 * @subpackage Utility/Parser
42 */
43 class MirrorXmlPushParser extends \TYPO3\CMS\Extensionmanager\Utility\Parser\MirrorXmlAbstractParser implements \SplSubject {
44
45 /**
46 * Keeps list of attached observers.
47 *
48 * @var SplObserver[]
49 */
50 protected $observers = array();
51
52 /**
53 * Class constructor.
54 */
55 public function __construct() {
56 $this->requiredPhpExtensions = 'xml';
57 if ($this->isAvailable()) {
58 $this->objXml = xml_parser_create();
59 xml_set_object($this->objXml, $this);
60 }
61 }
62
63 /**
64 * Method parses a mirror.xml file.
65 *
66 * @param string $file GZIP stream resource
67 * @return void
68 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException in case of XML parser errors
69 */
70 public function parseXml($file) {
71 if (!is_resource($this->objXml)) {
72 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Unable to create XML parser.', 1342641009);
73 }
74 // keep original character case of XML document
75 xml_parser_set_option($this->objXml, XML_OPTION_CASE_FOLDING, FALSE);
76 xml_parser_set_option($this->objXml, XML_OPTION_SKIP_WHITE, FALSE);
77 xml_parser_set_option($this->objXml, XML_OPTION_TARGET_ENCODING, 'utf-8');
78 xml_set_element_handler($this->objXml, 'startElement', 'endElement');
79 xml_set_character_data_handler($this->objXml, 'characterData');
80 if (!($fp = fopen($file, 'r'))) {
81 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('Unable to open file resource %s.', htmlspecialchars($file)), 1342641010);
82 }
83 while ($data = fread($fp, 4096)) {
84 if (!xml_parse($this->objXml, $data, feof($fp))) {
85 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('XML error %s in line %u of file resource %s.', xml_error_string(xml_get_error_code($this->objXml)), xml_get_current_line_number($this->objXml), htmlspecialchars($file)), 1342641011);
86 }
87 }
88 xml_parser_free($this->objXml);
89 }
90
91 /**
92 * Method is invoked when parser accesses start tag of an element.
93 *
94 * @param resource $parser parser resource
95 * @param string $elementName element name at parser's current position
96 * @param array $attrs array of an element's attributes if available
97 * @return void
98 */
99 protected function startElement($parser, $elementName, $attrs) {
100 switch ($elementName) {
101 default:
102 $this->element = $elementName;
103 }
104 }
105
106 /**
107 * Method is invoked when parser accesses end tag of an element.
108 * Although the first parameter seems unused, it needs to be there for
109 * adherence to the API of xml_set_element_handler
110 *
111 * @see xml_set_element_handler
112 * @param resource $parser parser resource
113 * @param string $elementName element name at parser's current position
114 * @return void
115 */
116 protected function endElement($parser, $elementName) {
117 switch ($elementName) {
118 case 'mirror':
119 $this->notify();
120 $this->resetProperties();
121 break;
122 default:
123 $this->element = NULL;
124 }
125 }
126
127 /**
128 * Method is invoked when parser accesses any character other than elements.
129 * Although the first parameter seems unused, it needs to be there for
130 * adherence to the API of xml_set_character_data_handler
131 *
132 * @see xml_set_character_data_handler
133 * @param resource $parser parser resource
134 * @param string $data an element's value
135 * @return void
136 */
137 protected function characterData($parser, $data) {
138 if (isset($this->element)) {
139 switch ($this->element) {
140 case 'title':
141 $this->title = $data;
142 break;
143 case 'host':
144 $this->host = $data;
145 break;
146 case 'path':
147 $this->path = $data;
148 break;
149 case 'country':
150 $this->country = $data;
151 break;
152 case 'name':
153 $this->sponsorname = $data;
154 break;
155 case 'link':
156 $this->sponsorlink = $data;
157 break;
158 case 'logo':
159 $this->sponsorlogo = $data;
160 break;
161 default:
162
163 }
164 }
165 }
166
167 /**
168 * Method attaches an observer.
169 *
170 * @param SplObserver $observer an observer to attach
171 * @return void
172 * @see $observers, detach(), notify()
173 */
174 public function attach(\SplObserver $observer) {
175 $this->observers[] = $observer;
176 }
177
178 /**
179 * Method detaches an attached observer
180 *
181 * @param SplObserver $observer an observer to detach
182 * @return void
183 * @see $observers, attach(), notify()
184 */
185 public function detach(\SplObserver $observer) {
186 $key = array_search($observer, $this->observers, TRUE);
187 if (!($key === FALSE)) {
188 unset($this->observers[$key]);
189 }
190 }
191
192 /**
193 * Method notifies attached observers.
194 *
195 * @access public
196 * @return void
197 * @see $observers, attach(), detach()
198 */
199 public function notify() {
200 foreach ($this->observers as $observer) {
201 $observer->update($this);
202 }
203 }
204
205 }
206
207
208 ?>