Test Failed
Push — master ( 690440...5089f0 )
by Steve
09:47
created

Seed::createUser()   D

Complexity

Conditions 9
Paths 600

Size

Total Lines 60
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 32
nc 600
nop 2
dl 0
loc 60
rs 4.5454
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Elgg\Database\Seeds;
4
5
use ElggEntity;
6
use ElggGroup;
7
use ElggObject;
8
use ElggUser;
9
use Exception;
10
use Faker\Factory;
11
12
/**
13
 * Abstract seed
14
 *
15
 * Plugins should extend this class to create their own seeders,
16
 * add use 'seeds','database' plugin hook to add their seed to the sequence.
17
 */
18
abstract class Seed {
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();
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
44
45
	/**
46
	 * Removed seeded rows from database
47
	 * @return mixed
48
	 */
49
	abstract function unseed();
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
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);
0 ignored issues
show
Bug introduced by
It seems like $guid defined by register_user($attribute..., $attributes['email']) on line 94 can also be of type false or null; however, get_entity() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
96
			/* @var $user ElggUser */
97
98
			elgg_set_user_validation_status($guid, $this->faker->boolean(), 'seeder');
0 ignored issues
show
Bug introduced by
It seems like $guid defined by register_user($attribute..., $attributes['email']) on line 94 can also be of type false or null; however, elgg_set_user_validation_status() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
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
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
156 View Code Duplication
		if (empty($attributes['description'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
			$attributes['description'] = $this->faker->text($this->faker->numberBetween(500, 1000));
158
		}
159
160
		if (empty($attributes['owner_guid'])) {
161
			$user = $this->getRandomUser();
162
			if (!$user) {
163
				$user = $this->createUser();
164
			}
165
166
			$attributes['owner_guid'] = $user->guid;
167
		}
168
169
		if (empty($attributes['container_guid'])) {
170
			$attributes['container_guid'] = $attributes['owner_guid'];
171
		}
172
173
		$owner = get_entity($attributes['owner_guid']);
174
		if (!$owner) {
175
			return false;
176
		}
177
178
		$container = get_entity($attributes['container_guid']);
179
		if (!$container) {
180
			return false;
181
		}
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;
1 ignored issue
show
Documentation introduced by
The property group_acl does not exist on object<ElggEntity>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
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 View Code Duplication
		if (empty($attributes['description'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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,
0 ignored issues
show
Bug introduced by
The variable $container does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
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);
0 ignored issues
show
Documentation introduced by
$owner is of type object<ElggEntity>, but the function expects a null|object<ElggUser>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
312
		}
313
314
		$object = false;
315
316
		try {
317
			$class = get_subtype_class('object', $attributes['subtype']);
318
			if ($class && class_exists($class)) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $class of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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 View Code Duplication
	public function getRandomUser(array $exclude = []) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
	public function getRandomGroup(array $exclude = []) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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 View Code Duplication
						case 'location' :
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
577
							$metadata[$name] = $this->faker->address;
578
							$metadata['geo:lat'] = $this->faker->latitude;
579
							$metadata['geo:long'] = $this->faker->longitude;
580
							break;
581
582 View Code Duplication
						case 'email' :
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
		if ($result && $entity instanceof ElggUser) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $limit of type integer|null is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
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) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $limit of type integer|null is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
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
}
716