Skip to content
Snippets Groups Projects
user.php 77.2 KiB
Newer Older
<?php
/**
 * user.php - controller class for the user-administration
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * @author      Nico Müller <nico.mueller@uni-oldenburg.de>
 * @author      Michael Riehemann <michael.riehemann@uni-oldenburg.de>
 * @author      David Siegfried <david.siegfried@uni-vechta.de>
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
 * @category    Stud.IP
 * @package     admin
 * @since       2.1
 */
require_once 'vendor/email_message/blackhole_message.php';
require_once 'lib/statusgruppe.inc.php';

/**
 *
 * controller class for the user-administration
 *
 */
class Admin_UserController extends AuthenticatedController
{
    protected $_autobind = true;
    /**
     * Common tasks for all actions.
     */
    public function before_filter(&$action, &$args)
    {
        parent::before_filter($action, $args);

        // user must have root permission if restricted user management is disabled
        $GLOBALS['perm']->check(Config::get()->RESTRICTED_USER_MANAGEMENT ? 'root' : 'admin');

        // set navigation
        Navigation::activateItem('/admin/user/index');

        //PageLayout
        PageLayout::setHelpKeyword("Admins.Benutzerkonten");
        PageLayout::setTitle(_("Personenverwaltung"));

        $this->action = $action;
        $this->args   = $args;

        NotificationCenter::addObserver($this, 'addSidebar', 'SidebarWillRender');
    }

