Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
BlogPostDataFactory
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
9 / 9
12
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 toArray
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 makeDescription
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 makeCategory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 makeDate
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 makeAuthor
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 makeImage
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 makeDescriptionFromMarkdownBody
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMatter
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Hyde\Framework\Factories;
6
7use Illuminate\Support\Str;
8use Hyde\Framework\Factories\Concerns\CoreDataObject;
9use Hyde\Framework\Actions\ConvertsMarkdownToPlainText;
10use Hyde\Framework\Features\Blogging\Models\FeaturedImage;
11use Hyde\Framework\Features\Blogging\Models\PostAuthor;
12use Hyde\Markdown\Contracts\FrontMatter\BlogPostSchema;
13use Hyde\Markdown\Models\FrontMatter;
14use Hyde\Markdown\Models\Markdown;
15use Hyde\Support\Models\DateString;
16
17/**
18 * Streamlines the data construction specific to a blog post.
19 *
20 * Simply pass along the data the class needs to run, then access the data using the toArray() method.
21 *
22 * All data can be set using front matter in the page source file. If no front matter is set for the given key,
23 * this class will attempt to generate and discover the values based on the page and the project's configuration.
24 */
25class BlogPostDataFactory extends Concerns\PageDataFactory implements BlogPostSchema
26{
27    /**
28     * The front matter properties supported by this factory.
29     *
30     * Note that this class does not add the title, as that is already added to all pages.
31     */
32    final public const SCHEMA = BlogPostSchema::BLOG_POST_SCHEMA;
33
34    private readonly FrontMatter $matter;
35    private readonly Markdown $markdown;
36
37    protected readonly ?string $description;
38    protected readonly ?string $category;
39    protected readonly ?DateString $date;
40    protected readonly ?PostAuthor $author;
41    protected readonly ?FeaturedImage $image;
42
43    private readonly string $filePath;
44
45    public function __construct(CoreDataObject $pageData)
46    {
47        $this->matter = $pageData->matter;
48        $this->markdown = $pageData->markdown;
49        $this->filePath = $pageData->sourcePath;
50
51        $this->description = $this->makeDescription();
52        $this->category = $this->makeCategory();
53        $this->date = $this->makeDate();
54        $this->author = $this->makeAuthor();
55        $this->image = $this->makeImage();
56    }
57
58    /**
59     * @return array{description: string|null, category: string|null, date: \Hyde\Support\Models\DateString|null, author: \Hyde\Framework\Features\Blogging\Models\PostAuthor|null, image: \Hyde\Framework\Features\Blogging\Models\FeaturedImage|null}
60     */
61    public function toArray(): array
62    {
63        return [
64            'description' => $this->description,
65            'category' => $this->category,
66            'date' => $this->date,
67            'author' => $this->author,
68            'image' => $this->image,
69        ];
70    }
71
72    protected function makeDescription(): string
73    {
74        return $this->getMatter('description') ?? $this->makeDescriptionFromMarkdownBody();
75    }
76
77    protected function makeCategory(): ?string
78    {
79        return $this->getMatter('category');
80    }
81
82    protected function makeDate(): ?DateString
83    {
84        if ($this->getMatter('date')) {
85            return new DateString($this->getMatter('date'));
86        }
87
88        return null;
89    }
90
91    protected function makeAuthor(): ?PostAuthor
92    {
93        if ($this->getMatter('author')) {
94            return PostAuthor::getOrCreate($this->getMatter('author'));
95        }
96
97        return null;
98    }
99
100    protected function makeImage(): ?FeaturedImage
101    {
102        if ($this->getMatter('image')) {
103            return FeaturedImageFactory::make($this->matter, $this->filePath);
104        }
105
106        return null;
107    }
108
109    private function makeDescriptionFromMarkdownBody(): string
110    {
111        return Str::limit((new ConvertsMarkdownToPlainText($this->markdown->body()))->execute(), 125);
112    }
113
114    protected function getMatter(string $key): string|null|array
115    {
116        /** @var string|null|array $value */
117        $value = $this->matter->get($key);
118
119        return $value;
120    }
121}