Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
SearchDataService
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 2
6
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 search
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Http\Services;
4
5use App\Http\Repositories\interfaces\ISearchDataRepository;
6
7/**
8 * Service for search data business logic.
9 *
10 * Orchestrates search operations across shortcuts and templates,
11 * returning grouped results for the search-data endpoint.
12 */
13class SearchDataService
14{
15    public function __construct(
16        private ISearchDataRepository $searchDataRepository
17    ) {}
18
19    /**
20     * Default category name when a shortcut has no assigned category.
21     */
22    private const DEFAULT_CATEGORY_NAME = 'Default Category';
23
24    /**
25     * Search shortcuts and templates by a query string.
26     *
27     * Returns results grouped by type (Shortcuts and FlyPlates).
28     * Shortcuts are scoped to the authenticated user via UserScope.
29     * Templates are global (admin-created content).
30     * Each item includes a `category_name` field resolved from its category relationship.
31     * Shortcuts without a category will have `category_name` set to "Default Category".
32     *
33     * @param  string  $query  The search term
34     * @param  int  $limit  Maximum results per type (default: 50)
35     * @return array<int, array{type: string, items: array<int, array{_id: string, title: string, shortcut: string, first_line: string|null, text: string|null, html: string|null, version: int|null, category_id: string|null, category_name: string, uploads: array|null, type: string|null, created_at: string|null, updated_at: string|null}>}> Array with two groups: Shortcuts and FlyPlates
36     */
37    public function search(string $query, int $limit = 50): array
38    {
39        $shortcuts = $this->searchDataRepository->searchShortcuts($query, $limit);
40        $templates = $this->searchDataRepository->searchTemplates($query, $limit);
41
42        $shortcutItems = $shortcuts->map(function ($shortcut) {
43            $item = $shortcut->toArray();
44            $item['category_name'] = $shortcut->category?->name ?? self::DEFAULT_CATEGORY_NAME;
45            unset($item['category']);
46
47            return $item;
48        })->values()->toArray();
49
50        $templateItems = $templates->map(function ($template) {
51            $item = $template->toArray();
52            $item['category_name'] = $template->category?->name ?? null;
53            unset($item['category']);
54
55            return $item;
56        })->values()->toArray();
57
58        return [
59            [
60                'type' => 'Shortcuts',
61                'items' => $shortcutItems,
62            ],
63            [
64                'type' => 'FlyPlates',
65                'items' => $templateItems,
66            ],
67        ];
68    }
69}