Select Git revision
Forked from
Stud.IP / Stud.IP
Source project has a limited visibility.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
user.php 73.17 KiB
<?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
{
/**
* Common tasks for all actions.
*/
public function before_filter(&$action, &$args)
{
global $perm;
parent::before_filter($action, $args);
// user must have root permission if restricted user management is disabled
$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)
{
global $perm;
$this->perm = $perm;
$request = '';
//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
$search_datafields = [];
foreach ($this->datafields as $datafield) {
if (mb_strlen($request[$datafield->id]) > 0
&& !(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'];
$mapper = function ($u) {
$userdomains = array_map(function ($ud) {
return $ud->name;
}, UserDomain::getUserDomainsForUser($u->id));
return [
$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) : ''
];
};
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)
&& ($request['auth_plugins'] || $request['userdomains'] || $request['degree'] || $request['institute'] || $request['studycourse'] || $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 md5 $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')) {
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')) {
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 md5 $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) && (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');
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')) {
StudipMail::setDefaultTransporter($default_mailer);
}
//get message
$umdetails = explode('§', str_replace(['msg§', 'info§', 'error§'], '', mb_substr($um->msg, 0, -1)));
$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 (count($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)
{
global $perm, $auth;
$this->perm = $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++;
}
}
$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 ($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 ($this->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([$auth->auth['uid']]);
$faks = $statement->fetchAll(PDO::FETCH_ASSOC);
$domains = UserDomain::getUserDomainsForUser($auth->auth["uid"]);
}
$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 = $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 md5 $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);
}
}
/**
* Add lock-comment for locked user
* @param $user_id
*/
public function lock_comment_action($user_id)
{
$this->user = User::find($user_id);
PageLayout::setTitle(sprintf(_('%s sperren'), $this->user->getFullname()));
$this->params = [];
if (Request::int('from_index')) {
$this->params['from_index'] = 1;
}
}
/**
* Lock user
* @param $user_id
*/
public function lock_action($user_id)
{
CSRFProtection::verifyUnsafeRequest();
$user = User::find($user_id);
$user->locked = 1;
$user->lock_comment = Request::get('lock_comment');
$user->locked_by = $GLOBALS['user']->id;
if ($user->store()) {
PageLayout::postSuccess(sprintf(
_('%s wurde gesperrt.'),
htmlReady($user->getFullname())
));
}
if (Request::int('from_index')) {
$this->redirect('admin/user');
} else {
$this->redirect('admin/user/edit/' . $user_id);
}
}
/**
* Unlock an user, without security-query
*
* @param md5 $user_id
*/
public function unlock_action($user_id)
{
$user = User::find($user_id);
$user->locked = 0;
$user->lock_comment = null;
$user->locked_by = null;
if ($user->store()) {
PageLayout::postSuccess(sprintf(
_('%s wurde entsperrt.'),
htmlReady($user->getFullname())
));
} else {
PageLayout::postError(sprintf(
_('%s konnte nicht entsperrt werden.'),
htmlReady($user->getFullname())
));
}
if (Request::int('from_index')) {
$this->redirect('admin/user');
} else {
$this->redirect('admin/user/edit/' . $user_id);
}
}
/**
* Display institute informations of an user and save changes to it.
*
* @param md5 $user_id
* @param md5 $institute_id
*/
public function edit_institute_action($user_id, $institute_id)
{
$this->user = User::find($user_id);
if (count($this->user->institute_memberships)) {
$institute = null;
$this->user->institute_memberships->filter(function ($a) use ($institute_id, &$institute) {
if ($a->institut_id === $institute_id) {
$institute = $a;
}
});
}
$this->institute = $institute;
$this->faecher = StudyCourse::findBySQL('1 ORDER BY name');
$this->abschluesse = Abschluss::findBySQL('1 ORDER by name');
$this->perms = $this->user->getInstitutePerms();
$this->datafields = DataFieldEntry::getDataFieldEntries([$user_id, $institute_id], 'userinstrole');
}
/**
* Set user institute information
* @param $user_id
* @param $institute_id
*/
public function store_user_institute_action($user_id, $institute_id)
{
CSRFProtection::verifyRequest();
$inst_membership = InstituteMember::findOneBySQL('user_id = ? AND institut_id = ?', [$user_id, $institute_id]);
//change datafields
$datafields = Request::getArray('datafields');
foreach ($datafields as $id => $data) {
$datafield = DataField::find($id);
$entry = DataFieldEntry::createDataFieldEntry($datafield, [$user_id, $institute_id]);
$entry->setValueFromSubmit($data);
if ($entry->isValid()) {
$entry->store();
}
}
if ($inst_membership->inst_perms != Request::get('inst_perms')) {
StudipLog::log('INST_USER_STATUS', $institute_id, $user_id, $inst_membership->inst_perms . ' -> ' . Request::get('inst_perms'));
NotificationCenter::postNotification('UserInstitutionPermDidUpdate', $institute_id, $user_id);
}
$inst_membership->inst_perms = Request::get('inst_perms', '');
$inst_membership->visible = Request::int('visible', 0);
$inst_membership->sprechzeiten = Request::get('sprechzeiten', '');
$inst_membership->telefon = Request::get('telefon', '');
$inst_membership->fax = Request::get('fax', '');
$inst_membership->externdefault = Request::int('externdefault', 0);
$inst_membership->raum = Request::get('raum', '');
$inst_membership->store();
//output
PageLayout::postSuccess(_('Die Einrichtungsdaten der Person wurden geändert.'));
$this->relocate('admin/user/edit/' . $user_id);
return;
}
/**
* Delete an studycourse of an user , without a security-query
*
* @param md5 $user_id
* @param md5 $fach_id
* @param md5 $abschluss_id
*/
public function delete_studycourse_action($user_id, $fach_id, $abschlus_id)
{
$user_stc = UserStudyCourse::find([$user_id, $fach_id, $abschlus_id]);
$deleted = false;
if ($user_stc) {
$deleted = $user_stc->delete();
}
if ($deleted) {
PageLayout::postSuccess(_('Die Zuordnung zum Studiengang wurde gelöscht.'));
} else {
PageLayout::postError(_('Die Zuordnung zum Studiengang konnte nicht gelöscht werden.'));
}
$this->redirect('admin/user/edit/' . $user_id);
}
/**
* Delete an institute of an user , without a security-query
*
* @param md5 $user_id
* @param md5 $institut_id
*/
public function delete_institute_action($user_id, $institut_id)
{
if ($GLOBALS['perm']->have_studip_perm("admin", $institut_id)) {
$groups = GetAllStatusgruppen($institut_id);
$group_list = GetRoleNames($groups, 0, '', true);
if (is_array($group_list) && count($group_list) > 0) {
$query = "DELETE FROM statusgruppe_user
WHERE statusgruppe_id IN (?) AND user_id = ?";
$statement = DBManager::get()->prepare($query);
$statement->execute([array_keys($group_list), $user_id]);
}
$db = DBManager::get()->prepare("DELETE FROM user_inst WHERE user_id = ? AND Institut_id = ?");
$db->execute([$user_id, $institut_id]);
if ($db->rowCount() == 1) {
StudipLog::log('INST_USER_DEL', $institut_id, $user_id);
NotificationCenter::postNotification('UserInstitutionDidDelete', $institut_id, $user_id);
InstituteMember::ensureDefaultInstituteForUser($user_id);
if (UserConfig::get($user_id)->MY_INSTITUTES_DEFAULT == $institut_id) {
UserConfig::get($user_id)->delete('MY_INSTITUTES_DEFAULT');
}
PageLayout::postSuccess(_('Die Zuordnung zur Einrichtung wurde gelöscht.'));
} else {
PageLayout::postError(_('Die Zuordnung zur Einrichtung konnte nicht gelöscht werden.'));
}
} else {
PageLayout::postError(_('Die Zuordnung zur Einrichtung konnte nicht gelöscht werden.'));
}
$this->redirect('admin/user/edit/' . $user_id);
}
/**
* Delete an assignment of an user to an userdomain, without a security-query
*
* @param md5 $user_id
*/
public function delete_userdomain_action($user_id)
{
$domain_id = Request::get('domain_id');
UserDomain::find($domain_id)->removeUser($user_id);
$result = AutoInsert::instance()->saveUser($user_id);
$details = [];
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);
}
PageLayout::postSuccess(_('Die Zuordnung zur Nutzerdomäne wurde erfolgreich gelöscht.'), $details);
$this->redirect('admin/user/edit/' . $user_id);
}
/**
* Reset notfication for user
* @param $user_id
*/
public function reset_notification_action($user_id)
{
$resetted = CourseMemberNotification::deleteBySQL("user_id = ?", [$user_id]);
PageLayout::postSuccess(sprintf(_('Die Benachrichtigungseinstellungen für %s Veranstaltungen wurden zurück gesetzt.'), $resetted));
$this->redirect('admin/user/edit/' . $user_id);
}
/**
* Reset two factor authentication for user
* @param $user_id
*/
public function reset_tfa_action($user_id)
{
if (TFASecret::deleteByUser_id($user_id)) {
PageLayout::postSuccess(_('Die Zwei-Faktor-Authentifizierung wurde für diese Person deaktiviert.'));
}
$this->redirect('admin/user/edit/' . $user_id);
}
/**
* Show user activities
* @param $user_id
* @throws Exception
*/
public function activities_action($user_id)
{
$this->user = User::find($user_id);
$this->fullname = $this->user->getFullname();
$this->params = [];
if (Request::int('from_index')) {
$this->params['from_index'] = 1;
}
if (is_null($this->user)) {
throw new Exception(_('Nutzer nicht gefunden'));
}
PageLayout::setTitle(sprintf(_('Datei- und Aktivitätsübersicht für %s'), $this->fullname));
$this->queries = $this->getActivities($user_id);
$memberships = DBManager::get()->fetchAll("SELECT seminar_user.*, seminare.Name as course_name
FROM seminar_user
LEFT JOIN seminare USING (seminar_id)
LEFT JOIN semester_courses ON (seminare.Seminar_id = semester_courses.course_id)
LEFT JOIN semester_data ON (semester_data.semester_id = semester_courses.semester_id)
WHERE user_id = ? GROUP BY seminare.Seminar_id ORDER BY MAX(semester_data.beginn) DESC, seminare.Name",
[$user_id],
'CourseMember::buildExisting');
$courses = [];
$course_files = [];
$closed_courses = [];
$this->sections = [];
foreach ($memberships as $membership) {
$semester_name = $membership->course->isOpenEnded() ? _('unbegrenzt') : $membership->course->start_semester->name;
if (!Request::get('view') || Request::get('view') === 'files') {
// count files for course
$top_folder = Folder::findTopFolder($membership->seminar_id);
$top_folder = $top_folder->getTypedFolder();
$count = FileManager::countFilesInFolder($top_folder, true, $user_id);
if ($count) {
if (!isset($course_files[$membership->seminar_id])) {
$course_files[$semester_name][$membership->course->id]['course'] = $membership->course;
}
$course_files[$semester_name][$membership->course->id]['files'] = $count;
}
}
if (in_array(Request::get('view'), words('courses closed_courses'))) {
// check for closed courses
$closed_course
= $closed_course = DBManager::get()->fetchColumn('SELECT COUNT(sc.seminar_id) FROM seminar_courseset sc
INNER JOIN courseset_rule cr ON cr.set_id=sc.set_id AND cr.type="ParticipantRestrictedAdmission"
WHERE sc.seminar_id =?', [$membership->seminar_id]);
if ((int)$closed_course) {
$closed_courses[$semester_name][$membership->course->id] = $membership;
} else {
$courses[$semester_name][$membership->course->id] = $membership;
}
}
}
if (!Request::get('view') || Request::get('view') === 'files') {
$institutes = Institute::getMyInstitutes($user_id);
if (!empty($institutes)) {
foreach ($institutes as $index => $institute) {
$top_folder = Folder::findTopFolder($institute['Institut_id']);
$top_folder = $top_folder->getTypedFolder();
$count = FileManager::countFilesInFolder($top_folder, true, $user_id);
if ($count) {
$institutes[$index]['files'] = $count;
} else {
unset($institutes[$index]);
}
}
}
}
if (Request::get('view') === 'seminar_wait') {
// waiting list
$seminar_wait = AdmissionApplication::findByUser($user_id);
} elseif (Request::get('view') === 'priorities') {
// priorities
$priorities = DBManager::get()->fetchAll('SELECT * FROM `priorities` WHERE `user_id` = ?', [$user_id]);
}
if (!empty($course_files)) {
$this->sections['course_files'] = $course_files;
}
if (!empty($institutes)) {
$this->sections['institutes'] = $institutes;
}
if (!empty($courses)) {
$this->sections['courses'] = $courses;
}
if (!empty($courses)) {
$this->sections['closed_courses'] = $closed_courses;
}
if (is_array($seminar_wait) && count($seminar_wait)) {
$this->sections['seminar_wait'] = $seminar_wait;
}
if (!empty($priorities)) {
$this->sections['priorities'] = $priorities;
}
}
/**
* List files for course or institute
* @param $user_id
* @param $course_id
*/
public function list_files_action($user_id, $range_id)
{
$this->user = User::find($user_id);
$folder = Folder::findTopFolder($range_id);
if($folder) {
$folder = $folder->getTypedFolder();
}
if($folder) {
//Folder exists: We can collect all subfolders in the folder.
$this->folders = FileManager::getFolderFilesRecursive($folder, $this->user->id)['folders'];
} else {
//Folder does not exist: We can't collect any subfolders.
$this->folders = [];
}
$this->range = Course::find($range_id);
if (is_null($this->range)) {
$this->range = Institute::find($range_id);
}
PageLayout::setTitle(sprintf(_('Dateiübersicht für %s'), $this->range->getFullname()));
}
/**
* Create array
* @param $user_id
* @return array
*/
private function getActivities($user_id)
{
$queries[] = [
'desc' => _('Eingetragen in Veranstaltungen (dozent / tutor / autor / user)'),
'query' => "SELECT CONCAT_WS(' / ', SUM(status = 'dozent'), SUM(status = 'tutor'),
SUM(status = 'autor'), SUM(status = 'user'))
FROM seminar_user
WHERE user_id = ?
GROUP BY user_id",
'details' => "courses",
];
$queries[] = [
'desc' => _('Eingetragen in geschlossenen Veranstaltungen (dozent / tutor / autor / user)'),
'query' => "SELECT CONCAT_WS(' / ', SUM(su.status = 'dozent'), SUM(su.status = 'tutor'),
SUM(su.status = 'autor'), SUM(su.status = 'user'))
FROM seminar_user AS su
INNER JOIN seminar_courseset sc USING (seminar_id)
INNER JOIN courseset_rule cr ON cr.set_id=sc.set_id AND cr.type='ParticipantRestrictedAdmission'
WHERE user_id = ?
GROUP BY user_id",
'details' => "closed_courses",
];
$queries[] = [
'desc' => _("Eingetragen in Wartelisten (wartend / vorläufig akzeptiert)"),
'query' => "SELECT CONCAT_WS(' / ', SUM(status = 'awaiting'), SUM(status = 'accepted'))
FROM admission_seminar_user
WHERE user_id = ?
GROUP BY user_id",
'details' => "seminar_wait",
];
$queries[] = [
'desc' => _("Eingetragen in Anmeldelisten"),
'query' => "SELECT COUNT(*)
FROM priorities
WHERE user_id = ?
GROUP BY user_id",
'details' => "priorities",
];
$queries[] = [
'desc' => _("Eingetragen in Einrichtungen (admin / dozent / tutor / autor)"),
'query' => "SELECT CONCAT_WS(' / ', SUM(inst_perms = 'admin'), SUM(inst_perms = 'dozent'),
SUM(inst_perms = 'tutor'), SUM(inst_perms = 'autor'))
FROM user_inst
WHERE user_id = ?
GROUP BY user_id",
];
$queries[] = [
'desc' => _("Anzahl der Ankündigungen"),
'query' => "SELECT COUNT(*) FROM news WHERE user_id = ? GROUP BY user_id",
];
$queries[] = [
'desc' => _("Anzahl der Wikiseiten"),
'query' => "SELECT COUNT(*) FROM wiki WHERE user_id = ? GROUP BY user_id",
];
$queries[] = [
'desc' => _("Anzahl der Umfragen"),
'query' => "SELECT COUNT(*) FROM questionnaires WHERE user_id = ? GROUP BY user_id",
];
$queries[] = [
'desc' => _("Anzahl der Evaluationen"),
'query' => "SELECT COUNT(*) FROM eval WHERE author_id = ? GROUP BY author_id",
];
$queries[] = [
'desc' => _("Anzahl der Dateien in Veranstaltungen und Einrichtungen"),
'query' => "SELECT COUNT(file_refs.id)
FROM (file_refs INNER JOIN files ON file_refs.file_id = files.id)
INNER JOIN folders ON file_refs.folder_id = folders.id
WHERE (file_refs.user_id = ?)
AND (
(folders.range_type = 'course')
OR (folders.range_type = 'institute')
)
GROUP BY file_refs.user_id",
'details' => "files",
];
$queries[] = [
'desc' => _("Gesamtgröße der hochgeladenen Dateien in Veranstaltungen und Einrichtungen (in Megabytes)"),
'query' => "SELECT FORMAT(SUM(files.size)/1000000,2)
FROM (file_refs INNER JOIN files ON file_refs.file_id = files.id)
INNER JOIN folders ON file_refs.folder_id = folders.id
WHERE (file_refs.user_id = ?)
AND (files.filetype = 'StandardFile')
AND (
(folders.range_type = 'course')
OR (folders.range_type = 'institute')
)
GROUP BY file_refs.user_id",
'details' => "files",
];
foreach (PluginEngine::getPlugins('ForumModule') as $plugin) {
$table = $plugin->getEntryTableInfo();
$queries[] = [
'desc' => $plugin->getPluginName() . ' - ' . _("Anzahl der Postings"),
'query' => 'SELECT COUNT(*) FROM `' . $table['table'] . '`
WHERE `' . $table['user_id'] . '` = ?
GROUP BY `' . $table['user_id'] . '`',
];
}
// Evaluate queries
foreach ($queries as $index => $query) {
$statement = DBManager::get()->prepare($query['query']);
$statement->execute([$user_id]);
$queries[$index]['value'] = $statement->fetchColumn() ?: 0;
}
return $queries;
}
/**
* Download documents
* @param string $user_id
* @param string $range_id
*/
public function download_user_files_action($user_id, $range_id = null)
{
global $TMP_PATH;
Seminar_Perm::get()->check('root');
if ($range_id === null) {
$file_refs = FileRef::findBySQL("INNER JOIN folders ON folders.id = file_refs.folder_id WHERE folders.range_type IN ('course','institute') AND file_refs.user_id = ? GROUP BY file_id ORDER BY NULL", [$user_id]);
} else {
$file_refs = FileRef::findBySQL("INNER JOIN folders ON folders.id = file_refs.folder_id WHERE folders.range_id = ? AND file_refs.user_id = ? GROUP BY file_id ORDER BY NULL", [$range_id, $user_id]);
}
$user = User::find($user_id);
$archive_file_name = $user->username . '_files_' . date('Ymd-Hi') . '.zip';
$archive_path = $TMP_PATH . '/' . $archive_file_name;
$result = FileArchiveManager::createArchiveFromFileRefs(
$file_refs,
User::findCurrent(),
$archive_path,
false
);
$archive_download_link = FileManager::getDownloadURLForTemporaryFile(
$archive_path,
$archive_file_name
);
$this->redirect($archive_download_link);
}
/**
* Init sidebar
*/
public function addSidebar()
{
$sidebar = Sidebar::Get();
$actions = $sidebar->addWidget(new ActionsWidget());
if (in_array('Standard', $GLOBALS['STUDIP_AUTH_PLUGIN'])) {
$actions->addLink(
_('Neues Konto anlegen'),
$this->url_for('admin/user/new'),
Icon::create('person+add')
)->asDialog();
}
$actions->addLink(
_('Vorläufiges Konto anlegen'),
$this->url_for('admin/user/new/prelim'),
Icon::create('date+add')
)->asDialog();
$actions->addLink(
_('Konten zusammenführen'),
$this->url_for('admin/user/migrate/' . (($this->user && is_array($this->user)) ? $this->user['user_id'] : '')),
Icon::create('persons+new')
);
$search = $sidebar->addWidget(new SearchWidget());
$search->addNeedle(_('Person suchen'),
'user_id',
true,
new StandardSearch('user_id'),
'function (value) { document.location = STUDIP.URLHelper.getURL("dispatch.php/admin/user/edit/" + value); }'
);
if ($this->action === 'index' && !empty($this->users)) {
$export = $sidebar->addWidget(new ExportWidget());
$export->addLink(_('Suchergebnis exportieren'),
$this->url_for('admin/user?export=1'),
Icon::create('persons+move_right')
);
}
if (!is_object($this->user)) {
return;
}
$user_actions = new ActionsWidget();
$user_actions->setTitle(sprintf(_('Aktionen für "%s"'), $this->user->username));
$user_actions->addLink(
_('Nachricht an Person verschicken'),
URLHelper::getURL('dispatch.php/messages/write', ['rec_uname' => $this->user->username]),
Icon::create('mail')
)->asDialog();
if ($this->user->locked) {
$user_actions->addLink(
_('Personenaccount entsperren'),
$this->url_for("admin/user/unlock/{$this->user->id}"),
Icon::create('lock-unlocked')
);
} else {
$user_actions->addLink(
_('Personenaccount sperren'),
$this->url_for("admin/user/lock_comment/{$this->user->id}"),
Icon::create('lock-locked')
)->asDialog('size=auto');
}
if ($this->user->auth_plugin !== null && ($GLOBALS['perm']->have_perm('root') || $GLOBALS['perm']->is_fak_admin() || !in_array($this->user->perms, words('root admin')))) {
if (!StudipAuthAbstract::CheckField('auth_user_md5.password', $this->user->auth_plugin)) {
$user_actions->addLink(
_('Passwortlink zusenden'),
$this->url_for("admin/user/change_password/{$this->user->id}"),
Icon::create('key')
);
}
$user_actions->addLink(
_('Person löschen'),
$this->url_for("admin/user/bulk/{$this->user->id}", ['method' => 'delete']),
Icon::create('trash')
)->asDialog('size=auto');
}
if (Config::get()->MAIL_NOTIFICATION_ENABLE && CourseMemberNotification::findOneBySQL("user_id = ?", [$this->user->user_id])) {
$user_actions->addLink(
_('Benachrichtigungen zurücksetzen'),
$this->url_for("admin/user/reset_notification/{$this->user->id}"),
Icon::create('refresh')
);
}
if ($this->action === 'activities') {
$user_actions->addLink(
_('Alle Dateien des Nutzers aus Veranstaltungen und Einrichtungen als ZIP herunterladen'),
$this->url_for("admin/user/download_user_files/{$this->user->user_id}"),
Icon::create('folder-full')
);
}
if ($this->user->id !== $GLOBALS['user']->id && TFASecret::exists($this->user->id)) {
$user_actions->addLink(
_('Zwei-Faktor-Authentifizierung deaktivieren'),
$this->url_for("admin/user/reset_tfa/{$this->user->id}"),
Icon::create('code-qr')
);
}
$sidebar->insertWidget($user_actions, 'actions', 'user_actions');
// Privacy options
if (Privacy::isVisible($this->user->user_id)) {
$privacy = $sidebar->addWidget(new LinksWidget());
$privacy->setTitle(_('Datenschutz'));
$privacy->addLink(
_('Anzeige Personendaten'),
$this->url_for("privacy/landing/{$this->user->id}"),
Icon::create('log')
)->asDialog('size=medium');
$privacy->addLink(
_('Personendaten drucken'),
$this->url_for("privacy/print/{$this->user->id}"),
Icon::create('print'),
['class' => 'print_action', 'target' => '_blank']
);
$privacy->addLink(
_('Export Personendaten als CSV'),
$this->url_for("privacy/export/{$this->user->id}"),
Icon::create('file-text')
);
$privacy->addLink(
_('Export Personendaten als XML'),
$this->url_for("privacy/xml/{$this->user->id}"),
Icon::create('file-text')
);
$privacy->addLink(
_('Export persönlicher Dateien als ZIP'),
$this->url_for("privacy/filesexport/{$this->user->id}"),
Icon::create('file-archive')
);
}
$views = new ViewsWidget();
$views->addLink(
_('Zurück zur Übersicht'),
$this->url_for('admin/user')
)->setActive(false);
$views->addLink(
_('Person verwalten'),
$this->url_for("admin/user/edit/{$this->user->id}")
)->setActive($this->action === 'edit');
$views->addLink(
_('Zum Profil'),
URLHelper::getURL('dispatch.php/profile', ['username' => $this->user->username]),
Icon::create('person')
);
if ($GLOBALS['perm']->have_perm('root') && count($this->user)) {
$views->addLink(
_('Datei- und Aktivitätsübersicht'),
$this->url_for("admin/user/activities/{$this->user->id}"),
Icon::create('vcard')
)->setActive($this->action === 'activities');
if (Config::get()->LOG_ENABLE) {
$views->addLink(
_('Personeneinträge im Log'),
URLHelper::getURL('dispatch.php/event_log/show?search=' . $this->user->username . '&type=user&object_id=' . $this->user->user_id),
Icon::create('log')
);
}
// Create link to role administration for this user
$extra = '';
$roles = $this->user->getRoles();
$roles_attributes = [];
if ($roles) {
$extra = ' (' . count($roles) . ')';
$title = '• ' . implode("\n• ", array_map(function ($role) {
return $role->rolename;
}, $roles));
$roles_attributes['data-tooltip'] = json_encode([
'html' => htmlReady($title, true, true),
]);
}
$views->addLink(
_('Zur Rollenverwaltung') . $extra,
$this->url_for("admin/role/assign_role/{$this->user->id}"),
Icon::create('roles2'),
$roles_attributes
);
}
$sidebar->insertWidget($views, 'user_actions', 'views');
}
}