Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
GeneratesDocumentationSearchIndex
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
8 / 8
11
100.00% covered (success)
100.00%
1 / 1
 handle
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 run
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 generatePageEntry
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 save
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getSearchContentForDocument
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 formatDestination
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 getPath
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Hyde\Framework\Actions;
6
7use Hyde\Hyde;
8use Hyde\Facades\Config;
9use Hyde\Facades\Filesystem;
10use Hyde\Framework\Concerns\InteractsWithDirectories;
11use Hyde\Pages\DocumentationPage;
12use Illuminate\Support\Collection;
13
14use function basename;
15use function in_array;
16use function trim;
17
18/**
19 * @internal Generate a JSON file that can be used as a search index for documentation pages.
20 */
21class GeneratesDocumentationSearchIndex
22{
23    use InteractsWithDirectories;
24
25    protected Collection $index;
26    protected string $path;
27
28    /**
29     * Generate the search index and save it to disk.
30     *
31     * @return string The path to the generated file.
32     */
33    public static function handle(): string
34    {
35        $service = new static();
36        $service->run();
37        $service->save();
38
39        return $service->path;
40    }
41
42    protected function __construct()
43    {
44        $this->index = new Collection();
45        $this->path = $this->getPath();
46    }
47
48    protected function run(): void
49    {
50        DocumentationPage::all()->each(function (DocumentationPage $page): void {
51            if (! in_array($page->identifier, Config::getArray('docs.exclude_from_search', []))) {
52                $this->index->push($this->generatePageEntry($page));
53            }
54        });
55    }
56
57    /**
58     * @return array{slug: string, title: string, content: string, destination: string}
59     */
60    protected function generatePageEntry(DocumentationPage $page): array
61    {
62        return [
63            'slug' => basename($page->identifier),
64            'title' => $page->title,
65            'content' => trim($this->getSearchContentForDocument($page)),
66            'destination' => $this->formatDestination(basename($page->identifier)),
67        ];
68    }
69
70    protected function save(): void
71    {
72        $this->needsParentDirectory($this->path);
73
74        Filesystem::putContents($this->path, $this->index->toJson());
75    }
76
77    protected function getSearchContentForDocument(DocumentationPage $page): string
78    {
79        return (new ConvertsMarkdownToPlainText($page->markdown->body()))->execute();
80    }
81
82    protected function formatDestination(string $slug): string
83    {
84        if (Config::getBool('hyde.pretty_urls', false) === true) {
85            return $slug === 'index' ? '' : $slug;
86        }
87
88        return "$slug.html";
89    }
90
91    protected function getPath(): string
92    {
93        return Hyde::sitePath(DocumentationPage::outputDirectory().'/search.json');
94    }
95}