diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4779515..2ce8654 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 7b763da..ac3bcbe 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -17,10 +17,10 @@ jobs: continue-on-error: false strategy: matrix: - php-version: ['7.4', '8.0', '8.1', '8.2'] + php-version: ['8.1', '8.2', '8.3'] steps: - name: 'Checkout code' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Install PHP with extensions' uses: shivammathur/setup-php@2.27.1 @@ -38,6 +38,4 @@ jobs: composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable vendor/bin/simple-phpunit install - name: 'Run tests' - env: - SYMFONY_DEPRECATIONS_HELPER: 'max[indirect]=10&max[total]=27' - run: vendor/bin/simple-phpunit -v + run: vendor/bin/phpunit diff --git a/.gitignore b/.gitignore index 806efe3..3af2493 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,18 @@ Tests/log Tests/Functional/cache Tests/Functional/log vendor -.phpunit.result.cache .php-cs-fixer.cache clover.xml -.vscode \ No newline at end of file +.vscode +.phpunit.result.cache +###> symfony/framework-bundle ### +/.env.local +/.env.local.php +/.env.*.local +/config/secrets/prod/prod.decrypt.private.php +/public/bundles/ +/var/ +/vendor/ +###< symfony/framework-bundle ### +/phpunit.xml +/bin \ No newline at end of file diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 621e2b5..9415fe9 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -3,9 +3,9 @@ return (new PhpCsFixer\Config()) ->setRiskyAllowed(false) ->setRules([ - '@Symfony' => true, - '@PHP80Migration' => true, - 'array_syntax' => ['syntax' => 'short'], + '@Symfony' => true, + '@PHP80Migration' => true, + 'array_syntax' => ['syntax' => 'short'], 'combine_consecutive_unsets' => true, // one should use PHPUnit methods to set up expected exception instead of annotations 'general_phpdoc_annotation_remove' => [ @@ -17,15 +17,15 @@ 'expectedExceptionMessageRegExp', ], ], - 'function_typehint_space' => false, - 'no_empty_phpdoc' => true, - 'global_namespace_import' => ['import_classes' => true, 'import_functions' => true, 'import_constants' => true], - 'no_superfluous_phpdoc_tags' => ['allow_mixed' => false, 'allow_unused_params' => false], - 'phpdoc_line_span' => ['property' => 'single'], - 'heredoc_to_nowdoc' => true, - 'list_syntax' => ['syntax' => 'short'], + 'function_typehint_space' => false, + 'no_empty_phpdoc' => true, + 'global_namespace_import' => ['import_classes' => true, 'import_functions' => true, 'import_constants' => true], + 'no_superfluous_phpdoc_tags' => ['allow_mixed' => false, 'allow_unused_params' => false], + 'phpdoc_line_span' => ['property' => 'single'], + 'heredoc_to_nowdoc' => true, + 'list_syntax' => ['syntax' => 'short'], 'blank_line_before_statement' => ['statements' => ['if', 'break', 'continue', 'declare', 'return', 'throw', 'try', 'yield']], - 'no_extra_blank_lines' => [ + 'no_extra_blank_lines' => [ 'tokens' => [ 'break', 'continue', @@ -38,35 +38,35 @@ 'curly_brace_block', ], ], - 'echo_tag_syntax' => true, - 'method_argument_space' => false, - 'no_useless_else' => true, - 'no_useless_return' => true, - 'ordered_class_elements' => true, - 'ordered_imports' => ['sort_algorithm' => 'alpha', 'imports_order' => ['const', 'class', 'function']], + 'echo_tag_syntax' => true, + 'method_argument_space' => false, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'ordered_class_elements' => true, + 'ordered_imports' => ['sort_algorithm' => 'alpha', 'imports_order' => ['const', 'class', 'function']], 'php_unit_test_class_requires_covers' => true, - 'phpdoc_align' => [ + 'phpdoc_align' => [ 'tags' => [ 'param', 'return', 'throws', 'type', 'var' - ], + ], ], 'phpdoc_add_missing_param_annotation' => true, - 'phpdoc_order' => true, - 'phpdoc_no_alias_tag' => ['replacements' => ['link' => 'website']], - 'phpdoc_summary' => false, - 'phpdoc_to_comment' => false, - 'phpdoc_types_order' => false, // breaks psalm-specific notation sometimes! - 'semicolon_after_instruction' => true, - 'single_blank_line_at_eof' => true, - 'single_line_throw' => false, - 'types_spaces' => false, - 'binary_operator_spaces' => [ - 'default' => 'single_space', + 'phpdoc_order' => true, + 'phpdoc_no_alias_tag' => ['replacements' => ['link' => 'website']], + 'phpdoc_summary' => false, + 'phpdoc_to_comment' => false, + 'phpdoc_types_order' => false, // breaks psalm-specific notation sometimes! + 'semicolon_after_instruction' => true, + 'single_blank_line_at_eof' => true, + 'single_line_throw' => false, + 'types_spaces' => false, + 'binary_operator_spaces' => [ + 'default' => 'single_space', 'operators' => [ - '=' => 'align_single_space_minimal', - '-=' => 'align_single_space_minimal', - '+=' => 'align_single_space_minimal', - '=>' => 'align_single_space_minimal', + '=' => 'align_single_space_minimal', + '-=' => 'align_single_space_minimal', + '+=' => 'align_single_space_minimal', + '=>' => 'align_single_space_minimal', '===' => null, '??=' => 'align_single_space_minimal', ], @@ -79,6 +79,5 @@ ]) ->setFinder( PhpCsFixer\Finder::create() - ->in(__DIR__ . '/src') - ) -; + ->in(__DIR__ . '/src') + ); diff --git a/README.md b/README.md index 4d9fb57..f5a498b 100644 --- a/README.md +++ b/README.md @@ -23,42 +23,42 @@ Creation is inspired by simplicity and convenience of Finder program used in Mac Recommended bundles to use with: -| FMTinyMCEBundle | FOSCKEditorBundle | TrsteelCkeditorBundle| FMSummernoteBundle | -| ------------------------|-------------|-----------------|-----------------| -|[![FMTinyMCEBundle](https://img.shields.io/badge/FMTinyMCEBundle-download-brightgreen.svg)](https://github.com/helios-ag/FMTinyMCEBundle)|[![FOSCKEditorBundle](https://img.shields.io/badge/FOSCKEditorBundle-download-orange.svg)](https://github.com/FriendsOfSymfony/FOSCKEditorBundle)|[![TrsteelCkeditorBundle](https://img.shields.io/badge/TrsteelCkeditorBundle-download-blue.svg)](https://github.com/trsteel88/TrsteelCkeditorBundle)|[![FMSummernoteBundle](https://img.shields.io/badge/FMSummernoteBundle-download-brightgreen.svg)](https://github.com/helios-ag/summernote-bundle)| +| FMTinyMCEBundle | FOSCKEditorBundle | FMSummernoteBundle | +| ------------------------|-------------|-----------------| +|[![FMTinyMCEBundle](https://img.shields.io/badge/FMTinyMCEBundle-download-brightgreen.svg)](https://github.com/helios-ag/FMTinyMCEBundle)|[![FOSCKEditorBundle](https://img.shields.io/badge/FOSCKEditorBundle-download-orange.svg)](https://github.com/FriendsOfSymfony/FOSCKEditorBundle)|[![FMSummernoteBundle](https://img.shields.io/badge/FMSummernoteBundle-download-brightgreen.svg)](https://github.com/helios-ag/summernote-bundle)| **Table of contents** - [Installation](#installation) - - [Step 1: Installation](#step-1-installation) - - [Step 2: Enable the bundle](#step-2-enable-the-bundle-optional) - - [Step 3: Import FMElfinderBundle routing file](#step-3-import-fmelfinderbundle-routing-file) - - [Step 4: Securing paths](#step-4-configure-your-applications-securityyaml) + - [Step 1: Installation](#step-1-installation) + - [Step 2: Enable the bundle](#step-2-enable-the-bundle-optional) + - [Step 3: Import FMElfinderBundle routing file](#step-3-import-fmelfinderbundle-routing-file) + - [Step 4: Securing paths](#step-4-configure-your-applications-securityyaml) - [Basic configuration](#basic-configuration) - - [Add configuration options to your config.yaml](#add-configuration-options-to-your-configyaml) - - [Use multiple upload folder by instance](#use-multiple-upload-folder-by-instance) + - [Add configuration options to your config.yaml](#add-configuration-options-to-your-configyaml) + - [Use multiple upload folder by instance](#use-multiple-upload-folder-by-instance) - [CORS support](/docs/cors-support.md) - [Events listeners / subscribers](/docs/events-listeners-subscribers.md) - - [Events](/docs/events-listeners-subscribers.md#events) - - [Sub requests](/docs/events-listeners-subscribers.md#sub-requests) + - [Events](/docs/events-listeners-subscribers.md#events) + - [Sub requests](/docs/events-listeners-subscribers.md#sub-requests) - [Elfinder Form Type](/docs/elfinder-form-type.md) - - [Configuration](/docs/elfinder-form-type.md#configuration) - - [EasyAdmin 2.x](/docs/elfinder-form-type.md#easyadmin-2x-integration) - - [EasyAdmin 3.x/4.x](/docs/elfinder-form-type.md#easyadmin-3x/4x-integration) + - [Configuration](/docs/elfinder-form-type.md#configuration) + - [EasyAdmin 2.x](/docs/elfinder-form-type.md#easyadmin-2x-integration) + - [EasyAdmin 3.x/4.x](/docs/elfinder-form-type.md#easyadmin-3x/4x-integration) - [CKEditor integration](/docs/ckeditor-integration.md) - - [Installation](/docs/ckeditor-integration.md#step-1-installation) - - [Configuration](/docs/ckeditor-integration.md#step-2-configure-ckeditor-setting-via-settingsyml-or-through-form-builder) + - [Installation](/docs/ckeditor-integration.md#step-1-installation) + - [Configuration](/docs/ckeditor-integration.md#step-2-configure-ckeditor-setting-via-settingsyml-or-through-form-builder) - [TinyMCE integration](/docs/tinymce-integration.md) - - [Integration with TinyMCE 3](/docs/tinymce-integration.md#tinymce-3x) - - [Integration with TinyMCE 4](/docs/tinymce-integration.md#tinymce-4x) + - [Integration with TinyMCE 3](/docs/tinymce-integration.md#tinymce-3x) + - [Integration with TinyMCE 4](/docs/tinymce-integration.md#tinymce-4x) - [Summernote integration](/docs/summernote-integration.md) - [Advanced configuration](/docs/advanced-configuration.md) - - [Custom configuration provider](/docs/advanced-configuration.md#custom-configuration-provider) - - [Custom loader](/docs/advanced-configuration.md#custom-loader) - - [Plugins](/docs/advanced-configuration.md#plugins) - - [Service as volume driver](/docs/advanced-configuration.md#symfony-service-as-a-volume-driver) - - [Flysystem configuration](/docs/advanced-configuration.md#flysystem-configuration) + - [Custom configuration provider](/docs/advanced-configuration.md#custom-configuration-provider) + - [Custom loader](/docs/advanced-configuration.md#custom-loader) + - [Plugins](/docs/advanced-configuration.md#plugins) + - [Service as volume driver](/docs/advanced-configuration.md#symfony-service-as-a-volume-driver) + - [Flysystem configuration](/docs/advanced-configuration.md#flysystem-configuration) - [Configuration dump](/docs/configuration-dump.md) ## Installation @@ -156,12 +156,12 @@ fm_elfinder: * **default** - instance of elfinder, can be used to define multiple configurations of ElFinder, allows simultaneous configuration for different types of WYSIWYG editors in your project * **path** - define root directory for the files inside web/ directory, default is "uploads". Make sure to set proper write/read and owner permissions to this directory. * **url** - url to be prefixed to image path, for displaying. Can be either `absolute` or `relative`. If absolute, you can use `{homeFolder}` string as placeholder which will be replaced automatically. If relative, it will be prefixed with the applications base-url. If left blank, url will be the base-url, append with the value of the 'path' parameter -* **driver** - can be LocalFileSystem, FTP or MySQL, Flysystem, S3 and etc, check class FM\ElfinderBundle\DependencyInjection\Configuration +* **driver** - can be LocalFileSystem, FTP or MySQL, Flysystem, S3 and etc, check class FM\ElfinderBundle\DependencyInjection\Configuration * **locale** - locale determines, which language, ElFinder will use, to translate user interface, default is current request locale * **cors_support** - allows cross domain responses handling (default false) * **editor** - determines what template to render, to be compatible with WYSIWYG web editor, currently supported options are: - "ckeditor" (to use with FOSCKEditorBundle or TrsteelCkeditorBundle), "fm_tinymce" for tinymce4 (to use with FMTinyMCEBundle), "form" for form type, "simple" for standalone and "custom" for custom template. - How to configure CKEDitor and TinyMCE to work with this bundle, will be explained further in this document. + "ckeditor" (to use with FOSCKEditorBundle or TrsteelCkeditorBundle), "fm_tinymce" for tinymce4 (to use with FMTinyMCEBundle), "form" for form type, "simple" for standalone and "custom" for custom template. + How to configure CKEDitor and TinyMCE to work with this bundle, will be explained further in this document. * **editor_template** - define template to render when editor is set to "custom". * **connector** - root node for defining options for elfinder root directories. * **roots** - define "virtual directories" that reflect directories in your project. diff --git a/composer.json b/composer.json index 635da5e..f049a30 100644 --- a/composer.json +++ b/composer.json @@ -20,19 +20,20 @@ "exclude": ["/tests", "./github"] }, "require": { - "php": "^7.4 || ^8.0", + "php": "^8.1", "ext-json": "*", - "symfony/framework-bundle": "^4.4 || ^5.0 || ^5.2 || ^6.0 || ^7.0", - "symfony/twig-bundle": "^4.4 || ^5.0 || ^5.2 || ^6.0 || ^7.0", - "symfony/form": "^4.4 || ^5.0 || ^5.2 || ^6.0 || ^7.0", - "symfony/asset": "^4.4 || ^5.0 || ^5.2 || ^6.0 || ^7.0", + "symfony/framework-bundle": "^6.4 || ^7.0", + "symfony/twig-bundle": "^6.4 || ^7.0", + "symfony/form": "^6.4 || ^7.0", + "symfony/asset": "^6.4 || ^7.0", + "symfony/flex": "^2", "studio-42/elfinder": "~2.1.62" }, "require-dev" : { - "symfony/phpunit-bridge": "^7.0.1", - "matthiasnoback/symfony-config-test": "^4.0", - "matthiasnoback/symfony-dependency-injection-test": "^4.1", - "symfony/finder": "^4.4 || ^5.0 || ^5.2 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.4 || ^7.0.1", + "matthiasnoback/symfony-config-test": "^5.2", + "matthiasnoback/symfony-dependency-injection-test": "^6.0", + "symfony/finder": "^6.4 || ^7.0", "php-coveralls/php-coveralls": "^2.0", "friendsofphp/php-cs-fixer": "dev-master" }, @@ -43,6 +44,20 @@ "barryvdh/elfinder-flysystem-driver": "Flysystem driver for elfinder", "spatie/flysystem-dropbox": "Dropbox 2 Driver for Flysystem" }, + "config": { + "sort-packages": true, + "preferred-install": { + "symfony/doctrine-bridge": "source", + "*": "dist" + }, + "allow-plugins": { + "composer/installers": true, + "symfony/flex": true, + "symfony/runtime": true, + "composer/package-versions-deprecated": true, + "oomphinc/composer-installers-extender": true + } + }, "autoload": { "psr-4": { "FM\\ElfinderBundle\\": "src/" } }, @@ -51,7 +66,13 @@ }, "extra": { "branch-alias": { - "dev-master": "12.0-dev" + "dev-master": "13.0-dev" + } + }, + "scripts": { + "auto-scripts": { + "cache:clear": "symfony-cmd", + "assets:install %PUBLIC_DIR%": "symfony-cmd" } } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index fb1c3b7..5a19c1e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,31 +1,23 @@ - - - - ./ - - - ./src/Controller - ./src/Resources - ./tests - ./vendor - - - - - + + + + + + + + + + - - - ./tests @@ -34,4 +26,15 @@ + + + ./ + + + ./src/Controller + ./src/Resources + ./tests + ./vendor + + diff --git a/src/Bridge/ElFinderBridge.php b/src/Bridge/ElFinderBridge.php index 0f0405e..63f282d 100644 --- a/src/Bridge/ElFinderBridge.php +++ b/src/Bridge/ElFinderBridge.php @@ -24,10 +24,7 @@ public function setSession($session) $this->session = $session; } - /** - * @return array - */ - public function getVolumes() + public function getVolumes(): array { return $this->volumes; } @@ -43,7 +40,7 @@ protected function mountVolumes($opts) if (isset($o['service'])) { $driver = $o['service']; - if (is_object($driver) && $driver instanceof elFinderVolumeDriver) { + if ($driver instanceof elFinderVolumeDriver) { $volume = $driver; unset($opts['roots'][$i]); } diff --git a/src/Command/ElFinderInstallerCommand.php b/src/Command/ElFinderInstallerCommand.php index d1e1751..d97651d 100644 --- a/src/Command/ElFinderInstallerCommand.php +++ b/src/Command/ElFinderInstallerCommand.php @@ -3,6 +3,7 @@ namespace FM\ElfinderBundle\Command; use ReflectionClass; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -11,6 +12,10 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Filesystem\Filesystem; +#[AsCommand( + name: 'elfinder:install', + description: 'Copies elfinder assets to public directory', +)] final class ElFinderInstallerCommand extends Command { private const ELFINDER_CSS_DIR = 'vendor/studio-42/elfinder/css'; @@ -21,22 +26,16 @@ final class ElFinderInstallerCommand extends Command private const ELFINDER_IMG_DIR = 'vendor/studio-42/elfinder/img'; - protected $fileSystem; - - protected $parameterBag; - - public function __construct(Filesystem $filesystem, ParameterBagInterface $parameterBag) - { - $this->fileSystem = $filesystem; - $this->parameterBag = $parameterBag; + public function __construct( + protected Filesystem $fileSystem, + protected ParameterBagInterface $parameterBag + ) { parent::__construct(); } protected function configure(): void { $this - ->setName('elfinder:install') - ->setDescription('Copies elfinder assets to public directory') ->addOption('docroot', null, InputOption::VALUE_OPTIONAL, 'Website document root.', 'public') ->setHelp(<<<'EOF' Default docroot: diff --git a/src/Configuration/ElFinderConfigurationReader.php b/src/Configuration/ElFinderConfigurationReader.php index f1d0598..436f709 100644 --- a/src/Configuration/ElFinderConfigurationReader.php +++ b/src/Configuration/ElFinderConfigurationReader.php @@ -28,22 +28,15 @@ use Symfony\Component\HttpFoundation\RequestStack; use TypeError; -/** - * Class ElFinderConfigurationReader. - */ class ElFinderConfigurationReader implements ElFinderConfigurationProviderInterface { - /** @var array */ - protected $options = []; + protected array $options = []; - /** @var array */ - protected $parameters; + protected array $parameters; - /** @var RequestStack */ - protected $requestStack; + protected RequestStack $requestStack; - /** @var ContainerInterface */ - protected $container; + protected ContainerInterface $container; public function __construct(array $parameters, RequestStack $requestStack, ContainerInterface $container) { @@ -335,7 +328,7 @@ private function configureFlysystem($opt, $adapter, $serviceName) return $filesystem; } - private function getFlysystemFilesystem(string $serviceName) + private function getFlysystemFilesystem(string $serviceName): Filesystem { $filesystem = $this->container->get($serviceName); diff --git a/src/Connector/ElFinderConnector.php b/src/Connector/ElFinderConnector.php index f04c82a..6bc63b8 100644 --- a/src/Connector/ElFinderConnector.php +++ b/src/Connector/ElFinderConnector.php @@ -69,7 +69,7 @@ public function execute($queryParameters) $args[$name] = $arg; } - $args['debug'] = isset($src['debug']) ? (bool) $src['debug'] : false; + $args['debug'] = isset($src['debug']) && $src['debug']; return $this->output($this->elFinder->exec($cmd, $this->input_filter($args))); } @@ -78,8 +78,8 @@ protected function output(array $data) { if (isset($data['pointer'])) { parent::output($data); - } else { - return $data; } + + return $data; } } diff --git a/src/Controller/ElFinderController.php b/src/Controller/ElFinderController.php index 62c3405..d6aa04d 100644 --- a/src/Controller/ElFinderController.php +++ b/src/Controller/ElFinderController.php @@ -6,6 +6,7 @@ use FM\ElfinderBundle\Event\ElFinderPostExecutionEvent; use FM\ElfinderBundle\Event\ElFinderPreExecutionEvent; use FM\ElfinderBundle\Loader\ElFinderLoader; +use FM\ElfinderBundle\Loader\ElFinderLoaderInterface; use FM\ElfinderBundle\Session\ElFinderSession; use Symfony\Component\Asset\Package; use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy; @@ -20,11 +21,11 @@ class ElFinderController { + protected array $params; private Environment $twig; - private array $params; - private $loader; + private ElFinderLoaderInterface $loader; - public function __construct(Environment $twig, array $params, $loader) + public function __construct(Environment $twig, array $params, ElFinderLoaderInterface $loader) { $this->twig = $twig; $this->params = $params; @@ -77,7 +78,7 @@ public function load(SessionInterface $session, HttpKernelInterface $httpKernel, return new JsonResponse($postExecutionEvent->getResult()); } - public function mainJS() + public function mainJS(): Response { $version = new EmptyVersionStrategy(); $package = new Package($version); diff --git a/src/ElFinder/ElFinder.php b/src/ElFinder/ElFinder.php index e430c88..8949485 100644 --- a/src/ElFinder/ElFinder.php +++ b/src/ElFinder/ElFinder.php @@ -6,9 +6,6 @@ use elFinderSession; use elFinderSessionInterface; -/** - * Class ElFinder. - */ class ElFinder extends BaseElFinder { /** diff --git a/src/Event/ElFinderPostExecutionEvent.php b/src/Event/ElFinderPostExecutionEvent.php index 60e6e24..8b4c0a4 100644 --- a/src/Event/ElFinderPostExecutionEvent.php +++ b/src/Event/ElFinderPostExecutionEvent.php @@ -7,20 +7,13 @@ class ElFinderPostExecutionEvent extends ElFinderPreExecutionEvent { - /** - * Command execution result. - * - * @var array - */ - protected $result; + /** Command execution result. */ + protected array $result; /** * Constructor. - * - * @param string $instance - * @param string $homeFolder */ - public function __construct(Request $request, HttpKernelInterface $httpKernel, $instance, $homeFolder, array $result = null) + public function __construct(Request $request, HttpKernelInterface $httpKernel, string $instance, string $homeFolder, array $result = null) { parent::__construct($request, $httpKernel, $instance, $homeFolder); @@ -29,23 +22,18 @@ public function __construct(Request $request, HttpKernelInterface $httpKernel, $ /** * Tells if execution has encountered errors. - * - * @return bool */ - public function hasErrors() + public function hasErrors(): bool { return isset($this->result['error']); } - /** - * @return array - */ - public function getResult() + public function getResult(): array { return $this->result; } - public function setResult(array $result) + public function setResult(array $result): void { $this->result = $result; } diff --git a/src/Event/ElFinderPreExecutionEvent.php b/src/Event/ElFinderPreExecutionEvent.php index 93a18f5..4c911da 100644 --- a/src/Event/ElFinderPreExecutionEvent.php +++ b/src/Event/ElFinderPreExecutionEvent.php @@ -8,41 +8,19 @@ class ElFinderPreExecutionEvent extends Event { - /** - * Request object containing ElFinder command and parameters. - * - * @var Request - */ - protected $request; + /** Request object containing ElFinder command and parameters. */ + protected Request $request; - /** - * ElFinder instance. - * - * @var string - */ - protected $instance; + /** ElFinder instance. */ + protected string $instance; - /** - * Home folder. - * - * @var string - */ - protected $homeFolder; + /** Home folder. */ + protected string $homeFolder; - /** - * Used to make sub requests. - * - * @var HttpKernelInterface - */ - private $httpKernel; + /** Used to make sub requests. */ + private HttpKernelInterface $httpKernel; - /** - * Constructor. - * - * @param string $instance - * @param string $homeFolder - */ - public function __construct(Request $request, HttpKernelInterface $httpKernel, $instance, $homeFolder) + public function __construct(Request $request, HttpKernelInterface $httpKernel, string $instance, string $homeFolder) { $this->request = $request; $this->httpKernel = $httpKernel; @@ -59,7 +37,7 @@ public function __construct(Request $request, HttpKernelInterface $httpKernel, $ * @param array $path An array of path parameters * @param array $query An array of query parameters * - * @return Symfony\Component\HttpFoundation\Response A Response instance + * @return \Symfony\Component\HttpFoundation\Response A Response instance */ public function subRequest(array $path, array $query) { @@ -71,34 +49,23 @@ public function subRequest(array $path, array $query) /** * Returns executed command. - * - * @return string */ - public function getCommand() + public function getCommand(): string { return $this->request->get('cmd'); } - /** - * @return Request - */ - public function getRequest() + public function getRequest(): Request { return $this->request; } - /** - * @return string - */ - public function getInstance() + public function getInstance(): string { return $this->instance; } - /** - * @return string - */ - public function getHomeFolder() + public function getHomeFolder(): string { return $this->homeFolder; } diff --git a/src/FMElfinderBundle.php b/src/FMElfinderBundle.php index 95248e6..4a83d01 100644 --- a/src/FMElfinderBundle.php +++ b/src/FMElfinderBundle.php @@ -7,9 +7,6 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; -/** - * Class FMElfinderBundle. - */ class FMElfinderBundle extends Bundle { public function build(ContainerBuilder $container): void diff --git a/src/Form/Type/ElFinderType.php b/src/Form/Type/ElFinderType.php index 8df3d35..46f3188 100644 --- a/src/Form/Type/ElFinderType.php +++ b/src/Form/Type/ElFinderType.php @@ -67,7 +67,7 @@ public function getParent(): ?string /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return $this->getBlockPrefix(); } diff --git a/src/Loader/ElFinderLoader.php b/src/Loader/ElFinderLoader.php index 9290f64..ff2feb7 100644 --- a/src/Loader/ElFinderLoader.php +++ b/src/Loader/ElFinderLoader.php @@ -9,25 +9,17 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\SessionInterface; -/** - * Class ElFinderLoader. - */ -class ElFinderLoader +class ElFinderLoader implements ElFinderLoaderInterface { - /** @var string */ - protected $instance; + protected string $instance; - /** @var ElFinderConfigurationProviderInterface */ - protected $configurator; + protected ElFinderConfigurationProviderInterface $configurator; - /** @var array */ - protected $config; + protected array $config; - /** @var ElFinderBridge */ - protected $bridge; + protected ElFinderBridge $bridge; - /** @var SessionInterface */ - protected $session; + protected ?SessionInterface $session; public function __construct(ElFinderConfigurationProviderInterface $configurator) { @@ -36,28 +28,19 @@ public function __construct(ElFinderConfigurationProviderInterface $configurator /** * @throws Exception - * - * @return array */ - public function configure() + public function configure(): array { $configurator = $this->configurator; - if (!($configurator instanceof ElFinderConfigurationProviderInterface)) { - throw new Exception('Configurator class must implement ElFinderConfigurationProviderInterface'); - } - return $configurator->getConfiguration($this->instance); } /** * Configure the Bridge to ElFinder. - * - * @var string - * * @throws Exception */ - public function initBridge($instance, array $efParameters) + public function initBridge(string $instance, array $efParameters): void { $this->setInstance($instance); @@ -86,12 +69,8 @@ public function initBridge($instance, array $efParameters) /** * Starts ElFinder. - * - * @var Request - * - * @return void|array */ - public function load(Request $request) + public function load(Request $request): array|string { $connector = new ElFinderConnector($this->bridge); @@ -102,26 +81,20 @@ public function load(Request $request) return $connector->run($request->query->all()); } - /** - * @param string $instance - */ - public function setInstance($instance) + public function setInstance(string $instance): void { $this->instance = $instance; } - public function setConfigurator(ElFinderConfigurationProviderInterface $configurator) + public function setConfigurator(ElFinderConfigurationProviderInterface $configurator): void { $this->configurator = $configurator; } /** * Encode path into hash. - * - * @param string $path - * - **/ - public function encode($path) + */ + public function encode(string $path): mixed { $aPathEncoded = []; @@ -142,12 +115,8 @@ public function encode($path) /** * Decode path from hash. - * - * @param string $hash - * - * @return string - **/ - public function decode($hash) + */ + public function decode(string $hash): string { $volume = $this->bridge->getVolume($hash); @@ -155,7 +124,7 @@ public function decode($hash) return (!empty($volume)) ? $volume->getPath($hash) : false; } - public function setSession($session) + public function setSession(?SessionInterface $session): void { $this->session = $session; } diff --git a/src/Loader/ElFinderLoaderInterface.php b/src/Loader/ElFinderLoaderInterface.php new file mode 100644 index 0000000..94953be --- /dev/null +++ b/src/Loader/ElFinderLoaderInterface.php @@ -0,0 +1,37 @@ + array('rm','delete')); * First items (roles) in array has higher priority. - * - * @return array */ - public function getConfiguration(); + public function getConfiguration(): array; } diff --git a/src/Session/ElFinderSession.php b/src/Session/ElFinderSession.php index f7d4a37..79cd308 100644 --- a/src/Session/ElFinderSession.php +++ b/src/Session/ElFinderSession.php @@ -7,8 +7,7 @@ class ElFinderSession implements elFinderSessionInterface { - /** @var SessionInterface */ - protected $session; + protected SessionInterface $session; public function __construct(SessionInterface $session) { diff --git a/src/Twig/Extension/FMElfinderExtension.php b/src/Twig/Extension/FMElfinderExtension.php index 6b2da26..7755d0a 100644 --- a/src/Twig/Extension/FMElfinderExtension.php +++ b/src/Twig/Extension/FMElfinderExtension.php @@ -23,7 +23,7 @@ public function __construct(Environment $twig) * * @return array */ - public function getFunctions() + public function getFunctions(): array { $options = ['is_safe' => ['html']]; @@ -40,7 +40,7 @@ public function getFunctions() * @throws RuntimeError * @throws SyntaxError */ - public function tinymce(string $instance = 'default', array $parameters = ['width' => 900, 'height' => 450, 'title' => 'elFinder 2.0']) + public function tinymce(string $instance = 'default', array $parameters = ['width' => 900, 'height' => 450, 'title' => 'elFinder 2.0']): string { if (!is_string($instance)) { throw new RuntimeError('The function can be applied to strings only.'); @@ -50,9 +50,9 @@ public function tinymce(string $instance = 'default', array $parameters = ['widt '@FMElfinder/Elfinder/helper/_tinymce.html.twig', [ 'instance' => $instance, - 'width' => $parameters['width'], - 'height' => $parameters['height'], - 'title' => $parameters['title'], + 'width' => $parameters['width'], + 'height' => $parameters['height'], + 'title' => $parameters['title'], ] ); } @@ -68,9 +68,9 @@ public function tinymce4(string $instance = 'default', array $parameters = ['wid '@FMElfinder/Elfinder/helper/_tinymce4.html.twig', [ 'instance' => $instance, - 'width' => $parameters['width'], - 'height' => $parameters['height'], - 'title' => $parameters['title'], + 'width' => $parameters['width'], + 'height' => $parameters['height'], + 'title' => $parameters['title'], ] ); } @@ -89,16 +89,19 @@ public function tinymce5(string $instance = 'default'): string * @throws RuntimeError * @throws SyntaxError */ - public function summernote(string $instance = 'default', string $selector = '.summenote', array $parameters = ['width' => 900, 'height' => 450, 'title' => 'elFinder 2.0']): string - { + public function summernote( + string $instance = 'default', + string $selector = '.summernote', + array $parameters = ['width' => 900, 'height' => 450, 'title' => 'elFinder 2.0'] + ): string { return $this->twig->render( '@FMElfinder/Elfinder/helper/_summernote.html.twig', [ 'instance' => $instance, 'selector' => $selector, - 'width' => $parameters['width'], - 'height' => $parameters['height'], - 'title' => $parameters['title'], + 'width' => $parameters['width'], + 'height' => $parameters['height'], + 'title' => $parameters['title'], ] ); } diff --git a/tests/Command/ElFinderInstallerCommandTest.php b/tests/Command/ElFinderInstallerCommandTest.php new file mode 100644 index 0000000..88f985c --- /dev/null +++ b/tests/Command/ElFinderInstallerCommandTest.php @@ -0,0 +1,98 @@ +vendorDir = dirname($reflection->getFileName(), 3) . DIRECTORY_SEPARATOR . 'vendor'; + $this->projectDir = dirname($this->vendorDir); + + $this->fileSystem = $this->createMock(Filesystem::class); + $this->parameterBag = $this->createMock(ParameterBagInterface::class); + + $this->parameterBag + ->method('get') + ->willReturnMap([ + ['kernel.project_dir', $this->projectDir] + ]); + + $application = new Application(); + $command = new ElFinderInstallerCommand($this->fileSystem, $this->parameterBag); + $application->add($command); + + $this->commandTester = new CommandTester($application->find('elfinder:install')); + } + + public function testExecuteWithDefaultDocroot(): void + { + $this->assertFileSystemOperations('public'); + $this->commandTester->execute([]); + $this->assertCommandOutput(); + $this->assertEquals(0, $this->commandTester->getStatusCode()); + } + + public function testExecuteWithCustomDocroot(): void + { + $this->assertFileSystemOperations('custom'); + $this->commandTester->execute(['--docroot' => 'custom']); + $this->assertCommandOutput(); + $this->assertEquals(0, $this->commandTester->getStatusCode()); + } + + private function assertFileSystemOperations(string $docroot): void + { + $expectedCalls = [ + [ + $this->vendorDir . '/studio-42/elfinder/css', + $this->projectDir . "/$docroot/bundles/fmelfinder/css" + ], + [ + $this->vendorDir . '/studio-42/elfinder/img', + $this->projectDir . "/$docroot/bundles/fmelfinder/img" + ], + [ + $this->vendorDir . '/studio-42/elfinder/js', + $this->projectDir . "/$docroot/bundles/fmelfinder/js" + ], + [ + $this->vendorDir . '/studio-42/elfinder/sounds', + $this->projectDir . "/$docroot/bundles/fmelfinder/sounds" + ] + ]; + + $callIndex = 0; + $this->fileSystem + ->expects($this->exactly(4)) + ->method('mirror') + ->willReturnCallback(function ($source, $target) use (&$callIndex, $expectedCalls) { + $this->assertEquals($expectedCalls[$callIndex][0], $source, "Incorrect source path for call $callIndex"); + $this->assertEquals($expectedCalls[$callIndex][1], $target, "Incorrect target path for call $callIndex"); + $callIndex++; + }); + } + + private function assertCommandOutput(): void + { + $output = $this->commandTester->getDisplay(); + $this->assertStringContainsString('elFinder Installer', $output); + $this->assertStringContainsString('elFinder assets successfully installed', $output); + } +} diff --git a/tests/Configuration/ElFinderConfigurationReaderTest.php b/tests/Configuration/ElFinderConfigurationReaderTest.php index 817da1f..a5635ab 100644 --- a/tests/Configuration/ElFinderConfigurationReaderTest.php +++ b/tests/Configuration/ElFinderConfigurationReaderTest.php @@ -32,13 +32,13 @@ private function getConfigurationReader($attributesObject) $containerMock ->expects($this->any()) ->method('get') - ->will($this->returnValueMap([ + ->willReturnMap([ [ 'elfinder.driver.local', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $this->elFinderVolumeMock, ], - ])); + ]); /** @var \Symfony\Component\HttpFoundation\RequestStack $requestStack|\PHPUnit_Framework_MockObject_MockObject */ $requestStack = $this->createMock('Symfony\Component\HttpFoundation\RequestStack'); @@ -48,22 +48,22 @@ private function getConfigurationReader($attributesObject) $requestObject ->expects($this->any()) ->method('getScheme') - ->will($this->returnValue('http')); + ->willReturn('http'); $requestObject ->expects($this->any()) ->method('getHttpHost') - ->will($this->returnValue('test.com')); + ->willReturn('test.com'); $requestObject ->expects($this->any()) ->method('getBaseUrl') - ->will($this->returnValue('/unit-test')); + ->willReturn('/unit-test'); $requestObject->attributes = $attributesObject; $requestStack ->expects($this->any()) ->method('getCurrentRequest') - ->will($this->returnValue($requestObject)); + ->willReturn($requestObject); $params = [ 'instances' => [ @@ -298,7 +298,7 @@ private function getDefaultAttributesObject() $attributesObject ->expects($this->any()) ->method('get') - ->will($this->returnValue('')); + ->willReturn(''); return $attributesObject; } @@ -311,7 +311,7 @@ private function getHomeFolderAwareAttributesObject() ->expects($this->any()) ->method('get') ->with($this->equalTo('homeFolder')) - ->will($this->returnValue('bob')); + ->willReturn('bob'); return $attributesObject; } diff --git a/tests/DependencyInjection/ConfigurationLoadTest.php b/tests/DependencyInjection/ConfigurationLoadTest.php index cdea321..ca1df89 100644 --- a/tests/DependencyInjection/ConfigurationLoadTest.php +++ b/tests/DependencyInjection/ConfigurationLoadTest.php @@ -5,6 +5,7 @@ use FM\ElfinderBundle\DependencyInjection\FMElfinderExtension; use FM\ElfinderBundle\DependencyInjection\Configuration; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionConfigurationTestCase; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; @@ -20,11 +21,8 @@ protected function getConfiguration(): ConfigurationInterface return new Configuration(); } - /** - * @dataProvider getSupportsAllConfigFormatsData - * @requires PHP 7 - */ - public function testSupportsAllConfigFormats($path) + #[DataProvider('getSupportsAllConfigFormatsData')] + public function testSupportsAllConfigFormats($path): void { $expectedConfiguration = [ 'configuration_provider' => 'app.configurator.custom', @@ -186,7 +184,7 @@ public function testSupportsAllConfigFormats($path) $this->assertProcessedConfigurationEquals($expectedConfiguration, [__DIR__.'/../Fixtures/'.$path]); } - public function getSupportsAllConfigFormatsData() + public static function getSupportsAllConfigFormatsData(): array { return [ 'yml' => ['config/config.yml'], diff --git a/tests/Loader/ElFinderLoaderTest.php b/tests/Loader/ElFinderLoaderTest.php index fde2aaa..b10032b 100644 --- a/tests/Loader/ElFinderLoaderTest.php +++ b/tests/Loader/ElFinderLoaderTest.php @@ -16,7 +16,7 @@ public function setUp(): void $this->configuratorMock = $this->createMock(ElFinderConfigurationProviderInterface::class); $this->configuratorMock->expects($this->any()) ->method('getConfiguration') - ->will($this->returnValue(['parameters' => []])); + ->willReturn(['parameters' => []]); $this->loader = new ElFinderLoader($this->configuratorMock); $this->loader->setInstance('minimal'); }