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