TYPO3 API  SVNRelease
class.tx_em_parser_mirrorxmlpushparser.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  * class.tx_em_parser_mirrorxmlpushparser.php
00027  *
00028  * Module: Extension manager - mirrors.xml push-parser
00029  *
00030  * $Id$
00031  *
00032  * @author  Marcus Krause <marcus#exp2010@t3sec.info>
00033  * @author  Steffen Kamper <info@sk-typo3.de>
00034  */
00035 
00036 
00037 /**
00038  * Parser for TYPO3's mirrors.xml file.
00039  *
00040  * Depends on PHP ext/xml which should be available
00041  * with PHP 4+. This is the parser used in TYPO3
00042  * Core <= 4.3 (without the "collect all data in one
00043  * array" behaviour).
00044  * Notice: ext/xml has proven to be buggy with entities.
00045  * Use at least PHP 5.2.9+ and libxml2 2.7.3+!
00046  *
00047  * @author    Marcus Krause <marcus#exp2010@t3sec.info>
00048  * @author    Steffen Kamper <info@sk-typo3.de>
00049  *
00050  * @since      2010-11-17
00051  * @package  TYPO3
00052  * @subpackage  EM
00053  */
00054 class tx_em_Parser_MirrorXmlPushParser extends tx_em_Parser_MirrorXmlAbstractParser implements SplSubject {
00055 
00056 
00057     /**
00058      * Keeps list of attached observers.
00059      *
00060      * @var  array
00061      */
00062     protected $observers = array();
00063 
00064 
00065     /**
00066      * Class constructor.
00067      *
00068      * @return void
00069      */
00070     function __construct() {
00071         $this->requiredPHPExt = 'xml';
00072 
00073         if ($this->isAvailable()) {
00074             $this->objXML = xml_parser_create();
00075             xml_set_object($this->objXML, $this);
00076         }
00077     }
00078 
00079     /**
00080      * Method parses a mirror.xml file.
00081      *
00082      * @param   string  $file: GZIP stream resource
00083      * @return  void
00084      * @throws  em_mirrorxml_Exception  in case of XML parser errors
00085      */
00086     public function parseXML($file) {
00087 
00088         if (!is_resource($this->objXML)) {
00089             $this->throwException('Unable to create XML parser.');
00090         }
00091         // keep original character case of XML document
00092         xml_parser_set_option($this->objXML, XML_OPTION_CASE_FOLDING, FALSE);
00093         xml_parser_set_option($this->objXML, XML_OPTION_SKIP_WHITE, FALSE);
00094         xml_parser_set_option($this->objXML, XML_OPTION_TARGET_ENCODING, 'utf-8');
00095         xml_set_element_handler($this->objXML, 'startElement', 'endElement');
00096         xml_set_character_data_handler($this->objXML, 'characterData');
00097 
00098         if (!($fp = fopen($file, "r"))) {
00099             $this->throwException(sprintf('Unable to open file ressource %s.', htmlspecialchars($file)));
00100         }
00101         while ($data = fread($fp, 4096)) {
00102             if (!xml_parse($this->objXML, $data, feof($fp))) {
00103                 $this->throwException(sprintf('XML error %s in line %u of file ressource %s.',
00104                     xml_error_string(xml_get_error_code($this->objXML)),
00105                     xml_get_current_line_number($this->objXML),
00106                     htmlspecialchars($file)));
00107             }
00108         }
00109         xml_parser_free($this->objXML);
00110     }
00111 
00112     /**
00113      * Method is invoked when parser accesses start tag of an element.
00114      *
00115      * @param   ressource  $parser parser resource
00116      * @param   string   $elementName: element name at parser's current position
00117      * @param   array     $attrs: array of an element's attributes if available
00118      * @return  void
00119      */
00120     protected function startElement($parser, $elementName, $attrs) {
00121         switch ($elementName) {
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 'mirror':
00137                 $this->notify();
00138                 $this->resetProperties();
00139                 break;
00140             default:
00141                 $this->element = NULL;
00142         }
00143     }
00144 
00145     /**
00146      * Method is invoked when parser accesses any character other than elements.
00147      *
00148      * @param   ressource  $parser: parser ressource
00149      * @param   string   $data: an element's value
00150      * @return  void
00151      */
00152     protected function characterData($parser, $data) {
00153         if (isset($this->element)) {
00154             switch ($this->element) {
00155                 case 'title':
00156                     $this->title = $data;
00157                     break;
00158                 case 'host':
00159                     $this->host = $data;
00160                     break;
00161                 case 'path':
00162                     $this->path = $data;
00163                     break;
00164                 case 'country':
00165                     $this->country = $data;
00166                     break;
00167                 case 'name':
00168                     $this->sponsorname = $data;
00169                     break;
00170                 case 'link':
00171                     $this->sponsorlink = $data;
00172                     break;
00173                 case 'logo':
00174                     $this->sponsorlogo = $data;
00175                     break;
00176             }
00177         }
00178     }
00179 
00180     /**
00181      * Method attaches an observer.
00182      *
00183      * @access  public
00184      * @param   SplObserver  $observer  an observer to attach
00185      * @return  void
00186      * @see  $observers, detach(), notify()
00187      */
00188     public function attach(SplObserver $observer) {
00189         $this->observers[] = $observer;
00190     }
00191 
00192     /**
00193      * Method detaches an attached observer
00194      *
00195      * @access  public
00196      * @param   SplObserver  $observer  an observer to detach
00197      * @return  void
00198      * @see  $observers, attach(), notify()
00199      */
00200     public function detach(SplObserver $observer) {
00201         $key = array_search($observer, $this->observers, true);
00202         if (!($key === false)) {
00203             unset($this->observers[$key]);
00204         }
00205     }
00206 
00207     /**
00208      * Method notifies attached observers.
00209      *
00210      * @access  public
00211      * @return  void
00212      * @see  $observers, attach(), detach()
00213      */
00214     public function notify() {
00215         foreach ($this->observers as $observer) {
00216             $observer->update($this);
00217         }
00218     }
00219 }
00220 
00221 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/parser/class.tx_em_parser_mirrorxmlpushparser.php'])) {
00222     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/parser/class.tx_em_parser_mirrorxmlpushparser.php']);
00223 }
00224 
00225 ?>