123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802 |
- <?php
- /**
- * Elgg users
- * Functions to manage multiple or single users in an Elgg install
- *
- * @package Elgg.Core
- * @subpackage DataModel.User
- */
- /**
- * Return the user specific details of a user by a row.
- *
- * @param int $guid The \ElggUser guid
- *
- * @return mixed
- * @access private
- */
- function get_user_entity_as_row($guid) {
- return _elgg_services()->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' => "<span>$banned</span>",
- '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' => "<span>$location</span>",
- '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/<username>
- * /avatar/view/<username>/<size>/<icontime>
- *
- * @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');
- };
|