Elgg  Version 6.3
ElggUser.php
Go to the documentation of this file.
1 <?php
2 
3 use Elgg\Exceptions\InvalidArgumentException as ElggInvalidArgumentException;
5 use Elgg\Traits\Entity\Friends;
6 use Elgg\Traits\Entity\PluginSettings;
8 
28 class ElggUser extends \ElggEntity {
29 
30  use Friends;
31  use PluginSettings {
32  getPluginSetting as protected psGetPluginSetting;
33  }
34  use ProfileData;
35 
39  protected function initializeAttributes() {
40  parent::initializeAttributes();
41 
42  $this->attributes['type'] = 'user';
43  $this->attributes['subtype'] = 'user';
44 
45  $this->attributes['access_id'] = ACCESS_PUBLIC;
46  $this->attributes['owner_guid'] = 0; // Users aren't owned by anyone, even if they are admin created.
47  $this->attributes['container_guid'] = 0; // Users aren't contained by anyone, even if they are admin created.
48 
49  // Before Elgg 3.0 this was handled by database logic
50  $this->setMetadata('banned', 'no');
51  $this->setMetadata('admin', 'no');
52  $this->language = elgg_get_config('language');
53  $this->prev_last_action = 0;
54  $this->last_login = 0;
55  $this->prev_last_login = 0;
56  }
57 
66  public function getLanguage(?string $fallback = null): string {
67  if (!empty($this->language)) {
68  return $this->language;
69  }
70 
71  if ($fallback !== null) {
72  return $fallback;
73  }
74 
75  return elgg_get_config('language');
76  }
77 
83  public function __set($name, $value) {
84  switch ($name) {
85  case 'salt':
86  case 'password':
87  _elgg_services()->logger->error("User entities no longer contain {$name}");
88  return;
89  case 'password_hash':
90  _elgg_services()->logger->error('password_hash is a readonly attribute.');
91  return;
92  case 'email':
93  try {
94  _elgg_services()->accounts->assertValidEmail($value);
95  } catch (RegistrationException $ex) {
96  throw new ElggInvalidArgumentException($ex->getMessage(), $ex->getCode(), $ex);
97  }
98  break;
99  case 'username':
100  try {
101  _elgg_services()->accounts->assertValidUsername($value);
102  } catch (RegistrationException $ex) {
103  throw new ElggInvalidArgumentException($ex->getMessage(), $ex->getCode(), $ex);
104  }
105 
107  if ($existing_user instanceof \ElggUser && ($existing_user->guid !== $this->guid)) {
108  throw new ElggInvalidArgumentException("{$name} is supposed to be unique for ElggUser");
109  }
110  break;
111  case 'admin':
112  throw new ElggInvalidArgumentException(_elgg_services()->translator->translate('ElggUser:Error:SetAdmin', ['makeAdmin() / removeAdmin()']));
113  case 'banned':
114  throw new ElggInvalidArgumentException(_elgg_services()->translator->translate('ElggUser:Error:SetBanned', ['ban() / unban()']));
115  }
116 
117  parent::__set($name, $value);
118  }
119 
127  public function ban(string $reason = ''): bool {
128  if (!$this->canEdit()) {
129  return false;
130  }
131 
132  if (!_elgg_services()->events->trigger('ban', 'user', $this)) {
133  return false;
134  }
135 
136  $this->ban_reason = $reason;
137  $this->setMetadata('banned', 'yes');
138 
139  $this->invalidateCache();
140 
141  return true;
142  }
143 
149  public function unban(): bool {
150 
151  if (!$this->canEdit()) {
152  return false;
153  }
154 
155  if (!_elgg_services()->events->trigger('unban', 'user', $this)) {
156  return false;
157  }
158 
159  unset($this->ban_reason);
160  $this->setMetadata('banned', 'no');
161 
162  $this->invalidateCache();
163 
164  return true;
165  }
166 
172  public function isBanned(): bool {
173  return $this->banned === 'yes';
174  }
175 
181  public function isAdmin(): bool {
182  return $this->admin === 'yes';
183  }
184 
190  public function makeAdmin(): bool {
191 
192  if ($this->isAdmin()) {
193  return true;
194  }
195 
196  if (!_elgg_services()->events->trigger('make_admin', 'user', $this)) {
197  return false;
198  }
199 
200  $this->setMetadata('admin', 'yes');
201 
202  $this->invalidateCache();
203 
204  return true;
205  }
206 
212  public function removeAdmin(): bool {
213 
214  if (!$this->isAdmin()) {
215  return true;
216  }
217 
218  if (!_elgg_services()->events->trigger('remove_admin', 'user', $this)) {
219  return false;
220  }
221 
222  $this->setMetadata('admin', 'no');
223 
224  $this->invalidateCache();
225 
226  return true;
227  }
228 
234  public function setLastLogin(): void {
235  $time = $this->getCurrentTime()->getTimestamp();
236 
237  if ($this->last_login == $time) {
238  // no change required
239  return;
240  }
241 
243  // these writes actually work, we just type hint read-only.
244  $this->prev_last_login = $this->last_login;
245  $this->last_login = $time;
246  });
247  }
248 
254  public function setLastAction(): void {
255 
256  $time = $this->getCurrentTime()->getTimestamp();
257 
258  if ($this->last_action == $time) {
259  // no change required
260  return;
261  }
262 
263  $user = $this;
264 
265  elgg_register_event_handler('shutdown', 'system', function () use ($user, $time) {
266  // these writes actually work, we just type hint read-only.
267  $user->prev_last_action = $user->last_action;
268 
269  $user->updateLastAction($time);
270  });
271  }
272 
278  public function isValidated(): ?bool {
279  if (!isset($this->validated)) {
280  return null;
281  }
282 
283  return (bool) $this->validated;
284  }
285 
294  public function setValidationStatus(bool $status, string $method = ''): void {
295  if ($status === $this->isValidated()) {
296  // no change needed
297  return;
298  }
299 
300  $this->validated = $status;
301 
302  if ($status) {
303  $this->validated_method = $method;
304  $this->validated_ts = time();
305 
306  // make sure the user is enabled
307  if (!$this->isEnabled()) {
308  $this->enable();
309  }
310 
311  // let the system know the user is validated
312  _elgg_services()->events->triggerAfter('validate', 'user', $this);
313  } else {
314  // invalidating
315  unset($this->validated_ts);
316  unset($this->validated_method);
317  _elgg_services()->events->triggerAfter('invalidate', 'user', $this);
318  }
319  }
320 
328  public function getGroups(array $options = []) {
329  $options['type'] = 'group';
330  $options['relationship'] = 'member';
331  $options['relationship_guid'] = $this->guid;
332 
333  return elgg_get_entities($options);
334  }
335 
339  public function getObjects(array $options = []) {
340  $options['type'] = 'object';
341  $options['owner_guid'] = $this->guid;
342 
343  return elgg_get_entities($options);
344  }
345 
353  public function getOwnerGUID(): int {
354  $owner_guid = parent::getOwnerGUID();
355  if ($owner_guid === 0) {
356  $owner_guid = (int) $this->guid;
357  }
358 
359  return $owner_guid;
360  }
361 
365  protected function prepareObject(\Elgg\Export\Entity $object) {
366  $object = parent::prepareObject($object);
367  $object->name = $this->getDisplayName();
368  $object->username = $this->username;
369  $object->language = $this->language;
370  unset($object->read_access);
371  return $object;
372  }
373 
382  public function setPassword(string $password): void {
383  $this->setMetadata('password_hash', _elgg_services()->passwords->generateHash($password));
384  if ($this->guid === elgg_get_logged_in_user_guid()) {
385  // update the session user token, so this session remains valid
386  // other sessions for this user will be invalidated
387  _elgg_services()->session_manager->setUserToken();
388  }
389  }
390 
401  public function setNotificationSetting(string $method, bool $enabled = true, string $purpose = 'default'): bool {
402  if (empty($purpose)) {
403  throw new ElggInvalidArgumentException(__METHOD__ . ' requires $purpose to be set to a non-empty string');
404  }
405 
406  $this->{"notification:{$purpose}:{$method}"} = (int) $enabled;
407  return $this->save();
408  }
409 
428  public function getNotificationSettings(string $purpose = 'default', bool $only_active_methods = false): array {
429  if (empty($purpose)) {
430  throw new ElggInvalidArgumentException(__METHOD__ . ' requires $purpose to be set to a non-empty string');
431  }
432 
433  $settings = [];
434 
435  $methods = _elgg_services()->notifications->getMethods();
436  foreach ($methods as $method) {
437  if ($purpose !== 'default' && !isset($this->{"notification:{$purpose}:{$method}"})) {
438  // fallback to the default settings
439  $settings[$method] = (bool) $this->{"notification:default:{$method}"};
440  } else {
441  $settings[$method] = (bool) $this->{"notification:{$purpose}:{$method}"};
442  }
443  }
444 
445  return $only_active_methods ? array_keys(array_filter($settings)) : $settings;
446  }
447 
451  public function persistentDelete(bool $recursive = true): bool {
452  $result = parent::persistentDelete($recursive);
453  if ($result) {
454  // cleanup remember me cookie records
455  _elgg_services()->users_remember_me_cookies_table->deleteAllHashes($this);
456  }
457 
458  return $result;
459  }
460 
472  public function getPluginSetting(string $plugin_id, string $name, $default = null) {
473  $plugin = _elgg_services()->plugins->get($plugin_id);
474  if (!$plugin instanceof \ElggPlugin || !$plugin->isActive()) {
475  return $default;
476  }
477 
478  $static_defaults = (array) $plugin->getStaticConfig('user_settings', []);
479 
480  $default = elgg_extract($name, $static_defaults, $default);
481 
482  return $this->psGetPluginSetting($plugin_id, $name, $default);
483  }
484 
497  public function notify(string $action, \ElggData $subject, array $params = [], ?\ElggEntity $from = null): array {
498  return _elgg_services()->notifications->sendInstantNotification($this, $action, $subject, $params, $from);
499  }
500 }
$guid
Reset an ElggUpgrade.
Definition: reset.php:6
if(! $user instanceof \ElggUser) if($user->email===$email) $existing_user
$username
Definition: delete.php:23
if(! $user||! $user->canDelete()) $name
Definition: delete.php:22
$plugin_id
Remove all user and plugin settings from the give plugin ID.
Definition: remove.php:8
$params
Saves global plugin settings.
Definition: save.php:13
$language
Definition: useradd.php:17
return[ 'admin/delete_admin_notices'=>['access'=> 'admin'], 'admin/menu/save'=>['access'=> 'admin'], 'admin/plugins/activate'=>['access'=> 'admin'], 'admin/plugins/activate_all'=>['access'=> 'admin'], 'admin/plugins/deactivate'=>['access'=> 'admin'], 'admin/plugins/deactivate_all'=>['access'=> 'admin'], 'admin/plugins/set_priority'=>['access'=> 'admin'], 'admin/security/security_txt'=>['access'=> 'admin'], 'admin/security/settings'=>['access'=> 'admin'], 'admin/security/regenerate_site_secret'=>['access'=> 'admin'], 'admin/site/cache/invalidate'=>['access'=> 'admin'], 'admin/site/flush_cache'=>['access'=> 'admin'], 'admin/site/icons'=>['access'=> 'admin'], 'admin/site/set_maintenance_mode'=>['access'=> 'admin'], 'admin/site/set_robots'=>['access'=> 'admin'], 'admin/site/theme'=>['access'=> 'admin'], 'admin/site/unlock_upgrade'=>['access'=> 'admin'], 'admin/site/settings'=>['access'=> 'admin'], 'admin/upgrade'=>['access'=> 'admin'], 'admin/upgrade/reset'=>['access'=> 'admin'], 'admin/user/ban'=>['access'=> 'admin'], 'admin/user/bulk/ban'=>['access'=> 'admin'], 'admin/user/bulk/delete'=>['access'=> 'admin'], 'admin/user/bulk/unban'=>['access'=> 'admin'], 'admin/user/bulk/validate'=>['access'=> 'admin'], 'admin/user/change_email'=>['access'=> 'admin'], 'admin/user/delete'=>['access'=> 'admin'], 'admin/user/login_as'=>['access'=> 'admin'], 'admin/user/logout_as'=>[], 'admin/user/makeadmin'=>['access'=> 'admin'], 'admin/user/resetpassword'=>['access'=> 'admin'], 'admin/user/removeadmin'=>['access'=> 'admin'], 'admin/user/unban'=>['access'=> 'admin'], 'admin/user/validate'=>['access'=> 'admin'], 'annotation/delete'=>[], 'avatar/upload'=>[], 'comment/save'=>[], 'diagnostics/download'=>['access'=> 'admin'], 'entity/chooserestoredestination'=>[], 'entity/delete'=>[], 'entity/mute'=>[], 'entity/restore'=>[], 'entity/subscribe'=>[], 'entity/trash'=>[], 'entity/unmute'=>[], 'entity/unsubscribe'=>[], 'login'=>['access'=> 'logged_out'], 'logout'=>[], 'notifications/mute'=>['access'=> 'public'], 'plugins/settings/remove'=>['access'=> 'admin'], 'plugins/settings/save'=>['access'=> 'admin'], 'plugins/usersettings/save'=>[], 'register'=>['access'=> 'logged_out', 'middleware'=>[\Elgg\Router\Middleware\RegistrationAllowedGatekeeper::class,],], 'river/delete'=>[], 'settings/notifications'=>[], 'settings/notifications/subscriptions'=>[], 'user/changepassword'=>['access'=> 'public'], 'user/requestnewpassword'=>['access'=> 'public'], 'useradd'=>['access'=> 'admin'], 'usersettings/save'=>[], 'widgets/add'=>[], 'widgets/delete'=>[], 'widgets/move'=>[], 'widgets/save'=>[],]
Definition: actions.php:73
if(! $annotation instanceof ElggAnnotation) $time
Definition: time.php:20
$user
Definition: ban.php:7
A generic class that contains shared code among \ElggExtender, \ElggEntity, and \ElggRelationship.
Definition: ElggData.php:12
Plugin class containing helper functions for plugin activation/deactivation, dependency checking capa...
Definition: ElggPlugin.php:17
isAdmin()
Is this user admin?
Definition: ElggUser.php:181
notify(string $action, \ElggData $subject, array $params=[], ?\ElggEntity $from=null)
Notify the user about a given action on a subject.
Definition: ElggUser.php:497
getNotificationSettings(string $purpose='default', bool $only_active_methods=false)
Return the user notification settings [ 'email' => true, // enabled 'ajax' => false,...
Definition: ElggUser.php:428
removeAdmin()
Remove the admin flag for user.
Definition: ElggUser.php:212
getPluginSetting(string $plugin_id, string $name, $default=null)
Get a plugin setting.
Definition: ElggUser.php:472
initializeAttributes()
{Initialize the attributes array.This is vital to distinguish between metadata and base parameters....
Definition: ElggUser.php:39
getObjects(array $options=[])
{}
Definition: ElggUser.php:339
persistentDelete(bool $recursive=true)
{Permanently delete the entity from the database.If true (default) then all entities which are owned ...
Definition: ElggUser.php:451
__set($name, $value)
{Set an attribute or metadata value for this entity.Anything that is not an attribute is saved as met...
Definition: ElggUser.php:83
unban()
Unban this user.
Definition: ElggUser.php:149
isValidated()
Gets the validation status of a user.
Definition: ElggUser.php:278
getOwnerGUID()
Get a user's owner GUID.
Definition: ElggUser.php:353
setNotificationSetting(string $method, bool $enabled=true, string $purpose='default')
Enable or disable a notification delivery method.
Definition: ElggUser.php:401
isBanned()
Is this user banned or not?
Definition: ElggUser.php:172
setPassword(string $password)
Set the necessary metadata to store a hash of the user's password.
Definition: ElggUser.php:382
getLanguage(?string $fallback=null)
Get user language or default to site language.
Definition: ElggUser.php:66
makeAdmin()
Make the user an admin.
Definition: ElggUser.php:190
ban(string $reason='')
Ban this user.
Definition: ElggUser.php:127
setValidationStatus(bool $status, string $method='')
Set the validation status for a user.
Definition: ElggUser.php:294
setLastAction()
Sets the last action time of the given user to right now.
Definition: ElggUser.php:254
prepareObject(\Elgg\Export\Entity $object)
{Prepare an object copy for toObject()Object representation of the entity\Elgg\Export\Entity}
Definition: ElggUser.php:365
getGroups(array $options=[])
Gets the user's groups.
Definition: ElggUser.php:328
setLastLogin()
Sets the last logon time of the user to right now.
Definition: ElggUser.php:234
Could not register a new user for whatever reason.
Exception thrown if an argument is not of the expected type.
$owner_guid
elgg_get_config(string $name, $default=null)
Get an Elgg configuration value.
const ELGG_IGNORE_ACCESS
elgg_call() flags
Definition: constants.php:121
const ELGG_DISABLE_SYSTEM_LOG
Definition: constants.php:125
const ACCESS_PUBLIC
Definition: constants.php:12
if($who_can_change_language==='nobody') elseif($who_can_change_language==='admin_only' &&!elgg_is_admin_logged_in()) $options
Definition: language.php:20
$last_login
Definition: online.php:17
if($email instanceof \Elgg\Email) $object
Definition: body.php:24
$subject
HTML body of an email.
Definition: body.php:11
_elgg_services()
Get the global service provider.
Definition: elgglib.php:337
elgg_call(int $flags, Closure $closure)
Calls a callable autowiring the arguments using public DI services and applying logic based on flags.
Definition: elgglib.php:290
elgg_extract($key, $array, $default=null, bool $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:240
elgg_get_user_by_username(string $username, bool $try_email=false)
Get a user by username.
Definition: users.php:31
elgg_get_entities(array $options=[])
Fetches/counts entities or performs a calculation on their properties.
Definition: entities.php:507
$value
Definition: generic.php:51
$default
Definition: checkbox.php:30
elgg_register_event_handler(string $event, string $type, callable|string $callback, int $priority=500)
Helper functions for event handling.
Definition: events.php:48
setMetadata(string $name, mixed $value, string $value_type='', bool $multiple=false)
Set metadata on this entity.
Definition: Metadata.php:78
trait ProfileData
Adds methods to save profile data to an ElggEntity.
Definition: ProfileData.php:11
if(! $user||! $user->canEdit()) $password
if(parse_url(elgg_get_site_url(), PHP_URL_PATH) !=='/') if(file_exists(elgg_get_root_path() . 'robots.txt'))
Set robots.txt.
Definition: robots.php:10
elgg_get_logged_in_user_guid()
Return the current logged in user by guid.
Definition: sessions.php:34
$plugin
$purpose
Definition: record.php:16
$methods
Definition: subscribe.php:8
$action
Definition: subscribe.php:11
if($type !='user') $settings
Definition: save.php:16