Elgg  Version 3.0
Seeding.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Database\Seeds;
4 
9 use ElggEntity;
10 use ElggGroup;
11 use ElggObject;
12 use ElggUser;
13 use Exception;
14 use Faker\Factory;
17 
24 trait Seeding {
25 
29  protected $limit = 20;
30 
34  protected $faker;
35 
43  public function faker($locale = 'en_US') {
44  if (!isset($this->faker)) {
45  $this->faker = Factory::create($locale);
46  }
47 
48  $this->faker->addProvider(new LocalImage($this->faker));
49 
50  return $this->faker;
51  }
52 
57  public function getDomain() {
58  return elgg_get_site_entity()->getDomain();
59  }
60 
65  public function getEmailDomain() {
66  $email = elgg_get_site_entity()->email;
67  if (!$email) {
68  $email = "noreply@{$this->getDomain()}";
69  }
70 
71  list(, $domain) = explode('@', $email);
72 
73  if (sizeof(explode('.', $domain)) <= 1) {
74  $domain = 'example.net';
75  }
76 
77  return $domain;
78  }
79 
84  public function getRandomSubtype() {
85  return substr(sha1(microtime() . rand()), 0, 25);
86  }
87 
97  public function createUser(array $attributes = [], array $metadata = [], array $options = []) {
98 
99  $create = function () use ($attributes, $metadata, $options) {
100  $metadata['__faker'] = true;
101 
102  if (empty($metadata['password'])) {
104  }
105 
106  if (empty($metadata['name'])) {
107  $metadata['name'] = $this->faker()->name;
108  }
109 
110  if (empty($metadata['username'])) {
111  $metadata['username'] = $this->getRandomUsername($metadata['name']);
112  }
113 
114  if (empty($metadata['email'])) {
115  $metadata['email'] = $this->getRandomEmail($metadata['username']);
116  }
117 
118  if (empty($attributes['subtype'])) {
119  $attributes['subtype'] = 'user';
120  }
121 
122  $user = false;
123 
124  try {
125  $guid = register_user($metadata['username'], $metadata['password'], $metadata['name'], $metadata['email'], false, $attributes['subtype']);
126 
127  $user = get_user($guid);
128  if (!$user) {
129  throw new Exception("Unable to create new user with attributes: " . print_r($attributes, true));
130  }
131 
132  if (isset($metadata['admin'])) {
133  if ($metadata['admin']) {
134  $user->makeAdmin();
135  } else {
136  $user->removeAdmin();
137  }
138  }
139 
140  if (isset($metadata['banned'])) {
141  if ($metadata['banned']) {
142  $user->ban('Banned by seeder');
143  } else {
144  $user->unban();
145  }
146  }
147 
148  unset($metadata['username']);
149  unset($metadata['password']);
150  unset($metadata['name']);
151  unset($metadata['email']);
152  unset($metadata['banned']);
153  unset($metadata['admin']);
154 
155  $user->setValidationStatus($this->faker()->boolean(), 'seeder');
156 
157  $user->setNotificationSetting('email', false);
158  $user->setNotificationSetting('site', true);
159 
160  $profile_fields = elgg_extract('profile_fields', $options, []);
161  $user = $this->populateMetadata($user, $profile_fields, $metadata);
162 
163  $user->save();
164 
165  $this->log("Created new user {$user->getDisplayName()} [guid: {$user->guid}]");
166 
167  return $user;
168  } catch (\RegistrationException $e) {
169  if ($user && $user->guid) {
170  $user->delete();
171  }
172 
173  $attr_log = print_r($attributes, true);
174  $this->log("User creation failed with message {$e->getMessage()} [attributes: $attr_log]");
175 
176  return false;
177  }
178  };
179 
180  $ia = _elgg_services()->session->setIgnoreAccess(true);
181 
182  $user = false;
183  while (!$user instanceof \ElggUser) {
184  try {
185  $user = $create();
186  } catch (Exception $ex) {
187  // try again
188  }
189  }
190 
191  _elgg_services()->session->setIgnoreAccess($ia);
192 
193  return $user;
194 
195  }
196 
206  public function createGroup(array $attributes = [], array $metadata = [], array $options = []) {
207 
208  $create = function () use ($attributes, $metadata, $options) {
209 
210  $properties = array_merge($metadata, $attributes);
211 
212  $properties['__faker'] = true;
213 
214  if (!isset($properties['access_id'])) {
215  $properties['access_id'] = ACCESS_PUBLIC;
216  }
217 
218  if (!isset($properties['content_access_mode'])) {
219  $properties['content_access_mode'] = ElggGroup::CONTENT_ACCESS_MODE_UNRESTRICTED;
220  }
221 
222  if (!isset($properties['membership'])) {
223  $properties['membership'] = ACCESS_PUBLIC;
224  }
225 
226  if (empty($properties['name'])) {
227  $properties['name'] = $this->faker()->sentence();
228  }
229 
230  if (empty($properties['description'])) {
231  $properties['description'] = $this->faker()->text($this->faker()->numberBetween(500, 1000));
232  }
233 
234  if (!isset($properties['owner_guid'])) {
235  $user = _elgg_services()->session->getLoggedInUser();
236  if (!$user) {
237  $user = $this->createUser();
238  }
239 
240  $properties['owner_guid'] = $user->guid;
241  }
242 
243  if (!isset($properties['container_guid'])) {
244  $properties['container_guid'] = $properties['owner_guid'];
245  }
246 
247  if (empty($properties['subtype'])) {
248  $properties['subtype'] = 'group';
249  }
250 
251  $owner = get_entity($properties['owner_guid']);
252  if (!$owner) {
253  return false;
254  }
255 
256  $container = get_entity($properties['container_guid']);
257  if (!$container) {
258  return false;
259  }
260 
261  $tool_options = elgg_extract('group_tools_options', $options, []);
262  /* @var $tool_options Collection|Tool[] */
263 
264  foreach ($tool_options as $group_option) {
265  $prop_name = $group_option->mapMetadataName();
266  $prop_value = $group_option->mapMetadataValue();
267  $properties[$prop_name] = $prop_value;
268  }
269 
270  if ($this->faker()->boolean(20)) {
271  $properties['featured_group'] = 'yes';
272  }
273 
274  $group = new ElggGroup();
275  foreach ($properties as $name => $value) {
276  $group->$name = $value;
277  }
278 
279  $profile_fields = elgg_extract('profile_fields', $options, []);
280  $group = $this->populateMetadata($group, $profile_fields, $properties);
281 
282  $group->save();
283 
284  if ($group->access_id === ACCESS_PRIVATE) {
285  $acl = $group->getOwnedAccessCollection('group_acl');
286  if ($acl instanceof \ElggAccessCollection) {
287  $group->access_id = $acl->id;
288  $group->save();
289  }
290  }
291 
292  $group->join(get_entity($properties['owner_guid']));
293 
295  'view' => 'river/group/create',
296  'action_type' => 'create',
297  'subject_guid' => $owner->guid,
298  'object_guid' => $group->guid,
299  'target_guid' => $container->guid,
300  ]);
301 
302  $this->log("Created new group {$group->getDisplayName()} [guid: {$group->guid}]");
303 
304  return $group;
305  };
306 
307  $ia = _elgg_services()->session->setIgnoreAccess(true);
308 
309  $group = false;
310  while (!$group instanceof \ElggGroup) {
311  $group = $create();
312  }
313 
314  _elgg_services()->session->setIgnoreAccess($ia);
315 
316  return $group;
317  }
318 
328  public function createObject(array $attributes = [], array $metadata = [], array $options = []) {
329 
330  $create = function () use ($attributes, $metadata, $options) {
331 
332  $properties = array_merge($metadata, $attributes);
333 
334  $properties['__faker'] = true;
335 
336  if (empty($properties['title'])) {
337  $properties['title'] = $this->faker()->sentence();
338  }
339 
340  if (empty($properties['description'])) {
341  $properties['description'] = $this->faker()->text($this->faker()->numberBetween(500, 1000));
342  }
343 
344  if (empty($properties['subtype'])) {
345  $properties['subtype'] = $this->getRandomSubtype();
346  }
347 
348  if (empty($properties['tags'])) {
349  $properties['tags'] = $this->faker()->words(10);
350  }
351 
352  if (!isset($properties['container_guid'])) {
353  if (isset($properties['owner_guid'])) {
354  $properties['container_guid'] = $properties['owner_guid'];
355  } else {
356  $container = _elgg_services()->session->getLoggedInUser();
357  if (!$container) {
358  $container = $this->createUser();
359  }
360 
361  $properties['container_guid'] = $container->guid;
362  }
363  }
364 
365  $container = get_entity($properties['container_guid']);
366  if (!$container) {
367  return false;
368  }
369 
370  if (!isset($properties['owner_guid'])) {
371  $owner = $container;
372  $properties['owner_guid'] = $owner->guid;
373  }
374 
375  $owner = get_entity($properties['owner_guid']);
376  if (!$owner) {
377  return false;
378  }
379 
380  if (!isset($properties['access_id'])) {
381  $properties['access_id'] = ACCESS_PUBLIC;
382  }
383 
384  $class = elgg_get_entity_class('object', $properties['subtype']);
385  if ($class && class_exists($class)) {
386  $object = new $class();
387  } else {
388  $object = new ElggObject();
389  }
390 
391  foreach ($properties as $name => $value) {
392  $object->$name = $value;
393  }
394 
395  $profile_fields = elgg_extract('profile_fields', $options, []);
396  $object = $this->populateMetadata($object, $profile_fields, $properties);
397 
398  if (elgg_extract('save', $options, true)) {
399  $object->save();
400  }
401 
402  $type_str = elgg_echo("item:object:{$object->getSubtype()}");
403 
404  $this->log("Created new item in {$type_str} {$object->getDisplayName()} [guid: {$object->guid}]");
405 
406  return $object;
407  };
408 
409  $ia = _elgg_services()->session->setIgnoreAccess(true);
410 
411  $object = false;
412  while (!$object instanceof \ElggObject) {
413  $object = $create();
414  }
415 
416  _elgg_services()->session->setIgnoreAccess($ia);
417 
418  return $object;
419 
420  }
421 
430  public function createSite(array $attributes = [], array $metadata = []) {
431  // We don't want to create more than one site
432  return elgg_get_site_entity();
433  }
434 
442  public function getRandomUser(array $exclude = []) {
443 
444  $exclude[] = 0;
445 
446  $users = elgg_get_entities([
447  'types' => 'user',
448  'metadata_names' => ['__faker'],
449  'limit' => 1,
450  'wheres' => [
451  function(QueryBuilder $qb) use ($exclude) {
452  return $qb->compare('e.guid', 'NOT IN', $exclude, ELGG_VALUE_INTEGER);
453  }
454  ],
455  'order_by' => new OrderByClause('RAND()', null),
456  ]);
457 
458  return $users ? $users[0] : false;
459  }
460 
468  public function getRandomGroup(array $exclude = []) {
469 
470  $exclude[] = 0;
471 
472  $groups = elgg_get_entities([
473  'types' => 'group',
474  'metadata_names' => ['__faker'],
475  'limit' => 1,
476  'wheres' => [
477  function(QueryBuilder $qb) use ($exclude) {
478  return $qb->compare('e.guid', 'NOT IN', $exclude, ELGG_VALUE_INTEGER);
479  }
480  ],
481  'order_by' => new OrderByClause('RAND()', null),
482  ]);
483 
484  return $groups ? $groups[0] : false;
485  }
486 
495  public function getRandomAccessId(\ElggUser $user = null, ElggEntity $container = null) {
496 
497  $params = [
498  'container_guid' => $container ? $container->guid : null,
499  ];
500 
501  $access_array = get_write_access_array($user->guid, null, null, $params);
502 
503  $access_key = array_rand($access_array, 1);
504 
505  return $access_array[$access_key];
506  }
507 
515  public function getRandomUsername($name = null) {
516 
517  $make = function($name = null) {
518  if (!$name) {
519  return strtolower($this->faker()->firstName . '.' . $this->faker()->lastName);
520  }
521 
522  return implode('.', preg_split('/\W/', $name));
523  };
524 
525  $validate = function($username) {
526  try {
527  elgg()->accounts->assertValidUsername($username, true);
528  return true;
529  } catch (\RegistrationException $e) {
530  return false;
531  }
532  };
533 
534  $username = $make($name);
535  while (!$validate($username)) {
536  $username = $make();
537  }
538 
539  return $username;
540  }
541 
548  public function getRandomEmail($base = null) {
549 
550  $make = function($base = null) {
551  $base = $this->getRandomUsername($base);
552  return $base . '@' . $this->getEmailDomain();
553  };
554 
555  $validate = function($email) {
556  try {
557  elgg()->accounts->assertValidEmail($email, true);
558  return true;
559  } catch (\RegistrationException $e) {
560  return false;
561  }
562  };
563 
564  $email = $make($base);
565  while (!$validate($email)) {
566  $email = $make();
567  }
568 
569  return $email;
570  }
571 
581  public function populateMetadata(ElggEntity $entity, array $fields = [], array $metadata = []) {
582 
583  foreach ($fields as $name => $type) {
584  if (isset($metadata[$name])) {
585  continue;
586  }
587 
588  switch ($name) {
589  case 'phone' :
590  case 'mobile' :
591  $metadata[$name] = $this->faker()->phoneNumber;
592  break;
593 
594  default :
595  switch ($type) {
596  case 'plaintext' :
597  case 'longtext' :
598  $metadata[$name] = $this->faker()->text($this->faker()->numberBetween(500, 1000));
599  break;
600 
601  case 'text' :
602  $metadata[$name] = $this->faker()->sentence;
603  break;
604 
605  case 'tags' :
606  $metadata[$name] = $this->faker()->words(10);
607  break;
608 
609  case 'url' :
610  $metadata[$name] = $this->faker()->url;
611  break;
612 
613  case 'email' :
614  $metadata[$name] = $this->faker()->email;
615  break;
616 
617  case 'number' :
618  $metadata[$name] = $this->faker()->randomNumber();
619  break;
620 
621  case 'date' :
622  $metadata[$name] = $this->faker()->unixTime;
623  break;
624 
625  case 'password' :
627  break;
628 
629  case 'location' :
630  $metadata[$name] = $this->faker()->address;
631  $metadata['geo:lat'] = $this->faker()->latitude;
632  $metadata['geo:long'] = $this->faker()->longitude;
633  break;
634 
635  default :
636  $metadata[$name] = '';
637  break;
638  }
639 
640  break;
641  }
642  }
643 
644  foreach ($metadata as $key => $value) {
645  if (array_key_exists($key, $fields) && $entity instanceof ElggUser) {
646  $entity->deleteAnnotations("profile:$key");
647  $value = (array) $value;
648  foreach ($value as $val) {
649  $entity->annotate("profile:$key", $val, $this->getRandomAccessId($entity), $entity->guid);
650  }
651  } else {
652  $entity->$key = $value;
653  }
654  }
655 
656  return $entity;
657  }
658 
666  public function createIcon(ElggEntity $entity) {
667 
668  $icon_location = $this->faker()->image();
669  if (empty($icon_location)) {
670  return false;
671  }
672 
673  $result = $entity->saveIconFromLocalFile($icon_location);
674 
675  if ($result && $entity instanceof ElggUser) {
677  'view' => 'river/user/default/profileiconupdate',
678  'action_type' => 'update',
679  'subject_guid' => $entity->guid,
680  'object_guid' => $entity->guid,
681  ]);
682  }
683 
684  return $result;
685  }
686 
695  public function createComments(ElggEntity $entity, $limit = null) {
696 
697  $ia = _elgg_services()->session->setIgnoreAccess(true);
698 
699  $tries = 0;
700  $success = 0;
701 
702  if ($limit === null) {
703  $limit = $this->faker()->numberBetween(1, 20);
704  }
705 
706  while ($tries < $limit) {
707  $comment = new \ElggComment();
708  $comment->owner_guid = $this->getRandomUser()->guid ? : $entity->owner_guid;
709  $comment->container_guid = $entity->guid;
710  $comment->description = $this->faker()->paragraph;
711 
712  $tries++;
713  if ($comment->save()) {
714  $success++;
715  }
716  }
717 
718  _elgg_services()->session->setIgnoreAccess($ia);
719 
720  return $success;
721 
722  }
723 
732  public function createLikes(ElggEntity $entity, $limit = null) {
733 
734  $ia = _elgg_services()->session->setIgnoreAccess(true);
735 
736  $success = 0;
737 
738  if ($limit === null) {
739  $limit = $this->faker()->numberBetween(1, 20);
740  }
741 
742  while ($success < $limit) {
743  if ($entity->annotate('likes', true, $entity->access_id, $this->getRandomUser()->guid)) {
744  $success++;
745  }
746  }
747 
748  _elgg_services()->session->setIgnoreAccess($ia);
749 
750  return $success;
751  }
752 
762  public function log($msg, $level = LogLevel::NOTICE) {
763  elgg_log($msg, $level);
764  }
765 }
Provide images from a local folder for seeding.
Definition: LocalImage.php:10
if(!$item instanceof ElggRiverItem) $object
Definition: responses.php:23
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
log($msg, $level=LogLevel::NOTICE)
Log a message.
Definition: Seeding.php:762
$username
Definition: delete.php:23
getRandomUser(array $exclude=[])
Returns random fake user.
Definition: Seeding.php:442
$params
Saves global plugin settings.
Definition: save.php:13
get_user($guid)
Get a user object from a GUID.
Definition: users.php:40
getRandomSubtype()
Returns random unique subtype.
Definition: Seeding.php:84
populateMetadata(ElggEntity $entity, array $fields=[], array $metadata=[])
Set random metadata.
Definition: Seeding.php:581
deleteAnnotations($name=null)
Deletes all annotations on this object (annotations.entity_guid = $this->guid).
Definition: ElggEntity.php:711
get_write_access_array($user_guid=0, $ignored=0, $flush=false, array $input_params=[])
Returns an array of access permissions that the user is allowed to save content with.
Definition: access.php:218
const ELGG_VALUE_INTEGER
Value types.
Definition: constants.php:138
Database abstraction query builder.
createIcon(ElggEntity $entity)
Create an icon for an entity.
Definition: Seeding.php:666
$guid
Removes an admin notice.
$type
Definition: delete.php:21
$email
Definition: register.php:18
elgg_create_river_item(array $options=[])
Adds an item to the river.
Definition: river.php:33
$comment
Definition: save.php:43
elgg_echo($message_key, array $args=[], $language="")
Given a message key, returns an appropriately translated full-text string.
Definition: languages.php:21
createObject(array $attributes=[], array $metadata=[], array $options=[])
Create a new fake object.
Definition: Seeding.php:328
$options
Elgg admin footer.
Definition: footer.php:6
$metadata
Outputs object metadata $vars[&#39;metadata&#39;] Metadata/menu $vars[&#39;show_entity_menu&#39;] Show the entity m...
Definition: metadata.php:10
faker($locale= 'en_US')
Returns an instance of faker.
Definition: Seeding.php:43
getDomain()
Get site domain.
Definition: Seeding.php:57
$limit
Definition: userpicker.php:52
const ACCESS_PRIVATE
Definition: constants.php:12
$class
Definition: field.php:29
$entity
Definition: reset.php:8
$owner
Definition: crop.php:7
$container
Definition: delete.php:23
elgg_get_entities(array $options=[])
Fetches/counts entities or performs a calculation on their properties.
Definition: entities.php:545
const CONTENT_ACCESS_MODE_UNRESTRICTED
Definition: ElggGroup.php:14
createUser(array $attributes=[], array $metadata=[], array $options=[])
Create a new fake user.
Definition: Seeding.php:97
elgg_log($message, $level=\Psr\Log\LogLevel::NOTICE)
Log a message.
Definition: elgglib.php:786
elgg_get_entity_class($type, $subtype)
Procedural code for creating, loading, and modifying objects.
Definition: entities.php:16
$user
Definition: ban.php:7
compare($x, $comparison, $y=null, $type=null, $case_sensitive=null)
Build value comparison clause.
createComments(ElggEntity $entity, $limit=null)
Create comments/replies.
Definition: Seeding.php:695
elgg ElggUser
Definition: ElggUser.js:12
createGroup(array $attributes=[], array $metadata=[], array $options=[])
Create a new fake group.
Definition: Seeding.php:206
getRandomUsername($name=null)
Generates a unique available and valid username.
Definition: Seeding.php:515
$fields
Definition: save.php:28
register_user($username, $password, $name, $email, $allow_multiple_emails=false, $subtype=null)
Registers a user, returning false if the username already exists.
Definition: users.php:205
elgg_get_site_entity()
Get the current site entity.
Definition: entities.php:130
elgg_extract($key, $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:1131
createLikes(ElggEntity $entity, $limit=null)
Create likes.
Definition: Seeding.php:732
Extends QueryBuilder with ORDER BY clauses.
getRandomGroup(array $exclude=[])
Returns random fake group.
Definition: Seeding.php:468
if($container instanceof ElggGroup &&$container->guid!=elgg_get_page_owner_guid()) $key
Definition: summary.php:55
$value
Definition: debugging.php:7
generate_random_cleartext_password()
Generate a random 12 character clear text password.
Definition: users.php:146
createSite(array $attributes=[], array $metadata=[])
Create a new fake site.
Definition: Seeding.php:430
$domain
Definition: layout.php:32
getEmailDomain()
Get valid domain for emails.
Definition: Seeding.php:65
getRandomAccessId(\ElggUser $user=null, ElggEntity $container=null)
Get random access id.
Definition: Seeding.php:495
annotate($name, $value, $access_id=ACCESS_PRIVATE, $owner_guid=0, $value_type="")
Adds an annotation to an entity.
Definition: ElggEntity.php:834
_elgg_services()
Get the global service provider.
Definition: elgglib.php:1292
const ACCESS_PUBLIC
Definition: constants.php:14
getRandomEmail($base=null)
Generate a random valid email.
Definition: Seeding.php:548
$attributes
Definition: ajax_loader.php:13
elgg ElggEntity
Definition: ElggEntity.js:15
var elgg
Definition: elgglib.js:4
get_entity($guid)
Loads and returns an entity object from a guid.
Definition: entities.php:87
saveIconFromLocalFile($filename, $type= 'icon', array $coords=[])
Saves icons using a local file as the source.