Skip to content

Commit 9b3c320

Browse files
committed
[LazyImage] Abstract image content fetching
1 parent ba75b9f commit 9b3c320

File tree

7 files changed

+129
-5
lines changed

7 files changed

+129
-5
lines changed

src/LazyImage/doc/index.rst

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,39 @@ blurred, data-uri thumbnail of the image:
9999

100100
The ``data_uri_thumbnail`` function receives 3 arguments:
101101

102-
- the server path to the image to generate the data-uri thumbnail for ;
102+
- the path to the image to generate the data-uri thumbnail for ;
103103
- the width of the BlurHash to generate
104104
- the height of the BlurHash to generate
105105

106+
Customizing images fetching
107+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
108+
109+
By default, images fetched in ``data_uri_thumbnail`` are fetched using the function
110+
`file_get_contents`_. It works well for local files, but you may want to customize it
111+
to fetch images from a remote server, from `Flysystem`_, etc...
112+
113+
To do so you can create a invokable class, the first argument is the filename to fetch:
114+
115+
.. ::
116+
117+
namespace App\BlurHash;
118+
119+
class FetchImageContent
120+
{
121+
public function __invoke(string $filename): string
122+
{
123+
// Your custom implementation here to fetch the image content
124+
}
125+
}
126+
127+
Then you must configure the service in your Symfony configuration:
128+
129+
.. code-block:: yaml
130+
131+
# config/packages/lazy_image.yaml
132+
lazy_image:
133+
fetch_image_content: 'App\BlurHash\FetchImageContent'
134+
106135
Performance considerations
107136
~~~~~~~~~~~~~~~~~~~~~~~~~~
108137

@@ -190,3 +219,5 @@ https://symfony.com/doc/current/contributing/code/bc.html
190219
.. _`BlurHash implementation`: https://blurha.sh
191220
.. _`StimulusBundle`: https://symfony.com/bundles/StimulusBundle/current/index.html
192221
.. _StimulusBundle configured in your app: https://symfony.com/bundles/StimulusBundle/current/index.html
222+
.. _`file_get_contents`: https://www.php.net/manual/en/function.file-get-contents.php
223+
.. _`Flysystem`: https://flysystem.thephpleague.com

