Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
DataCollections
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
5 / 5
7
100.00% covered (success)
100.00%
1 / 1
 markdown
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 yaml
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 json
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 findFiles
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 makeIdentifier
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\Support;
6
7use Hyde\Facades\Filesystem;
8use Symfony\Component\Yaml\Yaml;
9use Hyde\Markdown\Models\FrontMatter;
10use Hyde\Framework\Actions\MarkdownFileParser;
11use Hyde\Framework\Concerns\InteractsWithDirectories;
12use Illuminate\Support\Collection;
13use Illuminate\Support\Str;
14
15use function implode;
16use function json_decode;
17use function sprintf;
18use function Hyde\unslash;
19use function str_starts_with;
20
21/**
22 * Automatically generates Laravel Collections from static data files,
23 * such as Markdown components and YAML files using Hyde Autodiscovery.
24 *
25 * This class acts both as a base collection class, a factory for
26 * creating collections, and static facade shorthand helper methods.
27 *
28 * The static "facade" methods are what makes this class special,
29 * they allow you to quickly access the data collections.
30 *
31 * To use them retrieve a collection, call a facade method with the
32 * name of the data collection subdirectory directory.
33 *
34 * All collections are indexed by their filename, which is relative
35 * to the configured data collection source directory.
36 */
37class DataCollections extends Collection
38{
39    use InteractsWithDirectories;
40
41    /**
42     * The base directory for all data collections. Can be modified using a service provider.
43     */
44    public static string $sourceDirectory = 'resources/collections';
45
46    /**
47     * Get a collection of Markdown documents in the resources/collections/<$key> directory.
48     *
49     * Each Markdown file will be parsed into a MarkdownDocument with front matter.
50     *
51     * @return DataCollections<string, \Hyde\Markdown\Models\MarkdownDocument>
52     */
53    public static function markdown(string $name): static
54    {
55        static::needsDirectory(static::$sourceDirectory);
56
57        return new static(static::findFiles($name, 'md')->mapWithKeys(function (string $file): array {
58            return [static::makeIdentifier($file) => MarkdownFileParser::parse($file)];
59        }));
60    }
61
62    /**
63     * Get a collection of YAML documents in the resources/collections/<$key> directory.
64     *
65     * Each YAML file will be parsed into a FrontMatter object.
66     *
67     * @return DataCollections<string, \Hyde\Markdown\Models\FrontMatter>
68     */
69    public static function yaml(string $name): static
70    {
71        static::needsDirectory(static::$sourceDirectory);
72
73        return new static(static::findFiles($name, ['yaml', 'yml'])->mapWithKeys(function (string $file): array {
74            $content = Filesystem::get($file);
75
76            if (str_starts_with($content, '---')) {
77                $content = Str::between($content, '---', '---');
78            }
79
80            $parsed = Yaml::parse($content) ?: [];
81            $matter = new FrontMatter($parsed);
82
83            return [static::makeIdentifier($file) => $matter];
84        }));
85    }
86
87    /**
88     * Get a collection of JSON documents in the resources/collections/<$key> directory.
89     *
90     * Each JSON file will be parsed into a stdClass object, or an associative array, depending on the second parameter.
91     *
92     * @return DataCollections<string, \stdClass|array>
93     */
94    public static function json(string $name, bool $asArray = false): static
95    {
96        static::needsDirectory(static::$sourceDirectory);
97
98        return new static(static::findFiles($name, 'json')->mapWithKeys(function (string $file) use ($asArray): array {
99            return [static::makeIdentifier($file) => json_decode(Filesystem::get($file), $asArray)];
100        }));
101    }
102
103    protected static function findFiles(string $name, array|string $extensions): Collection
104    {
105        return Filesystem::smartGlob(sprintf('%s/%s/*.{%s}',
106            static::$sourceDirectory, $name, implode(',', (array) $extensions)
107        ), GLOB_BRACE);
108    }
109
110    protected static function makeIdentifier(string $path): string
111    {
112        return unslash(Str::after($path, static::$sourceDirectory));
113    }
114}