Skip to content

Commit

Permalink
Minify profile pictures
Browse files Browse the repository at this point in the history
  • Loading branch information
GeniJaho committed Jan 20, 2024
1 parent 82202b7 commit 4364c6a
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 6 deletions.
5 changes: 4 additions & 1 deletion app/Actions/Fortify/UpdateUserProfileInformation.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Actions\Fortify;

use App\Jobs\MinifyProfilePhoto;
use App\Models\User;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Http\UploadedFile;
Expand All @@ -22,13 +23,15 @@ public function update(User $user, array $input): void
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
'photo' => ['nullable', 'mimes:jpg,jpeg,png', 'max:1024'],
'photo' => ['nullable', 'mimes:jpg,jpeg,png', 'max:15360'], // 15MB
])->validateWithBag('updateProfileInformation');

if (isset($input['photo'])) {
/** @var UploadedFile $photo */
$photo = $input['photo'];
$user->updateProfilePhoto($photo);

MinifyProfilePhoto::dispatch($user);
}

if ($input['email'] !== $user->email &&
Expand Down
5 changes: 2 additions & 3 deletions app/Actions/Photos/ExtractLocationFromPhotoAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
namespace App\Actions\Photos;

use Illuminate\Http\UploadedFile;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\ImageManager;

class ExtractLocationFromPhotoAction implements ExtractsLocationFromPhoto
{
public function run(UploadedFile $photo): array
{
$manager = new ImageManager(new Driver());
$image = $manager->read($photo);
$image = ImageManager::gd()->read($photo);

$exif = $image->exif('GPS');

if ($this->isExifInvalid($exif)) {
Expand Down
37 changes: 37 additions & 0 deletions app/Jobs/MinifyProfilePhoto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace App\Jobs;

use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManager;

class MinifyProfilePhoto implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;

public function __construct(public readonly User $user)
{
}

public function handle(): void
{
if ($this->user->profile_photo_path === null) {
return;
}

$photo = Storage::disk('public')->path($this->user->profile_photo_path);

$image = ImageManager::gd()->read($photo);
$image->scaleDown(height: 500);
$image->save(quality: 50);
}
}
14 changes: 13 additions & 1 deletion tests/Feature/Auth/ProfileInformationTest.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
<?php

use App\Jobs\MinifyProfilePhoto;
use App\Models\User;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Storage;

test('profile information can be updated', function () {
Queue::fake();
Storage::fake('public');
$this->actingAs($user = User::factory()->create());

$response = $this->put('/user/profile-information', [
'name' => 'Test Name',
'email' => '[email protected]',
'photo' => UploadedFile::fake()->image('photo.png'),
]);

$response->assertRedirect();
expect($user->fresh())
->name->toEqual('Test Name')
->email->toEqual('[email protected]');
->email->toEqual('[email protected]')
->profile_photo_path->not()->toBeNull();

Storage::disk('public')->assertExists($user->fresh()->profile_photo_path);
Queue::assertPushed(MinifyProfilePhoto::class);
});
29 changes: 29 additions & 0 deletions tests/Feature/Jobs/MinifyProfilePhotoTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use App\Jobs\MinifyProfilePhoto;
use App\Models\User;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Drivers\Gd\Driver;

test('it minifies the profile photo', function () {
Storage::fake('public');
Storage::disk('public')->put(
'profile-photos/default.jpg',
Storage::disk('local')->get('default.jpg')
);
$user = User::factory()->create([
'profile_photo_path' => 'profile-photos/default.jpg',
]);
$previousSize = Storage::disk('public')->size($user->profile_photo_path);

$action = new MinifyProfilePhoto($user);
$action->handle(new Driver());

$this->assertFileExists(
Storage::disk('public')->path($user->profile_photo_path)
);
$this->assertLessThan(
$previousSize,
Storage::disk('public')->size($user->profile_photo_path)
);
})->group('slow');
2 changes: 1 addition & 1 deletion tests/Feature/Photos/UploadPhotosTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
$photo = $user->photos()->first();
expect($photo->latitude)->toBe(40.053030045789)
->and($photo->longitude)->toBe(-77.15449870066);
});
})->group('slow');

test('a photo can not be larger than 20MB', function () {
Storage::fake('public');
Expand Down

0 comments on commit 4364c6a

Please sign in to comment.