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 App\Dto\Builder\DocumentationCategory as DocumentationCategoryBuilderDto;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
final readonly class DocumentationCategoryRepository
|
final readonly class DocumentationCategoryRepository
|
||||||
@@ -93,4 +96,52 @@ final readonly class DocumentationCategoryRepository
|
|||||||
->pluck('title', 'id')
|
->pluck('title', 'id')
|
||||||
->toArray();
|
->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