Passed
Push — master ( bf136f...f669a1 )
by Caen
03:41 queued 14s
created

makeDescriptionFromMarkdownBody()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Factories;
6
7
use Hyde\Framework\Factories\Concerns\CoreDataObject;
8
use Hyde\Framework\Actions\ConvertsMarkdownToPlainText;
9
use Hyde\Framework\Features\Blogging\Models\FeaturedImage;
10
use Hyde\Framework\Features\Blogging\Models\PostAuthor;
11
use Hyde\Markdown\Contracts\FrontMatter\BlogPostSchema;
12
use Hyde\Markdown\Models\FrontMatter;
13
use Hyde\Markdown\Models\Markdown;
14
use Hyde\Support\Models\DateString;
15
16
use function strlen;
17
use function substr;
18
19
/**
20
 * Streamlines the data construction specific to a blog post.
21
 *
22
 * Simply pass along the data the class needs to run, then access the data using the toArray() method.
23
 *
24
 * All data can be set using front matter in the page source file. If no front matter is set for the given key,
25
 * this class will attempt to generate and discover the values based on the page and the project's configuration.
26
 */
27
class BlogPostDataFactory extends Concerns\PageDataFactory implements BlogPostSchema
28
{
29
    /**
30
     * The front matter properties supported by this factory.
31
     *
32
     * Note that this class does not add the title, as that is already added to all pages.
33
     */
34
    final public const SCHEMA = BlogPostSchema::BLOG_POST_SCHEMA;
35
36
    private readonly FrontMatter $matter;
37
    private readonly Markdown $markdown;
38
39
    protected readonly ?string $description;
40
    protected readonly ?string $category;
41
    protected readonly ?DateString $date;
42
    protected readonly ?PostAuthor $author;
43
    protected readonly ?FeaturedImage $image;
44
45
    private readonly string $filePath;
46
47
    public function __construct(CoreDataObject $pageData)
48
    {
49
        $this->matter = $pageData->matter;
0 ignored issues
show
Bug introduced by
The property matter is declared read-only in Hyde\Framework\Factories\BlogPostDataFactory.
Loading history...
50
        $this->markdown = $pageData->markdown;
0 ignored issues
show
Bug introduced by
The property markdown is declared read-only in Hyde\Framework\Factories\BlogPostDataFactory.
Loading history...
51
        $this->filePath = $pageData->sourcePath;
0 ignored issues
show
Bug introduced by
The property filePath is declared read-only in Hyde\Framework\Factories\BlogPostDataFactory.
Loading history...
52
53
        $this->description = $this->makeDescription();
0 ignored issues
show
Bug introduced by
The property description is declared read-only in Hyde\Framework\Factories\BlogPostDataFactory.
Loading history...
54
        $this->category = $this->makeCategory();
0 ignored issues
show
Bug introduced by
The property category is declared read-only in Hyde\Framework\Factories\BlogPostDataFactory.
Loading history...
55
        $this->date = $this->makeDate();
0 ignored issues
show
Bug introduced by
The property date is declared read-only in Hyde\Framework\Factories\BlogPostDataFactory.
Loading history...
56
        $this->author = $this->makeAuthor();
0 ignored issues
show
Bug introduced by
The property author is declared read-only in Hyde\Framework\Factories\BlogPostDataFactory.
Loading history...
57
        $this->image = $this->makeImage();
0 ignored issues
show
Bug introduced by
The property image is declared read-only in Hyde\Framework\Factories\BlogPostDataFactory.
Loading history...
58
    }
59
60
    /**
61
     * @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}
62
     */
63
    public function toArray(): array
64
    {
65
        return [
66
            'description' => $this->description,
67
            'category' => $this->category,
68
            'date' => $this->date,
69
            'author' => $this->author,
70
            'image' => $this->image,
71
        ];
72
    }
73
74
    protected function makeDescription(): string
75
    {
76
        return $this->getMatter('description') ?? $this->makeDescriptionFromMarkdownBody();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getMatter(...ptionFromMarkdownBody() could return the type array which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
77
    }
78
79
    protected function makeCategory(): ?string
80
    {
81
        return $this->getMatter('category');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getMatter('category') could return the type array which is incompatible with the type-hinted return null|string. Consider adding an additional type-check to rule them out.
Loading history...
82
    }
83
84
    protected function makeDate(): ?DateString
85
    {
86
        if ($this->getMatter('date')) {
87
            return new DateString($this->getMatter('date'));
0 ignored issues
show
Bug introduced by
It seems like $this->getMatter('date') can also be of type array and null; however, parameter $string of Hyde\Support\Models\DateString::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

87
            return new DateString(/** @scrutinizer ignore-type */ $this->getMatter('date'));
Loading history...
88
        }
89
90
        return null;
91
    }
92
93
    protected function makeAuthor(): ?PostAuthor
94
    {
95
        if ($this->getMatter('author')) {
96
            return PostAuthor::getOrCreate($this->getMatter('author'));
0 ignored issues
show
Bug introduced by
It seems like $this->getMatter('author') can also be of type null; however, parameter $data of Hyde\Framework\Features\...stAuthor::getOrCreate() does only seem to accept array|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

96
            return PostAuthor::getOrCreate(/** @scrutinizer ignore-type */ $this->getMatter('author'));
Loading history...
97
        }
98
99
        return null;
100
    }
101
102
    protected function makeImage(): ?FeaturedImage
103
    {
104
        if ($this->getMatter('image')) {
105
            return FeaturedImageFactory::make($this->matter, $this->filePath);
106
        }
107
108
        return null;
109
    }
110
111
    private function makeDescriptionFromMarkdownBody(): string
112
    {
113
        return $this->getTruncatedMarkdown($this->stripMarkdownFromBody($this->markdown->body()));
114
    }
115
116
    private function getTruncatedMarkdown(string $markdown): string
117
    {
118
        if (strlen($markdown) >= 128) {
119
            return substr($markdown, 0, 125).'...';
120
        }
121
122
        return $markdown;
123
    }
124
125
    private function stripMarkdownFromBody(string $body): string
126
    {
127
        return (new ConvertsMarkdownToPlainText($body))->execute();
128
    }
129
130
    protected function getMatter(string $key): string|null|array
131
    {
132
        return $this->matter->get($key);
133
    }
134
}
135