    /**
     * Display searchbox and all searched users (if any).
     *
     * @param bool $advanced open or close the advanced searchfields
     */
    public function index_action($advanced = false)
    {
        $this->perm = $GLOBALS['perm'];
        //Datafields
        $this->datafields = [];
        $datafields = DataField::getDataFields("user");
        foreach ($datafields as $datafield) {
            if ($datafield->accessAllowed()) {
                $this->datafields[] = $datafield;
            }
        }

        // roles
        $this->roles = array_filter(RolePersistence::getAllRoles(), function($role) {
            return !$role->systemtype;
        });

        //Daten annehmen
        if (Request::submitted('reset')) {
            unset($_SESSION['admin']['user']);
        } elseif (Request::submitted('search')) {
            $request = iterator_to_array(Request::getInstance());

            // Inaktivität für die suche anpassen
            $inaktiv = [$request['inaktiv'], $request['inaktiv_tage']];
            if (empty($request['inaktiv_tage']) && $request['inaktiv'] != 'nie') {
                $inaktiv = null;
            }

            //suche mit datafields
            foreach ($this->datafields as $datafield) {
                if (!empty($request[$datafield->id])
                    && !(in_array($datafield->type, words('selectbox radio')) && $request[$datafield->id] === '---ignore---')
                ) {
                    $search_datafields[$datafield->id] = trim($request[$datafield->id]);
            $request['username']   = trim($request['username']);
            $request['email']      = trim($request['email']);
            $request['vorname']    = trim($request['vorname']);
            $request['nachname']   = trim($request['nachname']);
            $request['inaktiv']    = $inaktiv;
            $request['datafields'] = $search_datafields;

            $_SESSION['admin']['user'] = $request;
        } elseif (!empty($_SESSION['admin']['user']['results'])) {
            //Suchparameter und Ergebnisse vorhanden
            $request = $_SESSION['admin']['user'];
        }

        $this->request = [];
        $this->users = [];

        //wenn suche durchgeführt
        if (!empty($request)) {
            //Suchparameter
            $this->sortby = Request::option('sortby', 'username');
            $this->order  = Request::option('order', 'asc');
            if (Request::int('toggle')) {
                $this->order = $this->order == 'desc' ? 'asc' : 'desc';
            }

            $request['sortby'] = $this->sortby;
            $request['order'] = $this->order;

            $empty_search          = $request['perm'] === 'alle';

            $values = [
                'username',
                'vorname',
                'nachname',
                'email',
                'inaktiv',
                'locked',
                'show_only_not_lectures',
                'datafields',
                'inaktiv_tage',
                'institute',
                'studycourse',
                'degree',
                'fachsem',
                'userdomains',
                'auth_plugins',
            ];
            foreach ($values as $value) {
                if (!empty($request[$value])) {
                    $empty_search = false;
                    break;
                }
            }
            //Daten abrufen
            $this->request = $request;
            $this->users   = $empty_search ? false : User::search($request);

            // Fehler abfangen
            if ($this->users === false) {
                PageLayout::postInfo(_('Sie haben keine Suchkriterien ausgewählt!'));
            } elseif (count($this->users) < 1 && Request::submitted('search')) {
                PageLayout::postInfo(_('Es wurden keine Personen mit diesen Suchkriterien gefunden.'));
            } else {
                $_SESSION['admin']['user']['results'] = true;
                PageLayout::postInfo(sprintf(_('Es wurden %s Personen mit diesen Suchkriterien gefunden.'), count($this->users)));
            }
            if (is_array($this->users) && Request::submitted('export')) {
                $tmpname  = md5(uniqid('tmp'));
                $captions = ['username',
                             'vorname',
                             'nachname',
                             'email',
                             'status',
                             'authentifizierung',
                             'domänen',
                             'registriert seit',
                             'inaktiv seit'];
                foreach ($this->datafields as $datafield) {
                    $captions[] = $datafield->name;
                }
                $mapper   = function ($u) {
                    $userdomains = array_map(function ($ud) {
                        return $ud->name;
                    }, UserDomain::getUserDomainsForUser($u->id));
                        $u['username'],
                        $u['Vorname'],
                        $u['Nachname'],
                        $u['Email'],
                        $u['perms'],
                        $u['auth_plugin'],
                        join(';', $userdomains),
                        $u['mkdate'] ? strftime('%x', $u['mkdate']) : '',
                        $u->online->last_lifesign ? strftime('%x', $u->online->last_lifesign) : ''
                    ];
                    foreach ($this->datafields as $datafield) {
                        $df = new DatafieldEntryModel(
                            [
                                $datafield->id,
                                $u['user_id'],
                                '',
                                ''
                            ]);
                        $data[] = $df->getTypedDatafield()->getDisplayValue(false);
                    }
                    return $data;
                };
                if (array_to_csv(array_map($mapper, $this->users), $GLOBALS['TMP_PATH'] . '/' . $tmpname, $captions)) {
                    $this->redirect(
                        FileManager::getDownloadURLForTemporaryFile(
                            $tmpname,
                            'nutzer-export.csv'
                        )
                    );
                }
            }
        }

        $this->degrees      = Abschluss::findBySQL('1 order by name');
        $this->studycourses = Fach::findBySQL('1 order by name');
        $this->userdomains  = UserDomain::getUserDomains();
        $this->institutes   = Institute::getInstitutes();
        foreach ($GLOBALS['STUDIP_AUTH_PLUGIN'] as $ap) {
            $this->available_auth_plugins[mb_strtolower($ap)] = $ap;
        }

        //show datafields search
        if ($advanced
            || !empty($search_datafields)
            || (!empty($request)
Moritz Strohm's avatar
Moritz Strohm committed
                && (!empty($request['auth_plugins']) || !empty($request['userdomains']) || !empty($request['degree']) ||
                    !empty($request['institute']) || !empty($request['studycourse']) || !empty($request['show_only_not_lectures']) || !empty($request['roles']))
            )
        ) {
            $this->advanced = true;
        }
    }

    /**
     * Bulk action (delete users or send message to all)
     */
    public function bulk_action($user_id = null)
    {
        $action = Request::option('method');

        if ($action === 'delete') {
            PageLayout::setTitle(_('Folgende Nutzer löschen'));
            if ($user_id) {
                $this->users = [User::find($user_id)];
            } else {
                $this->users = User::findMany(Request::getArray('user_ids'));
            }
            $this->render_template('admin/user/_delete.php');
            return;
        } elseif ($action === 'send_message') {
            $users = User::findMany(Request::getArray('user_ids'));

            if ($users) {
                $users = new SimpleCollection($users);
                $users = $users->pluck('username');
            }

            $_SESSION['sms_data']          = [];
            $_SESSION['sms_data']['p_rec'] = array_filter($users);
            $this->redirect(URLHelper::getURL('dispatch.php/messages/write', ['default_subject' => '', 'tmpsavesnd' => 1]));
            return;
        }
        $this->relocate('admin/user');
    }

    /**
     * Deleting one or more users
     *
     * @param string $user_id
     * @param string $parent redirect to this page after deleting users
     */
    public function delete_action($user_id = null, $parent = '')
    {
        $delete_documents           = (bool) Request::int('documents');
        $delete_content_from_course = (bool) Request::int('coursecontent');
        $delete_personal_documents  = (bool) Request::int('personaldocuments');
        $delete_personal_content    = (bool) Request::int('personalcontent');
        $delete_names               = (bool) Request::int('personalnames');
        $delete_memberships         = (bool) Request::int('memberships');

        //deleting one user
        if (!is_null($user_id)) {
            $user = User::find($user_id);

            //check user
            if (!count($user)) {
                PageLayout::postError(_('Fehler! Zu löschende Person ist nicht vorhanden.'));
                //antwort ja
            } elseif (!empty($user) && Request::submitted('delete')) {
                CSRFProtection::verifyUnsafeRequest();

                //if deleting user, go back to mainpage
                $parent = '';

                //deactivate message
                if (!Request::int('mail')) {
                    $dev_null       = new blackhole_message_class();
                    $default_mailer = StudipMail::getDefaultTransporter();
                    StudipMail::setDefaultTransporter($dev_null);
                }
                //preparing delete
                $umanager = new UserManagement();
                $umanager->getFromDatabase($user_id);

                //delete
                if ($umanager->deleteUser($delete_documents, $delete_content_from_course, $delete_personal_documents, $delete_personal_content, $delete_names, $delete_memberships)) {
                    $details = explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($umanager->msg, 0, -1)));
                    PageLayout::postSuccess(htmlReady(sprintf(_('"%s (%s)" wurde erfolgreich gelöscht.'), $user->getFullName(), $user->username)), $details);
                } else {
                    $details = explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($umanager->msg, 0, -1)));
                    PageLayout::postError(htmlReady(sprintf(_('Fehler! "%s (%s)" konnte nicht gelöscht werden.'), $user->getFullName(), $user->username)), $details);
                }

