TYPO3 API  SVNRelease
class.tx_em_parser_extensionxmlpushparser.php
Go to the documentation of this file.
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 ?>