Adding open_file_in_zip() helper function to XMLReader (#238)

This commit is contained in:
Adrien Loison committed 2016-05-29 23:22:57 -07:00
1 parent 03866a6604
commit 251c0bebc1
8 files changed
+64 -111

No files matched your search

+4 -2
View File
@@ -15,6 +15,8 @@ use Box\Spout\Reader\Wrapper\XMLReader;
*/
class SheetIterator implements IteratorInterface
{
const CONTENT_XML_FILE_PATH = 'content.xml';
/** Definition of XML nodes name and attribute used to parse sheet data */
const XML_NODE_TABLE = 'table:table';
const XML_ATTRIBUTE_TABLE_NAME = 'table:name';
@@ -63,8 +65,8 @@ class SheetIterator implements IteratorInterface
{
$this->xmlReader->close();
$contentXmlFilePath = $this->filePath . '#content.xml';
if ($this->xmlReader->open('zip://' . $contentXmlFilePath) === false) {
if ($this->xmlReader->openFileInZip($this->filePath, self::CONTENT_XML_FILE_PATH) === false) {
$contentXmlFilePath = $this->filePath . '#' . self::CONTENT_XML_FILE_PATH;
throw new IOException("Could not open \"{$contentXmlFilePath}\".");
}
+17 -39
View File
@@ -14,66 +14,44 @@ class XMLReader extends \XMLReader
{
use XMLInternalErrorsHelper;
const ZIP_WRAPPER = 'zip://';
/**
* Set the URI containing the XML to parse
* @see \XMLReader::open
* Opens the XML Reader to read a file located inside a ZIP file.
*
* @param string $URI URI pointing to the document
* @param string|null|void $encoding The document encoding
* @param int $options A bitmask of the LIBXML_* constants
* @param string $zipFilePath Path to the ZIP file
* @param string $fileInsideZipPath Relative or absolute path of the file inside the zip
* @return bool TRUE on success or FALSE on failure
*/
public function open($URI, $encoding = null, $options = 0)
public function openFileInZip($zipFilePath, $fileInsideZipPath)
{
$wasOpenSuccessful = false;
$realPathURI = $this->convertURIToUseRealPath($URI);
$realPathURI = $this->getRealPathURIForFileInZip($zipFilePath, $fileInsideZipPath);
// HHVM does not check if file exists within zip file
// @link https://github.com/facebook/hhvm/issues/5779
if ($this->isRunningHHVM() && $this->isZipStream($realPathURI)) {
if ($this->isRunningHHVM()) {
if ($this->fileExistsWithinZip($realPathURI)) {
$wasOpenSuccessful = parent::open($realPathURI, $encoding, $options|LIBXML_NONET);
$wasOpenSuccessful = $this->open($realPathURI, null, LIBXML_NONET);
}
} else {
$wasOpenSuccessful = parent::open($realPathURI, $encoding, $options|LIBXML_NONET);
$wasOpenSuccessful = $this->open($realPathURI, null, LIBXML_NONET);
}
return $wasOpenSuccessful;
}
/**
* Updates the given URI to use a real path.
* This is to avoid issues on some Windows setup.
* Returns the real path for the given path components.
* This is useful to avoid issues on some Windows setup.
*
* @param string $URI URI
* @return string The URI using a real path
* @param string $zipFilePath Path to the ZIP file
* @param string $fileInsideZipPath Relative or absolute path of the file inside the zip
* @return string The real path URI
*/
protected function convertURIToUseRealPath($URI)
public function getRealPathURIForFileInZip($zipFilePath, $fileInsideZipPath)
{
$realPathURI = $URI;
if ($this->isZipStream($URI)) {
if (preg_match('/zip:\/\/(.*)#(.*)/', $URI, $matches)) {
$documentPath = $matches[1];
$documentInsideZipPath = $matches[2];
$realPathURI = 'zip://' . realpath($documentPath) . '#' . $documentInsideZipPath;
}
} else {
$realPathURI = realpath($URI);
}
return $realPathURI;
}
/**
* Returns whether the given URI is a zip stream.
*
* @param string $URI URI pointing to a document
* @return bool TRUE if URI is a zip stream, FALSE otherwise
*/
protected function isZipStream($URI)
{
return (strpos($URI, 'zip://') === 0);
return (self::ZIP_WRAPPER . realpath($zipFilePath) . '#' . $fileInsideZipPath);
}
/**
+2 -2
View File
@@ -55,7 +55,7 @@ class SheetHelper
$sheetIndex = 0;
$xmlReader = new XMLReader();
if ($xmlReader->open('zip://' . $this->filePath . '#' . self::WORKBOOK_XML_FILE_PATH)) {
if ($xmlReader->openFileInZip($this->filePath, self::WORKBOOK_XML_FILE_PATH)) {
while ($xmlReader->read()) {
if ($xmlReader->isPositionedOnStartingNode('sheet')) {
$sheets[] = $this->getSheetFromSheetXMLNode($xmlReader, $sheetIndex);
@@ -105,7 +105,7 @@ class SheetHelper
// find the file path of the sheet, by looking at the "workbook.xml.res" file
$xmlReader = new XMLReader();
if ($xmlReader->open('zip://' . $this->filePath . '#' . self::WORKBOOK_XML_RELS_FILE_PATH)) {
if ($xmlReader->openFileInZip($this->filePath, self::WORKBOOK_XML_RELS_FILE_PATH)) {
while ($xmlReader->read()) {
if ($xmlReader->isPositionedOnStartingNode('Relationship')) {
$relationshipSheetId = $xmlReader->getAttribute('Id');
+1 -2
View File
@@ -76,10 +76,9 @@ class StyleHelper
$this->customNumberFormats = [];
$this->stylesAttributes = [];
$stylesXmlFilePath = $this->filePath .'#' . self::STYLES_XML_FILE_PATH;
$xmlReader = new XMLReader();
if ($xmlReader->open('zip://' . $stylesXmlFilePath)) {
if ($xmlReader->openFileInZip($this->filePath, self::STYLES_XML_FILE_PATH)) {
while ($xmlReader->read()) {
if ($xmlReader->isPositionedOnStartingNode(self::XML_NODE_NUM_FMTS)) {
$numFmtsNode = new SimpleXMLElement($xmlReader->readOuterXml());