Skip to content

Commit

Permalink
When uploading profile picture 3 different sized are created (#17)
Browse files Browse the repository at this point in the history
- full size is used for Character Profile view
- small size used for Messages
  • Loading branch information
mchekin authored Dec 16, 2018
1 parent fe990ff commit 786dfe9
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 43 deletions.
38 changes: 32 additions & 6 deletions app/Character.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use App\Contracts\Models\LocationInterface;
use App\Contracts\Models\RaceInterface;
use App\Contracts\Models\UserInterface;
use App\Services\FilesystemService\ImageFiles;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
Expand Down Expand Up @@ -154,19 +155,32 @@ public function isNPC(): bool
return is_null($this->user);
}

public function getImage(): string
public function getProfilePictureFull(): string
{
if ($this->profilePicture()->exists())
{
/** @var ImageInterface $image */
$image = $this->profilePicture()->first();

return $image->getFilename();
return $image->getFilePathFull();
}

return $this->race->getImageByGender($this->gender);
}

public function getProfilePictureSmall(): string
{
if ($this->profilePicture()->exists())
{
/** @var ImageInterface $image */
$image = $this->profilePicture()->first();

return $image->getFilePathSmall();
}

return 'svg/avatar.svg';
}

public function getRaceName(): string
{
return $this->race->getName();
Expand Down Expand Up @@ -346,19 +360,21 @@ public function getLocationId(): int
return $this->location_id;
}

public function addImage(string $fileName): ImageInterface
public function addImage(ImageFiles $imageFiles): ImageInterface
{
/** @var ImageInterface $image */
$image = $this->images()->create([
'filename' => $fileName,
'file_path_full' => $imageFiles->getFullSizePath(),
'file_path_small' => $imageFiles->getSmallSizePath(),
'file_path_icon' => $imageFiles->getIconSizePath(),
]);

return $image;
}

public function addProfilePicture(string $fileName): CharacterInterface
public function addProfilePicture(ImageFiles $imageFiles): CharacterInterface
{
$image = $this->addImage($fileName);
$image = $this->addImage($imageFiles);

$this->profilePicture()->associate($image)->save();

Expand All @@ -373,4 +389,14 @@ public function isOnline(): bool

return $this->user->isOnline();
}

public function getHitPoints(): int
{
return $this->hit_points;
}

public function getTotalHitPoints(): int
{
return $this->total_hit_points;
}
}
14 changes: 10 additions & 4 deletions app/Contracts/Models/CharacterInterface.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php

namespace App\Contracts\Models;
use App\Services\FilesystemService\ImageFiles;
use Illuminate\Http\Request;

interface CharacterInterface
{

public static function createCharacter(Request $request, RaceInterface $race): CharacterInterface;

public function getId();
Expand All @@ -26,7 +26,9 @@ public function isNPC(): bool;

public function isOnline(): bool;

public function getImage(): string;
public function getProfilePictureFull(): string;

public function getProfilePictureSmall(): string;

public function getRaceName(): string;

Expand All @@ -52,7 +54,11 @@ public function applyDamage($damageDone): CharacterInterface;

public function getLocationId(): int;

public function addImage(string $fileName): ImageInterface;
public function addImage(ImageFiles $imageFiles): ImageInterface;

public function addProfilePicture(ImageFiles $imageFiles): CharacterInterface;

public function getHitPoints(): int;

public function addProfilePicture(string $fileName): CharacterInterface;
public function getTotalHitPoints(): int;
}
6 changes: 5 additions & 1 deletion app/Contracts/Models/ImageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@ interface ImageInterface
{
public function getId(): int;

public function getFilename(): string;
public function getFilePathFull(): string;

public function getFilePathSmall(): string;

public function getFilePathIcon(): string;
}
9 changes: 2 additions & 7 deletions app/Http/Controllers/ImageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,10 @@ public function store(UploadImageRequest $request, FilesystemService $filesystem
$authenticatedUser = $request->user();
$character = $authenticatedUser->getCharacter();

$imageFile = $filesystemService->writeImage($request->file('file'));
$imageFiles = $filesystemService->writeImage($request->file('file'), $authenticatedUser);

$character->addProfilePicture(
'storage'. DIRECTORY_SEPARATOR
. 'images' .DIRECTORY_SEPARATOR
. $imageFile->basename
);
$character->addProfilePicture($imageFiles);

return back()->with('status', 'Profile picture has been changed');

}
}
23 changes: 19 additions & 4 deletions app/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,37 @@
use Illuminate\Database\Eloquent\Model;

/**
* @property string filename
* @property string file_path_full
* @property string file_path_small
* @property string file_path_icon
* @property int id
*/
class Image extends Model implements ImageInterface
{
protected $fillable = [
'filename',
'file_path_full',
'file_path_small',
'file_path_icon',
];

public function getId(): int
{
return $this->id;
}

public function getFilename(): string

public function getFilePathFull(): string
{
return $this->file_path_full;
}

public function getFilePathSmall(): string
{
return $this->file_path_small;
}

public function getFilePathIcon(): string
{
return $this->filename;
return $this->file_path_icon;
}
}
53 changes: 42 additions & 11 deletions app/Services/FilesystemService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,61 @@

namespace App\Services;

