|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info> 00006 * Steffen Kamper <info@sk-typo3.de> 00007 * All rights reserved 00008 * 00009 * This script is part of the TYPO3 project. The TYPO3 project is 00010 * free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * The GNU General Public License can be found at 00016 * http://www.gnu.org/copyleft/gpl.html. 00017 * 00018 * This script is distributed in the hope that it will be useful, 00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 * GNU General Public License for more details. 00022 * 00023 * This copyright notice MUST APPEAR in all copies of the script! 00024 ***************************************************************/ 00025 /** 00026 * Module: Extension manager - Extension.xml push-parser 00027 * 00028 * $Id: class.tx_em_parser_extensionxmlpushparser.php 1913 2010-02-21 15:47:37Z mkrause $ 00029 */ 00030 00031 00032 /** 00033 * Parser for TYPO3's extension.xml file. 00034 * 00035 * Depends on PHP ext/xml which should be available 00036 * with PHP 4+. This is the parser used in TYPO3 00037 * Core <= 4.3 (without the "collect all data in one 00038 * array" behaviour). 00039 * Notice: ext/xml has proven to be buggy with entities. 00040 * Use at least PHP 5.2.9+ and libxml2 2.7.3+! 00041 * 00042 * @author Marcus Krause <marcus#exp2010@t3sec.info> 00043 * @author Steffen Kamper <info@sk-typo3.de> 00044 * 00045 * @since 2010-02-10 00046 * @package TYPO3 00047 * @subpackage EM 00048 */ 00049 class tx_em_Parser_ExtensionXmlPushParser extends tx_em_Parser_ExtensionXmlAbstractParser implements SplSubject { 00050 00051 00052 /** 00053 * Keeps current element to process. 00054 * 00055 * @var string 00056 */ 00057 protected $element = NULL; 00058 00059 /** 00060 * Class constructor. 00061 * 00062 * @return void 00063 */ 00064 function __construct() { 00065 $this->requiredPHPExt = 'xml'; 00066 00067 if ($this->isAvailable()) { 00068 $this->objXML = xml_parser_create(); 00069 xml_set_object($this->objXML, $this); 00070 } 00071 } 00072 00073 /** 00074 * Method parses an extensions.xml file. 00075 * 00076 * @param string $file: GZIP stream resource 00077 * @return void 00078 * @throws tx_em_ExtensionXmlException in case of XML parser errors 00079 */ 00080 public function parseXML($file) { 00081 00082 if (!is_resource($this->objXML)) { 00083 $this->throwException('Unable to create XML parser.'); 00084 } 00085 // keep original character case of XML document 00086 xml_parser_set_option($this->objXML, XML_OPTION_CASE_FOLDING, FALSE); 00087 xml_parser_set_option($this->objXML, XML_OPTION_SKIP_WHITE, FALSE); 00088 xml_parser_set_option($this->objXML, XML_OPTION_TARGET_ENCODING, 'utf-8'); 00089 xml_set_element_handler($this->objXML, 'startElement', 'endElement'); 00090 xml_set_character_data_handler($this->objXML, 'characterData'); 00091 00092 if (!($fp = fopen($file, "r"))) { 00093 $this->throwException(sprintf('Unable to open file ressource %s.', htmlspecialchars($file))); 00094 } 00095 while ($data = fread($fp, 4096)) { 00096 if (!xml_parse($this->objXML, $data, feof($fp))) { 00097 $this->throwException(sprintf('XML error %s in line %u of file ressource %s.', 00098 xml_error_string(xml_get_error_code($this->objXML)), 00099 xml_get_current_line_number($this->objXML), 00100 htmlspecialchars($file))); 00101 } 00102 } 00103 xml_parser_free($this->objXML); 00104 } 00105 00106 /** 00107 * Method is invoked when parser accesses start tag of an element. 00108 * 00109 * @param ressource $parser parser resource 00110 * @param string $elementName: element name at parser's current position 00111 * @param array $attrs: array of an element's attributes if available 00112 * @return void 00113 */ 00114 protected function startElement($parser, $elementName, $attrs) { 00115 switch ($elementName) { 00116 case 'extension': 00117 $this->extensionKey = $attrs['extensionkey']; 00118 break; 00119 case 'version': 00120 $this->version = $attrs['version']; 00121 break; 00122 default: 00123 $this->element = $elementName; 00124 } 00125 } 00126 00127 /** 00128 * Method is invoked when parser accesses end tag of an element. 00129 * 00130 * @param ressource $parser parser resource 00131 * @param string $elementName: element name at parser's current position 00132 * @return void 00133 */ 00134 protected function endElement($parser, $elementName) { 00135 switch ($elementName) { 00136 case 'extension': 00137 $this->resetProperties(TRUE); 00138 break; 00139 case 'version': 00140 $this->notify(); 00141 $this->resetProperties(); 00142 break; 00143 default: 00144 $this->element = NULL; 00145 } 00146 } 00147 00148 /** 00149 * Method is invoked when parser accesses any character other than elements. 00150 * 00151 * @param ressource $parser: parser ressource 00152 * @param string $data: an element's value 00153 * @return void 00154 */ 00155 protected function characterData($parser, $data) { 00156 if (isset($this->element)) { 00157 switch ($this->element) { 00158 case 'downloadcounter': 00159 // downloadcounter could be a child node of 00160 // extension or version 00161 if ($this->version == NULL) { 00162 $this->extensionDLCounter = $data; 00163 } else { 00164 $this->versionDLCounter = $data; 00165 } 00166 break; 00167 case 'title': 00168 $this->title = $data; 00169 break; 00170 case 'description': 00171 $this->description = $data; 00172 break; 00173 case 'state': 00174 $this->state = $data; 00175 break; 00176 case 'reviewstate': 00177 $this->reviewstate = $data; 00178 break; 00179 case 'category': 00180 $this->category = $data; 00181 break; 00182 case 'lastuploaddate': 00183 $this->lastuploaddate = $data; 00184 break; 00185 case 'uploadcomment': 00186 $this->uploadcomment = $data; 00187 break; 00188 case 'dependencies': 00189 $this->dependencies = $this->convertDependencies($data); 00190 break; 00191 case 'authorname': 00192 $this->authorname = $data; 00193 break; 00194 case 'authoremail': 00195 $this->authoremail = $data; 00196 break; 00197 case 'authorcompany': 00198 $this->authorcompany = $data; 00199 break; 00200 case 'ownerusername': 00201 $this->ownerusername = $data; 00202 break; 00203 case 't3xfilemd5': 00204 $this->t3xfilemd5 = $data; 00205 break; 00206 } 00207 } 00208 } 00209 00210 /** 00211 * Method attaches an observer. 00212 * 00213 * @param SplObserver $observer: an observer to attach 00214 * @return void 00215 */ 00216 public function attach(SplObserver $observer) { 00217 $this->observers[] = $observer; 00218 } 00219 00220 /** 00221 * Method detaches an attached observer 00222 * 00223 * @param SplObserver $observer: an observer to detach 00224 * @return void 00225 */ 00226 public function detach(SplObserver $observer) { 00227 $key = array_search($observer, $this->observers, true); 00228 if (!($key === false)) { 00229 unset($this->observers[$key]); 00230 } 00231 } 00232 00233 /** 00234 * Method notifies attached observers. 00235 * 00236 * @return void 00237 */ 00238 public function notify() { 00239 foreach ($this->observers as $observer) { 00240 $observer->update($this); 00241 } 00242 } 00243 } 00244 00245 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpushparser.php'])) { 00246 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpushparser.php']); 00247 } 00248 00249 ?>
1.8.0