Skip to content

Commit 27517d3

Browse files
committed
[LazyImage] Abstract image content fetching
1 parent ba75b9f commit 27517d3

File tree

6 files changed

+111
-4
lines changed

6 files changed

+111
-4
lines changed

src/LazyImage/doc/index.rst

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,38 @@ 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, ``data_uri_thumbnail`` fetches images using the `file_get_contents`_ function.
110+
It works well for local files, but you may want to customize it to fetch images from a remote server, `Flysystem`_, etc.
111+
112+
To do so you can create a invokable class, the first argument is the filename to fetch:
113+
114+
.. ::
115+
116+
namespace App\BlurHash;
117+
118+
class FetchImageContent
119+
{
120+
public function __invoke(string $filename): string
121+
{
122+
// Your custom implementation here to fetch the image content
123+
}
124+
}
125+
126+
Then you must configure the service in your Symfony configuration:
127+
128+
.. code-block:: yaml
129+
130+
# config/packages/lazy_image.yaml
131+
lazy_image:
132+
fetch_image_content: 'App\BlurHash\FetchImageContent'
133+
106134
Performance considerations
107135
~~~~~~~~~~~~~~~~~~~~~~~~~~
108136

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

src/LazyImage/src/BlurHash/BlurHash.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,17 @@
2525
*/
2626
class BlurHash implements BlurHashInterface
2727
{
28+
private \Closure $fetchImageContent;
29+
30+
/**
31+
* @param (\Closure(string): string)|null $fetchImageContent
32+
*/
2833
public function __construct(
2934
private ?ImageManager $imageManager = null,
3035
private ?CacheInterface $cache = null,
36+
?callable $fetchImageContent = null,
3137
) {
38+
$this->fetchImageContent = $fetchImageContent ? $fetchImageContent(...) : file_get_contents(...);
3239
}
3340

3441
public static function intervention3(): bool
@@ -74,8 +81,10 @@ private function doEncode(string $filename, int $encodingWidth = 75, int $encodi
7481

7582
private function generatePixels(string $filename, int $encodingWidth, int $encodingHeight): array
7683
{
84+
$imageContent = ($this->fetchImageContent)($filename);
85+
7786
if (self::intervention3()) {
78-
$image = $this->imageManager->read($filename)->scale($encodingWidth, $encodingHeight);
87+
$image = $this->imageManager->read($imageContent)->scale($encodingWidth, $encodingHeight);
7988
$width = $image->width();
8089
$height = $image->height();
8190
$pixels = [];
@@ -93,7 +102,7 @@ private function generatePixels(string $filename, int $encodingWidth, int $encod
93102
}
94103

95104
// Resize image to increase encoding performance
96-
$image = $this->imageManager->make(file_get_contents($filename));
105+
$image = $this->imageManager->make($imageContent);
97106
$image->resize($encodingWidth, $encodingHeight, static function ($constraint) {
98107
$constraint->aspectRatio();
99108
$constraint->upsize();

src/LazyImage/src/DependencyInjection/Configuration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public function getConfigTreeBuilder(): TreeBuilder
2828
$rootNode
2929
->children()
3030
->scalarNode('cache')->end()
31+
->scalarNode('fetch_image_content')->defaultNull()->end()
3132
->end()
3233
;
3334

src/LazyImage/src/DependencyInjection/LazyImageExtension.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ public function load(array $configs, ContainerBuilder $container)
4646

4747
$container
4848
->setDefinition('lazy_image.blur_hash', new Definition(BlurHash::class))
49-
->setArgument(0, new Reference('lazy_image.image_manager', ContainerInterface::NULL_ON_INVALID_REFERENCE))
49+
->setArguments([
50+
new Reference('lazy_image.image_manager', ContainerInterface::NULL_ON_INVALID_REFERENCE),
51+
null, // $cache
52+
null, // $fetchImageContent
53+
])
5054
;
5155

5256
if (isset($config['cache'])) {
@@ -56,6 +60,13 @@ public function load(array $configs, ContainerBuilder $container)
5660
;
5761
}
5862

63+
if (isset($config['fetch_image_content'])) {
64+
$container
65+
->getDefinition('lazy_image.blur_hash')
66+
->setArgument(2, new Reference($config['fetch_image_content']))
67+
;
68+
}
69+
5970
$container->setAlias(BlurHashInterface::class, 'lazy_image.blur_hash')->setPublic(false);
6071

6172
$container

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)