use App\Contracts\Models\UserInterface;
use App\Services\FilesystemService\ImageFiles;
use Illuminate\Support\Facades\File;
use Intervention\Image\Constraint;
use Intervention\Image\Facades\Image as ImageFacade;
use Intervention\Image\Image as ImageFile;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class FilesystemService
{
public function writeImage(UploadedFile $originalImage): ImageFile
{
/** @var ImageFile $image */
$image = ImageFacade::make($originalImage);
const IMAGE_WIDTH_FULL = 1000;
const IMAGE_WIDTH_SMALL = 100;
const IMAGE_WIDTH_ICON = 20;

const AVAILABLE_IMAGE_WIDTHS = [
'full' => self::IMAGE_WIDTH_FULL,
'small' => self::IMAGE_WIDTH_SMALL,
'icon' => self::IMAGE_WIDTH_ICON,
];

const USERS_IMAGES_FOLDER = 'images' . DIRECTORY_SEPARATOR . 'users' . DIRECTORY_SEPARATOR;

$imagesFolder = storage_path(
public function writeImage(UploadedFile $originalImage, UserInterface $user): ImageFiles
{
$fullStorageFolderPath = storage_path(
'app' . DIRECTORY_SEPARATOR
. 'public' . DIRECTORY_SEPARATOR
. 'images' . DIRECTORY_SEPARATOR
. self::USERS_IMAGES_FOLDER
. $user->getId() . DIRECTORY_SEPARATOR
);

$urlPath = 'storage' . DIRECTORY_SEPARATOR
. self::USERS_IMAGES_FOLDER
. $user->getId() . DIRECTORY_SEPARATOR;

// creating directory if not exists
File::exists($fullStorageFolderPath) or File::makeDirectory($fullStorageFolderPath);

$fileName = time() . $originalImage->getClientOriginalName();

return $image
->resize(400, null, function (Constraint $constraint) {
$constraint->aspectRatio();
})
->save($imagesFolder . $fileName);
$imageFiles = new ImageFiles($urlPath);

foreach (static::AVAILABLE_IMAGE_WIDTHS as $key => $imageWidth) {
/** @var ImageFile $image */
$image = ImageFacade::make($originalImage);

$image
->resize($imageWidth, null, function (Constraint $constraint) {
$constraint->aspectRatio();
})
->save($fullStorageFolderPath . '_' . $key . '_' . $fileName );

$imageFiles->addImageFile($key, $image);
}

return $imageFiles;
}
}
58 changes: 58 additions & 0 deletions app/Services/FilesystemService/ImageFiles.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace App\Services\FilesystemService;

use Illuminate\Support\Collection;
use Intervention\Image\Image;

class ImageFiles extends Collection
{
/**
* @var string
*/
private $folder;

public function __construct(string $folder, $items = [])
{
parent::__construct($items);

$this->folder = $folder;
}

public function addImageFile($key, Image $image): self
{
$this->offsetSet($key, $image);

return $this;
}

public function getFullSizePath(): string
{
/** @var Image $image */
$image = $this->get('full');

$path = $image ? $this->folder . $image->basename : '';

return $path;
}

public function getSmallSizePath(): string
{
/** @var Image $image */
$image = $this->get('small');

$path = $image ? $this->folder . $image->basename : '';

return $path;
}

public function getIconSizePath(): string
{
/** @var Image $image */
$image = $this->get('icon');

$path = $image ? $this->folder . $image->basename : '';

return $path;
}
}
5 changes: 4 additions & 1 deletion database/migrations/2018_11_19_202701_create_images.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ public function up()
$table->unsignedInteger('character_id')->nullable();
$table->foreign('character_id')->references('id')->on('characters')->onDelete('restrict');

$table->string('filename');
$table->string('file_path_full');
$table->string('file_path_small');
$table->string('file_path_icon');

$table->timestamps();
});
}
Expand Down
7 changes: 4 additions & 3 deletions resources/views/character/show.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
</h2>

<?php
$hpPercent = ($character->hit_points / $character->total_hit_points) * 100
/** @var \App\Contracts\Models\CharacterInterface $character */
$hpPercent = ($character->getHitPoints() / $character->getTotalHitPoints()) * 100
?>

<div class="progress mx-5 my-3">
Expand All @@ -26,11 +27,11 @@
aria-valuenow="{{ $hpPercent }}"
aria-valuemin="0"
aria-valuemax="100">
{{ $character->hit_points }} / {{ $character->total_hit_points }}
{{ $character->getHitPoints() }} / {{ $character->getTotalHitPoints() }}
</div>
</div>

<img class="w-50 mx-auto d-block" src="{{ asset($character->getImage()) }}">
<img class="w-50 mx-auto d-block" src="{{ asset($character->getProfilePictureFull()) }}">

@if($character->isYou())
<div>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/message/partials/sender-card.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</a>
</div>
<div>
<img class="profile-picture" src="{{ asset('svg/avatar.svg') }}" alt="Avatar">
<img class="profile-picture" src="{{ asset($message->sender->getProfilePictureSmall()) }}" alt="Avatar">
</div>
<div>
<small>
Expand Down
3 changes: 0 additions & 3 deletions storage/app/public/.gitignore

This file was deleted.

2 changes: 0 additions & 2 deletions storage/app/public/images/.gitignore

This file was deleted.

0 comments on commit 786dfe9

Please sign in to comment.