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 | } |