Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
46 / 46 |
|
100.00% |
13 / 13 |
CRAP | |
100.00% |
1 / 1 |
PublicationsExtension | |
100.00% |
46 / 46 |
|
100.00% |
13 / 13 |
18 | |
100.00% |
1 / 1 |
getTypes | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getPageClasses | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
discoverFiles | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
discoverPages | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
discoverPublicationPages | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
generatePublicationListingPageForType | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
generatePublicationPaginatedListingPagesForType | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
3 | |||
generatePublicationTagPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
parsePublicationTypes | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
getSchemaFiles | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getPublicationFiles | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getPublicationFilesForType | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
shouldGeneratePublicationTagPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Hyde\Publications; |
6 | |
7 | use Hyde\Foundation\Concerns\HydeExtension; |
8 | use Hyde\Foundation\Facades\Files; |
9 | use Hyde\Foundation\Kernel\FileCollection; |
10 | use Hyde\Foundation\Kernel\PageCollection; |
11 | use Hyde\Hyde; |
12 | use Hyde\Pages\InMemoryPage; |
13 | use Hyde\Publications\Actions\GeneratesPublicationTagPages; |
14 | use Hyde\Publications\Models\PublicationType; |
15 | use Hyde\Publications\Pages\PublicationListPage; |
16 | use Hyde\Publications\Pages\PublicationPage; |
17 | use Hyde\Support\Filesystem\SourceFile; |
18 | use Illuminate\Support\Collection; |
19 | use Illuminate\Support\Str; |
20 | |
21 | use function glob; |
22 | use function range; |
23 | use function str_ends_with; |
24 | |
25 | /** |
26 | * @see \Hyde\Publications\Testing\Feature\PublicationsExtensionTest |
27 | */ |
28 | class PublicationsExtension extends HydeExtension |
29 | { |
30 | /** @var \Illuminate\Support\Collection<string, \Hyde\Publications\Models\PublicationType> */ |
31 | protected Collection $types; |
32 | |
33 | /** @return \Illuminate\Support\Collection<string, \Hyde\Publications\Models\PublicationType> */ |
34 | public function getTypes(): Collection |
35 | { |
36 | if (! isset($this->types)) { |
37 | $this->types = $this->parsePublicationTypes(); |
38 | } |
39 | |
40 | return $this->types; |
41 | } |
42 | |
43 | /** @return array<class-string<\Hyde\Pages\Concerns\HydePage>> */ |
44 | public static function getPageClasses(): array |
45 | { |
46 | return [ |
47 | // Since our page classes are not auto-discoverable by Hyde due to the dynamic source directories, |
48 | // we run our own discovery logic in the callbacks below. |
49 | ]; |
50 | } |
51 | |
52 | public function discoverFiles(FileCollection $collection): void |
53 | { |
54 | $this->types = $this->parsePublicationTypes(); |
55 | |
56 | $this->types->each(function (PublicationType $type) use ($collection): void { |
57 | Collection::make($this->getPublicationFilesForType($type))->map(function (string $filepath) use ($collection): void { |
58 | $collection->put(Hyde::pathToRelative($filepath), SourceFile::make($filepath, PublicationPage::class)); |
59 | }); |
60 | }); |
61 | } |
62 | |
63 | public function discoverPages(PageCollection $collection): void |
64 | { |
65 | $this->discoverPublicationPages($collection); |
66 | |
67 | if (self::shouldGeneratePublicationTagPages()) { |
68 | $this->generatePublicationTagPages($collection); |
69 | } |
70 | } |
71 | |
72 | protected function discoverPublicationPages(PageCollection $instance): void |
73 | { |
74 | Files::getFiles(PublicationPage::class)->each(function (SourceFile $file) use ($instance): void { |
75 | $instance->addPage(PublicationPage::parse(Str::before($file->getPath(), PublicationPage::fileExtension()))); |
76 | }); |
77 | |
78 | $this->types->each(function (PublicationType $type) use ($instance): void { |
79 | $this->generatePublicationListingPageForType($type, $instance); |
80 | }); |
81 | } |
82 | |
83 | protected function generatePublicationListingPageForType(PublicationType $type, PageCollection $instance): void |
84 | { |
85 | $page = new PublicationListPage($type); |
86 | $instance->put($page->getSourcePath(), $page); |
87 | |
88 | if ($type->usesPagination()) { |
89 | $this->generatePublicationPaginatedListingPagesForType($type, $instance); |
90 | } |
91 | } |
92 | |
93 | protected function generatePublicationPaginatedListingPagesForType(PublicationType $type, PageCollection $instance): void |
94 | { |
95 | $paginator = $type->getPaginator(); |
96 | |
97 | foreach (range(1, $paginator->totalPages()) as $page) { |
98 | $paginator->setCurrentPage($page); |
99 | $listTemplate = $type->listTemplate; |
100 | if (str_ends_with($listTemplate, '.blade.php')) { |
101 | $listTemplate = "{$type->getDirectory()}/$listTemplate"; |
102 | } |
103 | $listingPage = new InMemoryPage("{$type->getDirectory()}/page-$page", [ |
104 | 'publicationType' => $type, 'paginatorPage' => $page, |
105 | 'title' => $type->name.' - Page '.$page, |
106 | ], view: $listTemplate); |
107 | $instance->put($listingPage->getSourcePath(), $listingPage); |
108 | } |
109 | } |
110 | |
111 | protected function generatePublicationTagPages(PageCollection $collection): void |
112 | { |
113 | (new GeneratesPublicationTagPages($collection))->__invoke(); |
114 | } |
115 | |
116 | /** @return Collection<string, \Hyde\Publications\Pages\PublicationPage> */ |
117 | protected function parsePublicationTypes(): Collection |
118 | { |
119 | return Collection::make($this->getSchemaFiles())->mapWithKeys(function (string $schemaFile): array { |
120 | $type = PublicationType::fromFile(Hyde::pathToRelative($schemaFile)); |
121 | |
122 | return [$type->getDirectory() => $type]; |
123 | }); |
124 | } |
125 | |
126 | protected function getSchemaFiles(): array |
127 | { |
128 | return glob(Hyde::path(Hyde::getSourceRoot()).'/*/schema.json'); |
129 | } |
130 | |
131 | protected function getPublicationFiles(string $directory): array |
132 | { |
133 | return glob(Hyde::path("$directory/*.md")); |
134 | } |
135 | |
136 | protected function getPublicationFilesForType(PublicationType $type): array |
137 | { |
138 | return $this->getPublicationFiles($type->getDirectory()); |
139 | } |
140 | |
141 | protected static function shouldGeneratePublicationTagPages(): bool |
142 | { |
143 | return count(Publications::getPublicationTags()) > 0; |
144 | } |
145 | } |