Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
55 / 55
100.00% covered (success)
100.00%
14 / 14
CRAP
100.00% covered (success)
100.00%
1 / 1
SeedsPublicationFiles
100.00% covered (success)
100.00%
55 / 55
100.00% covered (success)
100.00%
14 / 14
24
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 create
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 generatePublicationData
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 getDateTimeValue
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getTextValue
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 generateFieldData
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 getCanonicalFieldName
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 canFieldTypeCanBeCanonical
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getArrayItems
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getTags
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 fakeSentence
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 fakeWord
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fakeUrl
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 randomMarkdownLines
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Hyde\Publications\Actions;
6
7use Hyde\Publications\Models\PublicationFieldDefinition;
8use Hyde\Publications\Models\PublicationType;
9use Hyde\Publications\Pages\PublicationPage;
10use Hyde\Publications\Publications;
11use Illuminate\Support\Arr;
12use Illuminate\Support\Carbon;
13use Illuminate\Support\Str;
14
15use function date;
16use function implode;
17use function in_array;
18use function mt_getrandmax;
19use function mt_rand;
20use function rand;
21use function substr;
22use function time;
23use function trim;
24use 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 */
34class 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);
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);
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}