1 | <?php |
||||
2 | |||||
3 | namespace LeKoala\DevToolkit; |
||||
4 | |||||
5 | use Exception; |
||||
6 | use SilverStripe\Assets\Image; |
||||
7 | use SilverStripe\Assets\Folder; |
||||
8 | use SilverStripe\ORM\DataObject; |
||||
9 | use LeKoala\Base\Geo\CountriesList; |
||||
0 ignored issues
–
show
|
|||||
10 | use SilverStripe\Assets\FileNameFilter; |
||||
11 | |||||
12 | /** |
||||
13 | * Provide fake data for random record generation |
||||
14 | */ |
||||
15 | class FakeDataProvider |
||||
16 | { |
||||
17 | protected static $folder = 'Faker'; |
||||
18 | protected static $latitude = 50.7802; |
||||
19 | protected static $longitude = 4.4269; |
||||
20 | protected static $firstNames = [ |
||||
21 | 'Caecilius', 'Quintus', 'Horatius', 'Flaccus', 'Clodius', |
||||
22 | 'Metellus', 'Flavius', 'Hortensius', 'Julius', 'Decimus', 'Gaius' |
||||
23 | ]; |
||||
24 | protected static $lastNames = [ |
||||
25 | 'Gracchus', 'Antonius', 'Brutus', 'Cassius', 'Casca', 'Lepidus', |
||||
26 | 'Crassus', 'Cinna' |
||||
27 | ]; |
||||
28 | protected static $addresses = [ |
||||
29 | [ |
||||
30 | 'Address' => '4880 Glory Rd', |
||||
31 | 'City' => 'Ponchatoula', |
||||
32 | 'Postcode' => 'LA 70454', |
||||
33 | 'Country' => 'US' |
||||
34 | ], |
||||
35 | [ |
||||
36 | 'Address' => '4363 Willow Oaks Lane', |
||||
37 | 'City' => 'Harrison Township', |
||||
38 | 'Postcode' => 'NJ 08062', |
||||
39 | 'Country' => 'US' |
||||
40 | ], |
||||
41 | [ |
||||
42 | 'Address' => '3471 Chipmunk Ln', |
||||
43 | 'City' => 'Clifton Heights', |
||||
44 | 'Postcode' => 'PA 19018 ‎', |
||||
45 | 'Country' => 'US' |
||||
46 | ], |
||||
47 | [ |
||||
48 | 'Address' => '666 Koala Ln', |
||||
49 | 'City' => 'Mt Laurel', |
||||
50 | 'Postcode' => 'NJ 08054‎', |
||||
51 | 'Country' => 'US' |
||||
52 | ], |
||||
53 | [ |
||||
54 | 'Address' => '3339 Little Acres Ln', |
||||
55 | 'City' => 'Woodford', |
||||
56 | 'Postcode' => 'VA 22580', |
||||
57 | 'Country' => 'US' |
||||
58 | ], |
||||
59 | [ |
||||
60 | 'Address' => '15 Anthony Avenue', |
||||
61 | 'City' => 'Essex', |
||||
62 | 'Postcode' => 'MD 21221', |
||||
63 | 'Country' => 'US' |
||||
64 | ], |
||||
65 | [ |
||||
66 | 'Address' => '2942 Kelly Ave', |
||||
67 | 'City' => 'Baltimore', |
||||
68 | 'Postcode' => 'MD 21209', |
||||
69 | 'Country' => 'US' |
||||
70 | ], |
||||
71 | [ |
||||
72 | 'Address' => '687 Burke Rd', |
||||
73 | 'City' => 'Delta', |
||||
74 | 'Postcode' => 'PA 17314', |
||||
75 | 'Country' => 'US' |
||||
76 | ], |
||||
77 | [ |
||||
78 | 'Address' => '1196 Court St', |
||||
79 | 'City' => 'York', |
||||
80 | 'Postcode' => 'PA 17404 ‎', |
||||
81 | 'Country' => 'US' |
||||
82 | ], |
||||
83 | [ |
||||
84 | 'Address' => '25 Barnes St', |
||||
85 | 'City' => 'Bel Air', |
||||
86 | 'Postcode' => 'MD 21014', |
||||
87 | 'Country' => 'US' |
||||
88 | ], |
||||
89 | ]; |
||||
90 | protected static $domains = ['perdu.com', 'silverstripe.org', 'google.be']; |
||||
91 | protected static $words = [ |
||||
92 | 'lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', |
||||
93 | 'elit', 'curabitur', 'vel', 'hendrerit', 'libero', 'eleifend', |
||||
94 | 'blandit', 'nunc', 'ornare', 'odio', 'ut', 'orci', |
||||
95 | 'gravida', 'imperdiet', 'nullam', 'purus', 'lacinia', 'a', |
||||
96 | 'pretium', 'quis', 'congue', 'praesent', 'sagittis', 'laoreet', |
||||
97 | 'auctor', 'mauris', 'non', 'velit', 'eros', 'dictum', |
||||
98 | 'proin', 'accumsan', 'sapien', 'nec', 'massa', 'volutpat', |
||||
99 | 'venenatis', 'sed', 'eu', 'molestie', 'lacus', 'quisque', |
||||
100 | 'porttitor', 'ligula', 'dui', 'mollis', 'tempus', 'at', |
||||
101 | 'magna', 'vestibulum', 'turpis', 'ac', 'diam', |
||||
102 | 'tincidunt', 'id', 'condimentum', 'enim', 'sodales', 'in', |
||||
103 | 'hac', 'habitasse', 'platea', 'dictumst', 'aenean', 'neque', |
||||
104 | 'fusce', 'augue', 'leo', 'eget', 'semper', 'mattis', |
||||
105 | 'tortor', 'scelerisque', 'nulla', 'interdum', 'tellus', |
||||
106 | 'malesuada', 'rhoncus', 'porta', 'sem', 'aliquet', |
||||
107 | 'et', 'nam', 'suspendisse', 'potenti', 'vivamus', 'luctus', |
||||
108 | 'fringilla', 'erat', 'donec', 'justo', 'vehicula', |
||||
109 | 'ultricies', 'varius', 'ante', 'primis', 'faucibus', 'ultrices', |
||||
110 | 'posuere', 'cubilia', 'curae', 'etiam', 'cursus', |
||||
111 | 'aliquam', 'quam', 'dapibus', 'nisl', 'feugiat', 'egestas', |
||||
112 | 'class', 'aptent', 'taciti', 'sociosqu', 'ad', 'litora', |
||||
113 | 'torquent', 'per', 'conubia', 'nostra', 'inceptos', 'himenaeos', |
||||
114 | 'phasellus', 'nibh', 'pulvinar', 'vitae', 'urna', 'iaculis', |
||||
115 | 'lobortis', 'nisi', 'viverra', 'arcu', 'morbi', 'pellentesque', |
||||
116 | 'metus', 'commodo', 'ut', 'facilisis', 'felis', |
||||
117 | 'tristique', 'ullamcorper', 'placerat', 'aenean', 'convallis', |
||||
118 | 'sollicitudin', 'integer', 'rutrum', 'duis', 'est', |
||||
119 | 'etiam', 'bibendum', 'donec', 'pharetra', 'vulputate', 'maecenas', |
||||
120 | 'mi', 'fermentum', 'consequat', 'suscipit', 'aliquam', |
||||
121 | 'habitant', 'senectus', 'netus', 'fames', 'quisque', |
||||
122 | 'euismod', 'curabitur', 'lectus', 'elementum', 'tempor', |
||||
123 | 'risus', 'cras' |
||||
124 | ]; |
||||
125 | |||||
126 | /** |
||||
127 | * A random firstname |
||||
128 | * |
||||
129 | * @return string |
||||
130 | */ |
||||
131 | public static function firstname() |
||||
132 | { |
||||
133 | return self::$firstNames[array_rand(self::$firstNames)]; |
||||
134 | } |
||||
135 | |||||
136 | /** |
||||
137 | * A random lastname |
||||
138 | * |
||||
139 | * @return string |
||||
140 | */ |
||||
141 | public static function lastname() |
||||
142 | { |
||||
143 | return self::$lastNames[array_rand(self::$lastNames)]; |
||||
144 | } |
||||
145 | |||||
146 | /** |
||||
147 | * A random name |
||||
148 | * |
||||
149 | * @return string |
||||
150 | */ |
||||
151 | public static function name() |
||||
152 | { |
||||
153 | return self::firstname() . ' ' . self::lastname(); |
||||
154 | } |
||||
155 | |||||
156 | /** |
||||
157 | * A random boolean |
||||
158 | * |
||||
159 | * @return bool |
||||
160 | */ |
||||
161 | public static function boolean() |
||||
162 | { |
||||
163 | return rand(0, 1) == 1; |
||||
164 | } |
||||
165 | |||||
166 | /** |
||||
167 | * A random address |
||||
168 | * |
||||
169 | * @return array |
||||
170 | */ |
||||
171 | public static function address() |
||||
172 | { |
||||
173 | return self::$addresses[array_rand(self::$addresses)]; |
||||
174 | } |
||||
175 | |||||
176 | /** |
||||
177 | * A random address part |
||||
178 | * |
||||
179 | * @param string $part Address, Street, StreetNumber, City, Postcode or Country |
||||
180 | * @return string |
||||
181 | */ |
||||
182 | public static function addressPart($part) |
||||
183 | { |
||||
184 | $address = self::address(); |
||||
185 | $rpart = $part; |
||||
186 | if ($part == 'Street' || $part == 'StreetNumber') { |
||||
187 | $rpart = 'Address'; |
||||
188 | } |
||||
189 | $v = $address[$rpart]; |
||||
190 | if ($part == 'Street' || $part == 'StreetNumber') { |
||||
191 | $vex = explode(' ', $v); |
||||
192 | if ($part == 'Street') { |
||||
193 | array_shift($vex); |
||||
194 | $v = implode(' ', $vex); |
||||
195 | } |
||||
196 | if ($part == 'StreetNumber') { |
||||
197 | $v = $vex[0]; |
||||
198 | } |
||||
199 | } |
||||
200 | return $v; |
||||
201 | } |
||||
202 | |||||
203 | /** |
||||
204 | * Random float point value |
||||
205 | * |
||||
206 | * @param int $intMin |
||||
207 | * @param int $intMax |
||||
208 | * @param int $intDecimals |
||||
209 | * @return float |
||||
210 | */ |
||||
211 | public static function fprand($intMin, $intMax, $intDecimals) |
||||
212 | { |
||||
213 | if ($intDecimals) { |
||||
214 | $intPowerTen = pow(10, $intDecimals); |
||||
215 | return rand($intMin, $intMax * $intPowerTen) / $intPowerTen; |
||||
216 | } else { |
||||
217 | return rand($intMin, $intMax); |
||||
218 | } |
||||
219 | } |
||||
220 | |||||
221 | /** |
||||
222 | * A randomized position |
||||
223 | * |
||||
224 | * @param float $latitude |
||||
225 | * @param float $longitude |
||||
226 | * @param int $radius |
||||
227 | * @return array |
||||
228 | */ |
||||
229 | public static function latLon($latitude = null, $longitude = null, $radius = 20) |
||||
230 | { |
||||
231 | if ($latitude === null) { |
||||
232 | $latitude = self::$latitude; |
||||
233 | } |
||||
234 | if ($longitude === null) { |
||||
235 | $longitude = self::$longitude; |
||||
236 | } |
||||
237 | $lng_min = $longitude - $radius / abs(cos(deg2rad($latitude)) * 69); |
||||
238 | $lng_max = $longitude + $radius / abs(cos(deg2rad($latitude)) * 69); |
||||
239 | $lat_min = $latitude - ($radius / 69); |
||||
240 | $lat_max = $latitude + ($radius / 69); |
||||
241 | |||||
242 | $rand = self::fprand(0, ($lng_max - $lng_min), 3); |
||||
0 ignored issues
–
show
$lng_max - $lng_min of type double is incompatible with the type integer expected by parameter $intMax of LeKoala\DevToolkit\FakeDataProvider::fprand() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
243 | $lng = $lng_min + $rand; |
||||
244 | $rand = self::fprand(0, ($lat_max - $lat_min), 3); |
||||
245 | $lat = $lat_min + $rand; |
||||
246 | |||||
247 | return compact('lat', 'lng', 'lng_min', 'lat_min', 'lng_max', 'lat_max'); |
||||
248 | } |
||||
249 | |||||
250 | /** |
||||
251 | * A random domain |
||||
252 | * @return string |
||||
253 | */ |
||||
254 | public static function domain() |
||||
255 | { |
||||
256 | return self::$domains[array_rand(self::$domains)]; |
||||
257 | } |
||||
258 | |||||
259 | /** |
||||
260 | * A random website |
||||
261 | * |
||||
262 | * @return string |
||||
263 | */ |
||||
264 | public static function website() |
||||
265 | { |
||||
266 | return 'http://www' . self::domain(); |
||||
267 | } |
||||
268 | |||||
269 | public static function adorableAvatar($size = 200, $id = null) |
||||
270 | { |
||||
271 | if (!$id) { |
||||
272 | $id = uniqid(); |
||||
273 | } |
||||
274 | $result = file_get_contents('https://api.adorable.io/avatars/' . $size . '/' . $id); |
||||
275 | |||||
276 | return self::storeFakeImage($result, $id . '.png', 'Adorable'); |
||||
277 | } |
||||
278 | |||||
279 | /** |
||||
280 | * Generate some random users |
||||
281 | * |
||||
282 | * @link https://randomuser.me/documentation |
||||
283 | * @param array $params |
||||
284 | * @param bool $useDefaultParams |
||||
285 | * @return array |
||||
286 | */ |
||||
287 | public static function randomUser($params = [], $useDefaultParams = true) |
||||
288 | { |
||||
289 | $defaultParams = [ |
||||
290 | 'results' => '20', |
||||
291 | 'password' => 'upper,lower,8-12', |
||||
292 | 'nat' => 'fr,us,gb,de', |
||||
293 | ]; |
||||
294 | |||||
295 | if ($useDefaultParams) { |
||||
296 | $params = array_merge($defaultParams, $params); |
||||
297 | } |
||||
298 | $result = file_get_contents('https://randomuser.me/api/?' . http_build_query($params)); |
||||
299 | |||||
300 | $data = json_decode($result, JSON_OBJECT_AS_ARRAY); |
||||
0 ignored issues
–
show
LeKoala\DevToolkit\JSON_OBJECT_AS_ARRAY of type integer is incompatible with the type boolean|null expected by parameter $associative of json_decode() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
301 | |||||
302 | if (!empty($data['error'])) { |
||||
303 | throw new Exception($data['error']); |
||||
304 | } |
||||
305 | |||||
306 | return $data['results']; |
||||
307 | } |
||||
308 | |||||
309 | /** |
||||
310 | * Store a fake image |
||||
311 | * |
||||
312 | * @param string $data |
||||
313 | * @param string $name The filename, including extension |
||||
314 | * @param string $folder The sub folder where the fake image is stored (default folder is Faker/Uploads) |
||||
315 | * @return Image |
||||
316 | */ |
||||
317 | public static function storeFakeImage($data, $name, $folder = 'Uploads') |
||||
318 | { |
||||
319 | $filter = new FileNameFilter; |
||||
320 | $name = $filter->filter($name); |
||||
321 | |||||
322 | $folderName = self::$folder . '/' . $folder; |
||||
323 | $filename = $folderName . '/' . $name; |
||||
324 | |||||
325 | $image = new Image; |
||||
326 | $image->setFromString($data, $filename); |
||||
327 | $image->write(); |
||||
328 | |||||
329 | return $image; |
||||
330 | } |
||||
331 | |||||
332 | /** |
||||
333 | * Get a random image |
||||
334 | * |
||||
335 | * Images are generated only once, if folder does not exists in assets |
||||
336 | * |
||||
337 | * @return Image |
||||
338 | */ |
||||
339 | public static function image() |
||||
340 | { |
||||
341 | $path = self::$folder . '/Images'; |
||||
342 | $images = Image::get()->where("FileFilename LIKE '$path%'"); |
||||
343 | if ($images->count() <= 0) { |
||||
344 | $folder = Folder::find_or_make($path); |
||||
0 ignored issues
–
show
|
|||||
345 | foreach (range(1, 30) as $i) { |
||||
346 | $data = file_get_contents("https://picsum.photos/id/$i/1920/1080"); |
||||
347 | $filename = "$path/fake-$i.jpg"; |
||||
348 | $imageObj = new Image; |
||||
349 | $imageObj->setFromString($data, $filename); |
||||
350 | $imageObj->write(); |
||||
351 | |||||
352 | // publish this stuff! |
||||
353 | if ($imageObj->isInDB() && !$imageObj->isPublished()) { |
||||
354 | $imageObj->publishSingle(); |
||||
355 | } |
||||
356 | } |
||||
357 | $images = Image::get()->where("FileFilename LIKE 'Faker/Images%'"); |
||||
358 | } |
||||
359 | $rand = rand(0, count($images)); |
||||
360 | foreach ($images as $key => $image) { |
||||
361 | if ($key == $rand) { |
||||
362 | // publish this stuff! |
||||
363 | if ($image->isInDB() && !$image->isPublished()) { |
||||
364 | $image->publishSingle(); |
||||
365 | } |
||||
366 | |||||
367 | return $image; |
||||
368 | } |
||||
369 | } |
||||
370 | return $images->First(); |
||||
371 | } |
||||
372 | |||||
373 | /** |
||||
374 | * Get a random image unique for a record that can be deleted without side effects |
||||
375 | * for other records |
||||
376 | * |
||||
377 | * @param DataObject $record |
||||
378 | * @return Image |
||||
379 | */ |
||||
380 | public static function ownImage($record) |
||||
381 | { |
||||
382 | $path = self::$folder; |
||||
383 | if ($record->hasMethod('getFolderName')) { |
||||
384 | $path = $record->getFolderName(); |
||||
385 | $path .= "/" . self::$folder; |
||||
386 | } |
||||
387 | |||||
388 | $i = rand(1, 1080); |
||||
389 | $data = file_get_contents("https://picsum.photos/id/$i/1920/1080"); |
||||
390 | |||||
391 | $name = "fake-$i.jpg"; |
||||
392 | $filename = "$path/$name"; |
||||
393 | |||||
394 | $image = new Image; |
||||
395 | $image->setFromString($data, $filename); |
||||
396 | $image->write(); |
||||
397 | |||||
398 | return $image; |
||||
399 | } |
||||
400 | |||||
401 | /** |
||||
402 | * Get a random record |
||||
403 | * |
||||
404 | * @param string $class |
||||
405 | * @param array $filters |
||||
406 | * @return DataObject |
||||
407 | */ |
||||
408 | public static function record($class, $filters = []) |
||||
409 | { |
||||
410 | $q = $class::get()->sort('RAND()'); |
||||
411 | if (!empty($filters)) { |
||||
412 | $q = $q->filter($filters); |
||||
413 | } |
||||
414 | return $q->first(); |
||||
415 | } |
||||
416 | |||||
417 | /** |
||||
418 | * Get random words |
||||
419 | * |
||||
420 | * @param int $num |
||||
421 | * @param int $num2 |
||||
422 | * @return string |
||||
423 | */ |
||||
424 | public static function words($num, $num2 = null) |
||||
425 | { |
||||
426 | $res = []; |
||||
427 | $i = 0; |
||||
428 | $total = $num; |
||||
429 | if ($num2 !== null) { |
||||
430 | $i = rand(0, $num); |
||||
431 | $total = $num2; |
||||
432 | } |
||||
433 | $req = $total - $i; |
||||
434 | foreach (array_rand(self::$words, $req) as $key) { |
||||
435 | $res[] = self::$words[$key]; |
||||
436 | } |
||||
437 | return implode(' ', $res); |
||||
438 | } |
||||
439 | |||||
440 | /** |
||||
441 | * Get random sentences |
||||
442 | * |
||||
443 | * @param int $num |
||||
444 | * @param int $num2 |
||||
445 | * @return string |
||||
446 | */ |
||||
447 | public static function sentences($num, $num2 = null) |
||||
448 | { |
||||
449 | $res = []; |
||||
450 | $i = 0; |
||||
451 | $total = $num; |
||||
452 | if ($num2 !== null) { |
||||
453 | $i = rand(0, $num); |
||||
454 | $total = $num2; |
||||
455 | } |
||||
456 | $req = $total - $i; |
||||
457 | while ($req--) { |
||||
458 | $res[] = self::words(5, 10); |
||||
459 | } |
||||
460 | return implode(".\n", $res); |
||||
461 | } |
||||
462 | |||||
463 | /** |
||||
464 | * Get random paragraphs |
||||
465 | * |
||||
466 | * @param int $num |
||||
467 | * @param int $num2 |
||||
468 | * @return string |
||||
469 | */ |
||||
470 | public static function paragraphs($num, $num2 = null) |
||||
471 | { |
||||
472 | $res = []; |
||||
473 | $i = 0; |
||||
474 | $total = $num; |
||||
475 | if ($num2 !== null) { |
||||
476 | $i = rand(0, $num); |
||||
477 | $total = $num2; |
||||
478 | } |
||||
479 | $req = $total - $i; |
||||
480 | while ($req--) { |
||||
481 | $res[] = "<p>" . self::sentences(3, 7) . "</p>"; |
||||
482 | } |
||||
483 | return implode("\n", $res); |
||||
484 | } |
||||
485 | |||||
486 | /** |
||||
487 | * Get a date between two dates |
||||
488 | * |
||||
489 | * @param string $num |
||||
490 | * @param string $num2 |
||||
491 | * @param string $format |
||||
492 | * @return string |
||||
493 | */ |
||||
494 | public static function date($num, $num2, $format = 'Y-m-d H:i:s') |
||||
495 | { |
||||
496 | if (is_string($num)) { |
||||
0 ignored issues
–
show
|
|||||
497 | $num = strtotime($num); |
||||
498 | } |
||||
499 | if (is_string($num2)) { |
||||
0 ignored issues
–
show
|
|||||
500 | $num2 = strtotime($num2); |
||||
501 | } |
||||
502 | $rand = rand($num, $num2); |
||||
503 | return date($format, $rand); |
||||
504 | } |
||||
505 | |||||
506 | /** |
||||
507 | * Male or female |
||||
508 | * |
||||
509 | * @return string |
||||
510 | */ |
||||
511 | public static function male_or_female() |
||||
512 | { |
||||
513 | return self::pick(['male', 'female']); |
||||
0 ignored issues
–
show
|
|||||
514 | } |
||||
515 | |||||
516 | /** |
||||
517 | * Randomly pick in an array |
||||
518 | * |
||||
519 | * @param array $arr |
||||
520 | * @return array |
||||
521 | */ |
||||
522 | public static function pick(array $arr) |
||||
523 | { |
||||
524 | return $arr[array_rand($arr)]; |
||||
525 | } |
||||
526 | |||||
527 | /** |
||||
528 | * Get a random country |
||||
529 | * |
||||
530 | * @return string |
||||
531 | */ |
||||
532 | public static function country() |
||||
533 | { |
||||
534 | $countries = array_values(CountriesList::get()); |
||||
535 | return $countries[array_rand($countries)]; |
||||
536 | } |
||||
537 | |||||
538 | /** |
||||
539 | * Get a random country code |
||||
540 | * |
||||
541 | * @return string |
||||
542 | */ |
||||
543 | public static function countryCode() |
||||
544 | { |
||||
545 | $countries = array_keys(CountriesList::get()); |
||||
546 | return $countries[array_rand($countries)]; |
||||
547 | } |
||||
548 | } |
||||
549 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths