Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
55 / 55 |
|
100.00% |
14 / 14 |
CRAP | |
100.00% |
1 / 1 |
| SeedsPublicationFiles | |
100.00% |
55 / 55 |
|
100.00% |
14 / 14 |
24 | |
100.00% |
1 / 1 |
| __construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
| create | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
| generatePublicationData | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
| getDateTimeValue | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
| getTextValue | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
| generateFieldData | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
1 | |||
| getCanonicalFieldName | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
| canFieldTypeCanBeCanonical | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getArrayItems | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
| getTags | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| fakeSentence | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
| fakeWord | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| fakeUrl | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| randomMarkdownLines | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
| 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); |
| 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 | } |