Skip to content

Commit e3b1582

Browse files
authored
Merge pull request #64 from dcblogdev/refactor-to-use-actions
refactor image handling by introducing action classes
2 parents e12ab05 + 83bbcde commit e3b1582

18 files changed

+464
-370
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions;
6+
7+
use Carbon\Carbon;
8+
use DateTime;
9+
use Exception;
10+
11+
class GetFormattedDateAction
12+
{
13+
/**
14+
* @throws Exception
15+
*/
16+
public function __invoke(null|string|Carbon $date): string
17+
{
18+
if ($date === null) {
19+
return '';
20+
}
21+
22+
return is_string($date) ? (new DateTime($date))->format('Y-m-d') : $date->format('Y-m-d');
23+
}
24+
}

app/Actions/GetInitialsAction.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions;
6+
7+
class GetInitialsAction
8+
{
9+
public function __invoke(?string $name = ''): string
10+
{
11+
if (empty($name)) {
12+
return '';
13+
}
14+
15+
$parts = explode(' ', $name);
16+
17+
$initials = strtoupper($parts[0][0] ?? '');
18+
19+
if (count($parts) > 1) {
20+
$initials .= strtoupper(end($parts)[0] ?? '');
21+
}
22+
23+
return $initials;
24+
}
25+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Images;
6+
7+
use Illuminate\Support\Facades\Storage;
8+
9+
class DeleteImageAction
10+
{
11+
public function __invoke(string $path, string $disk = 'public'): void
12+
{
13+
Storage::disk($disk)->delete($path);
14+
}
15+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Images;
6+
7+
use Illuminate\Http\UploadedFile;
8+
use Intervention\Image\Drivers\Gd\Driver;
9+
use Intervention\Image\ImageManager;
10+
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
11+
12+
class ResizeImageAction
13+
{
14+
public function __invoke(string|TemporaryUploadedFile|UploadedFile $image, int $width = 800, ?int $height = null): string
15+
{
16+
$manager = new ImageManager(new Driver);
17+
18+
return $manager
19+
->read($image)
20+
->scale(width: $width, height: $height)
21+
->encode()
22+
->toString();
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Images;
6+
7+
use Illuminate\Http\UploadedFile;
8+
use Illuminate\Support\Facades\Storage;
9+
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
10+
11+
class StoreUploadedImageAction
12+
{
13+
public function __invoke(TemporaryUploadedFile|UploadedFile $image, string $destinationFolder, string $disk = 'public', int $width = 800, ?int $height = null): string
14+
{
15+
$name = md5(random_int(1, 10).microtime()).'.jpg';
16+
$img = app(ResizeImageAction::class)($image, $width, $height);
17+
18+
$destinationFolder = rtrim($destinationFolder, DIRECTORY_SEPARATOR);
19+
20+
Storage::disk($disk)->put($destinationFolder.DIRECTORY_SEPARATOR.$name, $img);
21+
22+
return $destinationFolder.DIRECTORY_SEPARATOR.$name;
23+
}
24+
}

app/Http/Controllers/Admin/UploadController.php

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44

55
namespace App\Http\Controllers\Admin;
66

7+
use App\Actions\Images\StoreUploadedImageAction;
78
use App\Http\Controllers\Controller;
89
use Illuminate\Http\JsonResponse;
910
use Illuminate\Http\Request;
1011
use Illuminate\Http\UploadedFile;
11-
use Illuminate\Support\Facades\Storage;
12-
use Illuminate\Support\Str;
13-
use Intervention\Image\Facades\Image;
1412

1513
class UploadController extends Controller
1614
{
@@ -33,20 +31,11 @@ public function __invoke(Request $request): JsonResponse
3331
return response()->json(['error' => 'Invalid upload'], 400);
3432
}
3533

36-
$originalName = $file->getClientOriginalName();
37-
$extension = $file->getClientOriginalExtension();
38-
39-
$name = Str::slug(date('Y-m-d-h-i-s').'-'.pathinfo($originalName, PATHINFO_FILENAME));
40-
$image = Image::make($file);
41-
42-
$imageString = $image->stream()->__toString();
43-
$name = "$name.$extension";
44-
45-
Storage::disk('images')
46-
->put('uploads/'.$name, $imageString);
34+
/** @var UploadedFile $file */
35+
$image = (new StoreUploadedImageAction)($file, 'images', width: 400);
4736

4837
return response()->json([
49-
'url' => "/images/uploads/$name",
38+
'url' => storage_url($image),
5039
]);
5140
}
5241

app/Http/helpers.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,11 @@ function get_initials(string $name): string
6565
}
6666

6767
if (! function_exists('create_avatar')) {
68-
function create_avatar(string $name, string $filename, string $path): string
68+
function create_avatar(string $name, string $filename, string $path, string $disk = 'public'): string
6969
{
70-
$avatar = new LasseRafn\InitialAvatarGenerator\InitialAvatar;
71-
$source = $avatar->background('#000')->color('#fff')->name($name)->generate()->stream();
70+
Storage::disk($disk)->makeDirectory($path);
7271

73-
Storage::disk('public')->put($path.$filename, $source);
72+
Avatar::create($name)->save(Storage::disk($disk)->path($path.$filename), 100);
7473

7574
return $path.$filename;
7675
}

app/Livewire/Admin/Users/Edit/Profile.php

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
namespace App\Livewire\Admin\Users\Edit;
66

7+
use App\Actions\Images\DeleteImageAction;
8+
use App\Actions\Images\StoreUploadedImageAction;
79
use App\Models\User;
810
use Illuminate\Contracts\View\View;
9-
use Illuminate\Support\Facades\Storage;
1011
use Illuminate\Support\Str;
1112
use Illuminate\Validation\ValidationException;
12-
use Intervention\Image\Facades\Image;
1313
use Livewire\Component;
1414
use Livewire\WithFileUploads;
1515

@@ -68,13 +68,6 @@ protected function rules(): array
6868
];
6969
}
7070

71-
/**
72-
* @var array<string, string>
73-
*/
74-
protected array $messages = [
75-
'name.required' => 'Name is required',
76-
];
77-
7871
/**
7972
* @throws ValidationException
8073
*/
@@ -83,33 +76,21 @@ public function updated(string $propertyName): void
8376
$this->validateOnly($propertyName);
8477
}
8578

