Total Complexity | 110 |
Total Lines | 767 |
Duplicated Lines | 0 % |
Coverage | 60.12% |
Changes | 0 |
Complex classes like Seeding often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Seeding, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
22 | trait Seeding { |
||
23 | |||
24 | /** |
||
25 | * @var int Max number of items to be created by the seed |
||
26 | */ |
||
27 | protected $limit = 20; |
||
28 | |||
29 | /** |
||
30 | * @var \Faker\Generator |
||
31 | */ |
||
32 | protected $faker; |
||
33 | |||
34 | /** |
||
35 | * Returns an instance of faker |
||
36 | * |
||
37 | * @param string $locale Locale |
||
38 | * |
||
39 | * @return \Faker\Generator |
||
40 | */ |
||
41 | 358 | public function faker($locale = 'en_US') { |
|
42 | 358 | if (!isset($this->faker)) { |
|
43 | 358 | $this->faker = Factory::create($locale); |
|
44 | } |
||
45 | |||
46 | 358 | return $this->faker; |
|
47 | } |
||
48 | |||
49 | /** |
||
50 | * Get site domain |
||
51 | * @return string |
||
52 | */ |
||
53 | public function getDomain() { |
||
54 | return elgg_get_site_entity()->getDomain(); |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Get valid domain for emails |
||
59 | * @return string |
||
60 | */ |
||
61 | 160 | public function getEmailDomain() { |
|
62 | 160 | $email = elgg_get_site_entity()->email; |
|
63 | 160 | if (!$email) { |
|
64 | $email = "[email protected]{$this->getDomain()}"; |
||
65 | } |
||
66 | |||
67 | 160 | list(, $domain) = explode('@', $email); |
|
|
|||
68 | |||
69 | 160 | if (sizeof(explode('.', $domain)) <= 1) { |
|
70 | $domain = 'example.net'; |
||
71 | } |
||
72 | |||
73 | 160 | return $domain; |
|
74 | } |
||
75 | |||
76 | /** |
||
77 | * Returns random unique subtype |
||
78 | * @return bool|string |
||
79 | */ |
||
80 | 419 | public function getRandomSubtype() { |
|
81 | 419 | return substr(sha1(microtime() . rand()), 0, 25); |
|
82 | } |
||
83 | |||
84 | /** |
||
85 | * Create a new fake user |
||
86 | * |
||
87 | * @param array $attributes User entity attributes |
||
88 | * @param array $metadata User entity metadata |
||
89 | * @param array $options Seeding options |
||
90 | * |
||
91 | * @return ElggUser |
||
92 | */ |
||
93 | public function createUser(array $attributes = [], array $metadata = [], array $options = []) { |
||
186 | |||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Create a new fake group |
||
191 | * |
||
192 | * @param array $attributes Group entity attributes |
||
193 | * @param array $metadata Group entity metadata |
||
194 | * @param array $options Additional options |
||
195 | * |
||
196 | * @return ElggGroup |
||
197 | */ |
||
198 | public function createGroup(array $attributes = [], array $metadata = [], array $options = []) { |
||
199 | |||
200 | 73 | $create = function () use ($attributes, $metadata, $options) { |
|
201 | 73 | $metadata['__faker'] = true; |
|
202 | |||
203 | 73 | if (empty($attributes['access_id'])) { |
|
204 | 73 | $attributes['access_id'] = ACCESS_PUBLIC; |
|
205 | } |
||
206 | |||
207 | 73 | if (empty($metadata['content_access_mode'])) { |
|
208 | 73 | $metadata['content_access_mode'] = ElggGroup::CONTENT_ACCESS_MODE_UNRESTRICTED; |
|
209 | } |
||
210 | |||
211 | 73 | if (empty($metadata['membership'])) { |
|
212 | 73 | $metadata['membership'] = ACCESS_PUBLIC; |
|
213 | } |
||
214 | |||
215 | 73 | if (empty($metadata['name'])) { |
|
216 | 73 | $metadata['name'] = $this->faker()->sentence(); |
|
217 | } |
||
218 | |||
219 | 73 | if (empty($metadata['description'])) { |
|
220 | 73 | $metadata['description'] = $this->faker()->text($this->faker()->numberBetween(500, 1000)); |
|
221 | } |
||
222 | |||
223 | 73 | if (empty($attributes['owner_guid'])) { |
|
224 | 73 | $user = elgg_get_logged_in_user_entity(); |
|
225 | 73 | if (!$user) { |
|
226 | 66 | $user = $this->getRandomUser(); |
|
227 | } |
||
228 | 73 | if (!$user) { |
|
229 | $user = $this->createUser(); |
||
230 | } |
||
231 | |||
232 | 73 | $attributes['owner_guid'] = $user->guid; |
|
233 | } |
||
234 | |||
235 | 73 | if (empty($attributes['container_guid'])) { |
|
236 | 73 | $attributes['container_guid'] = $attributes['owner_guid']; |
|
237 | } |
||
238 | |||
239 | 73 | if (empty($attributes['subtype'])) { |
|
240 | 6 | $attributes['subtype'] = 'group'; |
|
241 | } |
||
242 | |||
243 | 73 | $owner = get_entity($attributes['owner_guid']); |
|
244 | 73 | if (!$owner) { |
|
245 | return false; |
||
246 | } |
||
247 | |||
248 | 73 | $container = get_entity($attributes['container_guid']); |
|
249 | 73 | if (!$container) { |
|
250 | return false; |
||
251 | } |
||
252 | |||
253 | 73 | $tool_options = elgg_extract('group_tools_options', $options, []); |
|
254 | 73 | if ($tool_options) { |
|
255 | foreach ($tool_options as $group_option) { |
||
256 | $option_toggle_name = $group_option->name . "_enable"; |
||
257 | $option_default = $group_option->default_on ? 'yes' : 'no'; |
||
258 | $metadata[$option_toggle_name] = $option_default; |
||
259 | } |
||
260 | } |
||
261 | |||
262 | 73 | if ($this->faker()->boolean(20)) { |
|
263 | 11 | $metadata['featured_group'] = 'yes'; |
|
264 | } |
||
265 | |||
266 | 73 | $group = new ElggGroup(); |
|
267 | 73 | foreach ($attributes as $name => $value) { |
|
268 | 73 | $group->$name = $value; |
|
269 | } |
||
270 | |||
271 | 73 | $profile_fields = elgg_extract('profile_fields', $options, []); |
|
272 | 73 | $group = $this->populateMetadata($group, $profile_fields, $metadata); |
|
273 | |||
274 | 73 | $group->save(); |
|
275 | |||
276 | 73 | if ($group->access_id == ACCESS_PRIVATE) { |
|
277 | $acls = $group->getOwnedAccessCollections(['subtype' => 'group_acl']); |
||
278 | if ($acls) { |
||
279 | $group->access_id = $acls[0]->id; |
||
280 | $group->save(); |
||
281 | } |
||
282 | } |
||
283 | |||
284 | 73 | $group->join(get_entity($attributes['owner_guid'])); |
|
285 | |||
286 | 73 | elgg_create_river_item([ |
|
287 | 73 | 'view' => 'river/group/create', |
|
288 | 73 | 'action_type' => 'create', |
|
289 | 73 | 'subject_guid' => $owner->guid, |
|
290 | 73 | 'object_guid' => $group->guid, |
|
291 | 73 | 'target_guid' => $container->guid, |
|
292 | ]); |
||
293 | |||
294 | 73 | $this->log("Created new group $group->name [guid: $group->guid]"); |
|
295 | |||
296 | 73 | return $group; |
|
297 | 73 | }; |
|
298 | |||
299 | 73 | $ia = elgg_set_ignore_access(true); |
|
300 | |||
301 | 73 | $group = false; |
|
302 | 73 | while (!$group instanceof \ElggGroup) { |
|
303 | 73 | $group = $create(); |
|
304 | } |
||
305 | |||
306 | 73 | elgg_set_ignore_access($ia); |
|
307 | |||
308 | 73 | return $group; |
|
309 | } |
||
310 | |||
311 | /** |
||
312 | * Create a new fake object |
||
313 | * |
||
314 | * @param array $attributes Object entity attributes |
||
315 | * @param array $metadata Object entity metadata |
||
316 | * @param array $options Additional options |
||
317 | * |
||
318 | * @return ElggObject |
||
319 | */ |
||
320 | public function createObject(array $attributes = [], array $metadata = [], array $options = []) { |
||
321 | |||
322 | 180 | $create = function () use ($attributes, $metadata, $options) { |
|
323 | |||
324 | 180 | $properties = array_merge($metadata, $attributes); |
|
325 | |||
326 | 180 | $properties['__faker'] = true; |
|
327 | |||
328 | 180 | if (empty($properties['title'])) { |
|
329 | 179 | $properties['title'] = $this->faker()->sentence(); |
|
330 | } |
||
331 | |||
332 | 180 | if (empty($properties['description'])) { |
|
333 | 179 | $properties['description'] = $this->faker()->text($this->faker()->numberBetween(500, 1000)); |
|
334 | } |
||
335 | |||
336 | 180 | if (empty($properties['subtype'])) { |
|
337 | 36 | $properties['subtype'] = $this->getRandomSubtype(); |
|
338 | } |
||
339 | |||
340 | 180 | if (empty($properties['tags'])) { |
|
341 | 158 | $properties['tags'] = $this->faker()->words(10); |
|
342 | } |
||
343 | |||
344 | 180 | if (empty($properties['container_guid'])) { |
|
345 | 179 | $container = elgg_get_logged_in_user_entity(); |
|
346 | 179 | if (!$container) { |
|
347 | 111 | $container = $this->getRandomUser(); |
|
348 | } |
||
349 | 179 | if (!$container) { |
|
350 | $container = $this->createUser(); |
||
351 | } |
||
352 | |||
353 | 179 | $properties['container_guid'] = $container->guid; |
|
354 | } |
||
355 | |||
356 | 180 | $container = get_entity($properties['container_guid']); |
|
357 | 180 | if (!$container) { |
|
358 | return false; |
||
359 | } |
||
360 | |||
361 | 180 | if (empty($properties['owner_guid'])) { |
|
362 | 166 | $owner = $container; |
|
363 | 166 | $properties['owner_guid'] = $owner->guid; |
|
364 | } |
||
365 | |||
366 | 180 | $owner = get_entity($properties['owner_guid']); |
|
367 | 180 | if (!$owner) { |
|
368 | return false; |
||
369 | } |
||
370 | |||
371 | 180 | if (!isset($properties['access_id'])) { |
|
372 | 175 | $properties['access_id'] = ACCESS_PUBLIC; |
|
373 | } |
||
374 | |||
375 | 180 | $class = elgg_get_entity_class('object', $properties['subtype']); |
|
376 | 180 | if ($class && class_exists($class)) { |
|
377 | 26 | $object = new $class(); |
|
378 | } else { |
||
379 | 155 | $object = new ElggObject(); |
|
380 | } |
||
381 | |||
382 | 180 | foreach ($properties as $name => $value) { |
|
383 | 180 | $object->$name = $value; |
|
384 | } |
||
385 | |||
386 | 180 | $profile_fields = elgg_extract('profile_fields', $options, []); |
|
387 | 180 | $object = $this->populateMetadata($object, $profile_fields, $properties); |
|
388 | |||
389 | 180 | if (elgg_extract('save', $options, true)) { |
|
390 | 180 | $object->save(); |
|
391 | } |
||
392 | |||
393 | 180 | $type_str = elgg_echo("item:object:{$object->getSubtype()}"); |
|
394 | |||
395 | 180 | $this->log("Created new item in $type_str $object->title [guid: $object->guid]"); |
|
396 | |||
397 | 180 | return $object; |
|
398 | 180 | }; |
|
399 | |||
400 | 180 | $ia = elgg_set_ignore_access(true); |
|
401 | |||
402 | 180 | $object = false; |
|
403 | 180 | while (!$object instanceof \ElggObject) { |
|
404 | 180 | $object = $create(); |
|
405 | } |
||
406 | |||
407 | 180 | elgg_set_ignore_access($ia); |
|
408 | |||
409 | 180 | return $object; |
|
410 | |||
411 | } |
||
412 | |||
413 | /** |
||
414 | * Create a new fake site |
||
415 | * |
||
416 | * @param array $attributes Object entity attributes |
||
417 | * @param array $metadata Object entity metadata |
||
418 | * |
||
419 | * @return ElggObject |
||
420 | */ |
||
421 | public function createSite(array $attributes = [], array $metadata = []) { |
||
2 ignored issues
–
show
|
|||
422 | // We don't want to create more than one site |
||
423 | return elgg_get_site_entity(); |
||
424 | } |
||
425 | |||
426 | /** |
||
427 | * Returns random fake user |
||
428 | * |
||
429 | * @param int[] $exclude GUIDs to exclude |
||
430 | * |
||
431 | * @return ElggUser|false |
||
432 | */ |
||
433 | 178 | public function getRandomUser(array $exclude = []) { |
|
434 | |||
435 | 178 | $exclude[] = 0; |
|
436 | 178 | $exclude_in = implode(',', array_map(function ($e) { |
|
437 | 178 | return (int) $e; |
|
438 | 178 | }, $exclude)); |
|
439 | |||
440 | 178 | $users = elgg_get_entities([ |
|
441 | 178 | 'types' => 'user', |
|
442 | 'metadata_names' => ['__faker'], |
||
443 | 178 | 'limit' => 1, |
|
444 | 'wheres' => [ |
||
445 | 178 | "e.guid NOT IN ($exclude_in)", |
|
446 | ], |
||
447 | 178 | 'order_by' => 'RAND()', |
|
448 | ]); |
||
449 | |||
450 | 178 | return $users ? $users[0] : false; |
|
451 | } |
||
452 | |||
453 | /** |
||
454 | * Returns random fake group |
||
455 | * |
||
456 | * @param int[] $exclude GUIDs to exclude |
||
457 | * |
||
458 | * @return ElggGroup|false |
||
459 | */ |
||
460 | public function getRandomGroup(array $exclude = []) { |
||
461 | |||
462 | $exclude[] = 0; |
||
463 | $exclude_in = implode(',', array_map(function ($e) { |
||
464 | return (int) $e; |
||
465 | }, $exclude)); |
||
466 | |||
467 | $groups = elgg_get_entities([ |
||
468 | 'types' => 'group', |
||
469 | 'metadata_names' => ['__faker'], |
||
470 | 'limit' => 1, |
||
471 | 'wheres' => [ |
||
472 | "e.guid NOT IN ($exclude_in)", |
||
473 | ], |
||
474 | 'order_by' => 'RAND()', |
||
475 | ]); |
||
476 | |||
477 | return $groups ? $groups[0] : false; |
||
478 | } |
||
479 | |||
480 | /** |
||
481 | * Get random access id |
||
482 | * |
||
483 | * @param ElggUser $user User |
||
484 | * @param ElggEntity $container Container |
||
485 | * |
||
486 | * @return int |
||
487 | */ |
||
488 | public function getRandomAccessId(\ElggUser $user = null, ElggEntity $container = null) { |
||
499 | } |
||
500 | |||
501 | /** |
||
502 | * Generates a unique available and valid username |
||
503 | * |
||
504 | * @param string $base_name Display name, email or other prefix to use as basis |
||
505 | * |
||
506 | * @return string |
||
507 | */ |
||
508 | 172 | public function getRandomUsername($base_name = 'user') { |
|
594 | } |
||
595 | |||
596 | /** |
||
597 | * Set random metadata |
||
598 | * |
||
599 | * @param ElggEntity $entity Entity |
||
600 | * @param array $fields An array of profile fields in $name => $input_type format |
||
601 | * @param array $metadata Other metadata $name => $value pairs to set |
||
602 | * |
||
603 | * @return ElggEntity |
||
604 | */ |
||
605 | 358 | public function populateMetadata(ElggEntity $entity, array $fields = [], array $metadata = []) { |
|
606 | |||
607 | 358 | foreach ($fields as $name => $type) { |
|
608 | if (isset($metadata[$name])) { |
||
609 | continue; |
||
610 | } |
||
611 | |||
612 | switch ($name) { |
||
613 | case 'phone' : |
||
614 | case 'mobile' : |
||
615 | $metadata[$name] = $this->faker()->phoneNumber; |
||
616 | break; |
||
617 | |||
618 | default : |
||
619 | switch ($type) { |
||
620 | case 'plaintext' : |
||
621 | case 'longtext' : |
||
622 | $metadata[$name] = $this->faker()->text($this->faker()->numberBetween(500, 1000)); |
||
623 | break; |
||
624 | |||
625 | case 'text' : |
||
626 | $metadata[$name] = $this->faker()->sentence; |
||
627 | break; |
||
628 | |||
629 | case 'tags' : |
||
630 | $metadata[$name] = $this->faker()->words(10); |
||
631 | break; |
||
632 | |||
633 | case 'url' : |
||
634 | $metadata[$name] = $this->faker()->url; |
||
635 | break; |
||
636 | |||
637 | case 'email' : |
||
638 | $metadata[$name] = $this->faker()->email; |
||
639 | break; |
||
640 | |||
641 | case 'number' : |
||
642 | $metadata[$name] = $this->faker()->randomNumber(); |
||
643 | break; |
||
644 | |||
645 | case 'date' : |
||
646 | $metadata[$name] = $this->faker()->unixTime; |
||
647 | break; |
||
648 | |||
649 | case 'password' : |
||
650 | $metadata[$name] = generate_random_cleartext_password(); |
||
651 | break; |
||
652 | |||
653 | case 'location' : |
||
654 | $metadata[$name] = $this->faker()->address; |
||
655 | $metadata['geo:lat'] = $this->faker()->latitude; |
||
656 | $metadata['geo:long'] = $this->faker()->longitude; |
||
657 | break; |
||
658 | |||
659 | default : |
||
660 | $metadata[$name] = ''; |
||
661 | break; |
||
662 | } |
||
663 | |||
664 | break; |
||
665 | } |
||
666 | } |
||
667 | |||
668 | 358 | foreach ($metadata as $key => $value) { |
|
669 | 358 | if (array_key_exists($key, $fields) && $entity instanceof ElggUser) { |
|
670 | $entity->deleteAnnotations("profile:$key"); |
||
671 | $value = (array) $value; |
||
672 | foreach ($value as $val) { |
||
673 | $entity->annotate("profile:$key", $val, $this->getRandomAccessId($entity), $entity->guid); |
||
674 | } |
||
675 | } else { |
||
676 | 358 | $entity->$key = $value; |
|
677 | } |
||
678 | } |
||
679 | |||
680 | 358 | return $entity; |
|
681 | } |
||
682 | |||
683 | /** |
||
684 | * Create an icon for an entity |
||
685 | * |
||
686 | * @param ElggEntity $entity Entity |
||
687 | * |
||
688 | * @return bool |
||
689 | */ |
||
690 | public function createIcon(ElggEntity $entity) { |
||
691 | |||
692 | $icon_location = $this->faker()->image(); |
||
693 | if (empty($icon_location)) { |
||
694 | return false; |
||
695 | } |
||
696 | |||
697 | $result = $entity->saveIconFromLocalFile($icon_location); |
||
698 | |||
699 | if ($result && $entity instanceof ElggUser) { |
||
700 | elgg_create_river_item([ |
||
701 | 'view' => 'river/user/default/profileiconupdate', |
||
702 | 'action_type' => 'update', |
||
703 | 'subject_guid' => $entity->guid, |
||
704 | 'object_guid' => $entity->guid, |
||
705 | ]); |
||
706 | } |
||
707 | |||
708 | return $result; |
||
709 | } |
||
710 | |||
711 | /** |
||
712 | * Create comments/replies |
||
713 | * |
||
714 | * @param ElggEntity $entity Entity to comment on |
||
715 | * @param int $limit Number of comments to create |
||
716 | * |
||
717 | * @return int Number of generated comments |
||
718 | */ |
||
719 | public function createComments(ElggEntity $entity, $limit = null) { |
||
746 | |||
747 | } |
||
748 | |||
749 | /** |
||
750 | * Create likes |
||
751 | * |
||
752 | * @param ElggEntity $entity Entity to like |
||
753 | * @param int $limit Number of likes to create |
||
754 | * |
||
755 | * @return int |
||
756 | */ |
||
757 | public function createLikes(ElggEntity $entity, $limit = null) { |
||
776 | } |
||
777 | |||
778 | /** |
||
779 | * Log a message |
||
780 | * |
||
781 | * @param string $msg Message to log |
||
782 | * @param string $level Message level |
||
783 | * Note that 'ERROR' will terminate further code execution |
||
784 | * |
||
785 | * @return void |
||
786 | */ |
||
787 | 358 | public function log($msg, $level = 'NOTICE') { |
|
789 | 358 | } |
|
790 | |||
791 | } |