diff --git a/.docs/README.md b/.docs/README.md index 89c192d..39029fc 100644 --- a/.docs/README.md +++ b/.docs/README.md @@ -8,7 +8,7 @@ jQuery-FileUpload is component which extends UploadControl in Nette form using [ ``` extensions: - fileUpload: Zet\FileUpload\FileUploadExtension + fileUpload: Contributte\FileUpload\FileUploadExtension ``` ### Configuration of DI extension options @@ -17,7 +17,7 @@ extensions: fileUpload: maxFiles: 10 maxFileSize: 2M - fileFilter: Zet\FileUpload\Filter\ImageFilter + fileFilter: Contributte\FileUpload\Filter\ImageFilter uploadModel: App\Model\MyUploadModel uiMode: # full nebo minimal ``` @@ -31,8 +31,8 @@ This component needs for its precise functionality some third party scripts and ### Loading CSS and JS in layout.latte ``` -{\Zet\FileUpload\FileUploadControl::getHead($basePath)} -{\Zet\FileUpload\FileUploadControl::getScripts($basePath)} +{\Contributte\FileUpload\FileUploadControl::getHead($basePath)} +{\Contributte\FileUpload\FileUploadControl::getScripts($basePath)} ``` ## Upload model @@ -41,15 +41,15 @@ Component can use custom processing file upload through `UploadModel` which does ### Interface -Custom `UploadModel` must implement interface **\Zet\FileUpload\Model\IUploadModel**. +Custom `UploadModel` must implement interface **\Contributte\FileUpload\Model\IUploadModel**. ```php -namespace Zet\FileUpload\Model; +namespace Contributte\FileUpload\Model; /** * Interface IUploadController * @author Zechy - * @package Zet\FileUpload\Model + * @package Contributte\FileUpload\Model */ interface IUploadModel { @@ -97,7 +97,7 @@ fileUpload: Uploaded files can be filtered using their mimetype or suffix, so it is possible to limit the upload of files to images only. There are filter classes for this purpose. -All filters are instances of the abstract class **\Zet\FileUpload\Filter\BaseFilter**, which implements the basic methodology for determining the correctness of a file using a mimetype, or according to the file extension. This basic filter implements the **\Zet\FileUpload\Filter\IMimeTypeFilter** interface. +All filters are instances of the abstract class **\Contributte\FileUpload\Filter\BaseFilter**, which implements the basic methodology for determining the correctness of a file using a mimetype, or according to the file extension. This basic filter implements the **\Contributte\FileUpload\Filter\IMimeTypeFilter** interface. ## Basic filters @@ -110,13 +110,13 @@ FileUploadControl::FILTER_AUDIO; // Allows uploading of files mp3, ogg, aiff onl FileUploadControl::setFileFilter("Constant or custom class"); // Sets the class to determine if the file can be uploaded ``` -The setFileFilter method accepts as a parameter a string in which the class name is written, eg **Zet\FileUpload\Filter\ImageFilter**. +The setFileFilter method accepts as a parameter a string in which the class name is written, eg **Contributte\FileUpload\Filter\ImageFilter**. ## Custom filter ### Using BaseFilter -To use the basic methodology for determining the correctness of a file type, you can create your own class, which will be a child of **\Zet\FileUpload\Filter\BaseFilter**. +To use the basic methodology for determining the correctness of a file type, you can create your own class, which will be a child of **\Contributte\FileUpload\Filter\BaseFilter**. The class created in this way must have its own implementation of the `getMimeTypes()` method, which returns an array of file mimetypes and their extensions, e.g.: @@ -138,14 +138,14 @@ protected function getMimeTypes() { ### Own filtering methodology -If you want to create your own way of determining the file type, you can create your own class, but it must implement the **\Zet\FileUpload\Filter\IMimeTypeFilter** interface. +If you want to create your own way of determining the file type, you can create your own class, but it must implement the **\Contributte\FileUpload\Filter\IMimeTypeFilter** interface. ```php /** * Interface IMimeTypeFilters * Interface for checking the mimetype of file * @author Zechy - * @package Zet\FileUpload\Filter + * @package Contributte\FileUpload\Filter */ interface IMimeTypeFilter { @@ -213,7 +213,7 @@ Uploaded files can be obtained by processing the form from the field **$values** FileUploadControl::setMaxFiles(25); // Setter for maximum of files. FileUploadControl::setMaxFileSize("2M"); // Setter for maximum of file size. FileUploadControl::setUploadModel('\Model\File\UploadModel'); // Setter for custom upload model. -FileUploadControl::setFileFilter('\Zet\FileUpload\Filter\ImageFilter'); // Setter for restrictions on uploading files to specified types. You can string a custom class or use the FileUploadControl constants. +FileUploadControl::setFileFilter('\Contributte\FileUpload\Filter\ImageFilter'); // Setter for restrictions on uploading files to specified types. You can string a custom class or use the FileUploadControl constants. FileUploadControl::setUiTemplate(FileUploadControl::UI_FULL, __DIR__ . "/path/to/my/template.latte"); FileUploadControl::setParams(["productId" => 10]); // Setter for custom values for the uploaded file ``` @@ -305,7 +305,7 @@ Progress bars can be HTML5 tags <progress> or <div>. #### BaseRenderer -The custom renderer must inherit from the **\Zet\FileUpload\Template\Renderer\BaseRenderer** class. This class has the attribute **$elements** in which are stored the Html Prototypes of all components in the field on indexes. +The custom renderer must inherit from the **\Contributte\FileUpload\Template\Renderer\BaseRenderer** class. This class has the attribute **$elements** in which are stored the Html Prototypes of all components in the field on indexes. BaseRenderer contains three abstract methods that need to be implemented. @@ -314,7 +314,7 @@ BaseRenderer contains three abstract methods that need to be implemented. * Class BaseRenderer * * @author Zechy - * @package Zet\FileUpload\Template\Renderer + * @package Contributte\FileUpload\Template\Renderer */ abstract class BaseRenderer extends Object implements IUploadRenderer { @@ -351,7 +351,7 @@ Since version 2.0.0-beta2, default files can be entered into the uploader. When ### DefaultFile -Use the container **\Zet\FileUpload\Model\DefaultFile** to add a default file. +Use the container **\Contributte\FileUpload\Model\DefaultFile** to add a default file. ```php class DefaultFile extends Object { diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 875a106..bb0c95c 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -9,6 +9,7 @@ on: - "*" schedule: - cron: "0 8 * * 1" # At 08:00 on Monday + workflow_dispatch: env: extensions: "json" @@ -23,13 +24,13 @@ jobs: strategy: matrix: - php-version: [ "7.4" ] + php-version: [ "8.2" ] operating-system: [ "ubuntu-latest" ] fail-fast: false steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Setup PHP cache environment" id: "extcache" @@ -40,7 +41,7 @@ jobs: key: "${{ env.cache-version }}" - name: "Cache PHP extensions" - uses: "actions/cache@v2" + uses: "actions/cache@v4" with: path: "${{ steps.extcache.outputs.dir }}" key: "${{ steps.extcache.outputs.key }}" @@ -51,17 +52,18 @@ jobs: with: php-version: "${{ matrix.php-version }}" extensions: "${{ env.extensions }}" - tools: "composer:${{ env.composer-version }} " + tools: "composer:${{ env.composer-version }}" + coverage: "none" - name: "Setup problem matchers for PHP" run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - name: "Get Composer cache directory" id: "composercache" - run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' + run: 'echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT' - name: "Cache PHP dependencies" - uses: "actions/cache@v2" + uses: "actions/cache@v4" with: path: "${{ steps.composercache.outputs.dir }}" key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" @@ -82,13 +84,13 @@ jobs: strategy: matrix: - php-version: [ "7.4" ] + php-version: [ "8.2" ] operating-system: [ "ubuntu-latest" ] fail-fast: false steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Setup PHP cache environment" id: "extcache" @@ -99,7 +101,7 @@ jobs: key: "${{ env.cache-version }}" - name: "Cache PHP extensions" - uses: "actions/cache@v2" + uses: "actions/cache@v4" with: path: "${{ steps.extcache.outputs.dir }}" key: "${{ steps.extcache.outputs.key }}" @@ -110,17 +112,18 @@ jobs: with: php-version: "${{ matrix.php-version }}" extensions: "${{ env.extensions }}" - tools: "composer:${{ env.composer-version }} " + tools: "composer:${{ env.composer-version }}" + coverage: "none" - name: "Setup problem matchers for PHP" run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - name: "Get Composer cache directory" id: "composercache" - run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' + run: 'echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT' - name: "Cache PHP dependencies" - uses: "actions/cache@v2" + uses: "actions/cache@v4" with: path: "${{ steps.composercache.outputs.dir }}" key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" @@ -138,23 +141,18 @@ jobs: strategy: matrix: - php-version: [ "7.3", "7.4", "8.0" ] + php-version: [ "8.2", "8.3", "8.4" ] operating-system: [ "ubuntu-latest" ] composer-args: [ "" ] include: - - php-version: "7.4" + - php-version: "8.2" operating-system: "ubuntu-latest" composer-args: "--prefer-lowest" - - php-version: "8.0" - operating-system: "ubuntu-latest" - composer-args: "" fail-fast: false - continue-on-error: "${{ matrix.php-version == '8.0' }}" - steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Setup PHP cache environment" id: "extcache" @@ -165,7 +163,7 @@ jobs: key: "${{ env.cache-version }}" - name: "Cache PHP extensions" - uses: "actions/cache@v2" + uses: "actions/cache@v4" with: path: "${{ steps.extcache.outputs.dir }}" key: "${{ steps.extcache.outputs.key }}" @@ -176,17 +174,18 @@ jobs: with: php-version: "${{ matrix.php-version }}" extensions: "${{ env.extensions }}" - tools: "composer:${{ env.composer-version }} " + tools: "composer:${{ env.composer-version }}" + coverage: "none" - name: "Setup problem matchers for PHP" run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - name: "Get Composer cache directory" id: "composercache" - run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' + run: 'echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT' - name: "Cache PHP dependencies" - uses: "actions/cache@v2" + uses: "actions/cache@v4" with: path: "${{ steps.composercache.outputs.dir }}" key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" @@ -195,9 +194,6 @@ jobs: - name: "Install dependencies" run: "${{ env.composer-install }} ${{ matrix.composer-args }}" - - name: "Setup problem matchers for PHPUnit" - run: 'echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"' - - name: "Tests" run: "make tests" @@ -207,7 +203,7 @@ jobs: strategy: matrix: - php-version: [ "7.4" ] + php-version: [ "8.2" ] operating-system: [ "ubuntu-latest" ] fail-fast: false @@ -215,7 +211,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Setup PHP cache environment" id: "extcache" @@ -226,7 +222,7 @@ jobs: key: "${{ env.cache-version }}" - name: "Cache PHP extensions" - uses: "actions/cache@v2" + uses: "actions/cache@v4" with: path: "${{ steps.extcache.outputs.dir }}" key: "${{ steps.extcache.outputs.key }}" @@ -237,17 +233,18 @@ jobs: with: php-version: "${{ matrix.php-version }}" extensions: "${{ env.extensions }}" - tools: "composer:${{ env.composer-version }} " + tools: "composer:${{ env.composer-version }}" + coverage: "pcov" - name: "Setup problem matchers for PHP" run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - name: "Get Composer cache directory" id: "composercache" - run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' + run: 'echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT' - name: "Cache PHP dependencies" - uses: "actions/cache@v2" + uses: "actions/cache@v4" with: path: "${{ steps.composercache.outputs.dir }}" key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" @@ -257,7 +254,7 @@ jobs: run: "${{ env.composer-install }}" - name: "Tests" - run: "make coverage-clover" + run: "make coverage" - name: "Coveralls.io" env: diff --git a/.gitignore b/.gitignore index 35fa452..c83f86d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,10 @@ # IDE -.idea - +/.idea # Composer /vendor /composer.lock # Tests -/temp /coverage.xml +/coverage.html diff --git a/Makefile b/Makefile index 67efeb3..f407abf 100644 --- a/Makefile +++ b/Makefile @@ -1,22 +1,29 @@ -.PHONY: install qa cs csf phpstan tests coverage-clover coverage-html +.PHONY: install qa cs csf phpstan tests coverage install: composer update +qa: phpstan cs + cs: - vendor/bin/codesniffer src tests +ifdef GITHUB_ACTION + vendor/bin/phpcs src tests --standard=ruleset.xml --report=checkstyle +else + vendor/bin/phpcs src tests --standard=ruleset.xml +endif csf: - vendor/bin/codefixer src tests + vendor/bin/phpcbf src tests --standard=ruleset.xml phpstan: - vendor/bin/phpstan analyse -l 8 -c phpstan.neon src + vendor/bin/phpstan analyse -c phpstan.neon tests: vendor/bin/tester -s -p php --colors 1 -C tests/cases -coverage-clover: +coverage: +ifdef GITHUB_ACTION vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage ./coverage.xml --coverage-src ./src tests/cases - -coverage-html: +else vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage ./coverage.html --coverage-src ./src tests/cases +endif diff --git a/composer.json b/composer.json index 8449fd6..c0f8697 100644 --- a/composer.json +++ b/composer.json @@ -11,19 +11,19 @@ } ], "require": { - "php": ">=7.2.0", + "php": ">=8.2", "ext-json": "*", - "latte/latte": "^2.10", - "nette/application": "^3.1", - "nette/caching": "^3.1", - "nette/di": "^3.0", - "nette/forms": "^3.1", - "nette/http": "^3.1", - "nette/utils": "^3.2" + "latte/latte": "^3.0", + "nette/application": "^3.2", + "nette/caching": "^3.3", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/http": "^3.3", + "nette/utils": "^4.0" }, "require-dev": { - "ninjify/nunjuck": "^0.4", - "ninjify/qa": "^0.12", + "contributte/qa": "^0.3", + "contributte/tester": "^0.3", "phpstan/phpstan": "^1.0", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-nette": "^1.0", @@ -31,14 +31,14 @@ "tracy/tracy": "^2.6" }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Contributte\\FileUpload\\": "src/" + } }, "autoload-dev": { - "classmap": [ - "tests/" - ] + "psr-4": { + "Tests\\": "tests/" + } }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/phpstan.neon b/phpstan.neon index 314862a..936b228 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,16 +1,25 @@ +includes: + - vendor/phpstan/phpstan-deprecation-rules/rules.neon + - vendor/phpstan/phpstan-nette/extension.neon + - vendor/phpstan/phpstan-nette/rules.neon + - vendor/phpstan/phpstan-strict-rules/rules.neon + parameters: - level: max + level: 8 + phpVersion: 80200 + + paths: + - src + + scanDirectories: + - vendor/nette + - vendor/tracy + ignoreErrors: - message: '#Construct empty\(\) is not allowed\. Use more strict comparison\.#' path: src/Model/UploadController.php - - message: '#Property Zet\\FileUpload\\Model\\UploadController::\$renderer \(Zet\\FileUpload\\Template\\Renderer\\BaseRenderer\) does not accept object\.#' + identifier: assign.propertyType path: src/Model/UploadController.php -includes: - - vendor/phpstan/phpstan-deprecation-rules/rules.neon - - vendor/phpstan/phpstan-nette/extension.neon - - vendor/phpstan/phpstan-nette/rules.neon - - vendor/phpstan/phpstan-strict-rules/rules.neon - diff --git a/ruleset.xml b/ruleset.xml index 64ec1df..a630aa5 100644 --- a/ruleset.xml +++ b/ruleset.xml @@ -1,24 +1,18 @@ - - - + - - + - - - diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 63f2e18..231bef9 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -1,6 +1,6 @@ */ class InvalidFileException extends Exception { diff --git a/src/Exception/InvalidValueException.php b/src/Exception/InvalidValueException.php index 64e88ae..7a3d5b8 100644 --- a/src/Exception/InvalidValueException.php +++ b/src/Exception/InvalidValueException.php @@ -1,13 +1,11 @@ */ class InvalidValueException extends Exception { diff --git a/src/Exception/LogicalException.php b/src/Exception/LogicalException.php index 3698570..91bec58 100644 --- a/src/Exception/LogicalException.php +++ b/src/Exception/LogicalException.php @@ -1,6 +1,6 @@ */ class FileUploadControl extends UploadControl { @@ -32,66 +31,56 @@ class FileUploadControl extends UploadControl /** * Povolí nahrávat pouze obrázky png, jpeg, jpg, gif. */ - public const FILTER_IMAGES = 'Zet\FileUpload\Filter\ImageFilter'; + public const FILTER_IMAGES = 'Contributte\FileUpload\Filter\ImageFilter'; /** * Povolí nahrávat pouze dokumenty typu txt, doc, docx, xls, xlsx, ppt, pptx, pdf. */ - public const FILTER_DOCUMENTS = 'Zet\FileUpload\Filter\DocumentFilter'; + public const FILTER_DOCUMENTS = 'Contributte\FileUpload\Filter\DocumentFilter'; /** * Povolí nahrávat soubory zip, tar, rar, 7z. */ - public const FILTER_ARCHIVE = 'Zet\FileUpload\Filter\ArchiveFilter'; + public const FILTER_ARCHIVE = 'Contributte\FileUpload\Filter\ArchiveFilter'; /** * Povolí nahrávat pouze soubory mp3, ogg, aiff. */ - public const FILTER_AUDIO = 'Zet\FileUpload\Filter\AudioFilter'; + public const FILTER_AUDIO = 'Contributte\FileUpload\Filter\AudioFilter'; - /** @var Container */ - private $container; + private Container $container; - /** @var Cache */ - private $cache; + private Cache $cache; - /** @var int */ - private $maxFiles; + private int $maxFiles; - /** @var int|null */ - private $maxFileSize; + private ?int $maxFileSize = null; - /** @var string */ - private $fileSizeString; + private string $fileSizeString; - /** @var UploadController */ - private $controller; + private UploadController $controller; /** @var class-string|null */ private $uploadModel; /** * Třída pro filtrování nahrávaných souborů. - * - * @var string|null */ - private $fileFilter; + private ?string $fileFilter = null; /** * Pole vlastních definovaných parametrů. * * @var array */ - private $params = []; + private array $params = []; - /** @var string */ - private $renderer; + private string $renderer; - /** @var string */ - private $token; + private string $token; /** @var DefaultFile[] */ - private $defaultFiles = []; + private array $defaultFiles = []; /** * Seznam chybových hlášek. @@ -110,21 +99,19 @@ class FileUploadControl extends UploadControl * * @var string[] */ - private $messages = []; + private array $messages = []; /** * Automaticky překládat všechny chybové zprávy? - * - * @var bool */ - private $autoTranslate = false; + private bool $autoTranslate = false; /** * Pole vlastních hodnot pro konfiguraci uploaderu. * * @var array */ - private $uploadSettings = []; + private array $uploadSettings = []; /** * @param string $name Název inputu. @@ -134,6 +121,7 @@ class FileUploadControl extends UploadControl public function __construct(string $name, int $maxFiles, ?string $maxFileSize = null) { parent::__construct($name); + $this->maxFiles = $maxFiles; if ($maxFileSize === null) { $this->fileSizeString = ini_get('upload_max_filesize') . 'B'; @@ -154,12 +142,19 @@ public function __construct(string $name, int $maxFiles, ?string $maxFileSize = // Registration // -------------------------------------------------------------------- + /** + * Delete cache + */ + public function __destruct() + { + $this->cache->remove($this->getTokenizedCacheName($this->token)); + } + /** * @static - * @param Container $systemContainer * @param array|stdClass $configuration */ - public static function register(Container $systemContainer, $configuration): void + public static function register(Container $systemContainer, array|stdClass $configuration): void { if (is_object($configuration)) { $configuration = json_decode((string) json_encode($configuration), true); @@ -176,8 +171,8 @@ public static function register(Container $systemContainer, $configuration): voi $systemContainer, $configuration ): self { - $maxFiles = $maxFiles ?? $configuration['maxFiles']; - $maxFileSize = $maxFileSize ?? $configuration['maxFileSize']; + $maxFiles ??= $configuration['maxFiles']; + $maxFileSize ??= $configuration['maxFileSize']; /** @var FileUploadControl $component */ $component = new $class($name, $maxFiles, $maxFileSize); @@ -229,37 +224,6 @@ public static function getScripts(string $basePath): void echo ''; } - /** - * Ověření nastavených direktiv, zda nepřekročují nastavení serveru. - * - * @throws InvalidValueException - */ - private function checkSettings(): void - { - $postMaxSize = $this->parseIniSize($postMaxSizeString = (string) ini_get('post_max_size')); - $iniMaxFileSize = $this->parseIniSize($iniMaxFileSizeString = (string) ini_get('upload_max_filesize')); - - if ($this->maxFileSize > $postMaxSize) { - throw new InvalidValueException( - sprintf( - 'The setting for the maximum file size is larger than allowed by the directive `post_max_size` (%s).', - $postMaxSizeString - ) - ); - } elseif ($this->maxFileSize > $iniMaxFileSize) { - throw new InvalidValueException( - sprintf( - 'The setting for the maximum file size is larger than allowed by the directive `upload_max_filesize` (%s).', - $iniMaxFileSizeString - ) - ); - } - } - - // -------------------------------------------------------------------- - // Setters \ Getters - // -------------------------------------------------------------------- - /** * @internal */ @@ -504,11 +468,7 @@ public function setUploadSettings(array $uploadSettings): self return $this; } - /** - * @param string $name - * @param mixed $value - */ - public function addUploadSettings(string $name, $value): self + public function addUploadSettings(string $name, mixed $value): self { $this->uploadSettings[$name] = $value; @@ -556,20 +516,43 @@ public function getControl(): Html /** * Vrátí nacachované hodnoty z controlleru. * - * @return mixed|NULL + * @return array|NULL */ - public function getValue() + public function getValue(): ?array { - return $this->cache->load($this->getTokenizedCacheName($this->token)); + $value = $this->cache->load($this->getTokenizedCacheName($this->token)); + + return is_array($value) ? $value : null; } /** - * Delete cache + * Ověření nastavených direktiv, zda nepřekročují nastavení serveru. + * + * @throws InvalidValueException */ - public function __destruct() + private function checkSettings(): void { - $this->cache->remove($this->getTokenizedCacheName($this->token)); - } + $postMaxSize = $this->parseIniSize($postMaxSizeString = (string) ini_get('post_max_size')); + $iniMaxFileSize = $this->parseIniSize($iniMaxFileSizeString = (string) ini_get('upload_max_filesize')); + + if ($this->maxFileSize > $postMaxSize) { + throw new InvalidValueException( + sprintf( + 'The setting for the maximum file size is larger than allowed by the directive `post_max_size` (%s).', + $postMaxSizeString + ) + ); + } elseif ($this->maxFileSize > $iniMaxFileSize) { + throw new InvalidValueException( + sprintf( + 'The setting for the maximum file size is larger than allowed by the directive `upload_max_filesize` (%s).', + $iniMaxFileSizeString + ) + ); + } + }// -------------------------------------------------------------------- +// Setters \ Getters +// -------------------------------------------------------------------- /** * Parses ini size diff --git a/src/FileUploadExtension.php b/src/FileUploadExtension.php index 17e40c6..bf09cf3 100644 --- a/src/FileUploadExtension.php +++ b/src/FileUploadExtension.php @@ -1,7 +1,13 @@ */ final class FileUploadExtension extends CompilerExtension { /** * Výchozí konfigurační hodnoty. - * - * @return Schema */ public function getConfigSchema(): Schema { @@ -91,9 +87,9 @@ public function getConfigSchema(): Schema public function afterCompile(ClassType $class): void { - $init = $class->methods['initialize']; + $init = $class->getMethod('initialize'); - $init->addBody('\Zet\FileUpload\FileUploadControl::register($this->getService(?), ?);', [ + $init->addBody('\Contributte\FileUpload\FileUploadControl::register($this->getService(?), ?);', [ $this->getContainerBuilder()->getByType(Container::class), $this->getConfig(), ]); diff --git a/src/Filter/ArchiveFilter.php b/src/Filter/ArchiveFilter.php index 62b2103..06d1e27 100644 --- a/src/Filter/ArchiveFilter.php +++ b/src/Filter/ArchiveFilter.php @@ -1,11 +1,9 @@ */ class ArchiveFilter extends BaseFilter { diff --git a/src/Filter/AudioFilter.php b/src/Filter/AudioFilter.php index 7010208..1e2ed0b 100644 --- a/src/Filter/AudioFilter.php +++ b/src/Filter/AudioFilter.php @@ -1,11 +1,9 @@ */ class AudioFilter extends BaseFilter { diff --git a/src/Filter/BaseFilter.php b/src/Filter/BaseFilter.php index 07052df..3b0fde2 100644 --- a/src/Filter/BaseFilter.php +++ b/src/Filter/BaseFilter.php @@ -1,6 +1,6 @@ */ abstract class BaseFilter implements IMimeTypeFilter { use SmartObject; - /** - * Vrátí seznam povolených typů souborů s jejich typickou koncovkou. - * - * @example array("text/plain" => "txt") - * @return string[] - */ - abstract protected function getMimeTypes(): array; - /** * Ověří mimetype předaného souboru. * @@ -32,12 +22,10 @@ abstract protected function getMimeTypes(): array; */ public function checkType(FileUpload $file): bool { - if (Arrays::getKeyOffset($this->getMimeTypes(), (string) $file->getContentType()) !== null) { - return true; - } else { + return Arrays::getKeyOffset($this->getMimeTypes(), (string) $file->getContentType()) !== null // Pokud se nepodaří ověřit mimetype, ověříme alespoň koncovku. - return array_search($this->getExtension($file->getUntrustedName()), array_unique($this->getMimeTypes()), true) !== false; - } + ? true + : array_search($this->getExtension($file->getUntrustedName()), array_unique($this->getMimeTypes()), true) !== false; } /** @@ -48,6 +36,14 @@ public function getAllowedTypes(): string return implode(', ', array_unique($this->getMimeTypes())); } + /** + * Vrátí seznam povolených typů souborů s jejich typickou koncovkou. + * + * @example array("text/plain" => "txt") + * @return string[] + */ + abstract protected function getMimeTypes(): array; + /** * Vrátí koncovku souboru. */ diff --git a/src/Filter/DocumentFilter.php b/src/Filter/DocumentFilter.php index 5014bc4..9a21e40 100644 --- a/src/Filter/DocumentFilter.php +++ b/src/Filter/DocumentFilter.php @@ -1,11 +1,9 @@ */ class DocumentFilter extends BaseFilter { diff --git a/src/Filter/IMimeTypeFilter.php b/src/Filter/IMimeTypeFilter.php index 58a9ae1..1aa9f84 100644 --- a/src/Filter/IMimeTypeFilter.php +++ b/src/Filter/IMimeTypeFilter.php @@ -1,14 +1,12 @@ */ interface IMimeTypeFilter { @@ -19,13 +17,11 @@ interface IMimeTypeFilter * @param FileUpload $file Nahraný soubor k ověření. * @return bool Má soubor správný mimetype? */ - public function checkType(FileUpload $file); + public function checkType(FileUpload $file): bool; /** * Vrátí seznam povolených typů souborů. - * - * @return string */ - public function getAllowedTypes(); + public function getAllowedTypes(): string; } diff --git a/src/Filter/ImageFilter.php b/src/Filter/ImageFilter.php index 2dd3a4a..98b6af7 100644 --- a/src/Filter/ImageFilter.php +++ b/src/Filter/ImageFilter.php @@ -1,11 +1,9 @@ */ class ImageFilter extends BaseFilter { diff --git a/src/Model/BaseUploadModel.php b/src/Model/BaseUploadModel.php index be00ea6..abd1a67 100644 --- a/src/Model/BaseUploadModel.php +++ b/src/Model/BaseUploadModel.php @@ -1,6 +1,6 @@ */ class BaseUploadModel implements IUploadModel { @@ -19,11 +17,10 @@ class BaseUploadModel implements IUploadModel /** * Uložení nahraného souboru. * - * @param FileUpload $file * @param array $params Pole vlastních parametrů. * @return mixed Vlastní navrátová hodnota. */ - public function save(FileUpload $file, array $params = []) + public function save(FileUpload $file, array $params = []): mixed { return $file->getSanitizedName(); } @@ -33,7 +30,7 @@ public function save(FileUpload $file, array $params = []) * * @param mixed $uploaded Hodnota navrácená funkcí save. */ - public function remove($uploaded): void + public function remove(mixed $uploaded): void { // By Pass... } @@ -45,7 +42,7 @@ public function remove($uploaded): void * @param string $newName Nové jméno souboru. * @return mixed Vlastní návratová hodnota. */ - public function rename($upload, $newName) + public function rename(mixed $upload, string $newName): mixed { return Strings::webalize($newName); } diff --git a/src/Model/DefaultFile.php b/src/Model/DefaultFile.php index 9119de1..f8318f1 100644 --- a/src/Model/DefaultFile.php +++ b/src/Model/DefaultFile.php @@ -1,14 +1,12 @@ */ class DefaultFile { @@ -20,28 +18,22 @@ class DefaultFile * * @var array */ - public $onDelete = []; + public array $onDelete = []; /** * Odkaz na náhled obrázku. - * - * @var string */ - private $preview; + private ?string $preview = null; /** * Název souboru. - * - * @var string */ - private $filename; + private ?string $filename = null; /** * Identifikátor souboru sloužící pro jeho smazání. - * - * @var mixed */ - private $identifier; + private mixed $identifier = null; /** * @return array @@ -55,38 +47,32 @@ public function toArray(): array ]; } - public function getPreview(): string + public function getPreview(): ?string { return $this->preview; } - public function setPreview(string $preview): void + public function setPreview(?string $preview): void { $this->preview = $preview; } - public function getFilename(): string + public function getFilename(): ?string { return $this->filename; } - public function setFilename(string $filename): void + public function setFilename(?string $filename): void { $this->filename = $filename; } - /** - * @return mixed - */ - public function getIdentifier() + public function getIdentifier(): mixed { return $this->identifier; } - /** - * @param mixed $identifier - */ - public function setIdentifier($identifier): void + public function setIdentifier(mixed $identifier): void { $this->identifier = $identifier; } diff --git a/src/Model/IUploadModel.php b/src/Model/IUploadModel.php index 1948fd3..9c39255 100644 --- a/src/Model/IUploadModel.php +++ b/src/Model/IUploadModel.php @@ -1,13 +1,11 @@ */ interface IUploadModel { @@ -15,11 +13,10 @@ interface IUploadModel /** * Uložení nahraného souboru. * - * @param FileUpload $file * @param array $params Pole vlastních parametrů. * @return mixed Vlastní navrátová hodnota. */ - public function save(FileUpload $file, array $params = []); + public function save(FileUpload $file, array $params = []): mixed; /** * Zpracování přejmenování souboru. @@ -28,13 +25,13 @@ public function save(FileUpload $file, array $params = []); * @param string $newName Nové jméno souboru. * @return mixed Vlastní návratová hodnota. */ - public function rename($upload, $newName); + public function rename(mixed $upload, string $newName): mixed; /** * Zpracování požadavku o smazání souboru. * * @param mixed $uploaded Hodnota navrácená funkcí save. */ - public function remove($uploaded): void; + public function remove(mixed $uploaded): void; } diff --git a/src/Model/UploadController.php b/src/Model/UploadController.php index a9d09fd..0819082 100644 --- a/src/Model/UploadController.php +++ b/src/Model/UploadController.php @@ -1,7 +1,12 @@ */ class UploadController extends Control { - /** @var FileUploadControl */ - private $uploadControl; + private FileUploadControl $uploadControl; - /** @var Request */ - private $request; + private Request $request; - /** @var IMimeTypeFilter */ - private $filter; + private ?IMimeTypeFilter $filter = null; - /** @var BaseRenderer */ - private $renderer; + private ?BaseRenderer $renderer = null; - /** - * @param FileUploadControl $uploadControl - */ public function __construct(FileUploadControl $uploadControl) { $this->uploadControl = $uploadControl; diff --git a/src/Template/JavascriptBuilder.php b/src/Template/JavascriptBuilder.php index ff1f64b..0ad5334 100644 --- a/src/Template/JavascriptBuilder.php +++ b/src/Template/JavascriptBuilder.php @@ -1,46 +1,29 @@ */ class JavascriptBuilder { use SmartObject; - /** - * @var Template - */ - private $template; + private Template $template; - /** - * @var BaseRenderer - */ - private $renderer; + private BaseRenderer $renderer; - /** - * @var UploadController - */ - private $controller; + private UploadController $controller; - /** - * JavascriptBuilder constructor. - * - * @param BaseRenderer $renderer - * @param UploadController $controller - */ public function __construct( BaseRenderer $renderer, UploadController $controller @@ -50,7 +33,7 @@ public function __construct( $this->controller = $controller; $this->template = $controller->template; - $this->template->setFile(__DIR__ . "/js.latte"); + $this->template->setFile(__DIR__ . '/js.latte'); } public function getJsTemplate(): string @@ -72,12 +55,12 @@ private function buildTemplate(): string */ private function setSettings(): void { - $this->template->uploadUrl = $this->controller->link("upload"); - $this->template->renameLink = $this->controller->link("rename"); - $this->template->removeLink = $this->controller->link("//remove"); + $this->template->uploadUrl = $this->controller->link('upload'); + $this->template->renameLink = $this->controller->link('rename'); + $this->template->removeLink = $this->controller->link('//remove'); /** @var Html $input */ - $input = $this->renderer->getElements()["input"]; - $this->template->inputId = $input->attrs["id"]; + $input = $this->renderer->getElements()['input']; + $this->template->inputId = $input->attrs['id']; $this->needTranslate(); $this->template->messages = $this->controller->getUploadControl()->getMessages(); @@ -116,11 +99,7 @@ private function setRendererSettings(): void $components = []; foreach ($elements as $type => $element) { - if ($element instanceof Html) { - $components[$type] = $element->getAttribute("data-upload-component"); - } else { - $components[$type] = null; - } + $components[$type] = $element instanceof Html ? $element->getAttribute('data-upload-component') : null; } $this->template->components = $components; @@ -133,8 +112,10 @@ private function needTranslate(): void foreach ($upload->getMessages() as $key => $value) { /** @var ITranslator $translator */ $translator = $upload->getTranslator(); - $upload->setMessage($key, $translator->translate($value)); + $translated = $translator->translate($value); + $upload->setMessage($key, is_string($translated) ? $translated : (string) $translated); } } } + } diff --git a/src/Template/Renderer/BaseRenderer.php b/src/Template/Renderer/BaseRenderer.php index 6819b99..3e7400d 100644 --- a/src/Template/Renderer/BaseRenderer.php +++ b/src/Template/Renderer/BaseRenderer.php @@ -1,30 +1,20 @@ - - * @package Zet\FileUpload\Template\Renderer */ abstract class BaseRenderer implements IUploadRenderer { use SmartObject; - /** - * ID template ve tvaru: HtmlId-ElementType - * - * @var string - */ - private $idTemplate = "%s-%s"; - /** * Seznam všech základních komponent uploaderu: *
    @@ -43,39 +33,36 @@ abstract class BaseRenderer implements IUploadRenderer * * @var array */ - protected $elements = [ - "container" => '', - "input" => '', - "globalProgress" => '', - "globalProgressValue" => '', - "fileProgress" => '', - "fileProgressValue" => '', - "imagePreview" => '', - "filePreview" => '', - "filename" => '', - "delete" => '', - "errorMessage" => '', + protected array $elements = [ + 'container' => '', + 'input' => '', + 'globalProgress' => '', + 'globalProgressValue' => '', + 'fileProgress' => '', + 'fileProgressValue' => '', + 'imagePreview' => '', + 'filePreview' => '', + 'filename' => '', + 'delete' => '', + 'errorMessage' => '', ]; - /** - * @var FileUploadControl - */ - protected $fileUploadControl; + protected FileUploadControl $fileUploadControl; + + /** @var Translator|NULL */ + protected ?Translator $translator = null; /** - * @var Translator|NULL + * ID template ve tvaru: HtmlId-ElementType */ - protected $translator; + private string $idTemplate = '%s-%s'; /** - * BaseRenderer constructor. - * - * @param FileUploadControl $fileUploadControl * @param Translator|NULL $translator */ public function __construct( FileUploadControl $fileUploadControl, - Translator $translator = null + ?Translator $translator = null ) { $this->fileUploadControl = $fileUploadControl; @@ -84,6 +71,21 @@ public function __construct( $this->translator = $translator; } + /** + * Sestavení výchozí šablony uploaderu. + */ + abstract public function buildDefaultTemplate(): Html; + + /** + * Sestavení šablony pro vkládání nových souborů. + */ + abstract public function buildFileContainerTemplate(): Html; + + /** + * Sestavení šablony pro soubor, u kterého vznikla chyba. + */ + abstract public function buildFileError(): Html; + /** * Inicializace elementů. */ @@ -92,23 +94,23 @@ public function init(): void $htmlId = $this->fileUploadControl->getHtmlId(); foreach ($this->elements as $type => $value) { - if ($type == "input") { + if ($type === 'input') { $element = Html::el("input type='file' multiple='multiple'")->addAttributes([ - "id" => $htmlId, - "name" => $this->fileUploadControl->getHtmlName(), - "data-upload-component" => $htmlId, + 'id' => $htmlId, + 'name' => $this->fileUploadControl->getHtmlName(), + 'data-upload-component' => $htmlId, ]); - } elseif ($type == "delete") { + } elseif ($type === 'delete') { $element = Html::el("button type='button'")->addAttributes([ - "data-upload-component" => sprintf($this->idTemplate, $htmlId, $type), + 'data-upload-component' => sprintf($this->idTemplate, $htmlId, $type), ]); - } elseif ($type == "imagePreview") { - $element = Html::el("img")->addAttributes([ - "data-upload-component" => sprintf($this->idTemplate, $htmlId, $type), + } elseif ($type === 'imagePreview') { + $element = Html::el('img')->addAttributes([ + 'data-upload-component' => sprintf($this->idTemplate, $htmlId, $type), ]); } else { - $element = Html::el("div")->addAttributes([ - "data-upload-component" => sprintf($this->idTemplate, $htmlId, $type), + $element = Html::el('div')->addAttributes([ + 'data-upload-component' => sprintf($this->idTemplate, $htmlId, $type), ]); } @@ -119,23 +121,9 @@ public function init(): void /** * @return array */ - public function getElements() + public function getElements(): array { return $this->elements; } - /** - * Sestavení výchozí šablony uploaderu. - */ - abstract public function buildDefaultTemplate(): Html; - - /** - * Sestavení šablony pro vkládání nových souborů. - */ - abstract public function buildFileContainerTemplate(): Html; - - /** - * Sestavení šablony pro soubor, u kterého vznikla chyba. - */ - abstract public function buildFileError(): Html; } diff --git a/src/Template/Renderer/Bootstrap3Renderer.php b/src/Template/Renderer/Bootstrap3Renderer.php index 5098a07..4b32820 100644 --- a/src/Template/Renderer/Bootstrap3Renderer.php +++ b/src/Template/Renderer/Bootstrap3Renderer.php @@ -1,13 +1,11 @@ - */ class Bootstrap3Renderer extends BaseRenderer { @@ -16,8 +14,8 @@ public function init(): void { parent::init(); - $this->elements["globalProgressValue"] = ''; - $this->elements["fileProgressValue"] = ''; + $this->elements['globalProgressValue'] = ''; + $this->elements['fileProgressValue'] = ''; } /** @@ -25,39 +23,39 @@ public function init(): void */ public function buildDefaultTemplate(): Html { - $customContainer = Html::el("div"); + $customContainer = Html::el('div'); /** @var Html $input */ - $input = $this->elements["input"]; - $input->setAttribute("style", "display: none"); + $input = $this->elements['input']; + $input->setAttribute('style', 'display: none'); /** @var Html $input */ - $input = $this->elements["input"]; - $id = $input->getAttribute("id"); + $input = $this->elements['input']; + $id = $input->getAttribute('id'); $button = Html::el("button type='button' class='btn btn-primary'"); - $button->setAttribute("onclick", "document.getElementById('$id').click(); return false;") - ->setAttribute("style", "margin-bottom: 10px"); - $button->setText("Nahrát soubor"); + $button->setAttribute('onclick', sprintf("document.getElementById('%s').click(); return false;", $id)) + ->setAttribute('style', 'margin-bottom: 10px'); + $button->setText('Nahrát soubor'); - $customContainer->addHtml($this->elements["input"]); + $customContainer->addHtml($this->elements['input']); $customContainer->addHtml($button); /** @var Html $globalProgress */ - $globalProgress = $this->elements["globalProgress"]; - $globalProgress->setAttribute("class", "progress-bar"); + $globalProgress = $this->elements['globalProgress']; + $globalProgress->setAttribute('class', 'progress-bar'); $progressContainer = Html::el("div class='progress'"); $progressContainer->addHtml($globalProgress); $customContainer->addHtml($progressContainer); - $container = Html::el("table"); - $container->setAttribute("class", "table table-striped"); + $container = Html::el('table'); + $container->setAttribute('class', 'table table-striped'); - $thead = Html::el("thead"); - $tr = Html::el("tr"); + $thead = Html::el('thead'); + $tr = Html::el('tr'); $preview = Html::el("th style='width: 15%;'"); $tr->addHtml($preview); - $filename = Html::el("th")->setText("Soubor"); + $filename = Html::el('th')->setText('Soubor'); $tr->addHtml($filename); - $status = Html::el("th style='width: 20%'")->setText("Stav"); + $status = Html::el("th style='width: 20%'")->setText('Stav'); $tr->addHtml($status); $actions = Html::el("th style='width: 50px'"); $tr->addHtml($actions); @@ -66,8 +64,8 @@ public function buildDefaultTemplate(): Html $container->addHtml($thead); /** @var Html $fileUploadContainer */ - $fileUploadContainer = $this->elements["container"]; - $fileUploadContainer->setName("tbody"); + $fileUploadContainer = $this->elements['container']; + $fileUploadContainer->setName('tbody'); $container->addHtml($fileUploadContainer); $customContainer->addHtml($container); @@ -79,35 +77,35 @@ public function buildDefaultTemplate(): Html */ public function buildFileContainerTemplate(): Html { - $tr = Html::el("tr"); + $tr = Html::el('tr'); $preview = Html::el("td style='vertical-align: middle'"); /** @var Html $imagePreview */ - $imagePreview = $this->elements["imagePreview"]; - $preview->addHtml($imagePreview->setAttribute("width", "100%")->setAttribute("class", "img-rounded")); + $imagePreview = $this->elements['imagePreview']; + $preview->addHtml($imagePreview->setAttribute('width', '100%')->setAttribute('class', 'img-rounded')); /** @var Html $filePreview */ - $filePreview = $this->elements["filePreview"]; - $preview->addHtml($filePreview->setName("span")->setAttribute("class", "label label-info")); + $filePreview = $this->elements['filePreview']; + $preview->addHtml($filePreview->setName('span')->setAttribute('class', 'label label-info')); $tr->addHtml($preview); $name = Html::el("td style='vertical-align: middle'"); - $name->addHtml($this->elements["filename"]); + $name->addHtml($this->elements['filename']); $tr->addHtml($name); $progressTd = Html::el("td style='vertical-align: middle'"); $progressContainer = Html::el("div class='progress' style='margin-bottom: 0px'"); /** @var Html $fileProgress */ - $fileProgress = $this->elements["fileProgress"]; - $progress = $fileProgress->setAttribute("class", "progress-bar"); + $fileProgress = $this->elements['fileProgress']; + $progress = $fileProgress->setAttribute('class', 'progress-bar'); $progressContainer->addHtml($progress); $progressTd->addHtml($progressContainer); $tr->addHtml($progressTd); $delete = Html::el("td style='vertical-align: middle' class='text-center'"); /** @var Html $deleteElement */ - $deleteElement = $this->elements["delete"]; - $deleteElement->setAttribute("class", "btn btn-danger") - ->setHtml("×"); + $deleteElement = $this->elements['delete']; + $deleteElement->setAttribute('class', 'btn btn-danger') + ->setHtml('×'); $delete->addHtml($deleteElement); $tr->addHtml($delete); @@ -121,11 +119,12 @@ public function buildFileError(): Html { $tr = Html::el("tr class='danger'"); /** @var Html $errorMessage */ - $errorMessage = $this->elements["errorMessage"]; - $tr->addHtml($errorMessage->setName("td")->addAttributes([ - "colspan" => 4, + $errorMessage = $this->elements['errorMessage']; + $tr->addHtml($errorMessage->setName('td')->addAttributes([ + 'colspan' => 4, ])); return $tr; } + } diff --git a/src/Template/Renderer/Bootstrap4Renderer.php b/src/Template/Renderer/Bootstrap4Renderer.php index 07a325d..806ba34 100644 --- a/src/Template/Renderer/Bootstrap4Renderer.php +++ b/src/Template/Renderer/Bootstrap4Renderer.php @@ -1,14 +1,11 @@ - * @package Zet\FileUpload\Template\Renderer */ class Bootstrap4Renderer extends BaseRenderer { @@ -17,8 +14,8 @@ public function init(): void { parent::init(); - $this->elements["globalProgressValue"] = ''; - $this->elements["fileProgressValue"] = ''; + $this->elements['globalProgressValue'] = ''; + $this->elements['fileProgressValue'] = ''; } /** @@ -26,41 +23,41 @@ public function init(): void */ public function buildDefaultTemplate(): Html { - $customContainer = Html::el("div"); + $customContainer = Html::el('div'); /** @var Html $input */ - $input = $this->elements["input"]; - $input->setAttribute("style", "display: none"); + $input = $this->elements['input']; + $input->setAttribute('style', 'display: none'); /** @var Html $input */ - $input = $this->elements["input"]; - $id = $input->getAttribute("id"); + $input = $this->elements['input']; + $id = $input->getAttribute('id'); $button = Html::el("button type='button' class='btn btn-primary mb-2'"); - $button->setAttribute("onclick", "document.getElementById('$id').click(); return false;"); - $button->setText("Nahrát soubor"); + $button->setAttribute('onclick', sprintf("document.getElementById('%s').click(); return false;", $id)); + $button->setText('Nahrát soubor'); - $customContainer->addHtml($this->elements["input"]); + $customContainer->addHtml($this->elements['input']); $customContainer->addHtml($button); /** @var Html $globalProgress */ - $globalProgress = $this->elements["globalProgress"]; - $globalProgress->setAttribute("class", "progress-bar") - ->setAttribute("style", "height: 20px"); + $globalProgress = $this->elements['globalProgress']; + $globalProgress->setAttribute('class', 'progress-bar') + ->setAttribute('style', 'height: 20px'); $progressContainer = Html::el("div class='progress mb-2'"); $progressContainer->addHtml($globalProgress); $customContainer->addHtml($progressContainer); /** @var Html $container */ - $container = $this->elements["container"]; - $container->setName("table"); - $container->setAttribute("class", "table"); + $container = $this->elements['container']; + $container->setName('table'); + $container->setAttribute('class', 'table'); $thead = Html::el("thead class='thead-inverse'"); - $tr = Html::el("tr"); + $tr = Html::el('tr'); $preview = Html::el("th style='width: 15%;'"); $tr->addHtml($preview); - $filename = Html::el("th")->setText("Soubor"); + $filename = Html::el('th')->setText('Soubor'); $tr->addHtml($filename); - $status = Html::el("th style='width: 20%'")->setText("Stav"); + $status = Html::el("th style='width: 20%'")->setText('Stav'); $tr->addHtml($status); $actions = Html::el("th style='width: 50px'"); $tr->addHtml($actions); @@ -77,36 +74,36 @@ public function buildDefaultTemplate(): Html */ public function buildFileContainerTemplate(): Html { - $tr = Html::el("tr"); + $tr = Html::el('tr'); $preview = Html::el("td class='align-middle'"); /** @var Html $imagePreview */ - $imagePreview = $this->elements["imagePreview"]; - $preview->addHtml($imagePreview->setAttribute("width", "100%")->setAttribute("class", "rounded")); + $imagePreview = $this->elements['imagePreview']; + $preview->addHtml($imagePreview->setAttribute('width', '100%')->setAttribute('class', 'rounded')); /** @var Html $filePreview */ - $filePreview = $this->elements["filePreview"]; - $preview->addHtml($filePreview->setName("span")->setAttribute("class", "badge badge-pill badge-info")); + $filePreview = $this->elements['filePreview']; + $preview->addHtml($filePreview->setName('span')->setAttribute('class', 'badge badge-pill badge-info')); $tr->addHtml($preview); $name = Html::el("td class='align-middle'"); - $name->addHtml($this->elements["filename"]); + $name->addHtml($this->elements['filename']); $tr->addHtml($name); $progressTd = Html::el("td class='align-middle'"); $progressContainer = Html::el("div class='progress'"); /** @var Html $fileProgress */ - $fileProgress = $this->elements["fileProgress"]; - $progress = $fileProgress->setAttribute("class", "progress-bar") - ->setAttribute("style", "height: 10px"); + $fileProgress = $this->elements['fileProgress']; + $progress = $fileProgress->setAttribute('class', 'progress-bar') + ->setAttribute('style', 'height: 10px'); $progressContainer->addHtml($progress); $progressTd->addHtml($progressContainer); $tr->addHtml($progressTd); $delete = Html::el("td class='align-middle text-center'"); /** @var Html $delEl */ - $delEl = $this->elements["delete"]; - $delEl->setAttribute("class", "btn btn-outline-danger") - ->setHtml("×"); + $delEl = $this->elements['delete']; + $delEl->setAttribute('class', 'btn btn-outline-danger') + ->setHtml('×'); $delete->addHtml($delEl); $tr->addHtml($delete); @@ -120,11 +117,12 @@ public function buildFileError(): Html { $tr = Html::el("tr class='bg-danger text-light'"); /** @var Html $errorMessage */ - $errorMessage = $this->elements["errorMessage"]; - $tr->addHtml($errorMessage->setName("td")->addAttributes([ - "colspan" => 4, + $errorMessage = $this->elements['errorMessage']; + $tr->addHtml($errorMessage->setName('td')->addAttributes([ + 'colspan' => 4, ])); return $tr; } + } diff --git a/src/Template/Renderer/Html5Renderer.php b/src/Template/Renderer/Html5Renderer.php index 263948b..d3bcf37 100644 --- a/src/Template/Renderer/Html5Renderer.php +++ b/src/Template/Renderer/Html5Renderer.php @@ -1,13 +1,11 @@ - * @package Zet\FileUpload\Template\Renderer */ class Html5Renderer extends BaseRenderer { @@ -16,51 +14,51 @@ public function init(): void { parent::init(); - $this->elements["globalProgressValue"] = ''; - $this->elements["fileProgressValue"] = ''; + $this->elements['globalProgressValue'] = ''; + $this->elements['fileProgressValue'] = ''; /** @var Html $container */ - $container = $this->elements["container"]; - $container->setName("table")->addAttributes([ - "style" => "width: 100%", - "border" => "0", + $container = $this->elements['container']; + $container->setName('table')->addAttributes([ + 'style' => 'width: 100%', + 'border' => '0', ]); /** @var Html $globalProgress */ - $globalProgress = $this->elements["globalProgress"]; - $globalProgress->setName("progress") + $globalProgress = $this->elements['globalProgress']; + $globalProgress->setName('progress') ->addAttributes([ - "value" => 0, - "max" => 100, - "style" => "width: 100%", + 'value' => 0, + 'max' => 100, + 'style' => 'width: 100%', ]); /** @var Html $fileProgress */ - $fileProgress = $this->elements["fileProgress"]; - $fileProgress->setName("progress") + $fileProgress = $this->elements['fileProgress']; + $fileProgress->setName('progress') ->addAttributes([ - "value" => 0, - "max" => 100, - "style" => "width: 100%", + 'value' => 0, + 'max' => 100, + 'style' => 'width: 100%', ]); /** @var Html $imagePreview */ - $imagePreview = $this->elements["imagePreview"]; + $imagePreview = $this->elements['imagePreview']; $imagePreview->addAttributes([ - "class" => "fileupload-image-preview", + 'class' => 'fileupload-image-preview', ]); /** @var Html $filePreview */ - $filePreview = $this->elements["filePreview"]; + $filePreview = $this->elements['filePreview']; $filePreview->addAttributes([ - "class" => "fileupload-file-extension", + 'class' => 'fileupload-file-extension', ]); /** @var Html $delete */ - $delete = $this->elements["delete"]; + $delete = $this->elements['delete']; $delete->addAttributes([ - "class" => "fileupload-delete-button", - ])->setHtml("×"); + 'class' => 'fileupload-delete-button', + ])->setHtml('×'); } /** @@ -69,35 +67,35 @@ public function init(): void public function buildDefaultTemplate(): Html { /** @var Html $table */ - $table = $this->elements["container"]; - $table->setAttribute("cellpadding", "5px"); + $table = $this->elements['container']; + $table->setAttribute('cellpadding', '5px'); // Header - $tr = Html::el("tr"); + $tr = Html::el('tr'); $th = Html::el("th colspan='2' style='border-right: none'"); - $th->setText("Nahrávání souborů"); + $th->setText('Nahrávání souborů'); $tr->addHtml($th); /** @var Html $th2 */ $th2 = Html::el("th colspan='2' style='text-align: right; border-left: none'"); /** @var Html $input */ - $input = $this->elements["input"]; - $input->setAttribute("style", "display: none"); + $input = $this->elements['input']; + $input->setAttribute('style', 'display: none'); $th2->addHtml($input); $button = Html::el("button type='button'"); - $button->setText("Nahrát soubor"); + $button->setText('Nahrát soubor'); /** @var Html $input */ - $input = $this->elements["input"]; - $id = $input->getAttribute("id"); - $button->setAttribute("onclick", "document.getElementById('$id').click(); return false;"); + $input = $this->elements['input']; + $id = $input->getAttribute('id'); + $button->setAttribute('onclick', sprintf("document.getElementById('%s').click(); return false;", $id)); $th2->addHtml($button); $tr->addHtml($th2); $table->addHtml($tr); // Global Progress - $tr = Html::el("tr"); + $tr = Html::el('tr'); $td = Html::el("td colspan='4'"); - $td->addHtml($this->elements["globalProgress"]); + $td->addHtml($this->elements['globalProgress']); $tr->addHtml($td); $table->addHtml($tr); @@ -109,31 +107,31 @@ public function buildDefaultTemplate(): Html */ public function buildFileContainerTemplate(): Html { - $tr = Html::el("tr"); + $tr = Html::el('tr'); - $preview = Html::el("td")->addAttributes([ - "style" => "width: 15%", + $preview = Html::el('td')->addAttributes([ + 'style' => 'width: 15%', ]); /** @var Html $imagePreview */ - $imagePreview = $this->elements["imagePreview"]; - $preview->addHtml($imagePreview->setAttribute("width", "100%")); - $preview->addHtml($this->elements["filePreview"]); + $imagePreview = $this->elements['imagePreview']; + $preview->addHtml($imagePreview->setAttribute('width', '100%')); + $preview->addHtml($this->elements['filePreview']); $tr->addHtml($preview); - $name = Html::el("td"); - $name->addHtml($this->elements["filename"]); + $name = Html::el('td'); + $name->addHtml($this->elements['filename']); $tr->addHtml($name); - $progress = Html::el("td"); - $progress->addHtml($this->elements["fileProgress"])->addAttributes([ - "style" => "width: 20%", + $progress = Html::el('td'); + $progress->addHtml($this->elements['fileProgress'])->addAttributes([ + 'style' => 'width: 20%', ]); $tr->addHtml($progress); - $delete = Html::el("td")->addAttributes([ - "style" => "width: 50px; text-align: center", + $delete = Html::el('td')->addAttributes([ + 'style' => 'width: 50px; text-align: center', ]); - $delete->addHtml($this->elements["delete"]); + $delete->addHtml($this->elements['delete']); $tr->addHtml($delete); return $tr; @@ -147,11 +145,12 @@ public function buildFileError(): Html /** @var Html $tr */ $tr = Html::el("tr style='background-color: #ffb6c1'"); /** @var Html $errorMessage */ - $errorMessage = $this->elements["errorMessage"]; - $tr->addHtml($errorMessage->setName("td")->addAttributes([ - "colspan" => 4, + $errorMessage = $this->elements['errorMessage']; + $tr->addHtml($errorMessage->setName('td')->addAttributes([ + 'colspan' => 4, ])); return $tr; } + } diff --git a/src/Template/Renderer/IUploadRenderer.php b/src/Template/Renderer/IUploadRenderer.php index 0757ba8..0439c2a 100644 --- a/src/Template/Renderer/IUploadRenderer.php +++ b/src/Template/Renderer/IUploadRenderer.php @@ -1,13 +1,11 @@ */ interface IUploadRenderer { @@ -26,4 +24,5 @@ public function buildFileContainerTemplate(): Html; * Sestavení šablony pro soubor, u kterého vznikla chyba. */ public function buildFileError(): Html; + } diff --git a/tests/fixtures/Filter/InvalidFilter.php b/tests/Fixtures/Filter/InvalidFilter.php similarity index 80% rename from tests/fixtures/Filter/InvalidFilter.php rename to tests/Fixtures/Filter/InvalidFilter.php index 7014fd0..3b58c67 100644 --- a/tests/fixtures/Filter/InvalidFilter.php +++ b/tests/Fixtures/Filter/InvalidFilter.php @@ -5,6 +5,9 @@ class InvalidFilter { + /** + * @return array + */ protected function getMimeTypes(): array { return [ diff --git a/tests/fixtures/Filter/ValidFilter.php b/tests/Fixtures/Filter/ValidFilter.php similarity index 69% rename from tests/fixtures/Filter/ValidFilter.php rename to tests/Fixtures/Filter/ValidFilter.php index 0b657dc..1e576e9 100644 --- a/tests/fixtures/Filter/ValidFilter.php +++ b/tests/Fixtures/Filter/ValidFilter.php @@ -2,11 +2,14 @@ namespace Tests\Fixtures\Filter; -use Zet\FileUpload\Filter\BaseFilter; +use Contributte\FileUpload\Filter\BaseFilter; class ValidFilter extends BaseFilter { + /** + * @return array + */ protected function getMimeTypes(): array { return [ diff --git a/tests/fixtures/Model/InvalidUploadModel.php b/tests/Fixtures/Model/InvalidUploadModel.php similarity index 63% rename from tests/fixtures/Model/InvalidUploadModel.php rename to tests/Fixtures/Model/InvalidUploadModel.php index 0726070..f319a85 100644 --- a/tests/fixtures/Model/InvalidUploadModel.php +++ b/tests/Fixtures/Model/InvalidUploadModel.php @@ -8,20 +8,25 @@ class InvalidUploadModel { - public function remove($uploaded): void + public function remove(mixed $uploaded): void { FileSystem::delete($uploaded[0] . '/' . $uploaded[1]); } - public function rename($upload, $newName) + public function rename(mixed $upload, string $newName): void { FileSystem::rename($upload[0] . '/' . $upload[1], $upload[0] . '/' . $newName); } - public function save(FileUpload $file, array $params = []) + /** + * @param array $params + * @return array|false + */ + public function save(FileUpload $file, array $params = []): array|false { if ($file->isOk()) { $file->move($params['folder'] . '/' . $file->name); + return [$params['folder'], $file->name]; } diff --git a/tests/fixtures/Model/ValidUploadModel.php b/tests/Fixtures/Model/ValidUploadModel.php similarity index 59% rename from tests/fixtures/Model/ValidUploadModel.php rename to tests/Fixtures/Model/ValidUploadModel.php index ffb2cc6..ee8cd01 100644 --- a/tests/fixtures/Model/ValidUploadModel.php +++ b/tests/Fixtures/Model/ValidUploadModel.php @@ -2,27 +2,34 @@ namespace Tests\Fixtures\Model; +use Contributte\FileUpload\Model\BaseUploadModel; use Nette\Http\FileUpload; use Nette\Utils\FileSystem; -use Zet\FileUpload\Model\BaseUploadModel; class ValidUploadModel extends BaseUploadModel { - public function remove($uploaded): void + public function remove(mixed $uploaded): void { FileSystem::delete($uploaded[0] . '/' . $uploaded[1]); } - public function rename($upload, $newName) + public function rename(mixed $upload, string $newName): mixed { FileSystem::rename($upload[0] . '/' . $upload[1], $upload[0] . '/' . $newName); + + return null; } - public function save(FileUpload $file, array $params = []) + /** + * @param array $params + * @return array|false + */ + public function save(FileUpload $file, array $params = []): array|false { if ($file->isOk()) { $file->move($params['folder'] . '/' . $file->name); + return [$params['folder'], $file->name]; } diff --git a/tests/fixtures/Template/Renderer/InvalidRenderer.php b/tests/Fixtures/Template/Renderer/InvalidRenderer.php similarity index 87% rename from tests/fixtures/Template/Renderer/InvalidRenderer.php rename to tests/Fixtures/Template/Renderer/InvalidRenderer.php index 00a99d5..5855e33 100644 --- a/tests/fixtures/Template/Renderer/InvalidRenderer.php +++ b/tests/Fixtures/Template/Renderer/InvalidRenderer.php @@ -1,6 +1,6 @@ build(); @@ -47,7 +47,7 @@ final class FileUploadExtension extends TestCase fileUpload: maxFiles: 10 maxFileSize: 2M - fileFilter: Zet\FileUpload\Filter\ImageFilter + fileFilter: Contributte\FileUpload\Filter\ImageFilter uiMode: full NEON)); }) @@ -90,7 +90,7 @@ final class FileUploadExtension extends TestCase fileUpload: maxFiles: 10 maxFileSize: 2M - fileFilter: Zet\FileUpload\Filter\ImageFilter + fileFilter: Contributte\FileUpload\Filter\ImageFilter uploadModel: $uploadModel NEON)); }) @@ -187,7 +187,7 @@ final class FileUploadExtension extends TestCase ->withCompiler(function (Compiler $compiler): void { $compiler->addConfig(Helpers::neon(<<build(); @@ -199,7 +199,7 @@ final class FileUploadExtension extends TestCase ->withCompiler(function (Compiler $compiler): void { $compiler->addConfig(Helpers::neon(<<build(); diff --git a/tests/cases/Model/DefaultFile.phpt b/tests/cases/Model/DefaultFile.phpt index d15f956..c6b81f1 100644 --- a/tests/cases/Model/DefaultFile.phpt +++ b/tests/cases/Model/DefaultFile.phpt @@ -1,12 +1,12 @@ setFilename('foo.bar');