1 | <?php |
||||||||
2 | /** |
||||||||
3 | * |
||||||||
4 | */ |
||||||||
5 | |||||||||
6 | namespace Elgg\Database\Seeds; |
||||||||
7 | |||||||||
8 | use Elgg\Project\Paths; |
||||||||
9 | use ElggEntity; |
||||||||
10 | use ElggGroup; |
||||||||
11 | use ElggObject; |
||||||||
12 | use ElggUser; |
||||||||
13 | use Exception; |
||||||||
14 | use Faker\Factory; |
||||||||
15 | |||||||||
16 | /** |
||||||||
17 | * Seeding trait |
||||||||
18 | * Can be used to easily create new random users, groups and objects in the database |
||||||||
19 | * |
||||||||
20 | * @access private |
||||||||
21 | */ |
||||||||
22 | trait Seeding { |
||||||||
23 | |||||||||
24 | /** |
||||||||
25 | * @var int Max number of items to be created by the seed |
||||||||
26 | */ |
||||||||
27 | protected $limit = 20; |
||||||||
28 | |||||||||
29 | /** |
||||||||
30 | * @var \Faker\Generator |
||||||||
31 | */ |
||||||||
32 | protected $faker; |
||||||||
33 | |||||||||
34 | /** |
||||||||
35 | * Returns an instance of faker |
||||||||
36 | * |
||||||||
37 | * @param string $locale Locale |
||||||||
38 | * |
||||||||
39 | * @return \Faker\Generator |
||||||||
40 | */ |
||||||||
41 | 358 | public function faker($locale = 'en_US') { |
|||||||
42 | 358 | if (!isset($this->faker)) { |
|||||||
43 | 358 | $this->faker = Factory::create($locale); |
|||||||
44 | } |
||||||||
45 | |||||||||
46 | 358 | return $this->faker; |
|||||||
47 | } |
||||||||
48 | |||||||||
49 | /** |
||||||||
50 | * Get site domain |
||||||||
51 | * @return string |
||||||||
52 | */ |
||||||||
53 | public function getDomain() { |
||||||||
54 | return elgg_get_site_entity()->getDomain(); |
||||||||
55 | } |
||||||||
56 | |||||||||
57 | /** |
||||||||
58 | * Get valid domain for emails |
||||||||
59 | * @return string |
||||||||
60 | */ |
||||||||
61 | 160 | public function getEmailDomain() { |
|||||||
62 | 160 | $email = elgg_get_site_entity()->email; |
|||||||
63 | 160 | if (!$email) { |
|||||||
64 | $email = "noreply@{$this->getDomain()}"; |
||||||||
65 | } |
||||||||
66 | |||||||||
67 | 160 | list(, $domain) = explode('@', $email); |
|||||||
68 | |||||||||
69 | 160 | if (sizeof(explode('.', $domain)) <= 1) { |
|||||||
70 | $domain = 'example.net'; |
||||||||
71 | } |
||||||||
72 | |||||||||
73 | 160 | return $domain; |
|||||||
74 | } |
||||||||
75 | |||||||||
76 | /** |
||||||||
77 | * Returns random unique subtype |
||||||||
78 | * @return bool|string |
||||||||
79 | */ |
||||||||
80 | 419 | public function getRandomSubtype() { |
|||||||
81 | 419 | return substr(sha1(microtime() . rand()), 0, 25); |
|||||||
82 | } |
||||||||
83 | |||||||||
84 | /** |
||||||||
85 | * Create a new fake user |
||||||||
86 | * |
||||||||
87 | * @param array $attributes User entity attributes |
||||||||
88 | * @param array $metadata User entity metadata |
||||||||
89 | * @param array $options Seeding options |
||||||||
90 | * |
||||||||
91 | * @return ElggUser |
||||||||
92 | */ |
||||||||
93 | public function createUser(array $attributes = [], array $metadata = [], array $options = []) { |
||||||||
94 | |||||||||
95 | 160 | $create = function () use ($attributes, $metadata, $options) { |
|||||||
96 | 160 | $metadata['__faker'] = true; |
|||||||
97 | |||||||||
98 | 160 | if (empty($metadata['password'])) { |
|||||||
99 | 154 | $metadata['password'] = generate_random_cleartext_password(); |
|||||||
100 | } |
||||||||
101 | |||||||||
102 | 160 | if (empty($metadata['name'])) { |
|||||||
103 | 160 | $metadata['name'] = $this->faker()->name; |
|||||||
104 | } |
||||||||
105 | |||||||||
106 | 160 | if (empty($metadata['username'])) { |
|||||||
107 | 160 | $metadata['username'] = $this->getRandomUsername($metadata['name']); |
|||||||
108 | } |
||||||||
109 | |||||||||
110 | 160 | if (empty($metadata['email'])) { |
|||||||
111 | 160 | $metadata['email'] = "{$metadata['username']}@{$this->getEmailDomain()}"; |
|||||||
112 | } |
||||||||
113 | |||||||||
114 | 160 | if (empty($attributes['subtype'])) { |
|||||||
115 | 47 | $attributes['subtype'] = 'user'; |
|||||||
116 | } |
||||||||
117 | |||||||||
118 | 160 | $user = false; |
|||||||
119 | |||||||||
120 | try { |
||||||||
121 | 160 | $guid = register_user($metadata['username'], $metadata['password'], $metadata['name'], $metadata['email'], false, $attributes['subtype']); |
|||||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
It seems like
$metadata['name'] can also be of type true ; however, parameter $name of register_user() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
It seems like
$metadata['username'] can also be of type true ; however, parameter $username of register_user() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
It seems like
$metadata['email'] can also be of type true ; however, parameter $email of register_user() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||||
122 | |||||||||
123 | 160 | $user = get_user($guid); |
|||||||
124 | 160 | if (!$user) { |
|||||||
125 | throw new Exception("Unable to create new user with attributes: " . print_r($attributes, true)); |
||||||||
126 | } |
||||||||
127 | |||||||||
128 | 160 | if (isset($metadata['admin'])) { |
|||||||
129 | 1 | if ($metadata['admin']) { |
|||||||
130 | 1 | $user->makeAdmin(); |
|||||||
131 | } else { |
||||||||
132 | $user->removeAdmin(); |
||||||||
133 | } |
||||||||
134 | } |
||||||||
135 | |||||||||
136 | 160 | if (isset($metadata['banned'])) { |
|||||||
137 | 2 | if ($metadata['banned']) { |
|||||||
138 | 2 | $user->ban('Banned by seeder'); |
|||||||
139 | } else { |
||||||||
140 | $user->unban('Unbanned by seeder'); |
||||||||
141 | } |
||||||||
142 | } |
||||||||
143 | |||||||||
144 | 160 | unset($metadata['username']); |
|||||||
145 | 160 | unset($metadata['password']); |
|||||||
146 | 160 | unset($metadata['name']); |
|||||||
147 | 160 | unset($metadata['email']); |
|||||||
148 | 160 | unset($metadata['banned']); |
|||||||
149 | 160 | unset($metadata['admin']); |
|||||||
150 | |||||||||
151 | 160 | $user->setValidationStatus($this->faker()->boolean(), 'seeder'); |
|||||||
152 | |||||||||
153 | 160 | $user->setNotificationSetting('email', false); |
|||||||
154 | 160 | $user->setNotificationSetting('site', true); |
|||||||
155 | |||||||||
156 | 160 | $profile_fields = elgg_extract('profile_fields', $options, []); |
|||||||
157 | 160 | $user = $this->populateMetadata($user, $profile_fields, $metadata); |
|||||||
158 | |||||||||
159 | 160 | $user->save(); |
|||||||
160 | |||||||||
161 | 160 | $this->log("Created new user $user->name [guid: $user->guid]"); |
|||||||
162 | |||||||||
163 | 160 | return $user; |
|||||||
164 | } catch (\RegistrationException $e) { |
||||||||
165 | if ($user && $user->guid) { |
||||||||
166 | $user->delete(); |
||||||||
167 | } |
||||||||
168 | |||||||||
169 | $attr_log = print_r($attributes, true); |
||||||||
170 | $this->log("User creation failed with message {$e->getMessage()} [attributes: $attr_log]"); |
||||||||
171 | |||||||||
172 | return false; |
||||||||
173 | } |
||||||||
174 | 160 | }; |
|||||||
175 | |||||||||
176 | 160 | $ia = elgg_set_ignore_access(true); |
|||||||
177 | |||||||||
178 | 160 | $user = false; |
|||||||
179 | 160 | while (!$user instanceof \ElggUser) { |
|||||||
180 | 160 | $user = $create(); |
|||||||
181 | } |
||||||||
182 | |||||||||
183 | 160 | elgg_set_ignore_access($ia); |
|||||||
184 | |||||||||
185 | 160 | return $user; |
|||||||
186 | |||||||||
187 | } |
||||||||
188 | |||||||||
189 | /** |
||||||||
190 | * Create a new fake group |
||||||||
191 | * |
||||||||
192 | * @param array $attributes Group entity attributes |
||||||||
193 | * @param array $metadata Group entity metadata |
||||||||
194 | * @param array $options Additional options |
||||||||
195 | * |
||||||||
196 | * @return ElggGroup |
||||||||
197 | */ |
||||||||
198 | public function createGroup(array $attributes = [], array $metadata = [], array $options = []) { |
||||||||
199 | |||||||||
200 | 73 | $create = function () use ($attributes, $metadata, $options) { |
|||||||
201 | 73 | $metadata['__faker'] = true; |
|||||||
202 | |||||||||
203 | 73 | if (empty($attributes['access_id'])) { |
|||||||
204 | 73 | $attributes['access_id'] = ACCESS_PUBLIC; |
|||||||
205 | } |
||||||||
206 | |||||||||
207 | 73 | if (empty($metadata['content_access_mode'])) { |
|||||||
208 | 73 | $metadata['content_access_mode'] = ElggGroup::CONTENT_ACCESS_MODE_UNRESTRICTED; |
|||||||
209 | } |
||||||||
210 | |||||||||
211 | 73 | if (empty($metadata['membership'])) { |
|||||||
212 | 73 | $metadata['membership'] = ACCESS_PUBLIC; |
|||||||
213 | } |
||||||||
214 | |||||||||
215 | 73 | if (empty($metadata['name'])) { |
|||||||
216 | 73 | $metadata['name'] = $this->faker()->sentence(); |
|||||||
217 | } |
||||||||
218 | |||||||||
219 | 73 | if (empty($metadata['description'])) { |
|||||||
220 | 73 | $metadata['description'] = $this->faker()->text($this->faker()->numberBetween(500, 1000)); |
|||||||
221 | } |
||||||||
222 | |||||||||
223 | 73 | if (empty($attributes['owner_guid'])) { |
|||||||
224 | 73 | $user = elgg_get_logged_in_user_entity(); |
|||||||
225 | 73 | if (!$user) { |
|||||||
226 | 66 | $user = $this->getRandomUser(); |
|||||||
227 | } |
||||||||
228 | 73 | if (!$user) { |
|||||||
229 | $user = $this->createUser(); |
||||||||
230 | } |
||||||||
231 | |||||||||
232 | 73 | $attributes['owner_guid'] = $user->guid; |
|||||||
233 | } |
||||||||
234 | |||||||||
235 | 73 | if (empty($attributes['container_guid'])) { |
|||||||
236 | 73 | $attributes['container_guid'] = $attributes['owner_guid']; |
|||||||
237 | } |
||||||||
238 | |||||||||
239 | 73 | if (empty($attributes['subtype'])) { |
|||||||
240 | 6 | $attributes['subtype'] = 'group'; |
|||||||
241 | } |
||||||||
242 | |||||||||
243 | 73 | $owner = get_entity($attributes['owner_guid']); |
|||||||
244 | 73 | if (!$owner) { |
|||||||
245 | return false; |
||||||||
246 | } |
||||||||
247 | |||||||||
248 | 73 | $container = get_entity($attributes['container_guid']); |
|||||||
249 | 73 | if (!$container) { |
|||||||
250 | return false; |
||||||||
251 | } |
||||||||
252 | |||||||||
253 | 73 | $tool_options = elgg_extract('group_tools_options', $options, []); |
|||||||
254 | 73 | if ($tool_options) { |
|||||||
255 | foreach ($tool_options as $group_option) { |
||||||||
256 | $option_toggle_name = $group_option->name . "_enable"; |
||||||||
257 | $option_default = $group_option->default_on ? 'yes' : 'no'; |
||||||||
258 | $metadata[$option_toggle_name] = $option_default; |
||||||||
259 | } |
||||||||
260 | } |
||||||||
261 | |||||||||
262 | 73 | if ($this->faker()->boolean(20)) { |
|||||||
263 | 11 | $metadata['featured_group'] = 'yes'; |
|||||||
264 | } |
||||||||
265 | |||||||||
266 | 73 | $group = new ElggGroup(); |
|||||||
267 | 73 | foreach ($attributes as $name => $value) { |
|||||||
268 | 73 | $group->$name = $value; |
|||||||
269 | } |
||||||||
270 | |||||||||
271 | 73 | $profile_fields = elgg_extract('profile_fields', $options, []); |
|||||||
272 | 73 | $group = $this->populateMetadata($group, $profile_fields, $metadata); |
|||||||
273 | |||||||||
274 | 73 | $group->save(); |
|||||||
275 | |||||||||
276 | 73 | if ($group->access_id == ACCESS_PRIVATE) { |
|||||||
277 | $acls = $group->getOwnedAccessCollections(['subtype' => 'group_acl']); |
||||||||
278 | if ($acls) { |
||||||||
279 | $group->access_id = $acls[0]->id; |
||||||||
280 | $group->save(); |
||||||||
281 | } |
||||||||
282 | } |
||||||||
283 | |||||||||
284 | 73 | $group->join(get_entity($attributes['owner_guid'])); |
|||||||
285 | |||||||||
286 | 73 | elgg_create_river_item([ |
|||||||
287 | 73 | 'view' => 'river/group/create', |
|||||||
288 | 73 | 'action_type' => 'create', |
|||||||
289 | 73 | 'subject_guid' => $owner->guid, |
|||||||
290 | 73 | 'object_guid' => $group->guid, |
|||||||
291 | 73 | 'target_guid' => $container->guid, |
|||||||
292 | ]); |
||||||||
293 | |||||||||
294 | 73 | $this->log("Created new group $group->name [guid: $group->guid]"); |
|||||||
295 | |||||||||
296 | 73 | return $group; |
|||||||
297 | 73 | }; |
|||||||
298 | |||||||||
299 | 73 | $ia = elgg_set_ignore_access(true); |
|||||||
300 | |||||||||
301 | 73 | $group = false; |
|||||||
302 | 73 | while (!$group instanceof \ElggGroup) { |
|||||||
303 | 73 | $group = $create(); |
|||||||
304 | } |
||||||||
305 | |||||||||
306 | 73 | elgg_set_ignore_access($ia); |
|||||||
307 | |||||||||
308 | 73 | return $group; |
|||||||
309 | } |
||||||||
310 | |||||||||
311 | /** |
||||||||
312 | * Create a new fake object |
||||||||
313 | * |
||||||||
314 | * @param array $attributes Object entity attributes |
||||||||
315 | * @param array $metadata Object entity metadata |
||||||||
316 | * @param array $options Additional options |
||||||||
317 | * |
||||||||
318 | * @return ElggObject |
||||||||
319 | */ |
||||||||
320 | public function createObject(array $attributes = [], array $metadata = [], array $options = []) { |
||||||||
321 | |||||||||
322 | 180 | $create = function () use ($attributes, $metadata, $options) { |
|||||||
323 | |||||||||
324 | 180 | $properties = array_merge($metadata, $attributes); |
|||||||
325 | |||||||||
326 | 180 | $properties['__faker'] = true; |
|||||||
327 | |||||||||
328 | 180 | if (empty($properties['title'])) { |
|||||||
329 | 179 | $properties['title'] = $this->faker()->sentence(); |
|||||||
330 | } |
||||||||
331 | |||||||||
332 | 180 | if (empty($properties['description'])) { |
|||||||
333 | 179 | $properties['description'] = $this->faker()->text($this->faker()->numberBetween(500, 1000)); |
|||||||
334 | } |
||||||||
335 | |||||||||
336 | 180 | if (empty($properties['subtype'])) { |
|||||||
337 | 36 | $properties['subtype'] = $this->getRandomSubtype(); |
|||||||
338 | } |
||||||||
339 | |||||||||
340 | 180 | if (empty($properties['tags'])) { |
|||||||
341 | 158 | $properties['tags'] = $this->faker()->words(10); |
|||||||
342 | } |
||||||||
343 | |||||||||
344 | 180 | if (empty($properties['container_guid'])) { |
|||||||
345 | 179 | $container = elgg_get_logged_in_user_entity(); |
|||||||
346 | 179 | if (!$container) { |
|||||||
347 | 111 | $container = $this->getRandomUser(); |
|||||||
348 | } |
||||||||
349 | 179 | if (!$container) { |
|||||||
350 | $container = $this->createUser(); |
||||||||
351 | } |
||||||||
352 | |||||||||
353 | 179 | $properties['container_guid'] = $container->guid; |
|||||||
354 | } |
||||||||
355 | |||||||||
356 | 180 | $container = get_entity($properties['container_guid']); |
|||||||
357 | 180 | if (!$container) { |
|||||||
358 | return false; |
||||||||
359 | } |
||||||||
360 | |||||||||
361 | 180 | if (empty($properties['owner_guid'])) { |
|||||||
362 | 166 | $owner = $container; |
|||||||
363 | 166 | $properties['owner_guid'] = $owner->guid; |
|||||||
364 | } |
||||||||
365 | |||||||||
366 | 180 | $owner = get_entity($properties['owner_guid']); |
|||||||
367 | 180 | if (!$owner) { |
|||||||
368 | return false; |
||||||||
369 | } |
||||||||
370 | |||||||||
371 | 180 | if (!isset($properties['access_id'])) { |
|||||||
372 | 175 | $properties['access_id'] = ACCESS_PUBLIC; |
|||||||
373 | } |
||||||||
374 | |||||||||
375 | 180 | $class = elgg_get_entity_class('object', $properties['subtype']); |
|||||||
376 | 180 | if ($class && class_exists($class)) { |
|||||||
377 | 26 | $object = new $class(); |
|||||||
378 | } else { |
||||||||
379 | 155 | $object = new ElggObject(); |
|||||||
380 | } |
||||||||
381 | |||||||||
382 | 180 | foreach ($properties as $name => $value) { |
|||||||
383 | 180 | $object->$name = $value; |
|||||||
384 | } |
||||||||
385 | |||||||||
386 | 180 | $profile_fields = elgg_extract('profile_fields', $options, []); |
|||||||
387 | 180 | $object = $this->populateMetadata($object, $profile_fields, $properties); |
|||||||
388 | |||||||||
389 | 180 | if (elgg_extract('save', $options, true)) { |
|||||||
390 | 180 | $object->save(); |
|||||||
391 | } |
||||||||
392 | |||||||||
393 | 180 | $type_str = elgg_echo("item:object:{$object->getSubtype()}"); |
|||||||
394 | |||||||||
395 | 180 | $this->log("Created new item in $type_str $object->title [guid: $object->guid]"); |
|||||||
396 | |||||||||
397 | 180 | return $object; |
|||||||
398 | 180 | }; |
|||||||
399 | |||||||||
400 | 180 | $ia = elgg_set_ignore_access(true); |
|||||||
401 | |||||||||
402 | 180 | $object = false; |
|||||||
403 | 180 | while (!$object instanceof \ElggObject) { |
|||||||
404 | 180 | $object = $create(); |
|||||||
405 | } |
||||||||
406 | |||||||||
407 | 180 | elgg_set_ignore_access($ia); |
|||||||
408 | |||||||||
409 | 180 | return $object; |
|||||||
410 | |||||||||
411 | } |
||||||||
412 | |||||||||
413 | /** |
||||||||
414 | * Create a new fake site |
||||||||
415 | * |
||||||||
416 | * @param array $attributes Object entity attributes |
||||||||
417 | * @param array $metadata Object entity metadata |
||||||||
418 | * |
||||||||
419 | * @return ElggObject |
||||||||
420 | */ |
||||||||
421 | public function createSite(array $attributes = [], array $metadata = []) { |
||||||||
422 | // We don't want to create more than one site |
||||||||
423 | return elgg_get_site_entity(); |
||||||||
424 | } |
||||||||
425 | |||||||||
426 | /** |
||||||||
427 | * Returns random fake user |
||||||||
428 | * |
||||||||
429 | * @param int[] $exclude GUIDs to exclude |
||||||||
430 | * |
||||||||
431 | * @return ElggUser|false |
||||||||
432 | */ |
||||||||
433 | 178 | public function getRandomUser(array $exclude = []) { |
|||||||
434 | |||||||||
435 | 178 | $exclude[] = 0; |
|||||||
436 | 178 | $exclude_in = implode(',', array_map(function ($e) { |
|||||||
437 | 178 | return (int) $e; |
|||||||
438 | 178 | }, $exclude)); |
|||||||
439 | |||||||||
440 | 178 | $users = elgg_get_entities([ |
|||||||
441 | 178 | 'types' => 'user', |
|||||||
442 | 'metadata_names' => ['__faker'], |
||||||||
443 | 178 | 'limit' => 1, |
|||||||
444 | 'wheres' => [ |
||||||||
445 | 178 | "e.guid NOT IN ($exclude_in)", |
|||||||
446 | ], |
||||||||
447 | 178 | 'order_by' => 'RAND()', |
|||||||
448 | ]); |
||||||||
449 | |||||||||
450 | 178 | return $users ? $users[0] : false; |
|||||||
451 | } |
||||||||
452 | |||||||||
453 | /** |
||||||||
454 | * Returns random fake group |
||||||||
455 | * |
||||||||
456 | * @param int[] $exclude GUIDs to exclude |
||||||||
457 | * |
||||||||
458 | * @return ElggGroup|false |
||||||||
459 | */ |
||||||||
460 | public function getRandomGroup(array $exclude = []) { |
||||||||
461 | |||||||||
462 | $exclude[] = 0; |
||||||||
463 | $exclude_in = implode(',', array_map(function ($e) { |
||||||||
464 | return (int) $e; |
||||||||
465 | }, $exclude)); |
||||||||
466 | |||||||||
467 | $groups = elgg_get_entities([ |
||||||||
468 | 'types' => 'group', |
||||||||
469 | 'metadata_names' => ['__faker'], |
||||||||
470 | 'limit' => 1, |
||||||||
471 | 'wheres' => [ |
||||||||
472 | "e.guid NOT IN ($exclude_in)", |
||||||||
473 | ], |
||||||||
474 | 'order_by' => 'RAND()', |
||||||||
475 | ]); |
||||||||
476 | |||||||||
477 | return $groups ? $groups[0] : false; |
||||||||
478 | } |
||||||||
479 | |||||||||
480 | /** |
||||||||
481 | * Get random access id |
||||||||
482 | * |
||||||||
483 | * @param ElggUser $user User |
||||||||
484 | * @param ElggEntity $container Container |
||||||||
485 | * |
||||||||
486 | * @return int |
||||||||
487 | */ |
||||||||
488 | public function getRandomAccessId(\ElggUser $user = null, ElggEntity $container = null) { |
||||||||
489 | |||||||||
490 | $params = [ |
||||||||
491 | 'container_guid' => $container ? $container->guid : null, |
||||||||
492 | ]; |
||||||||
493 | |||||||||
494 | $access_array = get_write_access_array($user->guid, null, null, $params); |
||||||||
495 | |||||||||
496 | $access_key = array_rand($access_array, 1); |
||||||||
497 | |||||||||
498 | return $access_array[$access_key]; |
||||||||
499 | } |
||||||||
500 | |||||||||
501 | /** |
||||||||
502 | * Generates a unique available and valid username |
||||||||
503 | * |
||||||||
504 | * @param string $base_name Display name, email or other prefix to use as basis |
||||||||
505 | * |
||||||||
506 | * @return string |
||||||||
507 | */ |
||||||||
508 | 172 | public function getRandomUsername($base_name = 'user') { |
|||||||
509 | |||||||||
510 | 172 | $available = false; |
|||||||
511 | |||||||||
512 | 172 | $base_name = iconv('UTF-8', 'ASCII//TRANSLIT', $base_name); |
|||||||
513 | 172 | $blacklist = '/[\x{0080}-\x{009f}\x{00a0}\x{2000}-\x{200f}\x{2028}-\x{202f}\x{3000}\x{e000}-\x{f8ff}]/u'; |
|||||||
514 | $blacklist2 = [ |
||||||||
515 | 172 | ' ', |
|||||||
516 | '\'', |
||||||||
517 | '/', |
||||||||
518 | '\\', |
||||||||
519 | '"', |
||||||||
520 | '*', |
||||||||
521 | '&', |
||||||||
522 | '?', |
||||||||
523 | '#', |
||||||||
524 | '%', |
||||||||
525 | '^', |
||||||||
526 | '(', |
||||||||
527 | ')', |
||||||||
528 | '{', |
||||||||
529 | '}', |
||||||||
530 | '[', |
||||||||
531 | ']', |
||||||||
532 | '~', |
||||||||
533 | '?', |
||||||||
534 | '<', |
||||||||
535 | '>', |
||||||||
536 | ';', |
||||||||
537 | '|', |
||||||||
538 | '¬', |
||||||||
539 | '`', |
||||||||
540 | '@', |
||||||||
541 | '-', |
||||||||
542 | '+', |
||||||||
543 | '=' |
||||||||
544 | ]; |
||||||||
545 | |||||||||
546 | 172 | $base_name = preg_replace($blacklist, '', $base_name); |
|||||||
547 | 172 | $base_name = str_replace($blacklist2, '', $base_name); |
|||||||
548 | 172 | $base_name = str_replace('.', '_', $base_name); |
|||||||
549 | |||||||||
550 | 172 | $ia = elgg_set_ignore_access(true); |
|||||||
551 | |||||||||
552 | 172 | $ha = access_get_show_hidden_status(); |
|||||||
553 | 172 | access_show_hidden_entities(true); |
|||||||
554 | |||||||||
555 | 172 | $minlength = elgg_get_config('minusername') ? : 8; |
|||||||
556 | 172 | if ($base_name) { |
|||||||
557 | 172 | $fill = $minlength - strlen($base_name); |
|||||||
558 | } else { |
||||||||
559 | $fill = 8; |
||||||||
560 | } |
||||||||
561 | |||||||||
562 | 172 | $separator = ''; |
|||||||
563 | |||||||||
564 | 172 | if ($fill > 0) { |
|||||||
565 | 26 | $suffix = (new \ElggCrypto())->getRandomString($fill); |
|||||||
566 | 26 | $base_name = "$base_name$separator$suffix"; |
|||||||
567 | } |
||||||||
568 | |||||||||
569 | 172 | $iterator = 0; |
|||||||
570 | 172 | while (!$available) { |
|||||||
571 | 172 | if ($iterator > 0) { |
|||||||
572 | $base_name = "$base_name$separator$iterator"; |
||||||||
573 | } |
||||||||
574 | 172 | $user = get_user_by_username($base_name); |
|||||||
575 | 172 | $available = !$user; |
|||||||
576 | try { |
||||||||
577 | 172 | if ($available) { |
|||||||
578 | 172 | validate_username($base_name); |
|||||||
579 | } |
||||||||
580 | } catch (\Exception $e) { |
||||||||
581 | if ($iterator >= 10) { |
||||||||
582 | // too many failed attempts |
||||||||
583 | $base_name = (new \ElggCrypto())->getRandomString(8); |
||||||||
584 | } |
||||||||
585 | } |
||||||||
586 | |||||||||
587 | 172 | $iterator++; |
|||||||
588 | } |
||||||||
589 | |||||||||
590 | 172 | access_show_hidden_entities($ha); |
|||||||
591 | 172 | elgg_set_ignore_access($ia); |
|||||||
592 | |||||||||
593 | 172 | return strtolower($base_name); |
|||||||
594 | } |
||||||||
595 | |||||||||
596 | /** |
||||||||
597 | * Set random metadata |
||||||||
598 | * |
||||||||
599 | * @param ElggEntity $entity Entity |
||||||||
600 | * @param array $fields An array of profile fields in $name => $input_type format |
||||||||
601 | * @param array $metadata Other metadata $name => $value pairs to set |
||||||||
602 | * |
||||||||
603 | * @return ElggEntity |
||||||||
604 | */ |
||||||||
605 | 358 | public function populateMetadata(ElggEntity $entity, array $fields = [], array $metadata = []) { |
|||||||
606 | |||||||||
607 | 358 | foreach ($fields as $name => $type) { |
|||||||
608 | if (isset($metadata[$name])) { |
||||||||
609 | continue; |
||||||||
610 | } |
||||||||
611 | |||||||||
612 | switch ($name) { |
||||||||
613 | case 'phone' : |
||||||||
614 | case 'mobile' : |
||||||||
615 | $metadata[$name] = $this->faker()->phoneNumber; |
||||||||
616 | break; |
||||||||
617 | |||||||||
618 | default : |
||||||||
619 | switch ($type) { |
||||||||
620 | case 'plaintext' : |
||||||||
621 | case 'longtext' : |
||||||||
622 | $metadata[$name] = $this->faker()->text($this->faker()->numberBetween(500, 1000)); |
||||||||
623 | break; |
||||||||
624 | |||||||||
625 | case 'text' : |
||||||||
626 | $metadata[$name] = $this->faker()->sentence; |
||||||||
627 | break; |
||||||||
628 | |||||||||
629 | case 'tags' : |
||||||||
630 | $metadata[$name] = $this->faker()->words(10); |
||||||||
631 | break; |
||||||||
632 | |||||||||
633 | case 'url' : |
||||||||
634 | $metadata[$name] = $this->faker()->url; |
||||||||
635 | break; |
||||||||
636 | |||||||||
637 | case 'email' : |
||||||||
638 | $metadata[$name] = $this->faker()->email; |
||||||||
639 | break; |
||||||||
640 | |||||||||
641 | case 'number' : |
||||||||
642 | $metadata[$name] = $this->faker()->randomNumber(); |
||||||||
643 | break; |
||||||||
644 | |||||||||
645 | case 'date' : |
||||||||
646 | $metadata[$name] = $this->faker()->unixTime; |
||||||||
647 | break; |
||||||||
648 | |||||||||
649 | case 'password' : |
||||||||
650 | $metadata[$name] = generate_random_cleartext_password(); |
||||||||
651 | break; |
||||||||
652 | |||||||||
653 | case 'location' : |
||||||||
654 | $metadata[$name] = $this->faker()->address; |
||||||||
655 | $metadata['geo:lat'] = $this->faker()->latitude; |
||||||||
656 | $metadata['geo:long'] = $this->faker()->longitude; |
||||||||
657 | break; |
||||||||
658 | |||||||||
659 | default : |
||||||||
660 | $metadata[$name] = ''; |
||||||||
661 | break; |
||||||||
662 | } |
||||||||
663 | |||||||||
664 | break; |
||||||||
665 | } |
||||||||
666 | } |
||||||||
667 | |||||||||
668 | 358 | foreach ($metadata as $key => $value) { |
|||||||
669 | 358 | if (array_key_exists($key, $fields) && $entity instanceof ElggUser) { |
|||||||
670 | $entity->deleteAnnotations("profile:$key"); |
||||||||
671 | $value = (array) $value; |
||||||||
672 | foreach ($value as $val) { |
||||||||
673 | $entity->annotate("profile:$key", $val, $this->getRandomAccessId($entity), $entity->guid); |
||||||||
674 | } |
||||||||
675 | } else { |
||||||||
676 | 358 | $entity->$key = $value; |
|||||||
677 | } |
||||||||
678 | } |
||||||||
679 | |||||||||
680 | 358 | return $entity; |
|||||||
681 | } |
||||||||
682 | |||||||||
683 | /** |
||||||||
684 | * Create an icon for an entity |
||||||||
685 | * |
||||||||
686 | * @param ElggEntity $entity Entity |
||||||||
687 | * |
||||||||
688 | * @return bool |
||||||||
689 | */ |
||||||||
690 | public function createIcon(ElggEntity $entity) { |
||||||||
691 | |||||||||
692 | $icon_location = $this->faker()->image(); |
||||||||
693 | if (empty($icon_location)) { |
||||||||
694 | return false; |
||||||||
695 | } |
||||||||
696 | |||||||||
697 | $result = $entity->saveIconFromLocalFile($icon_location); |
||||||||
698 | |||||||||
699 | if ($result && $entity instanceof ElggUser) { |
||||||||
700 | elgg_create_river_item([ |
||||||||
701 | 'view' => 'river/user/default/profileiconupdate', |
||||||||
702 | 'action_type' => 'update', |
||||||||
703 | 'subject_guid' => $entity->guid, |
||||||||
704 | 'object_guid' => $entity->guid, |
||||||||
705 | ]); |
||||||||
706 | } |
||||||||
707 | |||||||||
708 | return $result; |
||||||||
709 | } |
||||||||
710 | |||||||||
711 | /** |
||||||||
712 | * Create comments/replies |
||||||||
713 | * |
||||||||
714 | * @param ElggEntity $entity Entity to comment on |
||||||||
715 | * @param int $limit Number of comments to create |
||||||||
716 | * |
||||||||
717 | * @return int Number of generated comments |
||||||||
718 | */ |
||||||||
719 | public function createComments(ElggEntity $entity, $limit = null) { |
||||||||
720 | |||||||||
721 | $ia = elgg_set_ignore_access(true); |
||||||||
722 | |||||||||
723 | $tries = 0; |
||||||||
724 | $success = 0; |
||||||||
725 | |||||||||
726 | if (!$limit) { |
||||||||
727 | $limit = $this->faker()->numberBetween(1, 20); |
||||||||
728 | } |
||||||||
729 | |||||||||
730 | while ($tries < $limit) { |
||||||||
731 | $comment = new \ElggComment(); |
||||||||
732 | $comment->subtype = $entity->getSubtype() == 'discussion' ? 'discussion_reply' : 'comment'; |
||||||||
733 | $comment->owner_guid = $this->getRandomUser()->guid ? : $entity->owner_guid; |
||||||||
734 | $comment->container_guid = $entity->guid; |
||||||||
735 | $comment->description = $this->faker()->paragraph; |
||||||||
736 | |||||||||
737 | $tries++; |
||||||||
738 | if ($comment->save()) { |
||||||||
739 | $success++; |
||||||||
740 | } |
||||||||
741 | } |
||||||||
742 | |||||||||
743 | elgg_set_ignore_access($ia); |
||||||||
744 | |||||||||
745 | return $success; |
||||||||
746 | |||||||||
747 | } |
||||||||
748 | |||||||||
749 | /** |
||||||||
750 | * Create likes |
||||||||
751 | * |
||||||||
752 | * @param ElggEntity $entity Entity to like |
||||||||
753 | * @param int $limit Number of likes to create |
||||||||
754 | * |
||||||||
755 | * @return int |
||||||||
756 | */ |
||||||||
757 | public function createLikes(ElggEntity $entity, $limit = null) { |
||||||||
758 | |||||||||
759 | $ia = elgg_set_ignore_access(true); |
||||||||
760 | |||||||||
761 | $success = 0; |
||||||||
762 | |||||||||
763 | if (!$limit) { |
||||||||
764 | $limit = $this->faker()->numberBetween(1, 20); |
||||||||
765 | } |
||||||||
766 | |||||||||
767 | while ($success < $limit) { |
||||||||
768 | if ($entity->annotate('likes', true, $entity->access_id, $this->getRandomUser()->guid)) { |
||||||||
769 | $success++; |
||||||||
770 | } |
||||||||
771 | } |
||||||||
772 | |||||||||
773 | elgg_set_ignore_access($ia); |
||||||||
774 | |||||||||
775 | return $success; |
||||||||
776 | } |
||||||||
777 | |||||||||
778 | /** |
||||||||
779 | * Log a message |
||||||||
780 | * |
||||||||
781 | * @param string $msg Message to log |
||||||||
782 | * @param string $level Message level |
||||||||
783 | * Note that 'ERROR' will terminate further code execution |
||||||||
784 | * |
||||||||
785 | * @return void |
||||||||
786 | */ |
||||||||
787 | 358 | public function log($msg, $level = 'NOTICE') { |
|||||||
788 | 358 | elgg_log($msg, $level); |
|||||||
789 | 358 | } |
|||||||
790 | |||||||||
791 | } |