feature: add index endpoint for products
- implement DTO for product and modify productImageDTO. - add products resources and collection.
This commit is contained in:
parent
aef951f71d
commit
920666c201
53
backend/app/Data/ProductDTO.php
Normal file
53
backend/app/Data/ProductDTO.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Data;
|
||||||
|
|
||||||
|
use App\Contracts\OutputDataTransferObject;
|
||||||
|
use App\Models\Product;
|
||||||
|
use App\Models\ProductImage;
|
||||||
|
|
||||||
|
final readonly class ProductDTO implements OutputDataTransferObject
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param ProductImageDTO[] $productImages
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public int $id,
|
||||||
|
public string $title,
|
||||||
|
public string $description,
|
||||||
|
public int $actualPrice,
|
||||||
|
public int $listPrice,
|
||||||
|
public ProductCategoryDTO $category,
|
||||||
|
public array $productImages,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'title' => $this->title,
|
||||||
|
'description' => $this->description,
|
||||||
|
'actualPrice' => $this->actualPrice,
|
||||||
|
'listPrice' => $this->listPrice,
|
||||||
|
'category' => $this->category->toArray(),
|
||||||
|
'productImage' => array_map(fn (ProductImageDTO $productImage) => $productImage->toArray(),
|
||||||
|
$this->productImages),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromModel(Product $product): self
|
||||||
|
{
|
||||||
|
return new self(
|
||||||
|
id: $product->id,
|
||||||
|
title: $product->title,
|
||||||
|
description: $product->description,
|
||||||
|
actualPrice: $product->actual_price,
|
||||||
|
listPrice: $product->list_price,
|
||||||
|
category: ProductCategoryDTO::fromModel($product->category),
|
||||||
|
productImages: $product->images->map(fn (ProductImage $productImage) => ProductImageDTO::fromModel($productImage))->all(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@
|
|||||||
namespace App\Data;
|
namespace App\Data;
|
||||||
|
|
||||||
use App\Contracts\OutputDataTransferObject;
|
use App\Contracts\OutputDataTransferObject;
|
||||||
|
use App\Models\ProductImage;
|
||||||
|
|
||||||
final readonly class ProductImageDTO implements OutputDataTransferObject
|
final readonly class ProductImageDTO implements OutputDataTransferObject
|
||||||
{
|
{
|
||||||
@ -23,4 +24,13 @@ public function toArray(): array
|
|||||||
'productId' => $this->productId,
|
'productId' => $this->productId,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function fromModel(ProductImage $productImage): self
|
||||||
|
{
|
||||||
|
return new self(
|
||||||
|
$productImage->id,
|
||||||
|
$productImage->path,
|
||||||
|
$productImage->product_id
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,13 +2,21 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Data\ProductDTO;
|
||||||
use App\Http\Requests\CreateProductRequest;
|
use App\Http\Requests\CreateProductRequest;
|
||||||
|
use App\Http\Resources\ProductResource;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class ProductController extends Controller
|
class ProductController extends Controller
|
||||||
{
|
{
|
||||||
public function index() {}
|
public function index()
|
||||||
|
{
|
||||||
|
$paginator = Product::query()->with(['category:id,name,slug', 'images:id,path,product_id'])->paginate();
|
||||||
|
$paginatedDtos = $paginator->through(fn ($product) => ProductDTO::fromModel($product));
|
||||||
|
|
||||||
|
return ProductResource::collection($paginatedDtos);
|
||||||
|
}
|
||||||
|
|
||||||
public function store(CreateProductRequest $request)
|
public function store(CreateProductRequest $request)
|
||||||
{
|
{
|
||||||
|
|||||||
16
backend/app/Http/Resources/ProductCollection.php
Normal file
16
backend/app/Http/Resources/ProductCollection.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||||
|
|
||||||
|
class ProductCollection extends ResourceCollection
|
||||||
|
{
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'data' => $this->collection,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
18
backend/app/Http/Resources/ProductResource.php
Normal file
18
backend/app/Http/Resources/ProductResource.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Data\ProductDTO;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property ProductDTO $resource
|
||||||
|
*/
|
||||||
|
class ProductResource extends JsonResource
|
||||||
|
{
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return $this->resource->toArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,9 +16,9 @@ class Product extends Model
|
|||||||
'product_category_id',
|
'product_category_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function productCategory(): BelongsTo
|
public function category(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(ProductCategory::class);
|
return $this->belongsTo(ProductCategory::class, 'product_category_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function images(): HasMany
|
public function images(): HasMany
|
||||||
|
|||||||
@ -15,6 +15,6 @@
|
|||||||
Route::get('/user', [AuthenticatedUserController::class, 'show']);
|
Route::get('/user', [AuthenticatedUserController::class, 'show']);
|
||||||
Route::post('/logout', [AuthenticatedUserController::class, 'destroy']);
|
Route::post('/logout', [AuthenticatedUserController::class, 'destroy']);
|
||||||
Route::post('/upload/images', action: [ProductImagesController::class, 'store']);
|
Route::post('/upload/images', action: [ProductImagesController::class, 'store']);
|
||||||
Route::apiResource('products', ProductController::class);
|
|
||||||
});
|
});
|
||||||
Route::get('/categories', [ProductCategoryController::class, 'index']);
|
Route::get('/categories', [ProductCategoryController::class, 'index']);
|
||||||
|
Route::apiResource('products', ProductController::class);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user