[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/spout/src/Spout/Reader/Wrapper/ -> XMLReader.php (source)

   1  <?php
   2  
   3  namespace Box\Spout\Reader\Wrapper;
   4  
   5  
   6  /**
   7   * Class XMLReader
   8   * Wrapper around the built-in XMLReader
   9   * @see \XMLReader
  10   *
  11   * @package Box\Spout\Reader\Wrapper
  12   */
  13  class XMLReader extends \XMLReader
  14  {
  15      use XMLInternalErrorsHelper;
  16  
  17      /**
  18       * Set the URI containing the XML to parse
  19       * @see \XMLReader::open
  20       *
  21       * @param string $URI URI pointing to the document
  22          * @param string|null|void $encoding The document encoding
  23          * @param int $options A bitmask of the LIBXML_* constants
  24       * @return bool TRUE on success or FALSE on failure
  25       */
  26      public function open($URI, $encoding = null, $options = 0)
  27      {
  28          $wasOpenSuccessful = false;
  29          $realPathURI = $this->convertURIToUseRealPath($URI);
  30  
  31          // HHVM does not check if file exists within zip file
  32          // @link https://github.com/facebook/hhvm/issues/5779
  33          if ($this->isRunningHHVM() && $this->isZipStream($realPathURI)) {
  34              if ($this->fileExistsWithinZip($realPathURI)) {
  35                  $wasOpenSuccessful = parent::open($realPathURI, $encoding, $options|LIBXML_NONET);
  36              }
  37          } else {
  38              $wasOpenSuccessful = parent::open($realPathURI, $encoding, $options|LIBXML_NONET);
  39          }
  40  
  41          return $wasOpenSuccessful;
  42      }
  43  
  44      /**
  45       * Updates the given URI to use a real path.
  46       * This is to avoid issues on some Windows setup.
  47       *
  48       * @param string $URI URI
  49       * @return string The URI using a real path
  50       */
  51      protected function convertURIToUseRealPath($URI)
  52      {
  53          $realPathURI = $URI;
  54  
  55          if ($this->isZipStream($URI)) {
  56              if (preg_match('/zip:\/\/(.*)#(.*)/', $URI, $matches)) {
  57                  $documentPath = $matches[1];
  58                  $documentInsideZipPath = $matches[2];
  59                  $realPathURI = 'zip://' . realpath($documentPath) . '#' . $documentInsideZipPath;
  60              }
  61          } else {
  62              $realPathURI = realpath($URI);
  63          }
  64  
  65          return $realPathURI;
  66      }
  67  
  68      /**
  69       * Returns whether the given URI is a zip stream.
  70       *
  71       * @param string $URI URI pointing to a document
  72       * @return bool TRUE if URI is a zip stream, FALSE otherwise
  73       */
  74      protected function isZipStream($URI)
  75      {
  76          return (strpos($URI, 'zip://') === 0);
  77      }
  78  
  79      /**
  80       * Returns whether the current environment is HHVM
  81       *
  82       * @return bool TRUE if running on HHVM, FALSE otherwise
  83       */
  84      protected function isRunningHHVM()
  85      {
  86          return defined('HHVM_VERSION');
  87      }
  88  
  89      /**
  90       * Returns whether the file at the given location exists
  91       *
  92       * @param string $zipStreamURI URI of a zip stream, e.g. "zip://file.zip#path/inside.xml"
  93       * @return bool TRUE if the file exists, FALSE otherwise
  94       */
  95      protected function fileExistsWithinZip($zipStreamURI)
  96      {
  97          $doesFileExists = false;
  98  
  99          $pattern = '/zip:\/\/([^#]+)#(.*)/';
 100          if (preg_match($pattern, $zipStreamURI, $matches)) {
 101              $zipFilePath = $matches[1];
 102              $innerFilePath = $matches[2];
 103  
 104              $zip = new \ZipArchive();
 105              if ($zip->open($zipFilePath) === true) {
 106                  $doesFileExists = ($zip->locateName($innerFilePath) !== false);
 107                  $zip->close();
 108              }
 109          }
 110  
 111          return $doesFileExists;
 112      }
 113  
 114      /**
 115       * Move to next node in document
 116       * @see \XMLReader::read
 117       *
 118       * @return bool TRUE on success or FALSE on failure
 119       * @throws \Box\Spout\Reader\Exception\XMLProcessingException If an error/warning occurred
 120       */
 121      public function read()
 122      {
 123          $this->useXMLInternalErrors();
 124  
 125          $wasReadSuccessful = parent::read();
 126  
 127          $this->resetXMLInternalErrorsSettingAndThrowIfXMLErrorOccured();
 128  
 129          return $wasReadSuccessful;
 130      }
 131  
 132      /**
 133       * Read until the element with the given name is found, or the end of the file.
 134       *
 135       * @param string $nodeName Name of the node to find
 136       * @return bool TRUE on success or FALSE on failure
 137       * @throws \Box\Spout\Reader\Exception\XMLProcessingException If an error/warning occurred
 138       */
 139      public function readUntilNodeFound($nodeName)
 140      {
 141          while (($wasReadSuccessful = $this->read()) && ($this->nodeType !== \XMLReader::ELEMENT || $this->name !== $nodeName)) {
 142              // do nothing
 143          }
 144  
 145          return $wasReadSuccessful;
 146      }
 147  
 148      /**
 149       * Move cursor to next node skipping all subtrees
 150       * @see \XMLReader::next
 151       *
 152       * @param string|void $localName The name of the next node to move to
 153       * @return bool TRUE on success or FALSE on failure
 154       * @throws \Box\Spout\Reader\Exception\XMLProcessingException If an error/warning occurred
 155       */
 156      public function next($localName = null)
 157      {
 158          $this->useXMLInternalErrors();
 159  
 160          $wasNextSuccessful = parent::next($localName);
 161  
 162          $this->resetXMLInternalErrorsSettingAndThrowIfXMLErrorOccured();
 163  
 164          return $wasNextSuccessful;
 165      }
 166  
 167      /**
 168       * @param string $nodeName
 169       * @return bool Whether the XML Reader is currently positioned on the starting node with given name
 170       */
 171      public function isPositionedOnStartingNode($nodeName)
 172      {
 173          return ($this->nodeType === XMLReader::ELEMENT && $this->name === $nodeName);
 174      }
 175  
 176      /**
 177       * @param string $nodeName
 178       * @return bool Whether the XML Reader is currently positioned on the ending node with given name
 179       */
 180      public function isPositionedOnEndingNode($nodeName)
 181      {
 182          return ($this->nodeType === XMLReader::END_ELEMENT && $this->name === $nodeName);
 183      }
 184  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1