From 3425260b296f5367dda46e36fdd7cf82bd3428e7 Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Tue, 2 Jan 2024 11:06:54 -0600 Subject: [PATCH 01/10] remove unsupported dependencies --- composer.json | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/composer.json b/composer.json index 2b6c5c59..aabb9811 100644 --- a/composer.json +++ b/composer.json @@ -22,37 +22,36 @@ } }, "require": { - "php": "^8.0", + "php": "^8.1", "ext-mbstring": "*", "imagine/imagine": "^1.3.2", - "symfony/filesystem": "^5.3|^6.0|^7.0", - "symfony/finder": "^5.3|^6.0|^7.0", - "symfony/framework-bundle": "^5.3|^6.0|^7.0", - "symfony/mime": "^5.3|^6.0|^7.0", - "symfony/options-resolver": "^5.3|^6.0|^7.0", - "symfony/process": "^5.3|^6.0|^7.0", + "symfony/filesystem": "^5.4|^6.4|^7.0", + "symfony/finder": "^5.4|^6.4|^7.0", + "symfony/framework-bundle": "^5.4|^6.4|^7.0", + "symfony/mime": "^5.4|^6.4|^7.0", + "symfony/options-resolver": "^5.4|^6.4|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", "twig/twig": "^2.9|^3.0" }, "require-dev": { "ext-gd": "*", "amazonwebservices/aws-sdk-for-php": "^1.0", - "aws/aws-sdk-php": "^2.4|^3.0", - "doctrine/persistence": "^1.3|^2.0", - "league/flysystem": "^1.0|^2.0|^3.0", + "aws/aws-sdk-php": "^3.0", + "doctrine/persistence": "^2.0", + "league/flysystem": "^3.0", "phpstan/phpstan": "^1.10", "phpstan/phpstan-symfony": "^1.0", - "psr/cache": "^1.0|^2.0|^3.0", - "psr/log": "^1.0", - "symfony/browser-kit": "^5.3|^6.0|^7.0", - "symfony/cache": "^5.3|^6.0|^7.0", - "symfony/console": "^5.3|^6.0|^7.0", - "symfony/dependency-injection": "^5.3|^6.0|^7.0", - "symfony/form": "^5.3|^6.0|^7.0", - "symfony/messenger": "^5.3|^6.0|^7.0", - "symfony/phpunit-bridge": "^5.3|^6.0|^7.0", - "symfony/templating": "^5.3|^6.0|^7.0", - "symfony/validator": "^5.3|^6.0|^7.0", - "symfony/yaml": "^5.3|^6.0|^7.0" + "psr/cache": "^3.0", + "psr/log": "^1.0|^2.0|^3,0", + "symfony/browser-kit": "^5.4|^6.4|^7.0", + "symfony/cache": "^5.4|^6.4|^7.0", + "symfony/console": "^5.4|^6.4|^7.0", + "symfony/dependency-injection": "^5.4|^6.4|^7.0", + "symfony/form": "^5.4|^6.4|^7.0", + "symfony/messenger": "^5.4|^6.4|^7.0", + "symfony/phpunit-bridge": "^5.4|^6.4|^7.0", + "symfony/validator": "^5.4|^6.4|^7.0", + "symfony/yaml": "^5.4|^6.4|^7.0" }, "suggest": { "ext-exif": "required to read EXIF metadata from images", @@ -67,8 +66,7 @@ "league/flysystem": "required to use FlySystem data loader or cache resolver", "monolog/monolog": "A psr/log compatible logger is required to enable logging", "rokka/imagine-vips": "required to use 'vips' driver", - "symfony/messenger": "If you like to process images in background", - "symfony/templating": "required to use deprecated Templating component instead of Twig" + "symfony/messenger": "If you like to process images in background" }, "config": { "sort-packages": true From 77919de75e986621e39b8314b1128b72a9d4024a Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Tue, 2 Jan 2024 11:19:05 -0600 Subject: [PATCH 02/10] cleanup README, drop php templating and use DI instead of injecting the container --- README.md | 77 +++++++++++++++---------------------------------------- 1 file changed, 20 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index b6b52ab1..c5e5d3cb 100644 --- a/README.md +++ b/README.md @@ -115,8 +115,8 @@ our [data loaders](http://symfony.com/doc/current/bundles/LiipImagineBundle/data and [cache resolvers](http://symfony.com/doc/current/bundles/LiipImagineBundle/cache-resolvers.html) operate correctly. Use the following boilerplate in your configuration file. -```yml -# app/config/config.yml +```yaml +# config/packages/liip_imagine.yaml liip_imagine : @@ -149,7 +149,7 @@ name `my_thumb`) with two *filters* configured: the `thumbnail` and `background` *filters*. ```yml -# app/config/config.yml +# config/packages/liip_imagine.yaml liip_imagine : resolvers : @@ -193,18 +193,10 @@ There are a number of additional [filters](http://symfony.com/doc/current/bundle but for now you can use your newly defined ``my_thumb`` *filter set* immediately within a template. -*For Twig-based template, use:* - ```twig ``` -*Or, for PHP-based template, use:* - -```php - -``` - Behind the scenes, the bundle applies the filter(s) to the image on-the-fly when the first page request is served. The transformed image is then cached for subsequent requests. The final cached image path would be similar to @@ -217,7 +209,7 @@ rendered via the template helper. This is often caused by having images are rendered, it is strongly suggested to disable this option: ```yml -# app/config/config_dev.yml +# config/packages/web_profiler.yaml web_profiler : intercept_redirects : false @@ -226,37 +218,18 @@ web_profiler : ### Runtime Options -Sometime, you may have a filter defined that fulfills 99% of your usage -scenarios. Instead of defining a new filter for the erroneous 1% of cases, -you may instead choose to alter the behavior of a filter at runtime by +Sometime, you may may need to modify your filter at runtime. You can do so by passing the template helper an options array. -*For Twig-based template, use:* - ```twig {% set runtimeConfig = {"thumbnail": {"size": [50, 50] }} %} ``` -*Or, for PHP-based template, use:* - -```php - array( - "size" => array(50, 50) - ) -); -?> - - -``` - - ### Path Resolution -Sometime you need to resolve the image path returned by this bundle for a +Sometimes you need to resolve the image path returned by this bundle for a filtered image. This can easily be achieved using Symfony's console binary or programmatically from within a controller or other piece of code. @@ -268,7 +241,7 @@ You can resolve an image URL using the console command relative image paths (which must be separated by a space). ```bash -$ php bin/console liip:imagine:cache:resolve relative/path/to/image1.jpg relative/path/to/image2.jpg +php bin/console liip:imagine:cache:resolve relative/path/to/image1.jpg relative/path/to/image2.jpg ``` Additionally, you can use the ``--filter`` option to specify which filter @@ -276,7 +249,7 @@ you want to resolve for (if the ``--filter`` option is omitted, all available filters will be resolved). ```bash -$ php bin/console liip:imagine:cache:resolve relative/path/to/image1.jpg --filter=my_thumb +php bin/console liip:imagine:cache:resolve relative/path/to/image1.jpg --filter=my_thumb ``` @@ -288,24 +261,17 @@ have the service assigned to a variable called `$imagineCacheManager`, you would run: ```php -$imagineCacheManager->getBrowserPath('/relative/path/to/image.jpg', 'my_thumb'); -``` -Often, you need to perform this operation in a controller. Assuming your -controller inherits from the base Symfony controller, you can take advantage -of the inherited ``get`` method to request the ``liip_imagine.cache.manager`` -service, from which you can call ``getBrowserPath`` on a relative image -path to get its resolved location. +use Liip\ImagineBundle\Imagine\Cache\CacheManager; -```php -/** @var CacheManager */ -$imagineCacheManager = $this->get('liip_imagine.cache.manager'); +public function __construct(private CacheManager $imageCacheManager) { +} -/** @var string */ -$resolvedPath = $imagineCacheManager->getBrowserPath('/relative/path/to/image.jpg', 'my_thumb'); +public function doSomething() { + $this->imagineCacheManager->getBrowserPath('/relative/path/to/image.jpg', 'my_thumb'); +} ``` - ## Filters This bundle provides a set of built-in filters and you may easily @@ -323,15 +289,12 @@ lifting for you. ```php container - ->get('liip_imagine.service.filter'); +use Liip\ImagineBundle\Service\FilterService; + public function index(FilterService $imagine) + { // 1) Simple filter, OR $resourcePath = $imagine->getUrlOfFilteredImage('uploads/foo.jpg', 'my_thumb'); @@ -361,7 +324,7 @@ assets from. For many installations this will be sufficient, but sometime you may need to load images from other locations. To do this, you must set the `data_root` parameter in your configuration (often located at `app/config/config.yml`). -```yml +```yaml liip_imagine: loaders: default: @@ -372,7 +335,7 @@ liip_imagine: As of version `1.7.2` you can register multiple data root paths, and the file locator will search each for the requested file. -```yml +```yaml liip_imagine: loaders: default: From 82bc8ca229c4c6c845f07add0fa64f44292d542d Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Tue, 2 Jan 2024 11:24:49 -0600 Subject: [PATCH 03/10] drop 8.0 from testing, add 8.3 --- .github/workflows/phpunit.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 64324ab2..b4fb37ec 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - php: ['8.0', '8.1', '8.2'] + php: ['8.1', '8.2', '8.3'] dependencies: [highest] symfony: ['*'] stability: ['stable'] @@ -33,7 +33,7 @@ jobs: stability: 'stable' # Test each supported Symfony version with the lowest supported PHP version - - php: '8.0' + - php: '8.1' dependencies: highest symfony: '5.4.*' stability: 'stable' From a23839de11d0427f2ed0f4720550909c7d54d647 Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Tue, 2 Jan 2024 12:18:01 -0600 Subject: [PATCH 04/10] update to new xml configuration --- phpunit.xml.dist | 67 +++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index b30f16d7..0f21e702 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,42 +1,29 @@ - - - - - - ./tests - - - - - - ./src - - ./src/Resources - - - - - - - - - - - - - - - - - - + + + + ./src + + + ./src/Resources + + + + + + + + ./tests + + + + + + + + + + + + From 341e79d30a3d567e438bdd75043da93d3221298f Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Tue, 2 Jan 2024 13:52:53 -0600 Subject: [PATCH 05/10] fix typo Co-authored-by: David Buchmann --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index aabb9811..9a8ce001 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "phpstan/phpstan": "^1.10", "phpstan/phpstan-symfony": "^1.0", "psr/cache": "^3.0", - "psr/log": "^1.0|^2.0|^3,0", + "psr/log": "^1.0|^2.0|^3.0", "symfony/browser-kit": "^5.4|^6.4|^7.0", "symfony/cache": "^5.4|^6.4|^7.0", "symfony/console": "^5.4|^6.4|^7.0", From e8bceed59f41913644c0c0719cb0d08440925ca2 Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Tue, 2 Jan 2024 13:53:14 -0600 Subject: [PATCH 06/10] fix extra space. Co-authored-by: David Buchmann --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5e5d3cb..80b74c24 100644 --- a/README.md +++ b/README.md @@ -218,7 +218,7 @@ web_profiler : ### Runtime Options -Sometime, you may may need to modify your filter at runtime. You can do so by +Sometime, you may may need to modify your filter at runtime. You can do so by passing the template helper an options array. ```twig From 9bafc46130357d87f783b46d030012263a80292d Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Tue, 2 Jan 2024 13:56:12 -0600 Subject: [PATCH 07/10] move use statement --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 80b74c24..b6f72057 100644 --- a/README.md +++ b/README.md @@ -289,10 +289,10 @@ lifting for you. ```php Date: Tue, 2 Jan 2024 14:21:10 -0600 Subject: [PATCH 08/10] remove AmazonS3, use awsS3 instead --- .phpstan/iterable_types_baseline.neon | 10 - README.md | 3 +- composer.json | 32 +- doc/cache-resolver/amazons3.rst | 144 -------- doc/cache-resolver/aws_s3.rst | 2 +- doc/cache-resolver/psr_cache.rst | 6 +- .../Cache/Resolver/AmazonS3Resolver.php | 167 --------- .../Cache/Resolver/AmazonS3ResolverTest.php | 340 ------------------ 8 files changed, 20 insertions(+), 684 deletions(-) delete mode 100644 doc/cache-resolver/amazons3.rst delete mode 100644 src/Imagine/Cache/Resolver/AmazonS3Resolver.php delete mode 100644 tests/Imagine/Cache/Resolver/AmazonS3ResolverTest.php diff --git a/.phpstan/iterable_types_baseline.neon b/.phpstan/iterable_types_baseline.neon index 4a3be7cd..379eeec8 100644 --- a/.phpstan/iterable_types_baseline.neon +++ b/.phpstan/iterable_types_baseline.neon @@ -280,16 +280,6 @@ parameters: count: 1 path: ../src/Imagine/Cache/CacheManager.php - - - message: "#^Method Liip\\\\ImagineBundle\\\\Imagine\\\\Cache\\\\Resolver\\\\AmazonS3Resolver\\:\\:__construct\\(\\) has parameter \\$objUrlOptions with no value type specified in iterable type array\\.$#" - count: 1 - path: ../src/Imagine/Cache/Resolver/AmazonS3Resolver.php - - - - message: "#^Property Liip\\\\ImagineBundle\\\\Imagine\\\\Cache\\\\Resolver\\\\AmazonS3Resolver\\:\\:\\$objUrlOptions type has no value type specified in iterable type array\\.$#" - count: 1 - path: ../src/Imagine/Cache/Resolver/AmazonS3Resolver.php - - message: "#^Method Liip\\\\ImagineBundle\\\\Imagine\\\\Cache\\\\Resolver\\\\AwsS3Resolver\\:\\:__construct\\(\\) has parameter \\$getOptions with no value type specified in iterable type array\\.$#" count: 1 diff --git a/README.md b/README.md index b6f72057..d70cee5a 100644 --- a/README.md +++ b/README.md @@ -283,8 +283,7 @@ from our documentation. ## Use as a Service If you need to use your defined "filter sets" from within your controller, you -can fetch this bundle's FilterService from the service container to do the heavy -lifting for you. +can inject the bundle's FilterService to do the heavy lifting for you. ```php setObjectUrlOption('https', true); - - [ setObjectUrlOption, [ 'https', true ] ] - tags: - - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } - -You can also use the constructor of the resolver to directly inject multiple -options. - -.. code-block:: yaml - - # app/config/services.yml - - services: - acme.imagine.cache.resolver.amazon_s3: - class: Liip\ImagineBundle\Imagine\Cache\Resolver\AmazonS3Resolver - arguments: - - "@acme.amazon_s3" - - "%amazon_s3.bucket%" - - "public-read" # AmazonS3::ACL_PUBLIC (default) - - { https: true, torrent: true } - tags: - - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } - - -.. _`aws-sdk-php`: https://github.com/amazonwebservices/aws-sdk-for-php diff --git a/doc/cache-resolver/aws_s3.rst b/doc/cache-resolver/aws_s3.rst index b9f99f57..5b32ae30 100644 --- a/doc/cache-resolver/aws_s3.rst +++ b/doc/cache-resolver/aws_s3.rst @@ -167,7 +167,7 @@ for ``LiipImagineBundle`` using the following configuration: Usage on a Specific Filter ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Alternatively, you can set ``AmazonS3Resolver`` as the cache resolver for a specific +Alternatively, you can set ``AwsS3Resolver`` as the cache resolver for a specific filter set using the following configuration. .. code-block:: yaml diff --git a/doc/cache-resolver/psr_cache.rst b/doc/cache-resolver/psr_cache.rst index ab04a5e9..1c4b4c69 100644 --- a/doc/cache-resolver/psr_cache.rst +++ b/doc/cache-resolver/psr_cache.rst @@ -16,9 +16,9 @@ Dependencies This cache resolver requires a PSR-6 implementation, e.g. `symfony/cache`, which can be installed by executing the following command in your project directory: -.. code-block:: bash - - $ composer require symfony/cache +```bash +composer require symfony/cache +``` Configuration ------------- diff --git a/src/Imagine/Cache/Resolver/AmazonS3Resolver.php b/src/Imagine/Cache/Resolver/AmazonS3Resolver.php deleted file mode 100644 index 5d1bee0f..00000000 --- a/src/Imagine/Cache/Resolver/AmazonS3Resolver.php +++ /dev/null @@ -1,167 +0,0 @@ -storage = $storage; - $this->bucket = $bucket; - $this->acl = $acl; - $this->objUrlOptions = $objUrlOptions; - } - - public function setLogger(LoggerInterface $logger): void - { - $this->logger = $logger; - } - - public function isStored(string $path, string $filter): bool - { - return $this->objectExists($this->getObjectPath($path, $filter)); - } - - public function resolve(string $path, string $filter): string - { - return $this->getObjectUrl($this->getObjectPath($path, $filter)); - } - - public function store(BinaryInterface $binary, string $path, string $filter): void - { - $objectPath = $this->getObjectPath($path, $filter); - - $storageResponse = $this->storage->create_object($this->bucket, $objectPath, [ - 'body' => $binary->getContent(), - 'contentType' => $binary->getMimeType(), - 'length' => mb_strlen($binary->getContent()), - 'acl' => $this->acl, - ]); - - if (!$storageResponse->isOK()) { - $this->logger?->error('The object could not be created on Amazon S3.', [ - 'objectPath' => $objectPath, - 'filter' => $filter, - 's3_response' => $storageResponse, - ]); - - throw new NotStorableException('The object could not be created on Amazon S3.'); - } - } - - public function remove(array $paths, array $filters): void - { - if (empty($paths) && empty($filters)) { - return; - } - - if (empty($paths)) { - if (!$this->storage->delete_all_objects($this->bucket, sprintf('/%s/i', implode('|', $filters)))) { - $this->logger?->error('The objects could not be deleted from Amazon S3.', [ - 'filters' => implode(', ', $filters), - 'bucket' => $this->bucket, - ]); - } - - return; - } - - foreach ($filters as $filter) { - foreach ($paths as $path) { - $objectPath = $this->getObjectPath($path, $filter); - if (!$this->objectExists($objectPath)) { - continue; - } - - if (!$this->storage->delete_object($this->bucket, $objectPath)->isOK()) { - $this->logger?->error('The objects could not be deleted from Amazon S3.', [ - 'filter' => $filter, - 'bucket' => $this->bucket, - 'path' => $path, - ]); - } - } - } - } - - /** - * Sets a single option to be passed when retrieving an objects URL. - * - * If the option is already set, it will be overwritten. - * - * @param string $key The name of the option - * @param mixed $value The value to be set - * - * @return AmazonS3Resolver $this - * - * @see \AmazonS3::get_object_url() for available options - */ - public function setObjectUrlOption(string $key, $value): self - { - $this->objUrlOptions[$key] = $value; - - return $this; - } - - /** - * Returns the object path within the bucket. - * - * @param string $path The base path of the resource - * @param string $filter The name of the imagine filter in effect - * - * @return string The path of the object on S3 - */ - protected function getObjectPath(string $path, string $filter): string - { - return str_replace('//', '/', $filter.'/'.$path); - } - - /** - * Returns the URL for an object saved on Amazon S3. - */ - protected function getObjectUrl(string $path): string - { - return $this->storage->get_object_url($this->bucket, $path, 0, $this->objUrlOptions); - } - - /** - * Checks whether an object exists. - * - * @throws \S3_Exception - */ - protected function objectExists(string $objectPath): bool - { - return $this->storage->if_object_exists($this->bucket, $objectPath); - } -} diff --git a/tests/Imagine/Cache/Resolver/AmazonS3ResolverTest.php b/tests/Imagine/Cache/Resolver/AmazonS3ResolverTest.php deleted file mode 100644 index 66a6eea7..00000000 --- a/tests/Imagine/Cache/Resolver/AmazonS3ResolverTest.php +++ /dev/null @@ -1,340 +0,0 @@ -assertTrue($rc->implementsInterface(ResolverInterface::class)); - } - - public function testNoDoubleSlashesInObjectUrlOnResolve(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('get_object_url') - ->with('images.example.com', 'thumb/some-folder/path.jpg') - ->willReturn('http://images.example.com/some-folder/path.jpg'); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->resolve('/some-folder/path.jpg', 'thumb'); - } - - public function testObjUrlOptionsPassedToAmazonOnResolve(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('get_object_url') - ->with('images.example.com', 'thumb/some-folder/path.jpg', 0, ['torrent' => true]) - ->willReturn('http://images.example.com/some-folder/path.jpg'); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->setObjectUrlOption('torrent', true); - $resolver->resolve('/some-folder/path.jpg', 'thumb'); - } - - public function testThrowsAndLogIfCanNotCreateObjectOnAmazon(): void - { - $this->expectException(\Liip\ImagineBundle\Exception\Imagine\Cache\Resolver\NotStorableException::class); - $this->expectExceptionMessage('The object could not be created on Amazon S3'); - - $binary = new Binary('aContent', 'image/jpeg', 'jpeg'); - - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('create_object') - ->willReturn($this->createCFResponseMock(false)); - - $logger = $this->createLoggerInterfaceMock(); - $logger - ->expects($this->once()) - ->method('error'); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->setLogger($logger); - $resolver->store($binary, 'foobar.jpg', 'thumb'); - } - - public function testCreatedObjectOnAmazon(): void - { - $binary = new Binary('aContent', 'image/jpeg', 'jpeg'); - - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('create_object') - ->willReturn($this->createCFResponseMock(true)); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->store($binary, 'foobar.jpg', 'thumb'); - } - - public function testIsStoredChecksObjectExistence(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('if_object_exists') - ->willReturn(false); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - - $this->assertFalse($resolver->isStored('/some-folder/path.jpg', 'thumb')); - } - - public function testReturnResolvedImageUrlOnResolve(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('get_object_url') - ->with('images.example.com', 'thumb/some-folder/path.jpg', 0, []) - ->willReturn('http://images.example.com/some-folder/path.jpg'); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - - $this->assertSame( - 'http://images.example.com/some-folder/path.jpg', - $resolver->resolve('/some-folder/path.jpg', 'thumb') - ); - } - - public function testDoNothingIfFiltersAndPathsEmptyOnRemove(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->never()) - ->method('if_object_exists'); - $s3 - ->expects($this->never()) - ->method('delete_object'); - $s3 - ->expects($this->never()) - ->method('delete_all_objects'); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->remove([], []); - } - - public function testRemoveCacheForPathAndFilterOnRemove(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('if_object_exists') - ->with('images.example.com', 'thumb/some-folder/path.jpg') - ->willReturn(true); - $s3 - ->expects($this->once()) - ->method('delete_object') - ->with('images.example.com', 'thumb/some-folder/path.jpg') - ->willReturn($this->createCFResponseMock(true)); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->remove(['some-folder/path.jpg'], ['thumb']); - } - - public function testRemoveCacheForSomePathsAndFilterOnRemove(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->method('if_object_exists') - ->withConsecutive( - ['images.example.com', 'filter/pathOne.jpg'], - ['images.example.com', 'filter/pathTwo.jpg'] - ) - ->willReturn(true); - $s3 - ->method('delete_object') - ->withConsecutive( - ['images.example.com', 'filter/pathOne.jpg'], - ['images.example.com', 'filter/pathTwo.jpg'] - ) - ->willReturnOnConsecutiveCalls( - $this->createCFResponseMock(true), - $this->createCFResponseMock(true) - ); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->remove(['pathOne.jpg', 'pathTwo.jpg'], ['filter']); - } - - public function testRemoveCacheForSomePathsAndSomeFiltersOnRemove(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->method('if_object_exists') - ->withConsecutive( - ['images.example.com', 'filterOne/pathOne.jpg'], - ['images.example.com', 'filterOne/pathTwo.jpg'], - ['images.example.com', 'filterTwo/pathOne.jpg'], - ['images.example.com', 'filterTwo/pathTwo.jpg'] - ) - ->willReturn(true); - $s3 - ->method('delete_object') - ->withConsecutive( - ['images.example.com', 'filterOne/pathOne.jpg'], - ['images.example.com', 'filterOne/pathTwo.jpg'], - ['images.example.com', 'filterTwo/pathOne.jpg'], - ['images.example.com', 'filterTwo/pathTwo.jpg'] - ) - ->willReturnOnConsecutiveCalls( - $this->createCFResponseMock(true), - $this->createCFResponseMock(true), - $this->createCFResponseMock(true), - $this->createCFResponseMock(true) - ); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->remove( - ['pathOne.jpg', 'pathTwo.jpg'], - ['filterOne', 'filterTwo'] - ); - } - - public function testDoNothingWhenObjectNotExistForPathAndFilterOnRemove(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('if_object_exists') - ->with('images.example.com', 'filter/path.jpg') - ->willReturn(false); - $s3 - ->expects($this->never()) - ->method('delete_object'); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->remove(['path.jpg'], ['filter']); - } - - public function testLogIfNotDeletedForPathAndFilterOnRemove(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('if_object_exists') - ->with('images.example.com', 'filter/path.jpg') - ->willReturn(true); - $s3 - ->expects($this->once()) - ->method('delete_object') - ->willReturn($this->createCFResponseMock(false)); - - $logger = $this->createLoggerInterfaceMock(); - $logger - ->expects($this->once()) - ->method('error'); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->setLogger($logger); - $resolver->remove(['path.jpg'], ['filter']); - } - - public function testRemoveCacheForFilterOnRemove(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('delete_all_objects') - ->with('images.example.com', '/filter/i') - ->willReturn(true); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->remove([], ['filter']); - } - - public function testRemoveCacheForSomeFiltersOnRemove(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('delete_all_objects') - ->with('images.example.com', '/filterOne|filterTwo/i') - ->willReturn(true); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->remove([], ['filterOne', 'filterTwo']); - } - - public function testLogIfBatchNotDeletedForFilterOnRemove(): void - { - $s3 = $this->createAmazonS3Mock(); - $s3 - ->expects($this->once()) - ->method('delete_all_objects') - ->with('images.example.com', '/filter/i') - ->willReturn(false); - - $logger = $this->createLoggerInterfaceMock(); - $logger - ->expects($this->once()) - ->method('error'); - - $resolver = new AmazonS3Resolver($s3, 'images.example.com'); - $resolver->setLogger($logger); - $resolver->remove([], ['filter']); - } - - /** - * @return MockObject&\CFResponse - */ - protected function createCFResponseMock(bool $ok) - { - $s3Response = $this->createObjectMock(\CFResponse::class, ['isOK'], false); - $s3Response - ->expects($this->once()) - ->method('isOK') - ->willReturn($ok); - - return $s3Response; - } - - /** - * @return MockObject&\AmazonS3 - */ - protected function createAmazonS3Mock() - { - if (!class_exists(\AmazonS3::class)) { - $this->markTestSkipped('Requires the amazonwebservices/aws-sdk-for-php package.'); - } - - return $this - ->getMockBuilder(\AmazonS3::class) - ->disableOriginalConstructor() - ->setMethods([ - 'if_object_exists', - 'create_object', - 'get_object_url', - 'delete_object', - 'delete_all_objects', - 'authenticate', - ]) - ->getMock(); - } -} From ab11f8a9e30d0f40038adfb9b0cff06d6b3686de Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Tue, 2 Jan 2024 16:24:42 -0600 Subject: [PATCH 09/10] remove Symfony < 5 installation instructions --- doc/installation.rst | 42 ++++++------------------------------------ 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/doc/installation.rst b/doc/installation.rst index 86765d98..d42894ef 100644 --- a/doc/installation.rst +++ b/doc/installation.rst @@ -10,10 +10,10 @@ Open a command console, enter your project directory, and execute the following command to download the latest stable version of this bundle and add it as a dependency to your project: -.. code-block:: bash +```bash +composer require liip/imagine-bundle +``` - composer require liip/imagine-bundle - If you accept the Symfony Flex recipe during installation, the bundle is registered, routing set up and the configuration skeleton file is created. You can now adapt the configuration to your needs. @@ -21,46 +21,16 @@ Otherwise, you need to configure the bundle with the next steps. Step 2: Enable the Bundle ------------------------- - -Then, enable the bundle by adding ``new Liip\ImagineBundle\LiipImagineBundle()`` -to the bundles array of the ``registerBundles`` method in your project's -``app/AppKernel.php`` file: - -.. code-block:: php - - ['all' => true] ]; From 56e5f251b09756a8488417d91ad2e4ae6dd4482a Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Wed, 3 Jan 2024 06:22:21 -0600 Subject: [PATCH 10/10] fix php/symfony versions for v3 --- .github/workflows/phpunit.yml | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index b4fb37ec..f5995ac0 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -21,13 +21,13 @@ jobs: stability: ['stable'] include: # Minimum supported dependencies with the oldest supported PHP version - - php: '8.0' + - php: '8.1' dependencies: lowest symfony: '*' stability: 'stable' # Minimum supported dependencies with the latest supported PHP version - - php: '8.2' + - php: '8.3' dependencies: lowest symfony: '*' stability: 'stable' @@ -35,25 +35,25 @@ jobs: # Test each supported Symfony version with the lowest supported PHP version - php: '8.1' dependencies: highest - symfony: '5.4.*' + symfony: '6.4.*' stability: 'stable' - - php: '8.1' + - php: '8.2' dependencies: highest - symfony: '6.4.*' + symfony: '7.0.*' stability: 'stable' - # Test Symfony 6.4 dev version - - php: '8.2' + - php: '8.3' dependencies: highest - symfony: '6.4.*' - stability: 'dev' + symfony: '7.0.*' + stability: 'stable' - # Test Symfony 7.0 dev version + # Test Symfony 7.1 dev - php: '8.2' dependencies: highest - symfony: '7.0.*' + symfony: '7.1.*' stability: 'dev' + steps: - name: Checkout uses: actions/checkout@v4 @@ -76,19 +76,9 @@ jobs: composer global require --no-interaction --no-progress symfony/flex composer config extra.symfony.require ${{ matrix.symfony }} - - name: Remove non-compatible dependencies with Symfony 7 - if: matrix.symfony == '7.0.*' - run: | - composer remove enqueue/enqueue-bundle symfony/templating --dev --no-update - - name: Set minimum-stability run: composer config minimum-stability ${{ matrix.stability }} - # Incompatible with symfony/framework-bundle v3 - - name: Remove symfony/messenger - if: ${{ matrix.php == '7.2' && matrix.symfony == '3.4.*' }} - run: composer remove --dev --no-update symfony/messenger - - name: Update project dependencies uses: ramsey/composer-install@v2 with: