usersTable->getRow($guid); } /** * Disables all of a user's entities * * @param int $owner_guid The owner GUID * * @return bool Depending on success */ function disable_user_entities($owner_guid) { return _elgg_services()->usersTable->disableEntities($owner_guid); } /** * Ban a user * * @param int $user_guid The user guid * @param string $reason A reason * * @return bool */ function ban_user($user_guid, $reason = "") { return _elgg_services()->usersTable->ban($user_guid, $reason); } /** * Unban a user. * * @param int $user_guid Unban a user. * * @return bool */ function unban_user($user_guid) { return _elgg_services()->usersTable->unban($user_guid); } /** * Makes user $guid an admin. * * @param int $user_guid User guid * * @return bool */ function make_user_admin($user_guid) { return _elgg_services()->usersTable->makeAdmin($user_guid); } /** * Removes user $guid's admin flag. * * @param int $user_guid User GUID * * @return bool */ function remove_user_admin($user_guid) { return _elgg_services()->usersTable->removeAdmin($user_guid); } /** * Get a user object from a GUID. * * This function returns an \ElggUser from a given GUID. * * @param int $guid The GUID * * @return \ElggUser|false */ function get_user($guid) { return _elgg_services()->entityTable->get($guid, 'user'); } /** * Get user by username * * @param string $username The user's username * * @return \ElggUser|false Depending on success */ function get_user_by_username($username) { return _elgg_services()->usersTable->getByUsername($username); } /** * Get user by persistent login password * * @param string $hash Hash of the persistent login password * * @return \ElggUser */ function get_user_by_code($hash) { return _elgg_services()->persistentLogin->getUserFromHash($hash); } /** * Get an array of users from an email address * * @param string $email Email address. * * @return array */ function get_user_by_email($email) { return _elgg_services()->usersTable->getByEmail($email); } /** * Return users (or the number of them) who have been active within a recent period. * * @param array $options Array of options with keys: * * seconds (int) => Length of period (default 600 = 10min) * limit (int) => Limit (default from settings) * offset (int) => Offset (default 0) * count (bool) => Return a count instead of users? (default false) * * Formerly this was the seconds parameter. * * @param int $limit Limit (deprecated usage, use $options) * @param int $offset Offset (deprecated usage, use $options) * @param bool $count Count (deprecated usage, use $options) * * @return \ElggUser[]|int */ function find_active_users($options = array(), $limit = 10, $offset = 0, $count = false) { return _elgg_services()->usersTable->findActive($options, $limit, $offset, $count); } /** * Generate and send a password request email to a given user's registered email address. * * @param int $user_guid User GUID * * @return bool */ function send_new_password_request($user_guid) { return _elgg_services()->passwords->sendNewPasswordRequest($user_guid); } /** * Low level function to reset a given user's password. * * This can only be called from execute_new_password_request(). * * @param int $user_guid The user. * @param string $password Text (which will then be converted into a hash and stored) * * @return bool */ function force_user_password_reset($user_guid, $password) { return _elgg_services()->passwords->forcePasswordReset($user_guid, $password); } /** * Validate and change password for a user. * * @param int $user_guid The user id * @param string $conf_code Confirmation code as sent in the request email. * @param string $password Optional new password, if not randomly generated. * * @return bool True on success */ function execute_new_password_request($user_guid, $conf_code, $password = null) { return _elgg_services()->passwords->executeNewPasswordReset($user_guid, $conf_code, $password); } /** * Generate a random 12 character clear text password. * * @return string */ function generate_random_cleartext_password() { return _elgg_services()->crypto->getRandomString(12, \ElggCrypto::CHARS_PASSWORD); } /** * Simple function which ensures that a username contains only valid characters. * * This should only permit chars that are valid on the file system as well. * * @param string $username Username * * @return bool * @throws RegistrationException on invalid */ function validate_username($username) { global $CONFIG; // Basic, check length if (!isset($CONFIG->minusername)) { $CONFIG->minusername = 4; } if (strlen($username) < $CONFIG->minusername) { $msg = elgg_echo('registration:usernametooshort', array($CONFIG->minusername)); throw new \RegistrationException($msg); } // username in the database has a limit of 128 characters if (strlen($username) > 128) { $msg = elgg_echo('registration:usernametoolong', array(128)); throw new \RegistrationException($msg); } // Blacklist for bad characters (partially nicked from mediawiki) $blacklist = '/[' . '\x{0080}-\x{009f}' . // iso-8859-1 control chars '\x{00a0}' . // non-breaking space '\x{2000}-\x{200f}' . // various whitespace '\x{2028}-\x{202f}' . // breaks and control chars '\x{3000}' . // ideographic space '\x{e000}-\x{f8ff}' . // private use ']/u'; if (preg_match($blacklist, $username)) { // @todo error message needs work throw new \RegistrationException(elgg_echo('registration:invalidchars')); } // Belts and braces // @todo Tidy into main unicode $blacklist2 = '\'/\\"*& ?#%^(){}[]~?<>;|¬`@+='; $blacklist2 = elgg_trigger_plugin_hook('username:character_blacklist', 'user', array('blacklist' => $blacklist2), $blacklist2); for ($n = 0; $n < strlen($blacklist2); $n++) { if (strpos($username, $blacklist2[$n]) !== false) { $msg = elgg_echo('registration:invalidchars', array($blacklist2[$n], $blacklist2)); $msg = htmlspecialchars($msg, ENT_QUOTES, 'UTF-8'); throw new \RegistrationException($msg); } } $result = true; return elgg_trigger_plugin_hook('registeruser:validate:username', 'all', array('username' => $username), $result); } /** * Simple validation of a password. * * @param string $password Clear text password * * @return bool * @throws RegistrationException on invalid */ function validate_password($password) { global $CONFIG; if (!isset($CONFIG->min_password_length)) { $CONFIG->min_password_length = 6; } if (strlen($password) < $CONFIG->min_password_length) { $msg = elgg_echo('registration:passwordtooshort', array($CONFIG->min_password_length)); throw new \RegistrationException($msg); } $result = true; return elgg_trigger_plugin_hook('registeruser:validate:password', 'all', array('password' => $password), $result); } /** * Simple validation of a email. * * @param string $address Email address * * @throws RegistrationException on invalid * @return bool */ function validate_email_address($address) { if (!is_email_address($address)) { throw new \RegistrationException(elgg_echo('registration:notemail')); } // Got here, so lets try a hook (defaulting to ok) $result = true; return elgg_trigger_plugin_hook('registeruser:validate:email', 'all', array('email' => $address), $result); } /** * Registers a user, returning false if the username already exists * * @param string $username The username of the new user * @param string $password The password * @param string $name The user's display name * @param string $email The user's email address * @param bool $allow_multiple_emails Allow the same email address to be * registered multiple times? * * @return int|false The new user's GUID; false on failure * @throws RegistrationException */ function register_user($username, $password, $name, $email, $allow_multiple_emails = false) { return _elgg_services()->usersTable->register($username, $password, $name, $email, $allow_multiple_emails); } /** * Generates a unique invite code for a user * * @param string $username The username of the user sending the invitation * * @return string Invite code * @see elgg_validate_invite_code */ function generate_invite_code($username) { return _elgg_services()->usersTable->generateInviteCode($username); } /** * Validate a user's invite code * * @param string $username The username * @param string $code The invite code * * @return bool * @see generate_invite_code * @since 1.10 */ function elgg_validate_invite_code($username, $code) { return _elgg_services()->usersTable->validateInviteCode($username, $code); } /** * Set the validation status for a user. * * @param int $user_guid The user's GUID * @param bool $status Validated (true) or unvalidated (false) * @param string $method Optional method to say how a user was validated * @return bool * @since 1.8.0 */ function elgg_set_user_validation_status($user_guid, $status, $method = '') { return _elgg_services()->usersTable->setValidationStatus($user_guid, $status, $method); } /** * Gets the validation status of a user. * * @param int $user_guid The user's GUID * @return bool|null Null means status was not set for this user. * @since 1.8.0 */ function elgg_get_user_validation_status($user_guid) { return _elgg_services()->usersTable->getValidationStatus($user_guid); } /** * Page handler for account related pages * * @param array $page_elements Page elements * @param string $handler The handler string * * @return bool * @access private */ function elgg_user_account_page_handler($page_elements, $handler) { $base_dir = elgg_get_root_path() . 'pages/account'; switch ($handler) { case 'login': require_once("$base_dir/login.php"); break; case 'forgotpassword': require_once("$base_dir/forgotten_password.php"); break; case 'changepassword': require_once("$base_dir/change_password.php"); break; case 'register': require_once("$base_dir/register.php"); break; default: return false; } return true; } /** * Sets the last action time of the given user to right now. * * @param int $user_guid The user GUID * * @return void */ function set_last_action($user_guid) { _elgg_services()->usersTable->setLastAction($user_guid); } /** * Sets the last logon time of the given user to right now. * * @param int $user_guid The user GUID * * @return void */ function set_last_login($user_guid) { _elgg_services()->usersTable->setLastLogin($user_guid); } /** * Creates a relationship between this site and the user. * * @param string $event create * @param string $object_type user * @param \ElggUser $object User object * * @return void * @access private */ function user_create_hook_add_site_relationship($event, $object_type, $object) { add_entity_relationship($object->getGUID(), 'member_of_site', elgg_get_site_entity()->guid); } /** * Serves the user's avatar * * @param string $hook * @param string $entity_type * @param string $returnvalue * @param array $params * @return string * @access private */ function user_avatar_hook($hook, $entity_type, $returnvalue, $params) { $user = $params['entity']; $size = $params['size']; if (isset($user->icontime)) { return "avatar/view/$user->username/$size/$user->icontime"; } else { return "_graphics/icons/user/default{$size}.gif"; } } /** * Setup the default user hover menu * @access private */ function elgg_user_hover_menu($hook, $type, $return, $params) { $user = elgg_extract('entity', $params); /* @var \ElggUser $user */ if (!$user instanceof \ElggUser) { return; } if (!elgg_is_logged_in()) { return; } if (elgg_get_logged_in_user_guid() == $user->guid) { $url = "profile/$user->username/edit"; $item = new \ElggMenuItem('profile:edit', elgg_echo('profile:edit'), $url); $item->setSection('action'); $return[] = $item; $url = "avatar/edit/$user->username"; $item = new \ElggMenuItem('avatar:edit', elgg_echo('avatar:edit'), $url); $item->setSection('action'); $return[] = $item; } // prevent admins from banning or deleting themselves if (elgg_get_logged_in_user_guid() == $user->guid) { return $return; } if (elgg_is_admin_logged_in()) { $actions = array(); if (!$user->isBanned()) { $actions[] = 'ban'; } else { $actions[] = 'unban'; } $actions[] = 'delete'; $actions[] = 'resetpassword'; if (!$user->isAdmin()) { $actions[] = 'makeadmin'; } else { $actions[] = 'removeadmin'; } foreach ($actions as $action) { $url = "action/admin/user/$action?guid={$user->guid}"; $url = elgg_add_action_tokens_to_url($url); $item = new \ElggMenuItem($action, elgg_echo($action), $url); $item->setSection('admin'); $item->setConfirmText(true); $return[] = $item; } $url = "profile/$user->username/edit"; $item = new \ElggMenuItem('profile:edit', elgg_echo('profile:edit'), $url); $item->setSection('admin'); $return[] = $item; $url = "avatar/edit/$user->username"; $item = new \ElggMenuItem('avatar:edit', elgg_echo('avatar:edit'), $url); $item->setSection('admin'); $return[] = $item; $url = "settings/user/$user->username"; $item = new \ElggMenuItem('settings:edit', elgg_echo('settings:edit'), $url); $item->setSection('admin'); $return[] = $item; $url = "activity/owner/$user->username"; $item = new \ElggMenuItem('activity:owner', elgg_echo('activity:owner'), $url); $item->setSection('action'); $return[] = $item; } return $return; } /** * Setup the menu shown with an entity * * @param string $hook * @param string $type * @param array $return * @param array $params * @return array * * @access private */ function elgg_users_setup_entity_menu($hook, $type, $return, $params) { if (elgg_in_context('widgets')) { return $return; } $entity = $params['entity']; if (!elgg_instanceof($entity, 'user')) { return $return; } /* @var \ElggUser $entity */ if ($entity->isBanned()) { $banned = elgg_echo('banned'); $options = array( 'name' => 'banned', 'text' => "$banned", 'href' => false, 'priority' => 0, ); $return = array(\ElggMenuItem::factory($options)); } else { $return = array(); $location = $entity->location; if (is_string($location) && $location !== '') { $location = htmlspecialchars($location, ENT_QUOTES, 'UTF-8', false); $options = array( 'name' => 'location', 'text' => "$location", 'href' => false, 'priority' => 150, ); $return[] = \ElggMenuItem::factory($options); } } return $return; } /** * This function loads a set of default fields into the profile, then triggers a hook letting other plugins to edit * add and delete fields. * * Note: This is a secondary system:init call and is run at a super low priority to guarantee that it is called after all * other plugins have initialised. * @access private */ function elgg_profile_fields_setup() { global $CONFIG; $profile_defaults = array ( 'description' => 'longtext', 'briefdescription' => 'text', 'location' => 'location', 'interests' => 'tags', 'skills' => 'tags', 'contactemail' => 'email', 'phone' => 'text', 'mobile' => 'text', 'website' => 'url', 'twitter' => 'text', ); $loaded_defaults = array(); $fieldlist = elgg_get_config('profile_custom_fields'); if ($fieldlist || $fieldlist === '0') { $fieldlistarray = explode(',', $fieldlist); foreach ($fieldlistarray as $listitem) { if ($translation = elgg_get_config("admin_defined_profile_{$listitem}")) { $type = elgg_get_config("admin_defined_profile_type_{$listitem}"); $loaded_defaults["admin_defined_profile_{$listitem}"] = $type; add_translation(get_current_language(), array("profile:admin_defined_profile_{$listitem}" => $translation)); } } } if (count($loaded_defaults)) { $CONFIG->profile_using_custom = true; $profile_defaults = $loaded_defaults; } $CONFIG->profile_fields = elgg_trigger_plugin_hook('profile:fields', 'profile', null, $profile_defaults); // register any tag metadata names foreach ($CONFIG->profile_fields as $name => $type) { if ($type == 'tags' || $type == 'location' || $type == 'tag') { elgg_register_tag_metadata_name($name); // register a tag name translation add_translation(get_current_language(), array("tag_names:$name" => elgg_echo("profile:$name"))); } } } /** * Avatar page handler * * /avatar/edit/ * /avatar/view/// * * @param array $page * @return bool * @access private */ function elgg_avatar_page_handler($page) { global $CONFIG; $user = get_user_by_username($page[1]); if ($user) { elgg_set_page_owner_guid($user->getGUID()); } if ($page[0] == 'edit') { require_once("{$CONFIG->path}pages/avatar/edit.php"); return true; } else { set_input('size', $page[2]); require_once("{$CONFIG->path}pages/avatar/view.php"); return true; } return false; } /** * Profile page handler * * @param array $page * @return bool * @access private */ function elgg_profile_page_handler($page) { global $CONFIG; $user = get_user_by_username($page[0]); elgg_set_page_owner_guid($user->guid); if ($page[1] == 'edit') { require_once("{$CONFIG->path}pages/profile/edit.php"); return true; } return false; } /** * Sets up user-related menu items * * @return void * @access private */ function users_pagesetup() { $owner = elgg_get_page_owner_entity(); $viewer = elgg_get_logged_in_user_entity(); if ($owner) { elgg_register_menu_item('page', array( 'name' => 'edit_avatar', 'href' => "avatar/edit/{$owner->username}", 'text' => elgg_echo('avatar:edit'), 'section' => '1_profile', 'contexts' => array('settings'), )); elgg_register_menu_item('page', array( 'name' => 'edit_profile', 'href' => "profile/{$owner->username}/edit", 'text' => elgg_echo('profile:edit'), 'section' => '1_profile', 'contexts' => array('settings'), )); } // topbar if ($viewer) { elgg_register_menu_item('topbar', array( 'name' => 'usersettings', 'href' => "settings/user/{$viewer->username}", 'text' => elgg_view_icon('settings') . elgg_echo('settings'), 'priority' => 500, 'section' => 'alt', )); elgg_register_menu_item('topbar', array( 'name' => 'logout', 'href' => "action/logout", 'text' => elgg_echo('logout'), 'is_action' => true, 'priority' => 1000, 'section' => 'alt', )); } } /** * Users initialisation function, which establishes the page handler * * @return void * @access private */ function users_init() { elgg_register_page_handler('register', 'elgg_user_account_page_handler'); elgg_register_page_handler('forgotpassword', 'elgg_user_account_page_handler'); elgg_register_page_handler('changepassword', 'elgg_user_account_page_handler'); elgg_register_page_handler('login', 'elgg_user_account_page_handler'); elgg_register_page_handler('avatar', 'elgg_avatar_page_handler'); elgg_register_page_handler('profile', 'elgg_profile_page_handler'); elgg_register_plugin_hook_handler('register', 'menu:user_hover', 'elgg_user_hover_menu'); elgg_register_action('register', '', 'public'); elgg_register_action('useradd', '', 'admin'); elgg_register_action('avatar/upload'); elgg_register_action('avatar/crop'); elgg_register_action('avatar/remove'); elgg_register_action('profile/edit'); elgg_register_plugin_hook_handler('entity:icon:url', 'user', 'user_avatar_hook'); elgg_register_action('user/changepassword', '', 'public'); elgg_register_action('user/requestnewpassword', '', 'public'); // Register the user type elgg_register_entity_type('user', ''); elgg_register_plugin_hook_handler('register', 'menu:entity', 'elgg_users_setup_entity_menu', 501); elgg_register_event_handler('create', 'user', 'user_create_hook_add_site_relationship'); } /** * Runs unit tests for \ElggUser * * @param string $hook unit_test * @param string $type system * @param mixed $value Array of tests * @param mixed $params Params * * @return array * @access private */ function users_test($hook, $type, $value, $params) { global $CONFIG; $value[] = "{$CONFIG->path}engine/tests/ElggUserTest.php"; return $value; } return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) { $events->registerHandler('init', 'system', 'users_init', 0); $events->registerHandler('init', 'system', 'elgg_profile_fields_setup', 10000); // Ensure this runs after other plugins $events->registerHandler('pagesetup', 'system', 'users_pagesetup', 0); $hooks->registerHandler('unit_test', 'system', 'users_test'); };