$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); } }