TYPO3 API  SVNRelease
class.tx_em_parser_extensionxmlpullparser.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 pull-parser
00027  *
00028  * $Id: class.tx_em_parser_extensionxmlpullparser.php 1913 2010-02-21 15:47:37Z mkrause $
00029  */
00030 
00031 /**
00032  * Parser for TYPO3's extension.xml file.
00033  *
00034  * Depends on PHP ext/xmlreader which should be available
00035  * with PHP >= 5.1.0.
00036  *
00037  * @author    Marcus Krause <marcus#exp2010@t3sec.info>
00038  * @author    Steffen Kamper <info@sk-typo3.de>
00039  *
00040  * @since      2010-02-09
00041  * @package  TYPO3
00042  * @subpackage  EM
00043  */
00044 class tx_em_Parser_ExtensionXmlPullParser extends tx_em_Parser_ExtensionXmlAbstractParser implements SplSubject {
00045 
00046 
00047     /**
00048      * Keeps list of attached observers.
00049      *
00050      * @var  array
00051      */
00052     protected $observers = array();
00053 
00054     /**
00055      * Class constructor.
00056      *
00057      * @return void
00058      */
00059     function __construct() {
00060         $this->requiredPHPExt = 'xmlreader';
00061 
00062         if ($this->isAvailable()) {
00063             $this->objXML = new XMLReader();
00064         }
00065     }
00066 
00067     /**
00068      * Method parses an extensions.xml file.
00069      *
00070      * @param   string  $file: GZIP stream resource
00071      * @return  void
00072      * @throws  em_extensionxml_Exception  in case of XML parser errors
00073      */
00074     public function parseXML($file) {
00075         if (!(is_object($this->objXML) && (get_class($this->objXML) == 'XMLReader'))) {
00076             $this->throwException('Unable to create XML parser.');
00077         }
00078         $this->objXML->open($file, 'utf-8') || $this->throwException(sprintf('Unable to open file ressource %s.', htmlspecialchars($file)));
00079 
00080         while ($this->objXML->read()) {
00081 
00082             if ($this->objXML->nodeType == XMLReader::ELEMENT) {
00083                 $this->startElement($this->objXML->name);
00084             } else {
00085                 if ($this->objXML->nodeType == XMLReader::END_ELEMENT) {
00086                     $this->endElement($this->objXML->name);
00087                 } else {
00088                     continue;
00089                 }
00090             }
00091         }
00092         $this->objXML->close();
00093     }
00094 
00095     /**
00096      * Method is invoked when parser accesses start tag of an element.
00097      *
00098      * @param   string   $elementName: element name at parser's current position
00099      * @return  void
00100      */
00101     protected function startElement($elementName) {
00102         switch ($elementName) {
00103             case 'extension':
00104                 $this->extensionKey = $this->objXML->getAttribute('extensionkey');
00105                 break;
00106             case 'version':
00107                 $this->version = $this->objXML->getAttribute('version');
00108                 break;
00109             case 'downloadcounter':
00110                 // downloadcounter could be a child node of
00111                 // extension or version
00112                 if ($this->version == NULL) {
00113                     $this->extensionDLCounter = $this->getElementValue($elementName);
00114                 } else {
00115                     $this->versionDLCounter = $this->getElementValue($elementName);
00116                 }
00117                 break;
00118             case 'title':
00119                 $this->title = $this->getElementValue($elementName);
00120                 break;
00121             case 'description':
00122                 $this->description = $this->getElementValue($elementName);
00123                 break;
00124             case 'state':
00125                 $this->state = $this->getElementValue($elementName);
00126                 break;
00127             case 'reviewstate':
00128                 $this->reviewstate = $this->getElementValue($elementName);
00129                 break;
00130             case 'category':
00131                 $this->category = $this->getElementValue($elementName);
00132                 break;
00133             case 'lastuploaddate':
00134                 $this->lastuploaddate = $this->getElementValue($elementName);
00135                 break;
00136             case 'uploadcomment':
00137                 $this->uploadcomment = $this->getElementValue($elementName);
00138                 break;
00139             case 'dependencies':
00140                 $this->dependencies = $this->convertDependencies($this->getElementValue($elementName));
00141                 break;
00142             case 'authorname':
00143                 $this->authorname = $this->getElementValue($elementName);
00144                 break;
00145             case 'authoremail':
00146                 $this->authoremail = $this->getElementValue($elementName);
00147                 break;
00148             case 'authorcompany':
00149                 $this->authorcompany = $this->getElementValue($elementName);
00150                 break;
00151             case 'ownerusername':
00152                 $this->ownerusername = $this->getElementValue($elementName);
00153                 break;
00154             case 't3xfilemd5':
00155                 $this->t3xfilemd5 = $this->getElementValue($elementName);
00156                 break;
00157         }
00158     }
00159 
00160     /**
00161      * Method is invoked when parser accesses end tag of an element.
00162      *
00163      * @param   string   $elementName: element name at parser's current position
00164      * @return  void
00165      */
00166     protected function endElement($elementName) {
00167         switch ($elementName) {
00168             case 'extension':
00169                 $this->resetProperties(TRUE);
00170                 break;
00171             case 'version':
00172                 $this->notify();
00173                 $this->resetProperties();
00174                 break;
00175         }
00176     }
00177 
00178     /**
00179      * Method returns the value of an element at XMLReader's current
00180      * position.
00181      *
00182      * Method will read until it finds the end of the given element.
00183      * If element has no value, method returns NULL.
00184      *
00185      * @param   string  $elementName: name of element to retrieve it's value from
00186      * @return  string  an element's value if it has a value, otherwise NULL
00187      */
00188     protected function getElementValue(&$elementName) {
00189         $value = NULL;
00190         if (!$this->objXML->isEmptyElement) {
00191             $value = '';
00192             while ($this->objXML->read()) {
00193                 if ($this->objXML->nodeType == XMLReader::TEXT
00194                         || $this->objXML->nodeType == XMLReader::CDATA
00195                         || $this->objXML->nodeType == XMLReader::WHITESPACE
00196                         || $this->objXML->nodeType == XMLReader::SIGNIFICANT_WHITESPACE) {
00197                     $value .= $this->objXML->value;
00198                 } else {
00199                     if ($this->objXML->nodeType == XMLReader::END_ELEMENT
00200                             && $this->objXML->name === $elementName) {
00201                         break;
00202                     }
00203                 }
00204             }
00205         }
00206         return $value;
00207     }
00208 
00209     /**
00210      * Method attaches an observer.
00211      *
00212      * @param   SplObserver  $observer: an observer to attach
00213      * @return  void
00214      */
00215     public function attach(SplObserver $observer) {
00216         $this->observers[] = $observer;
00217     }
00218 
00219     /**
00220      * Method detaches an attached observer
00221      *
00222      * @param   SplObserver  $observer: an observer to detach
00223      * @return  void
00224      */
00225     public function detach(SplObserver $observer) {
00226         $key = array_search($observer, $this->observers, true);
00227         if (!($key === false)) {
00228             unset($this->observers[$key]);
00229         }
00230     }
00231 
00232     /**
00233      * Method notifies attached observers.
00234      *
00235      * @return  void
00236      */
00237     public function notify() {
00238         foreach ($this->observers as $observer) {
00239             $observer->update($this);
00240         }
00241     }
00242 }
00243 
00244 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpullparser.php'])) {
00245     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpullparser.php']);
00246 }
00247 
00248 ?>