SeedsPublicationFiles::randomMarkdownLines()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Publications\Actions;
6
7
use Hyde\Publications\Models\PublicationFieldDefinition;
8
use Hyde\Publications\Models\PublicationType;
9
use Hyde\Publications\Pages\PublicationPage;
10
use Hyde\Publications\Publications;
11
use Illuminate\Support\Arr;
12
use Illuminate\Support\Carbon;
13
use Illuminate\Support\Str;
14
15
use function date;
16
use function implode;
17
use function in_array;
18
use function mt_getrandmax;
19
use function mt_rand;
20
use function rand;
21
use function substr;
22
use function time;
23
use function trim;
24
use function ucfirst;
25
26
/**
27
 * Seed publication files for a publication type.
28
 *
29
 * @internal This class is not part of the public API and does not adhere to the BC promise.
30
 *
31
 * @see \Hyde\Publications\Commands\SeedPublicationCommand
32
 * @see \Hyde\Publications\Testing\Feature\SeedsPublicationFilesTest
33
 */
34
class SeedsPublicationFiles
35
{
36
    protected PublicationType $publicationType;
37
    protected int $number = 1;
38
39
    protected array $matter;
40
    protected string $canonicalValue;
41
42
    public function __construct(PublicationType $publicationType, int $number = 1)
43
    {
44
        $this->number = $number;
45
        $this->publicationType = $publicationType;
46
    }
47
48
    public function create(): void
49
    {
50
        for ($i = 0; $i < $this->number; $i++) {
51
            $this->matter = [];
52
            $this->canonicalValue = '';
53
54
            $this->generatePublicationData();
55
            $identifier = Str::slug(substr($this->canonicalValue, 0, 64));
56
57
            $page = new PublicationPage($identifier, $this->matter, "## Write something awesome.\n\n{$this->randomMarkdownLines(rand(0, 16))}\n\n", $this->publicationType);
58
            $page->save();
59
        }
60
    }
61
62
    protected function generatePublicationData(): void
63
    {
64
        $this->matter['__createdAt'] = Carbon::today()->subDays(rand(1, 360))->addSeconds(rand(0, 86400));
65
        foreach ($this->publicationType->getFields() as $field) {
66
            $this->matter[$field->name] = $this->generateFieldData($field);
67
            $this->getCanonicalFieldName($field);
68
        }
69
70
        if (! $this->canonicalValue) {
71
            $this->canonicalValue = $this->fakeSentence(3);
72
        }
73
    }
74
75
    protected function getDateTimeValue(): string
76
    {
77
        return date('Y-m-d H:i:s', rand(
78
            time() - 86400 + rand(0, 86400),
79
            time() - (86400 * 365) + rand(0, 86400)
80
        ));
81
    }
82
83
    protected function getTextValue(int $lines): string
84
    {
85
        $value = '';
86
87
        for ($i = 0; $i < $lines; $i++) {
88
            $value .= $this->fakeSentence(rand(5, 20))."\n";
89
        }
90
91
        return $value;
92
    }
93
94
    protected function generateFieldData(PublicationFieldDefinition $field): string|int|float|array|bool
95
    {
96
        return match ($field->type->value) {
97
            'array' => $this->getArrayItems(),
98
            'boolean' => rand(0, 100) < 50,
99
            'datetime' => $this->getDateTimeValue(),
100
            'float' => ((mt_rand() / mt_getrandmax()) * 200000) + -100000,
101
            'media' => 'https://picsum.photos/id/'.rand(1, 1000).'/400/400',
102
            'integer' => rand(-100000, 100000),
103
            'string' => substr($this->fakeSentence(10), 0, rand(1, 255)),
104
            'tag' => $this->getTags(),
105
            'text' => $this->getTextValue(rand(3, 20)),
106
            'url' => $this->fakeUrl(),
107
        };
108
    }
109
110
    protected function getCanonicalFieldName(PublicationFieldDefinition $field): void
111
    {
112
        if ($this->canFieldTypeCanBeCanonical($field->type->value)) {
113
            if ($field->name === $this->publicationType->canonicalField) {
114
                $this->canonicalValue = $this->matter[$field->name];
115
            }
116
        }
117
    }
118
119
    protected function canFieldTypeCanBeCanonical(string $value): bool
120
    {
121
        return in_array($value, ['url', 'text', 'string', 'integer', 'float', 'datetime', 'array']);
122
    }
123
124
    protected function getArrayItems(): array
125
    {
126
        $arrayItems = [];
127
        for ($i = 0; $i < rand(3, 20); $i++) {
128
            $arrayItems[] = $this->fakeWord();
129
        }
130
131
        return $arrayItems;
132
    }
133
134
    protected function getTags(): string
135
    {
136
        $tags = Publications::getPublicationTags();
137
138
        return empty($tags) ? Arr::random(self::WORDS) : Arr::random($tags);
0 ignored issues
show
Bug Best Practice introduced by
The expression return empty($tags) ? Il...port\Arr::random($tags) could return the type array|null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
139
    }
140
141
    private const WORDS = [
142
        'lorem',        'ipsum',       'dolor',        'sit',
143
        'amet',         'consectetur', 'adipiscing',   'elit',
144
        'a',            'ac',          'accumsan',     'ad',
145
        'aenean',       'aliquam',     'aliquet',      'ante',
146
        'aptent',       'arcu',        'at',           'auctor',
147
        'augue',        'bibendum',    'blandit',      'class',
148
        'commodo',      'condimentum', 'congue',       'consequat',
149
        'conubia',      'convallis',   'cras',         'cubilia',
150
        'cum',          'curabitur',   'curae',        'cursus',
151
        'dapibus',      'diam',        'dictum',       'dictumst',
152
        'dignissim',    'dis',         'donec',        'dui',
153
        'duis',         'egestas',     'eget',         'eleifend',
154
        'elementum',    'enim',        'erat',         'eros',
155
        'est',          'et',          'etiam',        'eu',
156
        'euismod',      'facilisi',    'facilisis',    'fames',
157
        'faucibus',     'felis',       'fermentum',    'feugiat',
158
        'fringilla',    'fusce',       'gravida',      'habitant',
159
        'habitasse',    'hac',         'hendrerit',    'himenaeos',
160
        'iaculis',      'id',          'imperdiet',    'in',
161
        'inceptos',     'integer',     'interdum',     'justo',
162
        'lacinia',      'lacus',       'laoreet',      'lectus',
163
        'leo',          'libero',      'ligula',       'litora',
164
        'lobortis',     'luctus',      'maecenas',     'magna',
165
        'magnis',       'malesuada',   'massa',        'mattis',
166
        'mauris',       'metus',       'mi',           'molestie',
167
        'mollis',       'montes',      'morbi',        'mus',
168
        'nam',          'nascetur',    'natoque',      'nec',
169
        'neque',        'netus',       'nibh',         'nisi',
170
        'nisl',         'non',         'nostra',       'nulla',
171
        'nullam',       'nunc',        'odio',         'orci',
172
        'ornare',       'parturient',  'pellentesque', 'penatibus',
173
        'per',          'pharetra',    'phasellus',    'placerat',
174
        'platea',       'porta',       'porttitor',    'posuere',
175
        'potenti',      'praesent',    'pretium',      'primis',
176
        'proin',        'pulvinar',    'purus',        'quam',
177
        'quis',         'quisque',     'rhoncus',      'ridiculus',
178
        'risus',        'rutrum',      'sagittis',     'sapien',
179
        'scelerisque',  'sed',         'sem',          'semper',
180
        'senectus',     'sociis',      'sociosqu',     'sodales',
181
        'sollicitudin', 'suscipit',    'suspendisse',  'taciti',
182
        'tellus',       'tempor',      'tempus',       'tincidunt',
183
        'torquent',     'tortor',      'tristique',    'turpis',
184
        'ullamcorper',  'ultrices',    'ultricies',    'urna',
185
        'ut',           'varius',      'vehicula',     'vel',
186
        'velit',        'venenatis',   'vestibulum',   'vitae',
187
        'vivamus',      'viverra',     'volutpat',     'vulputate',
188
    ];
189
190
    private function fakeSentence(int $words): string
191
    {
192
        $sentence = '';
193
        for ($i = 0; $i < $words; $i++) {
194
            $sentence .= $this->fakeWord().' ';
195
        }
196
197
        return ucfirst(trim($sentence)).'.';
198
    }
199
200
    private function fakeWord(): string
201
    {
202
        return Arr::random(self::WORDS);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Illuminate\Support\Arr::random(self::WORDS) could return the type array|null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
203
    }
204
205
    private function fakeUrl(): string
206
    {
207
        return 'https://example.com/'.$this->fakeWord();
208
    }
209
210
    private function randomMarkdownLines(int $count): string
211
    {
212
        $lines = [];
213
        for ($i = 0; $i < $count; $i++) {
214
            $lines[] = $this->fakeSentence(rand(1, 15));
215
        }
216
217
        return implode("\n", $lines);
218
    }
219
}
220