Skip to content

Commit cb1491b

Browse files
authored
Merge pull request #9 from ace-of-aces/feat/cache-size-limit
2 parents 908a6dc + ba01d3f commit cb1491b

File tree

10 files changed

+373
-125
lines changed

10 files changed

+373
-125
lines changed

config/image-transform-url.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@
8282
'enabled' => env('IMAGE_TRANSFORM_CACHE_ENABLED', true),
8383
'lifetime' => env('IMAGE_TRANSFORM_CACHE_LIFETIME', 60 * 24 * 7), // 7 days
8484
'disk' => env('IMAGE_TRANSFORM_CACHE_DISK', 'local'),
85+
'max_size_mb' => env('IMAGE_TRANSFORM_CACHE_MAX_SIZE_MB', 100), // 100 MB
86+
'clear_to_percent' => env('IMAGE_TRANSFORM_CACHE_CLEAR_TO_PERCENT', 80), // 80% of max size
8587
],
8688

8789
/*

docs/pages/cdn-usage.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,17 @@ The most important configuration is the [`Cache-Control`](https://developer.mozi
66

77
```php
88
/*
9-
|--------------------------------------------------------------------------
10-
| Response Headers
11-
|--------------------------------------------------------------------------
12-
|
13-
| Below you may configure the response headers which are added to the
14-
| response. This is especially useful for controlling caching behavior
15-
| of CDNs.
16-
|
17-
*/
18-
19-
'headers' => [
20-
'Cache-Control' => env('IMAGE_TRANSFORM_HEADER_CACHE_CONTROL', 'immutable, public, max-age=2592000, s-maxage=2592000'),
21-
// more headers can be added here
22-
],
9+
|--------------------------------------------------------------------------
10+
| Response Headers
11+
|--------------------------------------------------------------------------
12+
|
13+
| Below you may configure the response headers which are added to the
14+
| response. This is especially useful for controlling caching behavior
15+
| of CDNs.
16+
|
17+
*/
18+
'headers' => [
19+
'Cache-Control' => env('IMAGE_TRANSFORM_HEADER_CACHE_CONTROL', 'immutable, public, max-age=2592000, s-maxage=2592000'),
20+
// more headers can be added here
21+
],
2322
```

docs/pages/configuring-options.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@ This package supports a variety of options, but you may not need or want to use
44

55
```php
66
/*
7-
|--------------------------------------------------------------------------
8-
| Enabled Options
9-
|--------------------------------------------------------------------------
10-
|
11-
| Here you may configure the options which are enabled for the image
12-
| transformer.
13-
|
14-
*/
7+
|--------------------------------------------------------------------------
8+
| Enabled Options
9+
|--------------------------------------------------------------------------
10+
|
11+
| Here you may configure the options which are enabled for the image
12+
| transformer.
13+
|
14+
*/
1515

