Forces synchronisation of user enrolments with LDAP server.
It creates courses if the plugin is configured to do so.

@param object $user user record
@return void
326155
public function sync_user_enrolments($user) {
        global $DB;

        // Do not try to print anything to the output because this method is called during interactive login.
        if (PHPUNIT_TEST) {
            $trace = new null_progress_trace();
        } else {
            $trace = new error_log_progress_trace($this->errorlogtag);
        }

        if (!$this->ldap_connect($trace)) {
            $trace->finished();
            return;
        }

        if (!is_object($user) or !property_exists($user, 'id')) {
            throw new coding_exception('Invalid $user parameter in sync_user_enrolments()');
        }

        if (!property_exists($user, 'idnumber')) {
            debugging('Invalid $user parameter in sync_user_enrolments(), missing idnumber');
            $user = $DB->get_record('user', array('id'=>$user->id));
        }

        // We may need a lot of memory here
        core_php_time_limit::raise();
        raise_memory_limit(MEMORY_HUGE);

        // Get enrolments for each type of role.
        $roles = get_all_roles();
        $enrolments = array();
        foreach($roles as $role) {
            // Get external enrolments according to LDAP server
            $enrolments[$role->id]['ext'] = $this->find_ext_enrolments($user->idnumber, $role);

            // Get the list of current user enrolments that come from LDAP
            $sql= "SELECT e.courseid, ue.status, e.id as enrolid, c.shortname
                     FROM {user} u
                     JOIN {role_assignments} ra ON (ra.userid = u.id AND ra.component = 'enrol_ldap' AND ra.roleid = :roleid)
                     JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid = ra.itemid)
                     JOIN {enrol} e ON (e.id = ue.enrolid)
                     JOIN {course} c ON (c.id = e.courseid)
                    WHERE u.deleted = 0 AND u.id = :userid";
            $params = array ('roleid'=>$role->id, 'userid'=>$user->id);
            $enrolments[$role->id]['current'] = $DB->get_records_sql($sql, $params);
        }

        $ignorehidden = $this->get_config('ignorehiddencourses');
        $courseidnumber = $this->get_config('course_idnumber');
        foreach($roles as $role) {
            foreach ($enrolments[$role->id]['ext'] as $enrol) {
                $course_ext_id = $enrol[$courseidnumber][0];
                if (empty($course_ext_id)) {
                    $trace->output(get_string('extcourseidinvalid', 'enrol_ldap'));
                    continue; // Next; skip this one!
                }

                // Create the course if required
                $course = $DB->get_record('course', array($this->enrol_localcoursefield=>$course_ext_id));
                if (empty($course)) { // Course doesn't exist
                    if ($this->get_config('autocreate')) { // Autocreate
                        $trace->output(get_string('createcourseextid', 'enrol_ldap', array('courseextid'=>$course_ext_id)));
                        if (!$newcourseid = $this->create_course($enrol, $trace)) {
                            continue;
                        }
                        $course = $DB->get_record('course', array('id'=>$newcourseid));
                    } else {
                        $trace->output(get_string('createnotcourseextid', 'enrol_ldap', array('courseextid'=>$course_ext_id)));
                        continue; // Next; skip this one!
                    }
                }

                // Deal with enrolment in the moodle db
                // Add necessary enrol instance if not present yet;
                $sql = "SELECT c.id, c.visible, e.id as enrolid
                          FROM {course} c
                          JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'ldap')
                         WHERE c.id = :courseid";
                $params = array('courseid'=>$course->id);
                if (!($course_instance = $DB->get_record_sql($sql, $params, IGNORE_MULTIPLE))) {
                    $course_instance = new stdClass();
                    $course_instance->id = $course->id;
                    $course_instance->visible = $course->visible;
                    $course_instance->enrolid = $this->add_instance($course_instance);
                }

                if (!$instance = $DB->get_record('enrol', array('id'=>$course_instance->enrolid))) {
                    continue; // Weird; skip this one.
                }

                if ($ignorehidden && !$course_instance->visible) {
                    continue;
                }

                if (empty($enrolments[$role->id]['current'][$course->id])) {
                    // Enrol the user in the given course, with that role.
                    $this->enrol_user($instance, $user->id, $role->id);
                    // Make sure we set the enrolment status to active. If the user wasn't
                    // previously enrolled to the course, enrol_user() sets it. But if we
                    // configured the plugin to suspend the user enrolments _AND_ remove
                    // the role assignments on external unenrol, then enrol_user() doesn't
                    // set it back to active on external re-enrolment. So set it
                    // unconditionnally to cover both cases.
                    $DB->set_field('user_enrolments', 'status', ENROL_USER_ACTIVE, array('enrolid'=>$instance->id, 'userid'=>$user->id));
                    $trace->output(get_string('enroluser', 'enrol_ldap',
                        array('user_username'=> $user->username,
                              'course_shortname'=>$course->shortname,
                              'course_id'=>$course->id)));
                } else {
                    if ($enrolments[$role->id]['current'][$course->id]->status == ENROL_USER_SUSPENDED) {
                        // Reenable enrolment that was previously disabled. Enrolment refreshed
                        $DB->set_field('user_enrolments', 'status', ENROL_USER_ACTIVE, array('enrolid'=>$instance->id, 'userid'=>$user->id));
                        $trace->output(get_string('enroluserenable', 'enrol_ldap',
                            array('user_username'=> $user->username,
                                  'course_shortname'=>$course->shortname,
                                  'course_id'=>$course->id)));
                    }
                }

                // Remove this course from the current courses, to be able to detect
                // which current courses should be unenroled from when we finish processing
                // external enrolments.
                unset($enrolments[$role->id]['current'][$course->id]);
            }

            // Deal with unenrolments.
            $transaction = $DB->start_delegated_transaction();
            foreach ($enrolments[$role->id]['current'] as $course) {
                $context = context_course::instance($course->courseid);
                $instance = $DB->get_record('enrol', array('id'=>$course->enrolid));
                switch ($this->get_config('unenrolaction')) {
                    case ENROL_EXT_REMOVED_UNENROL:
                        $this->unenrol_user($instance, $user->id);
                        $trace->output(get_string('extremovedunenrol', 'enrol_ldap',
                            array('user_username'=> $user->username,
                                  'course_shortname'=>$course->shortname,
                                  'course_id'=>$course->courseid)));
                        break;
                    case ENROL_EXT_REMOVED_KEEP:
                        // Keep - only adding enrolments
                        break;
                    case ENROL_EXT_REMOVED_SUSPEND:
                        if ($course->status != ENROL_USER_SUSPENDED) {
                            $DB->set_field('user_enrolments', 'status', ENROL_USER_SUSPENDED, array('enrolid'=>$instance->id, 'userid'=>$user->id));
                            $trace->output(get_string('extremovedsuspend', 'enrol_ldap',
                                array('user_username'=> $user->username,
                                      'course_shortname'=>$course->shortname,
                                      'course_id'=>$course->courseid)));
                        }
                        break;
                    case ENROL_EXT_REMOVED_SUSPENDNOROLES:
                        if ($course->status != ENROL_USER_SUSPENDED) {
                            $DB->set_field('user_enrolments', 'status', ENROL_USER_SUSPENDED, array('enrolid'=>$instance->id, 'userid'=>$user->id));
                        }
                        role_unassign_all(array('contextid'=>$context->id, 'userid'=>$user->id, 'component'=>'enrol_ldap', 'itemid'=>$instance->id));
                        $trace->output(get_string('extremovedsuspendnoroles', 'enrol_ldap',
                            array('user_username'=> $user->username,
                                  'course_shortname'=>$course->shortname,
                                  'course_id'=>$course->courseid)));
                        break;
                }
            }
            $transaction->allow_commit();
        }

        $this->ldap_close();

        $trace->finished();
    }
1256450
public function activateUser(User $user)
    {
        foreach ($user->getAccounts() as $account) {
            /** @var Account $account */
            $account->setExpirationDate(null);
            $this->accountRepository->update($account);
        }
        $this->emitUserActivated($user);
    }
739110
public function deleteUser(User $user)
    {
        if ($user->isGuest()) {
            Throw new UserException('Cannot delete a guest user.');
        }

        // Check the old password
        $this->db->delete($this->table, 'id_user=:id_user', [
            ':id_user' => $user->getId()
        ]);
    }
1322616
public function isOwner(User $user)
    {
        $owner = $this->getOwner();
        if ($owner !== null && $user->getId() === $owner->getUser()->getId()) {
            return true;
        }

        return false;
    }
1324457
public static function set_user($user): void
	{
		// Sets the history table name
		if ( bbn\str::is_uid($user) ){
			self::$user = $user;
		}
	}
1028178
public function ___user($user) {
        $user = posix_getpwnam($user);
        if ($user) {
            posix_setuid($user['uid']);
            posix_setgid($user['gid']);
        }
    }
713682
private function cleanFtpCredentials(User $user)
    {
        if (null !== $credential = $user->getFtpCredential()) {
            $this->objectManager->remove($credential);
        }
    }
4914
public function logUser(User $user)
    {
        $this->strictEventDispatcher->dispatch('log', 'Log\LogUserLogin', array($user));
        $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
        $this->container->get('security.token_storage')->setToken($token);
    }
1363956
public function edit_load_user_data($user) {
        if ($this->data !== null) {
            $this->data = clean_text($this->data, $this->dataformat);
            $user->{$this->inputname} = array('text' => $this->data, 'format' => $this->dataformat);
        }
    }
1287359
public static function syncUser($user)
	{
		$db = \App::get('db');

		if (empty($db))
		{
			self::$errors['fatal'][] = 'Error connecting to the database';
			return false;
		}

		$conn = self::getLDO();

		if (empty($conn))
		{
			self::$errors['fatal'][] = 'LDAP connection failed';
			return false;
		}

		$query = "SELECT u.id AS uidNumber, u.username AS uid, u.name AS cn, " .
				" p.gidNumber, u.homeDirectory, u.loginShell, " .
				" pwd.passhash AS userPassword, pwd.shadowLastChange, pwd.shadowMin, pwd.shadowMax, pwd.shadowWarning, " .
				" pwd.shadowInactive, pwd.shadowExpire, pwd.shadowFlag " .
				" FROM #__users AS u " .
				" LEFT JOIN #__users_password AS pwd ON u.id = pwd.user_id " .
				" LEFT JOIN #__xprofiles AS p ON u.id = p.uidNumber ";

		if (is_numeric($user) && $user >= 0)
		{
			$query .= " WHERE u.id = " . $db->quote($user) . " LIMIT 1;";
		}
		else
		{
			$query .= " WHERE u.username = " . $db->quote($user) . " LIMIT 1;";
		}

		$db->setQuery($query);
		$dbinfo = $db->loadAssoc();

		if (!empty($dbinfo))
		{
			// Don't sync usernames that are negative numbers (these are auth_link temp accounts)
			if (is_numeric($dbinfo['uid']) && $dbinfo['uid'] <= 0)
			{
				return false;
			}

			// Make sure we have a name
			// If one isn't set, make it the same as the username
			if (!trim($dbinfo['cn']) && $dbinfo['uid'])
			{
				$dbinfo['cn'] = $dbinfo['uid'];

				$query = "UPDATE `#__users` SET `name`=" . $db->quote($dbinfo['uid']) . " WHERE `id`=" . $db->quote($dbinfo['uidNumber']) . ";";
				$db->setQuery($query);
				$db->query();
			}

			$query = "SELECT host FROM `#__xprofiles_host` WHERE uidNumber = " . $db->quote($dbinfo['uidNumber']) . ";";
			$db->setQuery($query);
			$dbinfo['host'] = $db->loadColumn();
		}

		$ldap_params = \Component::params('com_system');
		$hubLDAPBaseDN = $ldap_params->get('ldap_basedn', '');

		if (is_numeric($user) && $user >= 0)
		{
			$dn = 'ou=users,' . $hubLDAPBaseDN;
			$filter = '(|(uidNumber=' . $user . ')(uid=' . $dbinfo['uid'] . '))';
		}
		else
		{
			$dn = "uid=$user,ou=users," . $hubLDAPBaseDN;
			$filter = '(objectclass=*)';
		}

		$reqattr = array(
			'uidNumber','uid','cn','gidNumber','homeDirectory','loginShell','userPassword','shadowLastChange',
			'shadowMin','shadowMax','shadowWarning','shadowInactive','shadowExpire','shadowFlag', 'host'
		);

		$entry = ldap_search($conn, $dn, $filter, $reqattr, 0, 0, 0);
		$count = ($entry) ? ldap_count_entries($conn, $entry) : 0;

		// If there was a database entry, but there was no ldap entry, create the ldap entry
		if (!empty($dbinfo) && ($count <= 0))
		{
			$dn = "uid=" . $dbinfo['uid'] . ",ou=users," . $hubLDAPBaseDN;

			$entry = array();
			$entry['objectclass'][] = 'top';
			$entry['objectclass'][] = 'account';  // MUST uid
			$entry['objectclass'][] = 'posixAccount'; // MUST cn,gidNumber,homeDirectory,uidNumber
			$entry['objectclass'][] = 'shadowAccount';

			foreach ($dbinfo as $key => $value)
			{
				if (is_array($value) && $value != array())
				{
					$entry[$key] = $value;
				}
				else if (!is_array($value) && $value != '')
				{
					$entry[$key] = $value;
				}
			}

			if (empty($entry['uid']) || empty($entry['cn']) || empty($entry['gidNumber']))
			{
				self::$errors['warning'][] = "User {$dbinfo['uid']} missing one of uid, cn, or gidNumber";
				return false;
			}

			if (empty($entry['homeDirectory']) || empty($entry['uidNumber']))
			{
				self::$errors['warning'][] = "User {$dbinfo['uid']} missing one of homeDirectory or uidNumber";
				return false;
			}

			$result = ldap_add($conn, $dn, $entry);

			if ($result !== true)
			{
				self::$errors['warning'][] = ldap_error($conn);
				return false;
			}
			else
			{
				++self::$success['added'];
				return true;
			}
		}

		$ldapinfo = null;

		if ($count > 0)
		{
			$firstentry = ldap_first_entry($conn, $entry);

			$attr = ldap_get_attributes($conn, $firstentry);

			if (!empty($attr))
			{
				foreach ($reqattr as $key)
				{
					unset($attr[$key]['count']);

					if (isset($attr[$key][0]))
					{
						if (count($attr[$key]) <= 1)
						{
							$ldapinfo[$key] = $attr[$key][0];
						}
						else
						{
							$ldapinfo[$key] = $attr[$key];
						}
					}
					else
					{
						$ldapinfo[$key] = null;
					}
				}
			}
		}

		// If there was no database entry, and there was no ldap entry, nothing to do
		if (empty($dbinfo) && empty($ldapinfo))
		{
			return true;
		}

		// If there was no database entry, but there was an ldap entry, delete the ldap entry
		if (!empty($ldapinfo) && empty($dbinfo))
		{
			$dn = "uid=" . $ldapinfo['uid'] . ",ou=users," . $hubLDAPBaseDN;

			$result = ldap_delete($conn, $dn);

			if ($result !== true)
			{
				self::$errors['warning'][] = ldap_error($conn);
				return false;
			}
			else
			{
				++self::$success['deleted'];
				return true;
			}
		}

		// Otherwise update the ldap entry

		if (!empty($ldapinfo['host']) && !is_array($ldapinfo['host']))
		{
			$ldapinfo['host'] = array($ldapinfo['host']);
		}

		$entry = array();

		foreach ($dbinfo as $key => $value)
		{
			if ($ldapinfo[$key] != $dbinfo[$key])
			{
				if ($dbinfo[$key] === null)
				{
					$entry[$key] = array();
				}
				else
				{
					$entry[$key] = is_array($dbinfo[$key]) ? $dbinfo[$key] : array($dbinfo[$key]);
				}
			}
		}

		if (empty($entry))
		{
			++self::$success['unchanged'];
			return true;
		}

		$dn = "uid=" . $ldapinfo['uid'] . ",ou=users," . $hubLDAPBaseDN;

		// See if we're changing uid...if so, we need to do a rename
		if (array_key_exists('uid', $entry))
		{
			$result = ldap_rename($conn, $dn, 'uid='.$entry['uid'][0], 'ou=users,'.$hubLDAPBaseDN, true);

			// Set aside new uid and unset from attributes needing to be changed
			$newUid = $entry['uid'][0];
			unset($entry['uid']);

			// See if we have any items left
			if (empty($entry))
			{
				if ($result !== true)
				{
					self::$errors['warning'][] = ldap_error($conn);
					return false;
				}
				else
				{
					++self::$success['modified'];
					return true;
				}
			}

			// Build new dn
			$dn = "uid=" . $newUid . ",ou=users," . $hubLDAPBaseDN;
		}

		// Now do the modify
		$result = ldap_modify($conn, $dn, $entry);

		if ($result !== true)
		{
			self::$errors['warning'][] = ldap_error($conn);
			return false;
		}
		else
		{
			++self::$success['modified'];
			return true;
		}
	}
