Passed
Push — master ( ad6b2a...b41ca0 )
by Caen
07:45 queued 14s
created

PostAuthor::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Features\Blogging\Models;
6
7
use Hyde\Hyde;
8
use Stringable;
9
use Illuminate\Support\Str;
10
use Hyde\Pages\MarkdownPost;
11
use Illuminate\Support\Collection;
12
use Hyde\Support\Concerns\Serializable;
13
use Hyde\Foundation\Kernel\PageCollection;
14
use Hyde\Support\Contracts\SerializableContract;
15
16
use function array_merge;
17
use function array_filter;
18
19
/**
20
 * Object representation of a blog post author for the site.
21
 *
22
 * @see \Hyde\Facades\Author For the facade to conveniently interact with and create authors.
23
 */
24
class PostAuthor implements Stringable, SerializableContract
25
{
26
    use Serializable;
27
28
    /**
29
     * The username of the author.
30
     *
31
     * This is the key used to find authors in the config and is taken from that array key.
32
     */
33
    public readonly string $username;
34
35
    /**
36
     * The display name of the author.
37
     */
38
    public readonly string $name;
39
40
    /**
41
     * The author's website URL.
42
     *
43
     * Could for example, be a Twitter page, website, or a hyperlink to more posts by the author.
44
     * Should be a fully qualified link, meaning it starts with http:// or https://.
45
     */
46
    public readonly ?string $website;
47
48
    /**
49
     * The author's biography.
50
     */
51
    public readonly ?string $bio;
52
53
    /**
54
     * The author's avatar image.
55
     *
56
     * If you in your Blade view use `Hyde::asset($author->avatar)`, then this value supports using both image names for files in `_media`, or full URIs starting with the protocol.
57
     */
58
    public readonly ?string $avatar;
59
60
    /**
61
     * The author's social media links/handles.
62
     *
63
     * @var ?array<string, string> String-to-string map of social media services to their respective handles.
64
     *
65
     * @example ['twitter' => 'mr_hyde'] ($service => $handle)
66
     */
67
    public readonly ?array $socials;
68
69
    /**
70
     * Construct a new Post Author instance with the given data.
71
     *
72
     * If your input is in the form of an array, you may rather want to use the `create` method.
73
     *
74
     * @param  array<string, string>  $socials
75
     */
76
    public function __construct(string $username, ?string $name = null, ?string $website = null, ?string $bio = null, ?string $avatar = null, ?array $socials = null)
77
    {
78
        $this->username = static::normalizeUsername($username);
79
        $this->name = $name ?? static::generateName($username);
80
        $this->website = $website;
81
        $this->bio = $bio;
82
        $this->avatar = $avatar;
83
        $this->socials = $socials;
84
    }
85
86
    /**
87
     * Create a new Post Author instance from an array of data.
88
     *
89
     * If you do not supply a username, the name will be used as the username, or 'Guest' if no name is provided.
90
     *
91
     * @param  array{username?: string, name?: string, website?: string, bio?: string, avatar?: string, socials?: array<string, string>}  $data
92
     */
93
    public static function create(array $data): PostAuthor
94
    {
95
        return new static(...array_merge([
96
            'username' => static::findUsernameFromData($data),
97
        ], $data));
98
    }
99
100
    /** Get a Post Author instance by username, or null if not found. */
101
    public static function get(string $username): ?static
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_STATIC on line 101 at column 51
Loading history...
102
    {
103
        return static::all()->get(static::normalizeUsername($username));
104
    }
105
106
    /** @return \Illuminate\Support\Collection<string, \Hyde\Framework\Features\Blogging\Models\PostAuthor> */
107
    public static function all(): Collection
108
    {
109
        return Hyde::authors();
110
    }
111
112
    public function __toString(): string
113
    {
114
        return $this->name;
115
    }
116
117
    public function toArray(): array
118
    {
119
        return array_filter($this->automaticallySerialize());
120
    }
121
122
    /**
123
     * Get all posts by this author.
124
     *
125
     * @return \Hyde\Foundation\Kernel\PageCollection<\Hyde\Pages\MarkdownPost>
126
     */
127
    public function getPosts(): PageCollection
128
    {
129
        return MarkdownPost::getLatestPosts()->filter(function (MarkdownPost $post) {
130
            return $post->author?->username === $this->username;
131
        });
132
    }
133
134
    /** @param array{username?: string, name?: string, website?: string} $data */
135
    protected static function findUsernameFromData(array $data): string
136
    {
137
        return static::normalizeUsername($data['username'] ?? $data['name'] ?? 'guest');
138
    }
139
140
    /** @internal */
141
    public static function normalizeUsername(string $username): string
142
    {
143
        return Str::slug($username, '_');
144
    }
145
146
    protected static function generateName(string $username): string
147
    {
148
        return Str::headline($username);
149
    }
150
}
151