| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- <?php
- namespace PhpZip\Model;
- use PhpZip\Constants\ZipEncryptionMethod;
- use PhpZip\Exception\InvalidArgumentException;
- use PhpZip\Exception\ZipEntryNotFoundException;
- use PhpZip\Exception\ZipException;
- /**
- * Class ZipContainer.
- */
- class ZipContainer extends ImmutableZipContainer
- {
- /**
- * @var ImmutableZipContainer|null The source container contains zip entries from
- * an open zip archive. The source container makes
- * it possible to undo changes in the archive.
- * When cloning, this container is not cloned.
- */
- private $sourceContainer;
- /**
- * @var int|null Apk zipalign value
- *
- * @todo remove and use in ApkFileWriter
- */
- private $zipAlign;
- /**
- * MutableZipContainer constructor.
- *
- * @param ImmutableZipContainer|null $sourceContainer
- */
- public function __construct(ImmutableZipContainer $sourceContainer = null)
- {
- $entries = [];
- $archiveComment = null;
- if ($sourceContainer !== null) {
- foreach ($sourceContainer->getEntries() as $entryName => $entry) {
- $entries[$entryName] = clone $entry;
- }
- $archiveComment = $sourceContainer->getArchiveComment();
- }
- parent::__construct($entries, $archiveComment);
- $this->sourceContainer = $sourceContainer;
- }
- /**
- * @return ImmutableZipContainer|null
- */
- public function getSourceContainer()
- {
- return $this->sourceContainer;
- }
- /**
- * @param ZipEntry $entry
- */
- public function addEntry(ZipEntry $entry)
- {
- $this->entries[$entry->getName()] = $entry;
- }
- /**
- * @param string|ZipEntry $entry
- *
- * @return bool
- */
- public function deleteEntry($entry)
- {
- $entry = $entry instanceof ZipEntry ? $entry->getName() : (string) $entry;
- if (isset($this->entries[$entry])) {
- unset($this->entries[$entry]);
- return true;
- }
- return false;
- }
- /**
- * @param string|ZipEntry $old
- * @param string|ZipEntry $new
- *
- * @throws ZipException
- *
- * @return ZipEntry New zip entry
- */
- public function renameEntry($old, $new)
- {
- $old = $old instanceof ZipEntry ? $old->getName() : (string) $old;
- $new = $new instanceof ZipEntry ? $new->getName() : (string) $new;
- if (isset($this->entries[$new])) {
- throw new InvalidArgumentException('New entry name ' . $new . ' is exists.');
- }
- $entry = $this->getEntry($old);
- $newEntry = $entry->rename($new);
- $this->deleteEntry($entry);
- $this->addEntry($newEntry);
- return $newEntry;
- }
- /**
- * @param string|ZipEntry $entryName
- *
- * @throws ZipEntryNotFoundException
- *
- * @return ZipEntry
- */
- public function getEntry($entryName)
- {
- $entry = $this->getEntryOrNull($entryName);
- if ($entry !== null) {
- return $entry;
- }
- throw new ZipEntryNotFoundException($entryName);
- }
- /**
- * @param string|ZipEntry $entryName
- *
- * @return ZipEntry|null
- */
- public function getEntryOrNull($entryName)
- {
- $entryName = $entryName instanceof ZipEntry ? $entryName->getName() : (string) $entryName;
- return isset($this->entries[$entryName]) ? $this->entries[$entryName] : null;
- }
- /**
- * @param string|ZipEntry $entryName
- *
- * @return bool
- */
- public function hasEntry($entryName)
- {
- $entryName = $entryName instanceof ZipEntry ? $entryName->getName() : (string) $entryName;
- return isset($this->entries[$entryName]);
- }
- /**
- * Delete all entries.
- */
- public function deleteAll()
- {
- $this->entries = [];
- }
- /**
- * Delete entries by regex pattern.
- *
- * @param string $regexPattern Regex pattern
- *
- * @return ZipEntry[] Deleted entries
- */
- public function deleteByRegex($regexPattern)
- {
- if (empty($regexPattern)) {
- throw new InvalidArgumentException('The regex pattern is not specified');
- }
- /** @var ZipEntry[] $found */
- $found = [];
- foreach ($this->entries as $entryName => $entry) {
- if (preg_match($regexPattern, $entryName)) {
- $found[] = $entry;
- }
- }
- foreach ($found as $entry) {
- $this->deleteEntry($entry);
- }
- return $found;
- }
- /**
- * Undo all changes done in the archive.
- */
- public function unchangeAll()
- {
- $this->entries = [];
- if ($this->sourceContainer !== null) {
- foreach ($this->sourceContainer->getEntries() as $entry) {
- $this->entries[$entry->getName()] = clone $entry;
- }
- }
- $this->unchangeArchiveComment();
- }
- /**
- * Undo change archive comment.
- */
- public function unchangeArchiveComment()
- {
- $this->archiveComment = null;
- if ($this->sourceContainer !== null) {
- $this->archiveComment = $this->sourceContainer->archiveComment;
- }
- }
- /**
- * Revert all changes done to an entry with the given name.
- *
- * @param string|ZipEntry $entry Entry name or ZipEntry
- *
- * @return bool
- */
- public function unchangeEntry($entry)
- {
- $entry = $entry instanceof ZipEntry ? $entry->getName() : (string) $entry;
- if (
- $this->sourceContainer !== null &&
- isset($this->entries[$entry], $this->sourceContainer->entries[$entry])
- ) {
- $this->entries[$entry] = clone $this->sourceContainer->entries[$entry];
- return true;
- }
- return false;
- }
- /**
- * Entries sort by name.
- *
- * Example:
- * ```php
- * $zipContainer->sortByName(static function (string $nameA, string $nameB): int {
- * return strcmp($nameA, $nameB);
- * });
- * ```
- *
- * @param callable $cmp
- */
- public function sortByName(callable $cmp)
- {
- uksort($this->entries, $cmp);
- }
- /**
- * Entries sort by entry.
- *
- * Example:
- * ```php
- * $zipContainer->sortByEntry(static function (ZipEntry $a, ZipEntry $b): int {
- * return strcmp($a->getName(), $b->getName());
- * });
- * ```
- *
- * @param callable $cmp
- */
- public function sortByEntry(callable $cmp)
- {
- uasort($this->entries, $cmp);
- }
- /**
- * @param string|null $archiveComment
- */
- public function setArchiveComment($archiveComment)
- {
- if ($archiveComment !== null && $archiveComment !== '') {
- $archiveComment = (string) $archiveComment;
- $length = \strlen($archiveComment);
- if ($length > 0xffff) {
- throw new InvalidArgumentException('Length comment out of range');
- }
- }
- $this->archiveComment = $archiveComment;
- }
- /**
- * @return ZipEntryMatcher
- */
- public function matcher()
- {
- return new ZipEntryMatcher($this);
- }
- /**
- * Specify a password for extracting files.
- *
- * @param string|null $password
- */
- public function setReadPassword($password)
- {
- if ($this->sourceContainer !== null) {
- foreach ($this->sourceContainer->entries as $entry) {
- if ($entry->isEncrypted()) {
- $entry->setPassword($password);
- }
- }
- }
- }
- /**
- * @param string $entryName
- * @param string $password
- *
- * @throws ZipEntryNotFoundException
- * @throws ZipException
- */
- public function setReadPasswordEntry($entryName, $password)
- {
- if (!isset($this->sourceContainer->entries[$entryName])) {
- throw new ZipEntryNotFoundException($entryName);
- }
- if ($this->sourceContainer->entries[$entryName]->isEncrypted()) {
- $this->sourceContainer->entries[$entryName]->setPassword($password);
- }
- }
- /**
- * @return int|null
- */
- public function getZipAlign()
- {
- return $this->zipAlign;
- }
- /**
- * @param int|null $zipAlign
- */
- public function setZipAlign($zipAlign)
- {
- $this->zipAlign = $zipAlign === null ? null : (int) $zipAlign;
- }
- /**
- * @return bool
- */
- public function isZipAlign()
- {
- return $this->zipAlign !== null;
- }
- /**
- * @param string|null $writePassword
- */
- public function setWritePassword($writePassword)
- {
- $this->matcher()->all()->setPassword($writePassword);
- }
- /**
- * Remove password.
- */
- public function removePassword()
- {
- $this->matcher()->all()->setPassword(null);
- }
- /**
- * @param string|ZipEntry $entryName
- */
- public function removePasswordEntry($entryName)
- {
- $this->matcher()->add($entryName)->setPassword(null);
- }
- /**
- * @param int $encryptionMethod
- */
- public function setEncryptionMethod($encryptionMethod = ZipEncryptionMethod::WINZIP_AES_256)
- {
- $this->matcher()->all()->setEncryptionMethod($encryptionMethod);
- }
- }
|