mirror of
https://github.com/Ne-Lexa/php-zip.git
synced 2025-07-31 20:50:13 +02:00
Implemented the ability to override the instance of ZipContainer.
ZipContainer will be cloned before writing the zip file. Tested custom ZipWriter, ZipReader, ZipContainer and ZipFile.
This commit is contained in:
98
tests/Internal/Epub/EpubFile.php
Normal file
98
tests/Internal/Epub/EpubFile.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
|
||||
namespace PhpZip\Tests\Internal\Epub;
|
||||
|
||||
use PhpZip\Constants\ZipPlatform;
|
||||
use PhpZip\Exception\ZipEntryNotFoundException;
|
||||
use PhpZip\Exception\ZipException;
|
||||
use PhpZip\IO\ZipReader;
|
||||
use PhpZip\IO\ZipWriter;
|
||||
use PhpZip\Model\ImmutableZipContainer;
|
||||
use PhpZip\Model\ZipContainer;
|
||||
use PhpZip\Model\ZipEntry;
|
||||
use PhpZip\ZipFile;
|
||||
|
||||
/**
|
||||
* Class EpubFile.
|
||||
*
|
||||
* @property EpubZipContainer $zipContainer
|
||||
*/
|
||||
class EpubFile extends ZipFile
|
||||
{
|
||||
/**
|
||||
* @return ZipWriter
|
||||
*/
|
||||
protected function createZipWriter()
|
||||
{
|
||||
return new EpubWriter($this->zipContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $inputStream
|
||||
* @param array $options
|
||||
*
|
||||
* @return ZipReader
|
||||
*/
|
||||
protected function createZipReader($inputStream, array $options = [])
|
||||
{
|
||||
return new EpubReader($inputStream, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImmutableZipContainer|null $sourceContainer
|
||||
*
|
||||
* @return ZipContainer
|
||||
*/
|
||||
protected function createZipContainer(ImmutableZipContainer $sourceContainer = null)
|
||||
{
|
||||
return new EpubZipContainer($sourceContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZipEntry $zipEntry
|
||||
*/
|
||||
protected function addZipEntry(ZipEntry $zipEntry)
|
||||
{
|
||||
$zipEntry->setCreatedOS(ZipPlatform::OS_DOS);
|
||||
$zipEntry->setExtractedOS(ZipPlatform::OS_UNIX);
|
||||
parent::addZipEntry($zipEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ZipEntryNotFoundException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMimeType()
|
||||
{
|
||||
return $this->zipContainer->getMimeType();
|
||||
}
|
||||
|
||||
public function getEpubInfo()
|
||||
{
|
||||
return new EpubInfo($this->getEntryContents($this->getRootFile()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ZipException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRootFile()
|
||||
{
|
||||
$entryName = 'META-INF/container.xml';
|
||||
$contents = $this->getEntryContents($entryName);
|
||||
$doc = new \DOMDocument();
|
||||
$doc->loadXML($contents);
|
||||
$xpath = new \DOMXPath($doc);
|
||||
$rootFile = $xpath->evaluate('string(//@full-path)');
|
||||
|
||||
if ($rootFile === '') {
|
||||
throw new ZipException('Incorrect ' . $entryName . ' file format');
|
||||
}
|
||||
|
||||
return $rootFile;
|
||||
}
|
||||
}
|
159
tests/Internal/Epub/EpubInfo.php
Normal file
159
tests/Internal/Epub/EpubInfo.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
|
||||
namespace PhpZip\Tests\Internal\Epub;
|
||||
|
||||
use PhpZip\Exception\ZipException;
|
||||
|
||||
/**
|
||||
* Class EpubInfo.
|
||||
*
|
||||
* @see http://idpf.org/epub/30/spec/epub30-publications.html
|
||||
*/
|
||||
class EpubInfo
|
||||
{
|
||||
/** @var string|null */
|
||||
private $title;
|
||||
|
||||
/** @var string|null */
|
||||
private $creator;
|
||||
|
||||
/** @var string|null */
|
||||
private $language;
|
||||
|
||||
/** @var string|null */
|
||||
private $publisher;
|
||||
|
||||
/** @var string|null */
|
||||
private $description;
|
||||
|
||||
/** @var string|null */
|
||||
private $rights;
|
||||
|
||||
/** @var string|null */
|
||||
private $date;
|
||||
|
||||
/** @var string|null */
|
||||
private $subject;
|
||||
|
||||
/**
|
||||
* EpubInfo constructor.
|
||||
*
|
||||
* @param $xmlContents
|
||||
*
|
||||
* @throws ZipException
|
||||
*/
|
||||
public function __construct($xmlContents)
|
||||
{
|
||||
$doc = new \DOMDocument();
|
||||
$doc->loadXML($xmlContents);
|
||||
$xpath = new \DOMXpath($doc);
|
||||
$xpath->registerNamespace('root', 'http://www.idpf.org/2007/opf');
|
||||
$metaDataNodeList = $xpath->query('//root:metadata');
|
||||
|
||||
if (\count($metaDataNodeList) !== 1) {
|
||||
throw new ZipException('Invalid .opf file format');
|
||||
}
|
||||
$metaDataNode = $metaDataNodeList->item(0);
|
||||
|
||||
$title = $xpath->evaluate('string(//dc:title)', $metaDataNode);
|
||||
$creator = $xpath->evaluate('string(//dc:creator)', $metaDataNode);
|
||||
$language = $xpath->evaluate('string(//dc:language)', $metaDataNode);
|
||||
$publisher = $xpath->evaluate('string(//dc:publisher)', $metaDataNode);
|
||||
$description = $xpath->evaluate('string(//dc:description)', $metaDataNode);
|
||||
$rights = $xpath->evaluate('string(//dc:rights)', $metaDataNode);
|
||||
$date = $xpath->evaluate('string(//dc:date)', $metaDataNode);
|
||||
$subject = $xpath->evaluate('string(//dc:subject)', $metaDataNode);
|
||||
|
||||
$this->title = empty($title) ? null : $title;
|
||||
$this->creator = empty($creator) ? null : $creator;
|
||||
$this->language = empty($language) ? null : $language;
|
||||
$this->publisher = empty($publisher) ? null : $publisher;
|
||||
$this->description = empty($description) ? null : $description;
|
||||
$this->rights = empty($rights) ? null : $rights;
|
||||
$this->date = empty($date) ? null : $date;
|
||||
$this->subject = empty($subject) ? null : $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCreator()
|
||||
{
|
||||
return $this->creator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLanguage()
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPublisher()
|
||||
{
|
||||
return $this->publisher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRights()
|
||||
{
|
||||
return $this->rights;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDate()
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSubject()
|
||||
{
|
||||
return $this->subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'creator' => $this->creator,
|
||||
'language' => $this->language,
|
||||
'publisher' => $this->publisher,
|
||||
'description' => $this->description,
|
||||
'rights' => $this->rights,
|
||||
'date' => $this->date,
|
||||
'subject' => $this->subject,
|
||||
];
|
||||
}
|
||||
}
|
21
tests/Internal/Epub/EpubReader.php
Normal file
21
tests/Internal/Epub/EpubReader.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace PhpZip\Tests\Internal\Epub;
|
||||
|
||||
use PhpZip\IO\ZipReader;
|
||||
|
||||
/**
|
||||
* Class EpubReader.
|
||||
*/
|
||||
class EpubReader extends ZipReader
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @see https://github.com/w3c/epubcheck/issues/334
|
||||
*/
|
||||
protected function isZip64Support()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
66
tests/Internal/Epub/EpubWriter.php
Normal file
66
tests/Internal/Epub/EpubWriter.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace PhpZip\Tests\Internal\Epub;
|
||||
|
||||
use PhpZip\Constants\ZipCompressionMethod;
|
||||
use PhpZip\Constants\ZipPlatform;
|
||||
use PhpZip\Exception\ZipUnsupportMethodException;
|
||||
use PhpZip\IO\ZipWriter;
|
||||
use PhpZip\Model\Data\ZipNewData;
|
||||
use PhpZip\Model\ZipEntry;
|
||||
|
||||
/**
|
||||
* Class EpubWriter.
|
||||
*
|
||||
* @property EpubZipContainer $zipContainer
|
||||
*/
|
||||
class EpubWriter extends ZipWriter
|
||||
{
|
||||
/**
|
||||
* @throws ZipUnsupportMethodException
|
||||
*/
|
||||
protected function beforeWrite()
|
||||
{
|
||||
parent::beforeWrite();
|
||||
|
||||
if (!$this->zipContainer->hasEntry('mimetype')) {
|
||||
$zipEntry = new ZipEntry('mimetype');
|
||||
$zipEntry->setCreatedOS(ZipPlatform::OS_DOS);
|
||||
$zipEntry->setExtractedOS(ZipPlatform::OS_DOS);
|
||||
$zipEntry->setCompressionMethod(ZipCompressionMethod::STORED);
|
||||
$zipEntry->setData(new ZipNewData($zipEntry, 'application/epub+zip'));
|
||||
$this->zipContainer->addEntry($zipEntry);
|
||||
}
|
||||
|
||||
$this->sortEntries();
|
||||
}
|
||||
|
||||
private function sortEntries()
|
||||
{
|
||||
$this->zipContainer->sortByEntry(
|
||||
static function (ZipEntry $a, ZipEntry $b) {
|
||||
if (strcasecmp($a->getName(), 'mimetype') === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcasecmp($b->getName(), 'mimetype') === 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($a->isDirectory() && $b->isDirectory()) {
|
||||
return strcmp($a->getName(), $b->getName());
|
||||
}
|
||||
|
||||
if ($a->isDirectory()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($b->isDirectory()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return strcmp($a->getName(), $b->getName());
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
22
tests/Internal/Epub/EpubZipContainer.php
Normal file
22
tests/Internal/Epub/EpubZipContainer.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace PhpZip\Tests\Internal\Epub;
|
||||
|
||||
use PhpZip\Exception\ZipEntryNotFoundException;
|
||||
use PhpZip\Model\ZipContainer;
|
||||
|
||||
/**
|
||||
* Class EpubZipContainer.
|
||||
*/
|
||||
class EpubZipContainer extends ZipContainer
|
||||
{
|
||||
/**
|
||||
* @throws ZipEntryNotFoundException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMimeType()
|
||||
{
|
||||
return $this->getEntry('mimetype')->getData()->getDataAsString();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user