Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
Publications
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
7 / 7
10
100.00% covered (success)
100.00%
1 / 1
 getPublicationTypes
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPublicationsForType
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getMediaForType
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getPublicationTags
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPublicationsGroupedByTags
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 publicationTypeExists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPublicationTagFields
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\Publications;
6
7use Hyde\Hyde;
8use Hyde\Publications\Concerns\PublicationFieldTypes;
9use Hyde\Publications\Models\PublicationType;
10use Hyde\Publications\Pages\PublicationPage;
11use Hyde\Support\Filesystem\MediaFile;
12use Illuminate\Support\Collection;
13use Illuminate\Support\Str;
14
15use function array_keys;
16use function array_unique;
17use function array_values;
18use function collect;
19
20/**
21 * @see \Hyde\Publications\Testing\Feature\PublicationServiceTest
22 */
23class Publications
24{
25    /**
26     * Return a collection of all defined publication types, indexed by the directory name.
27     *
28     * @return Collection<string, PublicationType>
29     */
30    public static function getPublicationTypes(): Collection
31    {
32        return Hyde::kernel()->getExtension(PublicationsExtension::class)->getTypes();
33    }
34
35    /**
36     * Return all publications for a given publication type.
37     *
38     * @return Collection<int, \Hyde\Publications\Pages\PublicationPage>
39     */
40    public static function getPublicationsForType(PublicationType $publicationType, ?string $sortField = null, ?bool $sortAscending = null): Collection
41    {
42        $publications = Hyde::pages()->getPages(PublicationPage::class);
43
44        $sortAscending ??= $publicationType->sortAscending;
45        $sortField ??= $publicationType->sortField;
46
47        return $publications->sortBy(function (PublicationPage $page) use ($sortField): mixed {
48            return $page->matter($sortField);
49        }, descending: ! $sortAscending)->values()->toBase();
50    }
51
52    /**
53     * Return all media items for a given publication type.
54     */
55    public static function getMediaForType(PublicationType $publicationType): Collection
56    {
57        return collect(MediaFile::all())->filter(function (MediaFile $file) use ($publicationType): bool {
58            return Str::startsWith($file->getPath(), Hyde::getMediaDirectory().'/'.$publicationType->getDirectory());
59        })->keys()->toBase();
60    }
61
62    /**
63     * Get all available tags used in the publications.
64     *
65     * The tags are aggregated from the front matter of all publication pages, where the field type is "tag".
66     *
67     * @return array<string>
68     */
69    public static function getPublicationTags(): array
70    {
71        return array_values(array_unique(array_keys(self::getPublicationsGroupedByTags())));
72    }
73
74    /**
75     * Get all pages grouped by their tags. Note that pages with multiple tags will appear multiple times.
76     * It's also useful to count the number of times a tag is used by using `array_map('count', $pagesByTag)`.
77     *
78     * @experimental May be renamed to `getPublicationsGroupedByTag` before release.
79     *
80     * @return array<string, array<\Hyde\Publications\Pages\PublicationPage>>
81     */
82    public static function getPublicationsGroupedByTags(): array
83    {
84        $pagesByTag = [];
85
86        /** @var PublicationPage $publication */
87        foreach (PublicationPage::all() as $publication) {
88            foreach (self::getPublicationTagFields($publication) as $field) {
89                foreach ((array) $publication->matter($field->name) as $tag) {
90                    $pagesByTag[$tag][] = $publication;
91                }
92            }
93        }
94
95        return $pagesByTag;
96    }
97
98    /**
99     * Check whether a given publication type exists.
100     */
101    public static function publicationTypeExists(string $publicationTypeName): bool
102    {
103        return static::getPublicationTypes()->has(Str::slug($publicationTypeName));
104    }
105
106    protected static function getPublicationTagFields(PublicationPage $publication): Collection
107    {
108        return $publication->getType()->getFields()->whereStrict('type', PublicationFieldTypes::Tag);
109    }
110}