16-
'enabled_options' => env('IMAGE_TRANSFORM_ENABLED_OPTIONS', [
17-
'width',
18-
'height',
19-
'format',
20-
'quality',
21-
// 'flip',
22-
// 'contrast',
23-
// 'version',
24-
// 'background',
25-
// 'blur'
26-
]),
16+
'enabled_options' => env('IMAGE_TRANSFORM_ENABLED_OPTIONS', [
17+
'width',
18+
'height',
19+
'format',
20+
'quality',
21+
// 'flip',
22+
// 'contrast',
23+
// 'version',
24+
// 'background',
25+
// 'blur'
26+
]),
2727
```

docs/pages/image-caching.md

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,36 @@ To force a revalidation, you can either:
2020
3. change the [version number](/available-options#version) in the options (e.g. `version=2`)
2121
4. or flush the entire cache of your application using the `php artisan cache:clear` command.
2222

23+
## Cache Size Limit
24+
25+
The image caching feature also comes with a size limit to prevent the cache from growing indefinitely. The default maximum size is set to **100 MB**, but you can change this in the configuration file.
26+
27+
When the cache reaches the specified size limit, it will automatically clean up old files to make space for new ones.
28+
29+
You may also configure the percentage of the maximum size that should be kept after cleanup, referred to as `clear_to_percent`.
30+
For example, if `clear_to_percent` is set to 80, 20% of the cache is cleared on each cleanup run, and 80% is retained. The default is set to 80% of the maximum size.
31+
2332
---
2433

2534
You can configure the caching options in the `image-transform-url.php` configuration file:
2635

2736
```php
2837
/*
29-
|--------------------------------------------------------------------------
30-
| Image Cache
31-
|--------------------------------------------------------------------------
32-
|
33-
| Here you may configure the image cache settings. The cache is used to
34-
| store the transformed images for a certain amount of time. This is
35-
| useful to prevent reprocessing the same image multiple times.
36-
| The cache is stored in the configured cache disk.
37-
|
38-
*/
39-
40-
'cache' => [
41-
'enabled' => env('IMAGE_TRANSFORM_CACHE_ENABLED', true),
42-
'lifetime' => env('IMAGE_TRANSFORM_CACHE_LIFETIME', 60 * 24 * 7), // 7 days
43-
'disk' => env('IMAGE_TRANSFORM_CACHE_DISK', 'local'),
44-
],
38+
|--------------------------------------------------------------------------
39+
| Image Cache
40+
|--------------------------------------------------------------------------
41+
|
42+
| Here you may configure the image cache settings. The cache is used to
43+
| store the transformed images for a certain amount of time. This is
44+
| useful to prevent reprocessing the same image multiple times.
45+
| The cache is stored in the configured cache disk.
46+
|
47+
*/
48+
'cache' => [
49+
'enabled' => env('IMAGE_TRANSFORM_CACHE_ENABLED', true),
50+
'lifetime' => env('IMAGE_TRANSFORM_CACHE_LIFETIME', 60 * 24 * 7), // 7 days
51+
'disk' => env('IMAGE_TRANSFORM_CACHE_DISK', 'local'),
52+
'max_size_mb' => env('IMAGE_TRANSFORM_CACHE_MAX_SIZE_MB', 100), // 100 MB
53+
'clear_to_percent' => env('IMAGE_TRANSFORM_CACHE_CLEAR_TO_PERCENT', 80), // 80% of max size
54+
],
4555
```

docs/pages/rate-limiting.md

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,22 @@ By default, rate limiting is disabled for the `local` and `testing` app environe
88

99
```php
1010
/*
11-
|--------------------------------------------------------------------------
12-
| Rate Limit
13-
|--------------------------------------------------------------------------
14-
|
15-
| Below you may configure the rate limit which is applied for each image
16-
| new transformation by the path and IP address. It is recommended to
17-
| set this to a low value, e.g. 2 requests per minute, to prevent
18-
| abuse.
19-
*/
20-
21-
'rate_limit' => [
22-
'enabled' => env('IMAGE_TRANSFORM_RATE_LIMIT_ENABLED', true),
23-
'disabled_for_environments' => [
24-
'local',
25-
'testing',
26-
],
27-
'max_attempts' => env('IMAGE_TRANSFORM_RATE_LIMIT_MAX_REQUESTS', 2),
28-
'decay_seconds' => env('IMAGE_TRANSFORM_RATE_LIMIT_DECAY_SECONDS', 60),
11+
|--------------------------------------------------------------------------
12+
| Rate Limit
13+
|--------------------------------------------------------------------------
14+
|
15+
| Below you may configure the rate limit which is applied for each image
16+
| new transformation by the path and IP address. It is recommended to
17+
| set this to a low value, e.g. 2 requests per minute, to prevent
18+
| abuse.
19+
*/
20+
'rate_limit' => [
21+
'enabled' => env('IMAGE_TRANSFORM_RATE_LIMIT_ENABLED', true),
22+
'disabled_for_environments' => [
23+
'local',
24+
'testing',
2925
],
26+
'max_attempts' => env('IMAGE_TRANSFORM_RATE_LIMIT_MAX_REQUESTS', 2),
27+
'decay_seconds' => env('IMAGE_TRANSFORM_RATE_LIMIT_DECAY_SECONDS', 60),
28+
],
3029
```

docs/pages/setup.md

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,32 @@ An example source directory configuration might look like this:
1111

1212
```php
1313
/*
14-
|--------------------------------------------------------------------------
15-
| Source Directories
16-
|--------------------------------------------------------------------------
17-
|
18-
| Here you may configure the directories from which the image transformer
19-
| is allowed to serve images. For security reasons, it is recommended
20-
| to only allow directories which are already publicly accessible.
21-
|
22-
| Important: The public storage directory should be addressed directly via
23-
| storage('app/public') instead of the public_path('storage') link.
24-
|
25-
*/
26-
27-
'source_directories' => [
28-
'images' => public_path('images'),
29-
'storage' => storage_path('app/public/images'),
30-
],
31-
32-
/*
33-
|--------------------------------------------------------------------------
34-
| Default Source Directory
35-
|--------------------------------------------------------------------------
36-
|
37-
| Below you may configure the default source directory which is used when
38-
| no specific path prefix is provided in the URL. This should be one of
39-
| the keys from the source_directories array.
40-
|
41-
*/
42-
43-
'default_source_directory' => env('IMAGE_TRANSFORM_DEFAULT_SOURCE_DIRECTORY', 'images'),
44-
45-
// ...
14+
|--------------------------------------------------------------------------
15+
| Source Directories
16+
|--------------------------------------------------------------------------
17+
|
18+
| Here you may configure the directories from which the image transformer
19+
| is allowed to serve images. For security reasons, it is recommended
20+
| to only allow directories which are already publicly accessible.
21+
|
22+
| Important: The public storage directory should be addressed directly via
23+
| storage('app/public') instead of the public_path('storage') link.
24+
|
25+
*/
26+
'source_directories' => [
27+
'images' => public_path('images'),
28+
'storage' => storage_path('app/public/images'),
29+
],
30+
/*
31+
|--------------------------------------------------------------------------
32+
| Default Source Directory
33+
|--------------------------------------------------------------------------
34+
|
35+
| Below you may configure the default source directory which is used when
36+
| no specific path prefix is provided in the URL. This should be one of
37+
| the keys from the source_directories array.
38+
|
39+
*/
40+
'default_source_directory' => env('IMAGE_TRANSFORM_DEFAULT_SOURCE_DIRECTORY', 'images'),
41+
// ...
4642
```

src/Http/Controllers/ImageTransformerController.php

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use AceOfAces\LaravelImageTransformUrl\Enums\AllowedMimeTypes;
88
use AceOfAces\LaravelImageTransformUrl\Enums\AllowedOptions;
9+
use AceOfAces\LaravelImageTransformUrl\Traits\ManagesImageCache;
910
use AceOfAces\LaravelImageTransformUrl\Traits\ResolvesOptions;
1011
use Illuminate\Http\Request;
1112
use Illuminate\Http\Response;
@@ -14,7 +15,6 @@
1415
use Illuminate\Support\Facades\Cache;
1516
use Illuminate\Support\Facades\File;
1617
use Illuminate\Support\Facades\RateLimiter;
17-
use Illuminate\Support\Facades\Storage;
1818
use Illuminate\Support\Str;
1919
use Intervention\Image\Drivers\Gd\Encoders\WebpEncoder;
2020
use Intervention\Image\Encoders\AutoEncoder;
@@ -25,7 +25,7 @@
2525

2626
class ImageTransformerController extends \Illuminate\Routing\Controller
2727
{
28-
use ResolvesOptions;
28+
use ManagesImageCache, ResolvesOptions;
2929

3030
public function transformWithPrefix(Request $request, string $pathPrefix, string $options, string $path)
3131
{
@@ -127,19 +127,7 @@ protected function handleTransform(Request $request, ?string $pathPrefix, string
127127

128128
if (config()->boolean('image-transform-url.cache.enabled')) {
129129
defer(function () use ($pathPrefix, $path, $options, $encoded) {
130-
131-
$cachePath = $this->getCachePath($pathPrefix, $path, $options);
132-
133-
$cacheDir = dirname($cachePath);
134-
135-
File::ensureDirectoryExists($cacheDir);
136-
File::put($cachePath, $encoded->toString());
137-
138-
Cache::put(
139-
key: 'image-transform-url:'.$cachePath,
140-
value: true,
141-
ttl: config()->integer('image-transform-url.cache.lifetime'),
142-
);
130+
$this->storeCachedImage($pathPrefix, $path, $options, $encoded);
143131
});
144132
}
145133

@@ -235,16 +223,6 @@ protected static function parseOptions(string $options): array
235223
})->toArray();
236224
}
237225

238-
/**
239-
* Get the cache path for the given path and options.
240-
*/
241-
protected static function getCachePath(string $pathPrefix, string $path, array $options): string
242-
{
243-
$optionsHash = md5(json_encode($options));
244-
245-
return Storage::disk(config()->string('image-transform-url.cache.disk'))->path('_cache/image-transform-url/'.$pathPrefix.'/'.$optionsHash.'_'.$path);
246-
}
247-
248226
/**
249227
* Respond with the image content.
250228
*/

0 commit comments

Comments
 (0)