diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index c4604b9..f192e96 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -24,6 +24,7 @@ jobs: php-version: - 8.3 - 8.4 + - 8.5 dependencies: - "highest" symfony_version: @@ -36,29 +37,39 @@ jobs: - symfony_version: "6.4.*" php-version: "8.4" dependencies: "highest" + - symfony_version: "6.4.*" + php-version: "8.5" + dependencies: "highest" + + # Test against latest Symfony 7.4 + - symfony_version: "7.4.*" + php-version: "8.3" + dependencies: "highest" + - symfony_version: "7.4.*" + php-version: "8.4" + dependencies: "highest" + - symfony_version: "7.4.*" + php-version: "8.5" + dependencies: "highest" # Test against the highest dependencies - php-version: "8.3" dependencies: "highest" - php-version: "8.4" dependencies: "highest" + - php-version: "8.5" + dependencies: "highest" steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: ${{ matrix.php-versions }} + php-version: ${{ matrix.php-version }} coverage: pcov - ini-values: "zend.assertions=1" - - - name: "symfony/flex is required to install the correct symfony version" - if: ${{ matrix.symfony_version }} - run: | - composer global config --no-plugins allow-plugins.symfony/flex true - composer global require symfony/flex + tools: flex - name: "Configure Symfony version for symfony/flex" if: ${{ matrix.symfony_version }} diff --git a/Makefile b/Makefile index d38be2c..f96805d 100644 --- a/Makefile +++ b/Makefile @@ -20,16 +20,10 @@ coding-standard-fix: .PHONY: static-analysis static-analysis: ## Run static analysis checks ./vendor/bin/phpstan --configuration=config/phpstan.neon --memory-limit=256M - ./vendor/bin/psalm --config config/psalm.xml --no-cache .PHONY: static-analysis-update static-analysis-update: ## Update static analysis baselines ./vendor/bin/phpstan --configuration=config/phpstan.neon --generate-baseline=config/phpstan-baseline.neon --allow-empty-baseline - ./vendor/bin/psalm --config config/psalm.xml --set-baseline=psalm.baseline.xml --show-info=true --no-cache - -.PHONY: security-analysis -security-analysis: ## Run static analysis security checks - ./vendor/bin/psalm -c config/psalm.xml --taint-analysis .PHONY: unit-tests unit-tests: ## Run unit test suite @@ -40,4 +34,4 @@ composer-validate: ./vendor/bin/composer validate .PHONY: check -check: coding-standard-check static-analysis security-analysis unit-tests ## Run all checks for local development iterations +check: coding-standard-check static-analysis unit-tests ## Run all checks for local development iterations diff --git a/composer.json b/composer.json index 6fdf5a3..a35068e 100644 --- a/composer.json +++ b/composer.json @@ -17,29 +17,26 @@ ], "homepage": "https://github.com/protung/cloudinary-bundle", "require": { - "php": "~8.3.0 || ~8.4.0", - "azjezz/psl": "^3.0.0", + "php": "~8.3.0 || ~8.4.0 || ~8.5.0", + "azjezz/psl": "^3.0.0 || ^4.0.0", "cloudinary/cloudinary_php": "^3.1.1", - "symfony/console": "^6.4 || ^7.2", - "symfony/finder": "^6.4 || ^7.2", - "symfony/framework-bundle": "^6.4 || ^7.2", - "symfony/yaml": "^6.4 || ^7.2" + "symfony/console": "^6.4 || ^7.2 || ^8.0", + "symfony/finder": "^6.4 || ^7.2 || ^8.0", + "symfony/framework-bundle": "^6.4 || ^7.2 || ^8.0", + "symfony/yaml": "^6.4 || ^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^13.0", - "ergebnis/composer-normalize": "^2.47.0", - "php-standard-library/phpstan-extension": "^2.0.0", - "php-standard-library/psalm-plugin": "^2.3", - "phpstan/phpstan": "^2.1.17", + "doctrine/coding-standard": "^14.0.0", + "ergebnis/composer-normalize": "^2.48.2", + "php-standard-library/phpstan-extension": "^2.0.2", + "phpstan/phpstan": "^2.1.33", "phpstan/phpstan-deprecation-rules": "^2.0.3", - "phpstan/phpstan-phpunit": "^2.0.6", - "phpstan/phpstan-strict-rules": "^2.0.4", - "phpstan/phpstan-symfony": "^2.0.6", - "phpunit/phpunit": "^12.2.6", - "psalm/plugin-phpunit": "^0.19.5", + "phpstan/phpstan-phpunit": "^2.0.10", + "phpstan/phpstan-strict-rules": "^2.0.7", + "phpstan/phpstan-symfony": "^2.0.9", + "phpunit/phpunit": "^12.5.1", "roave/security-advisories": "dev-latest", - "twig/twig": "^3.21", - "vimeo/psalm": "^6.12.1" + "twig/twig": "^3.22.1" }, "suggest": { "twig/twig": "Allow to use the cloudinary_url function/filter" diff --git a/config/phpstan-baseline.neon b/config/phpstan-baseline.neon index b0cd96c..c3e0f81 100644 --- a/config/phpstan-baseline.neon +++ b/config/phpstan-baseline.neon @@ -1,55 +1,61 @@ parameters: ignoreErrors: - - message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + rawMessage: 'Argument of an invalid type mixed supplied for foreach, only iterables are supported.' identifier: foreach.nonIterable count: 1 path: ../src/Command/DeleteCommand.php - - message: '#^Parameter \#1 \$prefix of method Cloudinary\\Api\\Admin\\AdminApi\:\:deleteAssetsByPrefix\(\) expects string, mixed given\.$#' + rawMessage: 'Parameter #1 $prefix of method Cloudinary\Api\Admin\AdminApi::deleteAssetsByPrefix() expects string, mixed given.' identifier: argument.type count: 1 path: ../src/Command/DeleteCommand.php - - message: '#^Parameter \#1 \$publicIds of method Cloudinary\\Api\\Admin\\AdminApi\:\:deleteAssets\(\) expects array\|string, mixed given\.$#' + rawMessage: 'Parameter #1 $publicIds of method Cloudinary\Api\Admin\AdminApi::deleteAssets() expects array|string, mixed given.' identifier: argument.type count: 1 path: ../src/Command/DeleteCommand.php - - message: '#^Parameter \#2 \.\.\.\$args of function Psl\\Str\\format expects float\|int\|string, mixed given\.$#' + rawMessage: 'Parameter #2 ...$args of function Psl\Str\format expects float|int|string, mixed given.' identifier: argument.type count: 2 path: ../src/Command/DeleteCommand.php - - message: '#^Parameter \#1 \$publicId of method Cloudinary\\Api\\Admin\\AdminApi\:\:asset\(\) expects string, mixed given\.$#' + rawMessage: 'Parameter #1 $publicId of method Cloudinary\Api\Admin\AdminApi::asset() expects string, mixed given.' identifier: argument.type count: 1 path: ../src/Command/InfoCommand.php - - message: '#^Parameter \#2 \$derivedResources of method Speicher210\\CloudinaryBundle\\Command\\InfoCommand\:\:renderDerivedResources\(\) expects array\, mixed given\.$#' + rawMessage: 'Parameter #2 $derivedResources of method Speicher210\CloudinaryBundle\Command\InfoCommand::renderDerivedResources() expects array, mixed given.' identifier: argument.type count: 1 path: ../src/Command/InfoCommand.php - - message: '#^Parameter \#1 \$dirs of method Symfony\\Component\\Finder\\Finder\:\:in\(\) expects array\\|string, mixed given\.$#' + rawMessage: 'Parameter #1 $dirs of method Symfony\Component\Finder\Finder::in() expects array|string, mixed given.' identifier: argument.type count: 1 path: ../src/Command/UploadCommand.php - - message: '#^Parameter \#1 \$node of function Psl\\Filesystem\\get_filename expects non\-empty\-string, string given\.$#' + rawMessage: 'Parameter #1 $node of function Psl\Filesystem\get_filename expects non-empty-string, string given.' identifier: argument.type count: 1 path: ../src/Command/UploadCommand.php - - message: '#^Parameter \#1 \$patterns of method Symfony\\Component\\Finder\\Finder\:\:name\(\) expects array\\|string, mixed given\.$#' + rawMessage: 'Parameter #1 $patterns of method Symfony\Component\Finder\Finder::name() expects array|string, mixed given.' identifier: argument.type count: 1 path: ../src/Command/UploadCommand.php + + - + rawMessage: 'Method Speicher210\CloudinaryBundle\DependencyInjection\Configuration::getConfigTreeBuilder() return type with generic class Symfony\Component\Config\Definition\Builder\TreeBuilder does not specify its types: T' + identifier: missingType.generics + count: 1 + path: ../src/DependencyInjection/Configuration.php diff --git a/config/psalm.baseline.xml b/config/psalm.baseline.xml deleted file mode 100644 index a0930ad..0000000 --- a/config/psalm.baseline.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - getFilename()]]> - - - - - - - - diff --git a/config/psalm.xml b/config/psalm.xml deleted file mode 100644 index f193278..0000000 --- a/config/psalm.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/DependencyInjection/Speicher210CloudinaryExtension.php b/src/DependencyInjection/Speicher210CloudinaryExtension.php index 3b414c8..a7bae84 100644 --- a/src/DependencyInjection/Speicher210CloudinaryExtension.php +++ b/src/DependencyInjection/Speicher210CloudinaryExtension.php @@ -19,8 +19,8 @@ final class Speicher210CloudinaryExtension extends ConfigurableExtension #[Override] protected function loadInternal(array $mergedConfig, ContainerBuilder $container): void { - $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); - $loader->load('services.xml'); + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + $loader->load('services.yaml'); $container ->getDefinition(CloudinaryFactory::class) diff --git a/src/Factory/CloudinaryFactory.php b/src/Factory/CloudinaryFactory.php index 1a3647e..570d0db 100644 --- a/src/Factory/CloudinaryFactory.php +++ b/src/Factory/CloudinaryFactory.php @@ -10,9 +10,9 @@ use function array_key_exists; use function parse_url; -final class CloudinaryFactory +final readonly class CloudinaryFactory { - private readonly Configuration $configuration; + private Configuration $configuration; /** * @param array{url?: string, cloud_name?: string, access_identifier?: array{api_key: string, api_secret: string}, secure?: bool} $config diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml deleted file mode 100644 index d06b47c..0000000 --- a/src/Resources/config/services.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml new file mode 100644 index 0000000..fa3170b --- /dev/null +++ b/src/Resources/config/services.yaml @@ -0,0 +1,51 @@ +services: + Speicher210\CloudinaryBundle\Factory\CloudinaryFactory: + public: false + arguments: + - [ ] + + speicher210_cloudinary.cloudinary: + class: Speicher210\CloudinaryBundle\Cloudinary\Cloudinary + public: true + factory: [ '@Speicher210\CloudinaryBundle\Factory\CloudinaryFactory', 'createCloudinary' ] + + Cloudinary\Cloudinary: + alias: speicher210_cloudinary.cloudinary + public: true + + speicher210_cloudinary.uploader: + class: Speicher210\CloudinaryBundle\Cloudinary\Uploader + public: true + factory: [ '@speicher210_cloudinary.cloudinary', 'uploadApi' ] + + speicher210_cloudinary.admin: + class: Speicher210\CloudinaryBundle\Cloudinary\Admin + public: true + factory: [ '@speicher210_cloudinary.cloudinary', 'adminApi' ] + + twig.extension.cloudinary: + class: Speicher210\CloudinaryBundle\Twig\Extension\CloudinaryExtension + public: true + arguments: + - '@speicher210_cloudinary.cloudinary' + tags: + - { name: 'twig.extension' } + + Speicher210\CloudinaryBundle\Command\DeleteCommand: + arguments: + - '@speicher210_cloudinary.admin' + tags: + - { name: 'console.command' } + + Speicher210\CloudinaryBundle\Command\InfoCommand: + arguments: + - '@speicher210_cloudinary.admin' + tags: + - { name: 'console.command' } + + Speicher210\CloudinaryBundle\Command\UploadCommand: + arguments: + - '@speicher210_cloudinary.uploader' + tags: + - { name: 'console.command' } +