Passed
Push — master ( e3b121...219a49 )
by Caen
03:57 queued 14s
created

FeaturedImageFactory::makeCopyrightText()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Factories;
6
7
use Hyde\Framework\Concerns\InteractsWithFrontMatter;
8
use Hyde\Framework\Features\Blogging\Models\FeaturedImage;
9
use Hyde\Framework\Features\Blogging\Models\LocalFeaturedImage;
10
use Hyde\Framework\Features\Blogging\Models\RemoteFeaturedImage;
11
use Hyde\Hyde;
12
use Hyde\Markdown\Contracts\FrontMatter\SubSchemas\FeaturedImageSchema;
13
use Hyde\Markdown\Models\FrontMatter;
14
use Illuminate\Support\Str;
15
use function is_string;
16
use RuntimeException;
17
use function str_starts_with;
18
19
class FeaturedImageFactory extends Concerns\PageDataFactory implements FeaturedImageSchema
20
{
21
    use InteractsWithFrontMatter;
22
23
    final public const SCHEMA = FeaturedImageSchema::FEATURED_IMAGE_SCHEMA;
24
25
    protected readonly string $source;
26
    protected readonly ?string $altText;
27
    protected readonly ?string $titleText;
28
    protected readonly ?string $authorName;
29
    protected readonly ?string $authorUrl;
30
    protected readonly ?string $copyrightText;
31
    protected readonly ?string $licenseName;
32
    protected readonly ?string $licenseUrl;
33
34
    public function __construct(
35
        private readonly FrontMatter $matter,
36
    ) {
37
        $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...
38
        $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...
39
        $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...
40
        $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...
41
        $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...
42
        $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...
43
        $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...
44
        $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...
45
    }
46
47
    /**
48
     * @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}
49
     */
50
    public function toArray(): array
51
    {
52
        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...
53
            'source' => $this->source,
54
            'altText' => $this->altText,
55
            'titleText' => $this->titleText,
56
            'authorName' => $this->authorName,
57
            'authorUrl' => $this->authorUrl,
58
            'copyrightText' => $this->copyrightText,
59
            'licenseName' => $this->licenseName,
60
            'licenseUrl' => $this->licenseUrl,
61
        ];
62
    }
63
64
    public static function make(FrontMatter $matter): FeaturedImage
65
    {
66
        $data = (new static($matter))->toArray();
67
68
        if (self::isRemote($matter)) {
69
            return new RemoteFeaturedImage(...$data);
70
        }
71
72
        return new LocalFeaturedImage(...$data);
73
    }
74
75
    protected function makeSource(): string
76
    {
77
        if (is_string($this->matter('image'))) {
78
            if (str_starts_with($this->matter('image'), 'http')) {
79
                return $this->matter('image');
80
            }
81
82
            return self::normalizeLocalImagePath($this->matter('image'));
83
        }
84
85
        if ($this->matter('image.url') !== null) {
86
            return $this->matter('image.url');
87
        }
88
89
        if ($this->matter('image.path') !== null) {
90
            return $this->normalizeLocalImagePath($this->matter('image.path'));
91
        }
92
93
        // Todo, we might want to add a note about which file caused the error.
94
        // We could also check for these before calling the factory, and just ignore the image if it's not valid.
95
        throw new RuntimeException('No featured image source was found');
96
    }
97
98
    protected function makeAltText(): ?string
99
    {
100
        return $this->matter('image.description');
101
    }
102
103
    protected function makeTitleText(): ?string
104
    {
105
        return $this->matter('image.title');
106
    }
107
108
    protected function makeAuthorName(): ?string
109
    {
110
        return $this->matter('image.author');
111
    }
112
113
    protected function makeAuthorUrl(): ?string
114
    {
115
        return $this->matter('image.attributionUrl');
116
    }
117
118
    protected function makeCopyrightText(): ?string
119
    {
120
        return $this->matter('image.copyright');
121
    }
122
123
    protected function makeLicenseName(): ?string
124
    {
125
        return $this->matter('image.license');
126
    }
127
128
    protected function makeLicenseUrl(): ?string
129
    {
130
        return $this->matter('image.licenseUrl');
131
    }
132
133
    protected static function normalizeLocalImagePath(string $path): string
134
    {
135
        $path = Hyde::pathToRelative($path);
136
137
        $path = Str::after($path, Hyde::getMediaDirectory());
138
        $path = Str::after($path, Hyde::getMediaOutputDirectory());
139
140
        return unslash($path);
141
    }
142
143
    protected static function isRemote(FrontMatter $matter): bool
144
    {
145
        if (is_string($matter->get('image')) && str_starts_with($matter->get('image'), 'http')) {
146
            return true;
147
        }
148
149
        return $matter->get('image.url') !== null;
150
    }
151
}
152