Skip to content

Commit 1b13463

Browse files
authored
Add route for dynamic image generation on application side (#462)
1 parent eff260d commit 1b13463

File tree

6 files changed

+184
-24
lines changed

6 files changed

+184
-24
lines changed

.php-cs-fixer.dist.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

3-
use Gomzyakov\CS\Finder;
4-
use Gomzyakov\CS\Config;
3+
use Gomzyakov\CodeStyleFinder;
4+
use Gomzyakov\CodeStyleConfig;
55

66
// Routes for analysis with `php-cs-fixer`
77
$routes = [
@@ -13,4 +13,4 @@
1313
__DIR__ . '/tests',
1414
];
1515

16-
return Config::createWithFinder(Finder::createWithRoutes($routes));
16+
return CodeStyleConfig::createWithFinder(CodeStyleFinder::createWithRoutes($routes));
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace App\Http\Controllers;
6+
7+
use Gomzyakov\ImagePlaceholder;
8+
use Illuminate\Http\Request;
9+
use Illuminate\Http\Response;
10+
use RuntimeException;
11+
12+
class PlaceholderController extends Controller
13+
{
14+
/**
15+
* Generate a placeholder image.
16+
*/
17+
public function generate(Request $request, int $width = 640, int $height = 480): Response
18+
{
19+
if ($width < 1 || $width > 2000) {
20+
return response('Width must be between 1 and 2000', 400);
21+
}
22+
if ($height < 1 || $height > 2000) {
23+
return response('Height must be between 1 and 2000', 400);
24+
}
25+
26+
$cx = (int) $request->get('cx', 4); // blurhash components on X axis
27+
$cy = (int) $request->get('cy', 3); // blurhash components on Y axis
28+
29+
if ($cx < 1 || $cx > 9) {
30+
return response('cx must be between 1 and 9', 400);
31+
}
32+
if ($cy < 1 || $cy > 9) {
33+
return response('cy must be between 1 and 9', 400);
34+
}
35+
36+
$seed = (string) $request->get('seed', 'default');
37+
38+
try {
39+
$generator = new ImagePlaceholder();
40+
$image_data = $generator->generate($width, $height, $seed, $cx, $cy);
41+
42+
return response($image_data)
43+
->header('Content-Type', 'image/png')
44+
->header('Cache-Control', 'public, max-age=31536000');
45+
} catch (RuntimeException $e) {
46+
return response($e->getMessage(), 500);
47+
}
48+
}
49+
}

composer.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
"require": {
88
"php": "^8.4",
99
"ext-intl": "*",
10+
"ext-gd": "*",
11+
"gomzyakov/image-placeholder": "^1.0",
1012
"laravel/framework": "^11.9",
1113
"laravel/tinker": "^2.10.0",
1214
"laravel/ui": "^4.5",
@@ -15,7 +17,7 @@
1517
"require-dev": {
1618
"fakerphp/faker": "^1.23.1",
1719
"friendsofphp/php-cs-fixer": "^3.53",
18-
"gomzyakov/php-cs-fixer-config": "^1.75",
20+
"gomzyakov/code-style": "^2.1",
1921
"mockery/mockery": "^1.6",
2022
"nunomaduro/collision": "^8.0",
2123
"phpstan/phpstan": "^1.10",
@@ -38,10 +40,10 @@
3840
"scripts": {
3941
"phpunit": "@php ./vendor/bin/phpunit ./tests --no-coverage --color=always",
4042
"phpstan": "@php ./vendor/bin/phpstan analyze -c ./phpstan.neon.dist --no-progress --ansi --verbose",
43+
"fix": "@php ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php",
4144
"cs-check": "@php ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --dry-run --diff",
42-
"cs-fix": "@php ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php",
45+
"rector": "@php ./vendor/bin/rector process",
4346
"rector-check": "@php ./vendor/bin/rector process --dry-run",
44-
"rector-fix": "@php ./vendor/bin/rector process",
4547
"test": [
4648
"@cs-check",
4749
"@phpstan",

composer.lock

Lines changed: 119 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

database/factories/PostFactory.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
use Illuminate\Database\Eloquent\Factories\Factory;
77
use Illuminate\Support\Str;
88

9-
use function mt_rand;
10-
119
/**
1210
* @extends Factory<Post>
1311
*/
@@ -23,8 +21,8 @@ public function definition(): array
2321
return [
2422
'title' => $title = fake()->text(100),
2523
'slug' => Str::slug($title),
26-
'preview_image' => 'https://loremflickr.com/640/480?random=' . mt_rand(1, 9999),
27-
'main_image' => 'https://loremflickr.com/640/480?random=' . mt_rand(1, 9999),
24+
'preview_image' => route('placeholder.generate', ['width' => 640, 'height' => 480, 'seed' => Str::slug($title) . '-preview']),
25+
'main_image' => route('placeholder.generate', ['width' => 640, 'height' => 480, 'seed' => Str::slug($title) . '-main']),
2826
'content' => fake()->realText(5000),
2927
];
3028
}

routes/web.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use App\Http\Controllers\AboutController;
44
use App\Http\Controllers\ContactsController;
5+
use App\Http\Controllers\PlaceholderController;
56
use App\Http\Controllers\PostController;
67
use Illuminate\Support\Facades\Auth;
78
use Illuminate\Support\Facades\Route;
@@ -19,6 +20,11 @@
1920

2021
Route::get('/', [PostController::class, 'showHomepage'])->name('main.index');
2122

23+
// Placeholder image generation
24+
Route::get('/placeholder/{width}/{height}', [PlaceholderController::class, 'generate'])
25+
->where(['width' => '[0-9]+', 'height' => '[0-9]+'])
26+
->name('placeholder.generate');
27+
2228
Auth::routes(['verify' => false]);
2329

2430
Route::prefix('contacts')->group(function () {

0 commit comments

Comments
 (0)