Add recursive method to fetch category path in DocumentationCategoryRepository

- Implement `getPathFromRoot` to retrieve the category path using recursive SQL query.
- Cache results for improved performance.
This commit is contained in:
2026-07-25 01:17:55 +05:00
parent 6e8b708749
commit a70e09bddc
@@ -11,6 +11,9 @@ use App\Services\Search\CreateSearchInstanceCommand;
use App\Dto\Builder\DocumentationCategory as DocumentationCategoryBuilderDto;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
final readonly class DocumentationCategoryRepository
@@ -93,4 +96,52 @@ final readonly class DocumentationCategoryRepository
->pluck('title', 'id')
->toArray();
}
public function getPathFromRoot(int $categoryId, ?ProjectLanguage $projectLanguage): Collection
{
$seconds = 3600;
return Cache::remember(self::class . $categoryId . '_' . $projectLanguage->id ?? 0, $seconds, function () use ($categoryId, $projectLanguage) {
$rows = DB::select(
<<<SQL
WITH RECURSIVE chain AS (
SELECT id, parent_id, 0 AS depth
FROM documentation_categories
WHERE id = ?
UNION ALL
SELECT dc.id, dc.parent_id, chain.depth + 1 AS depth
FROM documentation_categories dc
INNER JOIN chain ON chain.parent_id = dc.id
)
SELECT id, depth
FROM chain
ORDER BY depth DESC
SQL,
[$categoryId]
);
$idsInOrder = collect($rows)->pluck('id')->all();
$with = [
'content' => function (HasOne $hasOne) use ($projectLanguage) {
/** @var ?ProjectLanguage $projectLanguage */
$hasOne->when($projectLanguage, function (Builder $query, ProjectLanguage $projectLanguage) {
$query->where('language_id', $projectLanguage->id);
});
}
];
$categories = DocumentationCategory::query()
->whereIn('id', $idsInOrder)
->with($with)
->get()
->keyBy('id');
return collect($idsInOrder)
->map(fn (int $id) => $categories->get($id))
->filter()
->values();
});
}
}