1
0
Fork 0

initial commit

This commit is contained in:
Henrik Hautakoski 2026-04-07 23:16:12 +02:00
commit ae93c7e1a6
233 changed files with 20282 additions and 0 deletions

View file

@ -0,0 +1,100 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\ProductIndexRequest;
use App\Http\Resources\ProductResource;
use App\Models\Category;
use App\Models\Product;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
class ProductController extends Controller
{
public function index(ProductIndexRequest $request): AnonymousResourceCollection
{
$query = Product::query()
->with(['category:id,name,slug', 'brand:id,name,slug'])
->active()
->whereNotNull('published_at')
->orderByDesc('published_at')
->orderByDesc('id');
$this->applySearchFilter($query, (string) ($request->validated('q') ?? ''));
$this->applyCategoryFilter($query, $request->validated('category'));
$paginator = $query->paginate(24)->appends($request->query());
return ProductResource::collection($paginator);
}
private function applySearchFilter(Builder $query, string $search): void
{
$search = trim($search);
if ($search !== '') {
$query->where(function (Builder $builder) use ($search): void {
$builder
->where('name', 'like', "%{$search}%")
->orWhere('description', 'like', "%{$search}%")
->orWhere('sku', 'like', "%{$search}%");
});
}
}
private function applyCategoryFilter(Builder $query, mixed $categorySlug): void
{
if (is_string($categorySlug) && $categorySlug !== '') {
$category = Category::query()
->where('slug', $categorySlug)
->first();
if (! $category instanceof Category) {
return;
}
$query->whereIn('category_id', $this->collectDescendantCategoryIds($category->id));
}
}
/**
* @return list<int>
*/
private function collectDescendantCategoryIds(int $rootCategoryId): array
{
/** @var Collection<int, Category> $categories */
$categories = Category::query()
->select(['id', 'parent_id'])
->get();
$byParent = [];
foreach ($categories as $category) {
if ($category->parent_id === null) {
continue;
}
$byParent[$category->parent_id][] = (int) $category->id;
}
$stack = [$rootCategoryId];
$seen = [];
while ($stack !== []) {
$categoryId = array_pop($stack);
if ($categoryId === null || isset($seen[$categoryId])) {
continue;
}
$seen[$categoryId] = true;
foreach ($byParent[$categoryId] ?? [] as $childId) {
$stack[] = $childId;
}
}
return array_map('intval', array_keys($seen));
}
}