mirror of
https://github.com/Ne-Lexa/php-zip.git
synced 2025-01-16 23:08:14 +01:00
php8 support
This commit is contained in:
parent
44c2041f62
commit
a65fe4579b
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2,7 +2,6 @@
|
|||||||
.github export-ignore
|
.github export-ignore
|
||||||
.gitignore export-ignore
|
.gitignore export-ignore
|
||||||
.php_cs export-ignore
|
.php_cs export-ignore
|
||||||
.travis.yml export-ignore
|
|
||||||
bootstrap.php export-ignore
|
bootstrap.php export-ignore
|
||||||
phpunit.xml export-ignore
|
phpunit.xml export-ignore
|
||||||
tests export-ignore
|
tests export-ignore
|
||||||
|
122
.github/workflows/build.yml
vendored
122
.github/workflows/build.yml
vendored
@ -1,48 +1,86 @@
|
|||||||
name: build
|
name: build
|
||||||
|
|
||||||
on: [ push, pull_request ]
|
on:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run:
|
tests:
|
||||||
runs-on: ${{ matrix.operating-system }}
|
name: PHP ${{ matrix.php }} Test on ${{ matrix.os }}
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
operating-system: [ubuntu-latest]
|
|
||||||
php-versions: ['7.2', '7.3', '7.4', '8.0']
|
|
||||||
name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v1
|
|
||||||
|
|
||||||
- name: Setup PHP
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-versions }}
|
|
||||||
extensions: mbstring, intl, zip
|
|
||||||
coverage: none
|
|
||||||
|
|
||||||
- name: Check PHP Version
|
|
||||||
run: php -v
|
|
||||||
|
|
||||||
- name: Check Composer Version
|
|
||||||
run: composer -V
|
|
||||||
|
|
||||||
- name: Check PHP Extensions
|
|
||||||
run: php -m
|
|
||||||
|
|
||||||
- name: Validate composer.json and composer.lock
|
|
||||||
run: composer validate
|
|
||||||
|
|
||||||
- name: Install dependencies for PHP 7
|
|
||||||
if: matrix.php-versions < '8.0'
|
|
||||||
run: composer update --prefer-dist --no-progress
|
|
||||||
|
|
||||||
- name: Install dependencies for PHP 8
|
|
||||||
if: matrix.php-versions >= '8.0'
|
|
||||||
run: composer update --prefer-dist --no-progress --ignore-platform-req=php
|
|
||||||
|
|
||||||
- name: Run test suite
|
|
||||||
run: composer check
|
|
||||||
env:
|
env:
|
||||||
PHP_CS_FIXER_IGNORE_ENV: 1
|
extensions: bz2, dom, iconv, fileinfo, openssl, xml, zlib
|
||||||
|
key: cache-v1
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- windows-latest
|
||||||
|
php:
|
||||||
|
- '7.4'
|
||||||
|
- '8.0'
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Install linux dependencies
|
||||||
|
run: sudo apt-get install unzip p7zip-full
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Install PHP with extensions
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php }}
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
coverage: pcov
|
||||||
|
ini-values: date.timezone='UTC'
|
||||||
|
tools: composer:v2
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Determine composer cache directory on Linux
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Determine composer cache directory on Windows
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
run: echo "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Cache dependencies installed with composer
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ env.COMPOSER_CACHE_DIR }}
|
||||||
|
key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
php${{ matrix.php }}-composer-
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Check PHP Version
|
||||||
|
run: php -v
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Check Composer Version
|
||||||
|
run: composer -V
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Check PHP Extensions
|
||||||
|
run: php -m
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Validate composer.json and composer.lock
|
||||||
|
run: composer validate
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Install dependencies with composer
|
||||||
|
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Run tests with phpunit
|
||||||
|
run: vendor/bin/phpunit --colors=always
|
||||||
|
67
.travis.yml
67
.travis.yml
@ -1,67 +0,0 @@
|
|||||||
language: php
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- COVERAGE=false
|
|
||||||
- PHPUNIT_FLAGS="-v -c phpunit.xml"
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- php: 5.5
|
|
||||||
os: linux
|
|
||||||
dist: trusty
|
|
||||||
env: ZIPALIGN_INSTALL=false
|
|
||||||
|
|
||||||
- php: 5.6
|
|
||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
env: ZIPALIGN_INSTALL=true
|
|
||||||
|
|
||||||
- php: 7.0
|
|
||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
env: ZIPALIGN_INSTALL=true
|
|
||||||
|
|
||||||
- php: 7.1
|
|
||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
env: ZIPALIGN_INSTALL=true
|
|
||||||
|
|
||||||
- php: 7.2
|
|
||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
env: ZIPALIGN_INSTALL=true
|
|
||||||
|
|
||||||
- php: 7.3
|
|
||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
env: ZIPALIGN_INSTALL=true
|
|
||||||
|
|
||||||
- php: 7.4
|
|
||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
env: COVERAGE=true ZIPALIGN_INSTALL=true PHPUNIT_FLAGS="-v -c phpunit.xml --coverage-clover=coverage.clover"
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi
|
|
||||||
|
|
||||||
install:
|
|
||||||
- travis_retry composer self-update && composer --version
|
|
||||||
- travis_retry composer install --no-interaction
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- unzip
|
|
||||||
- p7zip-full
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- if [[ $ZIPALIGN_INSTALL = true ]]; then sudo apt-get install -y zipalign; fi
|
|
||||||
|
|
||||||
script:
|
|
||||||
- composer validate --no-check-lock
|
|
||||||
- vendor/bin/phpunit ${PHPUNIT_FLAGS}
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- if [[ $COVERAGE = true ]]; then wget https://scrutinizer-ci.com/ocular.phar; fi
|
|
||||||
- if [[ $COVERAGE = true ]]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
|
|
47
README.RU.md
47
README.RU.md
@ -28,7 +28,6 @@
|
|||||||
+ [Удаление записей из архива](#Documentation-Remove-Zip-Entries)
|
+ [Удаление записей из архива](#Documentation-Remove-Zip-Entries)
|
||||||
+ [Работа с записями и с архивом](#Documentation-Entries)
|
+ [Работа с записями и с архивом](#Documentation-Entries)
|
||||||
+ [Работа с паролями](#Documentation-Password)
|
+ [Работа с паролями](#Documentation-Password)
|
||||||
+ [zipalign - выравнивание архива для оптимизации Android пакетов (APK)](#Documentation-ZipAlign-Usage)
|
|
||||||
+ [Отмена изменений](#Documentation-Unchanged)
|
+ [Отмена изменений](#Documentation-Unchanged)
|
||||||
+ [Сохранение файла или вывод в браузер](#Documentation-Save-Or-Output-Entries)
|
+ [Сохранение файла или вывод в браузер](#Documentation-Save-Or-Output-Entries)
|
||||||
+ [Закрытие архива](#Documentation-Close-Zip-Archive)
|
+ [Закрытие архива](#Documentation-Close-Zip-Archive)
|
||||||
@ -50,8 +49,7 @@
|
|||||||
+ Deflate сжатие.
|
+ Deflate сжатие.
|
||||||
+ BZIP2 сжатие при наличии расширения `php-bz2`.
|
+ BZIP2 сжатие при наличии расширения `php-bz2`.
|
||||||
- Поддержка `ZIP64` (размер файла более 4 GB или количество записей в архиве более 65535).
|
- Поддержка `ZIP64` (размер файла более 4 GB или количество записей в архиве более 65535).
|
||||||
- Встроенная поддержка выравнивания архива для оптимизации Android пакетов (APK) [`zipalign`](https://developer.android.com/studio/command-line/zipalign.html).
|
- Работа с паролями
|
||||||
- Работа с паролями для PHP 5.5
|
|
||||||
> **Внимание!**
|
> **Внимание!**
|
||||||
>
|
>
|
||||||
> Для 32-bit систем, в данный момент не поддерживается метод шифрование `Traditional PKWARE Encryption (ZipCrypto)`.
|
> Для 32-bit систем, в данный момент не поддерживается метод шифрование `Traditional PKWARE Encryption (ZipCrypto)`.
|
||||||
@ -66,9 +64,9 @@
|
|||||||
+ Установка метода шифрования для всех или для отдельных записей в архиве.
|
+ Установка метода шифрования для всех или для отдельных записей в архиве.
|
||||||
|
|
||||||
### <a name="Requirements"></a> Требования
|
### <a name="Requirements"></a> Требования
|
||||||
- `PHP` >= 5.5 (предпочтительно 64-bit).
|
- `PHP` 7.4 или ^8.0 (предпочтительно 64-bit).
|
||||||
- Опционально php-расширение `bzip2` для поддержки BZIP2 компрессии.
|
- Опционально php-расширение `bzip2` для поддержки BZIP2 компрессии.
|
||||||
- Опционально php-расширение `openssl` или `mcrypt` для `WinZip Aes Encryption` шифрования.
|
- Опционально php-расширение `openssl` для `WinZip Aes Encryption` шифрования.
|
||||||
|
|
||||||
### <a name="Installation"></a> Установка
|
### <a name="Installation"></a> Установка
|
||||||
`composer require nelexa/zip`
|
`composer require nelexa/zip`
|
||||||
@ -110,10 +108,10 @@ finally{
|
|||||||
|
|
||||||
### <a name="Documentation"></a> Документация
|
### <a name="Documentation"></a> Документация
|
||||||
#### <a name="Documentation-Overview"></a> Обзор методов класса `\PhpZip\ZipFile`
|
#### <a name="Documentation-Overview"></a> Обзор методов класса `\PhpZip\ZipFile`
|
||||||
- [ZipFile::__construct](#Documentation-ZipFile-__construct) - инициализацирует ZIP-архив.
|
- [ZipFile::__construct](#Documentation-ZipFile-__construct) - инициализирует ZIP-архив.
|
||||||
- [ZipFile::addAll](#Documentation-ZipFile-addAll) - добавляет все записи из массива.
|
- [ZipFile::addAll](#Documentation-ZipFile-addAll) - добавляет все записи из массива.
|
||||||
- [ZipFile::addDir](#Documentation-ZipFile-addDir) - добавляет файлы из директории по указанному пути без вложенных директорий.
|
- [ZipFile::addDir](#Documentation-ZipFile-addDir) - добавляет файлы из директории по указанному пути без вложенных директорий.
|
||||||
- [ZipFile::addDirRecursive](#Documentation-ZipFile-addDirRecursive) - добавляет файлы из директории по указанному пути c вложенными директориями.
|
- [ZipFile::addDirRecursive](#Documentation-ZipFile-addDirRecursive) - добавляет файлы из директории по указанному пути с вложенными директориями.
|
||||||
- [ZipFile::addEmptyDir](#Documentation-ZipFile-addEmptyDir) - добавляет в ZIP-архив новую директорию.
|
- [ZipFile::addEmptyDir](#Documentation-ZipFile-addEmptyDir) - добавляет в ZIP-архив новую директорию.
|
||||||
- [ZipFile::addFile](#Documentation-ZipFile-addFile) - добавляет в ZIP-архив файл по указанному пути.
|
- [ZipFile::addFile](#Documentation-ZipFile-addFile) - добавляет в ZIP-архив файл по указанному пути.
|
||||||
- [ZipFile::addSplFile](#Documentation-ZipFile-addSplFile) - добавляет объект `\SplFileInfo` в zip-архив.
|
- [ZipFile::addSplFile](#Documentation-ZipFile-addSplFile) - добавляет объект `\SplFileInfo` в zip-архив.
|
||||||
@ -122,7 +120,7 @@ finally{
|
|||||||
- [ZipFile::addFilesFromGlob](#Documentation-ZipFile-addFilesFromGlob) - добавляет файлы из директории в соответствии с glob шаблоном без вложенных директорий.
|
- [ZipFile::addFilesFromGlob](#Documentation-ZipFile-addFilesFromGlob) - добавляет файлы из директории в соответствии с glob шаблоном без вложенных директорий.
|
||||||
- [ZipFile::addFilesFromGlobRecursive](#Documentation-ZipFile-addFilesFromGlobRecursive) - добавляет файлы из директории в соответствии с glob шаблоном c вложенными директориями.
|
- [ZipFile::addFilesFromGlobRecursive](#Documentation-ZipFile-addFilesFromGlobRecursive) - добавляет файлы из директории в соответствии с glob шаблоном c вложенными директориями.
|
||||||
- [ZipFile::addFilesFromRegex](#Documentation-ZipFile-addFilesFromRegex) - добавляет файлы из директории в соответствии с регулярным выражением без вложенных директорий.
|
- [ZipFile::addFilesFromRegex](#Documentation-ZipFile-addFilesFromRegex) - добавляет файлы из директории в соответствии с регулярным выражением без вложенных директорий.
|
||||||
- [ZipFile::addFilesFromRegexRecursive](#Documentation-ZipFile-addFilesFromRegexRecursive) - добавляет файлы из директории в соответствии с регулярным выражением c вложенными директориями.
|
- [ZipFile::addFilesFromRegexRecursive](#Documentation-ZipFile-addFilesFromRegexRecursive) - добавляет файлы из директории в соответствии с регулярным выражением с вложенными директориями.
|
||||||
- [ZipFile::addFromStream](#Documentation-ZipFile-addFromStream) - добавляет в ZIP-архив запись из потока.
|
- [ZipFile::addFromStream](#Documentation-ZipFile-addFromStream) - добавляет в ZIP-архив запись из потока.
|
||||||
- [ZipFile::addFromString](#Documentation-ZipFile-addFromString) - добавляет файл в ZIP-архив, используя его содержимое в виде строки.
|
- [ZipFile::addFromString](#Documentation-ZipFile-addFromString) - добавляет файл в ZIP-архив, используя его содержимое в виде строки.
|
||||||
- [ZipFile::close](#Documentation-ZipFile-close) - закрывает ZIP-архив.
|
- [ZipFile::close](#Documentation-ZipFile-close) - закрывает ZIP-архив.
|
||||||
@ -134,11 +132,9 @@ finally{
|
|||||||
- [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption) - отключает шифрования всех записей, находящихся в архиве.
|
- [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption) - отключает шифрования всех записей, находящихся в архиве.
|
||||||
- [ZipFile::disableEncryptionEntry](#Documentation-ZipFile-disableEncryptionEntry) - отключает шифрование записи по её имени.
|
- [ZipFile::disableEncryptionEntry](#Documentation-ZipFile-disableEncryptionEntry) - отключает шифрование записи по её имени.
|
||||||
- [ZipFile::extractTo](#Documentation-ZipFile-extractTo) - извлекает содержимое архива в заданную директорию.
|
- [ZipFile::extractTo](#Documentation-ZipFile-extractTo) - извлекает содержимое архива в заданную директорию.
|
||||||
- [ZipFile::getAllInfo](#Documentation-ZipFile-getAllInfo) - возвращает подробную информацию обо всех записях в архиве.
|
|
||||||
- [ZipFile::getArchiveComment](#Documentation-ZipFile-getArchiveComment) - возвращает комментарий ZIP-архива.
|
- [ZipFile::getArchiveComment](#Documentation-ZipFile-getArchiveComment) - возвращает комментарий ZIP-архива.
|
||||||
- [ZipFile::getEntryComment](#Documentation-ZipFile-getEntryComment) - возвращает комментарий к записи, используя её имя.
|
- [ZipFile::getEntryComment](#Documentation-ZipFile-getEntryComment) - возвращает комментарий к записи, используя её имя.
|
||||||
- [ZipFile::getEntryContent](#Documentation-ZipFile-getEntryContent) - возвращает содержимое записи.
|
- [ZipFile::getEntryContent](#Documentation-ZipFile-getEntryContent) - возвращает содержимое записи.
|
||||||
- [ZipFile::getEntryInfo](#Documentation-ZipFile-getEntryInfo) - возвращает подробную информацию о записи в архиве.
|
|
||||||
- [ZipFile::getListFiles](#Documentation-ZipFile-getListFiles) - возвращает список файлов архива.
|
- [ZipFile::getListFiles](#Documentation-ZipFile-getListFiles) - возвращает список файлов архива.
|
||||||
- [ZipFile::hasEntry](#Documentation-ZipFile-hasEntry) - проверяет, присутствует ли запись в архиве.
|
- [ZipFile::hasEntry](#Documentation-ZipFile-hasEntry) - проверяет, присутствует ли запись в архиве.
|
||||||
- [ZipFile::isDirectory](#Documentation-ZipFile-isDirectory) - проверяет, является ли запись в архиве директорией.
|
- [ZipFile::isDirectory](#Documentation-ZipFile-isDirectory) - проверяет, является ли запись в архиве директорией.
|
||||||
@ -160,15 +156,11 @@ finally{
|
|||||||
- [ZipFile::setEntryComment](#Documentation-ZipFile-setEntryComment) - устанавливает комментарий к записи, используя её имя.
|
- [ZipFile::setEntryComment](#Documentation-ZipFile-setEntryComment) - устанавливает комментарий к записи, используя её имя.
|
||||||
- [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword) - устанавливает пароль на чтение открытого запароленного архива для всех зашифрованных записей.
|
- [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword) - устанавливает пароль на чтение открытого запароленного архива для всех зашифрованных записей.
|
||||||
- [ZipFile::setReadPasswordEntry](#Documentation-ZipFile-setReadPasswordEntry) - устанавливает пароль на чтение конкретной зашифрованной записи открытого запароленного архива.
|
- [ZipFile::setReadPasswordEntry](#Documentation-ZipFile-setReadPasswordEntry) - устанавливает пароль на чтение конкретной зашифрованной записи открытого запароленного архива.
|
||||||
- ~~ZipFile::withNewPassword~~ - устаревший метод (**deprecated**) используйте метод [ZipFile::setPassword](#Documentation-ZipFile-setPassword).
|
|
||||||
- [ZipFile::setPassword](#Documentation-ZipFile-setPassword) - устанавливает новый пароль для всех файлов, находящихся в архиве.
|
- [ZipFile::setPassword](#Documentation-ZipFile-setPassword) - устанавливает новый пароль для всех файлов, находящихся в архиве.
|
||||||
- [ZipFile::setPasswordEntry](#Documentation-ZipFile-setPasswordEntry) - устанавливает новый пароль для конкретного файла.
|
- [ZipFile::setPasswordEntry](#Documentation-ZipFile-setPasswordEntry) - устанавливает новый пароль для конкретного файла.
|
||||||
- [ZipFile::setZipAlign](#Documentation-ZipFile-setZipAlign) - устанавливает выравнивание архива для оптимизации APK файлов (Android packages).
|
|
||||||
- [ZipFile::unchangeAll](#Documentation-ZipFile-unchangeAll) - отменяет все изменения, сделанные в архиве.
|
- [ZipFile::unchangeAll](#Documentation-ZipFile-unchangeAll) - отменяет все изменения, сделанные в архиве.
|
||||||
- [ZipFile::unchangeArchiveComment](#Documentation-ZipFile-unchangeArchiveComment) - отменяет изменения в комментарии к архиву.
|
- [ZipFile::unchangeArchiveComment](#Documentation-ZipFile-unchangeArchiveComment) - отменяет изменения в комментарии к архиву.
|
||||||
- [ZipFile::unchangeEntry](#Documentation-ZipFile-unchangeEntry) - отменяет изменения для конкретной записи архива.
|
- [ZipFile::unchangeEntry](#Documentation-ZipFile-unchangeEntry) - отменяет изменения для конкретной записи архива.
|
||||||
- ~~ZipFile::withoutPassword~~ - устаревший метод (**deprecated**) используйте метод [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption).
|
|
||||||
- ~~ZipFile::withReadPassword~~ - устаревший метод (**deprecated**) используйте метод [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword).
|
|
||||||
|
|
||||||
#### <a name="Documentation-Open-Zip-Archive"></a> Создание/Открытие ZIP-архива
|
#### <a name="Documentation-Open-Zip-Archive"></a> Создание/Открытие ZIP-архива
|
||||||
<a name="Documentation-ZipFile-__construct"></a>**ZipFile::__construct** - Инициализацирует ZIP-архив.
|
<a name="Documentation-ZipFile-__construct"></a>**ZipFile::__construct** - Инициализацирует ZIP-архив.
|
||||||
@ -289,15 +281,6 @@ $commentArchive = $zipFile->getArchiveComment();
|
|||||||
```php
|
```php
|
||||||
$commentEntry = $zipFile->getEntryComment($entryName);
|
$commentEntry = $zipFile->getEntryComment($entryName);
|
||||||
```
|
```
|
||||||
<a name="Documentation-ZipFile-getEntryInfo"></a> **ZipFile::getEntryInfo** - возвращает подробную информацию о записи в архиве.
|
|
||||||
```php
|
|
||||||
$zipFile = new \PhpZip\ZipFile();
|
|
||||||
$zipInfo = $zipFile->getEntryInfo('file.txt');
|
|
||||||
```
|
|
||||||
<a name="Documentation-ZipFile-getAllInfo"></a> **ZipFile::getAllInfo** - возвращает подробную информацию обо всех записях в архиве.
|
|
||||||
```php
|
|
||||||
$zipAllInfo = $zipFile->getAllInfo();
|
|
||||||
```
|
|
||||||
#### <a name="Documentation-Add-Zip-Entries"></a> Добавление записей в архив
|
#### <a name="Documentation-Add-Zip-Entries"></a> Добавление записей в архив
|
||||||
|
|
||||||
Все методы добавления записей в ZIP-архив позволяют указать метод сжатия содержимого.
|
Все методы добавления записей в ZIP-архив позволяют указать метод сжатия содержимого.
|
||||||
@ -395,7 +378,7 @@ $zipFile[$path] = null;
|
|||||||
$entries = [
|
$entries = [
|
||||||
'file.txt' => 'file contents', // запись из строки данных
|
'file.txt' => 'file contents', // запись из строки данных
|
||||||
'empty dir/' => null, // пустой каталог
|
'empty dir/' => null, // пустой каталог
|
||||||
'path/to/file.jpg' => fopen('..../filename', 'r'), // запись из потока
|
'path/to/file.jpg' => fopen('..../filename', 'rb'), // запись из потока
|
||||||
'path/to/file.dat' => new \SplFileInfo('..../filename'), // запись из файла
|
'path/to/file.dat' => new \SplFileInfo('..../filename'), // запись из файла
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -683,18 +666,6 @@ $zipFile->disableEncryption();
|
|||||||
```php
|
```php
|
||||||
$zipFile->disableEncryptionEntry($entryName);
|
$zipFile->disableEncryptionEntry($entryName);
|
||||||
```
|
```
|
||||||
#### <a name="Documentation-ZipAlign-Usage"></a> zipalign
|
|
||||||
<a name="Documentation-ZipFile-setZipAlign"></a> **ZipFile::setZipAlign** - устанавливает выравнивание архива для оптимизации APK файлов (Android packages).
|
|
||||||
|
|
||||||
Метод добавляет паддинги незашифрованным и не сжатым записям, для оптимизации расхода памяти в системе Android. Рекомендуется использовать для `APK` файлов. Файл может незначительно увеличиться.
|
|
||||||
|
|
||||||
Этот метод является альтернативой вызова команды `zipalign -f -v 4 filename.zip`.
|
|
||||||
|
|
||||||
Подробнее можно ознакомиться по [ссылке](https://developer.android.com/studio/command-line/zipalign.html).
|
|
||||||
```php
|
|
||||||
// вызовите до сохранения или вывода архива
|
|
||||||
$zipFile->setZipAlign(4);
|
|
||||||
```
|
|
||||||
#### <a name="Documentation-Unchanged"></a> Отмена изменений
|
#### <a name="Documentation-Unchanged"></a> Отмена изменений
|
||||||
<a name="Documentation-ZipFile-unchangeAll"></a> **ZipFile::unchangeAll** - отменяет все изменения, сделанные в архиве.
|
<a name="Documentation-ZipFile-unchangeAll"></a> **ZipFile::unchangeAll** - отменяет все изменения, сделанные в архиве.
|
||||||
```php
|
```php
|
||||||
@ -731,7 +702,7 @@ $zipFile->outputAsAttachment($outputFilename);
|
|||||||
```
|
```
|
||||||
Можно установить MIME-тип:
|
Можно установить MIME-тип:
|
||||||
```php
|
```php
|
||||||
$mimeType = 'application/zip'
|
$mimeType = 'application/zip';
|
||||||
$zipFile->outputAsAttachment($outputFilename, $mimeType);
|
$zipFile->outputAsAttachment($outputFilename, $mimeType);
|
||||||
```
|
```
|
||||||
<a name="Documentation-ZipFile-outputAsResponse"></a> **ZipFile::outputAsResponse** - выводит ZIP-архив, как Response [PSR-7](http://www.php-fig.org/psr/psr-7/).
|
<a name="Documentation-ZipFile-outputAsResponse"></a> **ZipFile::outputAsResponse** - выводит ZIP-архив, как Response [PSR-7](http://www.php-fig.org/psr/psr-7/).
|
||||||
@ -743,7 +714,7 @@ $zipFile->outputAsResponse($response, $outputFilename);
|
|||||||
```
|
```
|
||||||
Можно установить MIME-тип:
|
Можно установить MIME-тип:
|
||||||
```php
|
```php
|
||||||
$mimeType = 'application/zip'
|
$mimeType = 'application/zip';
|
||||||
$zipFile->outputAsResponse($response, $outputFilename, $mimeType);
|
$zipFile->outputAsResponse($response, $outputFilename, $mimeType);
|
||||||
```
|
```
|
||||||
Пример для Slim Framework:
|
Пример для Slim Framework:
|
||||||
|
71
README.md
71
README.md
@ -6,11 +6,16 @@
|
|||||||
[![Code Coverage](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/?branch=master)
|
[![Code Coverage](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/?branch=master)
|
||||||
[![Latest Stable Version](https://poser.pugx.org/nelexa/zip/v/stable)](https://packagist.org/packages/nelexa/zip)
|
[![Latest Stable Version](https://poser.pugx.org/nelexa/zip/v/stable)](https://packagist.org/packages/nelexa/zip)
|
||||||
[![Total Downloads](https://poser.pugx.org/nelexa/zip/downloads)](https://packagist.org/packages/nelexa/zip)
|
[![Total Downloads](https://poser.pugx.org/nelexa/zip/downloads)](https://packagist.org/packages/nelexa/zip)
|
||||||
[![Minimum PHP Version](http://img.shields.io/badge/php-%3E%3D%205.5-8892BF.svg)](https://php.net/)
|
|
||||||
[![License](https://poser.pugx.org/nelexa/zip/license)](https://packagist.org/packages/nelexa/zip)
|
[![License](https://poser.pugx.org/nelexa/zip/license)](https://packagist.org/packages/nelexa/zip)
|
||||||
|
|
||||||
[Russian Documentation](README.RU.md)
|
[Russian Documentation](README.RU.md)
|
||||||
|
|
||||||
|
### Versions & Dependencies
|
||||||
|
| Version | PHP | Documentation |
|
||||||
|
| ------------------- | ---------- | -------------------------------------------------------------------- |
|
||||||
|
| ^4.0 (master) | ^7.4\|^8.0 | current |
|
||||||
|
| ^3.0 | ^5.5\|^7.0 | [Docs v3.3](https://github.com/Ne-Lexa/php-zip/blob/3.3.3/README.md) |
|
||||||
|
|
||||||
Table of contents
|
Table of contents
|
||||||
-----------------
|
-----------------
|
||||||
- [Features](#Features)
|
- [Features](#Features)
|
||||||
@ -28,13 +33,13 @@ Table of contents
|
|||||||
+ [Deleting entries from the archive](#Documentation-Remove-Zip-Entries)
|
+ [Deleting entries from the archive](#Documentation-Remove-Zip-Entries)
|
||||||
+ [Working with entries and archive](#Documentation-Entries)
|
+ [Working with entries and archive](#Documentation-Entries)
|
||||||
+ [Working with passwords](#Documentation-Password)
|
+ [Working with passwords](#Documentation-Password)
|
||||||
+ [zipalign - alignment tool for Android (APK) files](#Documentation-ZipAlign-Usage)
|
|
||||||
+ [Undo changes](#Documentation-Unchanged)
|
+ [Undo changes](#Documentation-Unchanged)
|
||||||
+ [Saving a file or output to a browser](#Documentation-Save-Or-Output-Entries)
|
+ [Saving a file or output to a browser](#Documentation-Save-Or-Output-Entries)
|
||||||
+ [Closing the archive](#Documentation-Close-Zip-Archive)
|
+ [Closing the archive](#Documentation-Close-Zip-Archive)
|
||||||
- [Running the tests](#Running-Tests)
|
- [Running the tests](#Running-Tests)
|
||||||
- [Changelog](#Changelog)
|
- [Changelog](#Changelog)
|
||||||
- [Upgrade](#Upgrade)
|
- [Upgrade](#Upgrade)
|
||||||
|
+ [Upgrade version 3 to version 4](#Upgrade-v3-to-v4)
|
||||||
+ [Upgrade version 2 to version 3.0](#Upgrade-v2-to-v3)
|
+ [Upgrade version 2 to version 3.0](#Upgrade-v2-to-v3)
|
||||||
|
|
||||||
### <a name="Features"></a> Features
|
### <a name="Features"></a> Features
|
||||||
@ -50,8 +55,7 @@ Table of contents
|
|||||||
+ Deflate compression.
|
+ Deflate compression.
|
||||||
+ BZIP2 compression with the extension `php-bz2`.
|
+ BZIP2 compression with the extension `php-bz2`.
|
||||||
- Support for `ZIP64` (file size is more than 4 GB or the number of entries in the archive is more than 65535).
|
- Support for `ZIP64` (file size is more than 4 GB or the number of entries in the archive is more than 65535).
|
||||||
- Built-in support for aligning the archive to optimize Android packages (APK) [`zipalign`](https://developer.android.com/studio/command-line/zipalign.html).
|
- Working with passwords
|
||||||
- Working with passwords for PHP 5.5
|
|
||||||
> **Attention!**
|
> **Attention!**
|
||||||
>
|
>
|
||||||
> For 32-bit systems, the `Traditional PKWARE Encryption (ZipCrypto)` encryption method is not currently supported.
|
> For 32-bit systems, the `Traditional PKWARE Encryption (ZipCrypto)` encryption method is not currently supported.
|
||||||
@ -66,9 +70,9 @@ Table of contents
|
|||||||
+ Set the encryption method for all or individual entries in the archive.
|
+ Set the encryption method for all or individual entries in the archive.
|
||||||
|
|
||||||
### <a name="Requirements"></a> Requirements
|
### <a name="Requirements"></a> Requirements
|
||||||
- `PHP` >= 7.2 or `PHP` >= 8.0 (preferably 64-bit).
|
- `PHP` >= 7.4 or `PHP` >= 8.0 (preferably 64-bit).
|
||||||
- Optional php-extension `bzip2` for BZIP2 compression.
|
- Optional php-extension `bzip2` for BZIP2 compression.
|
||||||
- Optional php-extension `openssl` or `mcrypt` for `WinZip Aes Encryption` support.
|
- Optional php-extension `openssl` for `WinZip Aes Encryption` support.
|
||||||
|
|
||||||
### <a name="Installation"></a> Installation
|
### <a name="Installation"></a> Installation
|
||||||
`composer require nelexa/zip`
|
`composer require nelexa/zip`
|
||||||
@ -123,22 +127,20 @@ Other examples can be found in the `tests/` folder
|
|||||||
- [ZipFile::addFilesFromGlobRecursive](#Documentation-ZipFile-addFilesFromGlobRecursive) - adds files from a directory by glob pattern with subdirectories.
|
- [ZipFile::addFilesFromGlobRecursive](#Documentation-ZipFile-addFilesFromGlobRecursive) - adds files from a directory by glob pattern with subdirectories.
|
||||||
- [ZipFile::addFilesFromRegex](#Documentation-ZipFile-addFilesFromRegex) - adds files from a directory by PCRE pattern without subdirectories.
|
- [ZipFile::addFilesFromRegex](#Documentation-ZipFile-addFilesFromRegex) - adds files from a directory by PCRE pattern without subdirectories.
|
||||||
- [ZipFile::addFilesFromRegexRecursive](#Documentation-ZipFile-addFilesFromRegexRecursive) - adds files from a directory by PCRE pattern with subdirectories.
|
- [ZipFile::addFilesFromRegexRecursive](#Documentation-ZipFile-addFilesFromRegexRecursive) - adds files from a directory by PCRE pattern with subdirectories.
|
||||||
- [ZipFile::addFromStream](#Documentation-ZipFile-addFromStream) - adds a entry from the stream to the ZIP archive.
|
- [ZipFile::addFromStream](#Documentation-ZipFile-addFromStream) - adds an entry from the stream to the ZIP archive.
|
||||||
- [ZipFile::addFromString](#Documentation-ZipFile-addFromString) - adds a file to a ZIP archive using its contents.
|
- [ZipFile::addFromString](#Documentation-ZipFile-addFromString) - adds a file to a ZIP archive using its contents.
|
||||||
- [ZipFile::close](#Documentation-ZipFile-close) - close the archive.
|
- [ZipFile::close](#Documentation-ZipFile-close) - close the archive.
|
||||||
- [ZipFile::count](#Documentation-ZipFile-count) - returns the number of entries in the archive.
|
- [ZipFile::count](#Documentation-ZipFile-count) - returns the number of entries in the archive.
|
||||||
- [ZipFile::deleteFromName](#Documentation-ZipFile-deleteFromName) - deletes an entry in the archive using its name.
|
- [ZipFile::deleteFromName](#Documentation-ZipFile-deleteFromName) - deletes an entry in the archive using its name.
|
||||||
- [ZipFile::deleteFromGlob](#Documentation-ZipFile-deleteFromGlob) - deletes a entries in the archive using glob pattern.
|
- [ZipFile::deleteFromGlob](#Documentation-ZipFile-deleteFromGlob) - deletes an entries in the archive using glob pattern.
|
||||||
- [ZipFile::deleteFromRegex](#Documentation-ZipFile-deleteFromRegex) - deletes a entries in the archive using PCRE pattern.
|
- [ZipFile::deleteFromRegex](#Documentation-ZipFile-deleteFromRegex) - deletes an entries in the archive using PCRE pattern.
|
||||||
- [ZipFile::deleteAll](#Documentation-ZipFile-deleteAll) - deletes all entries in the ZIP archive.
|
- [ZipFile::deleteAll](#Documentation-ZipFile-deleteAll) - deletes all entries in the ZIP archive.
|
||||||
- [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption) - disable encryption for all entries that are already in the archive.
|
- [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption) - disable encryption for all entries that are already in the archive.
|
||||||
- [ZipFile::disableEncryptionEntry](#Documentation-ZipFile-disableEncryptionEntry) - disable encryption of an entry defined by its name.
|
- [ZipFile::disableEncryptionEntry](#Documentation-ZipFile-disableEncryptionEntry) - disable encryption of an entry defined by its name.
|
||||||
- [ZipFile::extractTo](#Documentation-ZipFile-extractTo) - extract the archive contents.
|
- [ZipFile::extractTo](#Documentation-ZipFile-extractTo) - extract the archive contents.
|
||||||
- [ZipFile::getAllInfo](#Documentation-ZipFile-getAllInfo) - returns detailed information about all entries in the archive.
|
|
||||||
- [ZipFile::getArchiveComment](#Documentation-ZipFile-getArchiveComment) - returns the Zip archive comment.
|
- [ZipFile::getArchiveComment](#Documentation-ZipFile-getArchiveComment) - returns the Zip archive comment.
|
||||||
- [ZipFile::getEntryComment](#Documentation-ZipFile-getEntryComment) - returns the comment of an entry using the entry name.
|
- [ZipFile::getEntryComment](#Documentation-ZipFile-getEntryComment) - returns the comment of an entry using the entry name.
|
||||||
- [ZipFile::getEntryContent](#Documentation-ZipFile-getEntryContent) - returns the entry contents using its name.
|
- [ZipFile::getEntryContent](#Documentation-ZipFile-getEntryContent) - returns the entry contents using its name.
|
||||||
- [ZipFile::getEntryInfo](#Documentation-ZipFile-getEntryInfo) - returns detailed information about the entry in the archive.
|
|
||||||
- [ZipFile::getListFiles](#Documentation-ZipFile-getListFiles) - returns list of archive files.
|
- [ZipFile::getListFiles](#Documentation-ZipFile-getListFiles) - returns list of archive files.
|
||||||
- [ZipFile::hasEntry](#Documentation-ZipFile-hasEntry) - checks if there is an entry in the archive.
|
- [ZipFile::hasEntry](#Documentation-ZipFile-hasEntry) - checks if there is an entry in the archive.
|
||||||
- [ZipFile::isDirectory](#Documentation-ZipFile-isDirectory) - checks that the entry in the archive is a directory.
|
- [ZipFile::isDirectory](#Documentation-ZipFile-isDirectory) - checks that the entry in the archive is a directory.
|
||||||
@ -160,15 +162,11 @@ Other examples can be found in the `tests/` folder
|
|||||||
- [ZipFile::setEntryComment](#Documentation-ZipFile-setEntryComment) - set the comment of an entry defined by its name.
|
- [ZipFile::setEntryComment](#Documentation-ZipFile-setEntryComment) - set the comment of an entry defined by its name.
|
||||||
- [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword) - set the password for the open archive.
|
- [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword) - set the password for the open archive.
|
||||||
- [ZipFile::setReadPasswordEntry](#Documentation-ZipFile-setReadPasswordEntry) - sets a password for reading of an entry defined by its name.
|
- [ZipFile::setReadPasswordEntry](#Documentation-ZipFile-setReadPasswordEntry) - sets a password for reading of an entry defined by its name.
|
||||||
- ~~ZipFile::withNewPassword~~ - is an deprecated method, use the [ZipFile::setPassword](#Documentation-ZipFile-setPassword) method.
|
|
||||||
- [ZipFile::setPassword](#Documentation-ZipFile-setPassword) - sets a new password for all files in the archive.
|
- [ZipFile::setPassword](#Documentation-ZipFile-setPassword) - sets a new password for all files in the archive.
|
||||||
- [ZipFile::setPasswordEntry](#Documentation-ZipFile-setPasswordEntry) - sets a new password of an entry defined by its name.
|
- [ZipFile::setPasswordEntry](#Documentation-ZipFile-setPasswordEntry) - sets a new password of an entry defined by its name.
|
||||||
- [ZipFile::setZipAlign](#Documentation-ZipFile-setZipAlign) - sets the alignment of the archive to optimize APK files (Android packages).
|
|
||||||
- [ZipFile::unchangeAll](#Documentation-ZipFile-unchangeAll) - undo all changes done in the archive.
|
- [ZipFile::unchangeAll](#Documentation-ZipFile-unchangeAll) - undo all changes done in the archive.
|
||||||
- [ZipFile::unchangeArchiveComment](#Documentation-ZipFile-unchangeArchiveComment) - undo changes to the archive comment.
|
- [ZipFile::unchangeArchiveComment](#Documentation-ZipFile-unchangeArchiveComment) - undo changes to the archive comment.
|
||||||
- [ZipFile::unchangeEntry](#Documentation-ZipFile-unchangeEntry) - undo changes of an entry defined by its name.
|
- [ZipFile::unchangeEntry](#Documentation-ZipFile-unchangeEntry) - undo changes of an entry defined by its name.
|
||||||
- ~~ZipFile::withoutPassword~~ - is an deprecated method, use the [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption) method.
|
|
||||||
- ~~ZipFile::withReadPassword~~ - is an deprecated method, use the [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword) method.
|
|
||||||
|
|
||||||
#### <a name="Documentation-Open-Zip-Archive"></a> Creation/Opening of ZIP-archive
|
#### <a name="Documentation-Open-Zip-Archive"></a> Creation/Opening of ZIP-archive
|
||||||
<a name="Documentation-ZipFile-__construct"></a>**ZipFile::__construct** - initializes the ZIP archive.
|
<a name="Documentation-ZipFile-__construct"></a>**ZipFile::__construct** - initializes the ZIP archive.
|
||||||
@ -293,15 +291,6 @@ $commentArchive = $zipFile->getArchiveComment();
|
|||||||
$zipFile = new \PhpZip\ZipFile();
|
$zipFile = new \PhpZip\ZipFile();
|
||||||
$commentEntry = $zipFile->getEntryComment($entryName);
|
$commentEntry = $zipFile->getEntryComment($entryName);
|
||||||
```
|
```
|
||||||
<a name="Documentation-ZipFile-getEntryInfo"></a> **ZipFile::getEntryInfo** - returns detailed information about the entry in the archive
|
|
||||||
```php
|
|
||||||
$zipFile = new \PhpZip\ZipFile();
|
|
||||||
$zipInfo = $zipFile->getEntryInfo('file.txt');
|
|
||||||
```
|
|
||||||
<a name="Documentation-ZipFile-getAllInfo"></a> **ZipFile::getAllInfo** - returns detailed information about all entries in the archive.
|
|
||||||
```php
|
|
||||||
$zipAllInfo = $zipFile->getAllInfo();
|
|
||||||
```
|
|
||||||
#### <a name="Documentation-Add-Zip-Entries"></a> Adding entries to the archive
|
#### <a name="Documentation-Add-Zip-Entries"></a> Adding entries to the archive
|
||||||
|
|
||||||
All methods of adding entries to a ZIP archive allow you to specify a method for compressing content.
|
All methods of adding entries to a ZIP archive allow you to specify a method for compressing content.
|
||||||
@ -346,7 +335,7 @@ $zipFile->addSplFile($splFile, $entryName, $options = [
|
|||||||
]);
|
]);
|
||||||
```
|
```
|
||||||
<a name="Documentation-ZipFile-addFromFinder"></a>
|
<a name="Documentation-ZipFile-addFromFinder"></a>
|
||||||
**ZipFile::addFromFinder"** - adds files from the `Symfony\Component\Finder\Finder` to a ZIP archive.
|
**ZipFile::addFromFinder** - adds files from the `Symfony\Component\Finder\Finder` to a ZIP archive.
|
||||||
https://symfony.com/doc/current/components/finder.html
|
https://symfony.com/doc/current/components/finder.html
|
||||||
```php
|
```php
|
||||||
$finder = new \Symfony\Component\Finder\Finder();
|
$finder = new \Symfony\Component\Finder\Finder();
|
||||||
@ -376,7 +365,7 @@ $zipFile->addFromString($entryName, $contents, \PhpZip\Constants\ZipCompressionM
|
|||||||
$zipFile->addFromString($entryName, $contents, \PhpZip\Constants\ZipCompressionMethod::DEFLATED); // Deflate compression
|
$zipFile->addFromString($entryName, $contents, \PhpZip\Constants\ZipCompressionMethod::DEFLATED); // Deflate compression
|
||||||
$zipFile->addFromString($entryName, $contents, \PhpZip\Constants\ZipCompressionMethod::BZIP2); // BZIP2 compression
|
$zipFile->addFromString($entryName, $contents, \PhpZip\Constants\ZipCompressionMethod::BZIP2); // BZIP2 compression
|
||||||
```
|
```
|
||||||
<a name="Documentation-ZipFile-addFromStream"></a> **ZipFile::addFromStream** - adds a entry from the stream to the ZIP archive.
|
<a name="Documentation-ZipFile-addFromStream"></a> **ZipFile::addFromStream** - adds an entry from the stream to the ZIP archive.
|
||||||
```php
|
```php
|
||||||
$zipFile = new \PhpZip\ZipFile();
|
$zipFile = new \PhpZip\ZipFile();
|
||||||
// $stream = fopen(..., 'rb');
|
// $stream = fopen(..., 'rb');
|
||||||
@ -710,17 +699,6 @@ $zipFile->disableEncryption();
|
|||||||
```php
|
```php
|
||||||
$zipFile->disableEncryptionEntry($entryName);
|
$zipFile->disableEncryptionEntry($entryName);
|
||||||
```
|
```
|
||||||
#### <a name="Documentation-ZipAlign-Usage"></a> zipalign
|
|
||||||
<a name="Documentation-ZipFile-setZipAlign"></a> **ZipFile::setZipAlign** - sets the alignment of the archive to optimize APK files (Android packages).
|
|
||||||
|
|
||||||
This method adds padding to unencrypted and not compressed entries, to optimize memory consumption in the Android system. It is recommended to use for `APK` files. The file may grow slightly.
|
|
||||||
|
|
||||||
This method is an alternative to executing the `zipalign -f -v 4 filename.zip`.
|
|
||||||
|
|
||||||
More details can be found on the [link](https://developer.android.com/studio/command-line/zipalign.html).
|
|
||||||
```php
|
|
||||||
$zipFile->setZipAlign(4);
|
|
||||||
```
|
|
||||||
#### <a name="Documentation-Unchanged"></a> Undo changes
|
#### <a name="Documentation-Unchanged"></a> Undo changes
|
||||||
<a name="Documentation-ZipFile-unchangeAll"></a> **ZipFile::unchangeAll** - undo all changes done in the archive.
|
<a name="Documentation-ZipFile-unchangeAll"></a> **ZipFile::unchangeAll** - undo all changes done in the archive.
|
||||||
```php
|
```php
|
||||||
@ -792,6 +770,20 @@ vendor/bin/phpunit
|
|||||||
Changes are documented in the [releases page](https://github.com/Ne-Lexa/php-zip/releases).
|
Changes are documented in the [releases page](https://github.com/Ne-Lexa/php-zip/releases).
|
||||||
|
|
||||||
### <a name="Upgrade"></a> Upgrade
|
### <a name="Upgrade"></a> Upgrade
|
||||||
|
#### <a name="Upgrade-v3-to-v4"></a> Upgrade version 3 to version 4
|
||||||
|
Update the major version in the file `composer.json` to `^4.0`.
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"nelexa/zip": "^4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Then install updates using `Composer`:
|
||||||
|
```bash
|
||||||
|
composer update nelexa/zip
|
||||||
|
```
|
||||||
|
|
||||||
#### <a name="Upgrade-v2-to-v3"></a> Upgrade version 2 to version 3.0
|
#### <a name="Upgrade-v2-to-v3"></a> Upgrade version 2 to version 3.0
|
||||||
Update the major version in the file `composer.json` to `^3.0`.
|
Update the major version in the file `composer.json` to `^3.0`.
|
||||||
```json
|
```json
|
||||||
@ -800,6 +792,9 @@ Update the major version in the file `composer.json` to `^3.0`.
|
|||||||
"nelexa/zip": "^3.0"
|
"nelexa/zip": "^3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Update your code to work with the new version:
|
||||||
|
**BC**
|
||||||
|
- removed `zipalign` functional. This functionality will be placed in a separate package `nelexa/apkfile`.
|
||||||
```
|
```
|
||||||
Then install updates using `Composer`:
|
Then install updates using `Composer`:
|
||||||
```bash
|
```bash
|
||||||
@ -828,5 +823,3 @@ Update your code to work with the new version:
|
|||||||
+ `getLevel`
|
+ `getLevel`
|
||||||
+ `setCompressionMethod`
|
+ `setCompressionMethod`
|
||||||
+ `setEntryPassword`
|
+ `setEntryPassword`
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// see https://stackoverflow.com/questions/33299149/phpstorm-8-and-phpunit-problems-with-runinseparateprocess/37174348#37174348
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
|
if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
|
||||||
define('PHPUNIT_COMPOSER_INSTALL', __DIR__ . '/vendor/autoload.php');
|
define('PHPUNIT_COMPOSER_INSTALL', __DIR__ . '/vendor/autoload.php');
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "nelexa/zip",
|
"name": "nelexa/zip",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"description": "PhpZip is a php-library for extended work with ZIP-archives. Open, create, update, delete, extract and get info tool. Supports appending to existing ZIP files, WinZip AES encryption, Traditional PKWARE Encryption, ZipAlign tool, BZIP2 compression, external file attributes and ZIP64 extensions. Alternative ZipArchive. It does not require php-zip extension.",
|
"description": "PhpZip is a php-library for extended work with ZIP-archives. Open, create, update, delete, extract and get info tool. Supports appending to existing ZIP files, WinZip AES encryption, Traditional PKWARE Encryption, BZIP2 compression, external file attributes and ZIP64 extensions. Alternative ZipArchive. It does not require php-zip extension.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"zip",
|
"zip",
|
||||||
"unzip",
|
"unzip",
|
||||||
@ -21,20 +21,23 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2 || ^8.0",
|
"php": "^7.4 || ^8.0",
|
||||||
"ext-zlib": "*",
|
"ext-zlib": "*",
|
||||||
"psr/http-message": "^1.0",
|
"psr/http-message": "^1.0",
|
||||||
"paragonie/random_compat": "*",
|
|
||||||
"symfony/finder": "^3.0 || ^4.0 || ^5.0"
|
"symfony/finder": "^3.0 || ^4.0 || ^5.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"ext-iconv": "*",
|
||||||
"ext-bz2": "*",
|
"ext-bz2": "*",
|
||||||
"ext-openssl": "*",
|
"ext-openssl": "*",
|
||||||
"ext-fileinfo": "*",
|
"ext-fileinfo": "*",
|
||||||
"ext-xml": "*",
|
"ext-xml": "*",
|
||||||
|
"ext-dom": "*",
|
||||||
"guzzlehttp/psr7": "^1.6",
|
"guzzlehttp/psr7": "^1.6",
|
||||||
"phpunit/phpunit": "^8 || ^9",
|
"phpunit/phpunit": "^9",
|
||||||
"symfony/var-dumper": "^5.0"
|
"symfony/var-dumper": "^5.0",
|
||||||
|
"friendsofphp/php-cs-fixer": "^2.18",
|
||||||
|
"vimeo/psalm": "^4.6"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
@ -47,8 +50,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
|
"ext-iconv": "Needed to support convert zip entry name to requested character encoding",
|
||||||
"ext-openssl": "Needed to support encrypt zip entries or use ext-mcrypt",
|
"ext-openssl": "Needed to support encrypt zip entries or use ext-mcrypt",
|
||||||
"ext-mcrypt": "Needed to support encrypt zip entries or use ext-openssl",
|
|
||||||
"ext-bz2": "Needed to support BZIP2 compression",
|
"ext-bz2": "Needed to support BZIP2 compression",
|
||||||
"ext-fileinfo": "Needed to get mime-type file"
|
"ext-fileinfo": "Needed to get mime-type file"
|
||||||
},
|
},
|
||||||
|
62
phpunit.xml
62
phpunit.xml
@ -1,36 +1,28 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" backupGlobals="false" colors="true" bootstrap="bootstrap.php">
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<coverage>
|
||||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
|
<include>
|
||||||
backupGlobals="false"
|
<directory>src</directory>
|
||||||
colors="true"
|
</include>
|
||||||
bootstrap="bootstrap.php">
|
</coverage>
|
||||||
<php>
|
<php>
|
||||||
<ini name="error_reporting" value="-1"/>
|
<ini name="error_reporting" value="-1"/>
|
||||||
</php>
|
</php>
|
||||||
|
<testsuites>
|
||||||
<testsuites>
|
<testsuite name="all_tests">
|
||||||
<testsuite name="all_tests">
|
<directory>tests</directory>
|
||||||
<directory>tests</directory>
|
</testsuite>
|
||||||
</testsuite>
|
<testsuite name="only_fast_tests">
|
||||||
<testsuite name="only_fast_tests">
|
<directory>tests</directory>
|
||||||
<directory>tests</directory>
|
<exclude>tests/SlowTests</exclude>
|
||||||
<exclude>tests/SlowTests</exclude>
|
</testsuite>
|
||||||
</testsuite>
|
<testsuite name="only_slow_tests">
|
||||||
<testsuite name="only_slow_tests">
|
<directory>tests/SlowTests</directory>
|
||||||
<directory>tests/SlowTests</directory>
|
</testsuite>
|
||||||
</testsuite>
|
</testsuites>
|
||||||
</testsuites>
|
<groups>
|
||||||
|
<exclude>
|
||||||
<groups>
|
<group>large</group>
|
||||||
<exclude>
|
</exclude>
|
||||||
<group>large</group>
|
</groups>
|
||||||
</exclude>
|
|
||||||
</groups>
|
|
||||||
|
|
||||||
<filter>
|
|
||||||
<whitelist>
|
|
||||||
<directory>src</directory>
|
|
||||||
</whitelist>
|
|
||||||
</filter>
|
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
17
psalm.xml
Normal file
17
psalm.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
errorLevel="3"
|
||||||
|
resolveFromConfigFile="true"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="https://getpsalm.org/schema/config"
|
||||||
|
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="src" />
|
||||||
|
<ignoreFiles>
|
||||||
|
<directory name="vendor" />
|
||||||
|
<directory name="benchmarks" />
|
||||||
|
<directory name="tests"/>
|
||||||
|
</ignoreFiles>
|
||||||
|
</projectFiles>
|
||||||
|
</psalm>
|
@ -1,33 +1,39 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface DosAttrs.
|
|
||||||
*/
|
|
||||||
interface DosAttrs
|
interface DosAttrs
|
||||||
{
|
{
|
||||||
/** @var int DOS File Attribute Read Only */
|
/** @var int DOS File Attribute Read Only */
|
||||||
const DOS_READ_ONLY = 0x01;
|
public const DOS_READ_ONLY = 0x01;
|
||||||
|
|
||||||
/** @var int DOS File Attribute Hidden */
|
/** @var int DOS File Attribute Hidden */
|
||||||
const DOS_HIDDEN = 0x02;
|
public const DOS_HIDDEN = 0x02;
|
||||||
|
|
||||||
/** @var int DOS File Attribute System */
|
/** @var int DOS File Attribute System */
|
||||||
const DOS_SYSTEM = 0x04;
|
public const DOS_SYSTEM = 0x04;
|
||||||
|
|
||||||
/** @var int DOS File Attribute Label */
|
/** @var int DOS File Attribute Label */
|
||||||
const DOS_LABEL = 0x08;
|
public const DOS_LABEL = 0x08;
|
||||||
|
|
||||||
/** @var int DOS File Attribute Directory */
|
/** @var int DOS File Attribute Directory */
|
||||||
const DOS_DIRECTORY = 0x10;
|
public const DOS_DIRECTORY = 0x10;
|
||||||
|
|
||||||
/** @var int DOS File Attribute Archive */
|
/** @var int DOS File Attribute Archive */
|
||||||
const DOS_ARCHIVE = 0x20;
|
public const DOS_ARCHIVE = 0x20;
|
||||||
|
|
||||||
/** @var int DOS File Attribute Link */
|
/** @var int DOS File Attribute Link */
|
||||||
const DOS_LINK = 0x40;
|
public const DOS_LINK = 0x40;
|
||||||
|
|
||||||
/** @var int DOS File Attribute Execute */
|
/** @var int DOS File Attribute Execute */
|
||||||
const DOS_EXE = 0x80;
|
public const DOS_EXE = 0x80;
|
||||||
}
|
}
|
||||||
|
@ -1,48 +1,52 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class DosCodePage.
|
|
||||||
*/
|
|
||||||
final class DosCodePage
|
final class DosCodePage
|
||||||
{
|
{
|
||||||
const CP_LATIN_US = 'cp437';
|
public const CP_LATIN_US = 'cp437';
|
||||||
|
|
||||||
const CP_GREEK = 'cp737';
|
public const CP_GREEK = 'cp737';
|
||||||
|
|
||||||
const CP_BALT_RIM = 'cp775';
|
public const CP_BALT_RIM = 'cp775';
|
||||||
|
|
||||||
const CP_LATIN1 = 'cp850';
|
public const CP_LATIN1 = 'cp850';
|
||||||
|
|
||||||
const CP_LATIN2 = 'cp852';
|
public const CP_LATIN2 = 'cp852';
|
||||||
|
|
||||||
const CP_CYRILLIC = 'cp855';
|
public const CP_CYRILLIC = 'cp855';
|
||||||
|
|
||||||
const CP_TURKISH = 'cp857';
|
public const CP_TURKISH = 'cp857';
|
||||||
|
|
||||||
const CP_PORTUGUESE = 'cp860';
|
public const CP_PORTUGUESE = 'cp860';
|
||||||
|
|
||||||
const CP_ICELANDIC = 'cp861';
|
public const CP_ICELANDIC = 'cp861';
|
||||||
|
|
||||||
const CP_HEBREW = 'cp862';
|
public const CP_HEBREW = 'cp862';
|
||||||
|
|
||||||
const CP_CANADA = 'cp863';
|
public const CP_CANADA = 'cp863';
|
||||||
|
|
||||||
const CP_ARABIC = 'cp864';
|
public const CP_ARABIC = 'cp864';
|
||||||
|
|
||||||
const CP_NORDIC = 'cp865';
|
public const CP_NORDIC = 'cp865';
|
||||||
|
|
||||||
const CP_CYRILLIC_RUSSIAN = 'cp866';
|
public const CP_CYRILLIC_RUSSIAN = 'cp866';
|
||||||
|
|
||||||
const CP_GREEK2 = 'cp869';
|
public const CP_GREEK2 = 'cp869';
|
||||||
|
|
||||||
const CP_THAI = 'cp874';
|
public const CP_THAI = 'cp874';
|
||||||
|
|
||||||
/** @var string[] */
|
/** @var string[] */
|
||||||
private static $CP_CHARSETS = [
|
private const CP_CHARSETS = [
|
||||||
self::CP_LATIN_US,
|
self::CP_LATIN_US,
|
||||||
self::CP_GREEK,
|
self::CP_GREEK,
|
||||||
self::CP_BALT_RIM,
|
self::CP_BALT_RIM,
|
||||||
@ -62,12 +66,9 @@ final class DosCodePage
|
|||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $str
|
* @noinspection PhpComposerExtensionStubsInspection
|
||||||
* @param string $sourceEncoding
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function toUTF8($str, $sourceEncoding)
|
public static function toUTF8(string $str, string $sourceEncoding): string
|
||||||
{
|
{
|
||||||
$s = iconv($sourceEncoding, 'UTF-8', $str);
|
$s = iconv($sourceEncoding, 'UTF-8', $str);
|
||||||
|
|
||||||
@ -79,12 +80,9 @@ final class DosCodePage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $str
|
* @noinspection PhpComposerExtensionStubsInspection
|
||||||
* @param string $destEncoding
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function fromUTF8($str, $destEncoding)
|
public static function fromUTF8(string $str, string $destEncoding): string
|
||||||
{
|
{
|
||||||
$s = iconv('UTF-8', $destEncoding, $str);
|
$s = iconv('UTF-8', $destEncoding, $str);
|
||||||
|
|
||||||
@ -98,8 +96,8 @@ final class DosCodePage
|
|||||||
/**
|
/**
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public static function getCodePages()
|
public static function getCodePages(): array
|
||||||
{
|
{
|
||||||
return self::$CP_CHARSETS;
|
return self::CP_CHARSETS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
/**
|
|
||||||
* General purpose bit flag constants.
|
|
||||||
*/
|
|
||||||
interface GeneralPurposeBitFlag
|
interface GeneralPurposeBitFlag
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* General Purpose Bit Flag mask for encrypted data.
|
* General Purpose Bit Flag mask for encrypted data.
|
||||||
* Bit 0: If set, indicates that the file is encrypted.
|
* Bit 0: If set, indicates that the file is encrypted.
|
||||||
*/
|
*/
|
||||||
const ENCRYPTION = 1; // 1 << 0
|
public const ENCRYPTION = 1 << 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compression Flag Bit 1 for method Deflating.
|
* Compression Flag Bit 1 for method Deflating.
|
||||||
@ -24,7 +30,7 @@ interface GeneralPurposeBitFlag
|
|||||||
*
|
*
|
||||||
* @see GeneralPurposeBitFlag::COMPRESSION_FLAG2
|
* @see GeneralPurposeBitFlag::COMPRESSION_FLAG2
|
||||||
*/
|
*/
|
||||||
const COMPRESSION_FLAG1 = 2; // 1 << 1
|
public const COMPRESSION_FLAG1 = 1 << 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compression Flag Bit 2 for method Deflating.
|
* Compression Flag Bit 2 for method Deflating.
|
||||||
@ -37,7 +43,7 @@ interface GeneralPurposeBitFlag
|
|||||||
*
|
*
|
||||||
* @see GeneralPurposeBitFlag::COMPRESSION_FLAG1
|
* @see GeneralPurposeBitFlag::COMPRESSION_FLAG1
|
||||||
*/
|
*/
|
||||||
const COMPRESSION_FLAG2 = 4; // 1 << 2
|
public const COMPRESSION_FLAG2 = 1 << 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General Purpose Bit Flag mask for data descriptor.
|
* General Purpose Bit Flag mask for data descriptor.
|
||||||
@ -47,7 +53,7 @@ interface GeneralPurposeBitFlag
|
|||||||
* local header. The correct values are put in the data
|
* local header. The correct values are put in the data
|
||||||
* descriptor immediately following the compressed data.
|
* descriptor immediately following the compressed data.
|
||||||
*/
|
*/
|
||||||
const DATA_DESCRIPTOR = 8; // 1 << 3
|
public const DATA_DESCRIPTOR = 1 << 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General Purpose Bit Flag mask for strong encryption.
|
* General Purpose Bit Flag mask for strong encryption.
|
||||||
@ -58,7 +64,7 @@ interface GeneralPurposeBitFlag
|
|||||||
* If AES encryption is used, the version needed to extract value
|
* If AES encryption is used, the version needed to extract value
|
||||||
* MUST be at least 51.
|
* MUST be at least 51.
|
||||||
*/
|
*/
|
||||||
const STRONG_ENCRYPTION = 64; // 1 << 6
|
public const STRONG_ENCRYPTION = 1 << 6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General Purpose Bit Flag mask for UTF-8.
|
* General Purpose Bit Flag mask for UTF-8.
|
||||||
@ -67,5 +73,5 @@ interface GeneralPurposeBitFlag
|
|||||||
* If this bit is set, the filename and comment fields
|
* If this bit is set, the filename and comment fields
|
||||||
* for this file MUST be encoded using UTF-8. (see APPENDIX D)
|
* for this file MUST be encoded using UTF-8. (see APPENDIX D)
|
||||||
*/
|
*/
|
||||||
const UTF8 = 2048; // 1 << 11
|
public const UTF8 = 1 << 11;
|
||||||
}
|
}
|
||||||
|
@ -1,84 +1,90 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unix stat constants.
|
* Unix stat constants.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
interface UnixStat
|
interface UnixStat
|
||||||
{
|
{
|
||||||
/** @var int unix file type mask */
|
/** @var int unix file type mask */
|
||||||
const UNX_IFMT = 0170000;
|
public const UNX_IFMT = 0170000;
|
||||||
|
|
||||||
/** @var int unix regular file */
|
/** @var int unix regular file */
|
||||||
const UNX_IFREG = 0100000;
|
public const UNX_IFREG = 0100000;
|
||||||
|
|
||||||
/** @var int unix socket (BSD, not SysV or Amiga) */
|
/** @var int unix socket (BSD, not SysV or Amiga) */
|
||||||
const UNX_IFSOCK = 0140000;
|
public const UNX_IFSOCK = 0140000;
|
||||||
|
|
||||||
/** @var int unix symbolic link (not SysV, Amiga) */
|
/** @var int unix symbolic link (not SysV, Amiga) */
|
||||||
const UNX_IFLNK = 0120000;
|
public const UNX_IFLNK = 0120000;
|
||||||
|
|
||||||
/** @var int unix block special (not Amiga) */
|
/** @var int unix block special (not Amiga) */
|
||||||
const UNX_IFBLK = 0060000;
|
public const UNX_IFBLK = 0060000;
|
||||||
|
|
||||||
/** @var int unix directory */
|
/** @var int unix directory */
|
||||||
const UNX_IFDIR = 0040000;
|
public const UNX_IFDIR = 0040000;
|
||||||
|
|
||||||
/** @var int unix character special (not Amiga) */
|
/** @var int unix character special (not Amiga) */
|
||||||
const UNX_IFCHR = 0020000;
|
public const UNX_IFCHR = 0020000;
|
||||||
|
|
||||||
/** @var int unix fifo (BCC, not MSC or Amiga) */
|
/** @var int unix fifo (BCC, not MSC or Amiga) */
|
||||||
const UNX_IFIFO = 0010000;
|
public const UNX_IFIFO = 0010000;
|
||||||
|
|
||||||
/** @var int unix set user id on execution */
|
/** @var int unix set user id on execution */
|
||||||
const UNX_ISUID = 04000;
|
public const UNX_ISUID = 04000;
|
||||||
|
|
||||||
/** @var int unix set group id on execution */
|
/** @var int unix set group id on execution */
|
||||||
const UNX_ISGID = 02000;
|
public const UNX_ISGID = 02000;
|
||||||
|
|
||||||
/** @var int unix directory permissions control */
|
/** @var int unix directory permissions control */
|
||||||
const UNX_ISVTX = 01000;
|
public const UNX_ISVTX = 01000;
|
||||||
|
|
||||||
/** @var int unix record locking enforcement flag */
|
/** @var int unix record locking enforcement flag */
|
||||||
const UNX_ENFMT = 02000;
|
public const UNX_ENFMT = 02000;
|
||||||
|
|
||||||
/** @var int unix read, write, execute: owner */
|
/** @var int unix read, write, execute: owner */
|
||||||
const UNX_IRWXU = 00700;
|
public const UNX_IRWXU = 00700;
|
||||||
|
|
||||||
/** @var int unix read permission: owner */
|
/** @var int unix read permission: owner */
|
||||||
const UNX_IRUSR = 00400;
|
public const UNX_IRUSR = 00400;
|
||||||
|
|
||||||
/** @var int unix write permission: owner */
|
/** @var int unix write permission: owner */
|
||||||
const UNX_IWUSR = 00200;
|
public const UNX_IWUSR = 00200;
|
||||||
|
|
||||||
/** @var int unix execute permission: owner */
|
/** @var int unix execute permission: owner */
|
||||||
const UNX_IXUSR = 00100;
|
public const UNX_IXUSR = 00100;
|
||||||
|
|
||||||
/** @var int unix read, write, execute: group */
|
/** @var int unix read, write, execute: group */
|
||||||
const UNX_IRWXG = 00070;
|
public const UNX_IRWXG = 00070;
|
||||||
|
|
||||||
/** @var int unix read permission: group */
|
/** @var int unix read permission: group */
|
||||||
const UNX_IRGRP = 00040;
|
public const UNX_IRGRP = 00040;
|
||||||
|
|
||||||
/** @var int unix write permission: group */
|
/** @var int unix write permission: group */
|
||||||
const UNX_IWGRP = 00020;
|
public const UNX_IWGRP = 00020;
|
||||||
|
|
||||||
/** @var int unix execute permission: group */
|
/** @var int unix execute permission: group */
|
||||||
const UNX_IXGRP = 00010;
|
public const UNX_IXGRP = 00010;
|
||||||
|
|
||||||
/** @var int unix read, write, execute: other */
|
/** @var int unix read, write, execute: other */
|
||||||
const UNX_IRWXO = 00007;
|
public const UNX_IRWXO = 00007;
|
||||||
|
|
||||||
/** @var int unix read permission: other */
|
/** @var int unix read permission: other */
|
||||||
const UNX_IROTH = 00004;
|
public const UNX_IROTH = 00004;
|
||||||
|
|
||||||
/** @var int unix write permission: other */
|
/** @var int unix write permission: other */
|
||||||
const UNX_IWOTH = 00002;
|
public const UNX_IWOTH = 00002;
|
||||||
|
|
||||||
/** @var int unix execute permission: other */
|
/** @var int unix execute permission: other */
|
||||||
const UNX_IXOTH = 00001;
|
public const UNX_IXOTH = 00001;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,28 +36,28 @@ namespace PhpZip\Constants;
|
|||||||
interface ZipCompressionLevel
|
interface ZipCompressionLevel
|
||||||
{
|
{
|
||||||
/** @var int Compression level for super fast compression. */
|
/** @var int Compression level for super fast compression. */
|
||||||
const SUPER_FAST = 1;
|
public const SUPER_FAST = 1;
|
||||||
|
|
||||||
/** @var int compression level for fast compression */
|
/** @var int compression level for fast compression */
|
||||||
const FAST = 2;
|
public const FAST = 2;
|
||||||
|
|
||||||
/** @var int compression level for normal compression */
|
/** @var int compression level for normal compression */
|
||||||
const NORMAL = 5;
|
public const NORMAL = 5;
|
||||||
|
|
||||||
/** @var int compression level for maximum compression */
|
/** @var int compression level for maximum compression */
|
||||||
const MAXIMUM = 9;
|
public const MAXIMUM = 9;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int int Minimum compression level
|
* @var int int Minimum compression level
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
const LEVEL_MIN = self::SUPER_FAST;
|
public const LEVEL_MIN = self::SUPER_FAST;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int int Maximum compression level
|
* @var int int Maximum compression level
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
const LEVEL_MAX = self::MAXIMUM;
|
public const LEVEL_MAX = self::MAXIMUM;
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,34 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipUnsupportMethodException;
|
use PhpZip\Exception\ZipUnsupportMethodException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipCompressionMethod.
|
|
||||||
*/
|
|
||||||
final class ZipCompressionMethod
|
final class ZipCompressionMethod
|
||||||
{
|
{
|
||||||
/** @var int Compression method Store */
|
/** @var int Compression method Store */
|
||||||
const STORED = 0;
|
public const STORED = 0;
|
||||||
|
|
||||||
/** @var int Compression method Deflate */
|
/** @var int Compression method Deflate */
|
||||||
const DEFLATED = 8;
|
public const DEFLATED = 8;
|
||||||
|
|
||||||
/** @var int Compression method Bzip2 */
|
/** @var int Compression method Bzip2 */
|
||||||
const BZIP2 = 12;
|
public const BZIP2 = 12;
|
||||||
|
|
||||||
/** @var int Compression method AES-Encryption */
|
/** @var int Compression method AES-Encryption */
|
||||||
const WINZIP_AES = 99;
|
public const WINZIP_AES = 99;
|
||||||
|
|
||||||
/** @var array Compression Methods */
|
/** @var array Compression Methods */
|
||||||
private static $ZIP_COMPRESSION_METHODS = [
|
private const ZIP_COMPRESSION_METHODS = [
|
||||||
self::STORED => 'Stored',
|
self::STORED => 'Stored',
|
||||||
1 => 'Shrunk',
|
1 => 'Shrunk',
|
||||||
2 => 'Reduced compression factor 1',
|
2 => 'Reduced compression factor 1',
|
||||||
@ -49,22 +55,15 @@ final class ZipCompressionMethod
|
|||||||
self::WINZIP_AES => 'AES Encryption',
|
self::WINZIP_AES => 'AES Encryption',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
public static function getCompressionMethodName(int $value): string
|
||||||
* @param int $value
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function getCompressionMethodName($value)
|
|
||||||
{
|
{
|
||||||
return isset(self::$ZIP_COMPRESSION_METHODS[$value]) ?
|
return self::ZIP_COMPRESSION_METHODS[$value] ?? 'Unknown Method';
|
||||||
self::$ZIP_COMPRESSION_METHODS[$value] :
|
|
||||||
'Unknown Method';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int[]
|
* @return int[]
|
||||||
*/
|
*/
|
||||||
public static function getSupportMethods()
|
public static function getSupportMethods(): array
|
||||||
{
|
{
|
||||||
static $methods;
|
static $methods;
|
||||||
|
|
||||||
@ -83,14 +82,10 @@ final class ZipCompressionMethod
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $compressionMethod
|
|
||||||
*
|
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*/
|
*/
|
||||||
public static function checkSupport($compressionMethod)
|
public static function checkSupport(int $compressionMethod): void
|
||||||
{
|
{
|
||||||
$compressionMethod = (int) $compressionMethod;
|
|
||||||
|
|
||||||
if (!\in_array($compressionMethod, self::getSupportMethods(), true)) {
|
if (!\in_array($compressionMethod, self::getSupportMethods(), true)) {
|
||||||
throw new ZipUnsupportMethodException(sprintf(
|
throw new ZipUnsupportMethodException(sprintf(
|
||||||
'Compression method %d (%s) is not supported.',
|
'Compression method %d (%s) is not supported.',
|
||||||
|
@ -1,38 +1,44 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zip Constants.
|
* Zip Constants.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
interface ZipConstants
|
interface ZipConstants
|
||||||
{
|
{
|
||||||
/** @var int End Of Central Directory Record signature. */
|
/** @var int End Of Central Directory Record signature. */
|
||||||
const END_CD = 0x06054B50; // "PK\005\006"
|
public const END_CD = 0x06054B50; // "PK\005\006"
|
||||||
|
|
||||||
/** @var int Zip64 End Of Central Directory Record. */
|
/** @var int Zip64 End Of Central Directory Record. */
|
||||||
const ZIP64_END_CD = 0x06064B50; // "PK\006\006"
|
public const ZIP64_END_CD = 0x06064B50; // "PK\006\006"
|
||||||
|
|
||||||
/** @var int Zip64 End Of Central Directory Locator. */
|
/** @var int Zip64 End Of Central Directory Locator. */
|
||||||
const ZIP64_END_CD_LOC = 0x07064B50; // "PK\006\007"
|
public const ZIP64_END_CD_LOC = 0x07064B50; // "PK\006\007"
|
||||||
|
|
||||||
/** @var int Central File Header signature. */
|
/** @var int Central File Header signature. */
|
||||||
const CENTRAL_FILE_HEADER = 0x02014B50; // "PK\001\002"
|
public const CENTRAL_FILE_HEADER = 0x02014B50; // "PK\001\002"
|
||||||
|
|
||||||
/** @var int Local File Header signature. */
|
/** @var int Local File Header signature. */
|
||||||
const LOCAL_FILE_HEADER = 0x04034B50; // "PK\003\004"
|
public const LOCAL_FILE_HEADER = 0x04034B50; // "PK\003\004"
|
||||||
|
|
||||||
/** @var int Data Descriptor signature. */
|
/** @var int Data Descriptor signature. */
|
||||||
const DATA_DESCRIPTOR = 0x08074B50; // "PK\007\008"
|
public const DATA_DESCRIPTOR = 0x08074B50; // "PK\007\008"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int value stored in four-byte size and similar fields
|
* @var int value stored in four-byte size and similar fields
|
||||||
* if ZIP64 extensions are used
|
* if ZIP64 extensions are used
|
||||||
*/
|
*/
|
||||||
const ZIP64_MAGIC = 0xFFFFFFFF;
|
public const ZIP64_MAGIC = 0xFFFFFFFF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local File Header signature 4
|
* Local File Header signature 4
|
||||||
@ -47,7 +53,7 @@ interface ZipConstants
|
|||||||
*
|
*
|
||||||
* @var int Local File Header filename position
|
* @var int Local File Header filename position
|
||||||
*/
|
*/
|
||||||
const LFH_FILENAME_LENGTH_POS = 26;
|
public const LFH_FILENAME_LENGTH_POS = 26;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum length of the Local File Header record.
|
* The minimum length of the Local File Header record.
|
||||||
@ -64,13 +70,13 @@ interface ZipConstants
|
|||||||
* file name length 2
|
* file name length 2
|
||||||
* extra field length 2
|
* extra field length 2
|
||||||
*/
|
*/
|
||||||
const LFH_FILENAME_POS = 30;
|
public const LFH_FILENAME_POS = 30;
|
||||||
|
|
||||||
/** @var int the length of the Zip64 End Of Central Directory Locator */
|
/** @var int the length of the Zip64 End Of Central Directory Locator */
|
||||||
const ZIP64_END_CD_LOC_LEN = 20;
|
public const ZIP64_END_CD_LOC_LEN = 20;
|
||||||
|
|
||||||
/** @var int the minimum length of the End Of Central Directory Record */
|
/** @var int the minimum length of the End Of Central Directory Record */
|
||||||
const END_CD_MIN_LEN = 22;
|
public const END_CD_MIN_LEN = 22;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum length of the Zip64 End Of Central Directory Record.
|
* The minimum length of the Zip64 End Of Central Directory Record.
|
||||||
@ -95,5 +101,5 @@ interface ZipConstants
|
|||||||
*
|
*
|
||||||
* @var int ZIP64 End Of Central Directory length
|
* @var int ZIP64 End Of Central Directory length
|
||||||
*/
|
*/
|
||||||
const ZIP64_END_OF_CD_LEN = 56;
|
public const ZIP64_END_OF_CD_LEN = 56;
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
use PhpZip\Exception\InvalidArgumentException;
|
use PhpZip\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipEncryptionMethod.
|
|
||||||
*/
|
|
||||||
final class ZipEncryptionMethod
|
final class ZipEncryptionMethod
|
||||||
{
|
{
|
||||||
const NONE = -1;
|
public const NONE = -1;
|
||||||
|
|
||||||
/** @var int Traditional PKWARE encryption. */
|
/** @var int Traditional PKWARE encryption. */
|
||||||
const PKWARE = 0;
|
public const PKWARE = 0;
|
||||||
|
|
||||||
/** @var int WinZip AES-256 */
|
/** @var int WinZip AES-256 */
|
||||||
const WINZIP_AES_256 = 1;
|
public const WINZIP_AES_256 = 1;
|
||||||
|
|
||||||
/** @var int WinZip AES-128 */
|
/** @var int WinZip AES-128 */
|
||||||
const WINZIP_AES_128 = 2;
|
public const WINZIP_AES_128 = 2;
|
||||||
|
|
||||||
/** @var int WinZip AES-192 */
|
/** @var int WinZip AES-192 */
|
||||||
const WINZIP_AES_192 = 3;
|
public const WINZIP_AES_192 = 3;
|
||||||
|
|
||||||
/** @var array<int, string> */
|
/** @var array<int, string> */
|
||||||
private static $ENCRYPTION_METHODS = [
|
private const ENCRYPTION_METHODS = [
|
||||||
self::NONE => 'no encryption',
|
self::NONE => 'no encryption',
|
||||||
self::PKWARE => 'Traditional PKWARE encryption',
|
self::PKWARE => 'Traditional PKWARE encryption',
|
||||||
self::WINZIP_AES_128 => 'WinZip AES-128',
|
self::WINZIP_AES_128 => 'WinZip AES-128',
|
||||||
@ -32,39 +38,20 @@ final class ZipEncryptionMethod
|
|||||||
self::WINZIP_AES_256 => 'WinZip AES-256',
|
self::WINZIP_AES_256 => 'WinZip AES-256',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
public static function getEncryptionMethodName(int $value): string
|
||||||
* @param int $value
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function getEncryptionMethodName($value)
|
|
||||||
{
|
{
|
||||||
$value = (int) $value;
|
return self::ENCRYPTION_METHODS[$value] ?? 'Unknown Encryption Method';
|
||||||
|
|
||||||
return isset(self::$ENCRYPTION_METHODS[$value]) ?
|
|
||||||
self::$ENCRYPTION_METHODS[$value] :
|
|
||||||
'Unknown Encryption Method';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function hasEncryptionMethod(int $encryptionMethod): bool
|
||||||
* @param int $encryptionMethod
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function hasEncryptionMethod($encryptionMethod)
|
|
||||||
{
|
{
|
||||||
return isset(self::$ENCRYPTION_METHODS[$encryptionMethod]);
|
return isset(self::ENCRYPTION_METHODS[$encryptionMethod]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function isWinZipAesMethod(int $encryptionMethod): bool
|
||||||
* @param int $encryptionMethod
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isWinZipAesMethod($encryptionMethod)
|
|
||||||
{
|
{
|
||||||
return \in_array(
|
return \in_array(
|
||||||
(int) $encryptionMethod,
|
$encryptionMethod,
|
||||||
[
|
[
|
||||||
self::WINZIP_AES_256,
|
self::WINZIP_AES_256,
|
||||||
self::WINZIP_AES_192,
|
self::WINZIP_AES_192,
|
||||||
@ -75,14 +62,10 @@ final class ZipEncryptionMethod
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $encryptionMethod
|
|
||||||
*
|
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public static function checkSupport($encryptionMethod)
|
public static function checkSupport(int $encryptionMethod): void
|
||||||
{
|
{
|
||||||
$encryptionMethod = (int) $encryptionMethod;
|
|
||||||
|
|
||||||
if (!self::hasEncryptionMethod($encryptionMethod)) {
|
if (!self::hasEncryptionMethod($encryptionMethod)) {
|
||||||
throw new InvalidArgumentException(sprintf(
|
throw new InvalidArgumentException(sprintf(
|
||||||
'Encryption method %d is not supported.',
|
'Encryption method %d is not supported.',
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
use PhpZip\IO\ZipReader;
|
use PhpZip\IO\ZipReader;
|
||||||
use PhpZip\ZipFile;
|
use PhpZip\ZipFile;
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface ZipOptions.
|
|
||||||
*/
|
|
||||||
interface ZipOptions
|
interface ZipOptions
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -15,7 +21,7 @@ interface ZipOptions
|
|||||||
*
|
*
|
||||||
* @see ZipFile::addFromFinder()
|
* @see ZipFile::addFromFinder()
|
||||||
*/
|
*/
|
||||||
const STORE_ONLY_FILES = 'only_files';
|
public const STORE_ONLY_FILES = 'only_files';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses the specified compression method.
|
* Uses the specified compression method.
|
||||||
@ -23,7 +29,7 @@ interface ZipOptions
|
|||||||
* @see ZipFile::addFromFinder()
|
* @see ZipFile::addFromFinder()
|
||||||
* @see ZipFile::addSplFile()
|
* @see ZipFile::addSplFile()
|
||||||
*/
|
*/
|
||||||
const COMPRESSION_METHOD = 'compression_method';
|
public const COMPRESSION_METHOD = 'compression_method';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the specified record modification time.
|
* Set the specified record modification time.
|
||||||
@ -33,7 +39,7 @@ interface ZipOptions
|
|||||||
* @see ZipFile::addFromFinder()
|
* @see ZipFile::addFromFinder()
|
||||||
* @see ZipFile::addSplFile()
|
* @see ZipFile::addSplFile()
|
||||||
*/
|
*/
|
||||||
const MODIFIED_TIME = 'mtime';
|
public const MODIFIED_TIME = 'mtime';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the encoding of the record name for cases when the UTF-8
|
* Specifies the encoding of the record name for cases when the UTF-8
|
||||||
@ -48,7 +54,7 @@ interface ZipOptions
|
|||||||
* @see ZipReader::getDefaultOptions()
|
* @see ZipReader::getDefaultOptions()
|
||||||
* @see DosCodePage::getCodePages()
|
* @see DosCodePage::getCodePages()
|
||||||
*/
|
*/
|
||||||
const CHARSET = 'charset';
|
public const CHARSET = 'charset';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows ({@see true}) or denies ({@see false}) unpacking unix symlinks.
|
* Allows ({@see true}) or denies ({@see false}) unpacking unix symlinks.
|
||||||
@ -58,5 +64,5 @@ interface ZipOptions
|
|||||||
*
|
*
|
||||||
* @see https://josipfranjkovic.blogspot.com/2014/12/reading-local-files-from-facebooks.html
|
* @see https://josipfranjkovic.blogspot.com/2014/12/reading-local-files-from-facebooks.html
|
||||||
*/
|
*/
|
||||||
const EXTRACT_SYMLINKS = 'extract_symlinks';
|
public const EXTRACT_SYMLINKS = 'extract_symlinks';
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipPlatform.
|
|
||||||
*/
|
|
||||||
final class ZipPlatform
|
final class ZipPlatform
|
||||||
{
|
{
|
||||||
/** @var int MS-DOS OS */
|
/** @var int MS-DOS OS */
|
||||||
const OS_DOS = 0;
|
public const OS_DOS = 0;
|
||||||
|
|
||||||
/** @var int Unix OS */
|
/** @var int Unix OS */
|
||||||
const OS_UNIX = 3;
|
public const OS_UNIX = 3;
|
||||||
|
|
||||||
/** MacOS platform */
|
/** @var int MacOS platform */
|
||||||
const OS_MAC_OSX = 19;
|
public const OS_MAC_OSX = 19;
|
||||||
|
|
||||||
/** @var array Zip Platforms */
|
/** @var array Zip Platforms */
|
||||||
private static $platforms = [
|
private const PLATFORMS = [
|
||||||
self::OS_DOS => 'MS-DOS',
|
self::OS_DOS => 'MS-DOS',
|
||||||
1 => 'Amiga',
|
1 => 'Amiga',
|
||||||
2 => 'OpenVMS',
|
2 => 'OpenVMS',
|
||||||
@ -41,13 +47,8 @@ final class ZipPlatform
|
|||||||
30 => 'AtheOS/Syllable',
|
30 => 'AtheOS/Syllable',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
public static function getPlatformName(int $platform): string
|
||||||
* @param int $platform
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function getPlatformName($platform)
|
|
||||||
{
|
{
|
||||||
return isset(self::$platforms[$platform]) ? self::$platforms[$platform] : 'Unknown';
|
return self::PLATFORMS[$platform] ?? 'Unknown';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,28 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Constants;
|
namespace PhpZip\Constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version needed to extract or software version.
|
* Version needed to extract or software version.
|
||||||
*
|
*
|
||||||
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT Section 4.4.3
|
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT Section 4.4.3
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
interface ZipVersion
|
interface ZipVersion
|
||||||
{
|
{
|
||||||
/** @var int 1.0 - Default value */
|
/** @var int 1.0 - Default value */
|
||||||
const v10_DEFAULT_MIN = 10;
|
public const v10_DEFAULT_MIN = 10;
|
||||||
|
|
||||||
/** @var int 1.1 - File is a volume label */
|
/** @var int 1.1 - File is a volume label */
|
||||||
const v11_FILE_VOLUME_LABEL = 11;
|
public const v11_FILE_VOLUME_LABEL = 11;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2.0 - File is a folder (directory)
|
* 2.0 - File is a folder (directory)
|
||||||
@ -25,22 +31,22 @@ interface ZipVersion
|
|||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
const v20_DEFLATED_FOLDER_ZIPCRYPTO = 20;
|
public const v20_DEFLATED_FOLDER_ZIPCRYPTO = 20;
|
||||||
|
|
||||||
/** @var int 2.1 - File is compressed using Deflate64(tm) */
|
/** @var int 2.1 - File is compressed using Deflate64(tm) */
|
||||||
const v21_DEFLATED64 = 21;
|
public const v21_DEFLATED64 = 21;
|
||||||
|
|
||||||
/** @var int 2.5 - File is compressed using PKWARE DCL Implode */
|
/** @var int 2.5 - File is compressed using PKWARE DCL Implode */
|
||||||
const v25_IMPLODED = 25;
|
public const v25_IMPLODED = 25;
|
||||||
|
|
||||||
/** @var int 2.7 - File is a patch data set */
|
/** @var int 2.7 - File is a patch data set */
|
||||||
const v27_PATCH_DATA = 27;
|
public const v27_PATCH_DATA = 27;
|
||||||
|
|
||||||
/** @var int 4.5 - File uses ZIP64 format extensions */
|
/** @var int 4.5 - File uses ZIP64 format extensions */
|
||||||
const v45_ZIP64_EXT = 45;
|
public const v45_ZIP64_EXT = 45;
|
||||||
|
|
||||||
/** @var int 4.6 - File is compressed using BZIP2 compression */
|
/** @var int 4.6 - File is compressed using BZIP2 compression */
|
||||||
const v46_BZIP2 = 46;
|
public const v46_BZIP2 = 46;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 5.0 - File is encrypted using DES
|
* 5.0 - File is encrypted using DES
|
||||||
@ -50,7 +56,7 @@ interface ZipVersion
|
|||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
const v50_ENCR_DES_3DES_RC2_ORIG_RC4 = 50;
|
public const v50_ENCR_DES_3DES_RC2_ORIG_RC4 = 50;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 5.1 - File is encrypted using AES encryption
|
* 5.1 - File is encrypted using AES encryption
|
||||||
@ -58,16 +64,16 @@ interface ZipVersion
|
|||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
const v51_ENCR_AES_RC2_CORRECT = 51;
|
public const v51_ENCR_AES_RC2_CORRECT = 51;
|
||||||
|
|
||||||
/** @var int 5.2 - File is encrypted using corrected RC2-64 encryption** */
|
/** @var int 5.2 - File is encrypted using corrected RC2-64 encryption** */
|
||||||
const v52_ENCR_RC2_64_CORRECT = 52;
|
public const v52_ENCR_RC2_64_CORRECT = 52;
|
||||||
|
|
||||||
/** @var int 6.1 - File is encrypted using non-OAEP key wrapping*** */
|
/** @var int 6.1 - File is encrypted using non-OAEP key wrapping*** */
|
||||||
const v61_ENCR_NON_OAE_KEY_WRAP = 61;
|
public const v61_ENCR_NON_OAE_KEY_WRAP = 61;
|
||||||
|
|
||||||
/** @var int 6.2 - Central directory encryption */
|
/** @var int 6.2 - Central directory encryption */
|
||||||
const v62_ENCR_CENTRAL_DIR = 62;
|
public const v62_ENCR_CENTRAL_DIR = 62;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 6.3 - File is compressed using LZMA
|
* 6.3 - File is compressed using LZMA
|
||||||
@ -77,5 +83,5 @@ interface ZipVersion
|
|||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
const v63_LZMA_PPMD_BLOWFISH_TWOFISH = 63;
|
public const v63_LZMA_PPMD_BLOWFISH_TWOFISH = 63;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Exception;
|
namespace PhpZip\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -8,34 +17,16 @@ namespace PhpZip\Exception;
|
|||||||
* and the computed value from the decompressed data.
|
* and the computed value from the decompressed data.
|
||||||
*
|
*
|
||||||
* The exception detail message is the name of the ZIP entry.
|
* The exception detail message is the name of the ZIP entry.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class Crc32Exception extends ZipException
|
class Crc32Exception extends ZipException
|
||||||
{
|
{
|
||||||
/**
|
/** Expected crc. */
|
||||||
* Expected crc.
|
private int $expectedCrc;
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $expectedCrc;
|
|
||||||
|
|
||||||
/**
|
/** Actual crc. */
|
||||||
* Actual crc.
|
private int $actualCrc;
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $actualCrc;
|
|
||||||
|
|
||||||
/**
|
public function __construct(string $name, int $expected, int $actual)
|
||||||
* Crc32Exception constructor.
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @param int $expected
|
|
||||||
* @param int $actual
|
|
||||||
*/
|
|
||||||
public function __construct($name, $expected, $actual)
|
|
||||||
{
|
{
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
sprintf(
|
sprintf(
|
||||||
@ -51,20 +42,16 @@ class Crc32Exception extends ZipException
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns expected crc.
|
* Returns expected crc.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getExpectedCrc()
|
public function getExpectedCrc(): int
|
||||||
{
|
{
|
||||||
return $this->expectedCrc;
|
return $this->expectedCrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns actual crc.
|
* Returns actual crc.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getActualCrc()
|
public function getActualCrc(): int
|
||||||
{
|
{
|
||||||
return $this->actualCrc;
|
return $this->actualCrc;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Exception;
|
namespace PhpZip\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown to indicate that a method has been passed an illegal or
|
* Thrown to indicate that a method has been passed an illegal or
|
||||||
* inappropriate argument.
|
* inappropriate argument.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class InvalidArgumentException extends RuntimeException
|
class InvalidArgumentException extends RuntimeException
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Exception;
|
namespace PhpZip\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runtime exception.
|
* Runtime exception.
|
||||||
* Exception thrown if an error which can only be found on runtime occurs.
|
* Exception thrown if an error which can only be found on runtime occurs.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class RuntimeException extends \RuntimeException
|
class RuntimeException extends \RuntimeException
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Exception;
|
namespace PhpZip\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown to indicate that an authenticated ZIP entry has been tampered with.
|
* Thrown to indicate that an authenticated ZIP entry has been tampered with.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class ZipAuthenticationException extends ZipCryptoException
|
class ZipAuthenticationException extends ZipCryptoException
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Exception;
|
namespace PhpZip\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if there is an issue when reading or writing an encrypted ZIP file
|
* Thrown if there is an issue when reading or writing an encrypted ZIP file
|
||||||
* or entry.
|
* or entry.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class ZipCryptoException extends ZipException
|
class ZipCryptoException extends ZipException
|
||||||
{
|
{
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Exception;
|
namespace PhpZip\Exception;
|
||||||
|
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if entry not found.
|
* Thrown if entry not found.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class ZipEntryNotFoundException extends ZipException
|
class ZipEntryNotFoundException extends ZipException
|
||||||
{
|
{
|
||||||
/** @var string */
|
private string $entryName;
|
||||||
private $entryName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ZipEntryNotFoundException constructor.
|
|
||||||
*
|
|
||||||
* @param ZipEntry|string $entryName
|
* @param ZipEntry|string $entryName
|
||||||
*/
|
*/
|
||||||
public function __construct($entryName)
|
public function __construct($entryName)
|
||||||
@ -30,10 +33,7 @@ class ZipEntryNotFoundException extends ZipException
|
|||||||
$this->entryName = $entryName;
|
$this->entryName = $entryName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getEntryName(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getEntryName()
|
|
||||||
{
|
{
|
||||||
return $this->entryName;
|
return $this->entryName;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Exception;
|
namespace PhpZip\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals that a Zip exception of some sort has occurred.
|
* Signals that a Zip exception of some sort has occurred.
|
||||||
*
|
*
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*
|
|
||||||
* @see \Exception
|
* @see \Exception
|
||||||
*/
|
*/
|
||||||
class ZipException extends \Exception
|
class ZipException extends \Exception
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Exception;
|
namespace PhpZip\Exception;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipUnsupportMethodException.
|
|
||||||
*/
|
|
||||||
class ZipUnsupportMethodException extends ZipException
|
class ZipUnsupportMethodException extends ZipException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO\Filter\Cipher\Pkware;
|
namespace PhpZip\IO\Filter\Cipher\Pkware;
|
||||||
|
|
||||||
use PhpZip\Exception\RuntimeException;
|
use PhpZip\Exception\RuntimeException;
|
||||||
use PhpZip\Exception\ZipAuthenticationException;
|
use PhpZip\Exception\ZipAuthenticationException;
|
||||||
use PhpZip\Util\PackUtil;
|
use PhpZip\Util\MathUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traditional PKWARE Encryption Engine.
|
* Traditional PKWARE Encryption Engine.
|
||||||
*
|
*
|
||||||
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
|
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class PKCryptContext
|
class PKCryptContext
|
||||||
{
|
{
|
||||||
/** Encryption header size */
|
/** @var int Encryption header size */
|
||||||
const STD_DEC_HDR_SIZE = 12;
|
public const STD_DEC_HDR_SIZE = 12;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crc table.
|
* Crc table.
|
||||||
*
|
*
|
||||||
* @var int[]|array
|
* @var int[]|array
|
||||||
*/
|
*/
|
||||||
private static $CRC_TABLE = [
|
private const CRC_TABLE = [
|
||||||
0x00000000,
|
0x00000000,
|
||||||
0x77073096,
|
0x77073096,
|
||||||
0xee0e612c,
|
0xee0e612c,
|
||||||
@ -283,19 +289,10 @@ class PKCryptContext
|
|||||||
0x2d02ef8d,
|
0x2d02ef8d,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/** @var array encryption keys */
|
||||||
* Encryption keys.
|
private array $keys;
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $keys;
|
|
||||||
|
|
||||||
/**
|
public function __construct(string $password)
|
||||||
* PKCryptContext constructor.
|
|
||||||
*
|
|
||||||
* @param string $password
|
|
||||||
*/
|
|
||||||
public function __construct($password)
|
|
||||||
{
|
{
|
||||||
if (\PHP_INT_SIZE === 4) {
|
if (\PHP_INT_SIZE === 4) {
|
||||||
throw new RuntimeException('Traditional PKWARE Encryption is not supported in 32-bit PHP.');
|
throw new RuntimeException('Traditional PKWARE Encryption is not supported in 32-bit PHP.');
|
||||||
@ -307,18 +304,15 @@ class PKCryptContext
|
|||||||
878082192,
|
878082192,
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach (unpack('C*', $password) as $b) {
|
foreach (unpack('C*', $password) as $byte) {
|
||||||
$this->updateKeys($b);
|
$this->updateKeys($byte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $header
|
|
||||||
* @param int $checkByte
|
|
||||||
*
|
|
||||||
* @throws ZipAuthenticationException
|
* @throws ZipAuthenticationException
|
||||||
*/
|
*/
|
||||||
public function checkHeader($header, $checkByte)
|
public function checkHeader(string $header, int $checkByte): void
|
||||||
{
|
{
|
||||||
$byte = 0;
|
$byte = 0;
|
||||||
|
|
||||||
@ -328,16 +322,11 @@ class PKCryptContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($byte !== $checkByte) {
|
if ($byte !== $checkByte) {
|
||||||
throw new ZipAuthenticationException(sprintf('Invalid password'));
|
throw new ZipAuthenticationException('Invalid password');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function decryptString(string $content): string
|
||||||
* @param string $content
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function decryptString($content)
|
|
||||||
{
|
{
|
||||||
$decryptContent = '';
|
$decryptContent = '';
|
||||||
|
|
||||||
@ -352,10 +341,8 @@ class PKCryptContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypt byte.
|
* Decrypt byte.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
private function decryptByte()
|
private function decryptByte(): int
|
||||||
{
|
{
|
||||||
$temp = $this->keys[2] | 2;
|
$temp = $this->keys[2] | 2;
|
||||||
|
|
||||||
@ -364,36 +351,24 @@ class PKCryptContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update keys.
|
* Update keys.
|
||||||
*
|
|
||||||
* @param int $charAt
|
|
||||||
*/
|
*/
|
||||||
private function updateKeys($charAt)
|
private function updateKeys(int $charAt): void
|
||||||
{
|
{
|
||||||
$this->keys[0] = $this->crc32($this->keys[0], $charAt);
|
$this->keys[0] = $this->crc32($this->keys[0], $charAt);
|
||||||
$this->keys[1] += ($this->keys[0] & 0xff);
|
$this->keys[1] += ($this->keys[0] & 0xff);
|
||||||
$this->keys[1] = PackUtil::toSignedInt32($this->keys[1] * 134775813 + 1);
|
$this->keys[1] = MathUtil::toSignedInt32($this->keys[1] * 134775813 + 1);
|
||||||
$this->keys[2] = PackUtil::toSignedInt32($this->crc32($this->keys[2], ($this->keys[1] >> 24) & 0xff));
|
$this->keys[2] = MathUtil::toSignedInt32($this->crc32($this->keys[2], ($this->keys[1] >> 24) & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update crc.
|
* Update crc.
|
||||||
*
|
|
||||||
* @param int $oldCrc
|
|
||||||
* @param int $charAt
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
private function crc32($oldCrc, $charAt)
|
private function crc32(int $oldCrc, int $charAt): int
|
||||||
{
|
{
|
||||||
return (($oldCrc >> 8) & 0xffffff) ^ self::$CRC_TABLE[($oldCrc ^ $charAt) & 0xff];
|
return (($oldCrc >> 8) & 0xffffff) ^ self::CRC_TABLE[($oldCrc ^ $charAt) & 0xff];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function encryptString(string $content): string
|
||||||
* @param string $content
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function encryptString($content)
|
|
||||||
{
|
{
|
||||||
$encryptContent = '';
|
$encryptContent = '';
|
||||||
|
|
||||||
@ -404,12 +379,7 @@ class PKCryptContext
|
|||||||
return $encryptContent;
|
return $encryptContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function encryptByte(int $byte): int
|
||||||
* @param int $byte
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
private function encryptByte($byte)
|
|
||||||
{
|
{
|
||||||
$tempVal = $byte ^ $this->decryptByte() & 0xff;
|
$tempVal = $byte ^ $this->decryptByte() & 0xff;
|
||||||
$this->updateKeys($byte);
|
$this->updateKeys($byte);
|
||||||
|
@ -1,8 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO\Filter\Cipher\Pkware;
|
namespace PhpZip\IO\Filter\Cipher\Pkware;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipAuthenticationException;
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10,37 +19,27 @@ use PhpZip\Model\ZipEntry;
|
|||||||
*/
|
*/
|
||||||
class PKDecryptionStreamFilter extends \php_user_filter
|
class PKDecryptionStreamFilter extends \php_user_filter
|
||||||
{
|
{
|
||||||
const FILTER_NAME = 'phpzip.decryption.pkware';
|
public const FILTER_NAME = 'phpzip.decryption.pkware';
|
||||||
|
|
||||||
/** @var int */
|
private int $checkByte = 0;
|
||||||
private $checkByte = 0;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $readLength = 0;
|
||||||
private $readLength = 0;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $size = 0;
|
||||||
private $size = 0;
|
|
||||||
|
|
||||||
/** @var bool */
|
private bool $readHeader = false;
|
||||||
private $readHeader = false;
|
|
||||||
|
|
||||||
/** @var PKCryptContext */
|
private PKCryptContext $context;
|
||||||
private $context;
|
|
||||||
|
|
||||||
/**
|
public static function register(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function register()
|
|
||||||
{
|
{
|
||||||
return stream_filter_register(self::FILTER_NAME, __CLASS__);
|
return stream_filter_register(self::FILTER_NAME, __CLASS__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://php.net/manual/en/php-user-filter.oncreate.php
|
* @see https://php.net/manual/en/php-user-filter.oncreate.php
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function onCreate()
|
public function onCreate(): bool
|
||||||
{
|
{
|
||||||
if (!isset($this->params['entry'])) {
|
if (!isset($this->params['entry'])) {
|
||||||
return false;
|
return false;
|
||||||
@ -78,18 +77,12 @@ class PKDecryptionStreamFilter extends \php_user_filter
|
|||||||
/**
|
/**
|
||||||
* Decryption filter.
|
* Decryption filter.
|
||||||
*
|
*
|
||||||
* @param resource $in
|
* @throws ZipAuthenticationException
|
||||||
* @param resource $out
|
|
||||||
* @param int $consumed
|
|
||||||
* @param bool $closing
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*
|
*
|
||||||
* @todo USE FFI in php 7.4
|
* @todo USE FFI in php 7.4
|
||||||
|
* @noinspection PhpDocSignatureInspection
|
||||||
*/
|
*/
|
||||||
public function filter($in, $out, &$consumed, $closing)
|
public function filter($in, $out, &$consumed, $closing): int
|
||||||
{
|
{
|
||||||
while ($bucket = stream_bucket_make_writeable($in)) {
|
while ($bucket = stream_bucket_make_writeable($in)) {
|
||||||
$buffer = $bucket->data;
|
$buffer = $bucket->data;
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO\Filter\Cipher\Pkware;
|
namespace PhpZip\IO\Filter\Cipher\Pkware;
|
||||||
|
|
||||||
use PhpZip\Exception\RuntimeException;
|
use PhpZip\Exception\RuntimeException;
|
||||||
@ -10,37 +19,27 @@ use PhpZip\Model\ZipEntry;
|
|||||||
*/
|
*/
|
||||||
class PKEncryptionStreamFilter extends \php_user_filter
|
class PKEncryptionStreamFilter extends \php_user_filter
|
||||||
{
|
{
|
||||||
const FILTER_NAME = 'phpzip.encryption.pkware';
|
public const FILTER_NAME = 'phpzip.encryption.pkware';
|
||||||
|
|
||||||
/** @var int */
|
private int $size;
|
||||||
private $size;
|
|
||||||
|
|
||||||
/** @var string */
|
private string $headerBytes;
|
||||||
private $headerBytes;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $writeLength;
|
||||||
private $writeLength;
|
|
||||||
|
|
||||||
/** @var bool */
|
private bool $writeHeader;
|
||||||
private $writeHeader;
|
|
||||||
|
|
||||||
/** @var PKCryptContext */
|
private PKCryptContext $context;
|
||||||
private $context;
|
|
||||||
|
|
||||||
/**
|
public static function register(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function register()
|
|
||||||
{
|
{
|
||||||
return stream_filter_register(self::FILTER_NAME, __CLASS__);
|
return stream_filter_register(self::FILTER_NAME, __CLASS__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://php.net/manual/en/php-user-filter.oncreate.php
|
* @see https://php.net/manual/en/php-user-filter.oncreate.php
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function onCreate()
|
public function onCreate(): bool
|
||||||
{
|
{
|
||||||
if (\PHP_INT_SIZE === 4) {
|
if (\PHP_INT_SIZE === 4) {
|
||||||
throw new RuntimeException('Traditional PKWARE Encryption is not supported in 32-bit PHP.');
|
throw new RuntimeException('Traditional PKWARE Encryption is not supported in 32-bit PHP.');
|
||||||
@ -66,9 +65,9 @@ class PKEncryptionStreamFilter extends \php_user_filter
|
|||||||
// init keys
|
// init keys
|
||||||
$this->context = new PKCryptContext($password);
|
$this->context = new PKCryptContext($password);
|
||||||
|
|
||||||
$crc = $entry->isDataDescriptorRequired() || $entry->getCrc() === ZipEntry::UNKNOWN ?
|
$crc = $entry->isDataDescriptorRequired() || $entry->getCrc() === ZipEntry::UNKNOWN
|
||||||
($entry->getDosTime() & 0x0000ffff) << 16 :
|
? ($entry->getDosTime() & 0x0000ffff) << 16
|
||||||
$entry->getCrc();
|
: $entry->getCrc();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$headerBytes = random_bytes(PKCryptContext::STD_DEC_HDR_SIZE);
|
$headerBytes = random_bytes(PKCryptContext::STD_DEC_HDR_SIZE);
|
||||||
@ -89,16 +88,11 @@ class PKEncryptionStreamFilter extends \php_user_filter
|
|||||||
/**
|
/**
|
||||||
* Encryption filter.
|
* Encryption filter.
|
||||||
*
|
*
|
||||||
* @param resource $in
|
|
||||||
* @param resource $out
|
|
||||||
* @param int $consumed
|
|
||||||
* @param bool $closing
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*
|
|
||||||
* @todo USE FFI in php 7.4
|
* @todo USE FFI in php 7.4
|
||||||
|
*
|
||||||
|
* @noinspection PhpDocSignatureInspection
|
||||||
*/
|
*/
|
||||||
public function filter($in, $out, &$consumed, $closing)
|
public function filter($in, $out, &$consumed, $closing): int
|
||||||
{
|
{
|
||||||
while ($bucket = stream_bucket_make_writeable($in)) {
|
while ($bucket = stream_bucket_make_writeable($in)) {
|
||||||
$buffer = $bucket->data;
|
$buffer = $bucket->data;
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO\Filter\Cipher\WinZipAes;
|
namespace PhpZip\IO\Filter\Cipher\WinZipAes;
|
||||||
|
|
||||||
use PhpZip\Exception\RuntimeException;
|
use PhpZip\Exception\RuntimeException;
|
||||||
@ -12,51 +21,35 @@ use PhpZip\Util\CryptoUtil;
|
|||||||
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT APPENDIX E
|
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT APPENDIX E
|
||||||
* @see https://www.winzip.com/win/en/aes_info.html
|
* @see https://www.winzip.com/win/en/aes_info.html
|
||||||
*
|
*
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*
|
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
class WinZipAesContext
|
class WinZipAesContext
|
||||||
{
|
{
|
||||||
/** @var int AES Block size */
|
/** @var int AES Block size */
|
||||||
const BLOCK_SIZE = self::IV_SIZE;
|
public const BLOCK_SIZE = self::IV_SIZE;
|
||||||
|
|
||||||
/** @var int Footer size */
|
/** @var int Footer size */
|
||||||
const FOOTER_SIZE = 10;
|
public const FOOTER_SIZE = 10;
|
||||||
|
|
||||||
/** @var int The iteration count for the derived keys of the cipher, KLAC and MAC. */
|
/** @var int The iteration count for the derived keys of the cipher, KLAC and MAC. */
|
||||||
const ITERATION_COUNT = 1000;
|
public const ITERATION_COUNT = 1000;
|
||||||
|
|
||||||
/** @var int Password verifier size */
|
/** @var int Password verifier size */
|
||||||
const PASSWORD_VERIFIER_SIZE = 2;
|
public const PASSWORD_VERIFIER_SIZE = 2;
|
||||||
|
|
||||||
/** @var int IV size */
|
/** @var int IV size */
|
||||||
const IV_SIZE = 16;
|
public const IV_SIZE = 16;
|
||||||
|
|
||||||
/** @var string */
|
private string $iv;
|
||||||
private $iv;
|
|
||||||
|
|
||||||
/** @var string */
|
private string $key;
|
||||||
private $key;
|
|
||||||
|
|
||||||
/** @var \HashContext|resource */
|
private \HashContext $hmacContext;
|
||||||
private $hmacContext;
|
|
||||||
|
|
||||||
/** @var string */
|
private string $passwordVerifier;
|
||||||
private $passwordVerifier;
|
|
||||||
|
|
||||||
/**
|
public function __construct(int $encryptionStrengthBits, string $password, string $salt)
|
||||||
* WinZipAesContext constructor.
|
|
||||||
*
|
|
||||||
* @param int $encryptionStrengthBits
|
|
||||||
* @param string $password
|
|
||||||
* @param string $salt
|
|
||||||
*/
|
|
||||||
public function __construct($encryptionStrengthBits, $password, $salt)
|
|
||||||
{
|
{
|
||||||
$encryptionStrengthBits = (int) $encryptionStrengthBits;
|
|
||||||
|
|
||||||
if ($password === '') {
|
if ($password === '') {
|
||||||
throw new RuntimeException('$password is empty');
|
throw new RuntimeException('$password is empty');
|
||||||
}
|
}
|
||||||
@ -87,15 +80,12 @@ class WinZipAesContext
|
|||||||
$this->passwordVerifier = substr($hash, 2 * $keyStrengthBytes, self::PASSWORD_VERIFIER_SIZE);
|
$this->passwordVerifier = substr($hash, 2 * $keyStrengthBytes, self::PASSWORD_VERIFIER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getPasswordVerifier(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getPasswordVerifier()
|
|
||||||
{
|
{
|
||||||
return $this->passwordVerifier;
|
return $this->passwordVerifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateIv()
|
public function updateIv(): void
|
||||||
{
|
{
|
||||||
for ($ivCharIndex = 0; $ivCharIndex < self::IV_SIZE; $ivCharIndex++) {
|
for ($ivCharIndex = 0; $ivCharIndex < self::IV_SIZE; $ivCharIndex++) {
|
||||||
$ivByte = \ord($this->iv[$ivCharIndex]);
|
$ivByte = \ord($this->iv[$ivCharIndex]);
|
||||||
@ -112,24 +102,14 @@ class WinZipAesContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function decryption(string $data): string
|
||||||
* @param string $data
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function decryption($data)
|
|
||||||
{
|
{
|
||||||
hash_update($this->hmacContext, $data);
|
hash_update($this->hmacContext, $data);
|
||||||
|
|
||||||
return CryptoUtil::decryptAesCtr($data, $this->key, $this->iv);
|
return CryptoUtil::decryptAesCtr($data, $this->key, $this->iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function encrypt(string $data): string
|
||||||
* @param string $data
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function encrypt($data)
|
|
||||||
{
|
{
|
||||||
$encryptionData = CryptoUtil::encryptAesCtr($data, $this->key, $this->iv);
|
$encryptionData = CryptoUtil::encryptAesCtr($data, $this->key, $this->iv);
|
||||||
hash_update($this->hmacContext, $encryptionData);
|
hash_update($this->hmacContext, $encryptionData);
|
||||||
@ -138,11 +118,9 @@ class WinZipAesContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $authCode
|
|
||||||
*
|
|
||||||
* @throws ZipAuthenticationException
|
* @throws ZipAuthenticationException
|
||||||
*/
|
*/
|
||||||
public function checkAuthCode($authCode)
|
public function checkAuthCode(string $authCode): void
|
||||||
{
|
{
|
||||||
$hmac = $this->getHmac();
|
$hmac = $this->getHmac();
|
||||||
|
|
||||||
@ -152,10 +130,7 @@ class WinZipAesContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getHmac(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getHmac()
|
|
||||||
{
|
{
|
||||||
return substr(
|
return substr(
|
||||||
hash_final($this->hmacContext, true),
|
hash_final($this->hmacContext, true),
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO\Filter\Cipher\WinZipAes;
|
namespace PhpZip\IO\Filter\Cipher\WinZipAes;
|
||||||
|
|
||||||
use PhpZip\Exception\RuntimeException;
|
use PhpZip\Exception\RuntimeException;
|
||||||
@ -12,43 +21,31 @@ use PhpZip\Model\ZipEntry;
|
|||||||
*/
|
*/
|
||||||
class WinZipAesDecryptionStreamFilter extends \php_user_filter
|
class WinZipAesDecryptionStreamFilter extends \php_user_filter
|
||||||
{
|
{
|
||||||
const FILTER_NAME = 'phpzip.decryption.winzipaes';
|
public const FILTER_NAME = 'phpzip.decryption.winzipaes';
|
||||||
|
|
||||||
/** @var string */
|
private string $buffer;
|
||||||
private $buffer;
|
|
||||||
|
|
||||||
/** @var string */
|
private ?string $authenticationCode = null;
|
||||||
private $authenticationCode;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $encBlockPosition = 0;
|
||||||
private $encBlockPosition = 0;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $encBlockLength = 0;
|
||||||
private $encBlockLength = 0;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $readLength = 0;
|
||||||
private $readLength = 0;
|
|
||||||
|
|
||||||
/** @var ZipEntry */
|
private ZipEntry $entry;
|
||||||
private $entry;
|
|
||||||
|
|
||||||
/** @var WinZipAesContext|null */
|
private ?WinZipAesContext $context = null;
|
||||||
private $context;
|
|
||||||
|
|
||||||
/**
|
public static function register(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function register()
|
|
||||||
{
|
{
|
||||||
return stream_filter_register(self::FILTER_NAME, __CLASS__);
|
return stream_filter_register(self::FILTER_NAME, __CLASS__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @noinspection DuplicatedCode
|
* @noinspection DuplicatedCode
|
||||||
*/
|
*/
|
||||||
public function onCreate()
|
public function onCreate(): bool
|
||||||
{
|
{
|
||||||
if (!isset($this->params['entry'])) {
|
if (!isset($this->params['entry'])) {
|
||||||
return false;
|
return false;
|
||||||
@ -60,9 +57,9 @@ class WinZipAesDecryptionStreamFilter extends \php_user_filter
|
|||||||
$this->entry = $this->params['entry'];
|
$this->entry = $this->params['entry'];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$this->entry->getPassword() === null ||
|
$this->entry->getPassword() === null
|
||||||
!$this->entry->isEncrypted() ||
|
|| !$this->entry->isEncrypted()
|
||||||
!$this->entry->hasExtraField(WinZipAesExtraField::HEADER_ID)
|
|| !$this->entry->hasExtraField(WinZipAesExtraField::HEADER_ID)
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -73,16 +70,10 @@ class WinZipAesDecryptionStreamFilter extends \php_user_filter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $in
|
|
||||||
* @param resource $out
|
|
||||||
* @param int $consumed
|
|
||||||
* @param bool $closing
|
|
||||||
*
|
|
||||||
* @throws ZipAuthenticationException
|
* @throws ZipAuthenticationException
|
||||||
*
|
* @noinspection PhpDocSignatureInspection
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function filter($in, $out, &$consumed, $closing)
|
public function filter($in, $out, &$consumed, $closing): int
|
||||||
{
|
{
|
||||||
while ($bucket = stream_bucket_make_writeable($in)) {
|
while ($bucket = stream_bucket_make_writeable($in)) {
|
||||||
$this->buffer .= $bucket->data;
|
$this->buffer .= $bucket->data;
|
||||||
@ -156,8 +147,8 @@ class WinZipAesDecryptionStreamFilter extends \php_user_filter
|
|||||||
$this->encBlockPosition += $offset;
|
$this->encBlockPosition += $offset;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$this->encBlockPosition === $this->encBlockLength &&
|
$this->encBlockPosition === $this->encBlockLength
|
||||||
\strlen($this->buffer) === WinZipAesContext::FOOTER_SIZE
|
&& \strlen($this->buffer) === WinZipAesContext::FOOTER_SIZE
|
||||||
) {
|
) {
|
||||||
$this->authenticationCode = $this->buffer;
|
$this->authenticationCode = $this->buffer;
|
||||||
$this->buffer = '';
|
$this->buffer = '';
|
||||||
@ -176,11 +167,11 @@ class WinZipAesDecryptionStreamFilter extends \php_user_filter
|
|||||||
*
|
*
|
||||||
* @throws ZipAuthenticationException
|
* @throws ZipAuthenticationException
|
||||||
*/
|
*/
|
||||||
public function onClose()
|
public function onClose(): void
|
||||||
{
|
{
|
||||||
$this->buffer = '';
|
$this->buffer = '';
|
||||||
|
|
||||||
if ($this->context !== null) {
|
if ($this->context !== null && $this->authenticationCode !== null) {
|
||||||
$this->context->checkAuthCode($this->authenticationCode);
|
$this->context->checkAuthCode($this->authenticationCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO\Filter\Cipher\WinZipAes;
|
namespace PhpZip\IO\Filter\Cipher\WinZipAes;
|
||||||
|
|
||||||
use PhpZip\Exception\RuntimeException;
|
use PhpZip\Exception\RuntimeException;
|
||||||
@ -11,37 +20,27 @@ use PhpZip\Model\ZipEntry;
|
|||||||
*/
|
*/
|
||||||
class WinZipAesEncryptionStreamFilter extends \php_user_filter
|
class WinZipAesEncryptionStreamFilter extends \php_user_filter
|
||||||
{
|
{
|
||||||
const FILTER_NAME = 'phpzip.encryption.winzipaes';
|
public const FILTER_NAME = 'phpzip.encryption.winzipaes';
|
||||||
|
|
||||||
/** @var string */
|
private string $buffer;
|
||||||
private $buffer;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $remaining = 0;
|
||||||
private $remaining = 0;
|
|
||||||
|
|
||||||
/** @var ZipEntry */
|
private ZipEntry $entry;
|
||||||
private $entry;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $size;
|
||||||
private $size;
|
|
||||||
|
|
||||||
/** @var WinZipAesContext|null */
|
private ?WinZipAesContext $context = null;
|
||||||
private $context;
|
|
||||||
|
|
||||||
/**
|
public static function register(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function register()
|
|
||||||
{
|
{
|
||||||
return stream_filter_register(self::FILTER_NAME, __CLASS__);
|
return stream_filter_register(self::FILTER_NAME, __CLASS__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @noinspection DuplicatedCode
|
* @noinspection DuplicatedCode
|
||||||
*/
|
*/
|
||||||
public function onCreate()
|
public function onCreate(): bool
|
||||||
{
|
{
|
||||||
if (!isset($this->params['entry'])) {
|
if (!isset($this->params['entry'])) {
|
||||||
return false;
|
return false;
|
||||||
@ -53,9 +52,9 @@ class WinZipAesEncryptionStreamFilter extends \php_user_filter
|
|||||||
$this->entry = $this->params['entry'];
|
$this->entry = $this->params['entry'];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$this->entry->getPassword() === null ||
|
$this->entry->getPassword() === null
|
||||||
!$this->entry->isEncrypted() ||
|
|| !$this->entry->isEncrypted()
|
||||||
!$this->entry->hasExtraField(WinZipAesExtraField::HEADER_ID)
|
|| !$this->entry->hasExtraField(WinZipAesExtraField::HEADER_ID)
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -67,15 +66,7 @@ class WinZipAesEncryptionStreamFilter extends \php_user_filter
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function filter($in, $out, &$consumed, $closing): int
|
||||||
* @param resource $in
|
|
||||||
* @param resource $out
|
|
||||||
* @param int $consumed
|
|
||||||
* @param bool $closing
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function filter($in, $out, &$consumed, $closing)
|
|
||||||
{
|
{
|
||||||
while ($bucket = stream_bucket_make_writeable($in)) {
|
while ($bucket = stream_bucket_make_writeable($in)) {
|
||||||
$this->buffer .= $bucket->data;
|
$this->buffer .= $bucket->data;
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO\Stream;
|
namespace PhpZip\IO\Stream;
|
||||||
|
|
||||||
use Psr\Http\Message\StreamInterface;
|
use Psr\Http\Message\StreamInterface;
|
||||||
@ -10,7 +19,7 @@ use Psr\Http\Message\StreamInterface;
|
|||||||
class ResponseStream implements StreamInterface
|
class ResponseStream implements StreamInterface
|
||||||
{
|
{
|
||||||
/** @var array */
|
/** @var array */
|
||||||
private static $readWriteHash = [
|
private const READ_WRITE_MAP = [
|
||||||
'read' => [
|
'read' => [
|
||||||
'r' => true,
|
'r' => true,
|
||||||
'w+' => true,
|
'w+' => true,
|
||||||
@ -53,20 +62,15 @@ class ResponseStream implements StreamInterface
|
|||||||
/** @var resource */
|
/** @var resource */
|
||||||
private $stream;
|
private $stream;
|
||||||
|
|
||||||
/** @var int|null */
|
private ?int $size = null;
|
||||||
private $size;
|
|
||||||
|
|
||||||
/** @var bool */
|
private bool $seekable;
|
||||||
private $seekable;
|
|
||||||
|
|
||||||
/** @var bool */
|
private bool $readable;
|
||||||
private $readable;
|
|
||||||
|
|
||||||
/** @var bool */
|
private bool $writable;
|
||||||
private $writable;
|
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $uri;
|
||||||
private $uri;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $stream stream resource to wrap
|
* @param resource $stream stream resource to wrap
|
||||||
@ -81,24 +85,15 @@ class ResponseStream implements StreamInterface
|
|||||||
$this->stream = $stream;
|
$this->stream = $stream;
|
||||||
$meta = stream_get_meta_data($this->stream);
|
$meta = stream_get_meta_data($this->stream);
|
||||||
$this->seekable = $meta['seekable'];
|
$this->seekable = $meta['seekable'];
|
||||||
$this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
|
$this->readable = isset(self::READ_WRITE_MAP['read'][$meta['mode']]);
|
||||||
$this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
|
$this->writable = isset(self::READ_WRITE_MAP['write'][$meta['mode']]);
|
||||||
$this->uri = $this->getMetadata('uri');
|
$this->uri = $this->getMetadata('uri');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get stream metadata as an associative array or retrieve a specific key.
|
* {@inheritdoc}
|
||||||
*
|
*
|
||||||
* The keys returned are identical to the keys returned from PHP's
|
* @noinspection PhpMissingReturnTypeInspection
|
||||||
* stream_get_meta_data() function.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/function.stream-get-meta-data.php
|
|
||||||
*
|
|
||||||
* @param string $key specific metadata to retrieve
|
|
||||||
*
|
|
||||||
* @return array|mixed|null Returns an associative array if no key is
|
|
||||||
* provided. Returns a specific key value if a key is provided and the
|
|
||||||
* value is found, or null if the key is not found.
|
|
||||||
*/
|
*/
|
||||||
public function getMetadata($key = null)
|
public function getMetadata($key = null)
|
||||||
{
|
{
|
||||||
@ -107,7 +102,7 @@ class ResponseStream implements StreamInterface
|
|||||||
}
|
}
|
||||||
$meta = stream_get_meta_data($this->stream);
|
$meta = stream_get_meta_data($this->stream);
|
||||||
|
|
||||||
return isset($meta[$key]) ? $meta[$key] : null;
|
return $meta[$key] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,10 +117,8 @@ class ResponseStream implements StreamInterface
|
|||||||
* string casting operations.
|
* string casting operations.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
|
* @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
if (!$this->stream) {
|
if (!$this->stream) {
|
||||||
return '';
|
return '';
|
||||||
@ -146,7 +139,7 @@ class ResponseStream implements StreamInterface
|
|||||||
* @see http://www.php.net/manual/en/function.fseek.php
|
* @see http://www.php.net/manual/en/function.fseek.php
|
||||||
* @see seek()
|
* @see seek()
|
||||||
*/
|
*/
|
||||||
public function rewind()
|
public function rewind(): void
|
||||||
{
|
{
|
||||||
$this->seekable && rewind($this->stream);
|
$this->seekable && rewind($this->stream);
|
||||||
}
|
}
|
||||||
@ -156,7 +149,7 @@ class ResponseStream implements StreamInterface
|
|||||||
*
|
*
|
||||||
* @return int|null returns the size in bytes if known, or null if unknown
|
* @return int|null returns the size in bytes if known, or null if unknown
|
||||||
*/
|
*/
|
||||||
public function getSize()
|
public function getSize(): ?int
|
||||||
{
|
{
|
||||||
if ($this->size !== null) {
|
if ($this->size !== null) {
|
||||||
return $this->size;
|
return $this->size;
|
||||||
@ -180,13 +173,6 @@ class ResponseStream implements StreamInterface
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current position of the file read/write pointer.
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException on error
|
|
||||||
*
|
|
||||||
* @return int Position of the file pointer
|
|
||||||
*/
|
|
||||||
public function tell()
|
public function tell()
|
||||||
{
|
{
|
||||||
return $this->stream ? ftell($this->stream) : false;
|
return $this->stream ? ftell($this->stream) : false;
|
||||||
@ -194,61 +180,38 @@ class ResponseStream implements StreamInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the stream is at the end of the stream.
|
* Returns true if the stream is at the end of the stream.
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function eof()
|
public function eof(): bool
|
||||||
{
|
{
|
||||||
return !$this->stream || feof($this->stream);
|
return !$this->stream || feof($this->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the stream is seekable.
|
* Returns whether or not the stream is seekable.
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function isSeekable()
|
public function isSeekable(): bool
|
||||||
{
|
{
|
||||||
return $this->seekable;
|
return $this->seekable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Seek to a position in the stream.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @see http://www.php.net/manual/en/function.fseek.php
|
|
||||||
*
|
|
||||||
* @param int $offset Stream offset
|
|
||||||
* @param int $whence Specifies how the cursor position will be calculated
|
|
||||||
* based on the seek offset. Valid values are identical to the built-in
|
|
||||||
* PHP $whence values for `fseek()`. SEEK_SET: Set position equal to
|
|
||||||
* offset bytes SEEK_CUR: Set position to current location plus offset
|
|
||||||
* SEEK_END: Set position to end-of-stream plus offset.
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException on failure
|
|
||||||
*/
|
*/
|
||||||
public function seek($offset, $whence = \SEEK_SET)
|
public function seek($offset, $whence = \SEEK_SET): void
|
||||||
{
|
{
|
||||||
$this->seekable && fseek($this->stream, $offset, $whence);
|
$this->seekable && fseek($this->stream, $offset, $whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the stream is writable.
|
* Returns whether or not the stream is writable.
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function isWritable()
|
public function isWritable(): bool
|
||||||
{
|
{
|
||||||
return $this->writable;
|
return $this->writable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write data to the stream.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $string the string that is to be written
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException on failure
|
|
||||||
*
|
|
||||||
* @return int returns the number of bytes written to the stream
|
|
||||||
*/
|
*/
|
||||||
public function write($string)
|
public function write($string)
|
||||||
{
|
{
|
||||||
@ -259,27 +222,16 @@ class ResponseStream implements StreamInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the stream is readable.
|
* Returns whether or not the stream is readable.
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function isReadable()
|
public function isReadable(): bool
|
||||||
{
|
{
|
||||||
return $this->readable;
|
return $this->readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read data from the stream.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param int $length Read up to $length bytes from the object and return
|
|
||||||
* them. Fewer than $length bytes may be returned if underlying stream
|
|
||||||
* call returns fewer bytes.
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException if an error occurs
|
|
||||||
*
|
|
||||||
* @return string returns the data read from the stream, or an empty string
|
|
||||||
* if no bytes are available
|
|
||||||
*/
|
*/
|
||||||
public function read($length)
|
public function read($length): string
|
||||||
{
|
{
|
||||||
return $this->readable ? fread($this->stream, $length) : '';
|
return $this->readable ? fread($this->stream, $length) : '';
|
||||||
}
|
}
|
||||||
@ -289,10 +241,8 @@ class ResponseStream implements StreamInterface
|
|||||||
*
|
*
|
||||||
* @throws \RuntimeException if unable to read or an error occurs while
|
* @throws \RuntimeException if unable to read or an error occurs while
|
||||||
* reading
|
* reading
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getContents()
|
public function getContents(): string
|
||||||
{
|
{
|
||||||
return $this->stream ? stream_get_contents($this->stream) : '';
|
return $this->stream ? stream_get_contents($this->stream) : '';
|
||||||
}
|
}
|
||||||
@ -308,7 +258,7 @@ class ResponseStream implements StreamInterface
|
|||||||
/**
|
/**
|
||||||
* Closes the stream and any underlying resources.
|
* Closes the stream and any underlying resources.
|
||||||
*/
|
*/
|
||||||
public function close()
|
public function close(): void
|
||||||
{
|
{
|
||||||
if (\is_resource($this->stream)) {
|
if (\is_resource($this->stream)) {
|
||||||
fclose($this->stream);
|
fclose($this->stream);
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO\Stream;
|
namespace PhpZip\IO\Stream;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
@ -15,7 +24,7 @@ use PhpZip\Model\ZipEntry;
|
|||||||
final class ZipEntryStreamWrapper
|
final class ZipEntryStreamWrapper
|
||||||
{
|
{
|
||||||
/** @var string the registered protocol */
|
/** @var string the registered protocol */
|
||||||
const PROTOCOL = 'zipentry';
|
public const PROTOCOL = 'zipentry';
|
||||||
|
|
||||||
/** @var resource */
|
/** @var resource */
|
||||||
public $context;
|
public $context;
|
||||||
@ -23,10 +32,7 @@ final class ZipEntryStreamWrapper
|
|||||||
/** @var resource */
|
/** @var resource */
|
||||||
private $fp;
|
private $fp;
|
||||||
|
|
||||||
/**
|
public static function register(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function register()
|
|
||||||
{
|
{
|
||||||
$protocol = self::PROTOCOL;
|
$protocol = self::PROTOCOL;
|
||||||
|
|
||||||
@ -41,14 +47,12 @@ final class ZipEntryStreamWrapper
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function unregister()
|
public static function unregister(): void
|
||||||
{
|
{
|
||||||
stream_wrapper_unregister(self::PROTOCOL);
|
stream_wrapper_unregister(self::PROTOCOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
|
||||||
* @return resource
|
* @return resource
|
||||||
*/
|
*/
|
||||||
public static function wrap(ZipEntry $entry)
|
public static function wrap(ZipEntry $entry)
|
||||||
@ -79,26 +83,24 @@ final class ZipEntryStreamWrapper
|
|||||||
* This method is called immediately after the wrapper is
|
* This method is called immediately after the wrapper is
|
||||||
* initialized (f.e. by {@see fopen()} and {@see file_get_contents()}).
|
* initialized (f.e. by {@see fopen()} and {@see file_get_contents()}).
|
||||||
*
|
*
|
||||||
* @param string $path specifies the URL that was passed to
|
* @param string $path specifies the URL that was passed to
|
||||||
* the original function
|
* the original function
|
||||||
* @param string $mode the mode used to open the file, as detailed
|
* @param string $mode the mode used to open the file, as detailed
|
||||||
* for {@see fopen()}
|
* for {@see fopen()}
|
||||||
* @param int $options Holds additional flags set by the streams
|
* @param int $options Holds additional flags set by the streams
|
||||||
* API. It can hold one or more of the
|
* API. It can hold one or more of the
|
||||||
* following values OR'd together.
|
* following values OR'd together.
|
||||||
* @param string $opened_path if the path is opened successfully, and
|
* @param string|null $opened_path if the path is opened successfully, and
|
||||||
* STREAM_USE_PATH is set in options,
|
* STREAM_USE_PATH is set in options,
|
||||||
* opened_path should be set to the
|
* opened_path should be set to the
|
||||||
* full path of the file/resource that
|
* full path of the file/resource that
|
||||||
* was actually opened
|
* was actually opened
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
*
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @see https://www.php.net/streamwrapper.stream-open
|
* @see https://www.php.net/streamwrapper.stream-open
|
||||||
*/
|
*/
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool
|
||||||
{
|
{
|
||||||
if ($this->context === null) {
|
if ($this->context === null) {
|
||||||
throw new \RuntimeException('stream context is null');
|
throw new \RuntimeException('stream context is null');
|
||||||
@ -142,7 +144,7 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-read
|
* @see https://www.php.net/streamwrapper.stream-read
|
||||||
*/
|
*/
|
||||||
public function stream_read($count)
|
public function stream_read(int $count)
|
||||||
{
|
{
|
||||||
return fread($this->fp, $count);
|
return fread($this->fp, $count);
|
||||||
}
|
}
|
||||||
@ -164,7 +166,7 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-seek
|
* @see https://www.php.net/streamwrapper.stream-seek
|
||||||
*/
|
*/
|
||||||
public function stream_seek($offset, $whence = \SEEK_SET)
|
public function stream_seek(int $offset, int $whence = \SEEK_SET): bool
|
||||||
{
|
{
|
||||||
return fseek($this->fp, $offset, $whence) === 0;
|
return fseek($this->fp, $offset, $whence) === 0;
|
||||||
}
|
}
|
||||||
@ -179,7 +181,7 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-tell
|
* @see https://www.php.net/streamwrapper.stream-tell
|
||||||
*/
|
*/
|
||||||
public function stream_tell()
|
public function stream_tell(): int
|
||||||
{
|
{
|
||||||
$pos = ftell($this->fp);
|
$pos = ftell($this->fp);
|
||||||
|
|
||||||
@ -201,7 +203,7 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-eof
|
* @see https://www.php.net/streamwrapper.stream-eof
|
||||||
*/
|
*/
|
||||||
public function stream_eof()
|
public function stream_eof(): bool
|
||||||
{
|
{
|
||||||
return feof($this->fp);
|
return feof($this->fp);
|
||||||
}
|
}
|
||||||
@ -211,13 +213,11 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* This method is called in response to {@see fstat()}.
|
* This method is called in response to {@see fstat()}.
|
||||||
*
|
*
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @see https://www.php.net/streamwrapper.stream-stat
|
* @see https://www.php.net/streamwrapper.stream-stat
|
||||||
* @see https://www.php.net/stat
|
* @see https://www.php.net/stat
|
||||||
* @see https://www.php.net/fstat
|
* @see https://www.php.net/fstat
|
||||||
*/
|
*/
|
||||||
public function stream_stat()
|
public function stream_stat(): array
|
||||||
{
|
{
|
||||||
return fstat($this->fp);
|
return fstat($this->fp);
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-flush
|
* @see https://www.php.net/streamwrapper.stream-flush
|
||||||
*/
|
*/
|
||||||
public function stream_flush()
|
public function stream_flush(): bool
|
||||||
{
|
{
|
||||||
return fflush($this->fp);
|
return fflush($this->fp);
|
||||||
}
|
}
|
||||||
@ -247,15 +247,15 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* Will respond to truncation, e.g., through {@see ftruncate()}.
|
* Will respond to truncation, e.g., through {@see ftruncate()}.
|
||||||
*
|
*
|
||||||
* @param int $new_size the new size
|
* @param int $newSize the new size
|
||||||
*
|
*
|
||||||
* @return bool returns TRUE on success or FALSE on failure
|
* @return bool returns TRUE on success or FALSE on failure
|
||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-truncate
|
* @see https://www.php.net/streamwrapper.stream-truncate
|
||||||
*/
|
*/
|
||||||
public function stream_truncate($new_size)
|
public function stream_truncate(int $newSize): bool
|
||||||
{
|
{
|
||||||
return ftruncate($this->fp, (int) $new_size);
|
return ftruncate($this->fp, $newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -272,7 +272,7 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-write
|
* @see https://www.php.net/streamwrapper.stream-write
|
||||||
*/
|
*/
|
||||||
public function stream_write($data)
|
public function stream_write(string $data): int
|
||||||
{
|
{
|
||||||
$bytes = fwrite($this->fp, $data);
|
$bytes = fwrite($this->fp, $data);
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* @return resource
|
* @return resource
|
||||||
*/
|
*/
|
||||||
public function stream_cast($cast_as)
|
public function stream_cast(int $cast_as)
|
||||||
{
|
{
|
||||||
return $this->fp;
|
return $this->fp;
|
||||||
}
|
}
|
||||||
@ -303,7 +303,7 @@ final class ZipEntryStreamWrapper
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-close
|
* @see https://www.php.net/streamwrapper.stream-close
|
||||||
*/
|
*/
|
||||||
public function stream_close()
|
public function stream_close(): void
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO;
|
namespace PhpZip\IO;
|
||||||
|
|
||||||
use PhpZip\Constants\DosCodePage;
|
use PhpZip\Constants\DosCodePage;
|
||||||
@ -24,28 +33,22 @@ use PhpZip\Model\Extra\ZipExtraDriver;
|
|||||||
use PhpZip\Model\Extra\ZipExtraField;
|
use PhpZip\Model\Extra\ZipExtraField;
|
||||||
use PhpZip\Model\ImmutableZipContainer;
|
use PhpZip\Model\ImmutableZipContainer;
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
use PhpZip\Util\PackUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zip reader.
|
* Zip reader.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class ZipReader
|
class ZipReader
|
||||||
{
|
{
|
||||||
/** @var int file size */
|
/** @var int file size */
|
||||||
protected $size;
|
protected int $size;
|
||||||
|
|
||||||
/** @var resource */
|
/** @var resource */
|
||||||
protected $inStream;
|
protected $inStream;
|
||||||
|
|
||||||
/** @var array */
|
protected array $options;
|
||||||
protected $options;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $inStream
|
* @param resource $inStream
|
||||||
* @param array $options
|
|
||||||
*/
|
*/
|
||||||
public function __construct($inStream, array $options = [])
|
public function __construct($inStream, array $options = [])
|
||||||
{
|
{
|
||||||
@ -59,7 +62,7 @@ class ZipReader
|
|||||||
}
|
}
|
||||||
$meta = stream_get_meta_data($inStream);
|
$meta = stream_get_meta_data($inStream);
|
||||||
|
|
||||||
$wrapperType = isset($meta['wrapper_type']) ? $meta['wrapper_type'] : 'Unknown';
|
$wrapperType = $meta['wrapper_type'] ?? 'Unknown';
|
||||||
$supportStreamWrapperTypes = ['plainfile', 'PHP', 'user-space'];
|
$supportStreamWrapperTypes = ['plainfile', 'PHP', 'user-space'];
|
||||||
|
|
||||||
if (!\in_array($wrapperType, $supportStreamWrapperTypes, true)) {
|
if (!\in_array($wrapperType, $supportStreamWrapperTypes, true)) {
|
||||||
@ -72,10 +75,10 @@ class ZipReader
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$wrapperType === 'plainfile' &&
|
$wrapperType === 'plainfile'
|
||||||
(
|
&& (
|
||||||
$meta['stream_type'] === 'dir' ||
|
$meta['stream_type'] === 'dir'
|
||||||
(isset($meta['uri']) && is_dir($meta['uri']))
|
|| (isset($meta['uri']) && is_dir($meta['uri']))
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
throw new InvalidArgumentException('Directory stream not supported');
|
throw new InvalidArgumentException('Directory stream not supported');
|
||||||
@ -94,10 +97,7 @@ class ZipReader
|
|||||||
$this->options = $options;
|
$this->options = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function getDefaultOptions(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getDefaultOptions()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
ZipOptions::CHARSET => null,
|
ZipOptions::CHARSET => null,
|
||||||
@ -106,10 +106,8 @@ class ZipReader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
|
||||||
* @return ImmutableZipContainer
|
|
||||||
*/
|
*/
|
||||||
public function read()
|
public function read(): ImmutableZipContainer
|
||||||
{
|
{
|
||||||
if ($this->size < ZipConstants::END_CD_MIN_LEN) {
|
if ($this->size < ZipConstants::END_CD_MIN_LEN) {
|
||||||
throw new ZipException('Corrupt zip file');
|
throw new ZipException('Corrupt zip file');
|
||||||
@ -121,10 +119,7 @@ class ZipReader
|
|||||||
return new ImmutableZipContainer($entries, $endOfCentralDirectory->getComment());
|
return new ImmutableZipContainer($entries, $endOfCentralDirectory->getComment());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getStreamMetaData(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getStreamMetaData()
|
|
||||||
{
|
{
|
||||||
return stream_get_meta_data($this->inStream);
|
return stream_get_meta_data($this->inStream);
|
||||||
}
|
}
|
||||||
@ -148,10 +143,8 @@ class ZipReader
|
|||||||
* .ZIP file comment (variable size)
|
* .ZIP file comment (variable size)
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
|
||||||
* @return EndOfCentralDirectory
|
|
||||||
*/
|
*/
|
||||||
protected function readEndOfCentralDirectory()
|
protected function readEndOfCentralDirectory(): EndOfCentralDirectory
|
||||||
{
|
{
|
||||||
if (!$this->findEndOfCentralDirectory()) {
|
if (!$this->findEndOfCentralDirectory()) {
|
||||||
throw new ZipException('Invalid zip file. The end of the central directory could not be found.');
|
throw new ZipException('Invalid zip file. The end of the central directory could not be found.');
|
||||||
@ -161,26 +154,34 @@ class ZipReader
|
|||||||
$sizeECD = $this->size - ftell($this->inStream);
|
$sizeECD = $this->size - ftell($this->inStream);
|
||||||
$buffer = fread($this->inStream, $sizeECD);
|
$buffer = fread($this->inStream, $sizeECD);
|
||||||
|
|
||||||
$unpack = unpack(
|
[
|
||||||
'vdiskNo/vcdDiskNo/vcdEntriesDisk/' .
|
'diskNo' => $diskNo,
|
||||||
'vcdEntries/VcdSize/VcdPos/vcommentLength',
|
'cdDiskNo' => $cdDiskNo,
|
||||||
|
'cdEntriesDisk' => $cdEntriesDisk,
|
||||||
|
'cdEntries' => $cdEntries,
|
||||||
|
'cdSize' => $cdSize,
|
||||||
|
'cdPos' => $cdPos,
|
||||||
|
'commentLength' => $commentLength,
|
||||||
|
] = unpack(
|
||||||
|
'vdiskNo/vcdDiskNo/vcdEntriesDisk/'
|
||||||
|
. 'vcdEntries/VcdSize/VcdPos/vcommentLength',
|
||||||
substr($buffer, 0, 18)
|
substr($buffer, 0, 18)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$unpack['diskNo'] !== 0 ||
|
$diskNo !== 0
|
||||||
$unpack['cdDiskNo'] !== 0 ||
|
|| $cdDiskNo !== 0
|
||||||
$unpack['cdEntriesDisk'] !== $unpack['cdEntries']
|
|| $cdEntriesDisk !== $cdEntries
|
||||||
) {
|
) {
|
||||||
throw new ZipException(
|
throw new ZipException(
|
||||||
'ZIP file spanning/splitting is not supported!'
|
'ZIP file spanning/splitting is not supported!'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// .ZIP file comment (variable sizeECD)
|
|
||||||
$comment = null;
|
$comment = null;
|
||||||
|
|
||||||
if ($unpack['commentLength'] > 0) {
|
if ($commentLength > 0) {
|
||||||
$comment = substr($buffer, 18, $unpack['commentLength']);
|
// .ZIP file comment (variable sizeECD)
|
||||||
|
$comment = substr($buffer, 18, $commentLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for ZIP64 End Of Central Directory Locator exists.
|
// Check for ZIP64 End Of Central Directory Locator exists.
|
||||||
@ -188,10 +189,10 @@ class ZipReader
|
|||||||
fseek($this->inStream, $zip64ECDLocatorPosition);
|
fseek($this->inStream, $zip64ECDLocatorPosition);
|
||||||
// zip64 end of central dir locator
|
// zip64 end of central dir locator
|
||||||
// signature 4 bytes (0x07064b50)
|
// signature 4 bytes (0x07064b50)
|
||||||
if ($zip64ECDLocatorPosition > 0 && unpack(
|
if (
|
||||||
'V',
|
$zip64ECDLocatorPosition > 0
|
||||||
fread($this->inStream, 4)
|
&& unpack('V', fread($this->inStream, 4))[1] === ZipConstants::ZIP64_END_CD_LOC
|
||||||
)[1] === ZipConstants::ZIP64_END_CD_LOC) {
|
) {
|
||||||
if (!$this->isZip64Support()) {
|
if (!$this->isZip64Support()) {
|
||||||
throw new ZipException('ZIP64 not supported this archive.');
|
throw new ZipException('ZIP64 not supported this archive.');
|
||||||
}
|
}
|
||||||
@ -201,9 +202,9 @@ class ZipReader
|
|||||||
$endCentralDirectory->setComment($comment);
|
$endCentralDirectory->setComment($comment);
|
||||||
} else {
|
} else {
|
||||||
$endCentralDirectory = new EndOfCentralDirectory(
|
$endCentralDirectory = new EndOfCentralDirectory(
|
||||||
$unpack['cdEntries'],
|
$cdEntries,
|
||||||
$unpack['cdPos'],
|
$cdPos,
|
||||||
$unpack['cdSize'],
|
$cdSize,
|
||||||
false,
|
false,
|
||||||
$comment
|
$comment
|
||||||
);
|
);
|
||||||
@ -212,10 +213,7 @@ class ZipReader
|
|||||||
return $endCentralDirectory;
|
return $endCentralDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function findEndOfCentralDirectory(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function findEndOfCentralDirectory()
|
|
||||||
{
|
{
|
||||||
$max = $this->size - ZipConstants::END_CD_MIN_LEN;
|
$max = $this->size - ZipConstants::END_CD_MIN_LEN;
|
||||||
$min = $max >= 0xffff ? $max - 0xffff : 0;
|
$min = $max >= 0xffff ? $max - 0xffff : 0;
|
||||||
@ -248,11 +246,13 @@ class ZipReader
|
|||||||
*
|
*
|
||||||
* @return int Zip64 End Of Central Directory position
|
* @return int Zip64 End Of Central Directory position
|
||||||
*/
|
*/
|
||||||
protected function findZip64ECDPosition()
|
protected function findZip64ECDPosition(): int
|
||||||
{
|
{
|
||||||
$diskNo = unpack('V', fread($this->inStream, 4))[1];
|
[
|
||||||
$zip64ECDPos = PackUtil::unpackLongLE(fread($this->inStream, 8));
|
'diskNo' => $diskNo,
|
||||||
$totalDisks = unpack('V', fread($this->inStream, 4))[1];
|
'zip64ECDPos' => $zip64ECDPos,
|
||||||
|
'totalDisks' => $totalDisks,
|
||||||
|
] = unpack('VdiskNo/Pzip64ECDPos/VtotalDisks', fread($this->inStream, 16));
|
||||||
|
|
||||||
if ($diskNo !== 0 || $totalDisks > 1) {
|
if ($diskNo !== 0 || $totalDisks > 1) {
|
||||||
throw new ZipException('ZIP file spanning/splitting is not supported!');
|
throw new ZipException('ZIP file spanning/splitting is not supported!');
|
||||||
@ -284,13 +284,9 @@ class ZipReader
|
|||||||
* the starting disk number 8 bytes
|
* the starting disk number 8 bytes
|
||||||
* zip64 extensible data sector (variable size)
|
* zip64 extensible data sector (variable size)
|
||||||
*
|
*
|
||||||
* @param int $zip64ECDPosition
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
|
||||||
* @return EndOfCentralDirectory
|
|
||||||
*/
|
*/
|
||||||
protected function readZip64EndOfCentralDirectory($zip64ECDPosition)
|
protected function readZip64EndOfCentralDirectory(int $zip64ECDPosition): EndOfCentralDirectory
|
||||||
{
|
{
|
||||||
fseek($this->inStream, $zip64ECDPosition);
|
fseek($this->inStream, $zip64ECDPosition);
|
||||||
|
|
||||||
@ -300,21 +296,26 @@ class ZipReader
|
|||||||
throw new ZipException('Expected ZIP64 End Of Central Directory Record!');
|
throw new ZipException('Expected ZIP64 End Of Central Directory Record!');
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = unpack(
|
[
|
||||||
// 'Psize/vversionMadeBy/vextractVersion/' .
|
// 'size' => $size,
|
||||||
'VdiskNo/VcdDiskNo',
|
// 'versionMadeBy' => $versionMadeBy,
|
||||||
substr($buffer, 16, 8)
|
// 'extractVersion' => $extractVersion,
|
||||||
|
'diskNo' => $diskNo,
|
||||||
|
'cdDiskNo' => $cdDiskNo,
|
||||||
|
'cdEntriesDisk' => $cdEntriesDisk,
|
||||||
|
'entryCount' => $entryCount,
|
||||||
|
'cdSize' => $cdSize,
|
||||||
|
'cdPos' => $cdPos,
|
||||||
|
] = unpack(
|
||||||
|
// 'Psize/vversionMadeBy/vextractVersion/'.
|
||||||
|
'VdiskNo/VcdDiskNo/PcdEntriesDisk/PentryCount/PcdSize/PcdPos',
|
||||||
|
substr($buffer, 16, 40)
|
||||||
);
|
);
|
||||||
|
|
||||||
$cdEntriesDisk = PackUtil::unpackLongLE(substr($buffer, 24, 8));
|
// $platform = ZipPlatform::fromValue(($versionMadeBy & 0xFF00) >> 8);
|
||||||
$entryCount = PackUtil::unpackLongLE(substr($buffer, 32, 8));
|
// $softwareVersion = $versionMadeBy & 0x00FF;
|
||||||
$cdSize = PackUtil::unpackLongLE(substr($buffer, 40, 8));
|
|
||||||
$cdPos = PackUtil::unpackLongLE(substr($buffer, 48, 8));
|
|
||||||
|
|
||||||
// $platform = ZipPlatform::fromValue(($data['versionMadeBy'] & 0xFF00) >> 8);
|
if ($diskNo !== 0 || $cdDiskNo !== 0 || $entryCount !== $cdEntriesDisk) {
|
||||||
// $softwareVersion = $data['versionMadeBy'] & 0x00FF;
|
|
||||||
|
|
||||||
if ($data['diskNo'] !== 0 || $data['cdDiskNo'] !== 0 || $entryCount !== $cdEntriesDisk) {
|
|
||||||
throw new ZipException('ZIP file spanning/splitting is not supported!');
|
throw new ZipException('ZIP file spanning/splitting is not supported!');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,13 +341,11 @@ class ZipReader
|
|||||||
* central directory alone, but not the data that requires the local
|
* central directory alone, but not the data that requires the local
|
||||||
* file header or additional data to be read.
|
* file header or additional data to be read.
|
||||||
*
|
*
|
||||||
* @param EndOfCentralDirectory $endCD
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
*
|
||||||
* @return ZipEntry[]
|
* @return ZipEntry[]
|
||||||
*/
|
*/
|
||||||
protected function readCentralDirectory(EndOfCentralDirectory $endCD)
|
protected function readCentralDirectory(EndOfCentralDirectory $endCD): array
|
||||||
{
|
{
|
||||||
$entries = [];
|
$entries = [];
|
||||||
|
|
||||||
@ -375,8 +374,8 @@ class ZipReader
|
|||||||
$unicodePath = str_replace('\\', '/', $unicodePath);
|
$unicodePath = str_replace('\\', '/', $unicodePath);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$unicodePath !== '' &&
|
$unicodePath !== ''
|
||||||
substr_count($entryName, '/') === substr_count($unicodePath, '/')
|
&& substr_count($entryName, '/') === substr_count($unicodePath, '/')
|
||||||
) {
|
) {
|
||||||
$entryName = $unicodePath;
|
$entryName = $unicodePath;
|
||||||
}
|
}
|
||||||
@ -417,46 +416,56 @@ class ZipReader
|
|||||||
* @param resource $stream
|
* @param resource $stream
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
|
||||||
* @return ZipEntry
|
|
||||||
*/
|
*/
|
||||||
protected function readZipEntry($stream)
|
protected function readZipEntry($stream): ZipEntry
|
||||||
{
|
{
|
||||||
if (unpack('V', fread($stream, 4))[1] !== ZipConstants::CENTRAL_FILE_HEADER) {
|
if (unpack('V', fread($stream, 4))[1] !== ZipConstants::CENTRAL_FILE_HEADER) {
|
||||||
throw new ZipException('Corrupt zip file. Cannot read zip entry.');
|
throw new ZipException('Corrupt zip file. Cannot read zip entry.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$unpack = unpack(
|
[
|
||||||
'vversionMadeBy/vversionNeededToExtract/' .
|
'versionMadeBy' => $versionMadeBy,
|
||||||
'vgeneralPurposeBitFlag/vcompressionMethod/' .
|
'versionNeededToExtract' => $versionNeededToExtract,
|
||||||
'VlastModFile/Vcrc/VcompressedSize/' .
|
'generalPurposeBitFlags' => $generalPurposeBitFlags,
|
||||||
'VuncompressedSize/vfileNameLength/vextraFieldLength/' .
|
'compressionMethod' => $compressionMethod,
|
||||||
'vfileCommentLength/vdiskNumberStart/vinternalFileAttributes/' .
|
'lastModFile' => $dosTime,
|
||||||
'VexternalFileAttributes/VoffsetLocalHeader',
|
'crc' => $crc,
|
||||||
|
'compressedSize' => $compressedSize,
|
||||||
|
'uncompressedSize' => $uncompressedSize,
|
||||||
|
'fileNameLength' => $fileNameLength,
|
||||||
|
'extraFieldLength' => $extraFieldLength,
|
||||||
|
'fileCommentLength' => $fileCommentLength,
|
||||||
|
'diskNumberStart' => $diskNumberStart,
|
||||||
|
'internalFileAttributes' => $internalFileAttributes,
|
||||||
|
'externalFileAttributes' => $externalFileAttributes,
|
||||||
|
'offsetLocalHeader' => $offsetLocalHeader,
|
||||||
|
] = unpack(
|
||||||
|
'vversionMadeBy/vversionNeededToExtract/'
|
||||||
|
. 'vgeneralPurposeBitFlags/vcompressionMethod/'
|
||||||
|
. 'VlastModFile/Vcrc/VcompressedSize/'
|
||||||
|
. 'VuncompressedSize/vfileNameLength/vextraFieldLength/'
|
||||||
|
. 'vfileCommentLength/vdiskNumberStart/vinternalFileAttributes/'
|
||||||
|
. 'VexternalFileAttributes/VoffsetLocalHeader',
|
||||||
fread($stream, 42)
|
fread($stream, 42)
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($unpack['diskNumberStart'] !== 0) {
|
if ($diskNumberStart !== 0) {
|
||||||
throw new ZipException('ZIP file spanning/splitting is not supported!');
|
throw new ZipException('ZIP file spanning/splitting is not supported!');
|
||||||
}
|
}
|
||||||
|
|
||||||
$generalPurposeBitFlags = $unpack['generalPurposeBitFlag'];
|
|
||||||
$isUtf8 = ($generalPurposeBitFlags & GeneralPurposeBitFlag::UTF8) !== 0;
|
$isUtf8 = ($generalPurposeBitFlags & GeneralPurposeBitFlag::UTF8) !== 0;
|
||||||
|
|
||||||
$name = fread($stream, $unpack['fileNameLength']);
|
$name = fread($stream, $fileNameLength);
|
||||||
|
|
||||||
$createdOS = ($unpack['versionMadeBy'] & 0xFF00) >> 8;
|
$createdOS = ($versionMadeBy & 0xFF00) >> 8;
|
||||||
$softwareVersion = $unpack['versionMadeBy'] & 0x00FF;
|
$softwareVersion = $versionMadeBy & 0x00FF;
|
||||||
|
|
||||||
$extractedOS = ($unpack['versionNeededToExtract'] & 0xFF00) >> 8;
|
|
||||||
$extractVersion = $unpack['versionNeededToExtract'] & 0x00FF;
|
|
||||||
|
|
||||||
$dosTime = $unpack['lastModFile'];
|
|
||||||
|
|
||||||
|
$extractedOS = ($versionNeededToExtract & 0xFF00) >> 8;
|
||||||
|
$extractVersion = $versionNeededToExtract & 0x00FF;
|
||||||
$comment = null;
|
$comment = null;
|
||||||
|
|
||||||
if ($unpack['fileCommentLength'] > 0) {
|
if ($fileCommentLength > 0) {
|
||||||
$comment = fread($stream, $unpack['fileCommentLength']);
|
$comment = fread($stream, $fileCommentLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode code page names
|
// decode code page names
|
||||||
@ -479,24 +488,23 @@ class ZipReader
|
|||||||
$extractedOS,
|
$extractedOS,
|
||||||
$softwareVersion,
|
$softwareVersion,
|
||||||
$extractVersion,
|
$extractVersion,
|
||||||
$unpack['compressionMethod'],
|
$compressionMethod,
|
||||||
$generalPurposeBitFlags,
|
$generalPurposeBitFlags,
|
||||||
$dosTime,
|
$dosTime,
|
||||||
$unpack['crc'],
|
$crc,
|
||||||
$unpack['compressedSize'],
|
$compressedSize,
|
||||||
$unpack['uncompressedSize'],
|
$uncompressedSize,
|
||||||
$unpack['internalFileAttributes'],
|
$internalFileAttributes,
|
||||||
$unpack['externalFileAttributes'],
|
$externalFileAttributes,
|
||||||
$unpack['offsetLocalHeader'],
|
$offsetLocalHeader,
|
||||||
$comment,
|
$comment,
|
||||||
$fallbackCharset
|
$fallbackCharset
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($unpack['extraFieldLength'] > 0) {
|
if ($extraFieldLength > 0) {
|
||||||
$this->parseExtraFields(
|
$this->parseExtraFields(
|
||||||
fread($stream, $unpack['extraFieldLength']),
|
fread($stream, $extraFieldLength),
|
||||||
$zipEntry,
|
$zipEntry
|
||||||
false
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/** @var Zip64ExtraField|null $extraZip64 */
|
/** @var Zip64ExtraField|null $extraZip64 */
|
||||||
@ -514,33 +522,27 @@ class ZipReader
|
|||||||
return $zipEntry;
|
return $zipEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function parseExtraFields(string $buffer, ZipEntry $zipEntry, bool $local = false): ExtraFieldsCollection
|
||||||
* @param string $buffer
|
|
||||||
* @param ZipEntry $zipEntry
|
|
||||||
* @param bool $local
|
|
||||||
*
|
|
||||||
* @return ExtraFieldsCollection
|
|
||||||
*/
|
|
||||||
protected function parseExtraFields($buffer, ZipEntry $zipEntry, $local = false)
|
|
||||||
{
|
{
|
||||||
$collection = $local ?
|
$collection = $local
|
||||||
$zipEntry->getLocalExtraFields() :
|
? $zipEntry->getLocalExtraFields()
|
||||||
$zipEntry->getCdExtraFields();
|
: $zipEntry->getCdExtraFields();
|
||||||
|
|
||||||
if (!empty($buffer)) {
|
if (!empty($buffer)) {
|
||||||
$pos = 0;
|
$pos = 0;
|
||||||
$endPos = \strlen($buffer);
|
$endPos = \strlen($buffer);
|
||||||
|
|
||||||
while ($endPos - $pos >= 4) {
|
while ($endPos - $pos >= 4) {
|
||||||
/** @var int[] $data */
|
[
|
||||||
$data = unpack('vheaderId/vdataSize', substr($buffer, $pos, 4));
|
'headerId' => $headerId,
|
||||||
|
'dataSize' => $dataSize,
|
||||||
|
] = unpack('vheaderId/vdataSize', substr($buffer, $pos, 4));
|
||||||
$pos += 4;
|
$pos += 4;
|
||||||
|
|
||||||
if ($endPos - $pos - $data['dataSize'] < 0) {
|
if ($endPos - $pos - $dataSize < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$bufferData = substr($buffer, $pos, $data['dataSize']);
|
$bufferData = substr($buffer, $pos, $dataSize);
|
||||||
$headerId = $data['headerId'];
|
|
||||||
|
|
||||||
/** @var string|ZipExtraField|null $className */
|
/** @var string|ZipExtraField|null $className */
|
||||||
$className = ZipExtraDriver::getClassNameOrNull($headerId);
|
$className = ZipExtraDriver::getClassNameOrNull($headerId);
|
||||||
@ -548,9 +550,9 @@ class ZipReader
|
|||||||
try {
|
try {
|
||||||
if ($className !== null) {
|
if ($className !== null) {
|
||||||
try {
|
try {
|
||||||
$extraField = $local ?
|
$extraField = $local
|
||||||
\call_user_func([$className, 'unpackLocalFileData'], $bufferData, $zipEntry) :
|
? $className::unpackLocalFileData($bufferData, $zipEntry)
|
||||||
\call_user_func([$className, 'unpackCentralDirData'], $bufferData, $zipEntry);
|
: $className::unpackCentralDirData($bufferData, $zipEntry);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
// skip errors while parsing invalid data
|
// skip errors while parsing invalid data
|
||||||
continue;
|
continue;
|
||||||
@ -560,7 +562,7 @@ class ZipReader
|
|||||||
}
|
}
|
||||||
$collection->add($extraField);
|
$collection->add($extraField);
|
||||||
} finally {
|
} finally {
|
||||||
$pos += $data['dataSize'];
|
$pos += $dataSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -568,11 +570,7 @@ class ZipReader
|
|||||||
return $collection;
|
return $collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function handleZip64Extra(Zip64ExtraField $extraZip64, ZipEntry $zipEntry): void
|
||||||
* @param Zip64ExtraField $extraZip64
|
|
||||||
* @param ZipEntry $zipEntry
|
|
||||||
*/
|
|
||||||
protected function handleZip64Extra(Zip64ExtraField $extraZip64, ZipEntry $zipEntry)
|
|
||||||
{
|
{
|
||||||
$uncompressedSize = $extraZip64->getUncompressedSize();
|
$uncompressedSize = $extraZip64->getUncompressedSize();
|
||||||
$compressedSize = $extraZip64->getCompressedSize();
|
$compressedSize = $extraZip64->getCompressedSize();
|
||||||
@ -608,11 +606,9 @@ class ZipReader
|
|||||||
* file name (variable size)
|
* file name (variable size)
|
||||||
* extra field (variable size)
|
* extra field (variable size)
|
||||||
*
|
*
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
protected function loadLocalExtraFields(ZipEntry $entry)
|
protected function loadLocalExtraFields(ZipEntry $entry): void
|
||||||
{
|
{
|
||||||
$offsetLocalHeader = $entry->getLocalHeaderOffset();
|
$offsetLocalHeader = $entry->getLocalHeaderOffset();
|
||||||
|
|
||||||
@ -623,16 +619,16 @@ class ZipReader
|
|||||||
}
|
}
|
||||||
|
|
||||||
fseek($this->inStream, $offsetLocalHeader + ZipConstants::LFH_FILENAME_LENGTH_POS);
|
fseek($this->inStream, $offsetLocalHeader + ZipConstants::LFH_FILENAME_LENGTH_POS);
|
||||||
$unpack = unpack('vfileNameLength/vextraFieldLength', fread($this->inStream, 4));
|
[
|
||||||
$offsetData = ftell($this->inStream)
|
'fileNameLength' => $fileNameLength,
|
||||||
+ $unpack['fileNameLength']
|
'extraFieldLength' => $extraFieldLength,
|
||||||
+ $unpack['extraFieldLength'];
|
] = unpack('vfileNameLength/vextraFieldLength', fread($this->inStream, 4));
|
||||||
|
$offsetData = ftell($this->inStream) + $fileNameLength + $extraFieldLength;
|
||||||
|
fseek($this->inStream, $fileNameLength, \SEEK_CUR);
|
||||||
|
|
||||||
fseek($this->inStream, $unpack['fileNameLength'], \SEEK_CUR);
|
if ($extraFieldLength > 0) {
|
||||||
|
|
||||||
if ($unpack['extraFieldLength'] > 0) {
|
|
||||||
$this->parseExtraFields(
|
$this->parseExtraFields(
|
||||||
fread($this->inStream, $unpack['extraFieldLength']),
|
fread($this->inStream, $extraFieldLength),
|
||||||
$entry,
|
$entry,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@ -643,11 +639,9 @@ class ZipReader
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ZipEntry $zipEntry
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
private function handleExtraEncryptionFields(ZipEntry $zipEntry)
|
private function handleExtraEncryptionFields(ZipEntry $zipEntry): void
|
||||||
{
|
{
|
||||||
if ($zipEntry->isEncrypted()) {
|
if ($zipEntry->isEncrypted()) {
|
||||||
if ($zipEntry->getCompressionMethod() === ZipCompressionMethod::WINZIP_AES) {
|
if ($zipEntry->getCompressionMethod() === ZipCompressionMethod::WINZIP_AES) {
|
||||||
@ -676,16 +670,12 @@ class ZipReader
|
|||||||
*
|
*
|
||||||
* This is a special method in which you can process ExtraField
|
* This is a special method in which you can process ExtraField
|
||||||
* and make changes to ZipEntry.
|
* and make changes to ZipEntry.
|
||||||
*
|
|
||||||
* @param ZipEntry $zipEntry
|
|
||||||
*/
|
*/
|
||||||
protected function handleExtraFields(ZipEntry $zipEntry)
|
protected function handleExtraFields(ZipEntry $zipEntry): void
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ZipSourceFileData $zipFileData
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
* @throws Crc32Exception
|
* @throws Crc32Exception
|
||||||
*
|
*
|
||||||
@ -701,13 +691,12 @@ class ZipReader
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ZipSourceFileData $zipFileData
|
* @param resource $outStream
|
||||||
* @param resource $outStream
|
|
||||||
*
|
*
|
||||||
* @throws Crc32Exception
|
* @throws Crc32Exception
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function copyUncompressedDataToStream(ZipSourceFileData $zipFileData, $outStream)
|
public function copyUncompressedDataToStream(ZipSourceFileData $zipFileData, $outStream): void
|
||||||
{
|
{
|
||||||
if (!\is_resource($outStream)) {
|
if (!\is_resource($outStream)) {
|
||||||
throw new InvalidArgumentException('outStream is not resource');
|
throw new InvalidArgumentException('outStream is not resource');
|
||||||
@ -865,10 +854,9 @@ class ZipReader
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ZipSourceFileData $zipData
|
* @param resource $outStream
|
||||||
* @param resource $outStream
|
|
||||||
*/
|
*/
|
||||||
public function copyCompressedDataToStream(ZipSourceFileData $zipData, $outStream)
|
public function copyCompressedDataToStream(ZipSourceFileData $zipData, $outStream): void
|
||||||
{
|
{
|
||||||
if ($zipData->getCompressedSize() > 0) {
|
if ($zipData->getCompressedSize() > 0) {
|
||||||
fseek($this->inStream, $zipData->getOffset());
|
fseek($this->inStream, $zipData->getOffset());
|
||||||
@ -876,15 +864,12 @@ class ZipReader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function isZip64Support(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function isZip64Support()
|
|
||||||
{
|
{
|
||||||
return \PHP_INT_SIZE === 8; // true for 64bit system
|
return \PHP_INT_SIZE === 8; // true for 64bit system
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close()
|
public function close(): void
|
||||||
{
|
{
|
||||||
if (\is_resource($this->inStream)) {
|
if (\is_resource($this->inStream)) {
|
||||||
fclose($this->inStream);
|
fclose($this->inStream);
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\IO;
|
namespace PhpZip\IO;
|
||||||
|
|
||||||
use PhpZip\Constants\DosCodePage;
|
use PhpZip\Constants\DosCodePage;
|
||||||
@ -13,30 +22,18 @@ use PhpZip\Exception\ZipUnsupportMethodException;
|
|||||||
use PhpZip\IO\Filter\Cipher\Pkware\PKEncryptionStreamFilter;
|
use PhpZip\IO\Filter\Cipher\Pkware\PKEncryptionStreamFilter;
|
||||||
use PhpZip\IO\Filter\Cipher\WinZipAes\WinZipAesEncryptionStreamFilter;
|
use PhpZip\IO\Filter\Cipher\WinZipAes\WinZipAesEncryptionStreamFilter;
|
||||||
use PhpZip\Model\Data\ZipSourceFileData;
|
use PhpZip\Model\Data\ZipSourceFileData;
|
||||||
use PhpZip\Model\Extra\Fields\ApkAlignmentExtraField;
|
|
||||||
use PhpZip\Model\Extra\Fields\WinZipAesExtraField;
|
use PhpZip\Model\Extra\Fields\WinZipAesExtraField;
|
||||||
use PhpZip\Model\Extra\Fields\Zip64ExtraField;
|
use PhpZip\Model\Extra\Fields\Zip64ExtraField;
|
||||||
use PhpZip\Model\ZipContainer;
|
use PhpZip\Model\ZipContainer;
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
use PhpZip\Util\PackUtil;
|
|
||||||
use PhpZip\Util\StringUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipWriter.
|
|
||||||
*/
|
|
||||||
class ZipWriter
|
class ZipWriter
|
||||||
{
|
{
|
||||||
/** @var int Chunk read size */
|
/** @var int Chunk read size */
|
||||||
const CHUNK_SIZE = 8192;
|
public const CHUNK_SIZE = 8192;
|
||||||
|
|
||||||
/** @var ZipContainer */
|
protected ZipContainer $zipContainer;
|
||||||
protected $zipContainer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZipWriter constructor.
|
|
||||||
*
|
|
||||||
* @param ZipContainer $container
|
|
||||||
*/
|
|
||||||
public function __construct(ZipContainer $container)
|
public function __construct(ZipContainer $container)
|
||||||
{
|
{
|
||||||
// we clone the container so that the changes made to
|
// we clone the container so that the changes made to
|
||||||
@ -49,7 +46,7 @@ class ZipWriter
|
|||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function write($outStream)
|
public function write($outStream): void
|
||||||
{
|
{
|
||||||
if (!\is_resource($outStream)) {
|
if (!\is_resource($outStream)) {
|
||||||
throw new \InvalidArgumentException('$outStream must be resource');
|
throw new \InvalidArgumentException('$outStream must be resource');
|
||||||
@ -62,7 +59,7 @@ class ZipWriter
|
|||||||
$this->writeEndOfCentralDirectoryBlock($outStream, $cdOffset, $cdSize);
|
$this->writeEndOfCentralDirectoryBlock($outStream, $cdOffset, $cdSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function beforeWrite()
|
protected function beforeWrite(): void
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +68,7 @@ class ZipWriter
|
|||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
protected function writeLocalBlock($outStream)
|
protected function writeLocalBlock($outStream): void
|
||||||
{
|
{
|
||||||
$zipEntries = $this->zipContainer->getEntries();
|
$zipEntries = $this->zipContainer->getEntries();
|
||||||
|
|
||||||
@ -87,17 +84,11 @@ class ZipWriter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $outStream
|
* @param resource $outStream
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
protected function writeLocalHeader($outStream, ZipEntry $entry)
|
protected function writeLocalHeader($outStream, ZipEntry $entry): void
|
||||||
{
|
{
|
||||||
// todo in 4.0 version move zipalign functional to ApkWriter class
|
|
||||||
if ($this->zipContainer->isZipAlign()) {
|
|
||||||
$this->zipAlign($outStream, $entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
$relativeOffset = ftell($outStream);
|
$relativeOffset = ftell($outStream);
|
||||||
$entry->setLocalHeaderOffset($relativeOffset);
|
$entry->setLocalHeaderOffset($relativeOffset);
|
||||||
|
|
||||||
@ -105,8 +96,8 @@ class ZipWriter
|
|||||||
$entry->enableDataDescriptor(true);
|
$entry->enableDataDescriptor(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dd = $entry->isDataDescriptorRequired() ||
|
$dd = $entry->isDataDescriptorRequired()
|
||||||
$entry->isDataDescriptorEnabled();
|
|| $entry->isDataDescriptorEnabled();
|
||||||
|
|
||||||
$compressedSize = $entry->getCompressedSize();
|
$compressedSize = $entry->getCompressedSize();
|
||||||
$uncompressedSize = $entry->getUncompressedSize();
|
$uncompressedSize = $entry->getUncompressedSize();
|
||||||
@ -202,75 +193,16 @@ class ZipWriter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param resource $outStream
|
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*/
|
|
||||||
private function zipAlign($outStream, ZipEntry $entry)
|
|
||||||
{
|
|
||||||
if (!$entry->isDirectory() && $entry->getCompressionMethod() === ZipCompressionMethod::STORED) {
|
|
||||||
$entry->removeExtraField(ApkAlignmentExtraField::HEADER_ID);
|
|
||||||
|
|
||||||
$extra = $this->getExtraFieldsContents($entry, true);
|
|
||||||
$extraLength = \strlen($extra);
|
|
||||||
$name = $entry->getName();
|
|
||||||
|
|
||||||
$dosCharset = $entry->getCharset();
|
|
||||||
|
|
||||||
if ($dosCharset !== null && !$entry->isUtf8Flag()) {
|
|
||||||
$name = DosCodePage::fromUTF8($name, $dosCharset);
|
|
||||||
}
|
|
||||||
$nameLength = \strlen($name);
|
|
||||||
|
|
||||||
$multiple = ApkAlignmentExtraField::ALIGNMENT_BYTES;
|
|
||||||
|
|
||||||
if (StringUtil::endsWith($name, '.so')) {
|
|
||||||
$multiple = ApkAlignmentExtraField::COMMON_PAGE_ALIGNMENT_BYTES;
|
|
||||||
}
|
|
||||||
|
|
||||||
$offset = ftell($outStream);
|
|
||||||
|
|
||||||
$dataMinStartOffset =
|
|
||||||
$offset +
|
|
||||||
ZipConstants::LFH_FILENAME_POS +
|
|
||||||
$extraLength +
|
|
||||||
$nameLength;
|
|
||||||
|
|
||||||
$padding =
|
|
||||||
($multiple - ($dataMinStartOffset % $multiple))
|
|
||||||
% $multiple;
|
|
||||||
|
|
||||||
if ($padding > 0) {
|
|
||||||
$dataMinStartOffset += ApkAlignmentExtraField::MIN_SIZE;
|
|
||||||
$padding =
|
|
||||||
($multiple - ($dataMinStartOffset % $multiple))
|
|
||||||
% $multiple;
|
|
||||||
|
|
||||||
$entry->getLocalExtraFields()->add(
|
|
||||||
new ApkAlignmentExtraField($multiple, $padding)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges the local file data fields of the given ZipExtraFields.
|
* Merges the local file data fields of the given ZipExtraFields.
|
||||||
*
|
*
|
||||||
* @param ZipEntry $entry
|
|
||||||
* @param bool $local
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function getExtraFieldsContents(ZipEntry $entry, $local)
|
protected function getExtraFieldsContents(ZipEntry $entry, bool $local): string
|
||||||
{
|
{
|
||||||
$local = (bool) $local;
|
$collection = $local
|
||||||
$collection = $local ?
|
? $entry->getLocalExtraFields()
|
||||||
$entry->getLocalExtraFields() :
|
: $entry->getCdExtraFields();
|
||||||
$entry->getCdExtraFields();
|
|
||||||
$extraData = '';
|
$extraData = '';
|
||||||
|
|
||||||
foreach ($collection as $extraField) {
|
foreach ($collection as $extraField) {
|
||||||
@ -304,11 +236,10 @@ class ZipWriter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $outStream
|
* @param resource $outStream
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
protected function writeData($outStream, ZipEntry $entry)
|
protected function writeData($outStream, ZipEntry $entry): void
|
||||||
{
|
{
|
||||||
$zipData = $entry->getData();
|
$zipData = $entry->getData();
|
||||||
|
|
||||||
@ -449,11 +380,8 @@ class ZipWriter
|
|||||||
/**
|
/**
|
||||||
* @param resource $inStream
|
* @param resource $inStream
|
||||||
* @param resource $outStream
|
* @param resource $outStream
|
||||||
* @param int $size
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
private function writeAndCountChecksum($inStream, $outStream, $size)
|
private function writeAndCountChecksum($inStream, $outStream, int $size): int
|
||||||
{
|
{
|
||||||
$contextHash = hash_init('crc32b');
|
$contextHash = hash_init('crc32b');
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
@ -471,7 +399,6 @@ class ZipWriter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $outStream
|
* @param resource $outStream
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
*
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*
|
*
|
||||||
@ -523,12 +450,10 @@ class ZipWriter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $outStream
|
* @param resource $outStream
|
||||||
* @param ZipEntry $entry
|
|
||||||
* @param int $size
|
|
||||||
*
|
*
|
||||||
* @return resource|null
|
* @return resource|null
|
||||||
*/
|
*/
|
||||||
protected function appendEncryptionFilter($outStream, ZipEntry $entry, $size)
|
protected function appendEncryptionFilter($outStream, ZipEntry $entry, int $size)
|
||||||
{
|
{
|
||||||
$encContextFilter = null;
|
$encContextFilter = null;
|
||||||
|
|
||||||
@ -560,9 +485,8 @@ class ZipWriter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $outStream
|
* @param resource $outStream
|
||||||
* @param ZipEntry $entry
|
|
||||||
*/
|
*/
|
||||||
protected function writeDataDescriptor($outStream, ZipEntry $entry)
|
protected function writeDataDescriptor($outStream, ZipEntry $entry): void
|
||||||
{
|
{
|
||||||
$crc = $entry->getCrc();
|
$crc = $entry->getCrc();
|
||||||
|
|
||||||
@ -585,14 +509,16 @@ class ZipWriter
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$entry->isZip64ExtensionsRequired() ||
|
$entry->isZip64ExtensionsRequired()
|
||||||
$entry->getLocalExtraFields()->has(Zip64ExtraField::HEADER_ID)
|
|| $entry->getLocalExtraFields()->has(Zip64ExtraField::HEADER_ID)
|
||||||
) {
|
) {
|
||||||
$dd =
|
$dd = pack(
|
||||||
|
'PP',
|
||||||
// compressed size 8 bytes
|
// compressed size 8 bytes
|
||||||
PackUtil::packLongLE($entry->getCompressedSize()) .
|
$entry->getCompressedSize(),
|
||||||
// uncompressed size 8 bytes
|
// uncompressed size 8 bytes
|
||||||
PackUtil::packLongLE($entry->getUncompressedSize());
|
$entry->getUncompressedSize()
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
$dd = pack(
|
$dd = pack(
|
||||||
'VV',
|
'VV',
|
||||||
@ -611,7 +537,7 @@ class ZipWriter
|
|||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
protected function writeCentralDirectoryBlock($outStream)
|
protected function writeCentralDirectoryBlock($outStream): void
|
||||||
{
|
{
|
||||||
foreach ($this->zipContainer->getEntries() as $outputEntry) {
|
foreach ($this->zipContainer->getEntries() as $outputEntry) {
|
||||||
$this->writeCentralDirectoryHeader($outStream, $outputEntry);
|
$this->writeCentralDirectoryHeader($outStream, $outputEntry);
|
||||||
@ -622,11 +548,10 @@ class ZipWriter
|
|||||||
* Writes a Central File Header record.
|
* Writes a Central File Header record.
|
||||||
*
|
*
|
||||||
* @param resource $outStream
|
* @param resource $outStream
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
protected function writeCentralDirectoryHeader($outStream, ZipEntry $entry)
|
protected function writeCentralDirectoryHeader($outStream, ZipEntry $entry): void
|
||||||
{
|
{
|
||||||
$compressedSize = $entry->getCompressedSize();
|
$compressedSize = $entry->getCompressedSize();
|
||||||
$uncompressedSize = $entry->getUncompressedSize();
|
$uncompressedSize = $entry->getUncompressedSize();
|
||||||
@ -635,9 +560,9 @@ class ZipWriter
|
|||||||
$entry->getCdExtraFields()->remove(Zip64ExtraField::HEADER_ID);
|
$entry->getCdExtraFields()->remove(Zip64ExtraField::HEADER_ID);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$localHeaderOffset > ZipConstants::ZIP64_MAGIC ||
|
$localHeaderOffset > ZipConstants::ZIP64_MAGIC
|
||||||
$compressedSize > ZipConstants::ZIP64_MAGIC ||
|
|| $compressedSize > ZipConstants::ZIP64_MAGIC
|
||||||
$uncompressedSize > ZipConstants::ZIP64_MAGIC
|
|| $uncompressedSize > ZipConstants::ZIP64_MAGIC
|
||||||
) {
|
) {
|
||||||
$zip64ExtraField = new Zip64ExtraField();
|
$zip64ExtraField = new Zip64ExtraField();
|
||||||
|
|
||||||
@ -745,14 +670,12 @@ class ZipWriter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $outStream
|
* @param resource $outStream
|
||||||
* @param int $centralDirectoryOffset
|
|
||||||
* @param int $centralDirectorySize
|
|
||||||
*/
|
*/
|
||||||
protected function writeEndOfCentralDirectoryBlock(
|
protected function writeEndOfCentralDirectoryBlock(
|
||||||
$outStream,
|
$outStream,
|
||||||
$centralDirectoryOffset,
|
int $centralDirectoryOffset,
|
||||||
$centralDirectorySize
|
int $centralDirectorySize
|
||||||
) {
|
): void {
|
||||||
$cdEntriesCount = \count($this->zipContainer);
|
$cdEntriesCount = \count($this->zipContainer);
|
||||||
|
|
||||||
$cdEntriesZip64 = $cdEntriesCount > 0xffff;
|
$cdEntriesZip64 = $cdEntriesCount > 0xffff;
|
||||||
@ -767,7 +690,7 @@ class ZipWriter
|
|||||||
$zip64EndOfCentralDirectoryOffset = ftell($outStream);
|
$zip64EndOfCentralDirectoryOffset = ftell($outStream);
|
||||||
|
|
||||||
// find max software version, version needed to extract and most common platform
|
// find max software version, version needed to extract and most common platform
|
||||||
list($softwareVersion, $versionNeededToExtract) = array_reduce(
|
[$softwareVersion, $versionNeededToExtract] = array_reduce(
|
||||||
$this->zipContainer->getEntries(),
|
$this->zipContainer->getEntries(),
|
||||||
static function (array $carry, ZipEntry $entry) {
|
static function (array $carry, ZipEntry $entry) {
|
||||||
$carry[0] = max($carry[0], $entry->getSoftwareVersion() & 0xFF);
|
$carry[0] = max($carry[0], $entry->getSoftwareVersion() & 0xFF);
|
||||||
@ -786,18 +709,12 @@ class ZipWriter
|
|||||||
fwrite(
|
fwrite(
|
||||||
$outStream,
|
$outStream,
|
||||||
pack(
|
pack(
|
||||||
'V',
|
'VPvvVVPPPPVVPV',
|
||||||
// signature 4 bytes (0x06064b50)
|
// signature 4 bytes (0x06064b50)
|
||||||
ZipConstants::ZIP64_END_CD
|
ZipConstants::ZIP64_END_CD,
|
||||||
)
|
// size of zip64 end of central
|
||||||
);
|
// directory record 8 bytes
|
||||||
// size of zip64 end of central
|
ZipConstants::ZIP64_END_OF_CD_LEN - 12,
|
||||||
// directory record 8 bytes
|
|
||||||
fwrite($outStream, PackUtil::packLongLE(ZipConstants::ZIP64_END_OF_CD_LEN - 12));
|
|
||||||
fwrite(
|
|
||||||
$outStream,
|
|
||||||
pack(
|
|
||||||
'vvVV',
|
|
||||||
// version made by 2 bytes
|
// version made by 2 bytes
|
||||||
$versionMadeBy & 0xFFFF,
|
$versionMadeBy & 0xFFFF,
|
||||||
// version needed to extract 2 bytes
|
// version needed to extract 2 bytes
|
||||||
@ -806,44 +723,32 @@ class ZipWriter
|
|||||||
0,
|
0,
|
||||||
// number of the disk with the
|
// number of the disk with the
|
||||||
// start of the central directory 4 bytes
|
// start of the central directory 4 bytes
|
||||||
0
|
0,
|
||||||
)
|
// total number of entries in the
|
||||||
);
|
// central directory on this disk 8 bytes
|
||||||
|
$cdEntriesCount,
|
||||||
fwrite(
|
// total number of entries in the
|
||||||
$outStream,
|
// central directory 8 bytes
|
||||||
// total number of entries in the
|
$cdEntriesCount,
|
||||||
// central directory on this disk 8 bytes
|
// size of the central directory 8 bytes
|
||||||
PackUtil::packLongLE($cdEntriesCount) .
|
$centralDirectorySize,
|
||||||
// total number of entries in the
|
// offset of start of central
|
||||||
// central directory 8 bytes
|
// directory with respect to
|
||||||
PackUtil::packLongLE($cdEntriesCount) .
|
// the starting disk number 8 bytes
|
||||||
// size of the central directory 8 bytes
|
$centralDirectoryOffset,
|
||||||
PackUtil::packLongLE($centralDirectorySize) .
|
|
||||||
// offset of start of central
|
|
||||||
// directory with respect to
|
|
||||||
// the starting disk number 8 bytes
|
|
||||||
PackUtil::packLongLE($centralDirectoryOffset)
|
|
||||||
);
|
|
||||||
|
|
||||||
// write zip64 end of central directory locator
|
|
||||||
fwrite(
|
|
||||||
$outStream,
|
|
||||||
pack(
|
|
||||||
'VV',
|
|
||||||
// zip64 end of central dir locator
|
// zip64 end of central dir locator
|
||||||
// signature 4 bytes (0x07064b50)
|
// signature 4 bytes (0x07064b50)
|
||||||
ZipConstants::ZIP64_END_CD_LOC,
|
ZipConstants::ZIP64_END_CD_LOC,
|
||||||
// number of the disk with the
|
// number of the disk with the
|
||||||
// start of the zip64 end of
|
// start of the zip64 end of
|
||||||
// central directory 4 bytes
|
// central directory 4 bytes
|
||||||
0
|
0,
|
||||||
) .
|
// relative offset of the zip64
|
||||||
// relative offset of the zip64
|
// end of central directory record 8 bytes
|
||||||
// end of central directory record 8 bytes
|
$zip64EndOfCentralDirectoryOffset,
|
||||||
PackUtil::packLongLE($zip64EndOfCentralDirectoryOffset) .
|
// total number of disks 4 bytes
|
||||||
// total number of disks 4 bytes
|
1
|
||||||
pack('V', 1)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Data;
|
namespace PhpZip\Model\Data;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
use PhpZip\Model\ZipData;
|
use PhpZip\Model\ZipData;
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipFileData.
|
|
||||||
*/
|
|
||||||
class ZipFileData implements ZipData
|
class ZipFileData implements ZipData
|
||||||
{
|
{
|
||||||
/** @var \SplFileInfo */
|
private \SplFileInfo $file;
|
||||||
private $file;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ZipStringData constructor.
|
|
||||||
*
|
|
||||||
* @param ZipEntry $zipEntry
|
|
||||||
* @param \SplFileInfo $fileInfo
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function __construct(ZipEntry $zipEntry, \SplFileInfo $fileInfo)
|
public function __construct(ZipEntry $zipEntry, \SplFileInfo $fileInfo)
|
||||||
@ -55,7 +55,7 @@ class ZipFileData implements ZipData
|
|||||||
*
|
*
|
||||||
* @return string returns data as string
|
* @return string returns data as string
|
||||||
*/
|
*/
|
||||||
public function getDataAsString()
|
public function getDataAsString(): string
|
||||||
{
|
{
|
||||||
if (!$this->file->isReadable()) {
|
if (!$this->file->isReadable()) {
|
||||||
throw new ZipException(sprintf('The %s file is no longer readable.', $this->file->getPathname()));
|
throw new ZipException(sprintf('The %s file is no longer readable.', $this->file->getPathname()));
|
||||||
@ -69,7 +69,7 @@ class ZipFileData implements ZipData
|
|||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function copyDataToStream($outStream)
|
public function copyDataToStream($outStream): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$stream = $this->getDataAsStream();
|
$stream = $this->getDataAsStream();
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Data;
|
namespace PhpZip\Model\Data;
|
||||||
|
|
||||||
use PhpZip\Model\ZipData;
|
use PhpZip\Model\ZipData;
|
||||||
@ -17,19 +26,16 @@ class ZipNewData implements ZipData
|
|||||||
*
|
*
|
||||||
* @var array<int, int> array of resource ids and the number of class clones
|
* @var array<int, int> array of resource ids and the number of class clones
|
||||||
*/
|
*/
|
||||||
private static $guardClonedStream = [];
|
private static array $guardClonedStream = [];
|
||||||
|
|
||||||
/** @var ZipEntry */
|
private ZipEntry $zipEntry;
|
||||||
private $zipEntry;
|
|
||||||
|
|
||||||
/** @var resource */
|
/** @var resource */
|
||||||
private $stream;
|
private $stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ZipStringData constructor.
|
* @param string|resource $data Raw string data or resource
|
||||||
*
|
* @noinspection PhpMissingParamTypeInspection
|
||||||
* @param ZipEntry $zipEntry
|
|
||||||
* @param string|resource $data
|
|
||||||
*/
|
*/
|
||||||
public function __construct(ZipEntry $zipEntry, $data)
|
public function __construct(ZipEntry $zipEntry, $data)
|
||||||
{
|
{
|
||||||
@ -51,10 +57,10 @@ class ZipNewData implements ZipData
|
|||||||
}
|
}
|
||||||
|
|
||||||
$resourceId = (int) $this->stream;
|
$resourceId = (int) $this->stream;
|
||||||
self::$guardClonedStream[$resourceId] =
|
self::$guardClonedStream[$resourceId]
|
||||||
isset(self::$guardClonedStream[$resourceId]) ?
|
= isset(self::$guardClonedStream[$resourceId])
|
||||||
self::$guardClonedStream[$resourceId] + 1 :
|
? self::$guardClonedStream[$resourceId] + 1
|
||||||
0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +78,7 @@ class ZipNewData implements ZipData
|
|||||||
/**
|
/**
|
||||||
* @return string returns data as string
|
* @return string returns data as string
|
||||||
*/
|
*/
|
||||||
public function getDataAsString()
|
public function getDataAsString(): string
|
||||||
{
|
{
|
||||||
$stream = $this->getDataAsStream();
|
$stream = $this->getDataAsStream();
|
||||||
$pos = ftell($stream);
|
$pos = ftell($stream);
|
||||||
@ -89,7 +95,7 @@ class ZipNewData implements ZipData
|
|||||||
/**
|
/**
|
||||||
* @param resource $outStream
|
* @param resource $outStream
|
||||||
*/
|
*/
|
||||||
public function copyDataToStream($outStream)
|
public function copyDataToStream($outStream): void
|
||||||
{
|
{
|
||||||
$stream = $this->getDataAsStream();
|
$stream = $this->getDataAsStream();
|
||||||
rewind($stream);
|
rewind($stream);
|
||||||
@ -102,10 +108,10 @@ class ZipNewData implements ZipData
|
|||||||
public function __clone()
|
public function __clone()
|
||||||
{
|
{
|
||||||
$resourceId = (int) $this->stream;
|
$resourceId = (int) $this->stream;
|
||||||
self::$guardClonedStream[$resourceId] =
|
self::$guardClonedStream[$resourceId]
|
||||||
isset(self::$guardClonedStream[$resourceId]) ?
|
= isset(self::$guardClonedStream[$resourceId])
|
||||||
self::$guardClonedStream[$resourceId] + 1 :
|
? self::$guardClonedStream[$resourceId] + 1
|
||||||
1;
|
: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Data;
|
namespace PhpZip\Model\Data;
|
||||||
|
|
||||||
use PhpZip\Exception\Crc32Exception;
|
use PhpZip\Exception\Crc32Exception;
|
||||||
@ -8,37 +17,22 @@ use PhpZip\IO\ZipReader;
|
|||||||
use PhpZip\Model\ZipData;
|
use PhpZip\Model\ZipData;
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipFileData.
|
|
||||||
*/
|
|
||||||
class ZipSourceFileData implements ZipData
|
class ZipSourceFileData implements ZipData
|
||||||
{
|
{
|
||||||
/** @var ZipReader */
|
private ZipReader $zipReader;
|
||||||
private $zipReader;
|
|
||||||
|
|
||||||
/** @var resource|null */
|
/** @var resource|null */
|
||||||
private $stream;
|
private $stream;
|
||||||
|
|
||||||
/** @var ZipEntry */
|
private ZipEntry $sourceEntry;
|
||||||
private $sourceEntry;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $offset;
|
||||||
private $offset;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $uncompressedSize;
|
||||||
private $uncompressedSize;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $compressedSize;
|
||||||
private $compressedSize;
|
|
||||||
|
|
||||||
/**
|
public function __construct(ZipReader $zipReader, ZipEntry $zipEntry, int $offsetData)
|
||||||
* ZipFileData constructor.
|
|
||||||
*
|
|
||||||
* @param ZipReader $zipReader
|
|
||||||
* @param ZipEntry $zipEntry
|
|
||||||
* @param int $offsetData
|
|
||||||
*/
|
|
||||||
public function __construct(ZipReader $zipReader, ZipEntry $zipEntry, $offsetData)
|
|
||||||
{
|
{
|
||||||
$this->zipReader = $zipReader;
|
$this->zipReader = $zipReader;
|
||||||
$this->offset = $offsetData;
|
$this->offset = $offsetData;
|
||||||
@ -47,21 +41,16 @@ class ZipSourceFileData implements ZipData
|
|||||||
$this->uncompressedSize = $zipEntry->getUncompressedSize();
|
$this->uncompressedSize = $zipEntry->getUncompressedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function hasRecompressData(ZipEntry $entry): bool
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function hasRecompressData(ZipEntry $entry)
|
|
||||||
{
|
{
|
||||||
return $this->sourceEntry->getCompressionLevel() !== $entry->getCompressionLevel() ||
|
return $this->sourceEntry->getCompressionLevel() !== $entry->getCompressionLevel()
|
||||||
$this->sourceEntry->getCompressionMethod() !== $entry->getCompressionMethod() ||
|
|| $this->sourceEntry->getCompressionMethod() !== $entry->getCompressionMethod()
|
||||||
$this->sourceEntry->isEncrypted() !== $entry->isEncrypted() ||
|
|| $this->sourceEntry->isEncrypted() !== $entry->isEncrypted()
|
||||||
$this->sourceEntry->getEncryptionMethod() !== $entry->getEncryptionMethod() ||
|
|| $this->sourceEntry->getEncryptionMethod() !== $entry->getEncryptionMethod()
|
||||||
$this->sourceEntry->getPassword() !== $entry->getPassword() ||
|
|| $this->sourceEntry->getPassword() !== $entry->getPassword()
|
||||||
$this->sourceEntry->getCompressedSize() !== $entry->getCompressedSize() ||
|
|| $this->sourceEntry->getCompressedSize() !== $entry->getCompressedSize()
|
||||||
$this->sourceEntry->getUncompressedSize() !== $entry->getUncompressedSize() ||
|
|| $this->sourceEntry->getUncompressedSize() !== $entry->getUncompressedSize()
|
||||||
$this->sourceEntry->getCrc() !== $entry->getCrc();
|
|| $this->sourceEntry->getCrc() !== $entry->getCrc();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,7 +72,7 @@ class ZipSourceFileData implements ZipData
|
|||||||
*
|
*
|
||||||
* @return string returns data as string
|
* @return string returns data as string
|
||||||
*/
|
*/
|
||||||
public function getDataAsString()
|
public function getDataAsString(): string
|
||||||
{
|
{
|
||||||
$autoClosable = $this->stream === null;
|
$autoClosable = $this->stream === null;
|
||||||
|
|
||||||
@ -105,64 +94,49 @@ class ZipSourceFileData implements ZipData
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $outputStream Output stream
|
* @param resource $outStream Output stream
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
* @throws Crc32Exception
|
* @throws Crc32Exception
|
||||||
*/
|
*/
|
||||||
public function copyDataToStream($outputStream)
|
public function copyDataToStream($outStream): void
|
||||||
{
|
{
|
||||||
if (\is_resource($this->stream)) {
|
if (\is_resource($this->stream)) {
|
||||||
rewind($this->stream);
|
rewind($this->stream);
|
||||||
stream_copy_to_stream($this->stream, $outputStream);
|
stream_copy_to_stream($this->stream, $outStream);
|
||||||
} else {
|
} else {
|
||||||
$this->zipReader->copyUncompressedDataToStream($this, $outputStream);
|
$this->zipReader->copyUncompressedDataToStream($this, $outStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $outputStream Output stream
|
* @param resource $outputStream Output stream
|
||||||
*/
|
*/
|
||||||
public function copyCompressedDataToStream($outputStream)
|
public function copyCompressedDataToStream($outputStream): void
|
||||||
{
|
{
|
||||||
$this->zipReader->copyCompressedDataToStream($this, $outputStream);
|
$this->zipReader->copyCompressedDataToStream($this, $outputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getSourceEntry(): ZipEntry
|
||||||
* @return ZipEntry
|
|
||||||
*/
|
|
||||||
public function getSourceEntry()
|
|
||||||
{
|
{
|
||||||
return $this->sourceEntry;
|
return $this->sourceEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCompressedSize(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getCompressedSize()
|
|
||||||
{
|
{
|
||||||
return $this->compressedSize;
|
return $this->compressedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getUncompressedSize(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getUncompressedSize()
|
|
||||||
{
|
{
|
||||||
return $this->uncompressedSize;
|
return $this->uncompressedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getOffset(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getOffset()
|
|
||||||
{
|
{
|
||||||
return $this->offset;
|
return $this->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
if (\is_resource($this->stream)) {
|
if (\is_resource($this->stream)) {
|
||||||
|
@ -1,40 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model;
|
namespace PhpZip\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* End of Central Directory.
|
* End of Central Directory.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class EndOfCentralDirectory
|
class EndOfCentralDirectory
|
||||||
{
|
{
|
||||||
/** @var int Count files. */
|
/** @var int Count files. */
|
||||||
private $entryCount;
|
private int $entryCount;
|
||||||
|
|
||||||
/** @var int Central Directory Offset. */
|
/** @var int Central Directory Offset. */
|
||||||
private $cdOffset;
|
private int $cdOffset;
|
||||||
|
|
||||||
/** @var int */
|
private int $cdSize;
|
||||||
private $cdSize;
|
|
||||||
|
|
||||||
/** @var string|null The archive comment. */
|
/** @var string|null The archive comment. */
|
||||||
private $comment;
|
private ?string $comment;
|
||||||
|
|
||||||
/** @var bool Zip64 extension */
|
/** @var bool Zip64 extension */
|
||||||
private $zip64;
|
private bool $zip64;
|
||||||
|
|
||||||
/**
|
public function __construct(int $entryCount, int $cdOffset, int $cdSize, bool $zip64, ?string $comment = null)
|
||||||
* EndOfCentralDirectory constructor.
|
|
||||||
*
|
|
||||||
* @param int $entryCount
|
|
||||||
* @param int $cdOffset
|
|
||||||
* @param int $cdSize
|
|
||||||
* @param bool $zip64
|
|
||||||
* @param string|null $comment
|
|
||||||
*/
|
|
||||||
public function __construct($entryCount, $cdOffset, $cdSize, $zip64, $comment = null)
|
|
||||||
{
|
{
|
||||||
$this->entryCount = $entryCount;
|
$this->entryCount = $entryCount;
|
||||||
$this->cdOffset = $cdOffset;
|
$this->cdOffset = $cdOffset;
|
||||||
@ -43,50 +39,32 @@ class EndOfCentralDirectory
|
|||||||
$this->comment = $comment;
|
$this->comment = $comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setComment(?string $comment): void
|
||||||
* @param string|null $comment
|
|
||||||
*/
|
|
||||||
public function setComment($comment)
|
|
||||||
{
|
{
|
||||||
$this->comment = $comment;
|
$this->comment = $comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getEntryCount(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getEntryCount()
|
|
||||||
{
|
{
|
||||||
return $this->entryCount;
|
return $this->entryCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCdOffset(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getCdOffset()
|
|
||||||
{
|
{
|
||||||
return $this->cdOffset;
|
return $this->cdOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCdSize(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getCdSize()
|
|
||||||
{
|
{
|
||||||
return $this->cdSize;
|
return $this->cdSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getComment(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getComment()
|
|
||||||
{
|
{
|
||||||
return $this->comment;
|
return $this->comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isZip64(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isZip64()
|
|
||||||
{
|
{
|
||||||
return $this->zip64;
|
return $this->zip64;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra;
|
namespace PhpZip\Model\Extra;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,14 +25,12 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
*
|
*
|
||||||
* @var ZipExtraField[]
|
* @var ZipExtraField[]
|
||||||
*/
|
*/
|
||||||
protected $collection = [];
|
protected array $collection = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of Extra Fields in this collection.
|
* Returns the number of Extra Fields in this collection.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function count()
|
public function count(): int
|
||||||
{
|
{
|
||||||
return \count($this->collection);
|
return \count($this->collection);
|
||||||
}
|
}
|
||||||
@ -37,17 +44,14 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
* @return ZipExtraField|null the Extra Field with the given Header ID or
|
* @return ZipExtraField|null the Extra Field with the given Header ID or
|
||||||
* if no such Extra Field exists
|
* if no such Extra Field exists
|
||||||
*/
|
*/
|
||||||
public function get($headerId)
|
public function get(int $headerId): ?ZipExtraField
|
||||||
{
|
{
|
||||||
$this->validateHeaderId($headerId);
|
$this->validateHeaderId($headerId);
|
||||||
|
|
||||||
return isset($this->collection[$headerId]) ? $this->collection[$headerId] : null;
|
return $this->collection[$headerId] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function validateHeaderId(int $headerId): void
|
||||||
* @param int $headerId
|
|
||||||
*/
|
|
||||||
private function validateHeaderId($headerId)
|
|
||||||
{
|
{
|
||||||
if ($headerId < 0 || $headerId > 0xffff) {
|
if ($headerId < 0 || $headerId > 0xffff) {
|
||||||
throw new \InvalidArgumentException('$headerId out of range');
|
throw new \InvalidArgumentException('$headerId out of range');
|
||||||
@ -62,7 +66,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
* @return ZipExtraField the Extra Field previously associated with the Header ID of
|
* @return ZipExtraField the Extra Field previously associated with the Header ID of
|
||||||
* of the given Extra Field or null if no such Extra Field existed
|
* of the given Extra Field or null if no such Extra Field existed
|
||||||
*/
|
*/
|
||||||
public function add(ZipExtraField $extraField)
|
public function add(ZipExtraField $extraField): ZipExtraField
|
||||||
{
|
{
|
||||||
$headerId = $extraField->getHeaderId();
|
$headerId = $extraField->getHeaderId();
|
||||||
|
|
||||||
@ -75,7 +79,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
/**
|
/**
|
||||||
* @param ZipExtraField[] $extraFields
|
* @param ZipExtraField[] $extraFields
|
||||||
*/
|
*/
|
||||||
public function addAll(array $extraFields)
|
public function addAll(array $extraFields): void
|
||||||
{
|
{
|
||||||
foreach ($extraFields as $extraField) {
|
foreach ($extraFields as $extraField) {
|
||||||
$this->add($extraField);
|
$this->add($extraField);
|
||||||
@ -85,7 +89,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
/**
|
/**
|
||||||
* @param ExtraFieldsCollection $collection
|
* @param ExtraFieldsCollection $collection
|
||||||
*/
|
*/
|
||||||
public function addCollection(self $collection)
|
public function addCollection(self $collection): void
|
||||||
{
|
{
|
||||||
$this->addAll($collection->collection);
|
$this->addAll($collection->collection);
|
||||||
}
|
}
|
||||||
@ -93,7 +97,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
/**
|
/**
|
||||||
* @return ZipExtraField[]
|
* @return ZipExtraField[]
|
||||||
*/
|
*/
|
||||||
public function getAll()
|
public function getAll(): array
|
||||||
{
|
{
|
||||||
return $this->collection;
|
return $this->collection;
|
||||||
}
|
}
|
||||||
@ -102,10 +106,8 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
* Returns Extra Field exists.
|
* Returns Extra Field exists.
|
||||||
*
|
*
|
||||||
* @param int $headerId the requested Header ID
|
* @param int $headerId the requested Header ID
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function has($headerId)
|
public function has(int $headerId): bool
|
||||||
{
|
{
|
||||||
return isset($this->collection[$headerId]);
|
return isset($this->collection[$headerId]);
|
||||||
}
|
}
|
||||||
@ -118,7 +120,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
* @return ZipExtraField|null the Extra Field with the given Header ID or null
|
* @return ZipExtraField|null the Extra Field with the given Header ID or null
|
||||||
* if no such Extra Field exists
|
* if no such Extra Field exists
|
||||||
*/
|
*/
|
||||||
public function remove($headerId)
|
public function remove(int $headerId): ?ZipExtraField
|
||||||
{
|
{
|
||||||
$this->validateHeaderId($headerId);
|
$this->validateHeaderId($headerId);
|
||||||
|
|
||||||
@ -137,11 +139,11 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/arrayaccess.offsetexists.php
|
* @see http://php.net/manual/en/arrayaccess.offsetexists.php
|
||||||
*
|
*
|
||||||
* @param int $offset an offset to check for
|
* @param mixed $offset an offset to check for
|
||||||
*
|
*
|
||||||
* @return bool true on success or false on failure
|
* @return bool true on success or false on failure
|
||||||
*/
|
*/
|
||||||
public function offsetExists($offset)
|
public function offsetExists($offset): bool
|
||||||
{
|
{
|
||||||
return isset($this->collection[(int) $offset]);
|
return isset($this->collection[(int) $offset]);
|
||||||
}
|
}
|
||||||
@ -151,13 +153,11 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/arrayaccess.offsetget.php
|
* @see http://php.net/manual/en/arrayaccess.offsetget.php
|
||||||
*
|
*
|
||||||
* @param int $offset the offset to retrieve
|
* @param mixed $offset the offset to retrieve
|
||||||
*
|
|
||||||
* @return ZipExtraField|null
|
|
||||||
*/
|
*/
|
||||||
public function offsetGet($offset)
|
public function offsetGet($offset): ?ZipExtraField
|
||||||
{
|
{
|
||||||
return isset($this->collection[$offset]) ? $this->collection[$offset] : null;
|
return $this->collection[(int) $offset] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,10 +165,10 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/arrayaccess.offsetset.php
|
* @see http://php.net/manual/en/arrayaccess.offsetset.php
|
||||||
*
|
*
|
||||||
* @param mixed $offset the offset to assign the value to
|
* @param mixed $offset the offset to assign the value to
|
||||||
* @param ZipExtraField $value the value to set
|
* @param mixed $value the value to set
|
||||||
*/
|
*/
|
||||||
public function offsetSet($offset, $value)
|
public function offsetSet($offset, $value): void
|
||||||
{
|
{
|
||||||
if (!$value instanceof ZipExtraField) {
|
if (!$value instanceof ZipExtraField) {
|
||||||
throw new \InvalidArgumentException('value is not instanceof ' . ZipExtraField::class);
|
throw new \InvalidArgumentException('value is not instanceof ' . ZipExtraField::class);
|
||||||
@ -183,7 +183,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
*
|
*
|
||||||
* @param mixed $offset the offset to unset
|
* @param mixed $offset the offset to unset
|
||||||
*/
|
*/
|
||||||
public function offsetUnset($offset)
|
public function offsetUnset($offset): void
|
||||||
{
|
{
|
||||||
$this->remove($offset);
|
$this->remove($offset);
|
||||||
}
|
}
|
||||||
@ -192,10 +192,8 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
* Return the current element.
|
* Return the current element.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/iterator.current.php
|
* @see http://php.net/manual/en/iterator.current.php
|
||||||
*
|
|
||||||
* @return ZipExtraField
|
|
||||||
*/
|
*/
|
||||||
public function current()
|
public function current(): ZipExtraField
|
||||||
{
|
{
|
||||||
return current($this->collection);
|
return current($this->collection);
|
||||||
}
|
}
|
||||||
@ -205,7 +203,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/iterator.next.php
|
* @see http://php.net/manual/en/iterator.next.php
|
||||||
*/
|
*/
|
||||||
public function next()
|
public function next(): void
|
||||||
{
|
{
|
||||||
next($this->collection);
|
next($this->collection);
|
||||||
}
|
}
|
||||||
@ -217,7 +215,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
*
|
*
|
||||||
* @return int scalar on success, or null on failure
|
* @return int scalar on success, or null on failure
|
||||||
*/
|
*/
|
||||||
public function key()
|
public function key(): int
|
||||||
{
|
{
|
||||||
return key($this->collection);
|
return key($this->collection);
|
||||||
}
|
}
|
||||||
@ -230,7 +228,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
* @return bool The return value will be casted to boolean and then evaluated.
|
* @return bool The return value will be casted to boolean and then evaluated.
|
||||||
* Returns true on success or false on failure.
|
* Returns true on success or false on failure.
|
||||||
*/
|
*/
|
||||||
public function valid()
|
public function valid(): bool
|
||||||
{
|
{
|
||||||
return key($this->collection) !== null;
|
return key($this->collection) !== null;
|
||||||
}
|
}
|
||||||
@ -240,20 +238,17 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/iterator.rewind.php
|
* @see http://php.net/manual/en/iterator.rewind.php
|
||||||
*/
|
*/
|
||||||
public function rewind()
|
public function rewind(): void
|
||||||
{
|
{
|
||||||
reset($this->collection);
|
reset($this->collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function clear()
|
public function clear(): void
|
||||||
{
|
{
|
||||||
$this->collection = [];
|
$this->collection = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
$formats = [];
|
$formats = [];
|
||||||
|
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
@ -11,45 +20,33 @@ use PhpZip\Model\ZipEntry;
|
|||||||
*/
|
*/
|
||||||
abstract class AbstractUnicodeExtraField implements ZipExtraField
|
abstract class AbstractUnicodeExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
const DEFAULT_VERSION = 0x01;
|
public const DEFAULT_VERSION = 0x01;
|
||||||
|
|
||||||
/** @var int */
|
private int $crc32;
|
||||||
private $crc32;
|
|
||||||
|
|
||||||
/** @var string */
|
private string $unicodeValue;
|
||||||
private $unicodeValue;
|
|
||||||
|
|
||||||
/**
|
public function __construct(int $crc32, string $unicodeValue)
|
||||||
* @param int $crc32
|
|
||||||
* @param string $unicodeValue
|
|
||||||
*/
|
|
||||||
public function __construct($crc32, $unicodeValue)
|
|
||||||
{
|
{
|
||||||
$this->crc32 = (int) $crc32;
|
$this->crc32 = $crc32;
|
||||||
$this->unicodeValue = (string) $unicodeValue;
|
$this->unicodeValue = $unicodeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int the CRC32 checksum of the filename or comment as
|
* @return int the CRC32 checksum of the filename or comment as
|
||||||
* encoded in the central directory of the zip file
|
* encoded in the central directory of the zip file
|
||||||
*/
|
*/
|
||||||
public function getCrc32()
|
public function getCrc32(): int
|
||||||
{
|
{
|
||||||
return $this->crc32;
|
return $this->crc32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setCrc32(int $crc32): void
|
||||||
* @param int $crc32
|
|
||||||
*/
|
|
||||||
public function setCrc32($crc32)
|
|
||||||
{
|
{
|
||||||
$this->crc32 = (int) $crc32;
|
$this->crc32 = $crc32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getUnicodeValue(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getUnicodeValue()
|
|
||||||
{
|
{
|
||||||
return $this->unicodeValue;
|
return $this->unicodeValue;
|
||||||
}
|
}
|
||||||
@ -57,7 +54,7 @@ abstract class AbstractUnicodeExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* @param string $unicodeValue the UTF-8 encoded name to set
|
* @param string $unicodeValue the UTF-8 encoded name to set
|
||||||
*/
|
*/
|
||||||
public function setUnicodeValue($unicodeValue)
|
public function setUnicodeValue(string $unicodeValue): void
|
||||||
{
|
{
|
||||||
$this->unicodeValue = $unicodeValue;
|
$this->unicodeValue = $unicodeValue;
|
||||||
}
|
}
|
||||||
@ -65,41 +62,44 @@ abstract class AbstractUnicodeExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException on error
|
* @throws ZipException on error
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
if (\strlen($buffer) < 5) {
|
if (\strlen($buffer) < 5) {
|
||||||
throw new ZipException('Unicode path extra data must have at least 5 bytes.');
|
throw new ZipException('Unicode path extra data must have at least 5 bytes.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = unpack('Cversion/Vcrc32', $buffer);
|
[
|
||||||
|
'version' => $version,
|
||||||
|
'crc32' => $crc32,
|
||||||
|
] = unpack('Cversion/Vcrc32', $buffer);
|
||||||
|
|
||||||
if ($data['version'] !== self::DEFAULT_VERSION) {
|
if ($version !== self::DEFAULT_VERSION) {
|
||||||
throw new ZipException(sprintf('Unsupported version [%d] for Unicode path extra data.', $data['version']));
|
throw new ZipException(sprintf('Unsupported version [%d] for Unicode path extra data.', $version));
|
||||||
}
|
}
|
||||||
|
|
||||||
$unicodeValue = substr($buffer, 5);
|
$unicodeValue = substr($buffer, 5);
|
||||||
|
|
||||||
return new static($data['crc32'], $unicodeValue);
|
return new static($crc32, $unicodeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException on error
|
* @throws ZipException on error
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
return self::unpackLocalFileData($buffer, $entry);
|
return self::unpackLocalFileData($buffer, $entry);
|
||||||
}
|
}
|
||||||
@ -110,14 +110,14 @@ abstract class AbstractUnicodeExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
return pack(
|
return pack(
|
||||||
'CV',
|
'CV',
|
||||||
self::DEFAULT_VERSION,
|
self::DEFAULT_VERSION,
|
||||||
$this->crc32
|
$this->crc32
|
||||||
) .
|
)
|
||||||
$this->unicodeValue;
|
. $this->unicodeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,7 +126,7 @@ abstract class AbstractUnicodeExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
return $this->packLocalFileData();
|
return $this->packLocalFileData();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
@ -20,31 +29,25 @@ class ApkAlignmentExtraField implements ZipExtraField
|
|||||||
* well as for aligning the entries's data. See ZIP
|
* well as for aligning the entries's data. See ZIP
|
||||||
* appnote.txt section 4.5 Extensible data fields.
|
* appnote.txt section 4.5 Extensible data fields.
|
||||||
*/
|
*/
|
||||||
const HEADER_ID = 0xd935;
|
public const HEADER_ID = 0xd935;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int minimum size (in bytes) of the extensible data block/field used
|
* @var int minimum size (in bytes) of the extensible data block/field used
|
||||||
* for alignment of uncompressed entries
|
* for alignment of uncompressed entries
|
||||||
*/
|
*/
|
||||||
const MIN_SIZE = 6;
|
public const MIN_SIZE = 6;
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
const ALIGNMENT_BYTES = 4;
|
public const ALIGNMENT_BYTES = 4;
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
const COMMON_PAGE_ALIGNMENT_BYTES = 4096;
|
public const COMMON_PAGE_ALIGNMENT_BYTES = 4096;
|
||||||
|
|
||||||
/** @var int */
|
private int $multiple;
|
||||||
private $multiple;
|
|
||||||
|
|
||||||
/** @var int */
|
private int $padding;
|
||||||
private $padding;
|
|
||||||
|
|
||||||
/**
|
public function __construct(int $multiple, int $padding)
|
||||||
* @param int $multiple
|
|
||||||
* @param int $padding
|
|
||||||
*/
|
|
||||||
public function __construct($multiple, $padding)
|
|
||||||
{
|
{
|
||||||
$this->multiple = $multiple;
|
$this->multiple = $multiple;
|
||||||
$this->padding = $padding;
|
$this->padding = $padding;
|
||||||
@ -54,57 +57,43 @@ class ApkAlignmentExtraField implements ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getMultiple(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getMultiple()
|
|
||||||
{
|
{
|
||||||
return $this->multiple;
|
return $this->multiple;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getPadding(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getPadding()
|
|
||||||
{
|
{
|
||||||
return $this->padding;
|
return $this->padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setMultiple(int $multiple): void
|
||||||
* @param int $multiple
|
|
||||||
*/
|
|
||||||
public function setMultiple($multiple)
|
|
||||||
{
|
{
|
||||||
$this->multiple = (int) $multiple;
|
$this->multiple = $multiple;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setPadding(int $padding): void
|
||||||
* @param int $padding
|
|
||||||
*/
|
|
||||||
public function setPadding($padding)
|
|
||||||
{
|
{
|
||||||
$this->padding = (int) $padding;
|
$this->padding = $padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
*
|
||||||
* @return ApkAlignmentExtraField
|
* @return ApkAlignmentExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
$length = \strlen($buffer);
|
$length = \strlen($buffer);
|
||||||
|
|
||||||
@ -127,14 +116,14 @@ class ApkAlignmentExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException on error
|
* @throws ZipException on error
|
||||||
*
|
*
|
||||||
* @return ApkAlignmentExtraField
|
* @return ApkAlignmentExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
return self::unpackLocalFileData($buffer, $entry);
|
return self::unpackLocalFileData($buffer, $entry);
|
||||||
}
|
}
|
||||||
@ -145,7 +134,7 @@ class ApkAlignmentExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
return pack('vx' . $this->padding, $this->multiple);
|
return pack('vx' . $this->padding, $this->multiple);
|
||||||
}
|
}
|
||||||
@ -156,15 +145,12 @@ class ApkAlignmentExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
return $this->packLocalFileData();
|
return $this->packLocalFileData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'0x%04x APK Alignment: Multiple=%d Padding=%d',
|
'0x%04x APK Alignment: Multiple=%d Padding=%d',
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Constants\UnixStat;
|
use PhpZip\Constants\UnixStat;
|
||||||
@ -47,37 +56,29 @@ use PhpZip\Model\ZipEntry;
|
|||||||
class AsiExtraField implements ZipExtraField
|
class AsiExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
/** @var int Header id */
|
/** @var int Header id */
|
||||||
const HEADER_ID = 0x756e;
|
public const HEADER_ID = 0x756e;
|
||||||
|
|
||||||
const USER_GID_PID = 1000;
|
public const USER_GID_PID = 1000;
|
||||||
|
|
||||||
/** Bits used for permissions (and sticky bit). */
|
/** Bits used for permissions (and sticky bit). */
|
||||||
const PERM_MASK = 07777;
|
public const PERM_MASK = 07777;
|
||||||
|
|
||||||
/** @var int Standard Unix stat(2) file mode. */
|
/** @var int Standard Unix stat(2) file mode. */
|
||||||
private $mode;
|
private int $mode;
|
||||||
|
|
||||||
/** @var int User ID. */
|
/** @var int User ID. */
|
||||||
private $uid;
|
private int $uid;
|
||||||
|
|
||||||
/** @var int Group ID. */
|
/** @var int Group ID. */
|
||||||
private $gid;
|
private int $gid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string File this entry points to, if it is a symbolic link.
|
* @var string File this entry points to, if it is a symbolic link.
|
||||||
* Empty string - if entry is not a symbolic link.
|
* Empty string - if entry is not a symbolic link.
|
||||||
*/
|
*/
|
||||||
private $link;
|
private string $link;
|
||||||
|
|
||||||
/**
|
public function __construct(int $mode, int $uid = self::USER_GID_PID, int $gid = self::USER_GID_PID, string $link = '')
|
||||||
* AsiExtraField constructor.
|
|
||||||
*
|
|
||||||
* @param int $mode
|
|
||||||
* @param int $uid
|
|
||||||
* @param int $gid
|
|
||||||
* @param string $link
|
|
||||||
*/
|
|
||||||
public function __construct($mode, $uid = self::USER_GID_PID, $gid = self::USER_GID_PID, $link = '')
|
|
||||||
{
|
{
|
||||||
$this->mode = $mode;
|
$this->mode = $mode;
|
||||||
$this->uid = $uid;
|
$this->uid = $uid;
|
||||||
@ -89,10 +90,8 @@ class AsiExtraField implements ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
@ -100,14 +99,14 @@ class AsiExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws Crc32Exception
|
* @throws Crc32Exception
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
$givenChecksum = unpack('V', $buffer)[1];
|
$givenChecksum = unpack('V', $buffer)[1];
|
||||||
$buffer = substr($buffer, 4);
|
$buffer = substr($buffer, 4);
|
||||||
@ -117,27 +116,32 @@ class AsiExtraField implements ZipExtraField
|
|||||||
throw new Crc32Exception('Asi Unix Extra Filed Data', $givenChecksum, $realChecksum);
|
throw new Crc32Exception('Asi Unix Extra Filed Data', $givenChecksum, $realChecksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = unpack('vmode/VlinkSize/vuid/vgid', $buffer);
|
[
|
||||||
|
'mode' => $mode,
|
||||||
|
'linkSize' => $linkSize,
|
||||||
|
'uid' => $uid,
|
||||||
|
'gid' => $gid,
|
||||||
|
] = unpack('vmode/VlinkSize/vuid/vgid', $buffer);
|
||||||
$link = '';
|
$link = '';
|
||||||
|
|
||||||
if ($data['linkSize'] > 0) {
|
if ($linkSize > 0) {
|
||||||
$link = substr($buffer, 10);
|
$link = substr($buffer, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new self($data['mode'], $data['uid'], $data['gid'], $link);
|
return new self($mode, $uid, $gid, $link);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws Crc32Exception
|
* @throws Crc32Exception
|
||||||
*
|
*
|
||||||
* @return AsiExtraField
|
* @return AsiExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
return self::unpackLocalFileData($buffer, $entry);
|
return self::unpackLocalFileData($buffer, $entry);
|
||||||
}
|
}
|
||||||
@ -148,7 +152,7 @@ class AsiExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
$data = pack(
|
$data = pack(
|
||||||
'vVvv',
|
'vVvv',
|
||||||
@ -167,7 +171,7 @@ class AsiExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
return $this->packLocalFileData();
|
return $this->packLocalFileData();
|
||||||
}
|
}
|
||||||
@ -178,7 +182,7 @@ class AsiExtraField implements ZipExtraField
|
|||||||
* @return string name of the file this entry links to if it is a
|
* @return string name of the file this entry links to if it is a
|
||||||
* symbolic link, the empty string otherwise
|
* symbolic link, the empty string otherwise
|
||||||
*/
|
*/
|
||||||
public function getLink()
|
public function getLink(): string
|
||||||
{
|
{
|
||||||
return $this->link;
|
return $this->link;
|
||||||
}
|
}
|
||||||
@ -189,9 +193,9 @@ class AsiExtraField implements ZipExtraField
|
|||||||
* @param string $link name of the file this entry links to, empty
|
* @param string $link name of the file this entry links to, empty
|
||||||
* string if it is not a symbolic link
|
* string if it is not a symbolic link
|
||||||
*/
|
*/
|
||||||
public function setLink($link)
|
public function setLink(string $link): void
|
||||||
{
|
{
|
||||||
$this->link = (string) $link;
|
$this->link = $link;
|
||||||
$this->mode = $this->getPermissionsMode($this->mode);
|
$this->mode = $this->getPermissionsMode($this->mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +204,7 @@ class AsiExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return bool true if this is a symbolic link
|
* @return bool true if this is a symbolic link
|
||||||
*/
|
*/
|
||||||
public function isLink()
|
public function isLink(): bool
|
||||||
{
|
{
|
||||||
return !empty($this->link);
|
return !empty($this->link);
|
||||||
}
|
}
|
||||||
@ -212,7 +216,7 @@ class AsiExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return int the type with the mode
|
* @return int the type with the mode
|
||||||
*/
|
*/
|
||||||
protected function getPermissionsMode($mode)
|
protected function getPermissionsMode(int $mode): int
|
||||||
{
|
{
|
||||||
$type = 0;
|
$type = 0;
|
||||||
|
|
||||||
@ -232,63 +236,42 @@ class AsiExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return bool true if this entry is a directory
|
* @return bool true if this entry is a directory
|
||||||
*/
|
*/
|
||||||
public function isDirectory()
|
public function isDirectory(): bool
|
||||||
{
|
{
|
||||||
return ($this->mode & UnixStat::UNX_IFDIR) !== 0 && !$this->isLink();
|
return ($this->mode & UnixStat::UNX_IFDIR) !== 0 && !$this->isLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getMode(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getMode()
|
|
||||||
{
|
{
|
||||||
return $this->mode;
|
return $this->mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setMode(int $mode): void
|
||||||
* @param int $mode
|
|
||||||
*/
|
|
||||||
public function setMode($mode)
|
|
||||||
{
|
{
|
||||||
$this->mode = $this->getPermissionsMode($mode);
|
$this->mode = $this->getPermissionsMode($mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getUserId(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getUserId()
|
|
||||||
{
|
{
|
||||||
return $this->uid;
|
return $this->uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setUserId(int $uid): void
|
||||||
* @param int $uid
|
|
||||||
*/
|
|
||||||
public function setUserId($uid)
|
|
||||||
{
|
{
|
||||||
$this->uid = (int) $uid;
|
$this->uid = $uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getGroupId(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getGroupId()
|
|
||||||
{
|
{
|
||||||
return $this->gid;
|
return $this->gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setGroupId(int $gid): void
|
||||||
* @param int $gid
|
|
||||||
*/
|
|
||||||
public function setGroupId($gid)
|
|
||||||
{
|
{
|
||||||
$this->gid = (int) $gid;
|
$this->gid = $gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'0x%04x ASI: Mode=%o UID=%d GID=%d Link="%s',
|
'0x%04x ASI: Mode=%o UID=%d GID=%d Link="%s',
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Model\Extra\ZipExtraField;
|
use PhpZip\Model\Extra\ZipExtraField;
|
||||||
@ -67,78 +76,69 @@ use PhpZip\Model\ZipEntry;
|
|||||||
class ExtendedTimestampExtraField implements ZipExtraField
|
class ExtendedTimestampExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
/** @var int Header id */
|
/** @var int Header id */
|
||||||
const HEADER_ID = 0x5455;
|
public const HEADER_ID = 0x5455;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int the bit set inside the flags by when the last modification time
|
* @var int the bit set inside the flags by when the last modification time
|
||||||
* is present in this extra field
|
* is present in this extra field
|
||||||
*/
|
*/
|
||||||
const MODIFY_TIME_BIT = 1;
|
public const MODIFY_TIME_BIT = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int the bit set inside the flags by when the last access time is
|
* @var int the bit set inside the flags by when the last access time is
|
||||||
* present in this extra field
|
* present in this extra field
|
||||||
*/
|
*/
|
||||||
const ACCESS_TIME_BIT = 2;
|
public const ACCESS_TIME_BIT = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int the bit set inside the flags by when the original creation time
|
* @var int the bit set inside the flags by when the original creation time
|
||||||
* is present in this extra field
|
* is present in this extra field
|
||||||
*/
|
*/
|
||||||
const CREATE_TIME_BIT = 4;
|
public const CREATE_TIME_BIT = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int The 3 boolean fields (below) come from this flags byte. The remaining 5 bits
|
* @var int The 3 boolean fields (below) come from this flags byte. The remaining 5 bits
|
||||||
* are ignored according to the current version of the spec (December 2012).
|
* are ignored according to the current version of the spec (December 2012).
|
||||||
*/
|
*/
|
||||||
private $flags;
|
private int $flags;
|
||||||
|
|
||||||
/** @var int|null Modify time */
|
/** @var int|null Modify time */
|
||||||
private $modifyTime;
|
private ?int $modifyTime;
|
||||||
|
|
||||||
/** @var int|null Access time */
|
/** @var int|null Access time */
|
||||||
private $accessTime;
|
private ?int $accessTime;
|
||||||
|
|
||||||
/** @var int|null Create time */
|
/** @var int|null Create time */
|
||||||
private $createTime;
|
private ?int $createTime;
|
||||||
|
|
||||||
/**
|
public function __construct(int $flags, ?int $modifyTime, ?int $accessTime, ?int $createTime)
|
||||||
* @param int $flags
|
|
||||||
* @param int|null $modifyTime
|
|
||||||
* @param int|null $accessTime
|
|
||||||
* @param int|null $createTime
|
|
||||||
*/
|
|
||||||
public function __construct($flags, $modifyTime, $accessTime, $createTime)
|
|
||||||
{
|
{
|
||||||
$this->flags = (int) $flags;
|
$this->flags = $flags;
|
||||||
$this->modifyTime = $modifyTime;
|
$this->modifyTime = $modifyTime;
|
||||||
$this->accessTime = $accessTime;
|
$this->accessTime = $accessTime;
|
||||||
$this->createTime = $createTime;
|
$this->createTime = $createTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int|null $modifyTime
|
* @param ?int $modifyTime
|
||||||
* @param int|null $accessTime
|
* @param ?int $accessTime
|
||||||
* @param int|null $createTime
|
* @param ?int $createTime
|
||||||
*
|
*
|
||||||
* @return ExtendedTimestampExtraField
|
* @return ExtendedTimestampExtraField
|
||||||
*/
|
*/
|
||||||
public static function create($modifyTime, $accessTime, $createTime)
|
public static function create(?int $modifyTime, ?int $accessTime, ?int $createTime): self
|
||||||
{
|
{
|
||||||
$flags = 0;
|
$flags = 0;
|
||||||
|
|
||||||
if ($modifyTime !== null) {
|
if ($modifyTime !== null) {
|
||||||
$modifyTime = (int) $modifyTime;
|
|
||||||
$flags |= self::MODIFY_TIME_BIT;
|
$flags |= self::MODIFY_TIME_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($accessTime !== null) {
|
if ($accessTime !== null) {
|
||||||
$accessTime = (int) $accessTime;
|
|
||||||
$flags |= self::ACCESS_TIME_BIT;
|
$flags |= self::ACCESS_TIME_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($createTime !== null) {
|
if ($createTime !== null) {
|
||||||
$createTime = (int) $createTime;
|
|
||||||
$flags |= self::CREATE_TIME_BIT;
|
$flags |= self::CREATE_TIME_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,10 +149,8 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
@ -160,12 +158,12 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @return ExtendedTimestampExtraField
|
* @return ExtendedTimestampExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
$length = \strlen($buffer);
|
$length = \strlen($buffer);
|
||||||
$flags = unpack('C', $buffer)[1];
|
$flags = unpack('C', $buffer)[1];
|
||||||
@ -197,12 +195,12 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @return ExtendedTimestampExtraField
|
* @return ExtendedTimestampExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
return self::unpackLocalFileData($buffer, $entry);
|
return self::unpackLocalFileData($buffer, $entry);
|
||||||
}
|
}
|
||||||
@ -213,7 +211,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
$data = '';
|
$data = '';
|
||||||
|
|
||||||
@ -241,7 +239,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
$cdLength = 1 + ($this->modifyTime !== null ? 4 : 0);
|
$cdLength = 1 + ($this->modifyTime !== null ? 4 : 0);
|
||||||
|
|
||||||
@ -263,7 +261,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
* @return int flags byte indicating which of the
|
* @return int flags byte indicating which of the
|
||||||
* three datestamp fields are present
|
* three datestamp fields are present
|
||||||
*/
|
*/
|
||||||
public function getFlags()
|
public function getFlags(): int
|
||||||
{
|
{
|
||||||
return $this->flags;
|
return $this->flags;
|
||||||
}
|
}
|
||||||
@ -274,7 +272,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return int|null modify time (seconds since epoch) or null
|
* @return int|null modify time (seconds since epoch) or null
|
||||||
*/
|
*/
|
||||||
public function getModifyTime()
|
public function getModifyTime(): ?int
|
||||||
{
|
{
|
||||||
return $this->modifyTime;
|
return $this->modifyTime;
|
||||||
}
|
}
|
||||||
@ -285,7 +283,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return int|null access time (seconds since epoch) or null
|
* @return int|null access time (seconds since epoch) or null
|
||||||
*/
|
*/
|
||||||
public function getAccessTime()
|
public function getAccessTime(): ?int
|
||||||
{
|
{
|
||||||
return $this->accessTime;
|
return $this->accessTime;
|
||||||
}
|
}
|
||||||
@ -301,7 +299,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return int|null create time (seconds since epoch) or null
|
* @return int|null create time (seconds since epoch) or null
|
||||||
*/
|
*/
|
||||||
public function getCreateTime()
|
public function getCreateTime(): ?int
|
||||||
{
|
{
|
||||||
return $this->createTime;
|
return $this->createTime;
|
||||||
}
|
}
|
||||||
@ -314,7 +312,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return \DateTimeInterface|null modify time as \DateTimeInterface or null
|
* @return \DateTimeInterface|null modify time as \DateTimeInterface or null
|
||||||
*/
|
*/
|
||||||
public function getModifyDateTime()
|
public function getModifyDateTime(): ?\DateTimeInterface
|
||||||
{
|
{
|
||||||
return self::timestampToDateTime($this->modifyTime);
|
return self::timestampToDateTime($this->modifyTime);
|
||||||
}
|
}
|
||||||
@ -327,7 +325,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return \DateTimeInterface|null access time as \DateTimeInterface or null
|
* @return \DateTimeInterface|null access time as \DateTimeInterface or null
|
||||||
*/
|
*/
|
||||||
public function getAccessDateTime()
|
public function getAccessDateTime(): ?\DateTimeInterface
|
||||||
{
|
{
|
||||||
return self::timestampToDateTime($this->accessTime);
|
return self::timestampToDateTime($this->accessTime);
|
||||||
}
|
}
|
||||||
@ -345,7 +343,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return \DateTimeInterface|null create time as \DateTimeInterface or null
|
* @return \DateTimeInterface|null create time as \DateTimeInterface or null
|
||||||
*/
|
*/
|
||||||
public function getCreateDateTime()
|
public function getCreateDateTime(): ?\DateTimeInterface
|
||||||
{
|
{
|
||||||
return self::timestampToDateTime($this->createTime);
|
return self::timestampToDateTime($this->createTime);
|
||||||
}
|
}
|
||||||
@ -356,13 +354,13 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @param int|null $unixTime unix time of the modify time (seconds per epoch) or null
|
* @param int|null $unixTime unix time of the modify time (seconds per epoch) or null
|
||||||
*/
|
*/
|
||||||
public function setModifyTime($unixTime)
|
public function setModifyTime(?int $unixTime): void
|
||||||
{
|
{
|
||||||
$this->modifyTime = $unixTime;
|
$this->modifyTime = $unixTime;
|
||||||
$this->updateFlags();
|
$this->updateFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function updateFlags()
|
private function updateFlags(): void
|
||||||
{
|
{
|
||||||
$flags = 0;
|
$flags = 0;
|
||||||
|
|
||||||
@ -386,7 +384,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @param int|null $unixTime Unix time of the access time (seconds per epoch) or null
|
* @param int|null $unixTime Unix time of the access time (seconds per epoch) or null
|
||||||
*/
|
*/
|
||||||
public function setAccessTime($unixTime)
|
public function setAccessTime(?int $unixTime): void
|
||||||
{
|
{
|
||||||
$this->accessTime = $unixTime;
|
$this->accessTime = $unixTime;
|
||||||
$this->updateFlags();
|
$this->updateFlags();
|
||||||
@ -398,18 +396,13 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @param int|null $unixTime Unix time of the create time (seconds per epoch) or null
|
* @param int|null $unixTime Unix time of the create time (seconds per epoch) or null
|
||||||
*/
|
*/
|
||||||
public function setCreateTime($unixTime)
|
public function setCreateTime(?int $unixTime): void
|
||||||
{
|
{
|
||||||
$this->createTime = $unixTime;
|
$this->createTime = $unixTime;
|
||||||
$this->updateFlags();
|
$this->updateFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static function timestampToDateTime(?int $timestamp): ?\DateTimeInterface
|
||||||
* @param int|null $timestamp
|
|
||||||
*
|
|
||||||
* @return \DateTimeInterface|null
|
|
||||||
*/
|
|
||||||
private static function timestampToDateTime($timestamp)
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $timestamp !== null ? new \DateTimeImmutable('@' . $timestamp) : null;
|
return $timestamp !== null ? new \DateTimeImmutable('@' . $timestamp) : null;
|
||||||
@ -418,10 +411,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
$args = [self::HEADER_ID];
|
$args = [self::HEADER_ID];
|
||||||
$format = '0x%04x ExtendedTimestamp:';
|
$format = '0x%04x ExtendedTimestamp:';
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
@ -14,18 +23,13 @@ use PhpZip\Model\ZipEntry;
|
|||||||
* by the extra field in the first file, which is hexadecimal in the 0xCAFE bytes series.
|
* by the extra field in the first file, which is hexadecimal in the 0xCAFE bytes series.
|
||||||
* If this extra field is added as the very first extra field of
|
* If this extra field is added as the very first extra field of
|
||||||
* the archive, Solaris will consider it an executable jar file.
|
* the archive, Solaris will consider it an executable jar file.
|
||||||
*
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class JarMarkerExtraField implements ZipExtraField
|
class JarMarkerExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
/** @var int Header id. */
|
/** @var int Header id. */
|
||||||
const HEADER_ID = 0xCAFE;
|
public const HEADER_ID = 0xCAFE;
|
||||||
|
|
||||||
/**
|
public static function setJarMarker(ZipContainer $container): void
|
||||||
* @param ZipContainer $container
|
|
||||||
*/
|
|
||||||
public static function setJarMarker(ZipContainer $container)
|
|
||||||
{
|
{
|
||||||
$zipEntries = $container->getEntries();
|
$zipEntries = $container->getEntries();
|
||||||
|
|
||||||
@ -44,10 +48,8 @@ class JarMarkerExtraField implements ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
@ -58,7 +60,7 @@ class JarMarkerExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -69,7 +71,7 @@ class JarMarkerExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -77,14 +79,14 @@ class JarMarkerExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException on error
|
* @throws ZipException on error
|
||||||
*
|
*
|
||||||
* @return JarMarkerExtraField
|
* @return JarMarkerExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
if (!empty($buffer)) {
|
if (!empty($buffer)) {
|
||||||
throw new ZipException("JarMarker doesn't expect any data");
|
throw new ZipException("JarMarker doesn't expect any data");
|
||||||
@ -96,22 +98,19 @@ class JarMarkerExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException on error
|
* @throws ZipException on error
|
||||||
*
|
*
|
||||||
* @return JarMarkerExtraField
|
* @return JarMarkerExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
return self::unpackLocalFileData($buffer, $entry);
|
return self::unpackLocalFileData($buffer, $entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
return sprintf('0x%04x Jar Marker', self::HEADER_ID);
|
return sprintf('0x%04x Jar Marker', self::HEADER_ID);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
@ -45,42 +54,33 @@ use PhpZip\Model\ZipEntry;
|
|||||||
class NewUnixExtraField implements ZipExtraField
|
class NewUnixExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
/** @var int header id */
|
/** @var int header id */
|
||||||
const HEADER_ID = 0x7875;
|
public const HEADER_ID = 0x7875;
|
||||||
|
|
||||||
/** ID of the first non-root user created on a unix system. */
|
/** ID of the first non-root user created on a unix system. */
|
||||||
const USER_GID_PID = 1000;
|
public const USER_GID_PID = 1000;
|
||||||
|
|
||||||
/** @var int version of this extra field, currently 1 */
|
/** @var int version of this extra field, currently 1 */
|
||||||
private $version = 1;
|
private int $version;
|
||||||
|
|
||||||
/** @var int User id */
|
/** @var int User id */
|
||||||
private $uid;
|
private int $uid;
|
||||||
|
|
||||||
/** @var int Group id */
|
/** @var int Group id */
|
||||||
private $gid;
|
private int $gid;
|
||||||
|
|
||||||
/**
|
public function __construct(int $version = 1, int $uid = self::USER_GID_PID, int $gid = self::USER_GID_PID)
|
||||||
* NewUnixExtraField constructor.
|
|
||||||
*
|
|
||||||
* @param int $version
|
|
||||||
* @param int $uid
|
|
||||||
* @param int $gid
|
|
||||||
*/
|
|
||||||
public function __construct($version = 1, $uid = self::USER_GID_PID, $gid = self::USER_GID_PID)
|
|
||||||
{
|
{
|
||||||
$this->version = (int) $version;
|
$this->version = $version;
|
||||||
$this->uid = (int) $uid;
|
$this->uid = $uid;
|
||||||
$this->gid = (int) $gid;
|
$this->gid = $gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
@ -88,14 +88,14 @@ class NewUnixExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
*
|
||||||
* @return NewUnixExtraField
|
* @return NewUnixExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
$length = \strlen($buffer);
|
$length = \strlen($buffer);
|
||||||
|
|
||||||
@ -103,29 +103,31 @@ class NewUnixExtraField implements ZipExtraField
|
|||||||
throw new ZipException(sprintf('X7875_NewUnix length is too short, only %s bytes', $length));
|
throw new ZipException(sprintf('X7875_NewUnix length is too short, only %s bytes', $length));
|
||||||
}
|
}
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
$data = unpack('Cversion/CuidSize', $buffer);
|
[
|
||||||
|
'version' => $version,
|
||||||
|
'uidSize' => $uidSize,
|
||||||
|
] = unpack('Cversion/CuidSize', $buffer);
|
||||||
$offset += 2;
|
$offset += 2;
|
||||||
$uidSize = $data['uidSize'];
|
|
||||||
$gid = self::readSizeIntegerLE(substr($buffer, $offset, $uidSize), $uidSize);
|
$gid = self::readSizeIntegerLE(substr($buffer, $offset, $uidSize), $uidSize);
|
||||||
$offset += $uidSize;
|
$offset += $uidSize;
|
||||||
$gidSize = unpack('C', $buffer[$offset])[1];
|
$gidSize = unpack('C', $buffer[$offset])[1];
|
||||||
$offset++;
|
$offset++;
|
||||||
$uid = self::readSizeIntegerLE(substr($buffer, $offset, $gidSize), $gidSize);
|
$uid = self::readSizeIntegerLE(substr($buffer, $offset, $gidSize), $gidSize);
|
||||||
|
|
||||||
return new self($data['version'], $gid, $uid);
|
return new self($version, $gid, $uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
*
|
||||||
* @return NewUnixExtraField
|
* @return NewUnixExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
return self::unpackLocalFileData($buffer, $entry);
|
return self::unpackLocalFileData($buffer, $entry);
|
||||||
}
|
}
|
||||||
@ -136,7 +138,7 @@ class NewUnixExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
return pack(
|
return pack(
|
||||||
'CCVCV',
|
'CCVCV',
|
||||||
@ -154,20 +156,15 @@ class NewUnixExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
return $this->packLocalFileData();
|
return $this->packLocalFileData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $data
|
|
||||||
* @param int $size
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
private static function readSizeIntegerLE($data, $size)
|
private static function readSizeIntegerLE(string $data, int $size): int
|
||||||
{
|
{
|
||||||
$format = [
|
$format = [
|
||||||
1 => 'C', // unsigned byte
|
1 => 'C', // unsigned byte
|
||||||
@ -182,50 +179,32 @@ class NewUnixExtraField implements ZipExtraField
|
|||||||
return unpack($format[$size], $data)[1];
|
return unpack($format[$size], $data)[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getUid(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getUid()
|
|
||||||
{
|
{
|
||||||
return $this->uid;
|
return $this->uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setUid(int $uid): void
|
||||||
* @param int $uid
|
|
||||||
*/
|
|
||||||
public function setUid($uid)
|
|
||||||
{
|
{
|
||||||
$this->uid = $uid & 0xffffffff;
|
$this->uid = $uid & 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getGid(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getGid()
|
|
||||||
{
|
{
|
||||||
return $this->gid;
|
return $this->gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setGid(int $gid): void
|
||||||
* @param int $gid
|
|
||||||
*/
|
|
||||||
public function setGid($gid)
|
|
||||||
{
|
{
|
||||||
$this->gid = $gid & 0xffffffff;
|
$this->gid = $gid & 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getVersion(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getVersion()
|
|
||||||
{
|
{
|
||||||
return $this->version;
|
return $this->version;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'0x%04x NewUnix: UID=%d GID=%d',
|
'0x%04x NewUnix: UID=%d GID=%d',
|
||||||
|
@ -1,30 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Exception\InvalidArgumentException;
|
use PhpZip\Exception\InvalidArgumentException;
|
||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
use PhpZip\Model\Extra\ZipExtraField;
|
use PhpZip\Model\Extra\ZipExtraField;
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
use PhpZip\Util\PackUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NTFS Extra Field.
|
* NTFS Extra Field.
|
||||||
*
|
*
|
||||||
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
|
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
|
||||||
*
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class NtfsExtraField implements ZipExtraField
|
class NtfsExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
/** @var int Header id */
|
/** @var int Header id */
|
||||||
const HEADER_ID = 0x000a;
|
public const HEADER_ID = 0x000a;
|
||||||
|
|
||||||
/** @var int Tag ID */
|
/** @var int Tag ID */
|
||||||
const TIME_ATTR_TAG = 0x0001;
|
public const TIME_ATTR_TAG = 0x0001;
|
||||||
|
|
||||||
/** @var int Attribute size */
|
/** @var int Attribute size */
|
||||||
const TIME_ATTR_SIZE = 24; // 3 * 8
|
public const TIME_ATTR_SIZE = 24; // 3 * 8
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int A file time is a 64-bit value that represents the number of
|
* @var int A file time is a 64-bit value that represents the number of
|
||||||
@ -32,41 +38,32 @@ class NtfsExtraField implements ZipExtraField
|
|||||||
* A.M. January 1, 1601 Coordinated Universal Time (UTC).
|
* A.M. January 1, 1601 Coordinated Universal Time (UTC).
|
||||||
* this is the offset of Windows time 0 to Unix epoch in 100-nanosecond intervals.
|
* this is the offset of Windows time 0 to Unix epoch in 100-nanosecond intervals.
|
||||||
*/
|
*/
|
||||||
const EPOCH_OFFSET = -116444736000000000;
|
public const EPOCH_OFFSET = -116444736000000000;
|
||||||
|
|
||||||
/** @var int Modify ntfs time */
|
/** @var int Modify ntfs time */
|
||||||
private $modifyNtfsTime;
|
private int $modifyNtfsTime;
|
||||||
|
|
||||||
/** @var int Access ntfs time */
|
/** @var int Access ntfs time */
|
||||||
private $accessNtfsTime;
|
private int $accessNtfsTime;
|
||||||
|
|
||||||
/** @var int Create ntfs time */
|
/** @var int Create ntfs time */
|
||||||
private $createNtfsTime;
|
private int $createNtfsTime;
|
||||||
|
|
||||||
/**
|
public function __construct(int $modifyNtfsTime, int $accessNtfsTime, int $createNtfsTime)
|
||||||
* @param int $modifyNtfsTime
|
|
||||||
* @param int $accessNtfsTime
|
|
||||||
* @param int $createNtfsTime
|
|
||||||
*/
|
|
||||||
public function __construct($modifyNtfsTime, $accessNtfsTime, $createNtfsTime)
|
|
||||||
{
|
{
|
||||||
$this->modifyNtfsTime = (int) $modifyNtfsTime;
|
$this->modifyNtfsTime = $modifyNtfsTime;
|
||||||
$this->accessNtfsTime = (int) $accessNtfsTime;
|
$this->accessNtfsTime = $accessNtfsTime;
|
||||||
$this->createNtfsTime = (int) $createNtfsTime;
|
$this->createNtfsTime = $createNtfsTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \DateTimeInterface $modifyDateTime
|
|
||||||
* @param \DateTimeInterface $accessDateTime
|
|
||||||
* @param \DateTimeInterface $createNtfsTime
|
|
||||||
*
|
|
||||||
* @return NtfsExtraField
|
* @return NtfsExtraField
|
||||||
*/
|
*/
|
||||||
public static function create(
|
public static function create(
|
||||||
\DateTimeInterface $modifyDateTime,
|
\DateTimeInterface $modifyDateTime,
|
||||||
\DateTimeInterface $accessDateTime,
|
\DateTimeInterface $accessDateTime,
|
||||||
\DateTimeInterface $createNtfsTime
|
\DateTimeInterface $createNtfsTime
|
||||||
) {
|
): self {
|
||||||
return new self(
|
return new self(
|
||||||
self::dateTimeToNtfsTime($modifyDateTime),
|
self::dateTimeToNtfsTime($modifyDateTime),
|
||||||
self::dateTimeToNtfsTime($accessDateTime),
|
self::dateTimeToNtfsTime($accessDateTime),
|
||||||
@ -78,10 +75,8 @@ class NtfsExtraField implements ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
@ -89,14 +84,14 @@ class NtfsExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
*
|
||||||
* @return NtfsExtraField
|
* @return NtfsExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
if (\PHP_INT_SIZE === 4) {
|
if (\PHP_INT_SIZE === 4) {
|
||||||
throw new ZipException('not supported for php-32bit');
|
throw new ZipException('not supported for php-32bit');
|
||||||
@ -109,17 +104,21 @@ class NtfsExtraField implements ZipExtraField
|
|||||||
$createTime = 0;
|
$createTime = 0;
|
||||||
|
|
||||||
while ($buffer || $buffer !== '') {
|
while ($buffer || $buffer !== '') {
|
||||||
$unpack = unpack('vtag/vsizeAttr', $buffer);
|
[
|
||||||
|
'tag' => $tag,
|
||||||
|
'sizeAttr' => $sizeAttr,
|
||||||
|
] = unpack('vtag/vsizeAttr', $buffer);
|
||||||
|
|
||||||
if ($unpack['tag'] === self::TIME_ATTR_TAG && $unpack['sizeAttr'] === self::TIME_ATTR_SIZE) {
|
if ($tag === self::TIME_ATTR_TAG && $sizeAttr === self::TIME_ATTR_SIZE) {
|
||||||
// refactoring will be needed when php 5.5 support ends
|
[
|
||||||
$modifyTime = PackUtil::unpackLongLE(substr($buffer, 4, 8));
|
'modifyTime' => $modifyTime,
|
||||||
$accessTime = PackUtil::unpackLongLE(substr($buffer, 12, 8));
|
'accessTime' => $accessTime,
|
||||||
$createTime = PackUtil::unpackLongLE(substr($buffer, 20, 8));
|
'createTime' => $createTime,
|
||||||
|
] = unpack('PmodifyTime/PaccessTime/PcreateTime', substr($buffer, 4, 24));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$buffer = substr($buffer, 4 + $unpack['sizeAttr']);
|
$buffer = substr($buffer, 4 + $sizeAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new self($modifyTime, $accessTime, $createTime);
|
return new self($modifyTime, $accessTime, $createTime);
|
||||||
@ -128,14 +127,14 @@ class NtfsExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
*
|
||||||
* @return NtfsExtraField
|
* @return NtfsExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
return self::unpackLocalFileData($buffer, $entry);
|
return self::unpackLocalFileData($buffer, $entry);
|
||||||
}
|
}
|
||||||
@ -146,63 +145,47 @@ class NtfsExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
$data = pack('Vvv', 0, self::TIME_ATTR_TAG, self::TIME_ATTR_SIZE);
|
return pack(
|
||||||
// refactoring will be needed when php 5.5 support ends
|
'VvvPPP',
|
||||||
$data .= PackUtil::packLongLE($this->modifyNtfsTime);
|
0,
|
||||||
$data .= PackUtil::packLongLE($this->accessNtfsTime);
|
self::TIME_ATTR_TAG,
|
||||||
$data .= PackUtil::packLongLE($this->createNtfsTime);
|
self::TIME_ATTR_SIZE,
|
||||||
|
$this->modifyNtfsTime,
|
||||||
return $data;
|
$this->accessNtfsTime,
|
||||||
|
$this->createNtfsTime
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getModifyNtfsTime(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getModifyNtfsTime()
|
|
||||||
{
|
{
|
||||||
return $this->modifyNtfsTime;
|
return $this->modifyNtfsTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setModifyNtfsTime(int $modifyNtfsTime): void
|
||||||
* @param int $modifyNtfsTime
|
|
||||||
*/
|
|
||||||
public function setModifyNtfsTime($modifyNtfsTime)
|
|
||||||
{
|
{
|
||||||
$this->modifyNtfsTime = (int) $modifyNtfsTime;
|
$this->modifyNtfsTime = $modifyNtfsTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getAccessNtfsTime(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getAccessNtfsTime()
|
|
||||||
{
|
{
|
||||||
return $this->accessNtfsTime;
|
return $this->accessNtfsTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setAccessNtfsTime(int $accessNtfsTime): void
|
||||||
* @param int $accessNtfsTime
|
|
||||||
*/
|
|
||||||
public function setAccessNtfsTime($accessNtfsTime)
|
|
||||||
{
|
{
|
||||||
$this->accessNtfsTime = (int) $accessNtfsTime;
|
$this->accessNtfsTime = $accessNtfsTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCreateNtfsTime(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getCreateNtfsTime()
|
|
||||||
{
|
{
|
||||||
return $this->createNtfsTime;
|
return $this->createNtfsTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setCreateNtfsTime(int $createNtfsTime): void
|
||||||
* @param int $createNtfsTime
|
|
||||||
*/
|
|
||||||
public function setCreateNtfsTime($createNtfsTime)
|
|
||||||
{
|
{
|
||||||
$this->createNtfsTime = (int) $createNtfsTime;
|
$this->createNtfsTime = $createNtfsTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -211,95 +194,63 @@ class NtfsExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
return $this->packLocalFileData();
|
return $this->packLocalFileData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getModifyDateTime(): \DateTimeInterface
|
||||||
* @return \DateTimeInterface
|
|
||||||
*/
|
|
||||||
public function getModifyDateTime()
|
|
||||||
{
|
{
|
||||||
return self::ntfsTimeToDateTime($this->modifyNtfsTime);
|
return self::ntfsTimeToDateTime($this->modifyNtfsTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setModifyDateTime(\DateTimeInterface $modifyTime): void
|
||||||
* @param \DateTimeInterface $modifyTime
|
|
||||||
*/
|
|
||||||
public function setModifyDateTime(\DateTimeInterface $modifyTime)
|
|
||||||
{
|
{
|
||||||
$this->modifyNtfsTime = self::dateTimeToNtfsTime($modifyTime);
|
$this->modifyNtfsTime = self::dateTimeToNtfsTime($modifyTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getAccessDateTime(): \DateTimeInterface
|
||||||
* @return \DateTimeInterface
|
|
||||||
*/
|
|
||||||
public function getAccessDateTime()
|
|
||||||
{
|
{
|
||||||
return self::ntfsTimeToDateTime($this->accessNtfsTime);
|
return self::ntfsTimeToDateTime($this->accessNtfsTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setAccessDateTime(\DateTimeInterface $accessTime): void
|
||||||
* @param \DateTimeInterface $accessTime
|
|
||||||
*/
|
|
||||||
public function setAccessDateTime(\DateTimeInterface $accessTime)
|
|
||||||
{
|
{
|
||||||
$this->accessNtfsTime = self::dateTimeToNtfsTime($accessTime);
|
$this->accessNtfsTime = self::dateTimeToNtfsTime($accessTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCreateDateTime(): \DateTimeInterface
|
||||||
* @return \DateTimeInterface
|
|
||||||
*/
|
|
||||||
public function getCreateDateTime()
|
|
||||||
{
|
{
|
||||||
return self::ntfsTimeToDateTime($this->createNtfsTime);
|
return self::ntfsTimeToDateTime($this->createNtfsTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setCreateDateTime(\DateTimeInterface $createTime): void
|
||||||
* @param \DateTimeInterface $createTime
|
|
||||||
*/
|
|
||||||
public function setCreateDateTime(\DateTimeInterface $createTime)
|
|
||||||
{
|
{
|
||||||
$this->createNtfsTime = self::dateTimeToNtfsTime($createTime);
|
$this->createNtfsTime = self::dateTimeToNtfsTime($createTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param float $timestamp Float timestamp
|
* @param float $timestamp Float timestamp
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public static function timestampToNtfsTime($timestamp)
|
public static function timestampToNtfsTime(float $timestamp): int
|
||||||
{
|
{
|
||||||
return (int) (((float) $timestamp * 10000000) - self::EPOCH_OFFSET);
|
return (int) (($timestamp * 10000000) - self::EPOCH_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function dateTimeToNtfsTime(\DateTimeInterface $dateTime): int
|
||||||
* @param \DateTimeInterface $dateTime
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public static function dateTimeToNtfsTime(\DateTimeInterface $dateTime)
|
|
||||||
{
|
{
|
||||||
return self::timestampToNtfsTime((float) $dateTime->format('U.u'));
|
return self::timestampToNtfsTime((float) $dateTime->format('U.u'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $ntfsTime
|
|
||||||
*
|
|
||||||
* @return float Float unix timestamp
|
* @return float Float unix timestamp
|
||||||
*/
|
*/
|
||||||
public static function ntfsTimeToTimestamp($ntfsTime)
|
public static function ntfsTimeToTimestamp(int $ntfsTime): float
|
||||||
{
|
{
|
||||||
return (float) (($ntfsTime + self::EPOCH_OFFSET) / 10000000);
|
return (float) (($ntfsTime + self::EPOCH_OFFSET) / 10000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function ntfsTimeToDateTime(int $ntfsTime): \DateTimeInterface
|
||||||
* @param int $ntfsTime
|
|
||||||
*
|
|
||||||
* @return \DateTimeInterface
|
|
||||||
*/
|
|
||||||
public static function ntfsTimeToDateTime($ntfsTime)
|
|
||||||
{
|
{
|
||||||
$timestamp = self::ntfsTimeToTimestamp($ntfsTime);
|
$timestamp = self::ntfsTimeToTimestamp($ntfsTime);
|
||||||
$dateTime = \DateTimeImmutable::createFromFormat('U.u', sprintf('%.6f', $timestamp));
|
$dateTime = \DateTimeImmutable::createFromFormat('U.u', sprintf('%.6f', $timestamp));
|
||||||
@ -311,10 +262,7 @@ class NtfsExtraField implements ZipExtraField
|
|||||||
return $dateTime;
|
return $dateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
$args = [self::HEADER_ID];
|
$args = [self::HEADER_ID];
|
||||||
$format = '0x%04x NtfsExtra:';
|
$format = '0x%04x NtfsExtra:';
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Model\Extra\ZipExtraField;
|
use PhpZip\Model\Extra\ZipExtraField;
|
||||||
@ -56,27 +65,21 @@ use PhpZip\Model\ZipEntry;
|
|||||||
class OldUnixExtraField implements ZipExtraField
|
class OldUnixExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
/** @var int Header id */
|
/** @var int Header id */
|
||||||
const HEADER_ID = 0x5855;
|
public const HEADER_ID = 0x5855;
|
||||||
|
|
||||||
/** @var int|null Access timestamp */
|
/** @var int|null Access timestamp */
|
||||||
private $accessTime;
|
private ?int $accessTime;
|
||||||
|
|
||||||
/** @var int|null Modify timestamp */
|
/** @var int|null Modify timestamp */
|
||||||
private $modifyTime;
|
private ?int $modifyTime;
|
||||||
|
|
||||||
/** @var int|null User id */
|
/** @var int|null User id */
|
||||||
private $uid;
|
private ?int $uid;
|
||||||
|
|
||||||
/** @var int|null Group id */
|
/** @var int|null Group id */
|
||||||
private $gid;
|
private ?int $gid;
|
||||||
|
|
||||||
/**
|
public function __construct(?int $accessTime, ?int $modifyTime, ?int $uid, ?int $gid)
|
||||||
* @param int|null $accessTime
|
|
||||||
* @param int|null $modifyTime
|
|
||||||
* @param int|null $uid
|
|
||||||
* @param int|null $gid
|
|
||||||
*/
|
|
||||||
public function __construct($accessTime, $modifyTime, $uid, $gid)
|
|
||||||
{
|
{
|
||||||
$this->accessTime = $accessTime;
|
$this->accessTime = $accessTime;
|
||||||
$this->modifyTime = $modifyTime;
|
$this->modifyTime = $modifyTime;
|
||||||
@ -88,10 +91,8 @@ class OldUnixExtraField implements ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
@ -99,12 +100,12 @@ class OldUnixExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @return OldUnixExtraField
|
* @return OldUnixExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
$length = \strlen($buffer);
|
$length = \strlen($buffer);
|
||||||
|
|
||||||
@ -132,12 +133,12 @@ class OldUnixExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @return OldUnixExtraField
|
* @return OldUnixExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
$length = \strlen($buffer);
|
$length = \strlen($buffer);
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ class OldUnixExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
$data = '';
|
$data = '';
|
||||||
|
|
||||||
@ -189,7 +190,7 @@ class OldUnixExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
$data = '';
|
$data = '';
|
||||||
|
|
||||||
@ -204,100 +205,67 @@ class OldUnixExtraField implements ZipExtraField
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getAccessTime(): ?int
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getAccessTime()
|
|
||||||
{
|
{
|
||||||
return $this->accessTime;
|
return $this->accessTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setAccessTime(?int $accessTime): void
|
||||||
* @param int|null $accessTime
|
|
||||||
*/
|
|
||||||
public function setAccessTime($accessTime)
|
|
||||||
{
|
{
|
||||||
$this->accessTime = $accessTime;
|
$this->accessTime = $accessTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getAccessDateTime(): ?\DateTimeInterface
|
||||||
* @return \DateTimeInterface|null
|
|
||||||
*/
|
|
||||||
public function getAccessDateTime()
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->accessTime === null ? null :
|
return $this->accessTime === null ? null
|
||||||
new \DateTimeImmutable('@' . $this->accessTime);
|
: new \DateTimeImmutable('@' . $this->accessTime);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getModifyTime(): ?int
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getModifyTime()
|
|
||||||
{
|
{
|
||||||
return $this->modifyTime;
|
return $this->modifyTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setModifyTime(?int $modifyTime): void
|
||||||
* @param int|null $modifyTime
|
|
||||||
*/
|
|
||||||
public function setModifyTime($modifyTime)
|
|
||||||
{
|
{
|
||||||
$this->modifyTime = $modifyTime;
|
$this->modifyTime = $modifyTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getModifyDateTime(): ?\DateTimeInterface
|
||||||
* @return \DateTimeInterface|null
|
|
||||||
*/
|
|
||||||
public function getModifyDateTime()
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->modifyTime === null ? null :
|
return $this->modifyTime === null ? null
|
||||||
new \DateTimeImmutable('@' . $this->modifyTime);
|
: new \DateTimeImmutable('@' . $this->modifyTime);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getUid(): ?int
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getUid()
|
|
||||||
{
|
{
|
||||||
return $this->uid;
|
return $this->uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setUid(?int $uid): void
|
||||||
* @param int|null $uid
|
|
||||||
*/
|
|
||||||
public function setUid($uid)
|
|
||||||
{
|
{
|
||||||
$this->uid = $uid;
|
$this->uid = $uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getGid(): ?int
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getGid()
|
|
||||||
{
|
{
|
||||||
return $this->gid;
|
return $this->gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setGid(?int $gid): void
|
||||||
* @param int|null $gid
|
|
||||||
*/
|
|
||||||
public function setGid($gid)
|
|
||||||
{
|
{
|
||||||
$this->gid = $gid;
|
$this->gid = $gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
$args = [self::HEADER_ID];
|
$args = [self::HEADER_ID];
|
||||||
$format = '0x%04x OldUnix:';
|
$format = '0x%04x OldUnix:';
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,24 +57,19 @@ namespace PhpZip\Model\Extra\Fields;
|
|||||||
*/
|
*/
|
||||||
class UnicodeCommentExtraField extends AbstractUnicodeExtraField
|
class UnicodeCommentExtraField extends AbstractUnicodeExtraField
|
||||||
{
|
{
|
||||||
const HEADER_ID = 0x6375;
|
public const HEADER_ID = 0x6375;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'0x%04x UnicodeComment: "%s"',
|
'0x%04x UnicodeComment: "%s"',
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,24 +58,19 @@ namespace PhpZip\Model\Extra\Fields;
|
|||||||
*/
|
*/
|
||||||
class UnicodePathExtraField extends AbstractUnicodeExtraField
|
class UnicodePathExtraField extends AbstractUnicodeExtraField
|
||||||
{
|
{
|
||||||
const HEADER_ID = 0x7075;
|
public const HEADER_ID = 0x7075;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'0x%04x UnicodePath: "%s"',
|
'0x%04x UnicodePath: "%s"',
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Exception\RuntimeException;
|
use PhpZip\Exception\RuntimeException;
|
||||||
@ -11,28 +20,18 @@ use PhpZip\Model\ZipEntry;
|
|||||||
*/
|
*/
|
||||||
class UnrecognizedExtraField implements ZipExtraField
|
class UnrecognizedExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
/** @var int */
|
private int $headerId;
|
||||||
private $headerId;
|
|
||||||
|
|
||||||
/** @var string extra field data without Header-ID or length specifier */
|
/** @var string extra field data without Header-ID or length specifier */
|
||||||
private $data;
|
private string $data;
|
||||||
|
|
||||||
/**
|
public function __construct(int $headerId, string $data)
|
||||||
* UnrecognizedExtraField constructor.
|
|
||||||
*
|
|
||||||
* @param int $headerId
|
|
||||||
* @param string $data
|
|
||||||
*/
|
|
||||||
public function __construct($headerId, $data)
|
|
||||||
{
|
{
|
||||||
$this->headerId = (int) $headerId;
|
$this->headerId = $headerId;
|
||||||
$this->data = (string) $data;
|
$this->data = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setHeaderId(int $headerId): void
|
||||||
* @param int $headerId
|
|
||||||
*/
|
|
||||||
public function setHeaderId($headerId)
|
|
||||||
{
|
{
|
||||||
$this->headerId = $headerId;
|
$this->headerId = $headerId;
|
||||||
}
|
}
|
||||||
@ -41,10 +40,8 @@ class UnrecognizedExtraField implements ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return $this->headerId;
|
return $this->headerId;
|
||||||
}
|
}
|
||||||
@ -52,10 +49,10 @@ class UnrecognizedExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): ZipExtraField
|
||||||
{
|
{
|
||||||
throw new RuntimeException('Unsupport parse');
|
throw new RuntimeException('Unsupport parse');
|
||||||
}
|
}
|
||||||
@ -63,10 +60,10 @@ class UnrecognizedExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): ZipExtraField
|
||||||
{
|
{
|
||||||
throw new RuntimeException('Unsupport parse');
|
throw new RuntimeException('Unsupport parse');
|
||||||
}
|
}
|
||||||
@ -74,7 +71,7 @@ class UnrecognizedExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
return $this->data;
|
return $this->data;
|
||||||
}
|
}
|
||||||
@ -82,31 +79,22 @@ class UnrecognizedExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
return $this->data;
|
return $this->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getData(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getData()
|
|
||||||
{
|
{
|
||||||
return $this->data;
|
return $this->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setData(string $data): void
|
||||||
* @param string $data
|
|
||||||
*/
|
|
||||||
public function setData($data)
|
|
||||||
{
|
{
|
||||||
$this->data = (string) $data;
|
$this->data = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
$args = [$this->headerId, $this->data];
|
$args = [$this->headerId, $this->data];
|
||||||
$format = '0x%04x Unrecognized Extra Field: "%s"';
|
$format = '0x%04x Unrecognized Extra Field: "%s"';
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Constants\ZipCompressionMethod;
|
use PhpZip\Constants\ZipCompressionMethod;
|
||||||
@ -18,69 +27,69 @@ use PhpZip\Model\ZipEntry;
|
|||||||
class WinZipAesExtraField implements ZipExtraField
|
class WinZipAesExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
/** @var int Header id */
|
/** @var int Header id */
|
||||||
const HEADER_ID = 0x9901;
|
public const HEADER_ID = 0x9901;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int Data size (currently 7, but subject to possible increase
|
* @var int Data size (currently 7, but subject to possible increase
|
||||||
* in the future)
|
* in the future)
|
||||||
*/
|
*/
|
||||||
const DATA_SIZE = 7;
|
public const DATA_SIZE = 7;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int The vendor ID field should always be set to the two ASCII
|
* @var int The vendor ID field should always be set to the two ASCII
|
||||||
* characters "AE"
|
* characters "AE"
|
||||||
*/
|
*/
|
||||||
const VENDOR_ID = 0x4541; // 'A' | ('E' << 8)
|
public const VENDOR_ID = 0x4541; // 'A' | ('E' << 8)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int Entries of this type do include the standard ZIP CRC-32 value.
|
* @var int Entries of this type do include the standard ZIP CRC-32 value.
|
||||||
* For use with {@see WinZipAesExtraField::setVendorVersion()}.
|
* For use with {@see WinZipAesExtraField::setVendorVersion()}.
|
||||||
*/
|
*/
|
||||||
const VERSION_AE1 = 1;
|
public const VERSION_AE1 = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int Entries of this type do not include the standard ZIP CRC-32 value.
|
* @var int Entries of this type do not include the standard ZIP CRC-32 value.
|
||||||
* For use with {@see WinZipAesExtraField::setVendorVersion().
|
* For use with {@see WinZipAesExtraField::setVendorVersion().
|
||||||
*/
|
*/
|
||||||
const VERSION_AE2 = 2;
|
public const VERSION_AE2 = 2;
|
||||||
|
|
||||||
/** @var int integer mode value indicating AES encryption 128-bit strength */
|
/** @var int integer mode value indicating AES encryption 128-bit strength */
|
||||||
const KEY_STRENGTH_128BIT = 0x01;
|
public const KEY_STRENGTH_128BIT = 0x01;
|
||||||
|
|
||||||
/** @var int integer mode value indicating AES encryption 192-bit strength */
|
/** @var int integer mode value indicating AES encryption 192-bit strength */
|
||||||
const KEY_STRENGTH_192BIT = 0x02;
|
public const KEY_STRENGTH_192BIT = 0x02;
|
||||||
|
|
||||||
/** @var int integer mode value indicating AES encryption 256-bit strength */
|
/** @var int integer mode value indicating AES encryption 256-bit strength */
|
||||||
const KEY_STRENGTH_256BIT = 0x03;
|
public const KEY_STRENGTH_256BIT = 0x03;
|
||||||
|
|
||||||
/** @var int[] */
|
/** @var int[] */
|
||||||
private static $allowVendorVersions = [
|
private const ALLOW_VENDOR_VERSIONS = [
|
||||||
self::VERSION_AE1,
|
self::VERSION_AE1,
|
||||||
self::VERSION_AE2,
|
self::VERSION_AE2,
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var array<int, int> */
|
/** @var array<int, int> */
|
||||||
private static $encryptionStrengths = [
|
private const ENCRYPTION_STRENGTHS = [
|
||||||
self::KEY_STRENGTH_128BIT => 128,
|
self::KEY_STRENGTH_128BIT => 128,
|
||||||
self::KEY_STRENGTH_192BIT => 192,
|
self::KEY_STRENGTH_192BIT => 192,
|
||||||
self::KEY_STRENGTH_256BIT => 256,
|
self::KEY_STRENGTH_256BIT => 256,
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var array<int, int> */
|
/** @var array<int, int> */
|
||||||
private static $MAP_KEY_STRENGTH_METHODS = [
|
private const MAP_KEY_STRENGTH_METHODS = [
|
||||||
self::KEY_STRENGTH_128BIT => ZipEncryptionMethod::WINZIP_AES_128,
|
self::KEY_STRENGTH_128BIT => ZipEncryptionMethod::WINZIP_AES_128,
|
||||||
self::KEY_STRENGTH_192BIT => ZipEncryptionMethod::WINZIP_AES_192,
|
self::KEY_STRENGTH_192BIT => ZipEncryptionMethod::WINZIP_AES_192,
|
||||||
self::KEY_STRENGTH_256BIT => ZipEncryptionMethod::WINZIP_AES_256,
|
self::KEY_STRENGTH_256BIT => ZipEncryptionMethod::WINZIP_AES_256,
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var int Integer version number specific to the zip vendor */
|
/** @var int Integer version number specific to the zip vendor */
|
||||||
private $vendorVersion = self::VERSION_AE1;
|
private int $vendorVersion = self::VERSION_AE1;
|
||||||
|
|
||||||
/** @var int Integer mode value indicating AES encryption strength */
|
/** @var int Integer mode value indicating AES encryption strength */
|
||||||
private $keyStrength = self::KEY_STRENGTH_256BIT;
|
private int $keyStrength = self::KEY_STRENGTH_256BIT;
|
||||||
|
|
||||||
/** @var int The actual compression method used to compress the file */
|
/** @var int The actual compression method used to compress the file */
|
||||||
private $compressionMethod;
|
private int $compressionMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $vendorVersion Integer version number specific to the zip vendor
|
* @param int $vendorVersion Integer version number specific to the zip vendor
|
||||||
@ -89,7 +98,7 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*/
|
*/
|
||||||
public function __construct($vendorVersion, $keyStrength, $compressionMethod)
|
public function __construct(int $vendorVersion, int $keyStrength, int $compressionMethod)
|
||||||
{
|
{
|
||||||
$this->setVendorVersion($vendorVersion);
|
$this->setVendorVersion($vendorVersion);
|
||||||
$this->setKeyStrength($keyStrength);
|
$this->setKeyStrength($keyStrength);
|
||||||
@ -97,15 +106,13 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*
|
*
|
||||||
* @return WinZipAesExtraField
|
* @return WinZipAesExtraField
|
||||||
*/
|
*/
|
||||||
public static function create(ZipEntry $entry)
|
public static function create(ZipEntry $entry): self
|
||||||
{
|
{
|
||||||
$keyStrength = array_search($entry->getEncryptionMethod(), self::$MAP_KEY_STRENGTH_METHODS, true);
|
$keyStrength = array_search($entry->getEncryptionMethod(), self::MAP_KEY_STRENGTH_METHODS, true);
|
||||||
|
|
||||||
if ($keyStrength === false) {
|
if ($keyStrength === false) {
|
||||||
throw new InvalidArgumentException('Not support encryption method ' . $entry->getEncryptionMethod());
|
throw new InvalidArgumentException('Not support encryption method ' . $entry->getEncryptionMethod());
|
||||||
@ -118,11 +125,11 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
//
|
//
|
||||||
// https://www.winzip.com/win/en/aes_info.html
|
// https://www.winzip.com/win/en/aes_info.html
|
||||||
$vendorVersion = (
|
$vendorVersion = (
|
||||||
$entry->getUncompressedSize() < 20 ||
|
$entry->getUncompressedSize() < 20
|
||||||
$entry->getCompressionMethod() === ZipCompressionMethod::BZIP2
|
|| $entry->getCompressionMethod() === ZipCompressionMethod::BZIP2
|
||||||
) ?
|
)
|
||||||
self::VERSION_AE2 :
|
? self::VERSION_AE2
|
||||||
self::VERSION_AE1;
|
: self::VERSION_AE1;
|
||||||
|
|
||||||
$field = new self($vendorVersion, $keyStrength, $entry->getCompressionMethod());
|
$field = new self($vendorVersion, $keyStrength, $entry->getCompressionMethod());
|
||||||
|
|
||||||
@ -136,10 +143,8 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
@ -147,14 +152,14 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException on error
|
* @throws ZipException on error
|
||||||
*
|
*
|
||||||
* @return WinZipAesExtraField
|
* @return WinZipAesExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
$size = \strlen($buffer);
|
$size = \strlen($buffer);
|
||||||
|
|
||||||
@ -168,36 +173,37 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = unpack('vvendorVersion/vvendorId/ckeyStrength/vcompressionMethod', $buffer);
|
[
|
||||||
|
'vendorVersion' => $vendorVersion,
|
||||||
|
'vendorId' => $vendorId,
|
||||||
|
'keyStrength' => $keyStrength,
|
||||||
|
'compressionMethod' => $compressionMethod,
|
||||||
|
] = unpack('vvendorVersion/vvendorId/ckeyStrength/vcompressionMethod', $buffer);
|
||||||
|
|
||||||
if ($data['vendorId'] !== self::VENDOR_ID) {
|
if ($vendorId !== self::VENDOR_ID) {
|
||||||
throw new ZipException(
|
throw new ZipException(
|
||||||
sprintf(
|
sprintf(
|
||||||
'Vendor id invalid: %d. Must be %d',
|
'Vendor id invalid: %d. Must be %d',
|
||||||
$data['vendorId'],
|
$vendorId,
|
||||||
self::VENDOR_ID
|
self::VENDOR_ID
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new self(
|
return new self($vendorVersion, $keyStrength, $compressionMethod);
|
||||||
$data['vendorVersion'],
|
|
||||||
$data['keyStrength'],
|
|
||||||
$data['compressionMethod']
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
*
|
||||||
* @return WinZipAesExtraField
|
* @return WinZipAesExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
return self::unpackLocalFileData($buffer, $entry);
|
return self::unpackLocalFileData($buffer, $entry);
|
||||||
}
|
}
|
||||||
@ -208,7 +214,7 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
return pack(
|
return pack(
|
||||||
'vvcv',
|
'vvcv',
|
||||||
@ -225,7 +231,7 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
return $this->packLocalFileData();
|
return $this->packLocalFileData();
|
||||||
}
|
}
|
||||||
@ -233,12 +239,10 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Returns the vendor version.
|
* Returns the vendor version.
|
||||||
*
|
*
|
||||||
* @return int
|
|
||||||
*
|
|
||||||
* @see WinZipAesExtraField::VERSION_AE2
|
* @see WinZipAesExtraField::VERSION_AE2
|
||||||
* @see WinZipAesExtraField::VERSION_AE1
|
* @see WinZipAesExtraField::VERSION_AE1
|
||||||
*/
|
*/
|
||||||
public function getVendorVersion()
|
public function getVendorVersion(): int
|
||||||
{
|
{
|
||||||
return $this->vendorVersion;
|
return $this->vendorVersion;
|
||||||
}
|
}
|
||||||
@ -251,11 +255,9 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
* @see WinZipAesExtraField::VERSION_AE2
|
* @see WinZipAesExtraField::VERSION_AE2
|
||||||
* @see WinZipAesExtraField::VERSION_AE1
|
* @see WinZipAesExtraField::VERSION_AE1
|
||||||
*/
|
*/
|
||||||
public function setVendorVersion($vendorVersion)
|
public function setVendorVersion(int $vendorVersion): void
|
||||||
{
|
{
|
||||||
$vendorVersion = (int) $vendorVersion;
|
if (!\in_array($vendorVersion, self::ALLOW_VENDOR_VERSIONS, true)) {
|
||||||
|
|
||||||
if (!\in_array($vendorVersion, self::$allowVendorVersions, true)) {
|
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
sprintf(
|
sprintf(
|
||||||
'Unsupport WinZip AES vendor version: %d',
|
'Unsupport WinZip AES vendor version: %d',
|
||||||
@ -268,113 +270,80 @@ class WinZipAesExtraField implements ZipExtraField
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns vendor id.
|
* Returns vendor id.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getVendorId()
|
public function getVendorId(): int
|
||||||
{
|
{
|
||||||
return self::VENDOR_ID;
|
return self::VENDOR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getKeyStrength(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getKeyStrength()
|
|
||||||
{
|
{
|
||||||
return $this->keyStrength;
|
return $this->keyStrength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set key strength.
|
* Set key strength.
|
||||||
*
|
|
||||||
* @param int $keyStrength
|
|
||||||
*/
|
*/
|
||||||
public function setKeyStrength($keyStrength)
|
public function setKeyStrength(int $keyStrength): void
|
||||||
{
|
{
|
||||||
$keyStrength = (int) $keyStrength;
|
if (!isset(self::ENCRYPTION_STRENGTHS[$keyStrength])) {
|
||||||
|
|
||||||
if (!isset(self::$encryptionStrengths[$keyStrength])) {
|
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
sprintf(
|
sprintf(
|
||||||
'Key strength %d not support value. Allow values: %s',
|
'Key strength %d not support value. Allow values: %s',
|
||||||
$keyStrength,
|
$keyStrength,
|
||||||
implode(', ', array_keys(self::$encryptionStrengths))
|
implode(', ', array_keys(self::ENCRYPTION_STRENGTHS))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$this->keyStrength = $keyStrength;
|
$this->keyStrength = $keyStrength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCompressionMethod(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getCompressionMethod()
|
|
||||||
{
|
{
|
||||||
return $this->compressionMethod;
|
return $this->compressionMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $compressionMethod
|
|
||||||
*
|
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*/
|
*/
|
||||||
public function setCompressionMethod($compressionMethod)
|
public function setCompressionMethod(int $compressionMethod): void
|
||||||
{
|
{
|
||||||
$compressionMethod = (int) $compressionMethod;
|
|
||||||
ZipCompressionMethod::checkSupport($compressionMethod);
|
ZipCompressionMethod::checkSupport($compressionMethod);
|
||||||
$this->compressionMethod = $compressionMethod;
|
$this->compressionMethod = $compressionMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getEncryptionStrength(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getEncryptionStrength()
|
|
||||||
{
|
{
|
||||||
return self::$encryptionStrengths[$this->keyStrength];
|
return self::ENCRYPTION_STRENGTHS[$this->keyStrength];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getEncryptionMethod(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getEncryptionMethod()
|
|
||||||
{
|
{
|
||||||
$keyStrength = $this->getKeyStrength();
|
$keyStrength = $this->getKeyStrength();
|
||||||
|
|
||||||
if (!isset(self::$MAP_KEY_STRENGTH_METHODS[$keyStrength])) {
|
if (!isset(self::MAP_KEY_STRENGTH_METHODS[$keyStrength])) {
|
||||||
throw new InvalidArgumentException('Invalid encryption method');
|
throw new InvalidArgumentException('Invalid encryption method');
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$MAP_KEY_STRENGTH_METHODS[$keyStrength];
|
return self::MAP_KEY_STRENGTH_METHODS[$keyStrength];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isV1(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isV1()
|
|
||||||
{
|
{
|
||||||
return $this->vendorVersion === self::VERSION_AE1;
|
return $this->vendorVersion === self::VERSION_AE1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isV2(): bool
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isV2()
|
|
||||||
{
|
{
|
||||||
return $this->vendorVersion === self::VERSION_AE2;
|
return $this->vendorVersion === self::VERSION_AE2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getSaltSize(): int
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getSaltSize()
|
|
||||||
{
|
{
|
||||||
return (int) ($this->getEncryptionStrength() / 8 / 2);
|
return (int) ($this->getEncryptionStrength() / 8 / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'0x%04x WINZIP AES: VendorVersion=%d KeyStrength=0x%02x CompressionMethod=%s',
|
'0x%04x WINZIP AES: VendorVersion=%d KeyStrength=0x%02x CompressionMethod=%s',
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra\Fields;
|
namespace PhpZip\Model\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Constants\ZipConstants;
|
use PhpZip\Constants\ZipConstants;
|
||||||
@ -7,7 +16,6 @@ use PhpZip\Exception\RuntimeException;
|
|||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
use PhpZip\Model\Extra\ZipExtraField;
|
use PhpZip\Model\Extra\ZipExtraField;
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
use PhpZip\Util\PackUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ZIP64 Extra Field.
|
* ZIP64 Extra Field.
|
||||||
@ -17,33 +25,21 @@ use PhpZip\Util\PackUtil;
|
|||||||
class Zip64ExtraField implements ZipExtraField
|
class Zip64ExtraField implements ZipExtraField
|
||||||
{
|
{
|
||||||
/** @var int The Header ID for a ZIP64 Extended Information Extra Field. */
|
/** @var int The Header ID for a ZIP64 Extended Information Extra Field. */
|
||||||
const HEADER_ID = 0x0001;
|
public const HEADER_ID = 0x0001;
|
||||||
|
|
||||||
/** @var int|null */
|
private ?int $uncompressedSize;
|
||||||
private $uncompressedSize;
|
|
||||||
|
|
||||||
/** @var int|null */
|
private ?int $compressedSize;
|
||||||
private $compressedSize;
|
|
||||||
|
|
||||||
/** @var int|null */
|
private ?int $localHeaderOffset;
|
||||||
private $localHeaderOffset;
|
|
||||||
|
|
||||||
/** @var int|null */
|
private ?int $diskStart;
|
||||||
private $diskStart;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Zip64ExtraField constructor.
|
|
||||||
*
|
|
||||||
* @param int|null $uncompressedSize
|
|
||||||
* @param int|null $compressedSize
|
|
||||||
* @param int|null $localHeaderOffset
|
|
||||||
* @param int|null $diskStart
|
|
||||||
*/
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$uncompressedSize = null,
|
?int $uncompressedSize = null,
|
||||||
$compressedSize = null,
|
?int $compressedSize = null,
|
||||||
$localHeaderOffset = null,
|
?int $localHeaderOffset = null,
|
||||||
$diskStart = null
|
?int $diskStart = null
|
||||||
) {
|
) {
|
||||||
$this->uncompressedSize = $uncompressedSize;
|
$this->uncompressedSize = $uncompressedSize;
|
||||||
$this->compressedSize = $compressedSize;
|
$this->compressedSize = $compressedSize;
|
||||||
@ -55,10 +51,8 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId()
|
public function getHeaderId(): int
|
||||||
{
|
{
|
||||||
return self::HEADER_ID;
|
return self::HEADER_ID;
|
||||||
}
|
}
|
||||||
@ -66,14 +60,14 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException on error
|
* @throws ZipException on error
|
||||||
*
|
*
|
||||||
* @return Zip64ExtraField
|
* @return Zip64ExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
$length = \strlen($buffer);
|
$length = \strlen($buffer);
|
||||||
|
|
||||||
@ -91,8 +85,10 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$uncompressedSize = PackUtil::unpackLongLE(substr($buffer, 0, 8));
|
[
|
||||||
$compressedSize = PackUtil::unpackLongLE(substr($buffer, 8, 8));
|
'uncompressedSize' => $uncompressedSize,
|
||||||
|
'compressedSize' => $compressedSize,
|
||||||
|
] = unpack('PuncompressedSize/PcompressedSize', substr($buffer, 0, 16));
|
||||||
|
|
||||||
return new self($uncompressedSize, $compressedSize);
|
return new self($uncompressedSize, $compressedSize);
|
||||||
}
|
}
|
||||||
@ -100,14 +96,14 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
*
|
||||||
* @return Zip64ExtraField
|
* @return Zip64ExtraField
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self
|
||||||
{
|
{
|
||||||
if ($entry === null) {
|
if ($entry === null) {
|
||||||
throw new RuntimeException('zipEntry is null');
|
throw new RuntimeException('zipEntry is null');
|
||||||
@ -125,7 +121,7 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
if ($remaining < 8) {
|
if ($remaining < 8) {
|
||||||
throw new ZipException('ZIP64 extension corrupt (no uncompressed size).');
|
throw new ZipException('ZIP64 extension corrupt (no uncompressed size).');
|
||||||
}
|
}
|
||||||
$uncompressedSize = PackUtil::unpackLongLE(substr($buffer, $length - $remaining, 8));
|
$uncompressedSize = unpack('P', substr($buffer, $length - $remaining, 8))[1];
|
||||||
$remaining -= 8;
|
$remaining -= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +129,7 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
if ($remaining < 8) {
|
if ($remaining < 8) {
|
||||||
throw new ZipException('ZIP64 extension corrupt (no compressed size).');
|
throw new ZipException('ZIP64 extension corrupt (no compressed size).');
|
||||||
}
|
}
|
||||||
$compressedSize = PackUtil::unpackLongLE(substr($buffer, $length - $remaining, 8));
|
$compressedSize = unpack('P', substr($buffer, $length - $remaining, 8))[1];
|
||||||
$remaining -= 8;
|
$remaining -= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +137,7 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
if ($remaining < 8) {
|
if ($remaining < 8) {
|
||||||
throw new ZipException('ZIP64 extension corrupt (no relative local header offset).');
|
throw new ZipException('ZIP64 extension corrupt (no relative local header offset).');
|
||||||
}
|
}
|
||||||
$localHeaderOffset = PackUtil::unpackLongLE(substr($buffer, $length - $remaining, 8));
|
$localHeaderOffset = unpack('P', substr($buffer, $length - $remaining, 8))[1];
|
||||||
$remaining -= 8;
|
$remaining -= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +154,7 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData()
|
public function packLocalFileData(): string
|
||||||
{
|
{
|
||||||
if ($this->uncompressedSize !== null || $this->compressedSize !== null) {
|
if ($this->uncompressedSize !== null || $this->compressedSize !== null) {
|
||||||
if ($this->uncompressedSize === null || $this->compressedSize === null) {
|
if ($this->uncompressedSize === null || $this->compressedSize === null) {
|
||||||
@ -173,19 +169,16 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function packSizes(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function packSizes()
|
|
||||||
{
|
{
|
||||||
$data = '';
|
$data = '';
|
||||||
|
|
||||||
if ($this->uncompressedSize !== null) {
|
if ($this->uncompressedSize !== null) {
|
||||||
$data .= PackUtil::packLongLE($this->uncompressedSize);
|
$data .= pack('P', $this->uncompressedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->compressedSize !== null) {
|
if ($this->compressedSize !== null) {
|
||||||
$data .= PackUtil::packLongLE($this->compressedSize);
|
$data .= pack('P', $this->compressedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
@ -197,12 +190,12 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData()
|
public function packCentralDirData(): string
|
||||||
{
|
{
|
||||||
$data = $this->packSizes();
|
$data = $this->packSizes();
|
||||||
|
|
||||||
if ($this->localHeaderOffset !== null) {
|
if ($this->localHeaderOffset !== null) {
|
||||||
$data .= PackUtil::packLongLE($this->localHeaderOffset);
|
$data .= pack('P', $this->localHeaderOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->diskStart !== null) {
|
if ($this->diskStart !== null) {
|
||||||
@ -212,74 +205,47 @@ class Zip64ExtraField implements ZipExtraField
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getUncompressedSize(): ?int
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getUncompressedSize()
|
|
||||||
{
|
{
|
||||||
return $this->uncompressedSize;
|
return $this->uncompressedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setUncompressedSize(?int $uncompressedSize): void
|
||||||
* @param int|null $uncompressedSize
|
|
||||||
*/
|
|
||||||
public function setUncompressedSize($uncompressedSize)
|
|
||||||
{
|
{
|
||||||
$this->uncompressedSize = $uncompressedSize;
|
$this->uncompressedSize = $uncompressedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCompressedSize(): ?int
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getCompressedSize()
|
|
||||||
{
|
{
|
||||||
return $this->compressedSize;
|
return $this->compressedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setCompressedSize(?int $compressedSize): void
|
||||||
* @param int|null $compressedSize
|
|
||||||
*/
|
|
||||||
public function setCompressedSize($compressedSize)
|
|
||||||
{
|
{
|
||||||
$this->compressedSize = $compressedSize;
|
$this->compressedSize = $compressedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getLocalHeaderOffset(): ?int
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getLocalHeaderOffset()
|
|
||||||
{
|
{
|
||||||
return $this->localHeaderOffset;
|
return $this->localHeaderOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setLocalHeaderOffset(?int $localHeaderOffset): void
|
||||||
* @param int|null $localHeaderOffset
|
|
||||||
*/
|
|
||||||
public function setLocalHeaderOffset($localHeaderOffset)
|
|
||||||
{
|
{
|
||||||
$this->localHeaderOffset = $localHeaderOffset;
|
$this->localHeaderOffset = $localHeaderOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getDiskStart(): ?int
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getDiskStart()
|
|
||||||
{
|
{
|
||||||
return $this->diskStart;
|
return $this->diskStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setDiskStart(?int $diskStart): void
|
||||||
* @param int|null $diskStart
|
|
||||||
*/
|
|
||||||
public function setDiskStart($diskStart)
|
|
||||||
{
|
{
|
||||||
$this->diskStart = $diskStart;
|
$this->diskStart = $diskStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
{
|
||||||
$args = [self::HEADER_ID];
|
$args = [self::HEADER_ID];
|
||||||
$format = '0x%04x ZIP64: ';
|
$format = '0x%04x ZIP64: ';
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra;
|
namespace PhpZip\Model\Extra;
|
||||||
|
|
||||||
use PhpZip\Exception\InvalidArgumentException;
|
use PhpZip\Exception\InvalidArgumentException;
|
||||||
@ -22,9 +31,9 @@ final class ZipExtraDriver
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var array<int, string>
|
* @var array<int, string>
|
||||||
* @psalm-var array<int, class-string<\PhpZip\Model\Extra\ZipExtraField>>
|
* @psalm-var array<int, class-string<ZipExtraField>>
|
||||||
*/
|
*/
|
||||||
private static $implementations = [
|
private static array $implementations = [
|
||||||
ApkAlignmentExtraField::HEADER_ID => ApkAlignmentExtraField::class,
|
ApkAlignmentExtraField::HEADER_ID => ApkAlignmentExtraField::class,
|
||||||
AsiExtraField::HEADER_ID => AsiExtraField::class,
|
AsiExtraField::HEADER_ID => AsiExtraField::class,
|
||||||
ExtendedTimestampExtraField::HEADER_ID => ExtendedTimestampExtraField::class,
|
ExtendedTimestampExtraField::HEADER_ID => ExtendedTimestampExtraField::class,
|
||||||
@ -45,7 +54,7 @@ final class ZipExtraDriver
|
|||||||
/**
|
/**
|
||||||
* @param string|ZipExtraField $extraField ZipExtraField object or class name
|
* @param string|ZipExtraField $extraField ZipExtraField object or class name
|
||||||
*/
|
*/
|
||||||
public static function register($extraField)
|
public static function register($extraField): void
|
||||||
{
|
{
|
||||||
if (!is_a($extraField, ZipExtraField::class, true)) {
|
if (!is_a($extraField, ZipExtraField::class, true)) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
@ -61,10 +70,8 @@ final class ZipExtraDriver
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int|string|ZipExtraField $extraType ZipExtraField object or class name or extra header id
|
* @param int|string|ZipExtraField $extraType ZipExtraField object or class name or extra header id
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public static function unregister($extraType)
|
public static function unregister($extraType): bool
|
||||||
{
|
{
|
||||||
$headerId = null;
|
$headerId = null;
|
||||||
|
|
||||||
@ -85,23 +92,12 @@ final class ZipExtraDriver
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function getClassNameOrNull(int $headerId): ?string
|
||||||
* @param int $headerId
|
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public static function getClassNameOrNull($headerId)
|
|
||||||
{
|
{
|
||||||
$headerId = (int) $headerId;
|
|
||||||
|
|
||||||
if ($headerId < 0 || $headerId > 0xffff) {
|
if ($headerId < 0 || $headerId > 0xffff) {
|
||||||
throw new \InvalidArgumentException('$headerId out of range: ' . $headerId);
|
throw new \InvalidArgumentException('$headerId out of range: ' . $headerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset(self::$implementations[$headerId])) {
|
return self::$implementations[$headerId] ?? null;
|
||||||
return self::$implementations[$headerId];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model\Extra;
|
namespace PhpZip\Model\Extra;
|
||||||
|
|
||||||
use PhpZip\Model\ZipEntry;
|
use PhpZip\Model\ZipEntry;
|
||||||
@ -15,30 +24,28 @@ interface ZipExtraField
|
|||||||
* Returns the Header ID (type) of this Extra Field.
|
* Returns the Header ID (type) of this Extra Field.
|
||||||
* The Header ID is an unsigned short integer (two bytes)
|
* The Header ID is an unsigned short integer (two bytes)
|
||||||
* which must be constant during the life cycle of this object.
|
* which must be constant during the life cycle of this object.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getHeaderId();
|
public function getHeaderId(): int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in local file data.
|
* Populate data from this array as if it was in local file data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function unpackLocalFileData($buffer, ZipEntry $entry = null);
|
public static function unpackLocalFileData(string $buffer, ?ZipEntry $entry = null): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate data from this array as if it was in central directory data.
|
* Populate data from this array as if it was in central directory data.
|
||||||
*
|
*
|
||||||
* @param string $buffer the buffer to read data from
|
* @param string $buffer the buffer to read data from
|
||||||
* @param ZipEntry|null $entry
|
* @param ?ZipEntry $entry
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function unpackCentralDirData($buffer, ZipEntry $entry = null);
|
public static function unpackCentralDirData(string $buffer, ?ZipEntry $entry = null): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual data to put into local file data - without Header-ID
|
* The actual data to put into local file data - without Header-ID
|
||||||
@ -46,7 +53,7 @@ interface ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packLocalFileData();
|
public function packLocalFileData(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual data to put into central directory - without Header-ID or
|
* The actual data to put into central directory - without Header-ID or
|
||||||
@ -54,10 +61,7 @@ interface ZipExtraField
|
|||||||
*
|
*
|
||||||
* @return string the data
|
* @return string the data
|
||||||
*/
|
*/
|
||||||
public function packCentralDirData();
|
public function packCentralDirData(): string;
|
||||||
|
|
||||||
/**
|
public function __toString(): string;
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString();
|
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model;
|
namespace PhpZip\Model;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ImmutableZipContainer.
|
|
||||||
*/
|
|
||||||
class ImmutableZipContainer implements \Countable
|
class ImmutableZipContainer implements \Countable
|
||||||
{
|
{
|
||||||
/** @var ZipEntry[] */
|
/** @var ZipEntry[] */
|
||||||
protected $entries;
|
protected array $entries;
|
||||||
|
|
||||||
/** @var string|null Archive comment */
|
/** @var string|null Archive comment */
|
||||||
protected $archiveComment;
|
protected ?string $archiveComment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ZipContainer constructor.
|
* @param ZipEntry[] $entries
|
||||||
*
|
* @param ?string $archiveComment
|
||||||
* @param ZipEntry[] $entries
|
|
||||||
* @param string|null $archiveComment
|
|
||||||
*/
|
*/
|
||||||
public function __construct(array $entries, $archiveComment)
|
public function __construct(array $entries, ?string $archiveComment = null)
|
||||||
{
|
{
|
||||||
$this->entries = $entries;
|
$this->entries = $entries;
|
||||||
$this->archiveComment = $archiveComment;
|
$this->archiveComment = $archiveComment;
|
||||||
@ -28,15 +32,12 @@ class ImmutableZipContainer implements \Countable
|
|||||||
/**
|
/**
|
||||||
* @return ZipEntry[]
|
* @return ZipEntry[]
|
||||||
*/
|
*/
|
||||||
public function &getEntries()
|
public function &getEntries(): array
|
||||||
{
|
{
|
||||||
return $this->entries;
|
return $this->entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getArchiveComment(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getArchiveComment()
|
|
||||||
{
|
{
|
||||||
return $this->archiveComment;
|
return $this->archiveComment;
|
||||||
}
|
}
|
||||||
@ -49,7 +50,7 @@ class ImmutableZipContainer implements \Countable
|
|||||||
* @return int The custom count as an integer.
|
* @return int The custom count as an integer.
|
||||||
* The return value is cast to an integer.
|
* The return value is cast to an integer.
|
||||||
*/
|
*/
|
||||||
public function count()
|
public function count(): int
|
||||||
{
|
{
|
||||||
return \count($this->entries);
|
return \count($this->entries);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model;
|
namespace PhpZip\Model;
|
||||||
|
|
||||||
use PhpZip\Constants\ZipEncryptionMethod;
|
use PhpZip\Constants\ZipEncryptionMethod;
|
||||||
@ -8,7 +17,7 @@ use PhpZip\Exception\ZipEntryNotFoundException;
|
|||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ZipContainer.
|
* Zip Container.
|
||||||
*/
|
*/
|
||||||
class ZipContainer extends ImmutableZipContainer
|
class ZipContainer extends ImmutableZipContainer
|
||||||
{
|
{
|
||||||
@ -18,21 +27,9 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
* it possible to undo changes in the archive.
|
* it possible to undo changes in the archive.
|
||||||
* When cloning, this container is not cloned.
|
* When cloning, this container is not cloned.
|
||||||
*/
|
*/
|
||||||
private $sourceContainer;
|
private ?ImmutableZipContainer $sourceContainer;
|
||||||
|
|
||||||
/**
|
public function __construct(?ImmutableZipContainer $sourceContainer = null)
|
||||||
* @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 = [];
|
$entries = [];
|
||||||
$archiveComment = null;
|
$archiveComment = null;
|
||||||
@ -47,28 +44,20 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
$this->sourceContainer = $sourceContainer;
|
$this->sourceContainer = $sourceContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getSourceContainer(): ?ImmutableZipContainer
|
||||||
* @return ImmutableZipContainer|null
|
|
||||||
*/
|
|
||||||
public function getSourceContainer()
|
|
||||||
{
|
{
|
||||||
return $this->sourceContainer;
|
return $this->sourceContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function addEntry(ZipEntry $entry): void
|
||||||
* @param ZipEntry $entry
|
|
||||||
*/
|
|
||||||
public function addEntry(ZipEntry $entry)
|
|
||||||
{
|
{
|
||||||
$this->entries[$entry->getName()] = $entry;
|
$this->entries[$entry->getName()] = $entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|ZipEntry $entry
|
* @param string|ZipEntry $entry
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function deleteEntry($entry)
|
public function deleteEntry($entry): bool
|
||||||
{
|
{
|
||||||
$entry = $entry instanceof ZipEntry ? $entry->getName() : (string) $entry;
|
$entry = $entry instanceof ZipEntry ? $entry->getName() : (string) $entry;
|
||||||
|
|
||||||
@ -89,7 +78,7 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
*
|
*
|
||||||
* @return ZipEntry New zip entry
|
* @return ZipEntry New zip entry
|
||||||
*/
|
*/
|
||||||
public function renameEntry($old, $new)
|
public function renameEntry($old, $new): ZipEntry
|
||||||
{
|
{
|
||||||
$old = $old instanceof ZipEntry ? $old->getName() : (string) $old;
|
$old = $old instanceof ZipEntry ? $old->getName() : (string) $old;
|
||||||
$new = $new instanceof ZipEntry ? $new->getName() : (string) $new;
|
$new = $new instanceof ZipEntry ? $new->getName() : (string) $new;
|
||||||
@ -111,10 +100,8 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
* @param string|ZipEntry $entryName
|
* @param string|ZipEntry $entryName
|
||||||
*
|
*
|
||||||
* @throws ZipEntryNotFoundException
|
* @throws ZipEntryNotFoundException
|
||||||
*
|
|
||||||
* @return ZipEntry
|
|
||||||
*/
|
*/
|
||||||
public function getEntry($entryName)
|
public function getEntry($entryName): ZipEntry
|
||||||
{
|
{
|
||||||
$entry = $this->getEntryOrNull($entryName);
|
$entry = $this->getEntryOrNull($entryName);
|
||||||
|
|
||||||
@ -127,22 +114,18 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|ZipEntry $entryName
|
* @param string|ZipEntry $entryName
|
||||||
*
|
|
||||||
* @return ZipEntry|null
|
|
||||||
*/
|
*/
|
||||||
public function getEntryOrNull($entryName)
|
public function getEntryOrNull($entryName): ?ZipEntry
|
||||||
{
|
{
|
||||||
$entryName = $entryName instanceof ZipEntry ? $entryName->getName() : (string) $entryName;
|
$entryName = $entryName instanceof ZipEntry ? $entryName->getName() : (string) $entryName;
|
||||||
|
|
||||||
return isset($this->entries[$entryName]) ? $this->entries[$entryName] : null;
|
return $this->entries[$entryName] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|ZipEntry $entryName
|
* @param string|ZipEntry $entryName
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function hasEntry($entryName)
|
public function hasEntry($entryName): bool
|
||||||
{
|
{
|
||||||
$entryName = $entryName instanceof ZipEntry ? $entryName->getName() : (string) $entryName;
|
$entryName = $entryName instanceof ZipEntry ? $entryName->getName() : (string) $entryName;
|
||||||
|
|
||||||
@ -152,7 +135,7 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
/**
|
/**
|
||||||
* Delete all entries.
|
* Delete all entries.
|
||||||
*/
|
*/
|
||||||
public function deleteAll()
|
public function deleteAll(): void
|
||||||
{
|
{
|
||||||
$this->entries = [];
|
$this->entries = [];
|
||||||
}
|
}
|
||||||
@ -164,7 +147,7 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
*
|
*
|
||||||
* @return ZipEntry[] Deleted entries
|
* @return ZipEntry[] Deleted entries
|
||||||
*/
|
*/
|
||||||
public function deleteByRegex($regexPattern)
|
public function deleteByRegex(string $regexPattern): array
|
||||||
{
|
{
|
||||||
if (empty($regexPattern)) {
|
if (empty($regexPattern)) {
|
||||||
throw new InvalidArgumentException('The regex pattern is not specified');
|
throw new InvalidArgumentException('The regex pattern is not specified');
|
||||||
@ -189,7 +172,7 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
/**
|
/**
|
||||||
* Undo all changes done in the archive.
|
* Undo all changes done in the archive.
|
||||||
*/
|
*/
|
||||||
public function unchangeAll()
|
public function unchangeAll(): void
|
||||||
{
|
{
|
||||||
$this->entries = [];
|
$this->entries = [];
|
||||||
|
|
||||||
@ -204,7 +187,7 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
/**
|
/**
|
||||||
* Undo change archive comment.
|
* Undo change archive comment.
|
||||||
*/
|
*/
|
||||||
public function unchangeArchiveComment()
|
public function unchangeArchiveComment(): void
|
||||||
{
|
{
|
||||||
$this->archiveComment = null;
|
$this->archiveComment = null;
|
||||||
|
|
||||||
@ -217,16 +200,14 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
* Revert all changes done to an entry with the given name.
|
* Revert all changes done to an entry with the given name.
|
||||||
*
|
*
|
||||||
* @param string|ZipEntry $entry Entry name or ZipEntry
|
* @param string|ZipEntry $entry Entry name or ZipEntry
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function unchangeEntry($entry)
|
public function unchangeEntry($entry): bool
|
||||||
{
|
{
|
||||||
$entry = $entry instanceof ZipEntry ? $entry->getName() : (string) $entry;
|
$entry = $entry instanceof ZipEntry ? $entry->getName() : (string) $entry;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$this->sourceContainer !== null &&
|
$this->sourceContainer !== null
|
||||||
isset($this->entries[$entry], $this->sourceContainer->entries[$entry])
|
&& isset($this->entries[$entry], $this->sourceContainer->entries[$entry])
|
||||||
) {
|
) {
|
||||||
$this->entries[$entry] = clone $this->sourceContainer->entries[$entry];
|
$this->entries[$entry] = clone $this->sourceContainer->entries[$entry];
|
||||||
|
|
||||||
@ -245,10 +226,8 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
* return strcmp($nameA, $nameB);
|
* return strcmp($nameA, $nameB);
|
||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
*
|
|
||||||
* @param callable $cmp
|
|
||||||
*/
|
*/
|
||||||
public function sortByName(callable $cmp)
|
public function sortByName(callable $cmp): void
|
||||||
{
|
{
|
||||||
uksort($this->entries, $cmp);
|
uksort($this->entries, $cmp);
|
||||||
}
|
}
|
||||||
@ -262,21 +241,15 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
* return strcmp($a->getName(), $b->getName());
|
* return strcmp($a->getName(), $b->getName());
|
||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
*
|
|
||||||
* @param callable $cmp
|
|
||||||
*/
|
*/
|
||||||
public function sortByEntry(callable $cmp)
|
public function sortByEntry(callable $cmp): void
|
||||||
{
|
{
|
||||||
uasort($this->entries, $cmp);
|
uasort($this->entries, $cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setArchiveComment(?string $archiveComment): void
|
||||||
* @param string|null $archiveComment
|
|
||||||
*/
|
|
||||||
public function setArchiveComment($archiveComment)
|
|
||||||
{
|
{
|
||||||
if ($archiveComment !== null && $archiveComment !== '') {
|
if ($archiveComment !== null && $archiveComment !== '') {
|
||||||
$archiveComment = (string) $archiveComment;
|
|
||||||
$length = \strlen($archiveComment);
|
$length = \strlen($archiveComment);
|
||||||
|
|
||||||
if ($length > 0xffff) {
|
if ($length > 0xffff) {
|
||||||
@ -286,10 +259,7 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
$this->archiveComment = $archiveComment;
|
$this->archiveComment = $archiveComment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function matcher(): ZipEntryMatcher
|
||||||
* @return ZipEntryMatcher
|
|
||||||
*/
|
|
||||||
public function matcher()
|
|
||||||
{
|
{
|
||||||
return new ZipEntryMatcher($this);
|
return new ZipEntryMatcher($this);
|
||||||
}
|
}
|
||||||
@ -297,9 +267,9 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
/**
|
/**
|
||||||
* Specify a password for extracting files.
|
* Specify a password for extracting files.
|
||||||
*
|
*
|
||||||
* @param string|null $password
|
* @param ?string $password
|
||||||
*/
|
*/
|
||||||
public function setReadPassword($password)
|
public function setReadPassword(?string $password): void
|
||||||
{
|
{
|
||||||
if ($this->sourceContainer !== null) {
|
if ($this->sourceContainer !== null) {
|
||||||
foreach ($this->sourceContainer->entries as $entry) {
|
foreach ($this->sourceContainer->entries as $entry) {
|
||||||
@ -311,13 +281,10 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $entryName
|
|
||||||
* @param string $password
|
|
||||||
*
|
|
||||||
* @throws ZipEntryNotFoundException
|
* @throws ZipEntryNotFoundException
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function setReadPasswordEntry($entryName, $password)
|
public function setReadPasswordEntry(string $entryName, string $password): void
|
||||||
{
|
{
|
||||||
if (!isset($this->sourceContainer->entries[$entryName])) {
|
if (!isset($this->sourceContainer->entries[$entryName])) {
|
||||||
throw new ZipEntryNotFoundException($entryName);
|
throw new ZipEntryNotFoundException($entryName);
|
||||||
@ -329,57 +296,39 @@ class ZipContainer extends ImmutableZipContainer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int|null
|
* @param ?string $writePassword
|
||||||
|
*
|
||||||
|
* @throws ZipEntryNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getZipAlign()
|
public function setWritePassword(?string $writePassword): void
|
||||||
{
|
|
||||||
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);
|
$this->matcher()->all()->setPassword($writePassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove password.
|
* Remove password.
|
||||||
|
*
|
||||||
|
* @throws ZipEntryNotFoundException
|
||||||
*/
|
*/
|
||||||
public function removePassword()
|
public function removePassword(): void
|
||||||
{
|
{
|
||||||
$this->matcher()->all()->setPassword(null);
|
$this->matcher()->all()->setPassword(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|ZipEntry $entryName
|
* @param string|ZipEntry $entryName
|
||||||
|
*
|
||||||
|
* @throws ZipEntryNotFoundException
|
||||||
*/
|
*/
|
||||||
public function removePasswordEntry($entryName)
|
public function removePasswordEntry($entryName): void
|
||||||
{
|
{
|
||||||
$this->matcher()->add($entryName)->setPassword(null);
|
$this->matcher()->add($entryName)->setPassword(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $encryptionMethod
|
* @throws ZipEntryNotFoundException
|
||||||
*/
|
*/
|
||||||
public function setEncryptionMethod($encryptionMethod = ZipEncryptionMethod::WINZIP_AES_256)
|
public function setEncryptionMethod(int $encryptionMethod = ZipEncryptionMethod::WINZIP_AES_256): void
|
||||||
{
|
{
|
||||||
$this->matcher()->all()->setEncryptionMethod($encryptionMethod);
|
$this->matcher()->all()->setEncryptionMethod($encryptionMethod);
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model;
|
namespace PhpZip\Model;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface ZipData.
|
|
||||||
*/
|
|
||||||
interface ZipData
|
interface ZipData
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return string returns data as string
|
* @return string returns data as string
|
||||||
*/
|
*/
|
||||||
public function getDataAsString();
|
public function getDataAsString(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return resource returns stream data
|
* @return resource returns stream data
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,24 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Model;
|
namespace PhpZip\Model;
|
||||||
|
|
||||||
/**
|
use PhpZip\Exception\ZipEntryNotFoundException;
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class ZipEntryMatcher implements \Countable
|
class ZipEntryMatcher implements \Countable
|
||||||
{
|
{
|
||||||
/** @var ZipContainer */
|
protected ZipContainer $zipContainer;
|
||||||
protected $zipContainer;
|
|
||||||
|
|
||||||
/** @var array */
|
protected array $matches = [];
|
||||||
protected $matches = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZipEntryMatcher constructor.
|
|
||||||
*
|
|
||||||
* @param ZipContainer $zipContainer
|
|
||||||
*/
|
|
||||||
public function __construct(ZipContainer $zipContainer)
|
public function __construct(ZipContainer $zipContainer)
|
||||||
{
|
{
|
||||||
$this->zipContainer = $zipContainer;
|
$this->zipContainer = $zipContainer;
|
||||||
@ -29,13 +29,11 @@ class ZipEntryMatcher implements \Countable
|
|||||||
*
|
*
|
||||||
* @return ZipEntryMatcher
|
* @return ZipEntryMatcher
|
||||||
*/
|
*/
|
||||||
public function add($entries)
|
public function add($entries): self
|
||||||
{
|
{
|
||||||
$entries = (array) $entries;
|
$entries = (array) $entries;
|
||||||
$entries = array_map(
|
$entries = array_map(
|
||||||
static function ($entry) {
|
static fn ($entry) => $entry instanceof ZipEntry ? $entry->getName() : (string) $entry,
|
||||||
return $entry instanceof ZipEntry ? $entry->getName() : (string) $entry;
|
|
||||||
},
|
|
||||||
$entries
|
$entries
|
||||||
);
|
);
|
||||||
$this->matches = array_values(
|
$this->matches = array_values(
|
||||||
@ -59,23 +57,16 @@ class ZipEntryMatcher implements \Countable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $regexp
|
|
||||||
*
|
|
||||||
* @return ZipEntryMatcher
|
* @return ZipEntryMatcher
|
||||||
*
|
|
||||||
* @noinspection PhpUnusedParameterInspection
|
* @noinspection PhpUnusedParameterInspection
|
||||||
*/
|
*/
|
||||||
public function match($regexp)
|
public function match(string $regexp): self
|
||||||
{
|
{
|
||||||
array_walk(
|
array_walk(
|
||||||
$this->zipContainer->getEntries(),
|
$this->zipContainer->getEntries(),
|
||||||
/**
|
function (ZipEntry $entry, string $entryName) use ($regexp): void {
|
||||||
* @param ZipEntry $entry
|
|
||||||
* @param string $entryName
|
|
||||||
*/
|
|
||||||
function (ZipEntry $entry, $entryName) use ($regexp) {
|
|
||||||
if (preg_match($regexp, $entryName)) {
|
if (preg_match($regexp, $entryName)) {
|
||||||
$this->matches[] = (string) $entryName;
|
$this->matches[] = $entryName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -87,7 +78,7 @@ class ZipEntryMatcher implements \Countable
|
|||||||
/**
|
/**
|
||||||
* @return ZipEntryMatcher
|
* @return ZipEntryMatcher
|
||||||
*/
|
*/
|
||||||
public function all()
|
public function all(): self
|
||||||
{
|
{
|
||||||
$this->matches = array_map(
|
$this->matches = array_map(
|
||||||
'strval',
|
'strval',
|
||||||
@ -102,36 +93,31 @@ class ZipEntryMatcher implements \Countable
|
|||||||
*
|
*
|
||||||
* Callable function signature:
|
* Callable function signature:
|
||||||
* function(string $entryName){}
|
* function(string $entryName){}
|
||||||
*
|
|
||||||
* @param callable $callable
|
|
||||||
*/
|
*/
|
||||||
public function invoke(callable $callable)
|
public function invoke(callable $callable): void
|
||||||
{
|
{
|
||||||
if (!empty($this->matches)) {
|
if (!empty($this->matches)) {
|
||||||
array_walk(
|
array_walk(
|
||||||
$this->matches,
|
$this->matches,
|
||||||
/** @param string $entryName */
|
/** @param string $entryName */
|
||||||
static function ($entryName) use ($callable) {
|
static function (string $entryName) use ($callable): void {
|
||||||
$callable($entryName);
|
$callable($entryName);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getMatches(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getMatches()
|
|
||||||
{
|
{
|
||||||
return $this->matches;
|
return $this->matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete()
|
public function delete(): void
|
||||||
{
|
{
|
||||||
array_walk(
|
array_walk(
|
||||||
$this->matches,
|
$this->matches,
|
||||||
/** @param string $entryName */
|
/** @param string $entryName */
|
||||||
function ($entryName) {
|
function (string $entryName): void {
|
||||||
$this->zipContainer->deleteEntry($entryName);
|
$this->zipContainer->deleteEntry($entryName);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -139,15 +125,17 @@ class ZipEntryMatcher implements \Countable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|null $password
|
* @param ?string $password
|
||||||
* @param int|null $encryptionMethod
|
* @param ?int $encryptionMethod
|
||||||
|
*
|
||||||
|
* @throws ZipEntryNotFoundException
|
||||||
*/
|
*/
|
||||||
public function setPassword($password, $encryptionMethod = null)
|
public function setPassword(?string $password, ?int $encryptionMethod = null): void
|
||||||
{
|
{
|
||||||
array_walk(
|
array_walk(
|
||||||
$this->matches,
|
$this->matches,
|
||||||
/** @param string $entryName */
|
/** @param string $entryName */
|
||||||
function ($entryName) use ($password, $encryptionMethod) {
|
function (string $entryName) use ($password, $encryptionMethod): void {
|
||||||
$entry = $this->zipContainer->getEntry($entryName);
|
$entry = $this->zipContainer->getEntry($entryName);
|
||||||
|
|
||||||
if (!$entry->isDirectory()) {
|
if (!$entry->isDirectory()) {
|
||||||
@ -158,14 +146,14 @@ class ZipEntryMatcher implements \Countable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $encryptionMethod
|
* @throws ZipEntryNotFoundException
|
||||||
*/
|
*/
|
||||||
public function setEncryptionMethod($encryptionMethod)
|
public function setEncryptionMethod(int $encryptionMethod): void
|
||||||
{
|
{
|
||||||
array_walk(
|
array_walk(
|
||||||
$this->matches,
|
$this->matches,
|
||||||
/** @param string $entryName */
|
/** @param string $entryName */
|
||||||
function ($entryName) use ($encryptionMethod) {
|
function (string $entryName) use ($encryptionMethod): void {
|
||||||
$entry = $this->zipContainer->getEntry($entryName);
|
$entry = $this->zipContainer->getEntry($entryName);
|
||||||
|
|
||||||
if (!$entry->isDirectory()) {
|
if (!$entry->isDirectory()) {
|
||||||
@ -175,12 +163,14 @@ class ZipEntryMatcher implements \Countable
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function disableEncryption()
|
/**
|
||||||
|
* @throws ZipEntryNotFoundException
|
||||||
|
*/
|
||||||
|
public function disableEncryption(): void
|
||||||
{
|
{
|
||||||
array_walk(
|
array_walk(
|
||||||
$this->matches,
|
$this->matches,
|
||||||
/** @param string $entryName */
|
function (string $entryName): void {
|
||||||
function ($entryName) {
|
|
||||||
$entry = $this->zipContainer->getEntry($entryName);
|
$entry = $this->zipContainer->getEntry($entryName);
|
||||||
|
|
||||||
if (!$entry->isDirectory()) {
|
if (!$entry->isDirectory()) {
|
||||||
@ -196,10 +186,8 @@ class ZipEntryMatcher implements \Countable
|
|||||||
* @see http://php.net/manual/en/countable.count.php
|
* @see http://php.net/manual/en/countable.count.php
|
||||||
*
|
*
|
||||||
* @return int the custom count as an integer
|
* @return int the custom count as an integer
|
||||||
*
|
|
||||||
* @since 5.1.0
|
|
||||||
*/
|
*/
|
||||||
public function count()
|
public function count(): int
|
||||||
{
|
{
|
||||||
return \count($this->matches);
|
return \count($this->matches);
|
||||||
}
|
}
|
||||||
|
@ -1,266 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PhpZip\Model;
|
|
||||||
|
|
||||||
use PhpZip\Constants\ZipCompressionMethod;
|
|
||||||
use PhpZip\Constants\ZipEncryptionMethod;
|
|
||||||
use PhpZip\Constants\ZipPlatform;
|
|
||||||
use PhpZip\Util\FileAttribUtil;
|
|
||||||
use PhpZip\Util\FilesUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Zip info.
|
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*
|
|
||||||
* @deprecated Use ZipEntry
|
|
||||||
*/
|
|
||||||
class ZipInfo
|
|
||||||
{
|
|
||||||
/** @var ZipEntry */
|
|
||||||
private $entry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZipInfo constructor.
|
|
||||||
*
|
|
||||||
* @param ZipEntry $entry
|
|
||||||
*/
|
|
||||||
public function __construct(ZipEntry $entry)
|
|
||||||
{
|
|
||||||
$this->entry = $entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ZipEntry $entry
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipPlatform::getPlatformName()}
|
|
||||||
*/
|
|
||||||
public static function getPlatformName(ZipEntry $entry)
|
|
||||||
{
|
|
||||||
return ZipPlatform::getPlatformName($entry->getExtractedOS());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getName()
|
|
||||||
{
|
|
||||||
return $this->entry->getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isFolder()
|
|
||||||
{
|
|
||||||
return $this->entry->isDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getSize()
|
|
||||||
{
|
|
||||||
return $this->entry->getUncompressedSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getCompressedSize()
|
|
||||||
{
|
|
||||||
return $this->entry->getCompressedSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getMtime()
|
|
||||||
{
|
|
||||||
return $this->entry->getMTime()->getTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getCtime()
|
|
||||||
{
|
|
||||||
$ctime = $this->entry->getCTime();
|
|
||||||
|
|
||||||
return $ctime === null ? null : $ctime->getTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getAtime()
|
|
||||||
{
|
|
||||||
$atime = $this->entry->getATime();
|
|
||||||
|
|
||||||
return $atime === null ? null : $atime->getTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getAttributes()
|
|
||||||
{
|
|
||||||
$externalAttributes = $this->entry->getExternalAttributes();
|
|
||||||
|
|
||||||
if ($this->entry->getCreatedOS() === ZipPlatform::OS_UNIX) {
|
|
||||||
$permission = (($externalAttributes >> 16) & 0xFFFF);
|
|
||||||
|
|
||||||
return FileAttribUtil::getUnixMode($permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FileAttribUtil::getDosMode($externalAttributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isEncrypted()
|
|
||||||
{
|
|
||||||
return $this->entry->isEncrypted();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getComment()
|
|
||||||
{
|
|
||||||
return $this->entry->getComment();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getCrc()
|
|
||||||
{
|
|
||||||
return $this->entry->getCrc();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*
|
|
||||||
* @deprecated use \PhpZip\Model\ZipInfo::getMethodName()
|
|
||||||
*/
|
|
||||||
public function getMethod()
|
|
||||||
{
|
|
||||||
return $this->getMethodName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getMethodName()
|
|
||||||
{
|
|
||||||
return ZipCompressionMethod::getCompressionMethodName($this->entry->getCompressionMethod());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getEncryptionMethodName()
|
|
||||||
{
|
|
||||||
return ZipEncryptionMethod::getEncryptionMethodName($this->entry->getEncryptionMethod());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getPlatform()
|
|
||||||
{
|
|
||||||
return ZipPlatform::getPlatformName($this->entry->getExtractedOS());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getVersion()
|
|
||||||
{
|
|
||||||
return $this->entry->getExtractVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getEncryptionMethod()
|
|
||||||
{
|
|
||||||
$encryptionMethod = $this->entry->getEncryptionMethod();
|
|
||||||
|
|
||||||
return $encryptionMethod === ZipEncryptionMethod::NONE ? null : $encryptionMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getCompressionLevel()
|
|
||||||
{
|
|
||||||
return $this->entry->getCompressionLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getCompressionMethod()
|
|
||||||
{
|
|
||||||
return $this->entry->getCompressionMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function toArray()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'name' => $this->getName(),
|
|
||||||
'folder' => $this->isFolder(),
|
|
||||||
'size' => $this->getSize(),
|
|
||||||
'compressed_size' => $this->getCompressedSize(),
|
|
||||||
'modified' => $this->getMtime(),
|
|
||||||
'created' => $this->getCtime(),
|
|
||||||
'accessed' => $this->getAtime(),
|
|
||||||
'attributes' => $this->getAttributes(),
|
|
||||||
'encrypted' => $this->isEncrypted(),
|
|
||||||
'encryption_method' => $this->getEncryptionMethod(),
|
|
||||||
'encryption_method_name' => $this->getEncryptionMethodName(),
|
|
||||||
'comment' => $this->getComment(),
|
|
||||||
'crc' => $this->getCrc(),
|
|
||||||
'method_name' => $this->getMethodName(),
|
|
||||||
'compression_method' => $this->getCompressionMethod(),
|
|
||||||
'platform' => $this->getPlatform(),
|
|
||||||
'version' => $this->getVersion(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
$ctime = $this->entry->getCTime();
|
|
||||||
$atime = $this->entry->getATime();
|
|
||||||
$comment = $this->getComment();
|
|
||||||
|
|
||||||
return __CLASS__ . ' {'
|
|
||||||
. 'Name="' . $this->getName() . '", '
|
|
||||||
. ($this->isFolder() ? 'Folder, ' : '')
|
|
||||||
. 'Size="' . FilesUtil::humanSize($this->getSize()) . '"'
|
|
||||||
. ', Compressed size="' . FilesUtil::humanSize($this->getCompressedSize()) . '"'
|
|
||||||
. ', Modified time="' . $this->entry->getMTime()->format(\DATE_W3C) . '", '
|
|
||||||
. ($ctime !== null ? 'Created time="' . $ctime->format(\DATE_W3C) . '", ' : '')
|
|
||||||
. ($atime !== null ? 'Accessed time="' . $atime->format(\DATE_W3C) . '", ' : '')
|
|
||||||
. ($this->isEncrypted() ? 'Encrypted, ' : '')
|
|
||||||
. ($comment !== null ? 'Comment="' . $comment . '", ' : '')
|
|
||||||
. (!empty($this->crc) ? 'Crc=0x' . dechex($this->crc) . ', ' : '')
|
|
||||||
. 'Method name="' . $this->getMethodName() . '", '
|
|
||||||
. 'Attributes="' . $this->getAttributes() . '", '
|
|
||||||
. 'Platform="' . $this->getPlatform() . '", '
|
|
||||||
. 'Version=' . $this->getVersion()
|
|
||||||
. '}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Util;
|
namespace PhpZip\Util;
|
||||||
|
|
||||||
use PhpZip\Exception\RuntimeException;
|
use PhpZip\Exception\RuntimeException;
|
||||||
@ -9,24 +18,8 @@ use PhpZip\Exception\RuntimeException;
|
|||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
class CryptoUtil
|
final class CryptoUtil
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Returns random bytes.
|
|
||||||
*
|
|
||||||
* @param int $length
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*
|
|
||||||
* @deprecated Use random_bytes()
|
|
||||||
*/
|
|
||||||
final public static function randomBytes($length)
|
|
||||||
{
|
|
||||||
return random_bytes($length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypt AES-CTR.
|
* Decrypt AES-CTR.
|
||||||
*
|
*
|
||||||
@ -36,7 +29,7 @@ class CryptoUtil
|
|||||||
*
|
*
|
||||||
* @return string Raw data
|
* @return string Raw data
|
||||||
*/
|
*/
|
||||||
public static function decryptAesCtr($data, $key, $iv)
|
public static function decryptAesCtr(string $data, string $key, string $iv): string
|
||||||
{
|
{
|
||||||
if (\extension_loaded('openssl')) {
|
if (\extension_loaded('openssl')) {
|
||||||
$numBits = \strlen($key) * 8;
|
$numBits = \strlen($key) * 8;
|
||||||
@ -44,11 +37,7 @@ class CryptoUtil
|
|||||||
return openssl_decrypt($data, 'AES-' . $numBits . '-CTR', $key, \OPENSSL_RAW_DATA, $iv);
|
return openssl_decrypt($data, 'AES-' . $numBits . '-CTR', $key, \OPENSSL_RAW_DATA, $iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\extension_loaded('mcrypt')) {
|
throw new RuntimeException('Openssl extension not loaded');
|
||||||
return mcrypt_decrypt(\MCRYPT_RIJNDAEL_128, $key, $data, 'ctr', $iv);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new RuntimeException('Extension openssl or mcrypt not loaded');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,7 +49,7 @@ class CryptoUtil
|
|||||||
*
|
*
|
||||||
* @return string Encrypted data
|
* @return string Encrypted data
|
||||||
*/
|
*/
|
||||||
public static function encryptAesCtr($data, $key, $iv)
|
public static function encryptAesCtr(string $data, string $key, string $iv): string
|
||||||
{
|
{
|
||||||
if (\extension_loaded('openssl')) {
|
if (\extension_loaded('openssl')) {
|
||||||
$numBits = \strlen($key) * 8;
|
$numBits = \strlen($key) * 8;
|
||||||
@ -68,10 +57,6 @@ class CryptoUtil
|
|||||||
return openssl_encrypt($data, 'AES-' . $numBits . '-CTR', $key, \OPENSSL_RAW_DATA, $iv);
|
return openssl_encrypt($data, 'AES-' . $numBits . '-CTR', $key, \OPENSSL_RAW_DATA, $iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\extension_loaded('mcrypt')) {
|
throw new RuntimeException('Openssl extension not loaded');
|
||||||
return mcrypt_encrypt(\MCRYPT_RIJNDAEL_128, $key, $data, 'ctr', $iv);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new RuntimeException('Extension openssl or mcrypt not loaded');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Util;
|
namespace PhpZip\Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,9 +29,6 @@ namespace PhpZip\Util;
|
|||||||
*
|
*
|
||||||
* @see https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-filetimetodosdatetime?redirectedfrom=MSDN
|
* @see https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-filetimetodosdatetime?redirectedfrom=MSDN
|
||||||
*
|
*
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*
|
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
class DateTimeConverter
|
class DateTimeConverter
|
||||||
@ -30,14 +36,18 @@ class DateTimeConverter
|
|||||||
/**
|
/**
|
||||||
* Smallest supported DOS date/time value in a ZIP file,
|
* Smallest supported DOS date/time value in a ZIP file,
|
||||||
* which is January 1st, 1980 AD 00:00:00 local time.
|
* which is January 1st, 1980 AD 00:00:00 local time.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
*/
|
*/
|
||||||
const MIN_DOS_TIME = 0x210000; // (1 << 21) | (1 << 16)
|
public const MIN_DOS_TIME = (1 << 21) | (1 << 16);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Largest supported DOS date/time value in a ZIP file,
|
* Largest supported DOS date/time value in a ZIP file,
|
||||||
* which is December 31st, 2107 AD 23:59:58 local time.
|
* which is December 31st, 2107 AD 23:59:58 local time.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
*/
|
*/
|
||||||
const MAX_DOS_TIME = 0xff9fbf7d; // ((2107 - 1980) << 25) | (12 << 21) | (31 << 16) | (23 << 11) | (59 << 5) | (58 >> 1);
|
public const MAX_DOS_TIME = ((2107 - 1980) << 25) | (12 << 21) | (31 << 16) | (23 << 11) | (59 << 5) | (58 >> 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a 32 bit integer DOS date/time value to a UNIX timestamp value.
|
* Convert a 32 bit integer DOS date/time value to a UNIX timestamp value.
|
||||||
@ -46,7 +56,7 @@ class DateTimeConverter
|
|||||||
*
|
*
|
||||||
* @return int Unix timestamp
|
* @return int Unix timestamp
|
||||||
*/
|
*/
|
||||||
public static function msDosToUnix($dosTime)
|
public static function msDosToUnix(int $dosTime): int
|
||||||
{
|
{
|
||||||
if ($dosTime <= self::MIN_DOS_TIME) {
|
if ($dosTime <= self::MIN_DOS_TIME) {
|
||||||
$dosTime = 0;
|
$dosTime = 0;
|
||||||
@ -74,7 +84,7 @@ class DateTimeConverter
|
|||||||
* rounded down to even seconds
|
* rounded down to even seconds
|
||||||
* and is in between DateTimeConverter::MIN_DOS_TIME and DateTimeConverter::MAX_DOS_TIME
|
* and is in between DateTimeConverter::MIN_DOS_TIME and DateTimeConverter::MAX_DOS_TIME
|
||||||
*/
|
*/
|
||||||
public static function unixToMsDos($unixTimestamp)
|
public static function unixToMsDos(int $unixTimestamp): int
|
||||||
{
|
{
|
||||||
if ($unixTimestamp < 0) {
|
if ($unixTimestamp < 0) {
|
||||||
throw new \InvalidArgumentException('Negative unix timestamp: ' . $unixTimestamp);
|
throw new \InvalidArgumentException('Negative unix timestamp: ' . $unixTimestamp);
|
||||||
@ -82,12 +92,12 @@ class DateTimeConverter
|
|||||||
|
|
||||||
$date = getdate($unixTimestamp);
|
$date = getdate($unixTimestamp);
|
||||||
$dosTime = (
|
$dosTime = (
|
||||||
(($date['year'] - 1980) << 25) |
|
(($date['year'] - 1980) << 25)
|
||||||
($date['mon'] << 21) |
|
| ($date['mon'] << 21)
|
||||||
($date['mday'] << 16) |
|
| ($date['mday'] << 16)
|
||||||
($date['hours'] << 11) |
|
| ($date['hours'] << 11)
|
||||||
($date['minutes'] << 5) |
|
| ($date['minutes'] << 5)
|
||||||
($date['seconds'] >> 1)
|
| ($date['seconds'] >> 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($dosTime <= self::MIN_DOS_TIME) {
|
if ($dosTime <= self::MIN_DOS_TIME) {
|
||||||
|
@ -1,28 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Util;
|
namespace PhpZip\Util;
|
||||||
|
|
||||||
use PhpZip\Constants\DosAttrs;
|
use PhpZip\Constants\DosAttrs;
|
||||||
use PhpZip\Constants\UnixStat;
|
use PhpZip\Constants\UnixStat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class FileAttribUtil.
|
|
||||||
*
|
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
class FileAttribUtil implements DosAttrs, UnixStat
|
class FileAttribUtil implements DosAttrs, UnixStat
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get DOS mode,.
|
* Get DOS mode.
|
||||||
*
|
|
||||||
* @param int $xattr
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function getDosMode($xattr)
|
public static function getDosMode(int $xattr): string
|
||||||
{
|
{
|
||||||
$xattr = (int) $xattr;
|
|
||||||
|
|
||||||
$mode = (($xattr & self::DOS_DIRECTORY) === self::DOS_DIRECTORY) ? 'd' : '-';
|
$mode = (($xattr & self::DOS_DIRECTORY) === self::DOS_DIRECTORY) ? 'd' : '-';
|
||||||
$mode .= (($xattr & self::DOS_ARCHIVE) === self::DOS_ARCHIVE) ? 'a' : '-';
|
$mode .= (($xattr & self::DOS_ARCHIVE) === self::DOS_ARCHIVE) ? 'a' : '-';
|
||||||
$mode .= (($xattr & self::DOS_READ_ONLY) === self::DOS_READ_ONLY) ? 'r' : '-';
|
$mode .= (($xattr & self::DOS_READ_ONLY) === self::DOS_READ_ONLY) ? 'r' : '-';
|
||||||
@ -34,14 +35,11 @@ class FileAttribUtil implements DosAttrs, UnixStat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $permission
|
* @noinspection DuplicatedCode
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function getUnixMode($permission)
|
public static function getUnixMode(int $permission): string
|
||||||
{
|
{
|
||||||
$mode = '';
|
$mode = '';
|
||||||
$permission = (int) $permission;
|
|
||||||
switch ($permission & self::UNX_IFMT) {
|
switch ($permission & self::UNX_IFMT) {
|
||||||
case self::UNX_IFDIR:
|
case self::UNX_IFDIR:
|
||||||
$mode .= 'd';
|
$mode .= 'd';
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Util;
|
namespace PhpZip\Util;
|
||||||
|
|
||||||
use PhpZip\Util\Iterator\IgnoreFilesFilterIterator;
|
use PhpZip\Util\Iterator\IgnoreFilesFilterIterator;
|
||||||
@ -8,9 +17,6 @@ use PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator;
|
|||||||
/**
|
/**
|
||||||
* Files util.
|
* Files util.
|
||||||
*
|
*
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*
|
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
final class FilesUtil
|
final class FilesUtil
|
||||||
@ -19,10 +25,8 @@ final class FilesUtil
|
|||||||
* Is empty directory.
|
* Is empty directory.
|
||||||
*
|
*
|
||||||
* @param string $dir Directory
|
* @param string $dir Directory
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public static function isEmptyDir($dir)
|
public static function isEmptyDir(string $dir): bool
|
||||||
{
|
{
|
||||||
if (!is_readable($dir)) {
|
if (!is_readable($dir)) {
|
||||||
return false;
|
return false;
|
||||||
@ -36,7 +40,7 @@ final class FilesUtil
|
|||||||
*
|
*
|
||||||
* @param string $dir directory path
|
* @param string $dir directory path
|
||||||
*/
|
*/
|
||||||
public static function removeDir($dir)
|
public static function removeDir(string $dir): void
|
||||||
{
|
{
|
||||||
$files = new \RecursiveIteratorIterator(
|
$files = new \RecursiveIteratorIterator(
|
||||||
new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
|
new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
|
||||||
@ -53,12 +57,8 @@ final class FilesUtil
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert glob pattern to regex pattern.
|
* Convert glob pattern to regex pattern.
|
||||||
*
|
|
||||||
* @param string $globPattern
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function convertGlobToRegEx($globPattern)
|
public static function convertGlobToRegEx(string $globPattern): string
|
||||||
{
|
{
|
||||||
// Remove beginning and ending * globs because they're useless
|
// Remove beginning and ending * globs because they're useless
|
||||||
$globPattern = trim($globPattern, '*');
|
$globPattern = trim($globPattern, '*');
|
||||||
@ -144,13 +144,9 @@ final class FilesUtil
|
|||||||
/**
|
/**
|
||||||
* Search files.
|
* Search files.
|
||||||
*
|
*
|
||||||
* @param string $inputDir
|
|
||||||
* @param bool $recursive
|
|
||||||
* @param array $ignoreFiles
|
|
||||||
*
|
|
||||||
* @return array Searched file list
|
* @return array Searched file list
|
||||||
*/
|
*/
|
||||||
public static function fileSearchWithIgnore($inputDir, $recursive = true, array $ignoreFiles = [])
|
public static function fileSearchWithIgnore(string $inputDir, bool $recursive = true, array $ignoreFiles = []): array
|
||||||
{
|
{
|
||||||
if ($recursive) {
|
if ($recursive) {
|
||||||
$directoryIterator = new \RecursiveDirectoryIterator($inputDir);
|
$directoryIterator = new \RecursiveDirectoryIterator($inputDir);
|
||||||
@ -182,16 +178,10 @@ final class FilesUtil
|
|||||||
/**
|
/**
|
||||||
* Search files from glob pattern.
|
* Search files from glob pattern.
|
||||||
*
|
*
|
||||||
* @param string $globPattern
|
|
||||||
* @param int $flags
|
|
||||||
* @param bool $recursive
|
|
||||||
*
|
|
||||||
* @return array Searched file list
|
* @return array Searched file list
|
||||||
*/
|
*/
|
||||||
public static function globFileSearch($globPattern, $flags = 0, $recursive = true)
|
public static function globFileSearch(string $globPattern, int $flags = 0, bool $recursive = true): array
|
||||||
{
|
{
|
||||||
$flags = (int) $flags;
|
|
||||||
$recursive = (bool) $recursive;
|
|
||||||
$files = glob($globPattern, $flags);
|
$files = glob($globPattern, $flags);
|
||||||
|
|
||||||
if (!$recursive) {
|
if (!$recursive) {
|
||||||
@ -210,13 +200,9 @@ final class FilesUtil
|
|||||||
/**
|
/**
|
||||||
* Search files from regex pattern.
|
* Search files from regex pattern.
|
||||||
*
|
*
|
||||||
* @param string $folder
|
|
||||||
* @param string $pattern
|
|
||||||
* @param bool $recursive
|
|
||||||
*
|
|
||||||
* @return array Searched file list
|
* @return array Searched file list
|
||||||
*/
|
*/
|
||||||
public static function regexFileSearch($folder, $pattern, $recursive = true)
|
public static function regexFileSearch(string $folder, string $pattern, bool $recursive = true): array
|
||||||
{
|
{
|
||||||
if ($recursive) {
|
if ($recursive) {
|
||||||
$directoryIterator = new \RecursiveDirectoryIterator($folder);
|
$directoryIterator = new \RecursiveDirectoryIterator($folder);
|
||||||
@ -243,10 +229,8 @@ final class FilesUtil
|
|||||||
*
|
*
|
||||||
* @param int $size Size bytes
|
* @param int $size Size bytes
|
||||||
* @param string|null $unit Unit support 'GB', 'MB', 'KB'
|
* @param string|null $unit Unit support 'GB', 'MB', 'KB'
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function humanSize($size, $unit = null)
|
public static function humanSize(int $size, ?string $unit = null): string
|
||||||
{
|
{
|
||||||
if (($unit === null && $size >= 1 << 30) || $unit === 'GB') {
|
if (($unit === null && $size >= 1 << 30) || $unit === 'GB') {
|
||||||
return number_format($size / (1 << 30), 2) . 'GB';
|
return number_format($size / (1 << 30), 2) . 'GB';
|
||||||
@ -267,18 +251,14 @@ final class FilesUtil
|
|||||||
* Normalizes zip path.
|
* Normalizes zip path.
|
||||||
*
|
*
|
||||||
* @param string $path Zip path
|
* @param string $path Zip path
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function normalizeZipPath($path)
|
public static function normalizeZipPath(string $path): string
|
||||||
{
|
{
|
||||||
return implode(
|
return implode(
|
||||||
\DIRECTORY_SEPARATOR,
|
\DIRECTORY_SEPARATOR,
|
||||||
array_filter(
|
array_filter(
|
||||||
explode('/', (string) $path),
|
explode('/', $path),
|
||||||
static function ($part) {
|
static fn ($part) => $part !== '.' && $part !== '..'
|
||||||
return $part !== '.' && $part !== '..';
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -288,11 +268,9 @@ final class FilesUtil
|
|||||||
*
|
*
|
||||||
* @param string $file A file path
|
* @param string $file A file path
|
||||||
*
|
*
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @see source symfony filesystem component
|
* @see source symfony filesystem component
|
||||||
*/
|
*/
|
||||||
public static function isAbsolutePath($file)
|
public static function isAbsolutePath(string $file): bool
|
||||||
{
|
{
|
||||||
return strspn($file, '/\\', 0, 1)
|
return strspn($file, '/\\', 0, 1)
|
||||||
|| (
|
|| (
|
||||||
@ -303,14 +281,7 @@ final class FilesUtil
|
|||||||
|| parse_url($file, \PHP_URL_SCHEME) !== null;
|
|| parse_url($file, \PHP_URL_SCHEME) !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function symlink(string $target, string $path, bool $allowSymlink): bool
|
||||||
* @param string $target
|
|
||||||
* @param string $path
|
|
||||||
* @param bool $allowSymlink
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function symlink($target, $path, $allowSymlink)
|
|
||||||
{
|
{
|
||||||
if (\DIRECTORY_SEPARATOR === '\\' || !$allowSymlink) {
|
if (\DIRECTORY_SEPARATOR === '\\' || !$allowSymlink) {
|
||||||
return file_put_contents($path, $target) !== false;
|
return file_put_contents($path, $target) !== false;
|
||||||
@ -319,12 +290,7 @@ final class FilesUtil
|
|||||||
return symlink($target, $path);
|
return symlink($target, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function isBadCompressionFile(string $file): bool
|
||||||
* @param string $file
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isBadCompressionFile($file)
|
|
||||||
{
|
{
|
||||||
$badCompressFileExt = [
|
$badCompressFileExt = [
|
||||||
'dic',
|
'dic',
|
||||||
@ -350,12 +316,7 @@ final class FilesUtil
|
|||||||
return self::isBadCompressionMimeType($mimeType);
|
return self::isBadCompressionMimeType($mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function isBadCompressionMimeType(string $mimeType): bool
|
||||||
* @param string $mimeType
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isBadCompressionMimeType($mimeType)
|
|
||||||
{
|
{
|
||||||
static $badDeflateCompMimeTypes = [
|
static $badDeflateCompMimeTypes = [
|
||||||
'application/epub+zip',
|
'application/epub+zip',
|
||||||
@ -406,21 +367,13 @@ final class FilesUtil
|
|||||||
'x-epoc/x-sisx-app',
|
'x-epoc/x-sisx-app',
|
||||||
];
|
];
|
||||||
|
|
||||||
if (\in_array($mimeType, $badDeflateCompMimeTypes, true)) {
|
return \in_array($mimeType, $badDeflateCompMimeTypes, true);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $file
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*
|
|
||||||
* @noinspection PhpComposerExtensionStubsInspection
|
* @noinspection PhpComposerExtensionStubsInspection
|
||||||
*/
|
*/
|
||||||
public static function getMimeTypeFromFile($file)
|
public static function getMimeTypeFromFile(string $file): string
|
||||||
{
|
{
|
||||||
if (\function_exists('mime_content_type')) {
|
if (\function_exists('mime_content_type')) {
|
||||||
return mime_content_type($file);
|
return mime_content_type($file);
|
||||||
@ -430,14 +383,10 @@ final class FilesUtil
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $contents
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
* @noinspection PhpComposerExtensionStubsInspection
|
* @noinspection PhpComposerExtensionStubsInspection
|
||||||
*/
|
*/
|
||||||
public static function getMimeTypeFromString($contents)
|
public static function getMimeTypeFromString(string $contents): string
|
||||||
{
|
{
|
||||||
$contents = (string) $contents;
|
|
||||||
$finfo = new \finfo(\FILEINFO_MIME);
|
$finfo = new \finfo(\FILEINFO_MIME);
|
||||||
$mimeType = $finfo->buffer($contents);
|
$mimeType = $finfo->buffer($contents);
|
||||||
|
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Util\Iterator;
|
namespace PhpZip\Util\Iterator;
|
||||||
|
|
||||||
use PhpZip\Util\StringUtil;
|
use PhpZip\Util\StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterator for ignore files.
|
* Iterator for ignore files.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class IgnoreFilesFilterIterator extends \FilterIterator
|
class IgnoreFilesFilterIterator extends \FilterIterator
|
||||||
{
|
{
|
||||||
/**
|
/** Ignore list files. */
|
||||||
* Ignore list files.
|
private array $ignoreFiles = ['..'];
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $ignoreFiles = ['..'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \Iterator $iterator
|
|
||||||
* @param array $ignoreFiles
|
|
||||||
*/
|
|
||||||
public function __construct(\Iterator $iterator, array $ignoreFiles)
|
public function __construct(\Iterator $iterator, array $ignoreFiles)
|
||||||
{
|
{
|
||||||
parent::__construct($iterator);
|
parent::__construct($iterator);
|
||||||
@ -35,10 +33,8 @@ class IgnoreFilesFilterIterator extends \FilterIterator
|
|||||||
* @see http://php.net/manual/en/filteriterator.accept.php
|
* @see http://php.net/manual/en/filteriterator.accept.php
|
||||||
*
|
*
|
||||||
* @return bool true if the current element is acceptable, otherwise false
|
* @return bool true if the current element is acceptable, otherwise false
|
||||||
*
|
|
||||||
* @since 5.1.0
|
|
||||||
*/
|
*/
|
||||||
public function accept()
|
public function accept(): bool
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \SplFileInfo $fileInfo
|
* @var \SplFileInfo $fileInfo
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Util\Iterator;
|
namespace PhpZip\Util\Iterator;
|
||||||
|
|
||||||
use PhpZip\Util\StringUtil;
|
use PhpZip\Util\StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursive iterator for ignore files.
|
* Recursive iterator for ignore files.
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*/
|
*/
|
||||||
class IgnoreFilesRecursiveFilterIterator extends \RecursiveFilterIterator
|
class IgnoreFilesRecursiveFilterIterator extends \RecursiveFilterIterator
|
||||||
{
|
{
|
||||||
/**
|
/** Ignore list files. */
|
||||||
* Ignore list files.
|
private array $ignoreFiles = ['..'];
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $ignoreFiles = ['..'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \RecursiveIterator $iterator
|
|
||||||
* @param array $ignoreFiles
|
|
||||||
*/
|
|
||||||
public function __construct(\RecursiveIterator $iterator, array $ignoreFiles)
|
public function __construct(\RecursiveIterator $iterator, array $ignoreFiles)
|
||||||
{
|
{
|
||||||
parent::__construct($iterator);
|
parent::__construct($iterator);
|
||||||
@ -35,10 +33,8 @@ class IgnoreFilesRecursiveFilterIterator extends \RecursiveFilterIterator
|
|||||||
* @see http://php.net/manual/en/filteriterator.accept.php
|
* @see http://php.net/manual/en/filteriterator.accept.php
|
||||||
*
|
*
|
||||||
* @return bool true if the current element is acceptable, otherwise false
|
* @return bool true if the current element is acceptable, otherwise false
|
||||||
*
|
|
||||||
* @since 5.1.0
|
|
||||||
*/
|
*/
|
||||||
public function accept()
|
public function accept(): bool
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \SplFileInfo $fileInfo
|
* @var \SplFileInfo $fileInfo
|
||||||
@ -67,8 +63,9 @@ class IgnoreFilesRecursiveFilterIterator extends \RecursiveFilterIterator
|
|||||||
/**
|
/**
|
||||||
* @return IgnoreFilesRecursiveFilterIterator
|
* @return IgnoreFilesRecursiveFilterIterator
|
||||||
*/
|
*/
|
||||||
public function getChildren()
|
public function getChildren(): self
|
||||||
{
|
{
|
||||||
|
/** @noinspection PhpPossiblePolymorphicInvocationInspection */
|
||||||
return new self($this->getInnerIterator()->getChildren(), $this->ignoreFiles);
|
return new self($this->getInnerIterator()->getChildren(), $this->ignoreFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
src/Util/MathUtil.php
Normal file
36
src/Util/MathUtil.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PhpZip\Util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Math util.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class MathUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Cast to signed int 32-bit.
|
||||||
|
*/
|
||||||
|
public static function toSignedInt32(int $int): int
|
||||||
|
{
|
||||||
|
if (\PHP_INT_SIZE === 8) {
|
||||||
|
$int &= 0xffffffff;
|
||||||
|
|
||||||
|
if ($int & 0x80000000) {
|
||||||
|
return $int - 0x100000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $int;
|
||||||
|
}
|
||||||
|
}
|
@ -1,69 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PhpZip\Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pack util.
|
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class PackUtil
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param int $longValue
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function packLongLE($longValue)
|
|
||||||
{
|
|
||||||
if (\PHP_VERSION_ID >= 506030) {
|
|
||||||
return pack('P', $longValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
$left = 0xffffffff00000000;
|
|
||||||
$right = 0x00000000ffffffff;
|
|
||||||
|
|
||||||
$r = ($longValue & $left) >> 32;
|
|
||||||
$l = $longValue & $right;
|
|
||||||
|
|
||||||
return pack('VV', $l, $r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $value
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public static function unpackLongLE($value)
|
|
||||||
{
|
|
||||||
if (\PHP_VERSION_ID >= 506030) {
|
|
||||||
return unpack('P', $value)[1];
|
|
||||||
}
|
|
||||||
$unpack = unpack('Va/Vb', $value);
|
|
||||||
|
|
||||||
return $unpack['a'] + ($unpack['b'] << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cast to signed int 32-bit.
|
|
||||||
*
|
|
||||||
* @param int $int
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public static function toSignedInt32($int)
|
|
||||||
{
|
|
||||||
if (\PHP_INT_SIZE === 8) {
|
|
||||||
$int &= 0xffffffff;
|
|
||||||
|
|
||||||
if ($int & 0x80000000) {
|
|
||||||
return $int - 0x100000000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $int;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Util;
|
namespace PhpZip\Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,40 +18,18 @@ namespace PhpZip\Util;
|
|||||||
*/
|
*/
|
||||||
final class StringUtil
|
final class StringUtil
|
||||||
{
|
{
|
||||||
/**
|
public static function endsWith(string $haystack, string $needle): bool
|
||||||
* @param string $haystack
|
|
||||||
* @param string $needle
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function endsWith($haystack, $needle)
|
|
||||||
{
|
{
|
||||||
$length = \strlen($needle);
|
return $needle === '' || ($haystack !== '' && substr_compare($haystack, $needle, -\strlen($needle)) === 0);
|
||||||
|
|
||||||
if ($length === 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return substr($haystack, -$length) === $needle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function isBinary(string $string): bool
|
||||||
* @param string $string
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isBinary($string)
|
|
||||||
{
|
{
|
||||||
return strpos($string, "\0") !== false;
|
return strpos($string, "\0") !== false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function isASCII(string $name): bool
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isASCII($name)
|
|
||||||
{
|
{
|
||||||
return preg_match('~[^\x20-\x7e]~', (string) $name) === 0;
|
return preg_match('~[^\x20-\x7e]~', $name) === 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
606
src/ZipFile.php
606
src/ZipFile.php
File diff suppressed because it is too large
Load Diff
@ -1,902 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PhpZip;
|
|
||||||
|
|
||||||
use PhpZip\Constants\ZipCompressionLevel;
|
|
||||||
use PhpZip\Constants\ZipCompressionMethod;
|
|
||||||
use PhpZip\Constants\ZipEncryptionMethod;
|
|
||||||
use PhpZip\Exception\ZipEntryNotFoundException;
|
|
||||||
use PhpZip\Exception\ZipException;
|
|
||||||
use PhpZip\Model\ZipEntry;
|
|
||||||
use PhpZip\Model\ZipEntryMatcher;
|
|
||||||
use PhpZip\Model\ZipInfo;
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
|
||||||
use Symfony\Component\Finder\Finder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create, open .ZIP files, modify, get info and extract files.
|
|
||||||
*
|
|
||||||
* Implemented support traditional PKWARE encryption and WinZip AES encryption.
|
|
||||||
* Implemented support ZIP64.
|
|
||||||
* Support ZipAlign functional.
|
|
||||||
*
|
|
||||||
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
|
|
||||||
*
|
|
||||||
* @author Ne-Lexa alexey@nelexa.ru
|
|
||||||
* @license MIT
|
|
||||||
*
|
|
||||||
* @deprecated will be removed in version 4.0. Use the {@see ZipFile} class.
|
|
||||||
*/
|
|
||||||
interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Method for Stored (uncompressed) entries.
|
|
||||||
*
|
|
||||||
* @see ZipEntry::setCompressionMethod()
|
|
||||||
* @deprecated Use {@see ZipCompressionMethod::STORED}
|
|
||||||
*/
|
|
||||||
const METHOD_STORED = ZipCompressionMethod::STORED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method for Deflated compressed entries.
|
|
||||||
*
|
|
||||||
* @see ZipEntry::setCompressionMethod()
|
|
||||||
* @deprecated Use {@see ZipCompressionMethod::DEFLATED}
|
|
||||||
*/
|
|
||||||
const METHOD_DEFLATED = ZipCompressionMethod::DEFLATED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method for BZIP2 compressed entries.
|
|
||||||
* Require php extension bz2.
|
|
||||||
*
|
|
||||||
* @see ZipEntry::setCompressionMethod()
|
|
||||||
* @deprecated Use {@see ZipCompressionMethod::BZIP2}
|
|
||||||
*/
|
|
||||||
const METHOD_BZIP2 = ZipCompressionMethod::BZIP2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int default compression level
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipCompressionLevel::NORMAL}
|
|
||||||
*/
|
|
||||||
const LEVEL_DEFAULT_COMPRESSION = ZipCompressionLevel::NORMAL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compression level for fastest compression.
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipCompressionLevel::FAST}
|
|
||||||
*/
|
|
||||||
const LEVEL_FAST = ZipCompressionLevel::FAST;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compression level for fastest compression.
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipCompressionLevel::SUPER_FAST}
|
|
||||||
*/
|
|
||||||
const LEVEL_BEST_SPEED = ZipCompressionLevel::SUPER_FAST;
|
|
||||||
|
|
||||||
/** @deprecated Use {@see ZipCompressionLevel::SUPER_FAST} */
|
|
||||||
const LEVEL_SUPER_FAST = ZipCompressionLevel::SUPER_FAST;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compression level for best compression.
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipCompressionLevel::MAXIMUM}
|
|
||||||
*/
|
|
||||||
const LEVEL_BEST_COMPRESSION = ZipCompressionLevel::MAXIMUM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No specified method for set encryption method to Traditional PKWARE encryption.
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipEncryptionMethod::PKWARE}
|
|
||||||
*/
|
|
||||||
const ENCRYPTION_METHOD_TRADITIONAL = ZipEncryptionMethod::PKWARE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No specified method for set encryption method to WinZip AES encryption.
|
|
||||||
* Default value 256 bit.
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipEncryptionMethod::WINZIP_AES_256}
|
|
||||||
*/
|
|
||||||
const ENCRYPTION_METHOD_WINZIP_AES = ZipEncryptionMethod::WINZIP_AES_256;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No specified method for set encryption method to WinZip AES encryption 128 bit.
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipEncryptionMethod::WINZIP_AES_128}
|
|
||||||
*/
|
|
||||||
const ENCRYPTION_METHOD_WINZIP_AES_128 = ZipEncryptionMethod::WINZIP_AES_128;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No specified method for set encryption method to WinZip AES encryption 194 bit.
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipEncryptionMethod::WINZIP_AES_192}
|
|
||||||
*/
|
|
||||||
const ENCRYPTION_METHOD_WINZIP_AES_192 = ZipEncryptionMethod::WINZIP_AES_192;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No specified method for set encryption method to WinZip AES encryption 256 bit.
|
|
||||||
*
|
|
||||||
* @deprecated Use {@see ZipEncryptionMethod::WINZIP_AES_256}
|
|
||||||
*/
|
|
||||||
const ENCRYPTION_METHOD_WINZIP_AES_256 = ZipEncryptionMethod::WINZIP_AES_256;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open zip archive from file.
|
|
||||||
*
|
|
||||||
* @param string $filename
|
|
||||||
* @param array $options
|
|
||||||
*
|
|
||||||
* @throws ZipException if can't open file
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function openFile($filename, array $options = []);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open zip archive from raw string data.
|
|
||||||
*
|
|
||||||
* @param string $data
|
|
||||||
* @param array $options
|
|
||||||
*
|
|
||||||
* @throws ZipException if can't open temp stream
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function openFromString($data, array $options = []);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open zip archive from stream resource.
|
|
||||||
*
|
|
||||||
* @param resource $handle
|
|
||||||
* @param array $options
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function openFromStream($handle, array $options = []);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string[] returns the list files
|
|
||||||
*/
|
|
||||||
public function getListFiles();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int returns the number of entries in this ZIP file
|
|
||||||
*/
|
|
||||||
public function count();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the file comment.
|
|
||||||
*
|
|
||||||
* @return string|null the file comment
|
|
||||||
*/
|
|
||||||
public function getArchiveComment();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set archive comment.
|
|
||||||
*
|
|
||||||
* @param string|null $comment
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function setArchiveComment($comment = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if there is an entry in the archive.
|
|
||||||
*
|
|
||||||
* @param string $entryName
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function hasEntry($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns ZipEntry object.
|
|
||||||
*
|
|
||||||
* @param string $entryName
|
|
||||||
*
|
|
||||||
* @throws ZipEntryNotFoundException
|
|
||||||
*
|
|
||||||
* @return ZipEntry
|
|
||||||
*/
|
|
||||||
public function getEntry($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks that the entry in the archive is a directory.
|
|
||||||
* Returns true if and only if this ZIP entry represents a directory entry
|
|
||||||
* (i.e. end with '/').
|
|
||||||
*
|
|
||||||
* @param string $entryName
|
|
||||||
*
|
|
||||||
* @throws ZipEntryNotFoundException
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isDirectory($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns entry comment.
|
|
||||||
*
|
|
||||||
* @param string $entryName
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
* @throws ZipEntryNotFoundException
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getEntryComment($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set entry comment.
|
|
||||||
*
|
|
||||||
* @param string $entryName
|
|
||||||
* @param string|null $comment
|
|
||||||
*
|
|
||||||
* @throws ZipEntryNotFoundException
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function setEntryComment($entryName, $comment = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the entry contents.
|
|
||||||
*
|
|
||||||
* @param string $entryName
|
|
||||||
*
|
|
||||||
* @throws ZipEntryNotFoundException
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getEntryContents($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $entryName
|
|
||||||
*
|
|
||||||
* @throws ZipEntryNotFoundException
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return resource
|
|
||||||
*/
|
|
||||||
public function getEntryStream($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get info by entry.
|
|
||||||
*
|
|
||||||
* @param string|ZipEntry $entryName
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
* @throws ZipEntryNotFoundException
|
|
||||||
*
|
|
||||||
* @return ZipInfo
|
|
||||||
*/
|
|
||||||
public function getEntryInfo($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get info by all entries.
|
|
||||||
*
|
|
||||||
* @return ZipInfo[]
|
|
||||||
*/
|
|
||||||
public function getAllInfo();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return ZipEntryMatcher
|
|
||||||
*/
|
|
||||||
public function matcher();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the archive contents (unzip).
|
|
||||||
*
|
|
||||||
* Extract the complete archive or the given files to the specified destination.
|
|
||||||
*
|
|
||||||
* @param string $destDir location where to extract the files
|
|
||||||
* @param array|string|null $entries entries to extract
|
|
||||||
* @param array $options extract options
|
|
||||||
* @param array $extractedEntries if the extractedEntries argument
|
|
||||||
* is present, then the specified
|
|
||||||
* array will be filled with
|
|
||||||
* information about the
|
|
||||||
* extracted entries
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function extractTo($destDir, $entries = null, array $options = [], &$extractedEntries = []);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add entry from the string.
|
|
||||||
*
|
|
||||||
* @param string $entryName zip entry name
|
|
||||||
* @param string $contents string contents
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED},
|
|
||||||
* {@see ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}.
|
|
||||||
* If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function addFromString($entryName, $contents, $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Finder $finder
|
|
||||||
* @param array $options
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipEntry[]
|
|
||||||
*/
|
|
||||||
public function addFromFinder(Finder $finder, array $options = []);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \SplFileInfo $file
|
|
||||||
* @param string|null $entryName
|
|
||||||
* @param array $options
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipEntry
|
|
||||||
*/
|
|
||||||
public function addSplFile(\SplFileInfo $file, $entryName = null, array $options = []);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add entry from the file.
|
|
||||||
*
|
|
||||||
* @param string $filename destination file
|
|
||||||
* @param string|null $entryName zip Entry name
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED},
|
|
||||||
* {@see ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}.
|
|
||||||
* If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function addFile($filename, $entryName = null, $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add entry from the stream.
|
|
||||||
*
|
|
||||||
* @param resource $stream stream resource
|
|
||||||
* @param string $entryName zip Entry name
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED},
|
|
||||||
* {@see ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}.
|
|
||||||
* If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function addFromStream($stream, $entryName, $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an empty directory in the zip archive.
|
|
||||||
*
|
|
||||||
* @param string $dirName
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function addEmptyDir($dirName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add directory not recursively to the zip archive.
|
|
||||||
*
|
|
||||||
* @param string $inputDir Input directory
|
|
||||||
* @param string $localPath add files to this directory, or the root
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
*
|
|
||||||
* Use {@see ZipCompressionMethod::STORED}, {@see
|
|
||||||
* ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}. If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function addDir($inputDir, $localPath = '/', $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add recursive directory to the zip archive.
|
|
||||||
*
|
|
||||||
* @param string $inputDir Input directory
|
|
||||||
* @param string $localPath add files to this directory, or the root
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED}, {@see
|
|
||||||
* ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}. If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*
|
|
||||||
* @see ZipCompressionMethod::STORED
|
|
||||||
* @see ZipCompressionMethod::DEFLATED
|
|
||||||
* @see ZipCompressionMethod::BZIP2
|
|
||||||
*/
|
|
||||||
public function addDirRecursive($inputDir, $localPath = '/', $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add directories from directory iterator.
|
|
||||||
*
|
|
||||||
* @param \Iterator $iterator directory iterator
|
|
||||||
* @param string $localPath add files to this directory, or the root
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED}, {@see
|
|
||||||
* ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}. If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*
|
|
||||||
* @see ZipCompressionMethod::STORED
|
|
||||||
* @see ZipCompressionMethod::DEFLATED
|
|
||||||
* @see ZipCompressionMethod::BZIP2
|
|
||||||
*/
|
|
||||||
public function addFilesFromIterator(\Iterator $iterator, $localPath = '/', $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add files from glob pattern.
|
|
||||||
*
|
|
||||||
* @param string $inputDir Input directory
|
|
||||||
* @param string $globPattern glob pattern
|
|
||||||
* @param string $localPath add files to this directory, or the root
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED},
|
|
||||||
* {@see ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}. If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
* @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
|
|
||||||
*/
|
|
||||||
public function addFilesFromGlob($inputDir, $globPattern, $localPath = '/', $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add files recursively from glob pattern.
|
|
||||||
*
|
|
||||||
* @param string $inputDir Input directory
|
|
||||||
* @param string $globPattern glob pattern
|
|
||||||
* @param string $localPath add files to this directory, or the root
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED},
|
|
||||||
* {@see ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}. If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
* @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
|
|
||||||
*/
|
|
||||||
public function addFilesFromGlobRecursive($inputDir, $globPattern, $localPath = '/', $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add files from regex pattern.
|
|
||||||
*
|
|
||||||
* @param string $inputDir search files in this directory
|
|
||||||
* @param string $regexPattern regex pattern
|
|
||||||
* @param string $localPath add files to this directory, or the root
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED},
|
|
||||||
* {@see ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}. If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*
|
|
||||||
* @internal param bool $recursive Recursive search
|
|
||||||
*/
|
|
||||||
public function addFilesFromRegex($inputDir, $regexPattern, $localPath = '/', $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add files recursively from regex pattern.
|
|
||||||
*
|
|
||||||
* @param string $inputDir search files in this directory
|
|
||||||
* @param string $regexPattern regex pattern
|
|
||||||
* @param string $localPath add files to this directory, or the root
|
|
||||||
* @param int|null $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED},
|
|
||||||
* {@see ZipCompressionMethod::DEFLATED} or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}. If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*
|
|
||||||
* @internal param bool $recursive Recursive search
|
|
||||||
*/
|
|
||||||
public function addFilesFromRegexRecursive($inputDir, $regexPattern, $localPath = '/', $compressionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add array data to archive.
|
|
||||||
* Keys is local names.
|
|
||||||
* Values is contents.
|
|
||||||
*
|
|
||||||
* @param array $mapData associative array for added to zip
|
|
||||||
*/
|
|
||||||
public function addAll(array $mapData);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rename the entry.
|
|
||||||
*
|
|
||||||
* @param string $oldName old entry name
|
|
||||||
* @param string $newName new entry name
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function rename($oldName, $newName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete entry by name.
|
|
||||||
*
|
|
||||||
* @param string $entryName zip Entry name
|
|
||||||
*
|
|
||||||
* @throws ZipEntryNotFoundException if entry not found
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function deleteFromName($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete entries by glob pattern.
|
|
||||||
*
|
|
||||||
* @param string $globPattern Glob pattern
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
* @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
|
|
||||||
*/
|
|
||||||
public function deleteFromGlob($globPattern);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete entries by regex pattern.
|
|
||||||
*
|
|
||||||
* @param string $regexPattern Regex pattern
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function deleteFromRegex($regexPattern);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all entries.
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function deleteAll();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set compression level for new entries.
|
|
||||||
*
|
|
||||||
* @param int $compressionLevel
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*
|
|
||||||
* @see ZipCompressionLevel::NORMAL
|
|
||||||
* @see ZipCompressionLevel::SUPER_FAST
|
|
||||||
* @see ZipCompressionLevel::FAST
|
|
||||||
* @see ZipCompressionLevel::MAXIMUM
|
|
||||||
*/
|
|
||||||
public function setCompressionLevel($compressionLevel = ZipCompressionLevel::NORMAL);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $entryName
|
|
||||||
* @param int $compressionLevel
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*
|
|
||||||
* @see ZipCompressionLevel::NORMAL
|
|
||||||
* @see ZipCompressionLevel::SUPER_FAST
|
|
||||||
* @see ZipCompressionLevel::FAST
|
|
||||||
* @see ZipCompressionLevel::MAXIMUM
|
|
||||||
*/
|
|
||||||
public function setCompressionLevelEntry($entryName, $compressionLevel);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $entryName
|
|
||||||
* @param int $compressionMethod Compression method.
|
|
||||||
* Use {@see ZipCompressionMethod::STORED}, {@see ZipCompressionMethod::DEFLATED}
|
|
||||||
* or
|
|
||||||
* {@see ZipCompressionMethod::BZIP2}. If null, then auto choosing method.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*
|
|
||||||
* @see ZipCompressionMethod::STORED
|
|
||||||
* @see ZipCompressionMethod::DEFLATED
|
|
||||||
* @see ZipCompressionMethod::BZIP2
|
|
||||||
*/
|
|
||||||
public function setCompressionMethodEntry($entryName, $compressionMethod);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* zipalign is optimization to Android application (APK) files.
|
|
||||||
*
|
|
||||||
* @param int|null $align
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*
|
|
||||||
* @see https://developer.android.com/studio/command-line/zipalign.html
|
|
||||||
*/
|
|
||||||
public function setZipAlign($align = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set password to all input encrypted entries.
|
|
||||||
*
|
|
||||||
* @param string $password Password
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function setReadPassword($password);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set password to concrete input entry.
|
|
||||||
*
|
|
||||||
* @param string $entryName
|
|
||||||
* @param string $password Password
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function setReadPasswordEntry($entryName, $password);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a new password for all files in the archive.
|
|
||||||
*
|
|
||||||
* @param string $password Password
|
|
||||||
* @param int|null $encryptionMethod Encryption method
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function setPassword($password, $encryptionMethod = ZipEncryptionMethod::WINZIP_AES_256);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a new password of an entry defined by its name.
|
|
||||||
*
|
|
||||||
* @param string $entryName
|
|
||||||
* @param string $password
|
|
||||||
* @param int|null $encryptionMethod
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function setPasswordEntry($entryName, $password, $encryptionMethod = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable encryption for all entries that are already in the archive.
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function disableEncryption();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable encryption of an entry defined by its name.
|
|
||||||
*
|
|
||||||
* @param string $entryName
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function disableEncryptionEntry($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Undo all changes done in the archive.
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function unchangeAll();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Undo change archive comment.
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function unchangeArchiveComment();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Revert all changes done to an entry with the given name.
|
|
||||||
*
|
|
||||||
* @param string|ZipEntry $entry Entry name or ZipEntry
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function unchangeEntry($entry);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save as file.
|
|
||||||
*
|
|
||||||
* @param string $filename Output filename
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function saveAsFile($filename);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save as stream.
|
|
||||||
*
|
|
||||||
* @param resource $handle Output stream resource
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function saveAsStream($handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Output .ZIP archive as attachment.
|
|
||||||
* Die after output.
|
|
||||||
*
|
|
||||||
* @param string $outputFilename Output filename
|
|
||||||
* @param string|null $mimeType Mime-Type
|
|
||||||
* @param bool $attachment Http Header 'Content-Disposition' if true then attachment otherwise inline
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*/
|
|
||||||
public function outputAsAttachment($outputFilename, $mimeType = null, $attachment = true);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Output .ZIP archive as PSR-7 Response.
|
|
||||||
*
|
|
||||||
* @param ResponseInterface $response Instance PSR-7 Response
|
|
||||||
* @param string $outputFilename Output filename
|
|
||||||
* @param string|null $mimeType Mime-Type
|
|
||||||
* @param bool $attachment Http Header 'Content-Disposition' if true then attachment otherwise inline
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ResponseInterface
|
|
||||||
*/
|
|
||||||
public function outputAsResponse(
|
|
||||||
ResponseInterface $response,
|
|
||||||
$outputFilename,
|
|
||||||
$mimeType = null,
|
|
||||||
$attachment = true
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the zip archive as a string.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function outputAsString();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close zip archive and release input stream.
|
|
||||||
*/
|
|
||||||
public function close();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save and reopen zip archive.
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return ZipFile
|
|
||||||
*/
|
|
||||||
public function rewrite();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Offset to set.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/arrayaccess.offsetset.php
|
|
||||||
*
|
|
||||||
* @param string $entryName the offset to assign the value to
|
|
||||||
* @param string|\DirectoryIterator|\SplFileInfo|resource $contents the value to set
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @see ZipFile::addFromString
|
|
||||||
* @see ZipFile::addEmptyDir
|
|
||||||
* @see ZipFile::addFile
|
|
||||||
* @see ZipFile::addFilesFromIterator
|
|
||||||
*/
|
|
||||||
public function offsetSet($entryName, $contents);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Offset to unset.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/arrayaccess.offsetunset.php
|
|
||||||
*
|
|
||||||
* @param string $entryName the offset to unset
|
|
||||||
*
|
|
||||||
* @throws ZipEntryNotFoundException
|
|
||||||
*/
|
|
||||||
public function offsetUnset($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the current element.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/iterator.current.php
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return mixed can return any type
|
|
||||||
*
|
|
||||||
* @since 5.0.0
|
|
||||||
*/
|
|
||||||
public function current();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Offset to retrieve.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/arrayaccess.offsetget.php
|
|
||||||
*
|
|
||||||
* @param string $entryName the offset to retrieve
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function offsetGet($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the key of the current element.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/iterator.key.php
|
|
||||||
*
|
|
||||||
* @return mixed scalar on success, or null on failure
|
|
||||||
*
|
|
||||||
* @since 5.0.0
|
|
||||||
*/
|
|
||||||
public function key();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move forward to next element.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/iterator.next.php
|
|
||||||
* @since 5.0.0
|
|
||||||
*/
|
|
||||||
public function next();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if current position is valid.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/iterator.valid.php
|
|
||||||
*
|
|
||||||
* @return bool The return value will be casted to boolean and then evaluated.
|
|
||||||
* Returns true on success or false on failure.
|
|
||||||
*
|
|
||||||
* @since 5.0.0
|
|
||||||
*/
|
|
||||||
public function valid();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether a offset exists.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/arrayaccess.offsetexists.php
|
|
||||||
*
|
|
||||||
* @param string $entryName an offset to check for
|
|
||||||
*
|
|
||||||
* @return bool true on success or false on failure.
|
|
||||||
* The return value will be casted to boolean if non-boolean was returned.
|
|
||||||
*/
|
|
||||||
public function offsetExists($entryName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rewind the Iterator to the first element.
|
|
||||||
*
|
|
||||||
* @see http://php.net/manual/en/iterator.rewind.php
|
|
||||||
* @since 5.0.0
|
|
||||||
*/
|
|
||||||
public function rewind();
|
|
||||||
}
|
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests;
|
namespace PhpZip\Tests;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipEntryNotFoundException;
|
use PhpZip\Exception\ZipEntryNotFoundException;
|
||||||
@ -26,7 +35,7 @@ final class CustomZipFormatTest extends ZipTestCase
|
|||||||
*
|
*
|
||||||
* @see http://www.epubtest.org/test-books source epub files
|
* @see http://www.epubtest.org/test-books source epub files
|
||||||
*/
|
*/
|
||||||
public function testEpub()
|
public function testEpub(): void
|
||||||
{
|
{
|
||||||
$epubFile = new EpubFile();
|
$epubFile = new EpubFile();
|
||||||
$epubFile->openFile(__DIR__ . '/resources/Advanced-v1.0.0.epub');
|
$epubFile->openFile(__DIR__ . '/resources/Advanced-v1.0.0.epub');
|
||||||
@ -67,7 +76,7 @@ final class CustomZipFormatTest extends ZipTestCase
|
|||||||
/**
|
/**
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function testBeforeSaveInZipWriter()
|
public function testBeforeSaveInZipWriter(): void
|
||||||
{
|
{
|
||||||
$zipFile = new ZipFileCustomWriter();
|
$zipFile = new ZipFileCustomWriter();
|
||||||
for ($i = 0; $i < 10; $i++) {
|
for ($i = 0; $i < 10; $i++) {
|
||||||
@ -88,7 +97,7 @@ final class CustomZipFormatTest extends ZipTestCase
|
|||||||
/**
|
/**
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function testBeforeSaveInZipFile()
|
public function testBeforeSaveInZipFile(): void
|
||||||
{
|
{
|
||||||
$zipFile = new ZipFileWithBeforeSave();
|
$zipFile = new ZipFileWithBeforeSave();
|
||||||
for ($i = 0; $i < 10; $i++) {
|
for ($i = 0; $i < 10; $i++) {
|
||||||
@ -106,11 +115,7 @@ final class CustomZipFormatTest extends ZipTestCase
|
|||||||
$zipFile->close();
|
$zipFile->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function existsExtraFields(ZipFile $zipFile, bool $exists): void
|
||||||
* @param ZipFile $zipFile
|
|
||||||
* @param bool $exists
|
|
||||||
*/
|
|
||||||
private function existsExtraFields(ZipFile $zipFile, $exists)
|
|
||||||
{
|
{
|
||||||
foreach ($zipFile->getEntries() as $entry) {
|
foreach ($zipFile->getEntries() as $entry) {
|
||||||
$localExtras = $entry->getLocalExtraFields();
|
$localExtras = $entry->getLocalExtraFields();
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/** @noinspection PhpUndefinedMethodInspection */
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
@ -8,32 +15,22 @@ use PHPUnit\Framework\TestCase;
|
|||||||
use PhpZip\Exception\ZipException;
|
use PhpZip\Exception\ZipException;
|
||||||
use PhpZip\Model\Extra\Fields\AbstractUnicodeExtraField;
|
use PhpZip\Model\Extra\Fields\AbstractUnicodeExtraField;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class AbstractUnicodeExtraFieldTest.
|
|
||||||
*/
|
|
||||||
abstract class AbstractUnicodeExtraFieldTest extends TestCase
|
abstract class AbstractUnicodeExtraFieldTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return string|AbstractUnicodeExtraField
|
* @return string|AbstractUnicodeExtraField
|
||||||
*
|
*
|
||||||
* @psalm-var class-string<\PhpZip\Model\Extra\Fields\AbstractUnicodeExtraField>
|
* @psalm-var class-string<AbstractUnicodeExtraField>
|
||||||
*/
|
*/
|
||||||
abstract protected function getUnicodeExtraFieldClassName();
|
abstract protected function getUnicodeExtraFieldClassName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int $crc32
|
|
||||||
* @param string $unicodePath
|
|
||||||
* @param string $originalPath
|
|
||||||
* @param string $binaryData
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testExtraField($crc32, $unicodePath, $originalPath, $binaryData)
|
public function testExtraField(int $crc32, string $unicodePath, string $originalPath, string $binaryData): void
|
||||||
{
|
{
|
||||||
$crc32 = (int) $crc32; // for php 32-bit
|
|
||||||
|
|
||||||
$className = $this->getUnicodeExtraFieldClassName();
|
$className = $this->getUnicodeExtraFieldClassName();
|
||||||
|
|
||||||
/** @var AbstractUnicodeExtraField $extraField */
|
/** @var AbstractUnicodeExtraField $extraField */
|
||||||
@ -48,12 +45,9 @@ abstract class AbstractUnicodeExtraFieldTest extends TestCase
|
|||||||
static::assertEquals($className::unpackCentralDirData($binaryData), $extraField);
|
static::assertEquals($className::unpackCentralDirData($binaryData), $extraField);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
abstract public function provideExtraField(): array;
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
abstract public function provideExtraField();
|
|
||||||
|
|
||||||
public function testSetter()
|
public function testSetter(): void
|
||||||
{
|
{
|
||||||
$className = $this->getUnicodeExtraFieldClassName();
|
$className = $this->getUnicodeExtraFieldClassName();
|
||||||
$entryName = '11111';
|
$entryName = '11111';
|
||||||
@ -74,12 +68,10 @@ abstract class AbstractUnicodeExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testUnicodeErrorParse()
|
public function testUnicodeErrorParse(): void
|
||||||
{
|
{
|
||||||
$this->expectException(
|
$this->expectException(ZipException::class);
|
||||||
ZipException::class,
|
$this->expectExceptionMessage('Unicode path extra data must have at least 5 bytes.');
|
||||||
'Unicode path extra data must have at least 5 bytes.'
|
|
||||||
);
|
|
||||||
|
|
||||||
$className = $this->getUnicodeExtraFieldClassName();
|
$className = $this->getUnicodeExtraFieldClassName();
|
||||||
$className::unpackLocalFileData('');
|
$className::unpackLocalFileData('');
|
||||||
@ -88,12 +80,10 @@ abstract class AbstractUnicodeExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testUnknownVersionParse()
|
public function testUnknownVersionParse(): void
|
||||||
{
|
{
|
||||||
$this->expectException(
|
$this->expectException(ZipException::class);
|
||||||
ZipException::class,
|
$this->expectExceptionMessage('Unsupported version [2] for Unicode path extra data.');
|
||||||
'Unsupported version [2] for Unicode path extra data.'
|
|
||||||
);
|
|
||||||
|
|
||||||
$className = $this->getUnicodeExtraFieldClassName();
|
$className = $this->getUnicodeExtraFieldClassName();
|
||||||
$className::unpackLocalFileData("\x02\x04a\xD28\xC3\xA4\\\xC3\xBC.txt");
|
$className::unpackLocalFileData("\x02\x04a\xD28\xC3\xA4\\\xC3\xBC.txt");
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -16,19 +25,14 @@ final class ApkAlignmentExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int $multiple
|
|
||||||
* @param int $padding
|
|
||||||
* @param string $binaryData
|
|
||||||
* @param string $toString
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testExtraField(
|
public function testExtraField(
|
||||||
$multiple,
|
int $multiple,
|
||||||
$padding,
|
int $padding,
|
||||||
$binaryData,
|
string $binaryData,
|
||||||
$toString
|
string $toString
|
||||||
) {
|
): void {
|
||||||
$extraField = new ApkAlignmentExtraField($multiple, $padding);
|
$extraField = new ApkAlignmentExtraField($multiple, $padding);
|
||||||
self::assertSame($extraField->getHeaderId(), ApkAlignmentExtraField::HEADER_ID);
|
self::assertSame($extraField->getHeaderId(), ApkAlignmentExtraField::HEADER_ID);
|
||||||
self::assertSame($extraField->getMultiple(), $multiple);
|
self::assertSame($extraField->getMultiple(), $multiple);
|
||||||
@ -43,10 +47,7 @@ final class ApkAlignmentExtraFieldTest extends TestCase
|
|||||||
self::assertSame((string) $extraField, $toString);
|
self::assertSame((string) $extraField, $toString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
@ -82,7 +83,7 @@ final class ApkAlignmentExtraFieldTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetter()
|
public function testSetter(): void
|
||||||
{
|
{
|
||||||
$extraField = new ApkAlignmentExtraField(ApkAlignmentExtraField::ALIGNMENT_BYTES, 3);
|
$extraField = new ApkAlignmentExtraField(ApkAlignmentExtraField::ALIGNMENT_BYTES, 3);
|
||||||
$extraField->setMultiple(ApkAlignmentExtraField::COMMON_PAGE_ALIGNMENT_BYTES);
|
$extraField->setMultiple(ApkAlignmentExtraField::COMMON_PAGE_ALIGNMENT_BYTES);
|
||||||
@ -94,12 +95,10 @@ final class ApkAlignmentExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testInvalidParse()
|
public function testInvalidParse(): void
|
||||||
{
|
{
|
||||||
$this->expectException(
|
$this->expectException(ZipException::class);
|
||||||
ZipException::class,
|
$this->expectExceptionMessage('Minimum 6 bytes of the extensible data block/field used for alignment of uncompressed entries.');
|
||||||
'Minimum 6 bytes of the extensible data block/field used for alignment of uncompressed entries.'
|
|
||||||
);
|
|
||||||
|
|
||||||
ApkAlignmentExtraField::unpackLocalFileData("\x04");
|
ApkAlignmentExtraField::unpackLocalFileData("\x04");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -17,15 +26,9 @@ final class AsiExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int $mode
|
|
||||||
* @param int $uid
|
|
||||||
* @param int $gid
|
|
||||||
* @param string $link
|
|
||||||
* @param string $binaryData
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testExtraField($mode, $uid, $gid, $link, $binaryData)
|
public function testExtraField(int $mode, int $uid, int $gid, string $link, string $binaryData): void
|
||||||
{
|
{
|
||||||
$asiExtraField = new AsiExtraField($mode, $uid, $gid, $link);
|
$asiExtraField = new AsiExtraField($mode, $uid, $gid, $link);
|
||||||
self::assertSame($asiExtraField->getHeaderId(), AsiExtraField::HEADER_ID);
|
self::assertSame($asiExtraField->getHeaderId(), AsiExtraField::HEADER_ID);
|
||||||
@ -42,10 +45,7 @@ final class AsiExtraFieldTest extends TestCase
|
|||||||
self::assertEquals(AsiExtraField::unpackCentralDirData($binaryData), $asiExtraField);
|
self::assertEquals(AsiExtraField::unpackCentralDirData($binaryData), $asiExtraField);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
@ -65,7 +65,7 @@ final class AsiExtraFieldTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetter()
|
public function testSetter(): void
|
||||||
{
|
{
|
||||||
$extraField = new AsiExtraField(0777);
|
$extraField = new AsiExtraField(0777);
|
||||||
$extraField->setMode(0100666);
|
$extraField->setMode(0100666);
|
||||||
@ -89,12 +89,10 @@ final class AsiExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws Crc32Exception
|
* @throws Crc32Exception
|
||||||
*/
|
*/
|
||||||
public function testInvalidParse()
|
public function testInvalidParse(): void
|
||||||
{
|
{
|
||||||
$this->expectException(
|
$this->expectException(Crc32Exception::class);
|
||||||
Crc32Exception::class,
|
$this->expectExceptionMessage('Asi Unix Extra Filed Data (expected CRC32 value');
|
||||||
'Asi Unix Extra Filed Data (expected CRC32 value'
|
|
||||||
);
|
|
||||||
|
|
||||||
AsiExtraField::unpackLocalFileData("\x01\x06\\\xF6\xEDA\x00\x00\x00\x00\xE8\x03\xE8\x03");
|
AsiExtraField::unpackLocalFileData("\x01\x06\\\xF6\xEDA\x00\x00\x00\x00\xE8\x03\xE8\x03");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -17,23 +26,20 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int $flags
|
|
||||||
* @param int|null $modifyTime
|
|
||||||
* @param int|null $accessTime
|
|
||||||
* @param int|null $createTime
|
|
||||||
* @param string $localData
|
|
||||||
* @param string $cdData
|
|
||||||
*
|
|
||||||
* @noinspection PhpTooManyParametersInspection
|
* @noinspection PhpTooManyParametersInspection
|
||||||
|
*
|
||||||
|
* @param ?int $modifyTime
|
||||||
|
* @param ?int $accessTime
|
||||||
|
* @param ?int $createTime
|
||||||
*/
|
*/
|
||||||
public function testExtraField(
|
public function testExtraField(
|
||||||
$flags,
|
int $flags,
|
||||||
$modifyTime,
|
?int $modifyTime,
|
||||||
$accessTime,
|
?int $accessTime,
|
||||||
$createTime,
|
?int $createTime,
|
||||||
$localData,
|
string $localData,
|
||||||
$cdData
|
string $cdData
|
||||||
) {
|
): void {
|
||||||
$localExtraField = new ExtendedTimestampExtraField($flags, $modifyTime, $accessTime, $createTime);
|
$localExtraField = new ExtendedTimestampExtraField($flags, $modifyTime, $accessTime, $createTime);
|
||||||
self::assertSame($localExtraField->getHeaderId(), ExtendedTimestampExtraField::HEADER_ID);
|
self::assertSame($localExtraField->getHeaderId(), ExtendedTimestampExtraField::HEADER_ID);
|
||||||
self::assertSame($localExtraField->getFlags(), $flags);
|
self::assertSame($localExtraField->getFlags(), $flags);
|
||||||
@ -59,16 +65,13 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
|||||||
self::assertSame($localExtraField->packCentralDirData(), $cdData);
|
self::assertSame($localExtraField->packCentralDirData(), $cdData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT |
|
| ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||||
ExtendedTimestampExtraField::CREATE_TIME_BIT,
|
| ExtendedTimestampExtraField::CREATE_TIME_BIT,
|
||||||
911512006,
|
911512006,
|
||||||
911430000,
|
911430000,
|
||||||
893709400,
|
893709400,
|
||||||
@ -76,8 +79,8 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
|||||||
"\x07\xC6\x91T6",
|
"\x07\xC6\x91T6",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT,
|
| ExtendedTimestampExtraField::ACCESS_TIME_BIT,
|
||||||
1492955702,
|
1492955702,
|
||||||
1492955638,
|
1492955638,
|
||||||
null,
|
null,
|
||||||
@ -98,7 +101,7 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function testSetter()
|
public function testSetter(): void
|
||||||
{
|
{
|
||||||
$mtime = time();
|
$mtime = time();
|
||||||
$atime = null;
|
$atime = null;
|
||||||
@ -115,8 +118,8 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
|||||||
$field->setAccessTime($atime);
|
$field->setAccessTime($atime);
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
$field->getFlags(),
|
$field->getFlags(),
|
||||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
| ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||||
);
|
);
|
||||||
self::assertSame($field->getModifyTime(), $mtime);
|
self::assertSame($field->getModifyTime(), $mtime);
|
||||||
self::assertSame($field->getAccessTime(), $atime);
|
self::assertSame($field->getAccessTime(), $atime);
|
||||||
@ -127,9 +130,9 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
|||||||
$field->setCreateTime($ctime);
|
$field->setCreateTime($ctime);
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
$field->getFlags(),
|
$field->getFlags(),
|
||||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT |
|
| ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||||
ExtendedTimestampExtraField::CREATE_TIME_BIT
|
| ExtendedTimestampExtraField::CREATE_TIME_BIT
|
||||||
);
|
);
|
||||||
self::assertSame($field->getModifyTime(), $mtime);
|
self::assertSame($field->getModifyTime(), $mtime);
|
||||||
self::assertSame($field->getAccessTime(), $atime);
|
self::assertSame($field->getAccessTime(), $atime);
|
||||||
@ -141,8 +144,8 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
|||||||
self::assertNull($field->getCreateDateTime());
|
self::assertNull($field->getCreateDateTime());
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
$field->getFlags(),
|
$field->getFlags(),
|
||||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
| ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||||
);
|
);
|
||||||
|
|
||||||
$field->setAccessTime(null);
|
$field->setAccessTime(null);
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -18,7 +27,7 @@ final class JarMarkerExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testExtraField()
|
public function testExtraField(): void
|
||||||
{
|
{
|
||||||
$jarField = new JarMarkerExtraField();
|
$jarField = new JarMarkerExtraField();
|
||||||
self::assertSame('', $jarField->packLocalFileData());
|
self::assertSame('', $jarField->packLocalFileData());
|
||||||
@ -30,12 +39,10 @@ final class JarMarkerExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testInvalidUnpackLocalData()
|
public function testInvalidUnpackLocalData(): void
|
||||||
{
|
{
|
||||||
$this->expectException(
|
$this->expectException(ZipException::class);
|
||||||
ZipException::class,
|
$this->expectExceptionMessage("JarMarker doesn't expect any data");
|
||||||
"JarMarker doesn't expect any data"
|
|
||||||
);
|
|
||||||
|
|
||||||
JarMarkerExtraField::unpackLocalFileData("\x02\x00\00");
|
JarMarkerExtraField::unpackLocalFileData("\x02\x00\00");
|
||||||
}
|
}
|
||||||
@ -43,12 +50,10 @@ final class JarMarkerExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testInvalidUnpackCdData()
|
public function testInvalidUnpackCdData(): void
|
||||||
{
|
{
|
||||||
$this->expectException(
|
$this->expectException(ZipException::class);
|
||||||
ZipException::class,
|
$this->expectExceptionMessage("JarMarker doesn't expect any data");
|
||||||
"JarMarker doesn't expect any data"
|
|
||||||
);
|
|
||||||
|
|
||||||
JarMarkerExtraField::unpackCentralDirData("\x02\x00\00");
|
JarMarkerExtraField::unpackCentralDirData("\x02\x00\00");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -18,14 +27,9 @@ final class NewUnixExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int $version
|
|
||||||
* @param int $uid
|
|
||||||
* @param int $gid
|
|
||||||
* @param string $binaryData
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testExtraField($version, $uid, $gid, $binaryData)
|
public function testExtraField(int $version, int $uid, int $gid, string $binaryData): void
|
||||||
{
|
{
|
||||||
$extraField = new NewUnixExtraField($version, $uid, $gid);
|
$extraField = new NewUnixExtraField($version, $uid, $gid);
|
||||||
self::assertSame($extraField->getHeaderId(), NewUnixExtraField::HEADER_ID);
|
self::assertSame($extraField->getHeaderId(), NewUnixExtraField::HEADER_ID);
|
||||||
@ -40,10 +44,7 @@ final class NewUnixExtraFieldTest extends TestCase
|
|||||||
self::assertSame($extraField->packCentralDirData(), $binaryData);
|
self::assertSame($extraField->packCentralDirData(), $binaryData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
@ -79,7 +80,7 @@ final class NewUnixExtraFieldTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetter()
|
public function testSetter(): void
|
||||||
{
|
{
|
||||||
$extraField = new NewUnixExtraField(1, 1000, 1000);
|
$extraField = new NewUnixExtraField(1, 1000, 1000);
|
||||||
self::assertSame(1, $extraField->getVersion());
|
self::assertSame(1, $extraField->getVersion());
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use PhpZip\Model\Extra\Fields\NtfsExtraField;
|
use PhpZip\Model\Extra\Fields\NtfsExtraField;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class NtfsExtraFieldTest.
|
|
||||||
*
|
|
||||||
* @internal
|
* @internal
|
||||||
*
|
*
|
||||||
* @small
|
* @small
|
||||||
@ -24,27 +31,19 @@ final class NtfsExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int $modifyNtfsTime
|
|
||||||
* @param int $accessNtfsTime
|
|
||||||
* @param int $createNtfsTime
|
|
||||||
* @param float $modifyTimestamp
|
|
||||||
* @param float $accessTimestamp
|
|
||||||
* @param float $createTimestamp
|
|
||||||
* @param string $binaryData
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*
|
*
|
||||||
* @noinspection PhpTooManyParametersInspection
|
* @noinspection PhpTooManyParametersInspection
|
||||||
*/
|
*/
|
||||||
public function testExtraField(
|
public function testExtraField(
|
||||||
$modifyNtfsTime,
|
int $modifyNtfsTime,
|
||||||
$accessNtfsTime,
|
int $accessNtfsTime,
|
||||||
$createNtfsTime,
|
int $createNtfsTime,
|
||||||
$modifyTimestamp,
|
float $modifyTimestamp,
|
||||||
$accessTimestamp,
|
float $accessTimestamp,
|
||||||
$createTimestamp,
|
float $createTimestamp,
|
||||||
$binaryData
|
string $binaryData
|
||||||
) {
|
): void {
|
||||||
$extraField = new NtfsExtraField($modifyNtfsTime, $accessNtfsTime, $createNtfsTime);
|
$extraField = new NtfsExtraField($modifyNtfsTime, $accessNtfsTime, $createNtfsTime);
|
||||||
self::assertSame($extraField->getHeaderId(), NtfsExtraField::HEADER_ID);
|
self::assertSame($extraField->getHeaderId(), NtfsExtraField::HEADER_ID);
|
||||||
|
|
||||||
@ -64,15 +63,24 @@ final class NtfsExtraFieldTest extends TestCase
|
|||||||
$extraField->getCreateDateTime()
|
$extraField->getCreateDateTime()
|
||||||
);
|
);
|
||||||
|
|
||||||
self::assertEqualsIntegerWithDelta($extraFieldFromDateTime->getModifyNtfsTime(), $extraField->getModifyNtfsTime(), 100);
|
self::assertEqualsIntegerWithDelta(
|
||||||
self::assertEqualsIntegerWithDelta($extraFieldFromDateTime->getAccessNtfsTime(), $extraField->getAccessNtfsTime(), 100);
|
$extraFieldFromDateTime->getModifyNtfsTime(),
|
||||||
self::assertEqualsIntegerWithDelta($extraFieldFromDateTime->getCreateNtfsTime(), $extraField->getCreateNtfsTime(), 100);
|
$extraField->getModifyNtfsTime(),
|
||||||
|
100
|
||||||
|
);
|
||||||
|
self::assertEqualsIntegerWithDelta(
|
||||||
|
$extraFieldFromDateTime->getAccessNtfsTime(),
|
||||||
|
$extraField->getAccessNtfsTime(),
|
||||||
|
100
|
||||||
|
);
|
||||||
|
self::assertEqualsIntegerWithDelta(
|
||||||
|
$extraFieldFromDateTime->getCreateNtfsTime(),
|
||||||
|
$extraField->getCreateNtfsTime(),
|
||||||
|
100
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
@ -105,18 +113,12 @@ final class NtfsExtraFieldTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $expected
|
|
||||||
* @param int $actual
|
|
||||||
* @param int $delta
|
|
||||||
* @param string $message
|
|
||||||
*/
|
|
||||||
private static function assertEqualsIntegerWithDelta(
|
private static function assertEqualsIntegerWithDelta(
|
||||||
$expected,
|
int $expected,
|
||||||
$actual,
|
int $actual,
|
||||||
$delta,
|
int $delta,
|
||||||
$message = ''
|
string $message = ''
|
||||||
) {
|
): void {
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
self::roundInt($expected, $delta),
|
self::roundInt($expected, $delta),
|
||||||
self::roundInt($actual, $delta),
|
self::roundInt($actual, $delta),
|
||||||
@ -124,13 +126,7 @@ final class NtfsExtraFieldTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static function roundInt(int $number, int $delta): int
|
||||||
* @param int $number
|
|
||||||
* @param int $delta
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
private static function roundInt($number, $delta)
|
|
||||||
{
|
{
|
||||||
return (int) (floor($number / $delta) * $delta);
|
return (int) (floor($number / $delta) * $delta);
|
||||||
}
|
}
|
||||||
@ -138,27 +134,19 @@ final class NtfsExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int $mtimeNtfs
|
|
||||||
* @param int $atimeNtfs
|
|
||||||
* @param int $ctimeNtfs
|
|
||||||
* @param float $mtimeTimestamp
|
|
||||||
* @param float $atimeTimestamp
|
|
||||||
* @param float $ctimeTimestamp
|
|
||||||
*
|
|
||||||
* @noinspection PhpTooManyParametersInspection
|
* @noinspection PhpTooManyParametersInspection
|
||||||
* @noinspection PhpUnitDeprecationsInspection
|
|
||||||
*/
|
*/
|
||||||
public function testConverter(
|
public function testConverter(
|
||||||
$mtimeNtfs,
|
int $mtimeNtfs,
|
||||||
$atimeNtfs,
|
int $atimeNtfs,
|
||||||
$ctimeNtfs,
|
int $ctimeNtfs,
|
||||||
$mtimeTimestamp,
|
float $mtimeTimestamp,
|
||||||
$atimeTimestamp,
|
float $atimeTimestamp,
|
||||||
$ctimeTimestamp
|
float $ctimeTimestamp
|
||||||
) {
|
): void {
|
||||||
self::assertEquals(NtfsExtraField::ntfsTimeToTimestamp($mtimeNtfs), $mtimeTimestamp, '', 0.00001);
|
self::assertEqualsWithDelta(NtfsExtraField::ntfsTimeToTimestamp($mtimeNtfs), $mtimeTimestamp, 0.00001);
|
||||||
self::assertEquals(NtfsExtraField::ntfsTimeToTimestamp($atimeNtfs), $atimeTimestamp, '', 0.00001);
|
self::assertEqualsWithDelta(NtfsExtraField::ntfsTimeToTimestamp($atimeNtfs), $atimeTimestamp, 0.00001);
|
||||||
self::assertEquals(NtfsExtraField::ntfsTimeToTimestamp($ctimeNtfs), $ctimeTimestamp, '', 0.00001);
|
self::assertEqualsWithDelta(NtfsExtraField::ntfsTimeToTimestamp($ctimeNtfs), $ctimeTimestamp, 0.00001);
|
||||||
|
|
||||||
self::assertEqualsIntegerWithDelta(NtfsExtraField::timestampToNtfsTime($mtimeTimestamp), $mtimeNtfs, 10);
|
self::assertEqualsIntegerWithDelta(NtfsExtraField::timestampToNtfsTime($mtimeTimestamp), $mtimeNtfs, 10);
|
||||||
self::assertEqualsIntegerWithDelta(NtfsExtraField::timestampToNtfsTime($atimeTimestamp), $atimeNtfs, 10);
|
self::assertEqualsIntegerWithDelta(NtfsExtraField::timestampToNtfsTime($atimeTimestamp), $atimeNtfs, 10);
|
||||||
@ -168,7 +156,7 @@ final class NtfsExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function testSetter()
|
public function testSetter(): void
|
||||||
{
|
{
|
||||||
$timeZone = new \DateTimeZone('UTC');
|
$timeZone = new \DateTimeZone('UTC');
|
||||||
$initDateTime = new \DateTimeImmutable('-1 min', $timeZone);
|
$initDateTime = new \DateTimeImmutable('-1 min', $timeZone);
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -17,25 +26,23 @@ final class OldUnixExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int|null $accessTime
|
|
||||||
* @param int|null $modifyTime
|
|
||||||
* @param int|null $uid
|
|
||||||
* @param int|null $gid
|
|
||||||
* @param string $localBinaryData
|
|
||||||
* @param string $cdBinaryData
|
|
||||||
*
|
|
||||||
* @noinspection PhpTooManyParametersInspection
|
* @noinspection PhpTooManyParametersInspection
|
||||||
*
|
*
|
||||||
|
* @param ?int $accessTime
|
||||||
|
* @param ?int $modifyTime
|
||||||
|
* @param ?int $uid
|
||||||
|
* @param ?int $gid
|
||||||
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function testExtraField(
|
public function testExtraField(
|
||||||
$accessTime,
|
?int $accessTime,
|
||||||
$modifyTime,
|
?int $modifyTime,
|
||||||
$uid,
|
?int $uid,
|
||||||
$gid,
|
?int $gid,
|
||||||
$localBinaryData,
|
string $localBinaryData,
|
||||||
$cdBinaryData
|
string $cdBinaryData
|
||||||
) {
|
): void {
|
||||||
$extraField = new OldUnixExtraField($accessTime, $modifyTime, $uid, $gid);
|
$extraField = new OldUnixExtraField($accessTime, $modifyTime, $uid, $gid);
|
||||||
self::assertSame($extraField->getHeaderId(), OldUnixExtraField::HEADER_ID);
|
self::assertSame($extraField->getHeaderId(), OldUnixExtraField::HEADER_ID);
|
||||||
|
|
||||||
@ -89,10 +96,7 @@ final class OldUnixExtraFieldTest extends TestCase
|
|||||||
self::assertSame($extraField->packCentralDirData(), $cdBinaryData);
|
self::assertSame($extraField->packCentralDirData(), $cdBinaryData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
@ -130,7 +134,7 @@ final class OldUnixExtraFieldTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetter()
|
public function testSetter(): void
|
||||||
{
|
{
|
||||||
$extraField = new OldUnixExtraField(null, null, null, null);
|
$extraField = new OldUnixExtraField(null, null, null, null);
|
||||||
|
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Model\Extra\Fields\UnicodeCommentExtraField;
|
use PhpZip\Model\Extra\Fields\UnicodeCommentExtraField;
|
||||||
@ -19,10 +28,7 @@ final class UnicodeCommentExtraFieldTest extends AbstractUnicodeExtraFieldTest
|
|||||||
return UnicodeCommentExtraField::class;
|
return UnicodeCommentExtraField::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PhpZip\Model\Extra\Fields\UnicodePathExtraField;
|
use PhpZip\Model\Extra\Fields\UnicodePathExtraField;
|
||||||
@ -21,10 +30,7 @@ final class UnicodePathExtraFieldTest extends AbstractUnicodeExtraFieldTest
|
|||||||
return UnicodePathExtraField::class;
|
return UnicodePathExtraField::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -15,7 +24,7 @@ use PhpZip\Model\Extra\Fields\UnrecognizedExtraField;
|
|||||||
*/
|
*/
|
||||||
final class UnrecognizedExtraFieldTest extends TestCase
|
final class UnrecognizedExtraFieldTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testExtraField()
|
public function testExtraField(): void
|
||||||
{
|
{
|
||||||
$headerId = 0xF00D;
|
$headerId = 0xF00D;
|
||||||
$binaryData = "\x01\x02\x03\x04\x05";
|
$binaryData = "\x01\x02\x03\x04\x05";
|
||||||
@ -35,22 +44,18 @@ final class UnrecognizedExtraFieldTest extends TestCase
|
|||||||
self::assertSame($unrecognizedExtraField->packCentralDirData(), $newBinaryData);
|
self::assertSame($unrecognizedExtraField->packCentralDirData(), $newBinaryData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUnpackLocalData()
|
public function testUnpackLocalData(): void
|
||||||
{
|
{
|
||||||
$this->expectException(
|
$this->expectException(RuntimeException::class);
|
||||||
RuntimeException::class,
|
$this->expectExceptionMessage('Unsupport parse');
|
||||||
'Unsupport parse'
|
|
||||||
);
|
|
||||||
|
|
||||||
UnrecognizedExtraField::unpackLocalFileData("\x01\x02");
|
UnrecognizedExtraField::unpackLocalFileData("\x01\x02");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUnpackCentralDirData()
|
public function testUnpackCentralDirData(): void
|
||||||
{
|
{
|
||||||
$this->expectException(
|
$this->expectException(RuntimeException::class);
|
||||||
RuntimeException::class,
|
$this->expectExceptionMessage('Unsupport parse');
|
||||||
'Unsupport parse'
|
|
||||||
);
|
|
||||||
|
|
||||||
UnrecognizedExtraField::unpackCentralDirData("\x01\x02");
|
UnrecognizedExtraField::unpackCentralDirData("\x01\x02");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -20,22 +29,16 @@ final class WinZipAesExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int $vendorVersion
|
|
||||||
* @param int $keyStrength
|
|
||||||
* @param int $compressionMethod
|
|
||||||
* @param int $saltSize
|
|
||||||
* @param string $binaryData
|
|
||||||
*
|
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*/
|
*/
|
||||||
public function testExtraField(
|
public function testExtraField(
|
||||||
$vendorVersion,
|
int $vendorVersion,
|
||||||
$keyStrength,
|
int $keyStrength,
|
||||||
$compressionMethod,
|
int $compressionMethod,
|
||||||
$saltSize,
|
int $saltSize,
|
||||||
$binaryData
|
string $binaryData
|
||||||
) {
|
): void {
|
||||||
$extraField = new WinZipAesExtraField($vendorVersion, $keyStrength, $compressionMethod);
|
$extraField = new WinZipAesExtraField($vendorVersion, $keyStrength, $compressionMethod);
|
||||||
self::assertSame($extraField->getHeaderId(), WinZipAesExtraField::HEADER_ID);
|
self::assertSame($extraField->getHeaderId(), WinZipAesExtraField::HEADER_ID);
|
||||||
self::assertSame($extraField->getVendorVersion(), $vendorVersion);
|
self::assertSame($extraField->getVendorVersion(), $vendorVersion);
|
||||||
@ -50,10 +53,7 @@ final class WinZipAesExtraFieldTest extends TestCase
|
|||||||
self::assertEquals(WinZipAesExtraField::unpackCentralDirData($binaryData), $extraField);
|
self::assertEquals(WinZipAesExtraField::unpackCentralDirData($binaryData), $extraField);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
@ -104,7 +104,7 @@ final class WinZipAesExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*/
|
*/
|
||||||
public function testSetter()
|
public function testSetter(): void
|
||||||
{
|
{
|
||||||
$extraField = new WinZipAesExtraField(
|
$extraField = new WinZipAesExtraField(
|
||||||
WinZipAesExtraField::VERSION_AE1,
|
WinZipAesExtraField::VERSION_AE1,
|
||||||
@ -155,9 +155,10 @@ final class WinZipAesExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*/
|
*/
|
||||||
public function testConstructUnsupportVendorVersion()
|
public function testConstructUnsupportVendorVersion(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class, 'Unsupport WinZip AES vendor version: 3');
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('Unsupport WinZip AES vendor version: 3');
|
||||||
|
|
||||||
new WinZipAesExtraField(
|
new WinZipAesExtraField(
|
||||||
3,
|
3,
|
||||||
@ -166,12 +167,10 @@ final class WinZipAesExtraFieldTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function testSetterUnsupportVendorVersion(): void
|
||||||
* @throws ZipUnsupportMethodException
|
|
||||||
*/
|
|
||||||
public function testSetterUnsupportVendorVersion()
|
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class, 'Unsupport WinZip AES vendor version: 3');
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('Unsupport WinZip AES vendor version: 3');
|
||||||
|
|
||||||
$extraField = new WinZipAesExtraField(
|
$extraField = new WinZipAesExtraField(
|
||||||
WinZipAesExtraField::VERSION_AE1,
|
WinZipAesExtraField::VERSION_AE1,
|
||||||
@ -181,12 +180,10 @@ final class WinZipAesExtraFieldTest extends TestCase
|
|||||||
$extraField->setVendorVersion(3);
|
$extraField->setVendorVersion(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function testConstructUnsupportCompressionMethod(): void
|
||||||
* @throws ZipUnsupportMethodException
|
|
||||||
*/
|
|
||||||
public function testConstructUnsupportCompressionMethod()
|
|
||||||
{
|
{
|
||||||
$this->expectException(ZipUnsupportMethodException::class, 'Compression method 3 (Reduced compression factor 2) is not supported.');
|
$this->expectException(ZipUnsupportMethodException::class);
|
||||||
|
$this->expectExceptionMessage('Compression method 3 (Reduced compression factor 2) is not supported.');
|
||||||
|
|
||||||
new WinZipAesExtraField(
|
new WinZipAesExtraField(
|
||||||
WinZipAesExtraField::VERSION_AE1,
|
WinZipAesExtraField::VERSION_AE1,
|
||||||
@ -195,12 +192,10 @@ final class WinZipAesExtraFieldTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function testSetterUnsupportCompressionMethod(): void
|
||||||
* @throws ZipUnsupportMethodException
|
|
||||||
*/
|
|
||||||
public function testSetterUnsupportCompressionMethod()
|
|
||||||
{
|
{
|
||||||
$this->expectException(ZipUnsupportMethodException::class, 'Compression method 3 (Reduced compression factor 2) is not supported.');
|
$this->expectException(ZipUnsupportMethodException::class);
|
||||||
|
$this->expectExceptionMessage('Compression method 3 (Reduced compression factor 2) is not supported.');
|
||||||
|
|
||||||
$extraField = new WinZipAesExtraField(
|
$extraField = new WinZipAesExtraField(
|
||||||
WinZipAesExtraField::VERSION_AE1,
|
WinZipAesExtraField::VERSION_AE1,
|
||||||
@ -213,9 +208,10 @@ final class WinZipAesExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*/
|
*/
|
||||||
public function testConstructUnsupportKeyStrength()
|
public function testConstructUnsupportKeyStrength(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class, 'Key strength 16 not support value. Allow values: 1, 2, 3');
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('Key strength 16 not support value. Allow values: 1, 2, 3');
|
||||||
|
|
||||||
new WinZipAesExtraField(
|
new WinZipAesExtraField(
|
||||||
WinZipAesExtraField::VERSION_AE1,
|
WinZipAesExtraField::VERSION_AE1,
|
||||||
@ -225,11 +221,12 @@ final class WinZipAesExtraFieldTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipException
|
||||||
*/
|
*/
|
||||||
public function testSetterUnsupportKeyStrength()
|
public function testSetterUnsupportKeyStrength(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class, 'Key strength 16 not support value. Allow values: 1, 2, 3');
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('Key strength 16 not support value. Allow values: 1, 2, 3');
|
||||||
|
|
||||||
new WinZipAesExtraField(
|
new WinZipAesExtraField(
|
||||||
WinZipAesExtraField::VERSION_AE1,
|
WinZipAesExtraField::VERSION_AE1,
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Extra\Fields;
|
namespace PhpZip\Tests\Extra\Fields;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -25,25 +34,25 @@ final class Zip64ExtraFieldTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideExtraField
|
* @dataProvider provideExtraField
|
||||||
*
|
*
|
||||||
* @param int|null $uncompressedSize
|
* @noinspection PhpTooManyParametersInspection
|
||||||
* @param int|null $compressedSize
|
*
|
||||||
* @param int|null $localHeaderOffset
|
* @param ?int $uncompressedSize
|
||||||
* @param int|null $diskStart
|
* @param ?int $compressedSize
|
||||||
* @param string|null $localBinaryData
|
* @param ?int $localHeaderOffset
|
||||||
* @param string|null $cdBinaryData
|
* @param ?int $diskStart
|
||||||
|
* @param ?string $localBinaryData
|
||||||
|
* @param ?string $cdBinaryData
|
||||||
*
|
*
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
|
||||||
* @noinspection PhpTooManyParametersInspection
|
|
||||||
*/
|
*/
|
||||||
public function testExtraField(
|
public function testExtraField(
|
||||||
$uncompressedSize,
|
?int $uncompressedSize,
|
||||||
$compressedSize,
|
?int $compressedSize,
|
||||||
$localHeaderOffset,
|
?int $localHeaderOffset,
|
||||||
$diskStart,
|
?int $diskStart,
|
||||||
$localBinaryData,
|
?string $localBinaryData,
|
||||||
$cdBinaryData
|
?string $cdBinaryData
|
||||||
) {
|
): void {
|
||||||
$extraField = new Zip64ExtraField(
|
$extraField = new Zip64ExtraField(
|
||||||
$uncompressedSize,
|
$uncompressedSize,
|
||||||
$compressedSize,
|
$compressedSize,
|
||||||
@ -72,10 +81,7 @@ final class Zip64ExtraFieldTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function provideExtraField(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provideExtraField()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
@ -105,7 +111,7 @@ final class Zip64ExtraFieldTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetter()
|
public function testSetter(): void
|
||||||
{
|
{
|
||||||
$extraField = new Zip64ExtraField();
|
$extraField = new Zip64ExtraField();
|
||||||
self::assertNull($extraField->getUncompressedSize());
|
self::assertNull($extraField->getUncompressedSize());
|
||||||
|
@ -1,30 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal\CustomZip;
|
namespace PhpZip\Tests\Internal\CustomZip;
|
||||||
|
|
||||||
use PhpZip\IO\ZipWriter;
|
use PhpZip\IO\ZipWriter;
|
||||||
use PhpZip\Model\Extra\Fields\NewUnixExtraField;
|
use PhpZip\Model\Extra\Fields\NewUnixExtraField;
|
||||||
use PhpZip\Model\Extra\Fields\NtfsExtraField;
|
use PhpZip\Model\Extra\Fields\NtfsExtraField;
|
||||||
use PhpZip\Model\ZipContainer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class CustomZipWriter.
|
|
||||||
*/
|
|
||||||
class CustomZipWriter extends ZipWriter
|
class CustomZipWriter extends ZipWriter
|
||||||
{
|
{
|
||||||
/**
|
protected function beforeWrite(): void
|
||||||
* ZipWriter constructor.
|
|
||||||
*
|
|
||||||
* @param ZipContainer $container
|
|
||||||
*/
|
|
||||||
public function __construct(ZipContainer $container)
|
|
||||||
{
|
|
||||||
// dump($container);
|
|
||||||
parent::__construct($container);
|
|
||||||
// dd($this->zipContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function beforeWrite()
|
|
||||||
{
|
{
|
||||||
parent::beforeWrite();
|
parent::beforeWrite();
|
||||||
$now = new \DateTimeImmutable();
|
$now = new \DateTimeImmutable();
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal\CustomZip;
|
namespace PhpZip\Tests\Internal\CustomZip;
|
||||||
|
|
||||||
use PhpZip\IO\ZipWriter;
|
use PhpZip\IO\ZipWriter;
|
||||||
use PhpZip\ZipFile;
|
use PhpZip\ZipFile;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipFileCustomWriter.
|
|
||||||
*/
|
|
||||||
class ZipFileCustomWriter extends ZipFile
|
class ZipFileCustomWriter extends ZipFile
|
||||||
{
|
{
|
||||||
/**
|
protected function createZipWriter(): ZipWriter
|
||||||
* @return ZipWriter
|
|
||||||
*/
|
|
||||||
protected function createZipWriter()
|
|
||||||
{
|
{
|
||||||
return new CustomZipWriter($this->zipContainer);
|
return new CustomZipWriter($this->zipContainer);
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal\CustomZip;
|
namespace PhpZip\Tests\Internal\CustomZip;
|
||||||
|
|
||||||
use PhpZip\Model\Extra\Fields\NewUnixExtraField;
|
use PhpZip\Model\Extra\Fields\NewUnixExtraField;
|
||||||
use PhpZip\Model\Extra\Fields\NtfsExtraField;
|
use PhpZip\Model\Extra\Fields\NtfsExtraField;
|
||||||
use PhpZip\ZipFile;
|
use PhpZip\ZipFile;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipFileWithBeforeSave.
|
|
||||||
*/
|
|
||||||
class ZipFileWithBeforeSave extends ZipFile
|
class ZipFileWithBeforeSave extends ZipFile
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Event before save or output.
|
* Event before save or output.
|
||||||
*/
|
*/
|
||||||
protected function onBeforeSave()
|
protected function onBeforeSave(): void
|
||||||
{
|
{
|
||||||
$now = new \DateTimeImmutable();
|
$now = new \DateTimeImmutable();
|
||||||
$ntfsTimeExtra = NtfsExtraField::create($now, $now->modify('-1 day'), $now->modify('-10 day'));
|
$ntfsTimeExtra = NtfsExtraField::create($now, $now->modify('-1 day'), $now->modify('-10 day'));
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal;
|
namespace PhpZip\Tests\Internal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,26 +27,24 @@ class DummyFileSystemStream
|
|||||||
* This method is called immediately after the wrapper is
|
* This method is called immediately after the wrapper is
|
||||||
* initialized (f.e. by {@see fopen()} and {@see file_get_contents()}).
|
* initialized (f.e. by {@see fopen()} and {@see file_get_contents()}).
|
||||||
*
|
*
|
||||||
* @param string $path specifies the URL that was passed to
|
* @param string $path specifies the URL that was passed to
|
||||||
* the original function
|
* the original function
|
||||||
* @param string $mode the mode used to open the file, as detailed
|
* @param string $mode the mode used to open the file, as detailed
|
||||||
* for {@see fopen()}
|
* for {@see fopen()}
|
||||||
* @param int $options Holds additional flags set by the streams
|
* @param int $options Holds additional flags set by the streams
|
||||||
* API. It can hold one or more of the
|
* API. It can hold one or more of the
|
||||||
* following values OR'd together.
|
* following values OR'd together.
|
||||||
* @param string $opened_path if the path is opened successfully, and
|
* @param string|null $opened_path if the path is opened successfully, and
|
||||||
* STREAM_USE_PATH is set in options,
|
* STREAM_USE_PATH is set in options,
|
||||||
* opened_path should be set to the
|
* opened_path should be set to the
|
||||||
* full path of the file/resource that
|
* full path of the file/resource that
|
||||||
* was actually opened
|
* was actually opened
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-open
|
* @see https://www.php.net/streamwrapper.stream-open
|
||||||
*
|
*
|
||||||
* @noinspection PhpUsageOfSilenceOperatorInspection
|
* @noinspection PhpUsageOfSilenceOperatorInspection
|
||||||
*/
|
*/
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool
|
||||||
{
|
{
|
||||||
$parsedUrl = parse_url($path);
|
$parsedUrl = parse_url($path);
|
||||||
$uri = substr($parsedUrl['path'], 1);
|
$uri = substr($parsedUrl['path'], 1);
|
||||||
@ -64,7 +71,7 @@ class DummyFileSystemStream
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-read
|
* @see https://www.php.net/streamwrapper.stream-read
|
||||||
*/
|
*/
|
||||||
public function stream_read($count)
|
public function stream_read(int $count)
|
||||||
{
|
{
|
||||||
return fread($this->fp, $count);
|
return fread($this->fp, $count);
|
||||||
}
|
}
|
||||||
@ -86,7 +93,7 @@ class DummyFileSystemStream
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-seek
|
* @see https://www.php.net/streamwrapper.stream-seek
|
||||||
*/
|
*/
|
||||||
public function stream_seek($offset, $whence = \SEEK_SET)
|
public function stream_seek(int $offset, int $whence = \SEEK_SET): bool
|
||||||
{
|
{
|
||||||
return fseek($this->fp, $offset, $whence) === 0;
|
return fseek($this->fp, $offset, $whence) === 0;
|
||||||
}
|
}
|
||||||
@ -101,7 +108,7 @@ class DummyFileSystemStream
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-tell
|
* @see https://www.php.net/streamwrapper.stream-tell
|
||||||
*/
|
*/
|
||||||
public function stream_tell()
|
public function stream_tell(): int
|
||||||
{
|
{
|
||||||
$pos = ftell($this->fp);
|
$pos = ftell($this->fp);
|
||||||
|
|
||||||
@ -123,7 +130,7 @@ class DummyFileSystemStream
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-eof
|
* @see https://www.php.net/streamwrapper.stream-eof
|
||||||
*/
|
*/
|
||||||
public function stream_eof()
|
public function stream_eof(): bool
|
||||||
{
|
{
|
||||||
return feof($this->fp);
|
return feof($this->fp);
|
||||||
}
|
}
|
||||||
@ -133,13 +140,11 @@ class DummyFileSystemStream
|
|||||||
*
|
*
|
||||||
* This method is called in response to {@see fstat()}.
|
* This method is called in response to {@see fstat()}.
|
||||||
*
|
*
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @see https://www.php.net/streamwrapper.stream-stat
|
* @see https://www.php.net/streamwrapper.stream-stat
|
||||||
* @see https://www.php.net/stat
|
* @see https://www.php.net/stat
|
||||||
* @see https://www.php.net/fstat
|
* @see https://www.php.net/fstat
|
||||||
*/
|
*/
|
||||||
public function stream_stat()
|
public function stream_stat(): array
|
||||||
{
|
{
|
||||||
return fstat($this->fp);
|
return fstat($this->fp);
|
||||||
}
|
}
|
||||||
@ -159,7 +164,7 @@ class DummyFileSystemStream
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-flush
|
* @see https://www.php.net/streamwrapper.stream-flush
|
||||||
*/
|
*/
|
||||||
public function stream_flush()
|
public function stream_flush(): bool
|
||||||
{
|
{
|
||||||
return fflush($this->fp);
|
return fflush($this->fp);
|
||||||
}
|
}
|
||||||
@ -175,9 +180,9 @@ class DummyFileSystemStream
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-truncate
|
* @see https://www.php.net/streamwrapper.stream-truncate
|
||||||
*/
|
*/
|
||||||
public function stream_truncate($new_size)
|
public function stream_truncate(int $new_size): bool
|
||||||
{
|
{
|
||||||
return ftruncate($this->fp, (int) $new_size);
|
return ftruncate($this->fp, $new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,7 +199,7 @@ class DummyFileSystemStream
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-write
|
* @see https://www.php.net/streamwrapper.stream-write
|
||||||
*/
|
*/
|
||||||
public function stream_write($data)
|
public function stream_write(string $data): int
|
||||||
{
|
{
|
||||||
$bytes = fwrite($this->fp, $data);
|
$bytes = fwrite($this->fp, $data);
|
||||||
|
|
||||||
@ -209,7 +214,7 @@ class DummyFileSystemStream
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/streamwrapper.stream-close
|
* @see https://www.php.net/streamwrapper.stream-close
|
||||||
*/
|
*/
|
||||||
public function stream_close()
|
public function stream_close(): void
|
||||||
{
|
{
|
||||||
fclose($this->fp);
|
fclose($this->fp);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal\Epub;
|
namespace PhpZip\Tests\Internal\Epub;
|
||||||
|
|
||||||
@ -21,39 +28,25 @@ use PhpZip\ZipFile;
|
|||||||
*/
|
*/
|
||||||
class EpubFile extends ZipFile
|
class EpubFile extends ZipFile
|
||||||
{
|
{
|
||||||
/**
|
protected function createZipWriter(): ZipWriter
|
||||||
* @return ZipWriter
|
|
||||||
*/
|
|
||||||
protected function createZipWriter()
|
|
||||||
{
|
{
|
||||||
return new EpubWriter($this->zipContainer);
|
return new EpubWriter($this->zipContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $inputStream
|
* @param resource $inputStream
|
||||||
* @param array $options
|
|
||||||
*
|
|
||||||
* @return ZipReader
|
|
||||||
*/
|
*/
|
||||||
protected function createZipReader($inputStream, array $options = [])
|
protected function createZipReader($inputStream, array $options = []): ZipReader
|
||||||
{
|
{
|
||||||
return new EpubReader($inputStream, $options);
|
return new EpubReader($inputStream, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function createZipContainer(?ImmutableZipContainer $sourceContainer = null): ZipContainer
|
||||||
* @param ImmutableZipContainer|null $sourceContainer
|
|
||||||
*
|
|
||||||
* @return ZipContainer
|
|
||||||
*/
|
|
||||||
protected function createZipContainer(ImmutableZipContainer $sourceContainer = null)
|
|
||||||
{
|
{
|
||||||
return new EpubZipContainer($sourceContainer);
|
return new EpubZipContainer($sourceContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addZipEntry(ZipEntry $zipEntry): void
|
||||||
* @param ZipEntry $zipEntry
|
|
||||||
*/
|
|
||||||
protected function addZipEntry(ZipEntry $zipEntry)
|
|
||||||
{
|
{
|
||||||
$zipEntry->setCreatedOS(ZipPlatform::OS_DOS);
|
$zipEntry->setCreatedOS(ZipPlatform::OS_DOS);
|
||||||
$zipEntry->setExtractedOS(ZipPlatform::OS_UNIX);
|
$zipEntry->setExtractedOS(ZipPlatform::OS_UNIX);
|
||||||
@ -62,25 +55,25 @@ class EpubFile extends ZipFile
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws ZipEntryNotFoundException
|
* @throws ZipEntryNotFoundException
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getMimeType()
|
public function getMimeType(): string
|
||||||
{
|
{
|
||||||
return $this->zipContainer->getMimeType();
|
return $this->zipContainer->getMimeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getEpubInfo()
|
/**
|
||||||
|
* @throws ZipException
|
||||||
|
* @throws ZipEntryNotFoundException
|
||||||
|
*/
|
||||||
|
public function getEpubInfo(): EpubInfo
|
||||||
{
|
{
|
||||||
return new EpubInfo($this->getEntryContents($this->getRootFile()));
|
return new EpubInfo($this->getEntryContents($this->getRootFile()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws ZipException
|
* @throws ZipException
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getRootFile()
|
public function getRootFile(): string
|
||||||
{
|
{
|
||||||
$entryName = 'META-INF/container.xml';
|
$entryName = 'META-INF/container.xml';
|
||||||
$contents = $this->getEntryContents($entryName);
|
$contents = $this->getEntryContents($entryName);
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal\Epub;
|
namespace PhpZip\Tests\Internal\Epub;
|
||||||
|
|
||||||
@ -13,29 +20,21 @@ use PhpZip\Exception\ZipException;
|
|||||||
*/
|
*/
|
||||||
class EpubInfo
|
class EpubInfo
|
||||||
{
|
{
|
||||||
/** @var string|null */
|
private ?string $title;
|
||||||
private $title;
|
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $creator;
|
||||||
private $creator;
|
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $language;
|
||||||
private $language;
|
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $publisher;
|
||||||
private $publisher;
|
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $description;
|
||||||
private $description;
|
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $rights;
|
||||||
private $rights;
|
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $date;
|
||||||
private $date;
|
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $subject;
|
||||||
private $subject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EpubInfo constructor.
|
* EpubInfo constructor.
|
||||||
@ -76,74 +75,47 @@ class EpubInfo
|
|||||||
$this->subject = empty($subject) ? null : $subject;
|
$this->subject = empty($subject) ? null : $subject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getTitle(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getTitle()
|
|
||||||
{
|
{
|
||||||
return $this->title;
|
return $this->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCreator(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getCreator()
|
|
||||||
{
|
{
|
||||||
return $this->creator;
|
return $this->creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getLanguage(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getLanguage()
|
|
||||||
{
|
{
|
||||||
return $this->language;
|
return $this->language;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getPublisher(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getPublisher()
|
|
||||||
{
|
{
|
||||||
return $this->publisher;
|
return $this->publisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getDescription(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getDescription()
|
|
||||||
{
|
{
|
||||||
return $this->description;
|
return $this->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getRights(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getRights()
|
|
||||||
{
|
{
|
||||||
return $this->rights;
|
return $this->rights;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getDate(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getDate()
|
|
||||||
{
|
{
|
||||||
return $this->date;
|
return $this->date;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getSubject(): ?string
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getSubject()
|
|
||||||
{
|
{
|
||||||
return $this->subject;
|
return $this->subject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function toArray(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function toArray()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'title' => $this->title,
|
'title' => $this->title,
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal\Epub;
|
namespace PhpZip\Tests\Internal\Epub;
|
||||||
|
|
||||||
use PhpZip\IO\ZipReader;
|
use PhpZip\IO\ZipReader;
|
||||||
@ -10,11 +19,9 @@ use PhpZip\IO\ZipReader;
|
|||||||
class EpubReader extends ZipReader
|
class EpubReader extends ZipReader
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @see https://github.com/w3c/epubcheck/issues/334
|
* @see https://github.com/w3c/epubcheck/issues/334
|
||||||
*/
|
*/
|
||||||
protected function isZip64Support()
|
protected function isZip64Support(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal\Epub;
|
namespace PhpZip\Tests\Internal\Epub;
|
||||||
|
|
||||||
use PhpZip\Constants\ZipCompressionMethod;
|
use PhpZip\Constants\ZipCompressionMethod;
|
||||||
@ -19,7 +28,7 @@ class EpubWriter extends ZipWriter
|
|||||||
/**
|
/**
|
||||||
* @throws ZipUnsupportMethodException
|
* @throws ZipUnsupportMethodException
|
||||||
*/
|
*/
|
||||||
protected function beforeWrite()
|
protected function beforeWrite(): void
|
||||||
{
|
{
|
||||||
parent::beforeWrite();
|
parent::beforeWrite();
|
||||||
|
|
||||||
@ -35,7 +44,7 @@ class EpubWriter extends ZipWriter
|
|||||||
$this->sortEntries();
|
$this->sortEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sortEntries()
|
private function sortEntries(): void
|
||||||
{
|
{
|
||||||
$this->zipContainer->sortByEntry(
|
$this->zipContainer->sortByEntry(
|
||||||
static function (ZipEntry $a, ZipEntry $b) {
|
static function (ZipEntry $a, ZipEntry $b) {
|
||||||
|
@ -1,21 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal\Epub;
|
namespace PhpZip\Tests\Internal\Epub;
|
||||||
|
|
||||||
use PhpZip\Exception\ZipEntryNotFoundException;
|
use PhpZip\Exception\ZipEntryNotFoundException;
|
||||||
use PhpZip\Model\ZipContainer;
|
use PhpZip\Model\ZipContainer;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class EpubZipContainer.
|
|
||||||
*/
|
|
||||||
class EpubZipContainer extends ZipContainer
|
class EpubZipContainer extends ZipContainer
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @throws ZipEntryNotFoundException
|
* @throws ZipEntryNotFoundException
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getMimeType()
|
public function getMimeType(): string
|
||||||
{
|
{
|
||||||
return $this->getEntry('mimetype')->getData()->getDataAsString();
|
return $this->getEntry('mimetype')->getData()->getDataAsString();
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the nelexa/zip package.
|
||||||
|
* (c) Ne-Lexa <https://github.com/Ne-Lexa/php-zip>
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace PhpZip\Tests\Internal;
|
namespace PhpZip\Tests\Internal;
|
||||||
|
|
||||||
use PhpZip\ZipFile;
|
use PhpZip\ZipFile;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ZipFileExtended.
|
|
||||||
*/
|
|
||||||
class ZipFileExtended extends ZipFile
|
class ZipFileExtended extends ZipFile
|
||||||
{
|
{
|
||||||
protected function onBeforeSave()
|
protected function onBeforeSave(): void
|
||||||
{
|
{
|
||||||
parent::onBeforeSave();
|
parent::onBeforeSave();
|
||||||
$this->deleteFromRegex('~^META\-INF/~i');
|
$this->deleteFromRegex('~^META\-INF/~i');
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user