Test Failed
Push — master ( 952d74...c89423 )
by Jeroen
04:10 queued 02:14
created
engine/classes/Elgg/Database/Seeds/Seed.php 2 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
 	 * @param array $attributes Object entity attributes
247 247
 	 * @param array $metadata   Object entity metadata
248 248
 	 *
249
-	 * @return ElggObject|false
249
+	 * @return string|null
250 250
 	 */
251 251
 	public function createObject(array $attributes = [], array $metadata = []) {
252 252
 
@@ -353,7 +353,7 @@  discard block
 block discarded – undo
353 353
 	 *
354 354
 	 * @param int[] $exclude GUIDs to exclude
355 355
 	 *
356
-	 * @return ElggUser|false
356
+	 * @return integer
357 357
 	 */
358 358
 	public function getRandomUser(array $exclude = []) {
359 359
 
Please login to merge, or discard this patch.
Indentation   +687 added lines, -687 removed lines patch added patch discarded remove patch
@@ -17,699 +17,699 @@
 block discarded – undo
17 17
  */
18 18
 abstract class Seed {
19 19
 
20
-	/**
21
-	 * @var int Max number of items to be created by the seed
22
-	 */
23
-	protected $limit = 20;
24
-
25
-	/**
26
-	 * @var \Faker\Generator
27
-	 */
28
-	protected $faker;
29
-
30
-	/**
31
-	 * Seed constructor.
32
-	 *
33
-	 * @param string $locale Locale
34
-	 */
35
-	public function __construct($locale = 'en_US') {
36
-		$this->faker = Factory::create($locale);
37
-	}
38
-
39
-	/**
40
-	 * Populate database
41
-	 * @return mixed
42
-	 */
43
-	abstract function seed();
44
-
45
-	/**
46
-	 * Removed seeded rows from database
47
-	 * @return mixed
48
-	 */
49
-	abstract function unseed();
50
-
51
-	/**
52
-	 * Get site domain
53
-	 * @return string
54
-	 */
55
-	public function getDomain() {
56
-		return elgg_get_site_entity()->getDomain();
57
-	}
58
-
59
-	/**
60
-	 * Create a new faker user
61
-	 *
62
-	 * @param array $attributes User entity attributes
63
-	 * @param array $metadata   User entity metadata
64
-	 *
65
-	 * @return ElggUser|false
66
-	 */
67
-	public function createUser(array $attributes = [], array $metadata = []) {
68
-
69
-		$metadata['__faker'] = true;
70
-
71
-		if (empty($attributes['password'])) {
72
-			$attributes['password'] = generate_random_cleartext_password();
73
-		}
74
-
75
-		if (empty($attributes['username'])) {
76
-			$attributes['name'] = $this->faker->name;
77
-		}
78
-
79
-		if (empty($attributes['username'])) {
80
-			$attributes['username'] = $this->getRandomUsername($attributes['name']);
81
-		}
82
-
83
-		if (empty($attributes['email'])) {
84
-			$attributes['email'] = "{$attributes['username']}@{$this->getDomain()}";
85
-			if (!filter_var($attributes['email'], FILTER_VALIDATE_EMAIL)) {
86
-				// Travis tests use localhost as the domain name, which generates invalid email addresses
87
-				$attributes['email'] = "{$attributes['username']}@localhost.com";
88
-			}
89
-		}
90
-
91
-		$user = false;
92
-
93
-		try {
94
-			$guid = register_user($attributes['username'], $attributes['password'], $attributes['name'], $attributes['email']);
95
-			$user = get_entity($guid);
96
-			/* @var $user ElggUser */
97
-
98
-			elgg_set_user_validation_status($guid, $this->faker->boolean(), 'seeder');
99
-
100
-			$user->setNotificationSetting('email', false);
101
-			$user->setNotificationSetting('site', true);
102
-
103
-			$profile_fields = elgg_get_config('profile_fields');
104
-
105
-			$user = $this->populateMetadata($user, $profile_fields, $metadata);
106
-
107
-			$user->save();
108
-
109
-			$this->createIcon($user);
110
-			$this->createComments($user);
111
-			$this->createLikes($user);
112
-
113
-			$this->log("Created new user $user->name [guid: $user->guid]");
114
-
115
-			return $user;
116
-		} catch (Exception $e) {
117
-			if ($user && $user->guid) {
118
-				$user->delete();
119
-			}
120
-
121
-			$this->log($e->getMessage());
122
-
123
-			return false;
124
-		}
125
-
126
-	}
127
-
128
-	/**
129
-	 * Create a new faker group
130
-	 *
131
-	 * @param array $attributes Group entity attributes
132
-	 * @param array $metadata   Group entity metadata
133
-	 *
134
-	 * @return ElggGroup|false
135
-	 */
136
-	public function createGroup(array $attributes = [], array $metadata = []) {
137
-
138
-		$metadata['__faker'] = true;
139
-
140
-		if (empty($attributes['access_id'])) {
141
-			$attributes['access_id'] = ACCESS_PUBLIC;
142
-		}
20
+    /**
21
+     * @var int Max number of items to be created by the seed
22
+     */
23
+    protected $limit = 20;
24
+
25
+    /**
26
+     * @var \Faker\Generator
27
+     */
28
+    protected $faker;
29
+
30
+    /**
31
+     * Seed constructor.
32
+     *
33
+     * @param string $locale Locale
34
+     */
35
+    public function __construct($locale = 'en_US') {
36
+        $this->faker = Factory::create($locale);
37
+    }
38
+
39
+    /**
40
+     * Populate database
41
+     * @return mixed
42
+     */
43
+    abstract function seed();
44
+
45
+    /**
46
+     * Removed seeded rows from database
47
+     * @return mixed
48
+     */
49
+    abstract function unseed();
50
+
51
+    /**
52
+     * Get site domain
53
+     * @return string
54
+     */
55
+    public function getDomain() {
56
+        return elgg_get_site_entity()->getDomain();
57
+    }
58
+
59
+    /**
60
+     * Create a new faker user
61
+     *
62
+     * @param array $attributes User entity attributes
63
+     * @param array $metadata   User entity metadata
64
+     *
65
+     * @return ElggUser|false
66
+     */
67
+    public function createUser(array $attributes = [], array $metadata = []) {
68
+
69
+        $metadata['__faker'] = true;
70
+
71
+        if (empty($attributes['password'])) {
72
+            $attributes['password'] = generate_random_cleartext_password();
73
+        }
74
+
75
+        if (empty($attributes['username'])) {
76
+            $attributes['name'] = $this->faker->name;
77
+        }
78
+
79
+        if (empty($attributes['username'])) {
80
+            $attributes['username'] = $this->getRandomUsername($attributes['name']);
81
+        }
82
+
83
+        if (empty($attributes['email'])) {
84
+            $attributes['email'] = "{$attributes['username']}@{$this->getDomain()}";
85
+            if (!filter_var($attributes['email'], FILTER_VALIDATE_EMAIL)) {
86
+                // Travis tests use localhost as the domain name, which generates invalid email addresses
87
+                $attributes['email'] = "{$attributes['username']}@localhost.com";
88
+            }
89
+        }
90
+
91
+        $user = false;
92
+
93
+        try {
94
+            $guid = register_user($attributes['username'], $attributes['password'], $attributes['name'], $attributes['email']);
95
+            $user = get_entity($guid);
96
+            /* @var $user ElggUser */
97
+
98
+            elgg_set_user_validation_status($guid, $this->faker->boolean(), 'seeder');
99
+
100
+            $user->setNotificationSetting('email', false);
101
+            $user->setNotificationSetting('site', true);
102
+
103
+            $profile_fields = elgg_get_config('profile_fields');
104
+
105
+            $user = $this->populateMetadata($user, $profile_fields, $metadata);
106
+
107
+            $user->save();
108
+
109
+            $this->createIcon($user);
110
+            $this->createComments($user);
111
+            $this->createLikes($user);
112
+
113
+            $this->log("Created new user $user->name [guid: $user->guid]");
114
+
115
+            return $user;
116
+        } catch (Exception $e) {
117
+            if ($user && $user->guid) {
118
+                $user->delete();
119
+            }
120
+
121
+            $this->log($e->getMessage());
122
+
123
+            return false;
124
+        }
125
+
126
+    }
127
+
128
+    /**
129
+     * Create a new faker group
130
+     *
131
+     * @param array $attributes Group entity attributes
132
+     * @param array $metadata   Group entity metadata
133
+     *
134
+     * @return ElggGroup|false
135
+     */
136
+    public function createGroup(array $attributes = [], array $metadata = []) {
137
+
138
+        $metadata['__faker'] = true;
139
+
140
+        if (empty($attributes['access_id'])) {
141
+            $attributes['access_id'] = ACCESS_PUBLIC;
142
+        }
143 143
 
144
-		if (empty($metadata['content_access_mode'])) {
145
-			$metadata['content_access_mode'] = ElggGroup::CONTENT_ACCESS_MODE_UNRESTRICTED;
146
-		}
147
-
148
-		if (empty($metadata['membership'])) {
149
-			$metadata['membership'] = ACCESS_PUBLIC;
150
-		}
151
-
152
-		if (empty($attributes['name'])) {
153
-			$attributes['name'] = $this->faker->sentence();
154
-		}
144
+        if (empty($metadata['content_access_mode'])) {
145
+            $metadata['content_access_mode'] = ElggGroup::CONTENT_ACCESS_MODE_UNRESTRICTED;
146
+        }
147
+
148
+        if (empty($metadata['membership'])) {
149
+            $metadata['membership'] = ACCESS_PUBLIC;
150
+        }
151
+
152
+        if (empty($attributes['name'])) {
153
+            $attributes['name'] = $this->faker->sentence();
154
+        }
155 155
 
156
-		if (empty($attributes['description'])) {
157
-			$attributes['description'] = $this->faker->text($this->faker->numberBetween(500, 1000));
158
-		}
156
+        if (empty($attributes['description'])) {
157
+            $attributes['description'] = $this->faker->text($this->faker->numberBetween(500, 1000));
158
+        }
159 159
 
160
-		if (empty($attributes['owner_guid'])) {
161
-			$user = $this->getRandomUser();
162
-			if (!$user) {
163
-				$user = $this->createUser();
164
-			}
160
+        if (empty($attributes['owner_guid'])) {
161
+            $user = $this->getRandomUser();
162
+            if (!$user) {
163
+                $user = $this->createUser();
164
+            }
165 165
 
166
-			$attributes['owner_guid'] = $user->guid;
167
-		}
166
+            $attributes['owner_guid'] = $user->guid;
167
+        }
168 168
 
169
-		if (empty($attributes['container_guid'])) {
170
-			$attributes['container_guid'] = $attributes['owner_guid'];
171
-		}
169
+        if (empty($attributes['container_guid'])) {
170
+            $attributes['container_guid'] = $attributes['owner_guid'];
171
+        }
172 172
 
173
-		$owner = get_entity($attributes['owner_guid']);
174
-		if (!$owner) {
175
-			return false;
176
-		}
173
+        $owner = get_entity($attributes['owner_guid']);
174
+        if (!$owner) {
175
+            return false;
176
+        }
177 177
 
178
-		$container = get_entity($attributes['container_guid']);
179
-		if (!$container) {
180
-			return false;
181
-		}
178
+        $container = get_entity($attributes['container_guid']);
179
+        if (!$container) {
180
+            return false;
181
+        }
182 182
 
183
-		$tool_options = elgg_get_config('group_tool_options');
184
-		if ($tool_options) {
185
-			foreach ($tool_options as $group_option) {
186
-				$option_toggle_name = $group_option->name . "_enable";
187
-				$option_default = $group_option->default_on ? 'yes' : 'no';
188
-				$metadata[$option_toggle_name] = $option_default;
189
-			}
190
-		}
191
-
192
-		if ($this->faker->boolean(20)) {
193
-			$metadata['featured_group'] = 'yes';
194
-		}
195
-
196
-		$group = false;
197
-
198
-		try {
199
-			$group = new ElggGroup();
200
-			foreach ($attributes as $name => $value) {
201
-				$group->$name = $value;
202
-			}
203
-
204
-			$group = $this->populateMetadata($group, elgg_get_config('group'), $metadata);
205
-
206
-			$group->save();
207
-
208
-			if ($group->access_id == ACCESS_PRIVATE) {
209
-				$group->access_id = $group->group_acl;
210
-				$group->save();
211
-			}
212
-
213
-			$group->join(get_entity($attributes['owner_guid']));
214
-
215
-			$this->createIcon($group);
216
-
217
-			$this->createComments($group);
218
-			$this->createLikes($group);
219
-
220
-			elgg_create_river_item([
221
-				'view' => 'river/group/create',
222
-				'action_type' => 'create',
223
-				'subject_guid' => $owner->guid,
224
-				'object_guid' => $group->guid,
225
-				'target_guid' => $container->guid,
226
-			]);
227
-
228
-			$this->log("Created new group $group->name [guid: $group->guid]");
229
-
230
-			return $group;
231
-		} catch (Exception $e) {
232
-			if ($group && $group->guid) {
233
-				$group->delete();
234
-			}
235
-
236
-			$this->log($e->getMessage());
237
-
238
-			return false;
239
-		}
240
-
241
-	}
242
-
243
-	/**
244
-	 * Create a new faker object
245
-	 *
246
-	 * @param array $attributes Object entity attributes
247
-	 * @param array $metadata   Object entity metadata
248
-	 *
249
-	 * @return ElggObject|false
250
-	 */
251
-	public function createObject(array $attributes = [], array $metadata = []) {
252
-
253
-		$metadata['__faker'] = true;
254
-
255
-		if (empty($attributes['title'])) {
256
-			$attributes['title'] = $this->faker->sentence();
257
-		}
258
-
259
-		if (empty($attributes['description'])) {
260
-			$attributes['description'] = $this->faker->text($this->faker->numberBetween(500, 1000));
261
-		}
262
-
263
-		if (empty($attributes['container_guid'])) {
264
-			if ($this->faker->boolean()) {
265
-				$container = $this->getRandomGroup();
266
-			} else {
267
-				$container = $this->getRandomUser();
268
-			}
269
-
270
-			$attributes['container_guid'] = $container->guid;
271
-		}
272
-
273
-		if (empty($attributes['subtype'])) {
274
-			$attributes['subtype'] = strtolower($this->faker->word);
275
-		}
276
-
277
-		if (empty($metadata['tags'])) {
278
-			$metadata['tags'] = $this->faker->words(10);
279
-		}
280
-
281
-		if (empty($attributes['owner_guid'])) {
282
-			if ($container instanceof ElggGroup) {
283
-				$members = elgg_get_entities_from_relationship([
284
-					'types' => 'user',
285
-					'relationship' => 'member',
286
-					'relationship_guid' => $container->guid,
287
-					'inverse_relationship' => true,
288
-					'limit' => 0,
289
-					'metadata_names' => '__faker',
290
-					'order_by' => 'RAND()',
291
-				]);
292
-				$owner = array_shift($members);
293
-			} else {
294
-				$owner = $container;
295
-			}
296
-
297
-			$attributes['owner_guid'] = $owner->guid;
298
-		}
299
-
300
-		$owner = get_entity($attributes['owner_guid']);
301
-		if (!$owner) {
302
-			return false;
303
-		}
304
-
305
-		$container = get_entity($attributes['container_guid']);
306
-		if (!$container) {
307
-			return false;
308
-		}
309
-
310
-		if (empty($attributes['access_id'])) {
311
-			$attributes['access_id'] = $this->getRandomAccessId($owner, $container);
312
-		}
313
-
314
-		$object = false;
315
-
316
-		try {
317
-			$class = get_subtype_class('object', $attributes['subtype']);
318
-			if ($class && class_exists($class)) {
319
-				$object = new $class();
320
-			} else {
321
-				$object = new ElggObject();
322
-			}
323
-			foreach ($attributes as $name => $value) {
324
-				$object->$name = $value;
325
-			}
326
-
327
-			$object = $this->populateMetadata($object, [], $metadata);
328
-
329
-			$object->save();
330
-
331
-			$this->createComments($object);
332
-			$this->createLikes($object);
333
-
334
-			$type_str = elgg_echo("item:object:{$object->getSubtype()}");
335
-
336
-			$this->log("Created new item in $type_str $object->title [guid: $object->guid]");
337
-
338
-			return $object;
339
-		} catch (Exception $e) {
340
-			if ($object && $object->guid) {
341
-				$object->delete();
342
-			}
343
-
344
-			$this->log($e->getMessage());
345
-
346
-			return false;
347
-		}
348
-
349
-	}
350
-
351
-	/**
352
-	 * Returns random fake user
353
-	 *
354
-	 * @param int[] $exclude GUIDs to exclude
355
-	 *
356
-	 * @return ElggUser|false
357
-	 */
358
-	public function getRandomUser(array $exclude = []) {
359
-
360
-		$exclude[] = 0;
361
-		$exclude_in = implode(',', array_map(function ($e) {
362
-			return (int) $e;
363
-		}, $exclude));
364
-
365
-		$users = elgg_get_entities_from_metadata([
366
-			'types' => 'user',
367
-			'metadata_names' => ['__faker'],
368
-			'limit' => 1,
369
-			'wheres' => [
370
-				"e.guid NOT IN ($exclude_in)",
371
-			],
372
-			'order_by' => 'RAND()',
373
-		]);
374
-
375
-		return $users ? $users[0] : false;
376
-	}
377
-
378
-	/**
379
-	 * Returns random fake group
380
-	 *
381
-	 * @param int[] $exclude GUIDs to exclude
382
-	 *
383
-	 * @return ElggGroup|false
384
-	 */
385
-	public function getRandomGroup(array $exclude = []) {
386
-
387
-		$exclude[] = 0;
388
-		$exclude_in = implode(',', array_map(function ($e) {
389
-			return (int) $e;
390
-		}, $exclude));
391
-
392
-		$groups = elgg_get_entities_from_metadata([
393
-			'types' => 'group',
394
-			'metadata_names' => ['__faker'],
395
-			'limit' => 1,
396
-			'wheres' => [
397
-				"e.guid NOT IN ($exclude_in)",
398
-			],
399
-			'order_by' => 'RAND()',
400
-		]);
401
-
402
-		return $groups ? $groups[0] : false;
403
-	}
404
-
405
-	/**
406
-	 * Get random access id
407
-	 *
408
-	 * @param ElggUser   $user      User
409
-	 * @param ElggEntity $container Container
410
-	 *
411
-	 * @return int
412
-	 */
413
-	public function getRandomAccessId(\ElggUser $user = null, ElggEntity $container = null) {
414
-
415
-		$params = [
416
-			'container_guid' => $container->guid,
417
-		];
418
-
419
-		$access_array = get_write_access_array($user->guid, null, null, $params);
420
-
421
-		$access_key = array_rand($access_array, 1);
422
-
423
-		return $access_array[$access_key];
424
-	}
425
-
426
-	/**
427
-	 * Generates a unique available and valid username
428
-	 *
429
-	 * @param string $base_name Display name, email or other prefix to use as basis
430
-	 *
431
-	 * @return string
432
-	 */
433
-	public function getRandomUsername($base_name = 'user') {
434
-
435
-		$available = false;
436
-
437
-		$base_name = iconv('UTF-8', 'ASCII//TRANSLIT', $base_name);
438
-		$blacklist = '/[\x{0080}-\x{009f}\x{00a0}\x{2000}-\x{200f}\x{2028}-\x{202f}\x{3000}\x{e000}-\x{f8ff}]/u';
439
-		$blacklist2 = [
440
-			' ',
441
-			'\'',
442
-			'/',
443
-			'\\',
444
-			'"',
445
-			'*',
446
-			'&',
447
-			'?',
448
-			'#',
449
-			'%',
450
-			'^',
451
-			'(',
452
-			')',
453
-			'{',
454
-			'}',
455
-			'[',
456
-			']',
457
-			'~',
458
-			'?',
459
-			'<',
460
-			'>',
461
-			';',
462
-			'|',
463
-			'¬',
464
-			'`',
465
-			'@',
466
-			'-',
467
-			'+',
468
-			'='
469
-		];
470
-
471
-		$base_name = preg_replace($blacklist, '', $base_name);
472
-		$base_name = str_replace($blacklist2, '.', $base_name);
473
-
474
-		$ia = elgg_set_ignore_access(true);
475
-
476
-		$ha = access_get_show_hidden_status();
477
-		access_show_hidden_entities(true);
478
-
479
-		$minlength = elgg_get_config('minusername') ? : 4;
480
-		if ($base_name) {
481
-			$fill = $minlength - strlen($base_name);
482
-		} else {
483
-			$fill = 8;
484
-		}
485
-
486
-		$separator = '.';
487
-
488
-		if ($fill > 0) {
489
-			$suffix = (new ElggCrypto())->getRandomString($fill);
490
-			$base_name = "$base_name$separator$suffix";
491
-		}
492
-
493
-		$iterator = 0;
494
-		while (!$available) {
495
-			if ($iterator > 0) {
496
-				$base_name = "$base_name$separator$iterator";
497
-			}
498
-			$user = get_user_by_username($base_name);
499
-			$available = !$user;
500
-			try {
501
-				if ($available) {
502
-					validate_username($base_name);
503
-				}
504
-			} catch (\Exception $e) {
505
-				if ($iterator >= 10) {
506
-					// too many failed attempts
507
-					$base_name = (new ElggCrypto())->getRandomString(8);
508
-				}
509
-			}
510
-
511
-			$iterator++;
512
-		}
513
-
514
-		access_show_hidden_entities($ha);
515
-		elgg_set_ignore_access($ia);
516
-
517
-		return strtolower($base_name);
518
-	}
519
-
520
-	/**
521
-	 * Set random metadata
522
-	 *
523
-	 * @param ElggEntity $entity   Entity
524
-	 * @param array      $fields   An array of profile fields in $name => $input_type format
525
-	 * @param array      $metadata Other metadata $name => $value pairs to set
526
-	 *
527
-	 * @return ElggEntity
528
-	 */
529
-	public function populateMetadata(ElggEntity $entity, array $fields = [], array $metadata = []) {
530
-
531
-		foreach ($fields as $name => $type) {
532
-			if (isset($metadata[$name])) {
533
-				continue;
534
-			}
535
-
536
-			switch ($name) {
537
-				case 'phone' :
538
-				case 'mobile' :
539
-					$metadata[$name] = $this->faker->phoneNumber;
540
-					break;
541
-
542
-				default :
543
-					switch ($type) {
544
-						case 'plaintext' :
545
-						case 'longtext' :
546
-							$metadata[$name] = $this->faker->text($this->faker->numberBetween(500, 1000));
547
-							break;
548
-
549
-						case 'text' :
550
-							$metadata[$name] = $this->faker->sentence;
551
-							break;
552
-
553
-						case 'tags' :
554
-							$metadata[$name] = $this->faker->words(10);
555
-							break;
556
-
557
-						case 'url' :
558
-							$metadata[$name] = $this->faker->url;
559
-
560
-						case 'email' :
561
-							$metadata[$name] = $this->faker->email;
562
-							break;
563
-
564
-						case 'number' :
565
-							$metadata[$name] = $this->faker->randomNumber();
566
-							break;
567
-
568
-						case 'date' :
569
-							$metadata[$name] = $this->faker->unixTime;
570
-							break;
571
-
572
-						case 'password' :
573
-							$metadata[$name] = generate_random_cleartext_password();
574
-							break;
575
-
576
-						case 'location' :
577
-							$metadata[$name] = $this->faker->address;
578
-							$metadata['geo:lat'] = $this->faker->latitude;
579
-							$metadata['geo:long'] = $this->faker->longitude;
580
-							break;
581
-
582
-						case 'email' :
583
-							$metadata[$name] = $this->faker->address;
584
-							$metadata['geo:lat'] = $this->faker->latitude;
585
-							$metadata['geo:long'] = $this->faker->longitude;
586
-							break;
587
-
588
-						default :
589
-							$metadata[$name] = '';
590
-							break;
591
-					}
592
-
593
-					break;
594
-			}
595
-		}
596
-
597
-		foreach ($metadata as $key => $value) {
598
-			$entity->$key = $value;
599
-		}
600
-
601
-		return $entity;
602
-	}
603
-
604
-	/**
605
-	 * Create an icon for an entity
606
-	 *
607
-	 * @param ElggEntity $entity Entity
608
-	 *
609
-	 * @return bool
610
-	 */
611
-	public function createIcon(ElggEntity $entity) {
612
-
613
-		$icon_url = $this->faker->imageURL();
614
-
615
-		$file_contents = file_get_contents($icon_url);
616
-
617
-		$tmp = new \ElggFile();
618
-		$tmp->owner_guid = $entity->guid;
619
-		$tmp->setFilename("tmp/icon_src.jpg");
620
-		$tmp->open('write');
621
-		$tmp->write($file_contents);
622
-		$tmp->close();
623
-
624
-		$result = $entity->saveIconFromElggFile($tmp);
625
-
626
-		$tmp->delete();
627
-
628
-		if ($result && $entity instanceof ElggUser) {
629
-			elgg_create_river_item([
630
-				'view' => 'river/user/default/profileiconupdate',
631
-				'action_type' => 'update',
632
-				'subject_guid' => $entity->guid,
633
-				'object_guid' => $entity->guid,
634
-			]);
635
-		}
636
-
637
-		return $result;
638
-	}
639
-
640
-	/**
641
-	 * Create comments/replies
642
-	 *
643
-	 * @param ElggEntity $entity Entity to comment on
644
-	 * @param int        $limit  Number of comments to create
645
-	 *
646
-	 * @return int Number of generated comments
647
-	 */
648
-	public function createComments(ElggEntity $entity, $limit = null) {
649
-
650
-		$success = 0;
651
-
652
-		if (!$limit) {
653
-			$limit = $this->faker->numberBetween(1, 20);
654
-		}
655
-
656
-		while ($success < $limit) {
657
-			$comment = new ElggObject();
658
-			$comment->subtype = $entity->getSubtype() == 'discussion' ? 'discussion_reply' : 'comment';
659
-			$comment->owner_guid = $this->getRandomUser()->guid ? : $entity->owner_guid;
660
-			$comment->container_guid = $entity->guid;
661
-			$comment->description = $this->faker->paragraph;
662
-
663
-			if ($comment->save()) {
664
-				$success++;
665
-			}
666
-		}
667
-
668
-		return $success;
669
-
670
-	}
671
-
672
-	/**
673
-	 * Create likes
674
-	 *
675
-	 * @param ElggEntity $entity Entity to like
676
-	 * @param int        $limit  Number of likes to create
677
-	 *
678
-	 * @return int
679
-	 */
680
-	public function createLikes(ElggEntity $entity, $limit = null) {
681
-
682
-		$success = 0;
683
-
684
-		if (!$limit) {
685
-			$limit = $this->faker->numberBetween(1, 20);
686
-		}
687
-
688
-		while ($success < $limit) {
689
-			if ($entity->annotate('likes', true, $entity->access_id, $this->getRandomUser()->guid)) {
690
-				$success++;
691
-			}
692
-		}
693
-
694
-		return $success;
695
-	}
696
-
697
-	/**
698
-	 * Log a message
699
-	 *
700
-	 * @param string $msg   Message to log
701
-	 * @param string $level Message level
702
-	 *                      Note that 'ERROR' will terminate further code execution
703
-	 *
704
-	 * @return void
705
-	 */
706
-	public function log($msg, $level = 'NOTICE') {
707
-
708
-		if (php_sapi_name() === 'cli') {
709
-			$handle = $level === 'ERROR' ? STDERR : STDOUT;
710
-			fwrite($handle, $msg . PHP_EOL);
711
-		} else {
712
-			elgg_log($msg, $level);
713
-		}
714
-	}
183
+        $tool_options = elgg_get_config('group_tool_options');
184
+        if ($tool_options) {
185
+            foreach ($tool_options as $group_option) {
186
+                $option_toggle_name = $group_option->name . "_enable";
187
+                $option_default = $group_option->default_on ? 'yes' : 'no';
188
+                $metadata[$option_toggle_name] = $option_default;
189
+            }
190
+        }
191
+
192
+        if ($this->faker->boolean(20)) {
193
+            $metadata['featured_group'] = 'yes';
194
+        }
195
+
196
+        $group = false;
197
+
198
+        try {
199
+            $group = new ElggGroup();
200
+            foreach ($attributes as $name => $value) {
201
+                $group->$name = $value;
202
+            }
203
+
204
+            $group = $this->populateMetadata($group, elgg_get_config('group'), $metadata);
205
+
206
+            $group->save();
207
+
208
+            if ($group->access_id == ACCESS_PRIVATE) {
209
+                $group->access_id = $group->group_acl;
210
+                $group->save();
211
+            }
212
+
213
+            $group->join(get_entity($attributes['owner_guid']));
214
+
215
+            $this->createIcon($group);
216
+
217
+            $this->createComments($group);
218
+            $this->createLikes($group);
219
+
220
+            elgg_create_river_item([
221
+                'view' => 'river/group/create',
222
+                'action_type' => 'create',
223
+                'subject_guid' => $owner->guid,
224
+                'object_guid' => $group->guid,
225
+                'target_guid' => $container->guid,
226
+            ]);
227
+
228
+            $this->log("Created new group $group->name [guid: $group->guid]");
229
+
230
+            return $group;
231
+        } catch (Exception $e) {
232
+            if ($group && $group->guid) {
233
+                $group->delete();
234
+            }
235
+
236
+            $this->log($e->getMessage());
237
+
238
+            return false;
239
+        }
240
+
241
+    }
242
+
243
+    /**
244
+     * Create a new faker object
245
+     *
246
+     * @param array $attributes Object entity attributes
247
+     * @param array $metadata   Object entity metadata
248
+     *
249
+     * @return ElggObject|false
250
+     */
251
+    public function createObject(array $attributes = [], array $metadata = []) {
252
+
253
+        $metadata['__faker'] = true;
254
+
255
+        if (empty($attributes['title'])) {
256
+            $attributes['title'] = $this->faker->sentence();
257
+        }
258
+
259
+        if (empty($attributes['description'])) {
260
+            $attributes['description'] = $this->faker->text($this->faker->numberBetween(500, 1000));
261
+        }
262
+
263
+        if (empty($attributes['container_guid'])) {
264
+            if ($this->faker->boolean()) {
265
+                $container = $this->getRandomGroup();
266
+            } else {
267
+                $container = $this->getRandomUser();
268
+            }
269
+
270
+            $attributes['container_guid'] = $container->guid;
271
+        }
272
+
273
+        if (empty($attributes['subtype'])) {
274
+            $attributes['subtype'] = strtolower($this->faker->word);
275
+        }
276
+
277
+        if (empty($metadata['tags'])) {
278
+            $metadata['tags'] = $this->faker->words(10);
279
+        }
280
+
281
+        if (empty($attributes['owner_guid'])) {
282
+            if ($container instanceof ElggGroup) {
283
+                $members = elgg_get_entities_from_relationship([
284
+                    'types' => 'user',
285
+                    'relationship' => 'member',
286
+                    'relationship_guid' => $container->guid,
287
+                    'inverse_relationship' => true,
288
+                    'limit' => 0,
289
+                    'metadata_names' => '__faker',
290
+                    'order_by' => 'RAND()',
291
+                ]);
292
+                $owner = array_shift($members);
293
+            } else {
294
+                $owner = $container;
295
+            }
296
+
297
+            $attributes['owner_guid'] = $owner->guid;
298
+        }
299
+
300
+        $owner = get_entity($attributes['owner_guid']);
301
+        if (!$owner) {
302
+            return false;
303
+        }
304
+
305
+        $container = get_entity($attributes['container_guid']);
306
+        if (!$container) {
307
+            return false;
308
+        }
309
+
310
+        if (empty($attributes['access_id'])) {
311
+            $attributes['access_id'] = $this->getRandomAccessId($owner, $container);
312
+        }
313
+
314
+        $object = false;
315
+
316
+        try {
317
+            $class = get_subtype_class('object', $attributes['subtype']);
318
+            if ($class && class_exists($class)) {
319
+                $object = new $class();
320
+            } else {
321
+                $object = new ElggObject();
322
+            }
323
+            foreach ($attributes as $name => $value) {
324
+                $object->$name = $value;
325
+            }
326
+
327
+            $object = $this->populateMetadata($object, [], $metadata);
328
+
329
+            $object->save();
330
+
331
+            $this->createComments($object);
332
+            $this->createLikes($object);
333
+
334
+            $type_str = elgg_echo("item:object:{$object->getSubtype()}");
335
+
336
+            $this->log("Created new item in $type_str $object->title [guid: $object->guid]");
337
+
338
+            return $object;
339
+        } catch (Exception $e) {
340
+            if ($object && $object->guid) {
341
+                $object->delete();
342
+            }
343
+
344
+            $this->log($e->getMessage());
345
+
346
+            return false;
347
+        }
348
+
349
+    }
350
+
351
+    /**
352
+     * Returns random fake user
353
+     *
354
+     * @param int[] $exclude GUIDs to exclude
355
+     *
356
+     * @return ElggUser|false
357
+     */
358
+    public function getRandomUser(array $exclude = []) {
359
+
360
+        $exclude[] = 0;
361
+        $exclude_in = implode(',', array_map(function ($e) {
362
+            return (int) $e;
363
+        }, $exclude));
364
+
365
+        $users = elgg_get_entities_from_metadata([
366
+            'types' => 'user',
367
+            'metadata_names' => ['__faker'],
368
+            'limit' => 1,
369
+            'wheres' => [
370
+                "e.guid NOT IN ($exclude_in)",
371
+            ],
372
+            'order_by' => 'RAND()',
373
+        ]);
374
+
375
+        return $users ? $users[0] : false;
376
+    }
377
+
378
+    /**
379
+     * Returns random fake group
380
+     *
381
+     * @param int[] $exclude GUIDs to exclude
382
+     *
383
+     * @return ElggGroup|false
384
+     */
385
+    public function getRandomGroup(array $exclude = []) {
386
+
387
+        $exclude[] = 0;
388
+        $exclude_in = implode(',', array_map(function ($e) {
389
+            return (int) $e;
390
+        }, $exclude));
391
+
392
+        $groups = elgg_get_entities_from_metadata([
393
+            'types' => 'group',
394
+            'metadata_names' => ['__faker'],
395
+            'limit' => 1,
396
+            'wheres' => [
397
+                "e.guid NOT IN ($exclude_in)",
398
+            ],
399
+            'order_by' => 'RAND()',
400
+        ]);
401
+
402
+        return $groups ? $groups[0] : false;
403
+    }
404
+
405
+    /**
406
+     * Get random access id
407
+     *
408
+     * @param ElggUser   $user      User
409
+     * @param ElggEntity $container Container
410
+     *
411
+     * @return int
412
+     */
413
+    public function getRandomAccessId(\ElggUser $user = null, ElggEntity $container = null) {
414
+
415
+        $params = [
416
+            'container_guid' => $container->guid,
417
+        ];
418
+
419
+        $access_array = get_write_access_array($user->guid, null, null, $params);
420
+
421
+        $access_key = array_rand($access_array, 1);
422
+
423
+        return $access_array[$access_key];
424
+    }
425
+
426
+    /**
427
+     * Generates a unique available and valid username
428
+     *
429
+     * @param string $base_name Display name, email or other prefix to use as basis
430
+     *
431
+     * @return string
432
+     */
433
+    public function getRandomUsername($base_name = 'user') {
434
+
435
+        $available = false;
436
+
437
+        $base_name = iconv('UTF-8', 'ASCII//TRANSLIT', $base_name);
438
+        $blacklist = '/[\x{0080}-\x{009f}\x{00a0}\x{2000}-\x{200f}\x{2028}-\x{202f}\x{3000}\x{e000}-\x{f8ff}]/u';
439
+        $blacklist2 = [
440
+            ' ',
441
+            '\'',
442
+            '/',
443
+            '\\',
444
+            '"',
445
+            '*',
446
+            '&',
447
+            '?',
448
+            '#',
449
+            '%',
450
+            '^',
451
+            '(',
452
+            ')',
453
+            '{',
454
+            '}',
455
+            '[',
456
+            ']',
457
+            '~',
458
+            '?',
459
+            '<',
460
+            '>',
461
+            ';',
462
+            '|',
463
+            '¬',
464
+            '`',
465
+            '@',
466
+            '-',
467
+            '+',
468
+            '='
469
+        ];
470
+
471
+        $base_name = preg_replace($blacklist, '', $base_name);
472
+        $base_name = str_replace($blacklist2, '.', $base_name);
473
+
474
+        $ia = elgg_set_ignore_access(true);
475
+
476
+        $ha = access_get_show_hidden_status();
477
+        access_show_hidden_entities(true);
478
+
479
+        $minlength = elgg_get_config('minusername') ? : 4;
480
+        if ($base_name) {
481
+            $fill = $minlength - strlen($base_name);
482
+        } else {
483
+            $fill = 8;
484
+        }
485
+
486
+        $separator = '.';
487
+
488
+        if ($fill > 0) {
489
+            $suffix = (new ElggCrypto())->getRandomString($fill);
490
+            $base_name = "$base_name$separator$suffix";
491
+        }
492
+
493
+        $iterator = 0;
494
+        while (!$available) {
495
+            if ($iterator > 0) {
496
+                $base_name = "$base_name$separator$iterator";
497
+            }
498
+            $user = get_user_by_username($base_name);
499
+            $available = !$user;
500
+            try {
501
+                if ($available) {
502
+                    validate_username($base_name);
503
+                }
504
+            } catch (\Exception $e) {
505
+                if ($iterator >= 10) {
506
+                    // too many failed attempts
507
+                    $base_name = (new ElggCrypto())->getRandomString(8);
508
+                }
509
+            }
510
+
511
+            $iterator++;
512
+        }
513
+
514
+        access_show_hidden_entities($ha);
515
+        elgg_set_ignore_access($ia);
516
+
517
+        return strtolower($base_name);
518
+    }
519
+
520
+    /**
521
+     * Set random metadata
522
+     *
523
+     * @param ElggEntity $entity   Entity
524
+     * @param array      $fields   An array of profile fields in $name => $input_type format
525
+     * @param array      $metadata Other metadata $name => $value pairs to set
526
+     *
527
+     * @return ElggEntity
528
+     */
529
+    public function populateMetadata(ElggEntity $entity, array $fields = [], array $metadata = []) {
530
+
531
+        foreach ($fields as $name => $type) {
532
+            if (isset($metadata[$name])) {
533
+                continue;
534
+            }
535
+
536
+            switch ($name) {
537
+                case 'phone' :
538
+                case 'mobile' :
539
+                    $metadata[$name] = $this->faker->phoneNumber;
540
+                    break;
541
+
542
+                default :
543
+                    switch ($type) {
544
+                        case 'plaintext' :
545
+                        case 'longtext' :
546
+                            $metadata[$name] = $this->faker->text($this->faker->numberBetween(500, 1000));
547
+                            break;
548
+
549
+                        case 'text' :
550
+                            $metadata[$name] = $this->faker->sentence;
551
+                            break;
552
+
553
+                        case 'tags' :
554
+                            $metadata[$name] = $this->faker->words(10);
555
+                            break;
556
+
557
+                        case 'url' :
558
+                            $metadata[$name] = $this->faker->url;
559
+
560
+                        case 'email' :
561
+                            $metadata[$name] = $this->faker->email;
562
+                            break;
563
+
564
+                        case 'number' :
565
+                            $metadata[$name] = $this->faker->randomNumber();
566
+                            break;
567
+
568
+                        case 'date' :
569
+                            $metadata[$name] = $this->faker->unixTime;
570
+                            break;
571
+
572
+                        case 'password' :
573
+                            $metadata[$name] = generate_random_cleartext_password();
574
+                            break;
575
+
576
+                        case 'location' :
577
+                            $metadata[$name] = $this->faker->address;
578
+                            $metadata['geo:lat'] = $this->faker->latitude;
579
+                            $metadata['geo:long'] = $this->faker->longitude;
580
+                            break;
581
+
582
+                        case 'email' :
583
+                            $metadata[$name] = $this->faker->address;
584
+                            $metadata['geo:lat'] = $this->faker->latitude;
585
+                            $metadata['geo:long'] = $this->faker->longitude;
586
+                            break;
587
+
588
+                        default :
589
+                            $metadata[$name] = '';
590
+                            break;
591
+                    }
592
+
593
+                    break;
594
+            }
595
+        }
596
+
597
+        foreach ($metadata as $key => $value) {
598
+            $entity->$key = $value;
599
+        }
600
+
601
+        return $entity;
602
+    }
603
+
604
+    /**
605
+     * Create an icon for an entity
606
+     *
607
+     * @param ElggEntity $entity Entity
608
+     *
609
+     * @return bool
610
+     */
611
+    public function createIcon(ElggEntity $entity) {
612
+
613
+        $icon_url = $this->faker->imageURL();
614
+
615
+        $file_contents = file_get_contents($icon_url);
616
+
617
+        $tmp = new \ElggFile();
618
+        $tmp->owner_guid = $entity->guid;
619
+        $tmp->setFilename("tmp/icon_src.jpg");
620
+        $tmp->open('write');
621
+        $tmp->write($file_contents);
622
+        $tmp->close();
623
+
624
+        $result = $entity->saveIconFromElggFile($tmp);
625
+
626
+        $tmp->delete();
627
+
628
+        if ($result && $entity instanceof ElggUser) {
629
+            elgg_create_river_item([
630
+                'view' => 'river/user/default/profileiconupdate',
631
+                'action_type' => 'update',
632
+                'subject_guid' => $entity->guid,
633
+                'object_guid' => $entity->guid,
634
+            ]);
635
+        }
636
+
637
+        return $result;
638
+    }
639
+
640
+    /**
641
+     * Create comments/replies
642
+     *
643
+     * @param ElggEntity $entity Entity to comment on
644
+     * @param int        $limit  Number of comments to create
645
+     *
646
+     * @return int Number of generated comments
647
+     */
648
+    public function createComments(ElggEntity $entity, $limit = null) {
649
+
650
+        $success = 0;
651
+
652
+        if (!$limit) {
653
+            $limit = $this->faker->numberBetween(1, 20);
654
+        }
655
+
656
+        while ($success < $limit) {
657
+            $comment = new ElggObject();
658
+            $comment->subtype = $entity->getSubtype() == 'discussion' ? 'discussion_reply' : 'comment';
659
+            $comment->owner_guid = $this->getRandomUser()->guid ? : $entity->owner_guid;
660
+            $comment->container_guid = $entity->guid;
661
+            $comment->description = $this->faker->paragraph;
662
+
663
+            if ($comment->save()) {
664
+                $success++;
665
+            }
666
+        }
667
+
668
+        return $success;
669
+
670
+    }
671
+
672
+    /**
673
+     * Create likes
674
+     *
675
+     * @param ElggEntity $entity Entity to like
676
+     * @param int        $limit  Number of likes to create
677
+     *
678
+     * @return int
679
+     */
680
+    public function createLikes(ElggEntity $entity, $limit = null) {
681
+
682
+        $success = 0;
683
+
684
+        if (!$limit) {
685
+            $limit = $this->faker->numberBetween(1, 20);
686
+        }
687
+
688
+        while ($success < $limit) {
689
+            if ($entity->annotate('likes', true, $entity->access_id, $this->getRandomUser()->guid)) {
690
+                $success++;
691
+            }
692
+        }
693
+
694
+        return $success;
695
+    }
696
+
697
+    /**
698
+     * Log a message
699
+     *
700
+     * @param string $msg   Message to log
701
+     * @param string $level Message level
702
+     *                      Note that 'ERROR' will terminate further code execution
703
+     *
704
+     * @return void
705
+     */
706
+    public function log($msg, $level = 'NOTICE') {
707
+
708
+        if (php_sapi_name() === 'cli') {
709
+            $handle = $level === 'ERROR' ? STDERR : STDOUT;
710
+            fwrite($handle, $msg . PHP_EOL);
711
+        } else {
712
+            elgg_log($msg, $level);
713
+        }
714
+    }
715 715
 }
Please login to merge, or discard this patch.