Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Events documentation with signed url example on POST resolve #1511

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Resources/doc/cache-resolver/aws_s3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ for the list of available options.
Note, that the following options are configured automatically and will be
ignored, even if you configure it via ObjectOptions:

* ``ACL``
StevenRenaux marked this conversation as resolved.
Show resolved Hide resolved
* ``Bucket``
* ``Key``
* ``Body``
Expand Down Expand Up @@ -307,8 +306,10 @@ You can also use the constructor of the resolver to directly inject multiple opt
- { CacheControl: "max-age=86400" }
tags:
- { name: "liip_imagine.cache.resolver", resolver: "aws_s3_resolver" }

You can find an example with private ACL and signed url on the `events`_ section.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal links should not be with absolute url, but with the :doc: syntax, here

:doc:`events chapter <../events.rst>`



.. _`events`: https://github.com/liip/LiipImagineBundle/tree/2.x/Resources/doc/events
.. _`aws-sdk-php`: https://github.com/amazonwebservices/aws-sdk-for-php
.. _`S3 SDK documentation`: http://docs.aws.amazon.com/aws-sdk-php/latest/class-Aws.S3.S3Client.html#_putObject
.. _`Default Credential Provider Chain`: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
155 changes: 155 additions & 0 deletions Resources/doc/events.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@


Events
======

Events availables in the bundle are ``PRE_RESOLVE`` and ``POST_RESOLVE``.
Both receive a CacheResolveEvent as event.

PRE_RESOLVE
-----------

Called before url to the cached filtered image is generated.


POST_RESOLVE
------------

Called after url to the cached filtered image is generated.

Example: Signed URLs
--------------------
Here is an implementation example about users media with differents filters and an S3 as IONOS. At the end we will update the url to get a temporary signed url to a private resource:
StevenRenaux marked this conversation as resolved.
Show resolved Hide resolved

First, we need to configure the adapters and the filesystem where will be loaded the images. Normally no need to configure where the cached images will be stored, but we will need it in the next step to generate a signed url.

.. code-block:: yaml
#oneup_flysystem.yaml

oneup_flysystem:
adapters:
# Original image addapter
user_adapter:
awss3v3:
client: Aws\S3\S3Client
bucket: '%env(IONOS_S3_BUCKET_NAME)%'
prefix: "users" # Original image location

# One adapter per filter and the location of the generated images, with the cache_prefix
user_thumbnail_adapter:
awss3v3:
client: Aws\S3\S3Client
bucket: '%env(IONOS_S3_BUCKET_NAME)%'
prefix: "cache/user_thumbnail"
user_medium_adapter:
awss3v3:
client: Aws\S3\S3Client
bucket: '%env(IONOS_S3_BUCKET_NAME)%'
prefix: "cache/user_medium"

filesystems:
user:
adapter: user_adapter
mount: user
userThumbnail:
adapter: user_thumbnail_adapter
mount: userThumbnail
userMedium:
adapter: user_medium_adapter
mount: userMedium

To get a cached resource as private we need to configure the acl of the resolver to private, or the generated image will be in public, it's not what we want in this example.

.. code-block:: yaml
liip_imagine:
driver: "gd"
loaders:
user_loader:
flysystem:
filesystem_service: oneup_flysystem.user_filesystem

resolvers:
aws_s3_resolver:
aws_s3:
bucket: '%env(IONOS_S3_BUCKET_NAME)%'
client_config:
credentials:
key: '%env(IONOS_S3_ACCESS_ID)%'
secret: '%env(IONOS_S3_ACCESS_SECRET)%'
endpoint: '%env(IONOS_S3_ENDPOINT)%'
region: '%env(IONOS_S3_REGION)%'
version: '%env(IONOS_S3_VERSION)%'
acl: private
cache_prefix: cache

get_options:
Scheme: 'https'
put_options:
CacheControl: 'max-age=86400'
cache: aws_s3_resolver
filter_sets:
cache: ~
user_thumbnail:
cache: aws_s3_resolver
quality: 75
filters:
thumbnail: { size: [ 130, 130 ], mode: outbound }
data_loader: user_loader
user_medium:
cache: aws_s3_resolver
quality: 75
filters:
thumbnail: { size: [ 302, 180 ], mode: outbound }
data_loader: user_loader

Finally we create a post resolve subscriber to update the url to the private resource location.

.. code-block:: php

namespace App\EventSubscriber;

use App\Enum\MediaFilterEnum;
use App\Repository\MediaRepository;
use League\Flysystem\FilesystemOperator;
use Liip\ImagineBundle\Events\CacheResolveEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class LiipImagineFilterSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly FilesystemOperator $userThumbnailFilesystem,
private readonly FilesystemOperator $userMediumFilesystem
)
{
}

