Passed
Push — master ( a8119a...bd111d )
by Caen
03:52 queued 15s
created

FeaturedImageFactory   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 54
dl 0
loc 134
rs 10
c 2
b 0
f 0
wmc 22

14 Methods

Rating   Name   Duplication   Size   Complexity  
A makeAltText() 0 3 1
A normalizeLocalImagePath() 0 8 1
A isRemote() 0 7 3
A makeLicenseName() 0 3 1
A makeSource() 0 21 5
A makeAuthorName() 0 3 1
A makeTitleText() 0 3 1
A getStringMatter() 0 3 2
A __construct() 0 11 1
A makeAuthorUrl() 0 3 1
A make() 0 9 2
A makeLicenseUrl() 0 3 1
A makeCopyrightText() 0 3 1
A toArray() 0 11 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Factories;
6
7
use Hyde\Framework\Features\Blogging\Models\FeaturedImage;
8
use Hyde\Framework\Features\Blogging\Models\LocalFeaturedImage;
9
use Hyde\Framework\Features\Blogging\Models\RemoteFeaturedImage;
10
use Hyde\Hyde;
11
use Hyde\Markdown\Contracts\FrontMatter\SubSchemas\FeaturedImageSchema;
12
use Hyde\Markdown\Models\FrontMatter;
13
use Illuminate\Support\Str;
14
use function is_string;
15
use RuntimeException;
16
use function str_starts_with;
17
18
class FeaturedImageFactory extends Concerns\PageDataFactory implements FeaturedImageSchema
19
{
20
    final public const SCHEMA = FeaturedImageSchema::FEATURED_IMAGE_SCHEMA;
21
22
    protected readonly string $source;
23
    protected readonly ?string $altText;
24
    protected readonly ?string $titleText;
25
    protected readonly ?string $authorName;
26
    protected readonly ?string $authorUrl;
27
    protected readonly ?string $copyrightText;
28
    protected readonly ?string $licenseName;
29
    protected readonly ?string $licenseUrl;
30
31
    public function __construct(
32
        private readonly FrontMatter $matter,
33
    ) {
34
        $this->source = $this->makeSource();
0 ignored issues
show
Bug introduced by
The property source is declared read-only in Hyde\Framework\Factories\FeaturedImageFactory.
Loading history...
35
        $this->altText = $this->makeAltText();
0 ignored issues
show
Bug introduced by
The property altText is declared read-only in Hyde\Framework\Factories\FeaturedImageFactory.
Loading history...
36
        $this->titleText = $this->makeTitleText();
0 ignored issues
show
Bug introduced by
The property titleText is declared read-only in Hyde\Framework\Factories\FeaturedImageFactory.
Loading history...
37
        $this->authorName = $this->makeAuthorName();
0 ignored issues
show
Bug introduced by
The property authorName is declared read-only in Hyde\Framework\Factories\FeaturedImageFactory.
Loading history...
38
        $this->authorUrl = $this->makeAuthorUrl();
0 ignored issues
show
Bug introduced by
The property authorUrl is declared read-only in Hyde\Framework\Factories\FeaturedImageFactory.
Loading history...
39
        $this->copyrightText = $this->makeCopyrightText();
0 ignored issues
show
Bug introduced by
The property copyrightText is declared read-only in Hyde\Framework\Factories\FeaturedImageFactory.
Loading history...
40
        $this->licenseName = $this->makeLicenseName();
0 ignored issues
show
Bug introduced by
The property licenseName is declared read-only in Hyde\Framework\Factories\FeaturedImageFactory.
Loading history...
41
        $this->licenseUrl = $this->makeLicenseUrl();
0 ignored issues
show
Bug introduced by
The property licenseUrl is declared read-only in Hyde\Framework\Factories\FeaturedImageFactory.
Loading history...
42
    }
43
44
    /**
45
     * @return array{source: string, altText: string|null, titleText: string|null, authorName: string|null, authorUrl: string|null, copyrightText: string|null, licenseName: string|null, licenseUrl: string|null}
46
     */
47
    public function toArray(): array
48
    {
49
        return [
0 ignored issues
show
introduced by
The expression return array('source' =>...' => $this->licenseUrl) returns an array which contains values of type string which are incompatible with the return type Illuminate\Contracts\Support\TValue mandated by Illuminate\Contracts\Support\Arrayable::toArray().
Loading history...
50
            'source' => $this->source,
51
            'altText' => $this->altText,
52
            'titleText' => $this->titleText,
53
            'authorName' => $this->authorName,
54
            'authorUrl' => $this->authorUrl,
55
            'copyrightText' => $this->copyrightText,
56
            'licenseName' => $this->licenseName,
57
            'licenseUrl' => $this->licenseUrl,
58
        ];
59
    }
60
61
    public static function make(FrontMatter $matter): FeaturedImage
62
    {
63
        $data = (new static($matter))->toArray();
64
65
        if (self::isRemote($matter)) {
66
            return new RemoteFeaturedImage(...$data);
67
        }
68
69
        return new LocalFeaturedImage(...$data);
70
    }
71
72
    protected function makeSource(): string
73
    {
74
        if (is_string($this->getStringMatter('image'))) {
75
            if (str_starts_with($this->getStringMatter('image'), 'http')) {
0 ignored issues
show
Bug introduced by
It seems like $this->getStringMatter('image') can also be of type null; however, parameter $haystack of str_starts_with() 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

75
            if (str_starts_with(/** @scrutinizer ignore-type */ $this->getStringMatter('image'), 'http')) {
Loading history...
76
                return $this->getStringMatter('image');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getStringMatter('image') could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
77
            }
78
79
            return self::normalizeLocalImagePath($this->getStringMatter('image'));
0 ignored issues
show
Bug introduced by
It seems like $this->getStringMatter('image') can also be of type null; however, parameter $path of Hyde\Framework\Factories...rmalizeLocalImagePath() 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

79
            return self::normalizeLocalImagePath(/** @scrutinizer ignore-type */ $this->getStringMatter('image'));
Loading history...
80
        }
81
82
        if ($this->getStringMatter('image.url') !== null) {
83
            return $this->getStringMatter('image.url');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getStringMatter('image.url') could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
84
        }
85
86
        if ($this->getStringMatter('image.path') !== null) {
87
            return $this->normalizeLocalImagePath($this->getStringMatter('image.path'));
88
        }
89
90
        // Todo, we might want to add a note about which file caused the error.
91
        // We could also check for these before calling the factory, and just ignore the image if it's not valid.
92
        throw new RuntimeException('No featured image source was found');
93
    }
94
95
    protected function makeAltText(): ?string
96
    {
97
        return $this->getStringMatter('image.description');
98
    }
99
100
    protected function makeTitleText(): ?string
101
    {
102
        return $this->getStringMatter('image.title');
103
    }
104
105
    protected function makeAuthorName(): ?string
106
    {
107
        return $this->getStringMatter('image.author');
108
    }
109
110
    protected function makeAuthorUrl(): ?string
111
    {
112
        return $this->getStringMatter('image.attributionUrl');
113
    }
114
115
    protected function makeCopyrightText(): ?string
116
    {
117
        return $this->getStringMatter('image.copyright');
118
    }
119
120
    protected function makeLicenseName(): ?string
121
    {
122
        return $this->getStringMatter('image.license');
123
    }
124
125
    protected function makeLicenseUrl(): ?string
126
    {
127
        return $this->getStringMatter('image.licenseUrl');
128
    }
129
130
    protected static function normalizeLocalImagePath(string $path): string
131
    {
132
        $path = Hyde::pathToRelative($path);
133
134
        $path = Str::after($path, Hyde::getMediaDirectory());
135
        $path = Str::after($path, Hyde::getMediaOutputDirectory());
136
137
        return unslash($path);
138
    }
139
140
    protected static function isRemote(FrontMatter $matter): bool
141
    {
142
        if (is_string($matter->get('image')) && str_starts_with($matter->get('image'), 'http')) {
143
            return true;
144
        }
145
146
        return $matter->get('image.url') !== null;
147
    }
148
149
    protected function getStringMatter(string $key): ?string
150
    {
151
        return is_string($this->matter->get($key)) ? $this->matter->get($key) : null;
152
    }
153
}
154