src/LazyImage/src/BlurHash/BlurHash.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
*/
2626
class BlurHash implements BlurHashInterface
2727
{
28+
/**
29+
* @param \Closure(string): string $fetchImageContent
30+
*/
2831
public function __construct(
32+
private \Closure $fetchImageContent,
2933
private ?ImageManager $imageManager = null,
3034
private ?CacheInterface $cache = null,
3135
) {
@@ -74,8 +78,10 @@ private function doEncode(string $filename, int $encodingWidth = 75, int $encodi
7478

7579
private function generatePixels(string $filename, int $encodingWidth, int $encodingHeight): array
7680
{
81+
$imageContent = ($this->fetchImageContent)($filename);
82+
7783
if (self::intervention3()) {
78-
$image = $this->imageManager->read($filename)->scale($encodingWidth, $encodingHeight);
84+
$image = $this->imageManager->read($imageContent)->scale($encodingWidth, $encodingHeight);
7985
$width = $image->width();
8086
$height = $image->height();
8187
$pixels = [];
@@ -93,7 +99,7 @@ private function generatePixels(string $filename, int $encodingWidth, int $encod
9399
}
94100

95101
// Resize image to increase encoding performance
96-
$image = $this->imageManager->make(file_get_contents($filename));
102+
$image = $this->imageManager->make($imageContent);
97103
$image->resize($encodingWidth, $encodingHeight, static function ($constraint) {
98104
$constraint->aspectRatio();
99105
$constraint->upsize();
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\UX\LazyImage\BlurHash;
13+
14+
/**
15+
* @author Hugo Alliaume <hugo@alliau.me>
16+
*/
17+
final class FetchImageContent
18+
{
19+
public function __invoke(string $filename): string
20+
{
21+
return file_get_contents($filename);
22+
}
23+
}

src/LazyImage/src/DependencyInjection/Configuration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public function getConfigTreeBuilder(): TreeBuilder
2727
$rootNode = $treeBuilder->getRootNode();
2828
$rootNode
2929
->children()
30+
->scalarNode('fetch_image_content')->defaultValue('lazy_image.fetch_image_content')->end()
3031
->scalarNode('cache')->end()
3132
->end()
3233
;

src/LazyImage/src/DependencyInjection/LazyImageExtension.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
2323
use Symfony\UX\LazyImage\BlurHash\BlurHash;
2424
use Symfony\UX\LazyImage\BlurHash\BlurHashInterface;
25+
use Symfony\UX\LazyImage\BlurHash\FetchImageContent;
2526
use Symfony\UX\LazyImage\Twig\BlurHashExtension;
2627
use Symfony\UX\LazyImage\Twig\BlurHashRuntime;
2728

@@ -44,15 +45,21 @@ public function load(array $configs, ContainerBuilder $container)
4445
;
4546
}
4647

48+
$container
49+
->setDefinition('lazy_image.fetch_image_content', new Definition(FetchImageContent::class));
50+
4751
$container
4852
->setDefinition('lazy_image.blur_hash', new Definition(BlurHash::class))
49-
->setArgument(0, new Reference('lazy_image.image_manager', ContainerInterface::NULL_ON_INVALID_REFERENCE))
53+
->setArgument(0, (new Definition('Closure'))
54+
->setFactory(['Closure', 'fromCallable'])
55+
->addArgument(new Reference($config['fetch_image_content'])))
56+
->setArgument(1, new Reference('lazy_image.image_manager', ContainerInterface::NULL_ON_INVALID_REFERENCE))
5057
;
5158

5259
if (isset($config['cache'])) {
5360
$container
5461
->getDefinition('lazy_image.blur_hash')
55-
->setArgument(1, new Reference($config['cache']))
62+
->setArgument(2, new Reference($config['cache']))
5663
;
5764
}
5865

src/LazyImage/tests/BlurHash/BlurHashTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
use Symfony\Component\Cache\Adapter\ArrayAdapter;
1616
use Symfony\Component\Config\Loader\LoaderInterface;
1717
use Symfony\Component\DependencyInjection\ContainerBuilder;
18+
use Symfony\Component\DependencyInjection\Definition;
1819
use Symfony\Contracts\Cache\CacheInterface;
1920
use Symfony\UX\LazyImage\BlurHash\BlurHash;
2021
use Symfony\UX\LazyImage\BlurHash\BlurHashInterface;
22+
use Symfony\UX\LazyImage\Tests\Fixtures\BlurHash\LoggedFetchImageContent;
2123
use Symfony\UX\LazyImage\Tests\Kernel\TwigAppKernel;
2224

2325
/**
@@ -42,6 +44,45 @@ public function testEncode()
4244
);
4345
}
4446

47+
public function testWithCustomGetImageContent(): void
48+
{
49+
$kernel = new class('test', true) extends TwigAppKernel {
50+
public function registerContainerConfiguration(LoaderInterface $loader)
51+
{
52+
parent::registerContainerConfiguration($loader);
53+
54+
$loader->load(static function (ContainerBuilder $container) {
55+
$container->loadFromExtension('lazy_image', [
56+
'fetch_image_content' => 'logged_get_image_content',
57+
]);
58+
59+
$container
60+
->setDefinition('logged_get_image_content', new Definition(LoggedFetchImageContent::class))
61+
->setPublic('true')
62+
;
63+
});
64+
}
65+
};
66+
67+
$kernel->boot();
68+
$container = $kernel->getContainer()->get('test.service_container');
69+
70+
/** @var BlurHashInterface $blurHash */
71+
$blurHash = $container->get('test.lazy_image.blur_hash');
72+
73+
$loggedGetImageContent = $container->get('logged_get_image_content');
74+
$this->assertInstanceOf(LoggedFetchImageContent::class, $loggedGetImageContent);
75+
$this->assertEmpty($loggedGetImageContent->logs);
76+
77+
$this->assertSame(
78+
BlurHash::intervention3() ? 'LnMtaO9FD%IU%MRjayRj~qIUM{of' : 'L54ec*~q_3?bofoffQWB9F9FD%IU',
79+
$blurHash->encode(__DIR__.'/../Fixtures/logo.png')
80+
);
81+
82+
$this->assertCount(1, $loggedGetImageContent->logs);
83+
$this->assertSame(__DIR__.'/../Fixtures/logo.png', $loggedGetImageContent->logs[0]);
84+
}
85+
4586
public function testEnsureCacheIsNotUsedWhenNotConfigured()
4687
{
4788
$kernel = new TwigAppKernel('test', true);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Symfony\UX\LazyImage\Tests\Fixtures\BlurHash;
4+
5+
final class LoggedFetchImageContent
6+
{
7+
public array $logs = [];
8+
9+
public function __invoke(string $filename): string
10+
{
11+
$this->logs[] = $filename;
12+
13+
return file_get_contents($filename);
14+
}
15+
}

0 commit comments

Comments
 (0)