                //reavtivate messages
                if (!Request::int('mail') && isset($default_mailer)) {
                    StudipMail::setDefaultTransporter($default_mailer);
                }

                //sicherheitsabfrage
            } elseif (!empty($user) && !Request::submitted('back')) {

                $this->flash['delete'] = [
                    'question' => sprintf(_('Wollen Sie "%s (%s)" wirklich löschen?'), $user->getFullName(), $user->username),
                    'action'   => ($parent != '') ? $this->url_for('admin/user/delete/' . $user_id . '/' . $parent) : $this->url_for('admin/user/delete/' . $user_id),
                ];
            }

            //deleting more users
        } else {
            $user_ids = Request::getArray('user_ids');

            if (count($user_ids) == 0) {
                PageLayout::postError(_('Bitte wählen Sie mindestens eine Person zum Löschen aus.'));
                $this->redirect('admin/user/' . $parent);
                return;
            }

            if (Request::submitted('delete')) {
                CSRFProtection::verifyUnsafeRequest();

                //deactivate message
                if (!Request::int('mail')) {
                    $dev_null       = new blackhole_message_class();
                    $default_mailer = StudipMail::getDefaultTransporter();
                    StudipMail::setDefaultTransporter($dev_null);
                }

                foreach ($user_ids as $i => $_user_id) {
                    $users[$i] = User::find($_user_id);
                    //preparing delete
                    $umanager = new UserManagement();
                    $umanager->getFromDatabase($_user_id);

                    //delete
                    if ($umanager->deleteUser($delete_documents, $delete_content_from_course, $delete_personal_documents, $delete_personal_content, $delete_names, $delete_memberships)) {
                        $details = explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($umanager->msg, 0, -1)));
                        PageLayout::postSuccess(htmlReady(sprintf(_('"%s (%s)" wurde erfolgreich gelöscht'), $users[$i]->getFullName(), $users[$i]->username)), $details);
                    } else {
                        $details = explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($umanager->msg, 0, -1)));
                        PageLayout::postError(htmlReady(sprintf(_('Fehler! "%s (%s)" konnte nicht gelöscht werden'), $users[$i]->getFullName(), $users[$i]->username)), $details);
                    }
                }

                //reactivate messages
                if (!Request::int('mail') && isset($default_mailer)) {
                    StudipMail::setDefaultTransporter($default_mailer);
                }

            }
        }

        //liste wieder anzeigen
        if ($parent == 'edit') {
            $this->redirect('admin/user/edit/' . $user_id);
        } else {
            $this->redirect('admin/user/' . $parent);
        }
    }



    /**
     * Display all information according to the selected user. All details can
     * be changed and deleted.
     *
     * @param string $user_id
     */
    public function edit_action($user_id = null)
    {
        //check submitted user_id
        if ($user_id === null) {
            if (Request::option('user')) {
                $user_id = Request::option('user');
            } else {
                PageLayout::postInfo(_('Sie haben niemanden ausgewählt!'));
                //liste wieder anzeigen
                $this->redirect('admin/user/');
                return;
            }
        }

        //get user
        $this->user = User::find($user_id);

        // Änderungen speichern
        if (Request::submitted('edit')) {
            if (Request::get('auth_plugin') === 'preliminary') {
                Request::set('auth_plugin', null);
            }
            $editPerms = Request::getArray('perms');
            $um        = new UserManagement($user_id);

            //new user data
            $editUser = [];
            if (count($editPerms)) {
                $editUser['auth_user_md5.perms'] = $editPerms[0];
            }
            foreach (words('Vorname Nachname auth_plugin visible') as $param) {
                if (Request::get($param)) $editUser['auth_user_md5.' . $param] = Request::get($param);
            }
            foreach (words('title_front title_rear geschlecht preferred_language') as $param) {
                if (Request::get($param) !== null) $editUser['user_info.' . $param] = Request::get($param);
            }
            //change username
            if (Request::get('username') && $this->user['username'] !== Request::get('username')) {
                $editUser['auth_user_md5.username'] = Request::get('username');
            }
            //change email
            if (Request::get('Email') && $this->user['Email'] !== Request::get('Email')) {
                //disable mailbox validation
                if (Request::get('disable_mail_host_check')) {
                    $GLOBALS['MAIL_VALIDATE_BOX'] = false;
                }
                $editUser['auth_user_md5.Email'] = Request::get('Email');
            }

            //change password
            if (
                $GLOBALS['perm']->have_perm('root')
                && Config::get()->ALLOW_ADMIN_USERACCESS
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
                && !StudipAuthAbstract::CheckField('auth_user_md5.password', $this->user->auth_plugin)
                && $this->user->auth_plugin !== null
                && (Request::get('pass_1') !== '' || Request::get('pass_2') !== '')
            ) {
                if (Request::get('pass_1') === Request::get('pass_2')) {
                    $validator = new email_validation_class();
                    if (!$validator->ValidatePassword(Request::get('pass_1'))) {
                        $details[] = _('Das Passwort ist zu kurz. Es sollte mindestens 8 Zeichen lang sein.');
                    } else {
                        $um->changePassword(Request::get('pass_1'));
                    }
                } else {
                    $details[] = _("Bei der Wiederholung des Passwortes ist ein Fehler aufgetreten! Bitte geben Sie das exakte Passwort ein!");
                }
            }

            //deleting validation-key
            if (Request::get('delete_val_key') == "1") {
                $editUser['auth_user_md5.validation_key'] = '';
                $details[]                                = _('Der Validation-Key wurde entfernt.');
            }

            //changing studiendaten
            if (in_array($editPerms[0], ['autor', 'tutor', 'dozent']) && Request::option('new_studiengang', 'none') != 'none' && Request::option('new_abschluss', 'none') != 'none') {
                //change studycourses
                if (Request::option('new_studiengang', 'none') == 'none' || Request::option('new_abschluss', 'none') == 'none') {
                    $details[] = _('<b>Der Studiengang wurde nicht hinzugefügt.</b> Bitte geben Sie Fach und Abschluss ein.');
                } else {
                    $user_stc = UserStudyCourse::find([
                        $user_id,
                        Request::option('new_studiengang'),
                        Request::option('new_abschluss'),
                    ]);
                    if (!$user_stc) {
                        UserStudyCourse::create([
                            'user_id'      => $user_id,
                            'fach_id'      => Request::option('new_studiengang'),
                            'semester'     => Request::int('fachsem'),
                            'abschluss_id' => Request::option('new_abschluss'),
                        ]);
                        $details[] = _('Der Studiengang wurde hinzugefügt.');
                    } else {
                        $user_stc->semester = Request::int('fachsem');
                        if ($user_stc->store()) {
                            $details[] = _('Der Studiengang wurde geändert.');
                        } else {
                            $details[] = _('Der Studiengang wurde nicht geändert.');
                        }
                    }
                }
            }

            // change version of studiengang if module management is enabled
            if (in_array($editPerms[0], ['autor', 'tutor', 'dozent'])) {
                $change_versions = Request::getArray('change_version');
                $any_change = false;
                foreach ($change_versions as $fach_id => $abschluesse) {
                    foreach ($abschluesse as $abschluss_id => $version_id) {
                        $version = StgteilVersion::findByFachAbschluss(
                            $fach_id, $abschluss_id, $version_id
                        );
                        $version = reset($version);
                        if ($version && $version->hasPublicStatus('genehmigt')) {
                            $user_stc = UserStudyCourse::find([
                                $user_id,
                                $fach_id,
                                $abschluss_id]);
                            if ($user_stc) {
                                $user_stc->version_id = $version->getId();
                                $any_change           = $user_stc->store() != false;
                            }
                        }
                    }
                }
                if ($any_change) {
                    $details[] = _('Die Versionen der Studiengänge wurden geändert.');
                }
            }
            $new_institutes = Request::getArray('new_inst');

            //change institute for studiendaten
            if (in_array($editPerms[0], ['autor', 'tutor', 'dozent'])
                && Request::option('new_student_inst')
                && empty($new_institutes)
                && $GLOBALS['perm']->have_studip_perm("admin", Request::option('new_student_inst'))
            ) {
                StudipLog::log('INST_USER_ADD', Request::option('new_student_inst'), $user_id, 'user');
                $db = DBManager::get()->prepare("INSERT IGNORE INTO user_inst (user_id, Institut_id, inst_perms) "
                    . "VALUES (?,?,'user')");
                $db->execute([$user_id, Request::option('new_student_inst')]);
                NotificationCenter::postNotification('UserInstitutionDidCreate', Request::option('new_student_inst'), $user_id);
                $details[] = _('Die Einrichtung wurde hinzugefügt.');
            }

            //change institute
            if (!empty($new_institutes)) {
                foreach ($new_institutes as $institute_id) {
                    if ($editPerms[0] != 'root'
                        && $GLOBALS['perm']->have_studip_perm("admin", $institute_id)
                        && !Request::option('new_student_inst')
                    ) {
                        $membership = InstituteMember::build(
                            ['user_id' => $user_id, 'Institut_id' => $institute_id, 'inst_perms' => $editPerms[0]]
                        );

                        if ($membership->store()) {
                            StudipLog::log('INST_USER_ADD', $institute_id, $user_id, $editPerms[0]);
                            NotificationCenter::postNotification('UserInstitutionDidUpdate', $institute_id, $user_id);
                            InstituteMember::ensureDefaultInstituteForUser($user_id);
                            $details[] = sprintf(_('%s wurde hinzugefügt.'), htmlReady($membership->institute->getFullname()));
                        }
                    } elseif ($institute_id != '' && Request::option('new_student_inst') == $institute_id && $editPerms[0] != 'root') {
                        $details[] = sprintf(
                            _('<b>%s wurde nicht hinzugefügt.</b> Sie können keine Person gleichzeitig als Studierende/-r und als Mitarbeiter/-in einer Einrichtung hinzufügen.'),
                            htmlReady(Institute::find($institute_id)->getFullname())
                        );
                    }
                }
            }

            //change userdomain
            if (Request::get('new_userdomain', 'none') != 'none' && $editPerms[0] != 'root') {
                UserDomain::find(Request::get('new_userdomain'))->addUser($user_id);
                $result = AutoInsert::instance()->saveUser($user_id);

                $details[] = _('Die Nutzerdomäne wurde hinzugefügt.');
                foreach ($result['added'] as $item) {
                    $details[] = sprintf(_("Das automatische Eintragen in die Veranstaltung <em>%s</em> wurde durchgeführt."), $item);
                }
                foreach ($result['removed'] as $item) {
                    $details[] = sprintf(_("Das automatische Austragen aus der Veranstaltung <em>%s</em> wurde durchgeführt."), $item);
                }
            }

            //change datafields
            $datafields = Request::getArray('datafields');
            foreach (DataFieldEntry::getDataFieldEntries($user_id) as $id => $entry) {
                if (isset($datafields[$id])) {
                    $entry->setValueFromSubmit($datafields[$id]);
                    if ($entry->isValid()) {
                        $entry->store();
                    }
                }
            }

            //change ablaufdatum
            if (Request::get('expiration_date_delete') == 1) {
                UserConfig::get($user_id)->delete("EXPIRATION_DATE");
            } elseif (Request::get('expiration_date')) {
                $a = explode(".", stripslashes(trim(Request::get('expiration_date'))));
                if ($timestamp = @mktime(0, 0, 0, $a[1], $a[0], $a[2])) {
                    UserConfig::get($user_id)->store("EXPIRATION_DATE", $timestamp);
                    $details[] = _("Das Ablaufdatum wurde geändert.");
                } else {
                    $details[] = _("Das Ablaufdatum wurde in einem falschen Format angegeben.");
                }
            }

            if ($GLOBALS['perm']->have_perm('root') && Request::get('lock_rule')) {
                $st = DBManager::get()->prepare("UPDATE user_info SET lock_rule=? WHERE user_id=?");
                $st->execute([(Request::option('lock_rule') == 'none' ? '' : Request::option('lock_rule')), $user_id]);
                if ($st->rowCount()) {
                    $details[] = _("Die Sperrebene wurde geändert.");
                }
            }

            if (!Request::int('u_edit_send_mail')) {
                $dev_null       = new blackhole_message_class();
                $default_mailer = StudipMail::getDefaultTransporter();
                StudipMail::setDefaultTransporter($dev_null);
                $GLOBALS['MAIL_VALIDATE_BOX']  = false;
                $GLOBALS['MAIL_VALIDATE_HOST'] = false;
            }
            //save action and messages
            $um->changeUser($editUser);
            if (!Request::int('u_edit_send_mail') && isset($default_mailer)) {
                StudipMail::setDefaultTransporter($default_mailer);
            }
            //get message
            $umdetails = explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($um->msg, 0, -1)));
            if (!empty($details)) {
                $details   = array_reverse(array_merge((array)$details, (array)$umdetails));
                PageLayout::postInfo(_('Hinweise:'), $details);
            }

            $this->redirect('admin/user/edit/' . $user_id);
        }

        $this->prelim = $this->user->auth_plugin === null;
        if ($this->prelim) {
            $this->available_auth_plugins['preliminary'] = _('vorläufig');
        }
        foreach ($GLOBALS['STUDIP_AUTH_PLUGIN'] as $ap) {
            $this->available_auth_plugins[mb_strtolower($ap)] = $ap;
        }

        if (!empty($this->user->institute_memberships)) {
            $this->student_institutes = $this->user->institute_memberships->filter(function ($a) {
                return $a->inst_perms === 'user';
            });
            $this->institutes = $this->user->institute_memberships->filter(function ($a) {
                return $a->inst_perms !== 'user';
            });
        }

        $this->available_institutes = Institute::getMyInstitutes();
        $this->userfields           = DataFieldEntry::getDataFieldEntries($user_id, 'user');
        $this->userdomains          = UserDomain::getUserDomainsForUser($user_id);
        if (LockRules::CheckLockRulePermission($user_id) && LockRules::getObjectRule($user_id)->description) {
            PageLayout::postInfo(formatLinks(LockRules::getObjectRule($user_id)->description));
        }

        $user_domains      = UserDomain::getUserDomainsForUser($this->user->user_id);
        $all_domains       = UserDomain::getUserDomains();
        $this->domains     = array_diff($all_domains, $user_domains);
        $this->faecher     = Fach::findBySQL('1 ORDER BY name');
        $this->abschluesse = Abschluss::findBySQL('1 ORDER BY name');
    }

    /**
     * Adding a new user to Stud.IP
     * @param bool $prelim
     */
    public function new_action($prelim = false)
    {
        $this->perm   = $GLOBALS['perm'];
        $this->prelim = $prelim;

        //check auth_plugins
        if (!in_array("Standard", $GLOBALS['STUDIP_AUTH_PLUGIN']) && !$prelim) {
            PageLayout::postInfo(_('Die Standard-Authentifizierung ist ausgeschaltet. Das Anlegen von neuen Benutzern ist nicht möglich!'));
            $this->redirect('admin/user');
            return;
        }

        //get formdata
        $this->user = [
            'username'    => trim(Request::get('username')),
            'perm'        => Request::option('perm'),
            'visible'     => Request::get('visible'),
            'Vorname'     => trim(Request::get('Vorname')),
            'Nachname'    => trim(Request::get('Nachname')),
            'geschlecht'  => Request::int('geschlecht'),
            'title_front' => trim(Request::get('title_front')),
            'title_rear'  => trim(Request::get('title_rear')),
            'Email'       => trim(Request::get('Email')),
            'auth_plugin' => Request::get('auth_plugin'),
            'institute'   => Request::option('institute'),
            'preferred_language' => Request::get('preferred_language')
            ];

        //save new user
        if (Request::submitted('speichern')) {

            //disable mailbox validation
            if (Request::get('disable_mail_host_check')) {
                $GLOBALS['MAIL_VALIDATE_BOX'] = false;
            }

            //messagebox details
            $details = [];

            //new user data
            $newuser = [
                'auth_user_md5.username'    => $this->user['username'],
                'auth_user_md5.Vorname'     => $this->user['Vorname'],
                'auth_user_md5.Nachname'    => $this->user['Nachname'],
                'auth_user_md5.Email'       => $this->user['Email'],
                'auth_user_md5.perms'       => $this->user['perm'],
                'auth_user_md5.auth_plugin' => $this->user['auth_plugin'],
                'auth_user_md5.visible'     => $this->user['visible'],
                'user_info.title_front'     => $this->user['title_front'],
                'user_info.title_rear'      => $this->user['title_rear'],
                'user_info.geschlecht'      => $this->user['geschlecht'],
                'user_info.preferred_language' => $this->user['preferred_language'],
            ];

            //create new user
            $UserManagement = new UserManagement();
            if (!$prelim) {
                $created = $UserManagement->createNewUser($newuser);
            } else {
                $created = $UserManagement->createPreliminaryUser($newuser);
            }
            if ($created) {

                //get user_id
                $user_id = $UserManagement->user_data['auth_user_md5.user_id'];
                $institutes = Request::getArray('institutes');

                if (!empty($institutes)) {
                    $institutes = Institute::findMany($institutes);
                    foreach ($institutes as $institute) {
                        //new user is added to an institute
                        if ($GLOBALS['perm']->have_studip_perm('admin', $institute->id)
                            && $UserManagement->user_data['auth_user_md5.perms'] != 'root'
                            && ($UserManagement->user_data['auth_user_md5.perms'] != 'admin'
                                || ($GLOBALS['perm']->is_fak_admin() && !$institute->isFaculty())
                                || $GLOBALS['perm']->have_perm('root'))
                        ) {
                            //log
                            StudipLog::log(
                                'INST_USER_ADD',
                                $institute->id,
                                $user_id,
                                $UserManagement->user_data['auth_user_md5.perms']);

                            $inst_user = InstituteMember::build([
                                'user_id' => $user_id,
                                'Institut_id' => $institute->id,
                                'inst_perms' => $UserManagement->user_data['auth_user_md5.perms']
                            ])->store();
                            NotificationCenter::postNotification('UserInstitutionDidCreate', $institute->id, $user_id);
                            InstituteMember::ensureDefaultInstituteForUser($user_id);

                            //send email, if new user is an admin
                            if ($inst_user) {
                                //check recipients
                                if (Request::get('enable_mail_admin') === 'admin' && Request::get('enable_mail_dozent') === 'dozent') {
                                    $in  = words('admin dozent');
                                    $wem = "Admins und Lehrende";
                                } elseif (Request::get('enable_mail_admin') === 'admin') {
                                    $in  = 'admin';
                                    $wem = "Admins";
                                } elseif (Request::get('enable_mail_dozent') === 'dozent') {
                                    $in  = 'dozent';
                                    $wem = "Lehrende";
                                }

                                if (!empty($in) && Request::get('perm') == 'admin') {
                                    $i     = 0;
                                    $notin = [];

                                    //get admins
                                    $sql = "SELECT user_id, b.Vorname, b.Nachname, b.Email
                                    FROM user_inst AS a
                                    INNER JOIN auth_user_md5 AS b USING (user_id)
                                    WHERE a.Institut_id = ? AND a.inst_perms IN (?) AND a.user_id != ?";

                                    $statement = DBManager::get()->prepare($sql);
                                    $statement->execute([
                                        $institute->id,
                                        $in,
                                        $user_id,
                                    ]);
                                    $users = $statement->fetchAll(PDO::FETCH_ASSOC);

                                    foreach ($users as $admin) {
                                        $subject  = _("Neuer Administrator in Ihrer Einrichtung angelegt");
                                        $mailbody = sprintf(_("Liebe(r) %s %s,\n\n"
                                            . "in der Einrichtung '%s' wurde %s %s als Administrator eingetragen "
                                            . " und steht Ihnen als neuer Ansprechpartner bei Fragen oder Problemen "
                                            . "in Stud.IP zur Verfügung. "),
                                            $admin['Vorname'], $admin['Nachname'],
                                            $institute->getFullname(), $this->user['Vorname'], $this->user['Nachname']);

                                        StudipMail::sendMessage($admin['Email'], $subject, $mailbody);
                                        $notin[] = $admin['user_id'];
                                        $i++;
                                    }

                                    //Noch ein paar Mails für die Fakultätsadmins
                                    if ($in != 'dozent') {
                                        $notin[] = $user_id;
                                        //get admins
                                        $sql = "SELECT a.user_id, b.Vorname, b.Nachname, b.Email
                                        FROM user_inst AS a
                                        INNER JOIN auth_user_md5 AS b USING (user_id)
                                        WHERE a.user_id NOT IN (?) AND a.Institut_id IN (
                                            SELECT fakultaets_id
                                            FROM Institute
                                            WHERE Institut_id = ? AND fakultaets_id != Institut_id
                                        ) AND a.inst_perms = 'admin'";
                                        $statement = DBManager::get()->prepare($sql);
                                        $statement->execute([
                                            $notin,
                                            $institute->id,
                                        ]);
                                        $fak_admins = $statement->fetchAll(PDO::FETCH_ASSOC);

                                        foreach ($fak_admins as $admin) {
                                            $subject  = _("Neuer Administrator in Ihrer Einrichtung angelegt");
                                            $mailbody = sprintf(_("Liebe(r) %s %s,\n\n"
                                                . "in der Einrichtung '%s' wurde %s %s als Administrator eingetragen "
                                                . " und steht Ihnen als neuer Ansprechpartner bei Fragen oder Problemen "
                                                . "in Stud.IP zur Verfügung. "),
                                                $admin['Vorname'], $admin['Nachname'],
                                                $institute->getFullname(), $this->user['Vorname'], $this->user['Nachname']);

                                            StudipMail::sendMessage($admin['Email'], $subject, $mailbody);
                                            $i++;
                                        }
                                    }

                                    if ($i >0 && isset($wem)) {
                                        $details[] = sprintf(
                                            _('Es wurden ingesamt %s Mails an die %s der Einrichtung "%s" geschickt.'),
                                            $i,
                                            $wem,
                                            htmlReady($institute->getFullname())
                                        );
                                    }
                                }

                                $details[] = sprintf(
                                    _('Person wurde erfolgreich in die Einrichtung "%s" mit dem Status "%s" eingetragen.'),
                                    htmlReady($institute->getFullname()),
                                    $UserManagement->user_data['auth_user_md5.perms']
                                );
                            } else {
                                $details[] = sprintf(
                                    _('Person konnte nicht in die Einrichtung "%s" eingetragen werden.'),
                                    htmlReady($institute->getFullname())
                                );
                            }
                        }
                    }
                }

                //adding userdomain
                if (Request::get('select_dom_id')) {
                    $domain = new UserDomain(Request::get('select_dom_id'));
                    if ($GLOBALS['perm']->have_perm('root') || in_array($domain, UserDomain::getUserDomainsForUser($GLOBALS['user']->id))) {
                        $domain->addUser($user_id);
                        $details[] = sprintf(_('Person wurde in Nutzerdomäne "%s" eingetragen.'), htmlReady($domain->name));
                    } else {
                        $details[] = _('Person konnte nicht in die Nutzerdomäne eingetragen werden.');
                    }
                    $result = AutoInsert::instance()->saveUser($user_id);

                    foreach ($result['added'] as $item) {
                        $details[] = sprintf(_('Das automatische Eintragen in die Veranstaltung <em>%s</em> wurde durchgeführt.'), $item);
                    }
                    foreach ($result['removed'] as $item) {
                        $details[] = sprintf(_('Das automatische Austragen aus der Veranstaltung <em>%s</em> wurde durchgeführt.'), $item);
                    }
                }

                //get message
                $details = explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($UserManagement->msg, 0, -1)));
                PageLayout::postSuccess(_('Person wurde angelegt.'), $details);
                $this->redirect('admin/user/edit/' . $user_id);
                return;
            } else {
                //get message
                $details = explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($UserManagement->msg, 0, -1)));
                PageLayout::postError(_('Person konnte nicht angelegt werden.'), $details);
            }
        }

        if ($GLOBALS['perm']->have_perm('root')) {
            $sql
                     = "SELECT Institut_id, Name, 1 AS is_fak
                    FROM Institute
                    WHERE Institut_id=fakultaets_id
                    ORDER BY Name";
            $faks    = DBManager::get()->query($sql)->fetchAll(PDO::FETCH_ASSOC);
            $domains = UserDomain::getUserDomains();
        } else {
            $sql
                       = "SELECT a.Institut_id, Name, b.Institut_id = b.fakultaets_id AS is_fak
                    FROM user_inst a
                    LEFT JOIN Institute b USING (Institut_id)
                    WHERE a.user_id = ? AND a.inst_perms = 'admin'
                    ORDER BY is_fak, Name";
            $statement = DBManager::get()->prepare($sql);
            $statement->execute([User::findCurrent()->id]);
            $faks    = $statement->fetchAll(PDO::FETCH_ASSOC);
            $domains = UserDomain::getUserDomainsForUser(User::findCurrent()->id);
        }

        $query
                   = "SELECT Institut_id, Name
                  FROM Institute
                  WHERE fakultaets_id = ? AND institut_id != fakultaets_id
                  ORDER BY Name";
        $statement = DBManager::get()->prepare($query);

        foreach ($faks as $index => $fak) {
            if ($fak['is_fak']) {
                $statement->execute([$fak['Institut_id']]);
                $faks[$index]['institutes'] = $statement->fetchAll(PDO::FETCH_ASSOC);
                $statement->closeCursor();
            }
        }

        $this->domains = $domains;
        $this->faks    = $faks;
        $this->perms   = $GLOBALS['perm'];
    }

    /**
     * Migrate 2 users to 1 account. This is a part of the old numit-plugin
     */
    public function migrate_action($user_id = null)
    {
        //check submitted form
        if (Request::submitted('umwandeln')) {
            $old_id = Request::option('old_id');
            $new_id = Request::option('new_id');

            //check existing users
            if (User::exists($old_id) && User::exists($new_id)) {
                $identity = Request:: get('convert_ident');
                $details  = User::convert($old_id, $new_id, $identity);

                //delete old user
                if (Request::get('delete_old')) {
                    //no messaging
                    $dev_null       = new blackhole_message_class();
                    $default_mailer = StudipMail::getDefaultTransporter();
                    StudipMail::setDefaultTransporter($dev_null);

                    //preparing delete
                    $umanager = new UserManagement();
                    $umanager->getFromDatabase($old_id);

                    //delete
                    $umanager->deleteUser();
                    $details = array_merge($details, explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($umanager->msg, 0, -1))));

                    //reactivate messaging
                    StudipMail::setDefaultTransporter($default_mailer);
                }

                PageLayout::postSuccess(_('Die Personen wurden migriert.'), $details);
                $this->redirect('admin/user/edit/' . $new_id);
            } else {
                PageLayout::postError(_('Bitte wählen Sie zwei gültige Personen aus.'));
            }
        }
        $this->user = $user_id ? User::find($user_id) : null;
    }

    /**
     * Set the password of an user to a new random password, without security-query
     *
     * @param string $user_id
     */
    public function change_password_action($user_id)
    {
        // mail address did not change, so skip this check
        $GLOBALS['MAIL_VALIDATE_BOX'] = false;
        $UserManagement               = new UserManagement($user_id);
        if ($UserManagement->setPassword()) {
            PageLayout::postSuccess(_('Es wurde eine Mail mit einem Link zum Neusetzen '
                . 'des Passworts verschickt, das bestehende Passwort wurde nicht verändert.'));
        } else {
            $details = explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($UserManagement->msg, 0, -1)));
            PageLayout::postError(_('Die Änderungen konnten nicht gespeichert werden.'), $details);
        }
        if (Request::int('from_index')) {
            $this->redirect('admin/user');
        } else {
            $this->redirect('admin/user/edit/' . $user_id);
        }
    }