Skip to content

Commit

Permalink
Optimized PersonPhotos class
Browse files Browse the repository at this point in the history
  • Loading branch information
MGeurts committed Nov 10, 2024
1 parent cdac6ed commit 01d2d67
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 95 deletions.
3 changes: 2 additions & 1 deletion app/Livewire/People/Add/Child.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ public function saveChild()
}

if ($this->photos) {
PersonPhotos::save($new_person, $this->photos);
$personPhotos = new PersonPhotos($new_person);
$personPhotos->save($this->photos);
}

$this->toast()->success(__('app.create'), $new_person->name . ' ' . __('app.created') . '.')->flash()->send();
Expand Down
3 changes: 2 additions & 1 deletion app/Livewire/People/Add/Father.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ public function saveFather()
]);

if ($this->photos) {
PersonPhotos::save($new_person, $this->photos);
$personPhotos = new PersonPhotos($new_person);
$personPhotos->save($this->photos);
}

$this->person->update([
Expand Down
3 changes: 2 additions & 1 deletion app/Livewire/People/Add/Mother.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ public function saveMother()
]);

if ($this->photos) {
PersonPhotos::save($new_person, $this->photos);
$personPhotos = new PersonPhotos($new_person);
$personPhotos->save($this->photos);
}

$this->person->update([
Expand Down
3 changes: 2 additions & 1 deletion app/Livewire/People/Add/Partner.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ public function savePartner()
]);

if ($this->photos) {
PersonPhotos::save($new_person, $this->photos);
$personPhotos = new PersonPhotos($new_person);
$personPhotos->save($this->photos);
}

$this->toast()->success(__('app.create'), $new_person->name . ' ' . __('app.created') . '.')->flash()->send();
Expand Down
3 changes: 2 additions & 1 deletion app/Livewire/People/Add/Person.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ public function savePerson()
]);

if ($this->photos) {
PersonPhotos::save($new_person, $this->photos);
$personPhotos = new PersonPhotos($new_person);
$personPhotos->save($this->photos);
}

