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:
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user