public function onPostResolve(CacheResolveEvent $event): void
{
$path = $event->getPath();
$filter = $event->getFilter();

$date = new \DateTime();
// We set the expiration in 10 minutes for example.
$date = $date->add(new \DateInterval('PT10M'));

if ($filter === MediaFilterEnum::USER_THUMBNAIL->value) {
$url = $this->userThumbnailFilesystem->temporaryUrl($path, $date);
}
else if ($filter === MediaFilterEnum::USER_MEDIUM->value) {
$url = $this->userMediumFilesystem->temporaryUrl($path, $date);
}

if (isset($url)) {
$event->setUrl($url);
}
}

public static function getSubscribedEvents(): array
{
return [
'liip_imagine.post_resolve' => 'onPostResolve'
];
}
}

Now, you will get a proper signed url to get your private resource.
101 changes: 51 additions & 50 deletions Resources/doc/index.rst
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@


LiipImagineBundle
=================
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happened here? is it line endings?

Copy link
Contributor Author

@StevenRenaux StevenRenaux May 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's like the original file, don't know why my commit pushed as a new file. The line 45 is the only one i added.


Overview
--------

The `LiipImagineBundle`_ package provides an *image manipulation abstraction toolkit*
for Symfony-based projects. Features include:

* :doc:`Filter Sets <basic-usage>`: Using any Symfony-supported configuration language
(such as YML and XML), you can create *filter set* definitions that specify
transformation routines. These include a set of *filters* and *post-processors*, as
well as other, optional parameters.
* :doc:`Filters <filters>`: A number of built-in filters are provided, allowing for an array of
common image transformations. Examples include :ref:`thumbnail <filter-thumbnail>`,
:ref:`scale <filter-scale>`, :ref:`crop <filter-crop>`, :ref:`strip <filter-strip>`,
and :ref:`watermark <filter-watermark>`, and many more. Additionally,
:ref:`custom filters <filter-custom>` are supported.
* :doc:`Post-Processors <post-processors>`: A number of build-in post-processors are provided,
allowing for the modification of the resulting binary file created by filters. Examples include
:ref:`JpegOptim <post-processor-jpegoptim>`, :ref:`OptiPNG <post-processor-optipng>`,
:ref:`MozJpeg <post-processor-mozjpeg>`, and :ref:`PngQuant <post-processor-pngquant>`. Additionally,
:ref:`custom post-processors <post-processors-custom>` are supported.


Chapters
--------

Jump into any of the available chapters to learn more about anything from the basic
usage to the architecture of bundle.

.. toctree::
:maxdepth: 2

installation
introduction
basic-usage
filters
post-processors
configuration
data-loaders
cache-resolvers
cache-manager
asset-versioning
commands
optimizations

.. _`LiipImagineBundle`: https://github.com/liip/LiipImagineBundle


LiipImagineBundle
=================

Overview
--------

The `LiipImagineBundle`_ package provides an *image manipulation abstraction toolkit*
for Symfony-based projects. Features include:

* :doc:`Filter Sets <basic-usage>`: Using any Symfony-supported configuration language
(such as YML and XML), you can create *filter set* definitions that specify
transformation routines. These include a set of *filters* and *post-processors*, as
well as other, optional parameters.
* :doc:`Filters <filters>`: A number of built-in filters are provided, allowing for an array of
common image transformations. Examples include :ref:`thumbnail <filter-thumbnail>`,
:ref:`scale <filter-scale>`, :ref:`crop <filter-crop>`, :ref:`strip <filter-strip>`,
and :ref:`watermark <filter-watermark>`, and many more. Additionally,
:ref:`custom filters <filter-custom>` are supported.
* :doc:`Post-Processors <post-processors>`: A number of build-in post-processors are provided,
allowing for the modification of the resulting binary file created by filters. Examples include
:ref:`JpegOptim <post-processor-jpegoptim>`, :ref:`OptiPNG <post-processor-optipng>`,
:ref:`MozJpeg <post-processor-mozjpeg>`, and :ref:`PngQuant <post-processor-pngquant>`. Additionally,
:ref:`custom post-processors <post-processors-custom>` are supported.


Chapters
--------

Jump into any of the available chapters to learn more about anything from the basic
usage to the architecture of bundle.

.. toctree::
:maxdepth: 2

installation
introduction
basic-usage
filters
post-processors
configuration
data-loaders
cache-resolvers
cache-manager
asset-versioning
commands
events
optimizations

.. _`LiipImagineBundle`: https://github.com/liip/LiipImagineBundle