Skip to content

Commit 57652a2

Browse files
committed
Enable image uploads for glasses
1 parent 8eed012 commit 57652a2

File tree

8 files changed

+62
-5
lines changed

8 files changed

+62
-5
lines changed

app/Http/Controllers/GlassController.php

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44

55
namespace Kami\Cocktail\Http\Controllers;
66

7+
use Throwable;
78
use Illuminate\Http\Request;
89
use Illuminate\Http\Response;
910
use OpenApi\Attributes as OAT;
1011
use Kami\Cocktail\Models\Glass;
12+
use Kami\Cocktail\Models\Image;
1113
use Illuminate\Http\JsonResponse;
1214
use Kami\Cocktail\OpenAPI as BAO;
1315
use Kami\Cocktail\Http\Requests\GlassRequest;
@@ -44,7 +46,7 @@ public function index(): JsonResource
4446
#[BAO\NotFoundResponse]
4547
public function show(Request $request, int $id): JsonResource
4648
{
47-
$glass = Glass::withCount('cocktails')->findOrFail($id);
49+
$glass = Glass::withCount('cocktails')->with('images')->findOrFail($id);
4850

4951
if ($request->user()->cannot('show', $glass)) {
5052
abort(403);
@@ -73,10 +75,21 @@ public function store(GlassRequest $request): JsonResponse
7375
abort(403);
7476
}
7577

76-
$glass = BAO\Schemas\GlassRequest::fromLaravelRequest($request)->toLaravelModel();
78+
$glassRequest = BAO\Schemas\GlassRequest::fromLaravelRequest($request);
79+
80+
$glass = $glassRequest->toLaravelModel();
7781
$glass->bar_id = bar()->id;
7882
$glass->save();
7983

84+
if (count($glassRequest->images) > 0) {
85+
try {
86+
$imageModels = Image::findOrFail($glassRequest->images);
87+
$glass->attachImages($imageModels);
88+
} catch (Throwable $e) {
89+
abort(500, $e->getMessage());
90+
}
91+
}
92+
8093
return (new GlassResource($glass))
8194
->response()
8295
->setStatusCode(201)
@@ -104,10 +117,21 @@ public function update(int $id, GlassRequest $request): JsonResource
104117
abort(403);
105118
}
106119

107-
$glass = BAO\Schemas\GlassRequest::fromLaravelRequest($request)->toLaravelModel($glass);
120+
$glassRequest = BAO\Schemas\GlassRequest::fromLaravelRequest($request);
121+
122+
$glass = $glassRequest->toLaravelModel($glass);
108123
$glass->updated_at = now();
109124
$glass->save();
110125

126+
if (count($glassRequest->images) > 0) {
127+
try {
128+
$imageModels = Image::findOrFail($glassRequest->images);
129+
$glass->attachImages($imageModels);
130+
} catch (Throwable $e) {
131+
abort(500, $e->getMessage());
132+
}
133+
}
134+
111135
$glass->cocktails->each(fn ($cocktail) => $cocktail->searchable());
112136

113137
return new GlassResource($glass);

app/Http/Filters/GlassQueryFilter.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public function __construct()
2424
->defaultSort('name')
2525
->allowedSorts('name', 'created_at')
2626
->withCount('cocktails')
27+
->with('images')
2728
->filterByBar();
2829
}
2930
}

app/Http/Resources/GlassResource.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
new OAT\Property(property: 'cocktails_count', type: 'integer', example: 32, description: 'The number of cocktails that use this glassware'),
2121
new OAT\Property(property: 'volume', type: 'number', format: 'float', nullable: true, example: 120.0, description: 'The volume of the glassware'),
2222
new OAT\Property(property: 'volume_units', type: 'string', nullable: true, example: 'ml', description: 'The volume units of the glassware'),
23+
new OAT\Property(property: 'images', type: 'array', items: new OAT\Items(type: ImageResource::class), description: 'Glassware images'),
2324
],
2425
required: ['id', 'name', 'description', 'cocktails_count', 'volume', 'volume_units']
2526
)]
@@ -40,6 +41,10 @@ public function toArray($request)
4041
'volume' => $this->volume,
4142
'volume_units' => $this->volume_units,
4243
'cocktails_count' => $this->whenCounted('cocktails'),
44+
'images' => $this->when(
45+
$this->relationLoaded('images'),
46+
fn () => ImageResource::collection($this->images)
47+
),
4348
];
4449
}
4550
}

app/Models/Concerns/HasImages.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function attachImages(Collection $images): void
6060
$disk = Storage::disk('uploads');
6161

6262
foreach ($images as $image) {
63-
if (!$image->isTemp()) { // Dont attach already attached images
63+
if (!$image->isTemporaryImage()) { // Dont attach already attached images
6464
continue;
6565
}
6666

app/Models/Glass.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
namespace Kami\Cocktail\Models;
66

7+
use Illuminate\Support\Str;
78
use Illuminate\Database\Eloquent\Model;
9+
use Kami\Cocktail\Models\Concerns\HasImages;
810
use Kami\Cocktail\Models\Concerns\HasAuthors;
911
use Illuminate\Database\Eloquent\Casts\Attribute;
1012
use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -18,6 +20,17 @@ class Glass extends Model
1820
use HasFactory;
1921
use HasBarAwareScope;
2022
use HasAuthors;
23+
use HasImages;
24+
25+
public function getUploadPath(): string
26+
{
27+
return 'glasses/';
28+
}
29+
30+
public function getSlugAttribute(): string
31+
{
32+
return Str::slug($this->name);
33+
}
2134

2235
/**
2336
* @return Attribute<?float, ?float>

app/Models/Image.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public function getAllBarImages(int $barId): Collection
107107
return $cocktailImages->merge($ingredientImages);
108108
}
109109

110-
public function isTemp(): bool
110+
public function isTemporaryImage(): bool
111111
{
112112
return str_starts_with($this->file_path, 'temp/') || $this->imageable_id === null;
113113
}

app/OpenAPI/Schemas/GlassRequest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ class GlassRequest
1919
public ?float $volume = null;
2020
#[OAT\Property(property: 'volume_units', example: 'ml')]
2121
public ?string $volumeUnits = null;
22+
/** @var array<int> */
23+
#[OAT\Property(items: new OAT\Items(type: 'integer'), description: 'Existing image ids')]
24+
public array $images = [];
2225

2326
public static function fromLaravelRequest(Request $request): self
2427
{
@@ -28,6 +31,7 @@ public static function fromLaravelRequest(Request $request): self
2831
$result->description = $request->input('description');
2932
$result->volume = $request->float('volume');
3033
$result->volumeUnits = $request->input('volume_units');
34+
$result->images = array_map('intval', $request->input('images', []));
3135

3236
return $result;
3337
}

docs/openapi-generated.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9088,6 +9088,11 @@ components:
90889088
- string
90899089
- 'null'
90909090
example: ml
9091+
images:
9092+
description: 'Glassware images'
9093+
type: array
9094+
items:
9095+
$ref: '#/components/schemas/Image'
90919096
type: object
90929097
Image:
90939098
description: 'Image attached to a specific resource'
@@ -10439,6 +10444,11 @@ components:
1043910444
- string
1044010445
- 'null'
1044110446
example: ml
10447+
images:
10448+
description: 'Existing image ids'
10449+
type: array
10450+
items:
10451+
type: integer
1044210452
type: object
1044310453
ImageRequest:
1044410454
required:

0 commit comments

Comments
 (0)