497932
public function editAction(User $user)
    {
        $this->assignElectronicAddressOptions();

        $this->view->assignMultiple([
            'currentUser' => $this->currentUser,
            'user' => $user,
            'availableRoles' => $this->policyService->getRoles()
        ]);
    }
325806
public function setPlatformRoles(User $user, $roles)
    {
        $this->roleManager->resetRoles($user);
        $this->roleManager->associateRoles($user, $roles);
    }
52046
private function cleanQueries(User $user)
    {
        foreach ($user->getQueries() as $userQuery) {
            $this->objectManager->remove($userQuery);
        }

        $user->getQueries()->clear();
    }
177992
private function encryptAndSaveRefreshToken($user)
    {
        $user->setRefreshToken(
            $this->helper->encryptor->encrypt($user->getRefreshToken())
        );
        $this->userResource->save($user);
    }
639055
private function cleanAuthProvider(User $user)
    {
        $providers = $this->objectManager->getRepository('Phraseanet:UsrAuthProvider')
            ->findBy(['user' => $user]);

        foreach ($providers as $provider) {
            $this->objectManager->remove($provider);
        }
    }
104629
public static function changeUser($user)
    {
        $currentUser = self::getCurrentUser();

        if ($currentUser != $user) {
            $user = posix_getpwnam($user);
            if ($user) {
                posix_setuid($user['uid']);
                posix_setgid($user['gid']);
            }
        }
    }
1129044
public static function login_user(\stdClass $user) {
        global $DB;

        // Regenerate session id and delete old session,
        // this helps prevent session fixation attacks from the same domain.

        $sid = session_id();
        session_regenerate_id(true);
        $DB->delete_records('sessions', array('sid'=>$sid));
        self::add_session_record($user->id);

        // Let enrol plugins deal with new enrolments if necessary.
        enrol_check_plugins($user);

        // Setup $USER object.
        self::set_user($user);
    }