86-
public function update(): void
79+
public function update(DeleteImageAction $deleteImageAction, StoreUploadedImageAction $storeUploadedImageAction): void
8780
{
88-
$this->validate();
81+
$validated = $this->validate();
82+
83+
if (! blank($this->image)) {
8984

90-
if ($this->image !== '' && $this->image !== null) {
9185
if ($this->user->image !== null) {
92-
Storage::disk('public')->delete($this->user->image);
86+
$deleteImageAction($this->user->image);
9387
}
9488

95-
$token = md5(random_int(1, 10).microtime());
96-
$name = $token.'.jpg';
97-
$img = Image::make($this->image)->encode('jpg')->resize(100, null, function (object $constraint) {
98-
/** @phpstan-ignore-next-line */
99-
$constraint->aspectRatio();
100-
});
101-
$img->stream();
102-
103-
// @phpstan-ignore-next-line
104-
Storage::disk('public')->put('users/'.$name, $img);
105-
106-
$this->user->image = 'users/'.$name;
89+
$validated['image'] = $storeUploadedImageAction($this->image, 'users', width: 400);
10790
}
10891

109-
$this->user->name = $this->name;
11092
$this->user->slug = Str::slug($this->name);
111-
$this->user->email = $this->email;
112-
$this->user->save();
93+
$this->user->update($validated);
11394

11495
add_user_log([
11596
'title' => 'updated '.$this->name."'s profile",

app/Livewire/Admin/Users/Invite.php

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,59 @@
44

55
namespace App\Livewire\Admin\Users;
66

7+
use App\Actions\GetInitialsAction;
78
use App\Mail\Users\SendInviteMail;
89
use App\Models\Role;
910
use App\Models\User;
1011
use Illuminate\Contracts\View\View;
1112
use Illuminate\Support\Facades\Mail;
1213
use Illuminate\Support\Str;
1314
use Illuminate\Validation\ValidationException;
14-
use Livewire\Attributes\Rule;
15-
use Livewire\Attributes\Validate;
1615
use Livewire\Component;
1716
use Livewire\WithPagination;
1817

1918
class Invite extends Component
2019
{
2120
use withPagination;
2221

23-
#[Rule('required', message: 'Please enter a name')]
2422
public string $name = '';
2523

26-
#[Rule('required', as: 'email', message: 'Please enter an email address')]
27-
#[Rule('email', message: 'The email must be a valid email address.')]
28-
#[Rule('unique:users,email')]
2924
public string $email = '';
3025

3126
/**
3227
* @var array<int>
3328
*/
34-
#[Validate('required', 'min:1', as: 'role', message: 'Please select at least one role')]
3529
public array $rolesSelected = [];
3630

31+
/**
32+
* @var array<string, array<int, string>>
33+
*/
34+
protected array $rules = [
35+
'name' => [
36+
'required',
37+
'string',
38+
],
39+
'email' => [
40+
'required',
41+
'string',
42+
'email',
43+
'unique:users,email',
44+
],
45+
'rolesSelected' => [
46+
'required',
47+
'min:1',
48+
],
49+
];
50+
51+
/**
52+
* @var array<string, string>
53+
*/
54+
protected array $messages = [
55+
'name.required' => 'Name is required',
56+
'email.required' => 'Email is required',
57+
'rolesSelected.required' => 'A role is required',
58+
];
59+
3760
/**
3861
* @throws ValidationException
3962
*/
@@ -49,7 +72,7 @@ public function render(): View
4972
return view('livewire.admin.users.invite', compact('roles'));
5073
}
5174

52-
public function store(): void
75+
public function store(GetInitialsAction $getInitialsAction): void
5376
{
5477
$this->validate();
5578

@@ -65,7 +88,7 @@ public function store(): void
6588
]);
6689

6790
// generate image
68-
$name = get_initials($user->name);
91+
$name = $getInitialsAction($user->name);
6992
$id = $user->id.'.png';
7093
$path = 'users/';
7194
$imagePath = create_avatar($name, $id, $path);

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
"php": "^8.2",
1212
"blade-ui-kit/blade-heroicons": "^2.6",
1313
"guzzlehttp/guzzle": "^7.9.3",
14-
"intervention/image": "^2.7.2",
14+
"intervention/image": "^3.7.2",
1515
"laracasts/flash": "^3.2.4",
1616
"laravel/framework": "^12.12.0",
1717
"laravel/sanctum": "^4.1.1",
1818
"laravel/tinker": "^2.10.1",
19-
"lasserafn/php-initial-avatar-generator": "^4.4",
19+
"laravolt/avatar": "^6.2",
2020
"livewire/livewire": "^3.6.3",
2121
"robthree/twofactorauth": "^1.8.2",
2222
"spatie/laravel-permission": "^6.17.0"

0 commit comments

Comments
 (0)