mirror of
https://github.com/Ne-Lexa/php-zip.git
synced 2025-07-31 04:30: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:
@@ -2,15 +2,15 @@ language: php
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- ZIPALIGN_INSTALL=false
|
|
||||||
- COVERAGE=false
|
- COVERAGE=false
|
||||||
- PHPUNIT_FLAGS="-v -c phpunit.xml --testsuite only_fast_tests"
|
- PHPUNIT_FLAGS="-v -c phpunit.xml"
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- php: 5.5
|
- php: 5.5
|
||||||
os: linux
|
os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
env: ZIPALIGN_INSTALL=false
|
||||||
|
|
||||||
- php: 5.6
|
- php: 5.6
|
||||||
os: linux
|
os: linux
|
||||||
@@ -40,7 +40,7 @@ matrix:
|
|||||||
- php: 7.4
|
- php: 7.4
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
env: COVERAGE=true ZIPALIGN_INSTALL=true PHPUNIT_FLAGS="-v -c phpunit.xml --testsuite only_fast_tests --coverage-clover=coverage.clover"
|
env: COVERAGE=true ZIPALIGN_INSTALL=true PHPUNIT_FLAGS="-v -c phpunit.xml --coverage-clover=coverage.clover"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi
|
- if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
`PhpZip` - php библиотека для продвинутой работы с ZIP-архивами.
|
`PhpZip` - php библиотека для продвинутой работы с ZIP-архивами.
|
||||||
|
|
||||||
[](https://travis-ci.org/Ne-Lexa/php-zip)
|
[](https://travis-ci.org/Ne-Lexa/php-zip)
|
||||||
|
[](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/?branch=master)
|
||||||
[](https://packagist.org/packages/nelexa/zip)
|
[](https://packagist.org/packages/nelexa/zip)
|
||||||
[](https://packagist.org/packages/nelexa/zip)
|
[](https://packagist.org/packages/nelexa/zip)
|
||||||
[](https://php.net/)
|
[](https://php.net/)
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
`PhpZip` is a php-library for extended work with ZIP-archives.
|
`PhpZip` is a php-library for extended work with ZIP-archives.
|
||||||
|
|
||||||
[](https://travis-ci.org/Ne-Lexa/php-zip)
|
[](https://travis-ci.org/Ne-Lexa/php-zip)
|
||||||
|
[](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/?branch=master)
|
||||||
[](https://packagist.org/packages/nelexa/zip)
|
[](https://packagist.org/packages/nelexa/zip)
|
||||||
[](https://packagist.org/packages/nelexa/zip)
|
[](https://packagist.org/packages/nelexa/zip)
|
||||||
[](https://php.net/)
|
[](https://php.net/)
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
"ext-bz2": "*",
|
"ext-bz2": "*",
|
||||||
"ext-openssl": "*",
|
"ext-openssl": "*",
|
||||||
"ext-fileinfo": "*",
|
"ext-fileinfo": "*",
|
||||||
|
"ext-xml": "*",
|
||||||
"guzzlehttp/psr7": "^1.6",
|
"guzzlehttp/psr7": "^1.6",
|
||||||
"phpunit/phpunit": "^4.8|^5.7",
|
"phpunit/phpunit": "^4.8|^5.7",
|
||||||
"symfony/var-dumper": "^3.0|^4.0|^5.0"
|
"symfony/var-dumper": "^3.0|^4.0|^5.0"
|
||||||
|
@@ -22,6 +22,12 @@
|
|||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
|
|
||||||
|
<groups>
|
||||||
|
<exclude>
|
||||||
|
<group>large</group>
|
||||||
|
</exclude>
|
||||||
|
</groups>
|
||||||
|
|
||||||
<filter>
|
<filter>
|
||||||
<whitelist>
|
<whitelist>
|
||||||
<directory>src</directory>
|
<directory>src</directory>
|
||||||
|
@@ -39,7 +39,9 @@ class ZipWriter
|
|||||||
*/
|
*/
|
||||||
public function __construct(ZipContainer $container)
|
public function __construct(ZipContainer $container)
|
||||||
{
|
{
|
||||||
$this->zipContainer = $container;
|
// we clone the container so that the changes made to
|
||||||
|
// it do not affect the data in the ZipFile class
|
||||||
|
$this->zipContainer = clone $container;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -20,6 +20,7 @@ use PhpZip\IO\ZipReader;
|
|||||||
use PhpZip\IO\ZipWriter;
|
use PhpZip\IO\ZipWriter;
|
||||||
use PhpZip\Model\Data\ZipFileData;
|
use PhpZip\Model\Data\ZipFileData;
|
||||||
use PhpZip\Model\Data\ZipNewData;
|
use PhpZip\Model\Data\ZipNewData;
|
||||||
|
use PhpZip\Model\ImmutableZipContainer;
|
||||||
use PhpZip\Model\ZipContainer;
|
use PhpZip\Model\ZipContainer;
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
use PhpZip\Model\ZipEntryMatcher;
|
use PhpZip\Model\ZipEntryMatcher;
|
||||||
@@ -68,7 +69,7 @@ class ZipFile implements ZipFileInterface
|
|||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->zipContainer = new ZipContainer();
|
$this->zipContainer = $this->createZipContainer(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,6 +91,16 @@ class ZipFile implements ZipFileInterface
|
|||||||
return new ZipWriter($this->zipContainer);
|
return new ZipWriter($this->zipContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ImmutableZipContainer|null $sourceContainer
|
||||||
|
*
|
||||||
|
* @return ZipContainer
|
||||||
|
*/
|
||||||
|
protected function createZipContainer(ImmutableZipContainer $sourceContainer = null)
|
||||||
|
{
|
||||||
|
return new ZipContainer($sourceContainer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open zip archive from file.
|
* Open zip archive from file.
|
||||||
*
|
*
|
||||||
@@ -151,7 +162,7 @@ class ZipFile implements ZipFileInterface
|
|||||||
public function openFromStream($handle, array $options = [])
|
public function openFromStream($handle, array $options = [])
|
||||||
{
|
{
|
||||||
$this->reader = $this->createZipReader($handle, $options);
|
$this->reader = $this->createZipReader($handle, $options);
|
||||||
$this->zipContainer = new ZipContainer($this->reader->read());
|
$this->zipContainer = $this->createZipContainer($this->reader->read());
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -1769,7 +1780,7 @@ class ZipFile implements ZipFileInterface
|
|||||||
if ($this->reader !== null) {
|
if ($this->reader !== null) {
|
||||||
$this->reader->close();
|
$this->reader->close();
|
||||||
$this->reader = null;
|
$this->reader = null;
|
||||||
$this->zipContainer = new ZipContainer();
|
$this->zipContainer = $this->createZipContainer(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
60
tests/CustomZipFormatTest.php
Normal file
60
tests/CustomZipFormatTest.php
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpZip\Tests;
|
||||||
|
|
||||||
|
use PhpZip\Exception\ZipEntryNotFoundException;
|
||||||
|
use PhpZip\Exception\ZipException;
|
||||||
|
use PhpZip\Tests\Internal\Epub\EpubFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the ability to create own file-type class, reader, writer and container.
|
||||||
|
*
|
||||||
|
* @see http://www.epubtest.org/test-books source epub files
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @small
|
||||||
|
*/
|
||||||
|
final class CustomZipFormatTest extends ZipTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws ZipException
|
||||||
|
*/
|
||||||
|
public function testEpub()
|
||||||
|
{
|
||||||
|
$epubFile = new EpubFile();
|
||||||
|
$epubFile->openFile(__DIR__ . '/resources/Advanced-v1.0.0.epub');
|
||||||
|
self::assertSame($epubFile->getRootFile(), 'EPUB/package.opf');
|
||||||
|
self::assertSame($epubFile->getMimeType(), 'application/epub+zip');
|
||||||
|
$epubInfo = $epubFile->getEpubInfo();
|
||||||
|
self::assertSame($epubInfo->toArray(), [
|
||||||
|
'title' => 'Advanced Accessibility Tests: Extended Descriptions',
|
||||||
|
'creator' => 'DAISY Consortium Transition to EPUB 3 and DIAGRAM Standards WG',
|
||||||
|
'language' => 'en-US',
|
||||||
|
'publisher' => 'DAISY Consortium and DIAGRAM Center',
|
||||||
|
'description' => 'Tests for accessible extended descriptions of images in EPUBs',
|
||||||
|
'rights' => 'This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike (CC BY-NC-SA) license.',
|
||||||
|
'date' => '2019-01-03',
|
||||||
|
'subject' => 'extended-descriptions',
|
||||||
|
]);
|
||||||
|
$epubFile->deleteFromName('mimetype');
|
||||||
|
self::assertFalse($epubFile->hasEntry('mimetype'));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$epubFile->getMimeType();
|
||||||
|
self::fail('deleted mimetype');
|
||||||
|
} catch (ZipEntryNotFoundException $e) {
|
||||||
|
self::assertSame('Zip Entry "mimetype" was not found in the archive.', $e->getMessage());
|
||||||
|
}
|
||||||
|
$epubFile->saveAsFile($this->outputFilename);
|
||||||
|
self::assertFalse($epubFile->hasEntry('mimetype'));
|
||||||
|
$epubFile->close();
|
||||||
|
|
||||||
|
self::assertCorrectZipArchive($this->outputFilename);
|
||||||
|
|
||||||
|
$epubFile->openFile($this->outputFilename);
|
||||||
|
// file appended in EpubWriter before write
|
||||||
|
self::assertTrue($epubFile->hasEntry('mimetype'));
|
||||||
|
$epubFile->close();
|
||||||
|
}
|
||||||
|
}
|
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();
|
||||||
|
}
|
||||||
|
}
|
@@ -2418,4 +2418,21 @@ class ZipFileTest extends ZipTestCase
|
|||||||
static::assertSame($zipFile->getEntry($newEntryName)->getCompressionMethod(), ZipCompressionMethod::STORED);
|
static::assertSame($zipFile->getEntry($newEntryName)->getCompressionMethod(), ZipCompressionMethod::STORED);
|
||||||
$zipFile->close();
|
$zipFile->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ZipEntryNotFoundException
|
||||||
|
* @throws ZipException
|
||||||
|
*/
|
||||||
|
public function testCloneZipContainerInZipWriter()
|
||||||
|
{
|
||||||
|
$zipFile = new ZipFile();
|
||||||
|
$zipFile['file 1'] = 'contents';
|
||||||
|
$zipEntryBeforeWrite = $zipFile->getEntry('file 1');
|
||||||
|
$zipFile->saveAsFile($this->outputFilename);
|
||||||
|
$zipAfterBeforeWrite = $zipFile->getEntry('file 1');
|
||||||
|
|
||||||
|
static::assertEquals($zipAfterBeforeWrite, $zipEntryBeforeWrite);
|
||||||
|
|
||||||
|
$zipFile->close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
BIN
tests/resources/Advanced-v1.0.0.epub
Normal file
BIN
tests/resources/Advanced-v1.0.0.epub
Normal file
Binary file not shown.
Reference in New Issue
Block a user