diff --git a/resources/php-epub-meta/epub.php b/resources/php-epub-meta/epub.php index c7d6b28..b30195d 100644 --- a/resources/php-epub-meta/epub.php +++ b/resources/php-epub-meta/epub.php @@ -3,7 +3,7 @@ * PHP EPub Meta library * * @author Andreas Gohr - * @author SĂ©bastien Lucas + * @author Sébastien Lucas */ require_once(realpath( dirname( __FILE__ ) ) . '/tbszip.php'); @@ -161,8 +161,6 @@ class EPub { } $data = $this->zip->FileRead($path); - $data = preg_replace ("/src=[\"']([\w\/\.]*?)[\"']/", "src='epubfs.php?comp=$1'", $data); - $data = preg_replace ("/href=[\"']([\w\/\.]*?)[\"']/", "href='epubfs.php?comp=$1'", $data); return $data; } @@ -189,7 +187,6 @@ class EPub { return $contents; } - /** * Get or set the book author(s) * @@ -200,7 +197,7 @@ class EPub { * * array( * 'Pratchett, Terry' => 'Terry Pratchett', - * 'Simpson, Jacqeline' => 'Jacqueline Simpson', + * 'Simpson, Jacqueline' => 'Jacqueline Simpson', * ) * * @params array $authors @@ -400,7 +397,7 @@ class EPub { * @param string $serie */ public function Serie($serie=false){ - return $this->getset('opf:meta',$serie,'name','calibre:series','content'); + return $this->getset('opf:meta',$serie,'name','cops:series','content'); } /** @@ -409,7 +406,7 @@ class EPub { * @param string $serieIndex */ public function SerieIndex($serieIndex=false){ - return $this->getset('opf:meta',$serieIndex,'name','calibre:series_index','content'); + return $this->getset('opf:meta',$serieIndex,'name','cops:series_index','content'); } /** diff --git a/resources/php-epub-meta/tbszip.php b/resources/php-epub-meta/tbszip.php index fbbb8cb..37db5ae 100644 --- a/resources/php-epub-meta/tbszip.php +++ b/resources/php-epub-meta/tbszip.php @@ -1,8 +1,8 @@ Meth8Ok)) $this->__construct(); // for PHP 4 compatibility $this->Close(); // close handle and init info $this->Error = false; - $this->ArchFile = $ArchFile; $this->ArchIsNew = false; - // open the file - $this->ArchHnd = fopen($ArchFile, 'rb', $UseIncludePath); + $this->ArchIsStream = (is_resource($ArchFile) && (get_resource_type($ArchFile)=='stream')); + if ($this->ArchIsStream) { + $this->ArchFile = 'from_stream.zip'; + $this->ArchHnd = $ArchFile; + } else { + // open the file + $this->ArchFile = $ArchFile; + $this->ArchHnd = fopen($ArchFile, 'rb', $UseIncludePath); + } $ok = !($this->ArchHnd===false); if ($ok) $ok = $this->CentralDirRead(); return $ok; @@ -90,9 +96,18 @@ class clsTbsZip { $cd_pos = -22; $this->_MoveTo($cd_pos, SEEK_END); $b = $this->_ReadData(4); - if ($b!==$cd_info) return $this->RaiseError('The End of Central Rirectory Record is not found.'); - - $this->CdEndPos = ftell($this->ArchHnd) - 4; + if ($b===$cd_info) { + $this->CdEndPos = ftell($this->ArchHnd) - 4; + } else { + $p = $this->_FindCDEnd($cd_info); + //echo 'p='.var_export($p,true); exit; + if ($p===false) { + return $this->RaiseError('The End of Central Directory Record is not found.'); + } else { + $this->CdEndPos = $p; + $this->_MoveTo($p+4); + } + } $this->CdInfo = $this->CentralDirRead_End($cd_info); $this->CdFileLst = array(); $this->CdFileNbr = $this->CdInfo['file_nbr_curr']; @@ -161,7 +176,13 @@ class clsTbsZip { } function RaiseError($Msg) { - if ($this->DisplayError) echo ''.get_class($this).' ERROR : '.$Msg.'
'."\r\n"; + if ($this->DisplayError) { + if (PHP_SAPI==='cli') { + echo get_class($this).' ERROR with the zip archive: '.$Msg."\r\n"; + } else { + echo ''.get_class($this).' ERROR with the zip archive: '.$Msg.'
'."\r\n"; + } + } $this->Error = $Msg; return false; } @@ -182,10 +203,10 @@ class clsTbsZip { $idx++; } } - + $nl = "\r\n"; echo "
";
-		
+
 		echo "-------------------------------".$nl;
 		echo "End of Central Directory record".$nl;
 		echo "-------------------------------".$nl;
@@ -206,7 +227,7 @@ class clsTbsZip {
 		}
 
 		echo "
"; - + } function DebugArray($arr) { @@ -219,7 +240,7 @@ class clsTbsZip { } return $arr; } - + function FileExists($NameOrIdx) { return ($this->FileGetIdx($NameOrIdx)!==false); } @@ -293,7 +314,7 @@ class clsTbsZip { // read the file header (and maybe the data ) in the archive, assuming the cursor in at a new file position $b = $this->_ReadData(30); - + $x = $this->_GetHex($b,0,4); if ($x!=='h:04034b50') return $this->RaiseError("Signature of Local File Header #".$idx." (data section) expected but not found at position ".$this->_TxtPos(ftell($this->ArchHnd)-30)."."); @@ -335,7 +356,7 @@ class clsTbsZip { } else { $this->_MoveTo($len, SEEK_CUR); } - + // Description information $desc_ok = ($x['purp'][2+3]=='1'); if ($desc_ok) { @@ -395,6 +416,32 @@ class clsTbsZip { } + /** + * Return the state of the file. + * @return {string} 'u'=unchanged, 'm'=modified, 'd'=deleted, 'a'=added, false=unknown + */ + function FileGetState($NameOrIdx) { + + $idx = $this->FileGetIdx($NameOrIdx); + if ($idx===false) { + $idx = $this->FileGetIdxAdd($NameOrIdx); + if ($idx===false) { + return false; + } else { + return 'a'; + } + } elseif (isset($this->ReplInfo[$idx])) { + if ($this->ReplInfo[$idx]===false) { + return 'd'; + } else { + return 'm'; + } + } else { + return 'u'; + } + + } + function FileCancelModif($NameOrIdx, $ReplacedAndDeleted=true) { // cancel added, modified or deleted modifications on a file in the archive // return the number of cancels @@ -585,8 +632,7 @@ class clsTbsZip { if (''.$File=='') $File = basename($this->ArchFile).'.zip'; $this->OutputHandle = @fopen($File, 'w'); if ($this->OutputHandle===false) { - $this->RaiseError('Method Flush() cannot overwrite the target file \''.$File.'\'. This may not be a valid file path or the file may be locked by another process or because of a denied permission.'); - return false; + return $this->RaiseError('Method Flush() cannot overwrite the target file \''.$File.'\'. This may not be a valid file path or the file may be locked by another process or because of a denied permission.'); } } elseif (($Render & TBSZIP_STRING)==TBSZIP_STRING) { $this->OutputMode = TBSZIP_STRING; @@ -608,6 +654,8 @@ class clsTbsZip { $Len = $this->_EstimateNewArchSize(); if ($Len!==false) header('Content-Length: '.$Len); } + } else { + return $this->RaiseError('Method Flush is called with a unsupported render option.'); } return true; @@ -748,6 +796,34 @@ class clsTbsZip { // Return the human readable position in both decimal and hexa return $pos." (h:".dechex($pos).")"; } + + /** + * Search the record of end of the Central Directory. + * Return the position of the record in the file. + * Return false if the record is not found. The comment cannot exceed 65335 bytes (=FFFF). + * The method is read backwards a block of 256 bytes and search the key in this block. + */ + function _FindCDEnd($cd_info) { + $nbr = 1; + $p = false; + $pos = ftell($this->ArchHnd) - 4 - 256; + while ( ($p===false) && ($nbr<256) ) { + if ($pos<=0) { + $pos = 0; + $nbr = 256; // in order to make this a last check + } + $this->_MoveTo($pos); + $x = $this->_ReadData(256); + $p = strpos($x, $cd_info); + if ($p===false) { + $nbr++; + $pos = $pos - 256 - 256; + } else { + return $pos + $p; + } + } + return false; + } function _DataOuputAddedFile($Idx, $PosLoc) { @@ -880,6 +956,9 @@ class clsTbsZip { if ($this->ArchIsNew) { $Len = strlen($this->CdInfo['bin']); + } elseif ($this->ArchIsStream) { + $x = fstat($this->ArchHnd); + $Len = $x['size']; } else { $Len = filesize($this->ArchFile); }