1
0
Fork 0
BitHarbor/backend/app/Http/Controllers/CategoryController.php
2026-04-29 15:35:06 +02:00

64 lines
2 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Http\Resources\CategoryResource;
use App\Models\Category;
use App\Models\Product;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
class CategoryController extends Controller
{
public function index(): AnonymousResourceCollection
{
/** @var Collection<int, Category> $categories */
$categories = Category::query()
->where('active', true)
->select(['id', 'parent_id', 'name', 'slug', 'description', 'sort_order'])
->orderBy('sort_order')
->orderBy('name')
->get();
$directProductCounts = Product::query()
->active()
->whereNotNull('published_at')
->selectRaw('category_id, COUNT(*) as aggregate')
->groupBy('category_id')
->pluck('aggregate', 'category_id');
$childrenByParent = [];
foreach ($categories as $category) {
if ($category->parent_id === null) {
continue;
}
$childrenByParent[$category->parent_id][] = (int) $category->id;
}
$totalCountsByCategory = [];
$countWithDescendants = function (int $categoryId) use (&$countWithDescendants, &$totalCountsByCategory, $childrenByParent, $directProductCounts): int {
if (isset($totalCountsByCategory[$categoryId])) {
return $totalCountsByCategory[$categoryId];
}
$total = (int) ($directProductCounts[$categoryId] ?? 0);
foreach ($childrenByParent[$categoryId] ?? [] as $childId) {
$total += $countWithDescendants($childId);
}
$totalCountsByCategory[$categoryId] = $total;
return $total;
};
$categories->each(function (Category $category) use ($countWithDescendants): void {
$category->setAttribute('products_count', $countWithDescendants((int) $category->id));
});
return CategoryResource::collection($categories);
}
}