$this->toast()->success(__('app.save'), $new_person->name . ' ' . __('app.created'))->flash()->send();
Expand Down
3 changes: 2 additions & 1 deletion app/Livewire/People/Edit/Photos.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ public function updatedUploads(): void
public function save()
{
if ($this->uploads) {
PersonPhotos::save($this->person, $this->uploads);
$personPhotos = new PersonPhotos($this->person);
$personPhotos->save($this->uploads);

$this->toast()->success(__('app.save'), trans_choice('person.photos_saved', count($this->uploads)))->send();

Expand Down
191 changes: 107 additions & 84 deletions app/PersonPhotos.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,98 +12,121 @@

class PersonPhotos
{
// -----------------------------------------------------------------------
// save all photos
// -----------------------------------------------------------------------
public static function save(?Person $person = null, $photos = []): void
protected Person $person;

protected ImageManager $imageManager;

protected array $config;

public function __construct(Person $person)
{
$this->person = $person;

$this->imageManager = new ImageManager(new Driver);

$this->config = config('app.image_upload');
}

public function save(array $photos): void
{
if ($person and $photos) {
// if needed, create folders
if (! storage::disk('photos')->exists(strval($person->team_id))) {
Storage::disk('photos')->makeDirectory(strval($person->team_id));
Storage::disk('photos-096')->makeDirectory(strval($person->team_id));
Storage::disk('photos-384')->makeDirectory(strval($person->team_id));
if (empty($photos)) {
return;
}

$this->ensureDirectoriesExist();

$lastIndex = $this->getLastImageIndex();

foreach ($photos as $photo) {
$this->savePhoto($photo, ++$lastIndex);
}

$this->cleanupTemporaryFiles();
}

protected function ensureDirectoriesExist(): void
{
$teamId = (string) $this->person->team_id;

foreach (['photos', 'photos-096', 'photos-384'] as $disk) {
if (! Storage::disk($disk)->exists($teamId)) {
Storage::disk($disk)->makeDirectory($teamId);
}
}
}

protected function getLastImageIndex(): int
{
$files = File::glob(public_path() . '/storage/photos/' . $this->person->team_id . '/' . $this->person->id . '_*.webp');

if ($files) {
$lastFile = last($files);

return (int) substr($lastFile, strpos($lastFile, '_') + 1, strrpos($lastFile, '_') - strpos($lastFile, '_') - 1);
}

return 0;
}

protected function savePhoto($photo, int $index): void
{
$timestamp = now()->format('YmdHis');
$imageName = "{$this->person->id}_" . str_pad((string) $index, 3, '0', STR_PAD_LEFT) . "_{$timestamp}.{$this->config['type']}";

// set image parameters
$image_width = config('app.image_upload_max_width');
$image_height = config('app.image_upload_max_height');
$image_quality = config('app.image_upload_quality');
$image_type = config('app.image_upload_type');
$image_add_watermark = config('app.image_upload_add_watermark');

// set image manager
$manager = new ImageManager(new Driver);

// determine last index
$files = File::glob(public_path() . '/storage/photos/' . $person->team_id . '/' . $person->id . '_*.webp');
$last_index = $files ? intval(substr(last($files), strpos(last($files), '_') + 1, strrpos(last($files), '_') - strpos(last($files), '_') - 1)) : 0;

foreach ($photos as $current_photo) {
// image name
$next_index = str_pad(strval(++$last_index), 3, '0', STR_PAD_LEFT);
$image_name = $person->id . '_' . $next_index . '_' . now()->format('YmdHis') . '.' . $image_type;

if ($image_add_watermark) {
// image: resize, add watermark and save
$manager->read($current_photo)
->scaleDown(width: $image_width, height: $image_height)
->place(public_path('img/watermark.png'), 'bottom-left', 5, 5)
->toWebp(quality: $image_quality)
->save(storage_path('app/public/photos/' . $person->team_id . '/' . $image_name));

// image : resize width 96px, add watermark and save
$manager->read($current_photo)
->scaleDown(width: 96)
->place(public_path('img/watermark.png'), 'bottom-left', 5, 5)
->toWebp(quality: $image_quality)
->save(storage_path('app/public/photos-096/' . $person->team_id . '/' . $image_name));

// image : resize width 384px, add watermark and save
$manager->read($current_photo)
->scaleDown(width: 384)
->place(public_path('img/watermark.png'), 'bottom-left', 5, 5)
->toWebp(quality: $image_quality)
->save(storage_path('app/public/photos-384/' . $person->team_id . '/' . $image_name));
} else {
// image: resize and save
$manager->read($current_photo)
->scaleDown(width: $image_width, height: $image_height)
->toWebp(quality: $image_quality)
->save(storage_path('app/public/photos/' . $person->team_id . '/' . $image_name));

// image : resize width 96px and save
$manager->read($current_photo)
->scaleDown(width: 96)
->toWebp(quality: $image_quality)
->save(storage_path('app/public/photos-096/' . $person->team_id . '/' . $image_name));

// image : resize width 384px and save
$manager->read($current_photo)
->scaleDown(width: 384)
->toWebp(quality: $image_quality)
->save(storage_path('app/public/photos-384/' . $person->team_id . '/' . $image_name));
}

// update person: photo
if (! isset($person->photo)) {
$person->update(['photo' => $image_name]);
}
if ($this->config['add_watermark']) {
$this->processAndSaveImage($photo, $imageName, true);
} else {
$this->processAndSaveImage($photo, $imageName, false);
}

if (empty($this->person->photo)) {
$this->person->update(['photo' => $imageName]);
}
}

protected function processAndSaveImage($photo, string $imageName, bool $addWatermark): void
{
$paths = [
'photos' => [
'width' => $this->config['max_width'],
'height' => $this->config['max_height'],
],
'photos-096' => [
'width' => 96,
'height' => null,
],
'photos-384' => [
'width' => 384,
'height' => null,
],
];

foreach ($paths as $disk => $dimensions) {
$image = $this->imageManager
->read($photo)
->scaleDown(
width: $dimensions['width'],
height: $dimensions['height']
);

if ($addWatermark) {
$image->place(public_path('img/watermark.png'), 'bottom-left', 5, 5);
}

// cleanup : livewire-tmp (delete files older than 1 day)
$yesterdaysStamp = now()->subDay()->timestamp;
$image
->toWebp(quality: $this->config['quality'])
->save(storage_path("app/public/{$disk}/{$this->person->team_id}/{$imageName}"));
}
}

foreach (Storage::files('livewire-tmp') as $file) {
if (! Storage::exists($file)) {
continue;
}
protected function cleanupTemporaryFiles(): void
{
$oneDayAgo = now()->subDay()->timestamp;

if ($yesterdaysStamp > Storage::lastModified($file)) {
Storage::delete($file);
}
foreach (Storage::files('livewire-tmp') as $file) {
if (Storage::lastModified($file) < $oneDayAgo) {
Storage::delete($file);
}
}
}
// -----------------------------------------------------------------------
}
12 changes: 7 additions & 5 deletions config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,11 @@
'backup_daily_run' => env('BACKUP_DAILY_RUN', '23:00'),
'backup_mail_address' => env('BACKUP_MAIL_ADDRESS', '[email protected]'),

'image_upload_max_width' => (int) env('IMAGE_UPLOAD_MAX_WIDTH', 600),
'image_upload_max_height' => (int) env('IMAGE_UPLOAD_MAX_HEIGHT', 800),
'image_upload_quality' => (int) env('IMAGE_UPLOAD_QUALITY', 80),
'image_upload_type' => env('IMAGE_UPLOAD_TYPE', 'webp'),
'image_upload_add_watermark' => env('IMAGE_UPLOAD_ADD_WATERMARK', true),
'image_upload' => [
'max_width' => (int) env('IMAGE_UPLOAD_MAX_WIDTH', 600),
'max_height' => (int) env('IMAGE_UPLOAD_MAX_HEIGHT', 800),
'quality' => (int) env('IMAGE_UPLOAD_QUALITY', 80),
'type' => env('IMAGE_UPLOAD_TYPE', 'webp'),
'add_watermark' => env('IMAGE_UPLOAD_ADD_WATERMARK', true),
],
];

0 comments on commit 01d2d67

Please sign in to comment.