aboutsummaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/accessibility/forms.php18
-rw-r--r--app/controllers/activityfeed.php193
-rw-r--r--app/controllers/admin/additional.php2
-rw-r--r--app/controllers/admin/api.php210
-rw-r--r--app/controllers/admin/cache.php11
-rw-r--r--app/controllers/admin/courseplanning.php2
-rw-r--r--app/controllers/admin/courses.php322
-rw-r--r--app/controllers/admin/cronjobs/schedules.php39
-rw-r--r--app/controllers/admin/datafields.php10
-rw-r--r--app/controllers/admin/domain.php2
-rw-r--r--app/controllers/admin/extern.php16
-rw-r--r--app/controllers/admin/install.php4
-rw-r--r--app/controllers/admin/lockrules.php4
-rw-r--r--app/controllers/admin/plugin.php36
-rw-r--r--app/controllers/admin/sem_classes.php2
-rw-r--r--app/controllers/admin/tree.php15
-rw-r--r--app/controllers/admin/user.php10
-rw-r--r--app/controllers/admission/courseset.php48
-rw-r--r--app/controllers/api/authorizations.php58
-rw-r--r--app/controllers/api/oauth.php113
-rw-r--r--app/controllers/api/oauth2/applications.php4
-rw-r--r--app/controllers/api/oauth2/authorize.php4
-rw-r--r--app/controllers/api/oauth2/oauth2_controller.php2
-rw-r--r--app/controllers/api/oauth2/token.php4
-rw-r--r--app/controllers/authenticated_controller.php32
-rw-r--r--app/controllers/avatar.php6
-rw-r--r--app/controllers/blubber.php53
-rw-r--r--app/controllers/calendar/calendar.php101
-rw-r--r--app/controllers/calendar/contentbox.php49
-rw-r--r--app/controllers/calendar/date.php26
-rw-r--r--app/controllers/calendar/schedule.php2
-rw-r--r--app/controllers/captcha.php12
-rw-r--r--app/controllers/consultation/admin.php11
-rw-r--r--app/controllers/consultation/consultation_controller.php11
-rw-r--r--app/controllers/consultation/overview.php2
-rw-r--r--app/controllers/contact.php14
-rw-r--r--app/controllers/contents/courseware.php4
-rw-r--r--app/controllers/course/admission.php8
-rw-r--r--app/controllers/course/basicdata.php26
-rw-r--r--app/controllers/course/block_appointments.php2
-rw-r--r--app/controllers/course/cancel_dates.php2
-rw-r--r--app/controllers/course/change_view.php5
-rw-r--r--app/controllers/course/contentmodules.php16
-rw-r--r--app/controllers/course/courseware.php8
-rw-r--r--app/controllers/course/dates.php5
-rw-r--r--app/controllers/course/details.php2
-rw-r--r--app/controllers/course/enrolment.php2
-rw-r--r--app/controllers/course/forum/forum_controller.php2
-rw-r--r--app/controllers/course/gradebook/lecturers.php4
-rw-r--r--app/controllers/course/grouping.php5
-rw-r--r--app/controllers/course/lti.php31
-rw-r--r--app/controllers/course/lvgselector.php9
-rw-r--r--app/controllers/course/members.php4
-rw-r--r--app/controllers/course/messenger.php10
-rw-r--r--app/controllers/course/overview.php4
-rw-r--r--app/controllers/course/room_requests.php161
-rw-r--r--app/controllers/course/scm.php2
-rw-r--r--app/controllers/course/statusgroups.php18
-rw-r--r--app/controllers/course/study_areas.php3
-rw-r--r--app/controllers/course/studygroup.php11
-rw-r--r--app/controllers/course/timesrooms.php46
-rw-r--r--app/controllers/course/wiki.php215
-rw-r--r--app/controllers/course/wizard.php9
-rw-r--r--app/controllers/debugbar.php24
-rw-r--r--app/controllers/document.php2
-rw-r--r--app/controllers/evaluation.php61
-rw-r--r--app/controllers/extern.php2
-rw-r--r--app/controllers/fachabschluss/kategorien.php6
-rw-r--r--app/controllers/file.php56
-rw-r--r--app/controllers/files.php10
-rw-r--r--app/controllers/institute/basicdata.php2
-rw-r--r--app/controllers/institute/overview.php3
-rw-r--r--app/controllers/jsupdater.php114
-rw-r--r--app/controllers/loncapa.php6
-rw-r--r--app/controllers/lvgruppen/lvgruppen.php21
-rw-r--r--app/controllers/materialien/files.php63
-rw-r--r--app/controllers/media_proxy.php2
-rw-r--r--app/controllers/module/module.php14
-rw-r--r--app/controllers/module/mvv_controller.php6
-rw-r--r--app/controllers/my_courses.php30
-rw-r--r--app/controllers/new_password.php56
-rw-r--r--app/controllers/notifications.php3
-rw-r--r--app/controllers/oer/endpoints.php8
-rw-r--r--app/controllers/plugin_controller.php72
-rw-r--r--app/controllers/privacy.php2
-rw-r--r--app/controllers/profile.php206
-rw-r--r--app/controllers/profilemodules.php2
-rw-r--r--app/controllers/questionnaire.php24
-rw-r--r--app/controllers/quicksearch.php4
-rw-r--r--app/controllers/quickselection.php2
-rw-r--r--app/controllers/resources/ajax.php245
-rw-r--r--app/controllers/resources/booking.php6
-rw-r--r--app/controllers/resources/room_request.php4
-rw-r--r--app/controllers/room_management/planning.php10
-rw-r--r--app/controllers/search/courses.php27
-rw-r--r--app/controllers/search/globalsearch.php57
-rw-r--r--app/controllers/search/studiengaenge.php4
-rw-r--r--app/controllers/settings/general.php2
-rw-r--r--app/controllers/settings/settings.php6
-rw-r--r--app/controllers/shared/contacts.php8
-rw-r--r--app/controllers/shared/download.php4
-rw-r--r--app/controllers/shared/log_event.php4
-rw-r--r--app/controllers/siteinfo.php2
-rw-r--r--app/controllers/start.php7
-rw-r--r--app/controllers/studiengaenge/abschluesse.php6
-rw-r--r--app/controllers/studiengaenge/fachbereiche.php2
-rw-r--r--app/controllers/studiengaenge/fachbereichestgteile.php2
-rw-r--r--app/controllers/studiengaenge/faecher.php2
-rw-r--r--app/controllers/studiengaenge/kategorien.php4
-rw-r--r--app/controllers/studiengaenge/shared_version.php22
-rw-r--r--app/controllers/studiengaenge/studiengaenge.php4
-rw-r--r--app/controllers/studiengaenge/studiengangteile.php2
-rw-r--r--app/controllers/studiengaenge/versionen.php4
-rw-r--r--app/controllers/studip_controller.php875
-rw-r--r--app/controllers/studip_controller_properties_trait.php69
-rw-r--r--app/controllers/studip_response.php55
-rw-r--r--app/controllers/vote.php94
117 files changed, 1727 insertions, 2663 deletions
diff --git a/app/controllers/accessibility/forms.php b/app/controllers/accessibility/forms.php
index f4f9adf..e240a6c 100644
--- a/app/controllers/accessibility/forms.php
+++ b/app/controllers/accessibility/forms.php
@@ -3,6 +3,21 @@ class Accessibility_FormsController extends StudipController
{
protected $with_session = true;
+ public function before_filter(&$action, &$args)
+ {
+ parent::before_filter($action, $args);
+
+ if (
+ Config::get()->REPORT_BARRIER_MODE === 'off'
+ || (
+ Config::get()->REPORT_BARRIER_MODE === 'logged-in'
+ && !User::findCurrent()
+ )
+ ) {
+ throw new AccessDeniedException();
+ }
+ }
+
public function report_barrier_action()
{
PageLayout::setTitle(_('Barriere melden'));
@@ -131,6 +146,9 @@ class Accessibility_FormsController extends StudipController
}
$this->form->addPart($personal_data_part);
+
+ $this->form->addPart(new \Studip\Forms\Captcha());
+
$this->form->setSaveButtonText(_('Barriere melden'));
$this->form->setSaveButtonName('report');
$this->form->setURL($this->report_barrierURL());
diff --git a/app/controllers/activityfeed.php b/app/controllers/activityfeed.php
index 2f93aa1..ee83826 100644
--- a/app/controllers/activityfeed.php
+++ b/app/controllers/activityfeed.php
@@ -53,7 +53,7 @@ class ActivityfeedController extends AuthenticatedController
unset($modules[Context::INSTITUTE]['participants']);
unset($modules[Context::INSTITUTE]['schedule']);
- $standard_plugins = PluginManager::getInstance()->getPlugins("StandardPlugin");
+ $standard_plugins = PluginManager::getInstance()->getPlugins(StandardPlugin::class);
foreach ($standard_plugins as $plugin) {
if ($plugin instanceof ActivityProvider) {
$modules[Context::COURSE][$plugin->getPluginName()] = $plugin->getPluginName();
@@ -67,7 +67,7 @@ class ActivityfeedController extends AuthenticatedController
'blubber' => _('Blubber'),
];
- $homepage_plugins = PluginEngine::getPlugins('HomepagePlugin');
+ $homepage_plugins = PluginEngine::getPlugins(HomepagePlugin::class);
foreach ($homepage_plugins as $plugin) {
if ($plugin->isActivated($GLOBALS['user']->id, 'user')) {
if ($plugin instanceof ActivityProvider) {
@@ -92,4 +92,193 @@ class ActivityfeedController extends AuthenticatedController
PageLayout::setTitle(_('Aktivitäten konfigurieren'));
}
+
+ public function load_action(): void
+ {
+ $user = User::findCurrent();
+
+ // failsafe einbauen - falls es keine älteren Aktivitäten mehr im System gibt, Abbruch!
+
+ $oldest_activity = \Studip\Activity\Activity::getOldestActivity();
+ $max_age = $oldest_activity ? $oldest_activity->mkdate : time();
+
+
+ $contexts = [];
+
+ // create system context
+ $system_context = new \Studip\Activity\SystemContext($user);
+ $contexts[] = $system_context;
+
+ $contexts[] = new \Studip\Activity\UserContext($user, $user);
+ $user->contacts->each(function ($another_user) use (&$contexts, $user) {
+ $contexts[] = new \Studip\Activity\UserContext($another_user, $user);
+ });
+
+ if (!in_array($user->perms, ['admin','root'])) {
+ // create courses and institutes context
+ foreach (\Course::findMany($user->course_memberships->pluck('seminar_id')) as $course) {
+ $contexts[] = new \Studip\Activity\CourseContext($course, $user);
+ }
+ foreach (\Institute::findMany($user->institute_memberships->pluck('institut_id')) as $institute) {
+ $contexts[] = new \Studip\Activity\InstituteContext($institute, $user);
+ }
+ }
+
+
+ // add filters
+ $filter = new \Studip\Activity\Filter();
+
+ $start = Request::int('start', strtotime('yesterday'));
+ $end = Request::int('end', time());
+
+
+ $scrollfrom = Request::int('scrollfrom', false);
+ $filtertype = Request::get('filtertype', '');
+
+ $objectType = Request::get('object_type');
+ $filter->setObjectType($objectType);
+
+ $objectId = Request::get('object_id');
+ $filter->setObjectId($objectId);
+
+ $context = Request::get('context_type');
+ $filter->setContext($context);
+
+ $contextId = Request::get('context_id');
+ $filter->setContextId($contextId);
+
+ if (!empty($filtertype)) {
+ $filter->setType(json_decode($filtertype));
+ }
+
+ if ($scrollfrom) {
+ // shorten "watch-window" by one second to prevent duplication of activities
+ $scrollfrom -= 1;
+
+ if ($scrollfrom > $max_age){
+ $end = $scrollfrom;
+ $start = strtotime('yesterday', $end);
+ $data = [];
+
+ $backtrack = 1;
+
+ while (empty($data)) {
+ $filter->setStartDate($start);
+ $filter->setEndDate($end);
+
+ $data = $this->getStreamData($contexts, $filter);
+
+ if ($start < $max_age) {
+ break;
+ }
+
+ // move "watch-window" back one day at a time
+ $end = $start - 1;
+ $start = strtotime("-{$backtrack} days", $start);
+
+ // enforce maximum "watch-window", currently 2 weeks
+ $backtrack = min(14, $backtrack + 1);
+ }
+ } else {
+ $data = false;
+ }
+ } else {
+ $filter->setStartDate($start);
+ $filter->setEndDate($end);
+ $data = $this->getStreamData($contexts, $filter);
+ }
+
+ // set etag for preventing resending the same stuff over and over again
+ $etag = md5(serialize($data));
+ $this->response->add_header('ETag', '"' . $etag . '"');
+ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $this->etagMatches($etag, $_SERVER['HTTP_IF_NONE_MATCH'])) {
+ $this->set_status(304);
+ $this->render_nothing();
+ return;
+ }
+ if (isset($_SERVER['HTTP_IF_MATCH']) && !$this->etagMatches($etag, $_SERVER['HTTP_IF_MATCH'])) {
+ $this->set_status(412);
+ $this->render_nothing();
+ return;
+ }
+
+ $this->render_json($data);
+ }
+
+ /**
+ * private helper function to get stream data for given contexts and filter
+ *
+ * @param $contexts
+ * @param $filter
+ * @return array
+ */
+
+ private function getStreamData($contexts, $filter): array
+ {
+ $stream = new Studip\Activity\Stream($contexts, $filter);
+ $data = $stream->toArray();
+
+ foreach ($data as $key => $act) {
+ $actor = [
+ 'type' => $act['actor_type'],
+ 'id' => $act['actor_id'],
+ ];
+
+ if ($act['actor_type'] == 'user') {
+ $a_user = \User::findFull($act['actor_id']);
+ $actor['details'] = $this->getMiniUser($a_user ?: new \User());
+ } elseif ($act['actor_type'] === 'anonymous') {
+ $actor['details'] = [
+ 'name' => _('Anonym'),
+ ];
+ }
+
+ unset($data[$key]['actor_type']);
+ unset($data[$key]['actor_id']);
+
+ $data[$key]['actor'] = $actor;
+ }
+
+ return $data;
+ }
+
+ private function getMiniUser(User $user): array
+ {
+ $avatar = \Avatar::getAvatar($user->id);
+
+ return [
+ 'id' => $user->id,
+ 'name' => $this->getNamesOfUser($user),
+ 'avatar_small' => $avatar->getURL(\Avatar::SMALL),
+ 'avatar_medium' => $avatar->getURL(\Avatar::MEDIUM),
+ 'avatar_normal' => $avatar->getURL(\Avatar::NORMAL),
+ 'avatar_original' => $avatar->getURL(\Avatar::NORMAL)
+ ];
+ }
+
+ private function getNamesOfUser(User $user): array
+ {
+ return [
+ 'username' => $user->username,
+ 'formatted' => $user->getFullName(),
+ 'family' => $user->nachname,
+ 'given' => $user->vorname,
+ 'prefix' => $user->title_front,
+ 'suffix' => $user->title_rear,
+ ];
+ }
+
+ // Helper method checking if a ETag value list includes the current ETag.
+ private function etagMatches(string $etag, string $list)
+ {
+ if ($list === '*') {
+ return true;
+ }
+
+ return in_array(
+ $etag,
+ preg_split('/\s*,\s*/', $list)
+ );
+ }
+
}
diff --git a/app/controllers/admin/additional.php b/app/controllers/admin/additional.php
index a98da20..6f8f08c 100644
--- a/app/controllers/admin/additional.php
+++ b/app/controllers/admin/additional.php
@@ -30,6 +30,8 @@ class Admin_AdditionalController extends AuthenticatedController
throw new AccessDeniedException(_("Sie haben keine Berechtigung diese " .
"Veranstaltung zu verändern."));
}
+
+ Sidebar::get()->addWidget(new CourseManagementSelectWidget());
}
/**
diff --git a/app/controllers/admin/api.php b/app/controllers/admin/api.php
deleted file mode 100644
index 96adb65..0000000
--- a/app/controllers/admin/api.php
+++ /dev/null
@@ -1,210 +0,0 @@
-<?php
-/**
- *
- **/
-class Admin_ApiController extends AuthenticatedController
-{
- /**
- *
- **/
- public function before_filter(&$action, &$args)
- {
- parent::before_filter($action, $args);
-
- require_once 'lib/bootstrap-api.php';
-
- $GLOBALS['perm']->check('root');
-
- Navigation::activateItem('/admin/config/api');
- PageLayout::setTitle(_('API Verwaltung'));
-
- $this->types = [
- 'website' => _('Website'),
- 'desktop' => _('Herkömmliches Desktopprogramm'),
- 'mobile' => _('Mobile App')
- ];
-
- // Sidebar
- $views = new ViewsWidget();
- $views->addLink(_('Registrierte Applikationen'),
- $this->url_for('admin/api'))
- ->setActive($action === 'index');
- $views->addLink(_('Globale Zugriffseinstellungen'),
- $this->url_for('admin/api/permissions'))
- ->setActive($action == 'permissions');
- $views->addLink(_('Konfiguration'),
- $this->url_for('admin/api/config'))
- ->setActive($action == 'config');
- Sidebar::get()->addWidget($views);
-
- $actions = new ActionsWidget();
- $actions->addLink(_('Neue Applikation registrieren'),
- $this->url_for('admin/api/edit'),
- Icon::create('add', 'clickable'))
- ->asDialog();
- Sidebar::get()->addWidget($actions);
- }
-
- /**
- *
- **/
- public function index_action()
- {
- $this->consumers = RESTAPI\Consumer\Base::findAll();
- $this->routes = RESTAPI\Router::getInstance()->getRoutes(true);
- }
-
- /**
- *
- **/
- public function render_keys($id)
- {
- $consumer = RESTAPI\Consumer\Base::find($id);
-
- return [
- 'Consumer Key = ' . $consumer->auth_key,
- 'Consumer Secret = ' . $consumer->auth_secret,
- ];
- }
-
- /**
- *
- **/
- public function keys_action($id)
- {
- $details = $this->render_keys($id);
-
- if (Request::isXhr()) {
- $this->render_text(implode('<br>', $details));
- } else {
- PageLayout::postMessage(MessageBox::info(_('Die Schlüssel in den Details dieser Meldung sollten vertraulich behandelt werden!'), $details, true));
- $this->redirect('admin/api/#' . $id);
- }
- }
-
- /**
- *
- **/
- public function edit_action($id = null)
- {
- $consumer = $id
- ? RESTAPI\Consumer\Base::find($id)
- : RESTAPI\Consumer\Base::create(Request::option('consumer_type') ?: 'oauth');
-
- if (Request::submitted('store')) {
- $errors = [];
-
- $consumer->active = (bool) Request::int('active');
- $consumer->title = Request::get('title');
- $consumer->contact = Request::get('contact');
- $consumer->email = Request::get('email');
- $consumer->callback = Request::get('callback');
- $consumer->url = Request::get('url');
- $consumer->type = Request::get('type') ?: null;
- $consumer->commercial = Request::int('commercial');
- $consumer->notes = Request::get('notes');
- $consumer->description = Request::get('description');
-
- if (!empty($errors)) {
- $message = MessageBox::error(_('Folgende Fehler sind aufgetreten:'), $errors);
- PageLayout::postMessage($message);
- return;
- }
-
- $consumer->store();
-
- if ($id) {
- $message = MessageBox::success(_('Die Applikation wurde erfolgreich gespeichert.'));
- } else {
- $details = $this->render_keys($consumer->id);
- $message = MessageBox::success(_('Die Applikation wurde erfolgreich erstellt, die Schlüssel finden Sie in den Details dieser Meldung.'), $details, true);
- }
- PageLayout::postMessage($message);
- $this->redirect('admin/api/index#' . $consumer->id);
- return;
- }
-
- $this->consumer = $consumer;
- $this->id = $id;
- }
-
- /**
- *
- **/
- public function toggle_action($id, $state = null)
- {
- $consumer = RESTAPI\Consumer\Base::find($id);
-
- $consumer->active = $state === null ? !$consumer->active : ($state === 'on');
- $consumer->store();
-
- $message = $state
- ? _('Die Applikation wurde erfolgreich aktiviert.')
- : _('Die Applikation wurde erfolgreich deaktiviert.');
-
- PageLayout::postMessage(MessageBox::success($message));
- $this->redirect('admin/api/#' . $consumer->id);
- }
-
- /**
- *
- **/
- public function delete_action($id)
- {
- if (!Request::isPost()) {
- throw new MethodNotAllowedException();
- }
- if ($consumer = RESTAPI\Consumer\Base::find($id)) {
- $consumer->delete();
-
- PageLayout::postSuccess(_('Die Applikation wurde erfolgreich gelöscht.'));
- }
- $this->redirect('admin/api');
- }
-
- /**
- *
- **/
- public function permissions_action($consumer_id = null)
- {
- if (Request::submitted('store')) {
- $perms = Request::getArray('permission');
- $permissions = RESTAPI\ConsumerPermissions::get($consumer_id ?: 'global');
-
- foreach ($perms as $route => $methods) {
- foreach ($methods as $method => $granted) {
- $permissions->set(urldecode($route), urldecode($method), (bool)$granted, true);
- }
- }
-
- $permissions->store();
-
- PageLayout::postMessage(MessageBox::success(_('Die Zugriffsberechtigungen wurden erfolgreich gespeichert')));
- $this->redirect($consumer_id ? 'admin/api' : 'admin/api/permissions');
- return;
- }
-
- $title = $consumer_id ? _('Zugriffsberechtigungen') : _('Globale Zugriffsberechtigungen');
- $title .= ' - ' . PageLayout::getTitle();
- PageLayout::setTitle($title);
-
- $this->consumer_id = $consumer_id;
- $this->router = RESTAPI\Router::getInstance();
- $this->routes = $this->router->getRoutes(true, false);
- $this->permissions = RESTAPI\ConsumerPermissions::get($consumer_id ?: 'global');
- $this->global = $consumer_id ? RESTAPI\ConsumerPermissions::get('global') : false;
- }
-
- public function config_action()
- {
- $this->config = Config::get();
-
- if (Request::isPost()) {
- $this->config->store('API_ENABLED', Request::int('active', 0));
- $this->config->store('API_OAUTH_AUTH_PLUGIN', Request::option('auth'));
-
- PageLayout::postMessage(MessageBox::success(_('Die Einstellungen wurden gespeichert.')));
- $this->redirect('admin/api/config');
- }
- }
-}
diff --git a/app/controllers/admin/cache.php b/app/controllers/admin/cache.php
index 329aab7..c016af5 100644
--- a/app/controllers/admin/cache.php
+++ b/app/controllers/admin/cache.php
@@ -81,11 +81,10 @@ class Admin_CacheController extends AuthenticatedController
/**
* Fetches necessary configuration for given cache type.
- *
- * @param string $className
*/
- public function get_config_action($className)
+ public function get_config_action()
{
+ $className = Request::get('cache');
$type = CacheType::findOneByClass_name($className);
$this->render_json($type->class_name::getConfig());
@@ -111,7 +110,7 @@ class Admin_CacheController extends AuthenticatedController
// Store settings to global config.
if (Config::get()->store('SYSTEMCACHE', $settings)) {
PageLayout::postSuccess(_('Die Einstellungen wurden gespeichert.'));
- StudipCacheFactory::unconfigure();
+ \Studip\Cache\Factory::unconfigure();
}
$this->relocate('admin/cache/settings');
@@ -122,7 +121,7 @@ class Admin_CacheController extends AuthenticatedController
*/
public function flush_action()
{
- $cache = StudipCacheFactory::getCache();
+ $cache = \Studip\Cache\Factory::getCache();
$cache->flush();
PageLayout::postSuccess(_('Die Inhalte des Caches wurden gelöscht.'));
@@ -135,7 +134,7 @@ class Admin_CacheController extends AuthenticatedController
*/
public function stats_action()
{
- $cache = StudipCacheFactory::getCache();
+ $cache = \Studip\Cache\Factory::getCache();
$this->stats = $cache->getStats();
}
diff --git a/app/controllers/admin/courseplanning.php b/app/controllers/admin/courseplanning.php
index b8971e2..44b372d 100644
--- a/app/controllers/admin/courseplanning.php
+++ b/app/controllers/admin/courseplanning.php
@@ -82,7 +82,7 @@ class Admin_CourseplanningController extends AuthenticatedController
foreach ($this->events as $event) {
$start_date_time = explode('T', $event['start']);
$time_elements = explode(':', $start_date_time[1]);
- if (!$event['comform'] || $time_elements[0] % 2) {
+ if (!$event['conform'] || $time_elements[0] % 2) {
Sidebar::get()->getWidget('actions')->addLink(
_('Veranstaltungen außerhalb des Rasters'),
$this->nonconformURL(),
diff --git a/app/controllers/admin/courses.php b/app/controllers/admin/courses.php
index 6f9312d..5f60442 100644
--- a/app/controllers/admin/courses.php
+++ b/app/controllers/admin/courses.php
@@ -22,6 +22,7 @@
* @category Stud.IP
* @since 3.1
*/
+
require_once 'lib/meine_seminare_func.inc.php';
require_once 'lib/object.inc.php';
require_once 'lib/archiv.inc.php'; //for lastActivity in getCourses() method
@@ -293,7 +294,7 @@ class Admin_CoursesController extends AuthenticatedController
PageLayout::setTitle(_('Verwaltung von Veranstaltungen und Einrichtungen'));
// Add admission functions.
PageLayout::addScript('studip-admission.js');
- $this->max_show_courses = 500;
+ $this->max_show_courses = Config::get()->MAX_SHOW_ADMIN_COURSES;
}
/**
@@ -322,6 +323,9 @@ class Admin_CoursesController extends AuthenticatedController
$institut_id = $configuration->MY_INSTITUTES_DEFAULT && $configuration->MY_INSTITUTES_DEFAULT !== 'all'
? $configuration->MY_INSTITUTES_DEFAULT
: null;
+ if ($configuration->MY_INSTITUTES_INCLUDE_CHILDREN) {
+ $institut_id .= '_withinst';
+ }
$filters = array_merge(
array_merge(...PluginEngine::sendMessage(AdminCourseWidgetPlugin::class, 'getFilters')),
@@ -375,14 +379,14 @@ class Admin_CoursesController extends AuthenticatedController
}
PluginEngine::sendMessage(AdminCourseWidgetPlugin::class, 'applyFilters', $filter);
- $count = $filter->countCourses();
- if ($count > $this->max_show_courses && !Request::submitted('without_limit')) {
- $this->render_json([
- 'count' => $count
- ]);
+ try {
+ $courses = $filter->fetchCourses(
+ Request::bool('without_limit') ? null: $this->max_show_courses
+ );
+ } catch (OverflowException $e) {
+ $this->render_json(['count' => (int) $e->getMessage()]);
return;
}
- $courses = AdminCourseFilter::get()->getCourses();
$data = [
'data' => []
@@ -417,7 +421,7 @@ class Admin_CoursesController extends AuthenticatedController
}
}
}
- $tf = new Flexi_TemplateFactory($GLOBALS['STUDIP_BASE_PATH'] . '/app/views');
+ $tf = new Flexi\Factory($GLOBALS['STUDIP_BASE_PATH'] . '/app/views');
switch ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA) {
case 1:
case 2:
@@ -487,12 +491,12 @@ class Admin_CoursesController extends AuthenticatedController
]);
break;
default:
- foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(AdminCourseAction::class) as $plugin) {
if ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA === get_class($plugin)) {
$multimode = $plugin->useMultimode();
if ($multimode) {
$data['buttons_top'] = '<label>'._('Alle auswählen').'<input type="checkbox" data-proxyfor=".course-admin td:last-child :checkbox"></label>';
- if ($multimode instanceof Flexi_Template) {
+ if ($multimode instanceof Flex\Template) {
$data['buttons_bottom'] = $multimode->render();
} elseif ($multimode instanceof \Studip\Button) {
$data['buttons_bottom'] = (string) $multimode;
@@ -531,14 +535,60 @@ class Admin_CoursesController extends AuthenticatedController
'institut_id' => 'MY_INSTITUTES_DEFAULT',
];
+ if (!empty($filters['institut_id'])) {
+ $config->store(
+ 'MY_INSTITUTES_INCLUDE_CHILDREN',
+ str_contains($filters['institut_id'], '_') ? 1 : 0
+ );
+ if ($config->MY_INSTITUTES_INCLUDE_CHILDREN) {
+ $filters['institut_id'] = substr($filters['institut_id'], 0, strpos($filters['institut_id'], '_'));
+ }
+ }
+
foreach ($mapping as $key => $field) {
if (isset($filters[$key])) {
$config->store($field, $filters[$key]);
}
-
unset($filters[$key]);
}
+ if ($config->ADMIN_COURSES_TEACHERFILTER) {
+ if (!$config->MY_INSTITUTES_DEFAULT) {
+ $config->delete('ADMIN_COURSES_TEACHERFILTER');
+ } else {
+ $include_children = $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN ? ' OR Institute.fakultaets_id = :institut_id ' : '';
+
+ $exists = InstituteMember::countBySQL("INNER JOIN `Institute` USING (`Institut_id`) WHERE `user_inst`.`user_id` = :user_id AND (`Institute`.`Institut_id` = :institut_id $include_children) AND `user_inst`.`inst_perms` = 'dozent' ", [
+ 'user_id' => $config->ADMIN_COURSES_TEACHERFILTER,
+ 'institut_id' => $config->MY_INSTITUTES_DEFAULT
+ ]) > 0;
+ if (!$exists) {
+ $config->delete('ADMIN_COURSES_TEACHERFILTER');
+ }
+ }
+ }
+ if ($config->MY_COURSES_SELECTED_STGTEIL) {
+ if (!$config->MY_INSTITUTES_DEFAULT) {
+ $config->delete('MY_COURSES_SELECTED_STGTEIL');
+ } else {
+ $statement = DBManager::get()->prepare("
+ SELECT 1
+ FROM `mvv_stg_stgteil`
+ INNER JOIN `mvv_studiengang` ON (`mvv_stg_stgteil`.`studiengang_id` = `mvv_studiengang`.`studiengang_id`)
+ WHERE `mvv_studiengang`.`institut_id` = :institut_id
+ AND `mvv_stg_stgteil`.`stgteil_id` = :stgteil_id
+ ");
+ $statement->execute([
+ 'institut_id' => $config->MY_INSTITUTES_DEFAULT,
+ 'stgteil_id' => $config->MY_COURSES_SELECTED_STGTEIL
+ ]);
+ $exists = (bool) $statement->fetch(PDO::FETCH_COLUMN);
+ if (!$exists) {
+ $config->delete('MY_COURSES_SELECTED_STGTEIL');
+ }
+ }
+ }
+
// Datafield filters
$activeSidebarElements = $this->getActiveElements();
@@ -576,19 +626,19 @@ class Admin_CoursesController extends AuthenticatedController
if (in_array('name', $activated_fields)) {
$params = tooltip2(_('Veranstaltungsdetails anzeigen'));
$params['style'] = 'cursor: pointer';
- $d['name'] = '<a href="'.URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id]).'">'
+ $d['name'] = '<a href="'.URLHelper::getLink('dispatch.php/course/basicdata/view', ['cid' => $course->id]).'">'
. htmlReady($course->name)
.'</a> '
.'<a href="'.URLHelper::getLink('dispatch.php/course/details/index/'. $course->id).'" data-dialog><button class="undecorated">'.Icon::create('info-circle', Icon::ROLE_INACTIVE)->asImg($params).'</button></a> '
.(!$course->visible ? _('(versteckt)') : '');
}
if (in_array('number', $activated_fields)) {
- $d['number'] = '<a href="'.URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id]).'">'
+ $d['number'] = '<a href="'.URLHelper::getLink('dispatch.php/course/basicdata/view', ['cid' => $course->id]).'">'
.$course->veranstaltungsnummer
.'</a>';
}
if (in_array('avatar', $activated_fields)) {
- $d['avatar'] = '<a href="'.URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id]).'">'
+ $d['avatar'] = '<a href="'.URLHelper::getLink('dispatch.php/course/basicdata/view', ['cid' => $course->id]).'">'
.CourseAvatar::getAvatar($course->getId())->getImageTag(Avatar::SMALL, ['title' => $course->name])
."</a>";
}
@@ -604,6 +654,7 @@ class Admin_CoursesController extends AuthenticatedController
}
if (in_array('semester', $activated_fields)) {
$d['semester'] = $course->semester_text;
+ $d['semester_sort'] = $course->start_semester ? $course->start_semester->beginn : 0;
}
if (in_array('institute', $activated_fields)) {
$d['institute'] = $course->home_institut ? $course->home_institut->name : $course->institute;
@@ -620,7 +671,7 @@ class Admin_CoursesController extends AuthenticatedController
}
if (in_array('members', $activated_fields)) {
$d['members'] = '<a href="'.URLHelper::getLink('dispatch.php/course/members', ['cid' => $course->id]).'">'
- .$course->getNumParticipants()
+ .$course->countMembersWithStatus('user autor')
.'</a>';
}
if (in_array('waiting', $activated_fields)) {
@@ -663,15 +714,18 @@ class Admin_CoursesController extends AuthenticatedController
$d['last_activity_raw'] = $last_activity;
}
- foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(AdminCourseContents::class) as $plugin) {
foreach ($plugin->adminAvailableContents() as $index => $label) {
if (in_array($plugin->getPluginId() . '_' . $index, $activated_fields)) {
$content = $plugin->adminAreaGetCourseContent($course, $index);
- $d[$plugin->getPluginId()."_".$index] = $content instanceof Flexi_Template ? $content->render() : $content;
+ if ($content instanceof Flexi\Template) {
+ $content = $content->render();
+ }
+ $d[$plugin->getPluginId()."_".$index] = $content;
}
}
}
- $tf = new Flexi_TemplateFactory($GLOBALS['STUDIP_BASE_PATH'].'/app/views');
+ $tf = new Flexi\Factory($GLOBALS['STUDIP_BASE_PATH'].'/app/views');
switch ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA) {
case 1:
@@ -789,10 +843,13 @@ class Admin_CoursesController extends AuthenticatedController
$d['action'] = $template->render();
break;
default:
- foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(AdminCourseAction::class) as $plugin) {
if ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA === get_class($plugin)) {
$output = $plugin->getAdminCourseActionTemplate($course->getId());
- $d['action'] = $output instanceof Flexi_Template ? $output->render() : (string) $output;
+ if ($output instanceof Flexi\Template) {
+ $output = $output->render();
+ }
+ $d['action'] = (string) $output;
break;
}
}
@@ -981,14 +1038,14 @@ class Admin_CoursesController extends AuthenticatedController
$row['institute'] = $course->home_institut ? (string) $course->home_institut['name'] : $course['institut_id'];
}
- foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(AdminCourseContents::class) as $plugin) {
foreach ($plugin->adminAvailableContents() as $index => $label) {
if (in_array($plugin->getPluginId() . "_" . $index, $filter_config)) {
$content = $plugin->adminAreaGetCourseContent($course, $index);
- $row[$plugin->getPluginId() . "_" . $index] = strip_tags(is_a($content, 'Flexi_Template')
- ? $content->render()
- : $content
- );
+ if ($content instanceof Flexi\Template) {
+ $content = $content->render();
+ }
+ $row[$plugin->getPluginId() . "_" . $index] = strip_tags($content);
}
}
}
@@ -1000,7 +1057,7 @@ class Admin_CoursesController extends AuthenticatedController
foreach ($filter_config as $index) {
$captions[$index] = $view_filters[$index];
}
- foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(AdminCourseContents::class) as $plugin) {
foreach ($plugin->adminAvailableContents() as $index => $label) {
if (in_array($plugin->getPluginId() . "_" . $index, $filter_config)) {
$captions[$plugin->getPluginId() . "_" . $index] = $label;
@@ -1398,7 +1455,7 @@ class Admin_CoursesController extends AuthenticatedController
ksort($actions);
- foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(AdminCourseAction::class) as $plugin) {
$actions[get_class($plugin)] = [
'name' => $plugin->getPluginName(),
'title' => $plugin->getPluginName(),
@@ -1438,7 +1495,7 @@ class Admin_CoursesController extends AuthenticatedController
'contents' => _('Inhalt'),
'last_activity' => _('Letzte Aktivität'),
];
- foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(AdminCourseContents::class) as $plugin) {
foreach ($plugin->adminAvailableContents() as $index => $label) {
$views[$plugin->getPluginId() . "_" . $index] = $label;
}
@@ -1446,169 +1503,6 @@ class Admin_CoursesController extends AuthenticatedController
return $views;
}
- /**
- * Returns all courses matching set criteria.
- *
- * @param array $params Additional parameters
- * @param bool $display_all : boolean should we show all courses or check for a limit of 500 courses?
- * @return array of courses
- */
- private function getCourses($params = [], $display_all = false)
- {
- // Init
- if ($GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === "all") {
- $inst = new SimpleCollection($this->insts);
- $inst->filter(function ($a) use (&$inst_ids) {
- $inst_ids[] = $a->Institut_id;
- });
- } else {
- //We must check, if the institute ID belongs to a faculty
- //and has the string _i appended to it.
- //In that case we must display the courses of the faculty
- //and all its institutes.
- //Otherwise we just display the courses of the faculty.
-
- $inst_id = $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT;
-
- $institut = new Institute($inst_id);
-
- if (!$institut->isFaculty() || $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN) {
- // If the institute is not a faculty or the child insts are included,
- // pick the institute IDs of the faculty/institute and of all sub-institutes.
- $inst_ids[] = $inst_id;
- if ($institut->isFaculty()) {
- foreach ($institut->sub_institutes->pluck('Institut_id') as $institut_id) {
- $inst_ids[] = $institut_id;
- }
- }
- } else {
- // If the institute is a faculty and the child insts are not included,
- // pick only the institute id of the faculty:
- $inst_ids[] = $inst_id;
- }
- }
-
- $active_elements = $this->getActiveElements();
-
- $filter = AdminCourseFilter::get(true);
-
- if ($params['datafields']) {
- foreach ($params['datafields'] as $field_id => $value) {
- $datafield = DataField::find($field_id);
- if ($datafield) {
- //enable filtering by datafield values:
- //and use the where-clause for each datafield:
- $filter->settings['query']['joins']['de_'.$field_id] = [
- 'table' => "datafields_entries",
- 'join' => "LEFT JOIN",
- 'on' => "seminare.seminar_id = de_".$field_id.".range_id"
- ];
- $filter->where("(de_".$field_id.".datafield_id = :fieldId_".$field_id." "
- . "AND de_".$field_id.".content = :fieldValue_".$field_id.") "
- . ($datafield['default_value'] == $value ? " OR (de_".$field_id.".content IS NULL)" : "")." ",
- [
- 'fieldId_'.$field_id => $field_id,
- 'fieldValue_'.$field_id => $value
- ]
- );
- }
- }
- }
-
- $filter->where("sem_classes.studygroup_mode = '0'");
-
- // Get only children of given course
- if (!empty($params['parent_course'])) {
- $filter->where("parent_course = :parent",
- [
- 'parent' => $params['parent_course']
- ]
- );
- }
-
- if ($active_elements['semester'] && is_object($this->semester)) {
- $filter->filterBySemester($this->semester->getId());
- }
- if ($active_elements['courseType'] && $params['typeFilter'] && $params['typeFilter'] !== "all") {
- $parts = explode('_', $params['typeFilter']);
- $class_filter = $parts[0];
- $type_filter = $parts[1] ?? null;
- if (!$type_filter && !empty($GLOBALS['SEM_CLASS'][$class_filter])) {
- $type_filter = array_keys($GLOBALS['SEM_CLASS'][$class_filter]->getSemTypes());
- }
- $filter->filterByType($type_filter);
- }
- if ($active_elements['search'] && $GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT) {
- $filter->filterBySearchString($GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT);
- }
- if ($active_elements['teacher'] && $GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER && ($GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER !== "all")) {
- $filter->filterByDozent($GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER);
- }
- if ($active_elements['institute']) {
- $filter->filterByInstitute($inst_ids);
- }
- if ($GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL && $GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL !== 'all') {
- $filter->filterByStgTeil($GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL);
- }
- if ($params['sortby'] === "status") {
- $filter->orderBy(sprintf('sem_classes.name %s, sem_types.name %s, VeranstaltungsNummer %s', $params['sortFlag'], $params['sortFlag'], $params['sortFlag']), $params['sortFlag']);
- } elseif ($params['sortby'] === 'institute') {
- $filter->orderBy('Institute.Name', $params['sortFlag']);
- } elseif ($params['sortby']) {
- $filter->orderBy($params['sortby'], $params['sortFlag']);
- }
- $filter->storeSettings();
- $this->count_courses = $filter->countCourses();
- if ($this->count_courses && ($this->count_courses <= $filter->max_show_courses || $display_all)) {
- $courses = $filter->getCourses();
- } else {
- return [];
- }
-
- $seminars = [];
- if (!empty($courses)) {
- foreach ($courses as $seminar_id => $seminar) {
- $seminars[$seminar_id] = $seminar[0];
- $seminars[$seminar_id]['seminar_id'] = $seminar_id;
- $seminars[$seminar_id]['obj_type'] = 'sem';
- $dozenten = $this->getTeacher($seminar_id);
- $seminars[$seminar_id]['dozenten'] = $dozenten;
-
- if (in_array('contents', $params['view_filter'])) {
- $tools = new SimpleCollection(ToolActivation::findbyRange_id($seminar_id, "ORDER BY position"));
- $visit_data = get_objects_visits([$seminar_id], 0, null, null, $tools->pluck('plugin_id'));
- $seminars[$seminar_id]['visitdate'] = $visit_data[$seminar_id][0]['visitdate'];
- $seminars[$seminar_id]['last_visitdate'] = $visit_data[$seminar_id][0]['last_visitdate'];
- $seminars[$seminar_id]['tools'] = $tools;
- $seminars[$seminar_id]['navigation'] = MyRealmModel::getAdditionalNavigations(
- $seminar_id,
- $seminars[$seminar_id],
- $seminars[$seminar_id]['sem_class'] ?? null,
- $GLOBALS['user']->id,
- $visit_data[$seminar_id]
- );
- }
- //add last activity column:
- if (in_array('last_activity', $params['view_filter'])) {
- $seminars[$seminar_id]['last_activity'] = lastActivity($seminar_id);
- }
- if ((int)$this->selected_action === 17) {
- $seminars[$seminar_id]['admission_locked'] = false;
- if ($seminar[0]['course_set']) {
- $set = new CourseSet($seminar[0]['course_set']);
- if (!is_null($set) && $set->hasAdmissionRule('LockedAdmission')) {
- $seminars[$seminar_id]['admission_locked'] = 'locked';
- } else {
- $seminars[$seminar_id]['admission_locked'] = 'disable';
- }
- unset($set);
- }
- }
- }
- }
-
- return $seminars;
- }
/**
* Returns the teacher for a given cours
@@ -1650,6 +1544,7 @@ class Admin_CoursesController extends AuthenticatedController
$institut['Institut_id'],
(!$institut['is_fak'] ? ' ' : '') . $institut['Name'],
$GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === $institut['Institut_id']
+ && !$GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN
);
//check if the institute is a faculty.
@@ -1662,7 +1557,8 @@ class Admin_CoursesController extends AuthenticatedController
new SelectElement(
$institut['Institut_id'] . '_withinst', //_withinst = with institutes
' ' . $institut['Name'] . ' +' . _('Institute'),
- ($GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === $institut['Institut_id'] && $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN)
+ $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === $institut['Institut_id']
+ && $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN
);
}
}
@@ -1695,6 +1591,9 @@ class Admin_CoursesController extends AuthenticatedController
private function getStgteilSelector($institut_id = null)
{
$institut_id = $institut_id ?: $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT;
+ if (str_contains($institut_id, '_')) {
+ $institut_id = substr($institut_id, 0, strpos($institut_id, '_'));
+ }
$stgteile = StudiengangTeil::getAllEnriched('fach_name', 'ASC', ['mvv_fach_inst.institut_id' => $institut_id]);
$list = [];
if (!$institut_id || $institut_id === 'all') {
@@ -1782,27 +1681,42 @@ class Admin_CoursesController extends AuthenticatedController
*/
private function getTeacherWidget($institut_id = null)
{
- $institut_id = $institut_id ?: $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT;
- $teachers = DBManager::get()->fetchAll("
+ if ($institut_id) {
+ if (str_contains($institut_id, '_')) {
+ $institut_id = substr($institut_id, 0, strpos($institut_id, '_'));
+ $GLOBALS['user']->cfg->store('MY_INSTITUTES_INCLUDE_CHILDREN', 1);
+ } else {
+ $GLOBALS['user']->cfg->store('MY_INSTITUTES_INCLUDE_CHILDREN', 0);
+ }
+ } else {
+ $institut_id = $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT;
+ }
+
+ $teachers = [];
+ $include_children = $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN ? ' OR Institute.fakultaets_id = :institut_id ' : '';
+
+ if ($institut_id) {
+ $teachers = DBManager::get()->fetchAll("
SELECT auth_user_md5.*, user_info.*
FROM auth_user_md5
LEFT JOIN user_info ON (auth_user_md5.user_id = user_info.user_id)
INNER JOIN user_inst ON (user_inst.user_id = auth_user_md5.user_id)
INNER JOIN Institute ON (Institute.Institut_id = user_inst.Institut_id)
- WHERE (Institute.Institut_id = :institut_id OR Institute.fakultaets_id = :institut_id)
- AND auth_user_md5.perms = 'dozent'
+ WHERE (Institute.Institut_id = :institut_id $include_children)
+ AND user_inst.inst_perms = 'dozent'
+ GROUP BY auth_user_md5.user_id
ORDER BY auth_user_md5.Nachname ASC, auth_user_md5.Vorname ASC
", [
'institut_id' => $institut_id
],
- function ($data) {
- $ret['user_id'] = $data['user_id'];
- unset($data['user_id']);
- $ret['fullname'] = User::build($data)->getFullName("full_rev");
- return $ret;
- }
- );
-
+ function ($data) {
+ $ret['user_id'] = $data['user_id'];
+ unset($data['user_id']);
+ $ret['fullname'] = User::build($data)->getFullName("full_rev");
+ return $ret;
+ }
+ );
+ }
$list = [];
if (!$institut_id || $institut_id === 'all') {
diff --git a/app/controllers/admin/cronjobs/schedules.php b/app/controllers/admin/cronjobs/schedules.php
index 294d78d..929ae29 100644
--- a/app/controllers/admin/cronjobs/schedules.php
+++ b/app/controllers/admin/cronjobs/schedules.php
@@ -29,7 +29,7 @@ class Admin_Cronjobs_SchedulesController extends AuthenticatedController
if (empty($_SESSION['cronjob-filter'])) {
$_SESSION['cronjob-filter'] = [
'where' => '1',
- 'values' => array_fill_keys(['type', 'status', 'task_id'], null),
+ 'values' => array_fill_keys(['status', 'task_id'], null),
];
}
@@ -102,9 +102,6 @@ class Admin_Cronjobs_SchedulesController extends AuthenticatedController
$filter = array_filter(Request::optionArray('filter'));
$conditions = [];
- if (!empty($filter['type'])) {
- $conditions[] = "type = " . DBManager::get()->quote($filter['type']);
- }
if (!empty($filter['status'])) {
$active = (int)($filter['status'] === 'active');
$conditions[] = "active = " . DBManager::get()->quote($active);
@@ -130,7 +127,6 @@ class Admin_Cronjobs_SchedulesController extends AuthenticatedController
if (Request::submitted('store')) {
$parameters = Request::getArray('parameters');
- $schedule->priority = Request::option('priority', 'normal');
$schedule->title = Request::get('title');
$schedule->description = Request::get('description');
$schedule->active = Request::int('active', 0);
@@ -138,27 +134,20 @@ class Admin_Cronjobs_SchedulesController extends AuthenticatedController
$schedule->task_id = Request::option('task_id');
}
$schedule->parameters = $parameters[$schedule->task_id];
- $schedule->type = Request::option('type') === 'once'
- ? 'once'
- : 'periodic';
-
- if ($schedule->type === 'once') {
- $temp = Request::getArray('once');
- $schedule->next_execution = strtotime($temp['date'] . ' ' . $temp['time']);
- } else {
- $temp = Request::getArray('periodic');
- $schedule->minute = $this->extractCronItem($temp['minute']);
- $schedule->hour = $this->extractCronItem($temp['hour']);
- $schedule->day = $this->extractCronItem($temp['day']);
- $schedule->month = $this->extractCronItem($temp['month']);
- $schedule->day_of_week = mb_strlen($temp['day_of_week']['value'])
- ? (int) $temp['day_of_week']['value']
- : null;
-
- if ($schedule->active) {
- $schedule->next_execution = $schedule->calculateNextExecution();
- }
+
+ $temp = Request::getArray('periodic');
+ $schedule->minute = $this->extractCronItem($temp['minute']);
+ $schedule->hour = $this->extractCronItem($temp['hour']);
+ $schedule->day = $this->extractCronItem($temp['day']);
+ $schedule->month = $this->extractCronItem($temp['month']);
+ $schedule->day_of_week = mb_strlen($temp['day_of_week']['value'])
+ ? (int) $temp['day_of_week']['value']
+ : null;
+
+ if ($schedule->active) {
+ $schedule->next_execution = $schedule->calculateNextExecution();
}
+
$schedule->store();
PageLayout::postSuccess(_('Die Änderungen wurden gespeichert.'));
diff --git a/app/controllers/admin/datafields.php b/app/controllers/admin/datafields.php
index bf390c9..6019a13 100644
--- a/app/controllers/admin/datafields.php
+++ b/app/controllers/admin/datafields.php
@@ -94,15 +94,17 @@ class Admin_DatafieldsController extends AuthenticatedController
if (Request::submitted('uebernehmen')) {
if (Request::get('datafield_name')) {
- $datafield->name = Request::i18n('datafield_name');
- if ($datafield->object_type === 'moduldeskriptor'
- || $datafield->object_type === 'modulteildeskriptor') {
+ $datafield->name = Request::i18n('datafield_name');
+ if (
+ $datafield->object_type === 'moduldeskriptor'
+ || $datafield->object_type === 'modulteildeskriptor'
+ ) {
$object_class = implode(',', Request::getArray('object_class'));
$datafield->object_class = (trim($object_class) && $object_class != 'NULL') ? $object_class : null;
} elseif ($datafield->object_type === 'studycourse') {
$datafield->object_class = trim(Request::option('object_class', 'all_settings'));
} else {
- $datafield->object_class = array_sum(Request::getArray('object_class')) ?: null;
+ $datafield->object_class = array_sum(Request::intArray('object_class')) ?: null;
}
$datafield->edit_perms = Request::get('edit_perms');
$datafield->view_perms = Request::get('visibility_perms');
diff --git a/app/controllers/admin/domain.php b/app/controllers/admin/domain.php
index e4bb9c8..37ab11f 100644
--- a/app/controllers/admin/domain.php
+++ b/app/controllers/admin/domain.php
@@ -70,7 +70,7 @@ class Admin_DomainController extends AuthenticatedController
{
foreach ($args as $arg) {
if ($arg && !preg_match('/' . UserDomain::REGEXP . '/', $arg)) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
}
diff --git a/app/controllers/admin/extern.php b/app/controllers/admin/extern.php
index 41833b1..732b586 100644
--- a/app/controllers/admin/extern.php
+++ b/app/controllers/admin/extern.php
@@ -66,8 +66,8 @@ class Admin_ExternController extends AuthenticatedController
ExternPageConfig::findEachBySQL(
function ($c) use (&$configs, &$count_not_migrated) {
$configs[$c->type][] = $c;
- if (isset($c->conf['not_fixed_after_migration'])) {
- $count_not_migrated++;
+ if (isset($c->conf['not_fixed_after_migration'])) {
+ $count_not_migrated++;
}
},
"range_id = ?", [$this->range]
@@ -165,7 +165,7 @@ class Admin_ExternController extends AuthenticatedController
if ($this->page->page_config->isNew()) {
PageLayout::postSuccess(sprintf(
_('Eine neue externe Seite "%$1s" vom Typ %$2s wurde angelegt.'),
- htmlReady($this->page->name),
+ htmlReady($this->page->name),
htmlReady($this->page->type)
));
} else {
@@ -259,7 +259,11 @@ class Admin_ExternController extends AuthenticatedController
*/
public function info_action(string $config_id)
{
- $this->page = ExternPage::get(ExternPageConfig::find($config_id));
+ $config = ExternPageConfig::find($config_id);
+ if (!$config) {
+ throw new Exception('ExternPageConfig object not found!');
+ }
+ $this->page = ExternPage::get($config);
if ($this->page->author) {
$this->author = '<a href="'
. URLHelper::getLink('dispatch.php/profile', ['username' => $this->page->author->username])
@@ -364,7 +368,7 @@ class Admin_ExternController extends AuthenticatedController
$config->author_id = $config->editor_id = $GLOBALS['user']->id;
$config->store();
PageLayout::postSuccess(
- sprintf(_('Die Konfiguration "%s" wurde erfolgreich importiert.'),
+ sprintf(_('Die Konfiguration "%s" wurde erfolgreich importiert.'),
htmlReady($config->name)
));
}
@@ -436,7 +440,7 @@ class Admin_ExternController extends AuthenticatedController
*/
protected function fetchPlugins(bool $is_system): void
{
- $plugins = PluginEngine::getPlugins('ExternPagePlugin');
+ $plugins = PluginEngine::getPlugins(ExternPagePlugin::class);
foreach ($plugins as $plugin) {
if (
$is_system === $plugin->isSystemPage()
diff --git a/app/controllers/admin/install.php b/app/controllers/admin/install.php
index 0054445..e45c281 100644
--- a/app/controllers/admin/install.php
+++ b/app/controllers/admin/install.php
@@ -1,7 +1,7 @@
<?php
-require_once __DIR__ . '/../studip_controller_properties_trait.php';
+require_once __DIR__ . '/../../../lib/classes/StudipControllerPropertiesTrait.php';
-class Admin_InstallController extends Trails_Controller
+class Admin_InstallController extends Trails\Controller
{
use StudipControllerPropertiesTrait;
diff --git a/app/controllers/admin/lockrules.php b/app/controllers/admin/lockrules.php
index 56879fe..202a2e9 100644
--- a/app/controllers/admin/lockrules.php
+++ b/app/controllers/admin/lockrules.php
@@ -164,7 +164,7 @@ class Admin_LockrulesController extends AuthenticatedController
{
$this->lock_rule = LockRule::find($lock_rule_id);
if (!(!$this->lock_rule->isNew() && ($GLOBALS['perm']->have_perm('root') || $this->lock_rule->user_id === $GLOBALS['user']->id))) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
CSRFProtection::verifyUnsafeRequest();
if ($this->lock_rule->delete()) {
@@ -186,4 +186,4 @@ class Admin_LockrulesController extends AuthenticatedController
}
return $this->lock_rule->store();
}
-} \ No newline at end of file
+}
diff --git a/app/controllers/admin/plugin.php b/app/controllers/admin/plugin.php
index 903c45e..8a6935b 100644
--- a/app/controllers/admin/plugin.php
+++ b/app/controllers/admin/plugin.php
@@ -86,7 +86,7 @@ class Admin_PluginController extends AuthenticatedController
* update information is available, an error message is set in
* this controller and an empty array is returned.
*
- * @param array array of plugin meta data
+ * @param array $plugins array of plugin meta data
*/
private function get_update_info($plugins)
{
@@ -127,7 +127,6 @@ class Admin_PluginController extends AuthenticatedController
}
$plugin_manager = PluginManager::getInstance();
- $plugin_filter = Request::option('plugin_filter', '');
$plugins = $plugin_manager->getPluginInfos($this->plugin_filter);
@@ -200,7 +199,6 @@ class Admin_PluginController extends AuthenticatedController
_('Die Position von Plugin "%s" wurde verändert.'),
$plugin['name']
);
- $changed = true;
}
}
}
@@ -344,7 +342,7 @@ class Admin_PluginController extends AuthenticatedController
/**
* Ask for confirmation from the user before deleting a plugin.
*
- * @param integer id of plugin to delete
+ * @param int $plugin_id id of plugin to delete
*/
public function ask_delete_action($plugin_id)
{
@@ -366,7 +364,7 @@ class Admin_PluginController extends AuthenticatedController
/**
* Completely delete a plugin from the system.
*
- * @param integer id of plugin to delete
+ * @param int $plugin_id id of plugin to delete
*/
public function delete_action($plugin_id)
{
@@ -390,7 +388,7 @@ class Admin_PluginController extends AuthenticatedController
/**
* Download a ZIP file containing the given plugin.
*
- * @param integer id of plugin to download
+ * @param int $plugin_id id of plugin to download
*/
public function download_action($plugin_id)
{
@@ -441,16 +439,16 @@ class Admin_PluginController extends AuthenticatedController
$update_info = $this->plugin_admin->getUpdateInfo($plugins);
$update = $this->flash['update'];
- $update_status = [];
-
- // update each plugin in turn
- foreach ($update as $id) {
- if (isset($update_info[$id]['update'])) {
- try {
- $update_url = $update_info[$id]['update']['url'];
- $this->plugin_admin->installPluginFromURL($update_url);
- } catch (PluginInstallationException $ex) {
- $update_errors[] = sprintf('%s: %s', $plugins[$id]['name'], $ex->getMessage());
+
+ if (!empty($update)) { // update each plugin in turn
+ foreach ($update as $id) {
+ if (isset($update_info[$id]['update'])) {
+ try {
+ $update_url = $update_info[$id]['update']['url'];
+ $this->plugin_admin->installPluginFromURL($update_url);
+ } catch (PluginInstallationException $ex) {
+ $update_errors[] = sprintf('%s: %s', $plugins[$id]['name'], $ex->getMessage());
+ }
}
}
}
@@ -473,6 +471,8 @@ class Admin_PluginController extends AuthenticatedController
/**
* Show a page describing this plugin's meta data and description,
* if available.
+ *
+ * @param int $plugin_id if of plugin to show manifest
*/
public function manifest_action($plugin_id)
{
@@ -491,7 +491,7 @@ class Admin_PluginController extends AuthenticatedController
/**
* migrate a plugin to top version
*
- * @param integer id of plugin to migrate
+ * @param int $plugin_id id of plugin to migrate
*/
public function migrate_action($plugin_id)
{
@@ -516,7 +516,7 @@ class Admin_PluginController extends AuthenticatedController
* register a plugin in database when it
* already exists in file system
*
- * @param integer number of found plugin
+ * @param int $number number of found plugin
*/
public function register_action($number)
{
diff --git a/app/controllers/admin/sem_classes.php b/app/controllers/admin/sem_classes.php
index c0b098f..7993c4b 100644
--- a/app/controllers/admin/sem_classes.php
+++ b/app/controllers/admin/sem_classes.php
@@ -65,7 +65,7 @@ class Admin_SemClassesController extends AuthenticatedController
{
Navigation::activateItem("/admin/locations/sem_classes");
- $plugins = PluginManager::getInstance()->getPlugins("StudipModule");
+ $plugins = PluginManager::getInstance()->getPlugins(StudipModule::class);
$this->sem_class = SemClass::getClasses()[Request::get("id")];
$modules = [];
foreach ($this->sem_class->getModuleObjects() as $plugin) {
diff --git a/app/controllers/admin/tree.php b/app/controllers/admin/tree.php
index 1afc438..c8f2a8f 100644
--- a/app/controllers/admin/tree.php
+++ b/app/controllers/admin/tree.php
@@ -130,12 +130,15 @@ class Admin_TreeController extends AuthenticatedController
$node->parent_id = Request::option('parent_id');
$parent = $classname::getNode(Request::option('parent_id'));
- $maxprio = max(array_map(
- function ($c) {
- return $c->priority;
- },
- $parent->getChildNodes()
- ));
+ $children = $parent->getChildNodes();
+ $maxprio = !empty($children)
+ ? max(array_map(
+ function ($c) {
+ return $c->priority;
+ },
+ $children
+ ))
+ : 0;
$node->priority = $maxprio + 1;
if (Request::option('studip_object_id')) {
diff --git a/app/controllers/admin/user.php b/app/controllers/admin/user.php
index 70dfdf1..37a5d2e 100644
--- a/app/controllers/admin/user.php
+++ b/app/controllers/admin/user.php
@@ -1440,17 +1440,13 @@ class Admin_UserController extends AuthenticatedController
];
$queries[] = [
'desc' => _("Anzahl der Wikiseiten"),
- 'query' => "SELECT COUNT(*) FROM wiki WHERE user_id = ? GROUP BY user_id",
+ 'query' => "SELECT COUNT(*) FROM `wiki_pages` 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)
@@ -1478,7 +1474,7 @@ class Admin_UserController extends AuthenticatedController
'details' => "files",
];
- foreach (PluginEngine::getPlugins('ForumModule') as $plugin) {
+ foreach (PluginEngine::getPlugins(ForumModule::class) as $plugin) {
$table = $plugin->getEntryTableInfo();
$queries[] = [
'desc' => $plugin->getPluginName() . ' - ' . _("Anzahl der Postings"),
@@ -1723,7 +1719,7 @@ class Admin_UserController extends AuthenticatedController
)->asDialog();
$actions->addLink(
_('Konten zusammenführen'),
- $this->url_for('admin/user/migrate/' . ((!empty($this->user) && is_array($this->user)) ? $this->user['user_id'] : '')),
+ $this->url_for('admin/user/migrate/' . (!empty($this->user['user_id']) ? $this->user['user_id'] : '')),
Icon::create('community')
);
diff --git a/app/controllers/admission/courseset.php b/app/controllers/admission/courseset.php
index b39cdfb..65d4247 100644
--- a/app/controllers/admission/courseset.php
+++ b/app/controllers/admission/courseset.php
@@ -23,18 +23,17 @@ class Admission_CoursesetController extends AuthenticatedController
{
parent::before_filter($action, $args);
- if (!Request::isXhr()) {
- PageLayout::setTitle(_('Anmeldesets'));
- // Get only own courses if user doesn't have permission to edit institute-wide coursesets.
- $this->onlyOwnCourses = true;
- if ($GLOBALS['perm']->have_perm('admin') || ($GLOBALS['perm']->have_perm('dozent') && Config::get()->ALLOW_DOZENT_COURSESET_ADMIN)) {
- // We have access to institute-wide course sets, so all courses may be assigned.
- $this->onlyOwnCourses = false;
- Navigation::activateItem('/browse/coursesets/sets');
- } else {
- throw new AccessDeniedException();
- }
+ PageLayout::setTitle(_('Anmeldesets'));
+ // Get only own courses if user doesn't have permission to edit institute-wide coursesets.
+ $this->onlyOwnCourses = true;
+ if ($GLOBALS['perm']->have_perm('admin') || ($GLOBALS['perm']->have_perm('dozent') && Config::get()->ALLOW_DOZENT_COURSESET_ADMIN)) {
+ // We have access to institute-wide course sets, so all courses may be assigned.
+ $this->onlyOwnCourses = false;
+ Navigation::activateItem('/browse/coursesets/sets');
+ } else {
+ throw new AccessDeniedException();
}
+
PageLayout::addScript('studip-admission.js');
$views = new ActionsWidget();
@@ -44,6 +43,7 @@ class Admission_CoursesetController extends AuthenticatedController
Icon::create('add')
)->setActive($action === 'configure');
Sidebar::Get()->addWidget($views);
+
if (!isset($this->instant_course_set_view)) {
$this->instant_course_set_view = false;
}
@@ -327,15 +327,19 @@ class Admission_CoursesetController extends AuthenticatedController
*
* @param String $coursesetId the course set to delete
*/
- public function delete_action($coursesetId) {
+ public function delete_action($coursesetId)
+ {
$this->courseset = new CourseSet($coursesetId);
- if (Request::int('really')) {
- $this->courseset->delete();
- $this->redirect($this->url_for('admission/courseset'));
+
+ if (!$this->courseset->isUserAllowedToEdit(User::findCurrent()->id)) {
+ throw new AccessDeniedException(_('Sie dürfen diese Anmelderegel nicht löschen.'));
}
- if (Request::int('cancel')) {
- $this->redirect($this->url_for('admission/courseset'));
+
+ if (Request::bool('really')) {
+ $this->courseset->delete();
}
+
+ $this->redirect($this->url_for('admission/courseset'));
}
/**
@@ -757,11 +761,17 @@ class Admission_CoursesetController extends AuthenticatedController
$ids = Request::optionArray('ids');
if (Request::submitted('delete')) {
+ $deleted = 0;
foreach ($ids as $id) {
$courseset = new CourseSet($id);
- $courseset->delete();
+ if ($courseset->isUserAllowedToEdit(User::findCurrent()->id)) {
+ $courseset->delete();
+ $deleted += 1;
+ }
+ }
+ if ($deleted > 0) {
+ PageLayout::postSuccess(_('Die Anmeldesets wurden gelöscht.'));
}
- PageLayout::postSuccess(_('Die Anmeldesets wurden gelöscht.'));
}
$this->redirect('admission/courseset');
diff --git a/app/controllers/api/authorizations.php b/app/controllers/api/authorizations.php
deleted file mode 100644
index 543bc79..0000000
--- a/app/controllers/api/authorizations.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-
-require_once 'lib/bootstrap-api.php';
-
-/**
-* @deprecated Since Stud.IP 5.0. Will be removed in Stud.IP 6.0.
- **/
-class Api_AuthorizationsController extends AuthenticatedController
-{
- /**
- *
- **/
- public function before_filter(&$action, &$args)
- {
- parent::before_filter($action, $args);
-
- $GLOBALS['perm']->check('autor');
-
- Navigation::activateItem('/profile/settings/api');
- PageLayout::setTitle(_('Applikationen'));
-
- $this->types = [
- 'website' => _('Website'),
- 'program' => _('Herkömmliches Desktopprogramm'),
- 'app' => _('Mobile App')
- ];
- }
-
- /**
- *
- **/
- public function index_action()
- {
- $this->consumers = RESTAPI\UserPermissions::get($GLOBALS['user']->id)->getConsumers();
- $this->types = [
- 'website' => _('Website'),
- 'program' => _('Herkömmliches Desktopprogramm'),
- 'app' => _('Mobile App')
- ];
-
- $widget = new SidebarWidget();
- $widget->setTitle(_('Informationen'));
- $widget->addElement(new WidgetElement(_('Dies sind die Apps, die Zugriff auf Ihren Account haben.')));
- Sidebar::Get()->addWidget($widget);
- }
-
- /**
- *
- **/
- public function revoke_action($id)
- {
- $consumer = new RESTAPI\Consumer\OAuth($id);
- $consumer->revokeAccess($GLOBALS['user']->id);
-
- PageLayout::postMessage(MessageBox::success(_('Der Applikation wurde der Zugriff auf Ihre Daten untersagt.')));
- $this->redirect('api/authorizations');
- }
-}
diff --git a/app/controllers/api/oauth.php b/app/controllers/api/oauth.php
deleted file mode 100644
index bc80c90..0000000
--- a/app/controllers/api/oauth.php
+++ /dev/null
@@ -1,113 +0,0 @@
-<?php
-
-require_once 'lib/bootstrap-api.php';
-
-/**
- * @deprecated Since Stud.IP 5.0. Will be removed in Stud.IP 6.0.
- **/
-class Api_OauthController extends StudipController
-{
- /**
- *
- **/
- public function before_filter(&$action, &$args)
- {
- parent::before_filter($action, $args);
-
- # initialize Stud.IP-Session
- page_open(['sess' => 'Seminar_Session',
- 'auth' => 'Seminar_Default_Auth',
- 'perm' => 'Seminar_Perm',
- 'user' => 'Seminar_User']);
-
- $this->set_layout(null);
- }
-
- /**
- *
- **/
- public function index_action()
- {
- $this->render_text('TODO');
- }
-
- /**
- *
- **/
- public function request_token_action()
- {
- $server = new OAuthServer();
- $token = $server->requestToken();
-
- $this->response->headers = [];
- $this->render_nothing();
- }
-
- /**
- *
- **/
- public function authorize_action()
- {
- global $user, $auth;
-
- $auth_plugin = Config::get()->API_OAUTH_AUTH_PLUGIN;
- if ($GLOBALS['user']->id === 'nobody' && $auth_plugin !== 'Standard' && !Request::option('sso')) {
- $params = $_GET;
- $params['sso'] = strtolower($auth_plugin);
- $this->redirect($this->url_for('api/oauth/authorize?' . http_build_query($params)));
- return;
- } else {
- $auth->login_if($user->id === 'nobody');
- }
-
- $user_id = RESTAPI\Consumer\OAuth::getOAuthId($GLOBALS['user']->id);
-
- try {
- $consumer = RESTAPI\Consumer\Base::detectConsumer('oauth', 'request');
- if (!$consumer) {
- $this->response->set_status(400, 'No consumer detected');
- $this->render_nothing();
- return;
- }
-
- if (Request::submitted('allow')) {
- $result = $consumer->grantAccess($GLOBALS['user']->id);
-
- $redirect_uri = Request::get('oauth_callback', $consumer->callback);
-
- if ($redirect_uri) {
- $this->redirect($redirect_uri);
- } else {
- // No oauth_callback, show the user the result of the authorization
- // ** your code here **
- PageLayout::postMessage(MessageBox::success(_('Sie haben der Applikation Zugriff auf Ihre Daten gewährt.')));
- $this->redirect('api/authorizations#' . $consumer->auth_key);
- }
- return;
- }
- } catch (OAuthException2 $e) {
- // No token to be verified in the request, show a page where the user can enter the token to be verified
- // **your code here**
- die('invalid');
- }
-
- PageLayout::disableHeader();
- PageLayout::setTitle(sprintf(_('"%s" bittet um Zugriff'), $consumer->title));
- $this->set_layout($GLOBALS['template_factory']->open('layouts/base.php'));
- $this->consumer = $consumer;
- $this->token = Request::option('oauth_token');
- $this->oauth_callback = Request::get('oauth_callback');
- }
-
- /**
- *
- **/
- public function access_token_action()
- {
- $server = new OAuthServer();
- $server->accessToken();
-
- $this->response->headers = [];
- $this->render_nothing();
- }
-}
diff --git a/app/controllers/api/oauth2/applications.php b/app/controllers/api/oauth2/applications.php
index d08ec1e..fd6a1bb 100644
--- a/app/controllers/api/oauth2/applications.php
+++ b/app/controllers/api/oauth2/applications.php
@@ -31,7 +31,7 @@ class Api_Oauth2_ApplicationsController extends AuthenticatedController
$this->application = $this->formatApplication($accessToken);
if (!$this->application) {
- throw new Trails_Exception(500, 'Error finding client.');
+ throw new Trails\Exception(500, 'Error finding client.');
}
}
@@ -42,7 +42,7 @@ class Api_Oauth2_ApplicationsController extends AuthenticatedController
$user = User::findCurrent();
$accessToken = AccessToken::find(Request::option('application'));
if (!$accessToken) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
if ($accessToken['user_id'] !== $user->id) {
throw new AccessDeniedException();
diff --git a/app/controllers/api/oauth2/authorize.php b/app/controllers/api/oauth2/authorize.php
index 5628d49..6387937 100644
--- a/app/controllers/api/oauth2/authorize.php
+++ b/app/controllers/api/oauth2/authorize.php
@@ -13,7 +13,7 @@ class Api_Oauth2_AuthorizeController extends OAuth2Controller
parent::before_filter($action, $args);
if ('index' !== $action) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$action = $this->determineAction();
@@ -55,7 +55,7 @@ class Api_Oauth2_AuthorizeController extends OAuth2Controller
if ('nobody' === $GLOBALS['user']->id && 'Standard' !== $authPlugin && !Request::option('sso')) {
$queryParams = $psrRequest->getQueryParams();
$queryParams['sso'] = strtolower($authPlugin);
- $this->redirect($this->authorizeURL($queryParams));
+ $this->redirect($this->url_for('api/oauth2/authorize', $queryParams));
return;
} else {
diff --git a/app/controllers/api/oauth2/oauth2_controller.php b/app/controllers/api/oauth2/oauth2_controller.php
index fd02ea9..6b3dacd 100644
--- a/app/controllers/api/oauth2/oauth2_controller.php
+++ b/app/controllers/api/oauth2/oauth2_controller.php
@@ -42,7 +42,7 @@ abstract class OAuth2Controller extends StudipController
return $this->convertPsrResponse($psrResponse);
}
- return new Trails_Response($exception->getMessage(), [], 500);
+ return new Trails\Response($exception->getMessage(), [], 500);
}
protected function getAuthorizationServer(): AuthorizationServer
diff --git a/app/controllers/api/oauth2/token.php b/app/controllers/api/oauth2/token.php
index 0ae7ffb..755d6b7 100644
--- a/app/controllers/api/oauth2/token.php
+++ b/app/controllers/api/oauth2/token.php
@@ -8,11 +8,11 @@ class Api_Oauth2_TokenController extends OAuth2Controller
parent::before_filter($action, $args);
if ('index' !== $action) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
if (!Request::isPost()) {
- throw new Trails_Exception(405);
+ throw new Trails\Exception(405);
}
$action = 'issue_token';
diff --git a/app/controllers/authenticated_controller.php b/app/controllers/authenticated_controller.php
deleted file mode 100644
index e051ffa..0000000
--- a/app/controllers/authenticated_controller.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-/*
- * Copyright (C) 2009 - Marcus Lunzenauer <mlunzena@uos.de>
- *
- * 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.
- */
-
-class AuthenticatedController extends StudipController
-{
- protected $with_session = true; //we do need to have a session for this controller
- protected $allow_nobody = false; //nobody is not allowed and always gets a login-screen
-
- public function before_filter(&$action, &$args)
- {
- parent::before_filter($action, $args);
-
- // Restore request if present
- if (isset($this->flash['request'])) {
- foreach ($this->flash['request'] as $key => $value) {
- Request::set($key, $value);
- }
- }
- }
-
- protected function keepRequest()
- {
- $this->flash['request'] = Request::getInstance()->getIterator()->getArrayCopy();
- }
-}
diff --git a/app/controllers/avatar.php b/app/controllers/avatar.php
index c549cf0..aafbb98 100644
--- a/app/controllers/avatar.php
+++ b/app/controllers/avatar.php
@@ -62,8 +62,14 @@ class AvatarController extends AuthenticatedController
Navigation::activateItem('/admin/institute/details');
} else {
Navigation::activateItem('/course/admin/avatar');
+
+ if ($GLOBALS['perm']->have_studip_perm('admin', $id)) {
+ $widget = new CourseManagementSelectWidget();
+ Sidebar::get()->addWidget($widget);
+ }
}
+
$avatar = $class::getAvatar($id);
$this->avatar = $avatar->getURL($class::NORMAL);
$this->customized = $avatar->is_customized();
diff --git a/app/controllers/blubber.php b/app/controllers/blubber.php
index c0490f0..aedf9b6 100644
--- a/app/controllers/blubber.php
+++ b/app/controllers/blubber.php
@@ -135,7 +135,7 @@ class BlubberController extends AuthenticatedController
'user_id' => $user_id,
]);
}
- $this->redirect("blubber/index/{$blubber->getId()}");
+ $this->relocate("blubber/index/{$blubber->getId()}");
return;
}
@@ -271,13 +271,12 @@ class BlubberController extends AuthenticatedController
$output = [];
foreach ($_FILES as $file) {
- $newfile = null; //is filled below
$file_ref = null; //is also filled below
if ($file['size']) {
$document['user_id'] = $GLOBALS['user']->id;
- $document['filesize'] = $file['size'];
-
+ $success = false;
+ $url = '';
try {
$root_dir = Folder::findTopFolder($GLOBALS['user']->id);
$root_dir = $root_dir->getTypedFolder();
@@ -339,7 +338,6 @@ class BlubberController extends AuthenticatedController
}
} catch (Exception $e) {
$output['errors'][] = $e->getMessage();
- $success = false;
}
if ($success) {
@@ -373,21 +371,22 @@ class BlubberController extends AuthenticatedController
}
PageLayout::setTitle(_('Person hinzufügen'));
if (Request::isPost() && Request::option('user_id')) {
- $query = "INSERT IGNORE INTO blubber_mentions
- SET thread_id = :thread_id,
- user_id = :user_id,
- external_contact = 0,
- mkdate = UNIX_TIMESTAMP()";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([
- 'thread_id' => $thread_id,
- 'user_id' => Request::option('user_id'),
- ]);
- $this->response->add_header('X-Dialog-Execute', 'STUDIP.Blubber.refreshThread');
- $this->response->add_header('X-Dialog-Close', '1');
- $this->render_json([
- 'thread_id' => $thread_id,
- ]);
+ $data = [
+ 'user_id' => Request::option('user_id'),
+ 'thread_id' => $thread_id,
+ 'external_contact' => 0,
+ ];
+
+ $blubber_mention = BlubberMention::findOneBySQL('user_id = ? AND thread_id = ?', [Request::option('user_id'), $thread_id]);
+
+ if ($blubber_mention) {
+ $blubber_mention->setData($data);
+ } else {
+ $blubber_mention = BlubberMention::create($data);
+ }
+ $blubber_mention->store();
+ $this->relocate('blubber/index/' . $thread_id);
+ return;
}
}
@@ -408,13 +407,9 @@ class BlubberController extends AuthenticatedController
CourseAvatar::getAvatar($course->getId())->createFromUpload('avatar');
}
- $query = "SELECT user_id
- FROM blubber_mentions
- WHERE thread_id = ?";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$this->thread->id]);
- foreach ($statement->fetchFirst() as $user_id) {
- CourseMember::insertCourseMember($course->getId(), $user_id, $user_id === $this->thread['user_id'] ? 'dozent' : 'tutor');
+ $blubber_mentions = BlubberMention::findBySQL('thread_id = ?', [$this->thread->id]);
+ foreach ($blubber_mentions as $blubber_mention) {
+ CourseMember::insertCourseMember($course->getId(), $blubber_mention->user_id, $blubber_mention->user_id === $this->thread['user_id'] ? 'dozent' : 'tutor');
}
$this->thread['context_type'] = 'course';
@@ -424,13 +419,13 @@ class BlubberController extends AuthenticatedController
PluginManager::getInstance()->setPluginActivated(
PluginManager::getInstance()
- ->getPlugin('Blubber')
+ ->getPlugin(Blubber::class)
->getPluginId(),
$course->getId(),
true
);
- PageLayout::postSuccess(sprintf(_("Studiengruppe '%s' wurde angelegt."), htmlReady($course['name'])));
+ PageLayout::postSuccess(sprintf(_('Studiengruppe "%s" wurde angelegt.'), htmlReady($course['name'])));
$this->redirect(URLHelper::getURL('seminar_main.php', ['auswahl' => $course->getId()]));
}
}
diff --git a/app/controllers/calendar/calendar.php b/app/controllers/calendar/calendar.php
index c605c01..0cb96ad 100644
--- a/app/controllers/calendar/calendar.php
+++ b/app/controllers/calendar/calendar.php
@@ -12,8 +12,12 @@ class Calendar_CalendarController extends AuthenticatedController
}
- protected function buildSidebar($schedule = false)
- {
+ protected function buildSidebar(
+ bool $schedule = false,
+ string $user_id = '',
+ string $group_id = ''
+ ) {
+
$sidebar = Sidebar::get();
$actions = new ActionsWidget();
@@ -25,11 +29,17 @@ class Calendar_CalendarController extends AuthenticatedController
['data-dialog' => 'size=default']
);
} else {
+ $params = [];
+ if ($user_id) {
+ $params['user_id'] = $user_id;
+ } elseif ($group_id) {
+ $params['group_id'] = $group_id;
+ }
$actions->addLink(
_('Termin anlegen'),
- $this->url_for('calendar/date/add'),
+ $this->url_for('calendar/date/add', $params),
Icon::create('add'),
- ['data-dialog' => 'size=auto']
+ ['data-dialog' => 'size=auto', 'class' => 'calendar-action']
);
}
@@ -101,6 +111,8 @@ class Calendar_CalendarController extends AuthenticatedController
{
PageLayout::setTitle(_('Kalender'));
+ $default_date = \Studip\Calendar\Helper::getDefaultCalendarDate();
+
if (Request::isPost()) {
//In case the checkbox of the options widget is clicked, the resulting
//POST request must be catched here and result in a redirect.
@@ -181,7 +193,11 @@ class Calendar_CalendarController extends AuthenticatedController
throw new AccessDeniedException(_('Sie dürfen diesen Kalender nicht sehen!'));
}
- $this->buildSidebar(false);
+ $this->buildSidebar(
+ false,
+ $calendar_owner ? $calendar_owner->id : '',
+ $selected_group ? $selected_group->id : ''
+ );
$sidebar = Sidebar::get();
@@ -189,6 +205,7 @@ class Calendar_CalendarController extends AuthenticatedController
if ($calendar_owner && $calendar_owner->id === User::findCurrent()->id) {
//The user is viewing their own calendar.
$options = new OptionsWidget();
+ $options->addLayoutCSSClass('calendar-action');
$options->addCheckbox(
_('Abgelehnte Termine anzeigen'),
Request::bool('show_declined'),
@@ -223,6 +240,7 @@ class Calendar_CalendarController extends AuthenticatedController
$this->url_for('calendar/calendar/index', ['view' => 'group']),
'group_id'
);
+ $group_select->addLayoutCSSClass('calendar-action');
$options = [
'' => _('(bitte wählen)')
];
@@ -249,6 +267,7 @@ class Calendar_CalendarController extends AuthenticatedController
$this->url_for('calendar/calendar'),
'user_id'
);
+ $calendar_select->addLayoutCSSClass('calendar-action');
$select_options = [
'' => _('(bitte wählen)'),
User::findCurrent()->id => _('Eigener Kalender')
@@ -321,7 +340,6 @@ class Calendar_CalendarController extends AuthenticatedController
$slot_durations = $this->getUserCalendarSlotSettings();
//Create the fullcalendar object:
- $default_date = \Studip\Calendar\Helper::getDefaultCalendarDate();
$data_url_params = [];
if (Request::bool('show_declined')) {
@@ -432,7 +450,7 @@ class Calendar_CalendarController extends AuthenticatedController
_('Termin anlegen'),
$this->url_for('calendar/date/add/course_' . $course->id),
Icon::create('add'),
- ['data-dialog' => 'size=default']
+ ['data-dialog' => 'size=default', 'class' => 'calendar-action']
);
$actions->addLink(
_('Drucken'),
@@ -564,20 +582,18 @@ class Calendar_CalendarController extends AuthenticatedController
$course_dates = CalendarCourseDate::getEvents($begin, $end, $owner->id);
foreach ($course_dates as $course_date) {
$event = $course_date->toEventData(User::findCurrent()->id);
- $event->background_colour = '#ffffff';
+ $event->background_colour = '';
$event->text_colour = '#000000';
- $event->border_colour = '#000000';
- $event->event_classes = [];
+ $event->border_colour = '';
$result[] = $event->toFullcalendarEvent();
}
//Include relevant cancelled course dates:
$cancelled_course_dates = CalendarCourseExDate::getEvents($begin, $end, $owner->id);
foreach ($cancelled_course_dates as $cancelled_course_date) {
$event = $cancelled_course_date->toEventData(User::findCurrent()->id);
- $event->background_colour = '#ffffff';
+ $event->background_colour = '';
$event->text_colour = '#000000';
- $event->border_colour = '#000000';
- $event->event_classes = [];
+ $event->border_colour = '';
$result[] = $event->toFullcalendarEvent();
}
}
@@ -660,7 +676,7 @@ class Calendar_CalendarController extends AuthenticatedController
public function add_courses_action()
{
$selected_semester_pseudo_id = Request::option('semester_id');
- $this->selected_semesters_id = '';
+ $this->selected_semester_id = '';
$this->available_semester_data = [];
$semesters = Semester::getAll();
foreach ($semesters as $semester) {
@@ -691,8 +707,9 @@ class Calendar_CalendarController extends AuthenticatedController
$this->selected_semester_id = $semester->id;
} else {
$this->selected_semester_id = $selected_semester_pseudo_id ?? '';
- if (!Semester::exists($this->selected_semesters_id)) {
- $this->selected_semester_id = '';
+ if (!Semester::exists($this->selected_semester_id)) {
+ $semester = Semester::findCurrent();
+ $this->selected_semester_id = $semester->id;
}
}
@@ -755,29 +772,41 @@ class Calendar_CalendarController extends AuthenticatedController
PageLayout::postError(_('Bitte wählen Sie aus, welche Termine exportiert werden sollen!'));
return;
}
- $ical = '';
- $calendar_export = new ICalendarExport();
- if ($this->dates_to_export === 'user') {
- $ical = $calendar_export->exportCalendarDates(User::findCurrent()->id, $this->begin, $this->end);
- } elseif ($this->dates_to_export === 'course') {
- $ical = $calendar_export->exportCourseDates(User::findCurrent()->id, $this->begin, $this->end);
- $ical .= $calendar_export->exportCourseExDates(User::findCurrent()->id, $this->begin, $this->end);
- } elseif ($this->dates_to_export === 'all') {
- $ical = $calendar_export->exportCalendarDates(User::findCurrent()->id, $this->begin, $this->end);
- $ical .= $calendar_export->exportCourseDates(User::findCurrent()->id, $this->begin, $this->end);
- $ical .= $calendar_export->exportCourseExDates(User::findCurrent()->id, $this->begin, $this->end);
- }
- $ical = $calendar_export->writeHeader() . $ical . $calendar_export->writeFooter();
- $this->response->add_header('Content-Type', 'text/calendar;charset=utf-8');
- $this->response->add_header('Content-Disposition', 'attachment; filename="studip.ics"');
- $this->response->add_header('Content-Transfer-Encoding', 'binary');
- $this->response->add_header('Pragma', 'public');
- $this->response->add_header('Cache-Control', 'private');
- $this->response->add_header('Content-Length', strlen($ical));
- $this->render_text($ical);
+ $this->relocate($this->url_for('calendar/calendar/export_file', [
+ 'begin' => $this->begin->format('d.m.Y'),
+ 'end' => $this->end->format('d.m.Y'),
+ 'dates_to_export' => $this->dates_to_export
+ ]));
}
}
+ public function export_file_action()
+ {
+ $begin = Request::getDateTime('begin', 'd.m.Y');
+ $end = Request::getDateTime('end', 'd.m.Y');
+ $dates_to_export = Request::option('dates_to_export', 'user');
+ $ical = '';
+ $calendar_export = new ICalendarExport();
+ if ($dates_to_export === 'user') {
+ $ical = $calendar_export->exportCalendarDates(User::findCurrent()->id, $begin, $end);
+ } elseif ($dates_to_export === 'course') {
+ $ical = $calendar_export->exportCourseDates(User::findCurrent()->id, $begin, $end);
+ $ical .= $calendar_export->exportCourseExDates(User::findCurrent()->id, $begin, $end);
+ } elseif ($dates_to_export === 'all') {
+ $ical = $calendar_export->exportCalendarDates(User::findCurrent()->id, $begin, $end);
+ $ical .= $calendar_export->exportCourseDates(User::findCurrent()->id, $begin, $end);
+ $ical .= $calendar_export->exportCourseExDates(User::findCurrent()->id, $begin, $end);
+ }
+ $ical = $calendar_export->writeHeader() . $ical . $calendar_export->writeFooter();
+ $this->response->add_header('Content-Type', 'text/calendar;charset=utf-8');
+ $this->response->add_header('Content-Disposition', 'attachment; filename="studip.ics"');
+ $this->response->add_header('Content-Transfer-Encoding', 'binary');
+ $this->response->add_header('Pragma', 'public');
+ $this->response->add_header('Cache-Control', 'private');
+ $this->response->add_header('Content-Length', strlen($ical));
+ $this->render_text($ical);
+ }
+
public function import_action() {}
public function import_file_action()
diff --git a/app/controllers/calendar/contentbox.php b/app/controllers/calendar/contentbox.php
index 8ba5215..b684905 100644
--- a/app/controllers/calendar/contentbox.php
+++ b/app/controllers/calendar/contentbox.php
@@ -78,21 +78,29 @@ class Calendar_ContentboxController extends StudipController
if ($this->admin) {
$this->isProfile = $this->single && $this->userRange;
}
+
+ // Sort dates
+ usort($this->termine, function ($a, $b) {
+ [$a_begin, $a_end] = $this->parseBeginAndEndFromDate($a);
+ [$b_begin, $b_end] = $this->parseBeginAndEndFromDate($b);
+
+ return $a_begin - $b_begin
+ ?: $a_end - $b_end;
+ });
}
private function parseSeminar($id)
{
- $course = Course::find($id);
- $this->termine = $course->getDatesWithExdates()->findBy('end_time', [$this->start, $this->start + $this->timespan], '><');
- foreach ($this->termine as $course_date) {
- if ($this->course_range) {
- //Display only date and time:
- $this->titles[$course_date->id] = $course_date->getFullName('include-room');
- } else {
- //Include the course title:
- $this->titles[$course_date->id] = $course_date->getFullName('verbose');
- }
- }
+ // Display only date and time if in course range, include course title
+ // otherwise
+ $date_format = $this->course_range ? 'include-room' : 'verbose';
+
+ $this->termine = Course::find($id)->getDatesWithExdates()
+ ->findBy('end_time', [$this->start, $this->start + $this->timespan], '><')
+ ->map(function ($course_date) use ($date_format) {
+ $this->titles[$course_date->id] = $course_date->getFullName($date_format);
+ return $course_date;
+ });
}
private function parseUser($id)
@@ -170,4 +178,23 @@ class Calendar_ContentboxController extends StudipController
$this->termine[] = $assignment;
}
}
+
+ private function parseBeginAndEndFromDate($date): array
+ {
+ if ($date instanceof CalendarDateAssignment) {
+ return [
+ $date->calendar_date->begin,
+ $date->calendar_date->end,
+ ];
+ }
+
+ if ($date instanceof CourseDate || $date instanceof CourseExDate) {
+ return [
+ $date->date,
+ $date->end_time,
+ ];
+ }
+
+ throw new Exception('Invalid date type passed: ' . get_class($date));
+ }
}
diff --git a/app/controllers/calendar/date.php b/app/controllers/calendar/date.php
index 72f3a40..cb61a7e 100644
--- a/app/controllers/calendar/date.php
+++ b/app/controllers/calendar/date.php
@@ -27,9 +27,8 @@ class Calendar_DateController extends AuthenticatedController
$range_id = $range_and_id[1];
}
if (!$range) {
- //Show the personal calendar of the current user:
+ $range_id = Request::option('user_id', $GLOBALS['user']->id);
$range = 'user';
- $range_id = $GLOBALS['user']->id;
}
$owner = null;
@@ -233,6 +232,14 @@ class Calendar_DateController extends AuthenticatedController
$this->date->repetition_end = $this->date->end;
} else {
$time = new DateTime();
+ if (Request::submitted('timestamp')) {
+ $time->setTimestamp(Request::int('timestamp'));
+ } elseif (Request::submitted('defaultDate')) {
+ $date_parts = explode('-', Request::get('defaultDate'));
+ if (count($date_parts) === 3) {
+ $time->setDate($date_parts[0], $date_parts[1], $date_parts[2]);
+ }
+ }
$time = $time->add(new DateInterval('PT1H'));
$time->setTime(intval($time->format('H')), 0, 0);
$this->date->begin = $time->getTimestamp();
@@ -325,15 +332,12 @@ class Calendar_DateController extends AuthenticatedController
if ($this->date->isNew()) {
if (!($owner instanceof Course)) {
- //Assign the date to the calendar of the current user by default:
- $user = User::findCurrent();
- if ($user) {
- $this->calendar_assignment_items[] = [
- 'value' => $user->id,
- 'name' => $user->getFullName(),
- 'deletable' => true
- ];
- }
+ //Assign the date to the calendar of the owner by default:
+ $this->calendar_assignment_items[] = [
+ 'value' => $owner->id,
+ 'name' => $owner->getFullName(),
+ 'deletable' => true
+ ];
}
} else {
$exceptions = CalendarDateException::findBySql(
diff --git a/app/controllers/calendar/schedule.php b/app/controllers/calendar/schedule.php
index 88c4304..5d9a26e 100644
--- a/app/controllers/calendar/schedule.php
+++ b/app/controllers/calendar/schedule.php
@@ -143,7 +143,7 @@ class Calendar_ScheduleController extends AuthenticatedController
'entry_height' => $this->calendar_view->getHeight()
];
- $factory = new Flexi_TemplateFactory($this->dispatcher->trails_root . '/views');
+ $factory = new Flexi\Factory($this->dispatcher->trails_root . '/views');
PageLayout::addStyle($factory->render('calendar/schedule/stylesheet', $style_parameters), 'screen, print');
if (Request::option('printview')) {
diff --git a/app/controllers/captcha.php b/app/controllers/captcha.php
new file mode 100644
index 0000000..37bac47
--- /dev/null
+++ b/app/controllers/captcha.php
@@ -0,0 +1,12 @@
+<?php
+final class CaptchaController extends StudipController
+{
+ public function challenge_action(): void
+ {
+ $this->response->add_header(
+ 'Expires',
+ gmdate('D, d M Y H:i:s', time() + CaptchaChallenge::CHALLENGE_EXPIRATION) . ' GMT'
+ );
+ $this->render_json(CaptchaChallenge::createNewChallenge());
+ }
+}
diff --git a/app/controllers/consultation/admin.php b/app/controllers/consultation/admin.php
index bc63a1a..8ee7575 100644
--- a/app/controllers/consultation/admin.php
+++ b/app/controllers/consultation/admin.php
@@ -138,6 +138,7 @@ class Consultation_AdminController extends ConsultationController
$this->room = '';
$this->responsible = false;
+ $this->slot_count_threshold = self::SLOT_COUNT_THRESHOLD;
// TODO: inst_default?
if ($this->range instanceof User) {
@@ -155,6 +156,8 @@ class Consultation_AdminController extends ConsultationController
$block->range = $this->range;
$this->responsible = $block->getPossibleResponsibilites();
}
+
+ $this->response->add_header('X-No-Buttons', '');
}
public function store_action()
@@ -186,7 +189,7 @@ class Consultation_AdminController extends ConsultationController
$end,
Request::int('day-of-week'),
Request::int('interval'),
- Request::int('duration'),
+ $duration,
$pause_time,
$pause_duration
);
@@ -214,6 +217,7 @@ class Consultation_AdminController extends ConsultationController
$block->note = Request::get('note');
$block->size = Request::int('size', 1);
$block->lock_time = Request::int('lock_time');
+ $block->consecutive = Request::bool('consecutive', false);
$slots = $block->createSlots(Request::int('duration'), $pause_time, $pause_duration);
if (count($slots) === 0) {
@@ -403,6 +407,7 @@ class Consultation_AdminController extends ConsultationController
$this->block->mail_to_tutors = Request::bool('mail-to-tutors', false);
$this->block->confirmation_text = trim(Request::get('confirmation-text'));
$this->block->lock_time = Request::int('lock_time');
+ $this->block->consecutive = Request::bool('consecutive', false);
foreach ($this->block->slots as $slot) {
$slot->note = '';
@@ -535,7 +540,7 @@ class Consultation_AdminController extends ConsultationController
public function toggle_action($what, $state, $expired = false)
{
if ($what === 'messages') {
- // TODO: Applicable everywhere?
+ // TODO: Applicable everywhere?
$this->getUserConfig()->store(
'CONSULTATION_SEND_MESSAGES',
(bool) $state
@@ -808,7 +813,7 @@ class Consultation_AdminController extends ConsultationController
_('Terminblöcke anlegen'),
$this->createURL(),
Icon::create('add')
- )->asDialog('size=auto');
+ )->asDialog('size=big');
$actions->addLink(
_('Namen des Reiters ändern'),
$this->tabURL($action === 'expired'),
diff --git a/app/controllers/consultation/consultation_controller.php b/app/controllers/consultation/consultation_controller.php
index d6927af..00e10ad 100644
--- a/app/controllers/consultation/consultation_controller.php
+++ b/app/controllers/consultation/consultation_controller.php
@@ -19,7 +19,7 @@ abstract class ConsultationController extends AuthenticatedController
$this->range = Context::get();
$type = 'object';
} else {
- $this->range = $GLOBALS['user']->getAuthenticatedUser();
+ $this->range = User::findCurrent();
}
if (!$this->range) {
@@ -60,7 +60,7 @@ abstract class ConsultationController extends AuthenticatedController
$this->render_template('consultation/not_found', $this->layout);
}
- protected function activateNavigation($path)
+ protected function activateNavigation($path): void
{
$path = ltrim($path, '/');
@@ -73,7 +73,7 @@ abstract class ConsultationController extends AuthenticatedController
}
}
- protected function getConsultationTitle()
+ protected function getConsultationTitle(): string
{
return $this->range->getConfiguration()->CONSULTATION_TAB_TITLE;
}
@@ -103,7 +103,8 @@ abstract class ConsultationController extends AuthenticatedController
return $block;
}
- protected function loadSlot($block_id, $slot_id)
+
+ protected function loadSlot($block_id, $slot_id): ConsultationSlot
{
$block = $this->loadBlock($block_id);
$slot = $block->slots->find($slot_id);
@@ -115,7 +116,7 @@ abstract class ConsultationController extends AuthenticatedController
return $slot;
}
- protected function loadBooking($block_id, $slot_id, $booking_id)
+ protected function loadBooking($block_id, $slot_id, $booking_id): ConsultationBooking
{
$slot = $this->loadSlot($block_id, $slot_id);
$booking = $slot->bookings->find($booking_id);
diff --git a/app/controllers/consultation/overview.php b/app/controllers/consultation/overview.php
index ce6cd31..2afb710 100644
--- a/app/controllers/consultation/overview.php
+++ b/app/controllers/consultation/overview.php
@@ -71,6 +71,8 @@ class Consultation_OverviewController extends ConsultationController
if ($this->slot->isOccupied()) {
PageLayout::postError(_('Dieser Termin ist bereits belegt.'));
+ } elseif (!$this->slot->isBookable()) {
+ PageLayout::postError(_('Dieser Termin ist für Buchungen gesperrt.'));
} else {
$booking = new ConsultationBooking();
$booking->slot_id = $this->slot->id;
diff --git a/app/controllers/contact.php b/app/controllers/contact.php
index 7dd2b05..2148777 100644
--- a/app/controllers/contact.php
+++ b/app/controllers/contact.php
@@ -189,9 +189,21 @@ class ContactController extends AuthenticatedController
$user = User::findManyByUsername(Request::getArray('user'));
}
if ($group) {
- $user = User::findMany(Statusgruppen::find($group)->members->pluck('user_id'));
+ $group_object = Statusgruppen::find($group);
+ if (!$group_object) {
+ $this->set_status(404);
+ $this->render_nothing();
+ return;
+ }
+ $user = User::findMany($group_object->members->pluck('user_id'));
}
if (!$user) {
+ $user_object = User::findCurrent();
+ if (!$user_object) {
+ $this->set_status(404);
+ $this->render_nothing();
+ return;
+ }
$user = User::findCurrent()->contacts;
}
diff --git a/app/controllers/contents/courseware.php b/app/controllers/contents/courseware.php
index f0d5023..d4291df 100644
--- a/app/controllers/contents/courseware.php
+++ b/app/controllers/contents/courseware.php
@@ -262,7 +262,7 @@ class Contents_CoursewareController extends CoursewareController
*/
private function isCoursewareEnabled($course_id): bool
{
- $studip_module = PluginManager::getInstance()->getPlugin('CoursewareModule');
+ $studip_module = PluginManager::getInstance()->getPlugin(CoursewareModule::class);
if (!$studip_module || !$studip_module->isActivated($course_id)) {
return false;
@@ -311,7 +311,7 @@ class Contents_CoursewareController extends CoursewareController
);
if (!$struct) {
- throw new Trails_Exception(404, _('Der geteilte Inhalt kann nicht gefunden werden.'));
+ throw new Trails\Exception(404, _('Der geteilte Inhalt kann nicht gefunden werden.'));
}
if (!$struct->canRead($user) && !$struct->canEdit($user)) {
diff --git a/app/controllers/course/admission.php b/app/controllers/course/admission.php
index 56342bb..14a9b20 100644
--- a/app/controllers/course/admission.php
+++ b/app/controllers/course/admission.php
@@ -31,7 +31,7 @@ class Course_AdmissionController extends AuthenticatedController
if (!get_object_type($this->course_id, ['sem']) ||
SeminarCategories::GetBySeminarId($this->course_id)->studygroup_mode ||
!$GLOBALS['perm']->have_studip_perm('tutor', $this->course_id)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$this->course = Course::find($this->course_id);
@@ -488,7 +488,7 @@ class Course_AdmissionController extends AuthenticatedController
}
$this->course_set_name = $course_set->getName();
} else {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
}
@@ -503,7 +503,7 @@ class Course_AdmissionController extends AuthenticatedController
$this->redirect($response->headers['Location']);
}
} else {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
@@ -518,7 +518,7 @@ class Course_AdmissionController extends AuthenticatedController
$this->redirect($response->headers['Location']);
}
} else {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
diff --git a/app/controllers/course/basicdata.php b/app/controllers/course/basicdata.php
index 8cc7d94..97ec053 100644
--- a/app/controllers/course/basicdata.php
+++ b/app/controllers/course/basicdata.php
@@ -445,6 +445,14 @@ class Course_BasicdataController extends AuthenticatedController
$widget = new CourseManagementSelectWidget();
$sidebar->addWidget($widget);
}
+
+ foreach ($this->flash['msg'] ?? [] as $msg) {
+ match ($msg[0]) {
+ 'msg' => PageLayout::postSuccess($msg[1]),
+ 'error' => PageLayout::postError($msg[1]),
+ 'info' => PageLayout::postInfo($msg[1]),
+ };
+ }
}
/**
@@ -956,20 +964,30 @@ class Course_BasicdataController extends AuthenticatedController
private function _getTypes($sem, $data, &$changable = true)
{
$sem_types = [];
+
+ $sem_classes = [];
if ($GLOBALS['perm']->have_perm("admin")) {
foreach (SemClass::getClasses() as $sc) {
if (!$sc['course_creation_forbidden']) {
- $sem_types[$sc['name']] = array_map(function ($st) {
- return $st['name'];
- }, $sc->getSemTypes());
+ $sem_classes[] = $sc;
}
}
} else {
- $sc = $sem->getSemClass();
+ $sem_classes[] = $sem->getSemClass();
+ }
+
+ if (!$sem->isStudyGroup()) {
+ $sem_classes = array_filter($sem_classes, function (SemClass $sc) {
+ return !$sc['studygroup_mode'];
+ });
+ }
+
+ foreach ($sem_classes as $sc) {
$sem_types[$sc['name']] = array_map(function ($st) {
return $st['name'];
}, $sc->getSemTypes());
}
+
if (!in_array($data['status'], array_flatten(array_values(array_map('array_keys', $sem_types))))) {
$class_name = $sem->getSemClass()->offsetGet('name');
if (!isset($sem_types[$class_name])) {
diff --git a/app/controllers/course/block_appointments.php b/app/controllers/course/block_appointments.php
index fef0d31..ad28b1e 100644
--- a/app/controllers/course/block_appointments.php
+++ b/app/controllers/course/block_appointments.php
@@ -33,7 +33,7 @@ class Course_BlockAppointmentsController extends AuthenticatedController
SeminarCategories::GetBySeminarId($this->course_id)->studygroup_mode ||
!$GLOBALS['perm']->have_studip_perm("tutor", $this->course_id)
) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
PageLayout::setHelpKeyword('Basis.VeranstaltungenVerwaltenAendernVonZeitenUndTerminen');
PageLayout::setTitle(Course::findCurrent()->getFullName() . " - " . _('Blockveranstaltungstermine anlegen'));
diff --git a/app/controllers/course/cancel_dates.php b/app/controllers/course/cancel_dates.php
index 0d5463c..8da0d09 100644
--- a/app/controllers/course/cancel_dates.php
+++ b/app/controllers/course/cancel_dates.php
@@ -39,7 +39,7 @@ class Course_CancelDatesController extends AuthenticatedController
$this->course_id = $this->dates[0]->range_id;
}
if (!get_object_type($this->course_id, ['sem']) || !$perm->have_studip_perm("tutor", $this->course_id)) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
PageLayout::setHelpKeyword('Basis.VeranstaltungenVerwaltenAendernVonZeitenUndTerminen');
PageLayout::setTitle(Course::findCurrent()->getFullName() . " - " . _('Veranstaltungstermine absagen'));
diff --git a/app/controllers/course/change_view.php b/app/controllers/course/change_view.php
index 156a68a..63395b6 100644
--- a/app/controllers/course/change_view.php
+++ b/app/controllers/course/change_view.php
@@ -16,7 +16,6 @@
*/
class Course_ChangeViewController extends AuthenticatedController
{
- // see Trails_Controller#before_filter
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
@@ -28,7 +27,7 @@ class Course_ChangeViewController extends AuthenticatedController
* Sets the current course into participant view.
* Only available for tutor upwards.
*
- * @throws Trails_Exception Someone with unfitting rights tried to call here.
+ * @throws Trails\Exception Someone with unfitting rights tried to call here.
*/
public function set_changed_view_action()
{
@@ -43,7 +42,7 @@ class Course_ChangeViewController extends AuthenticatedController
* Resets a course currently in participant view to normal view
* with real rights.
*
- * @throws Trails_Exception Someone with unfitting rights tried to call here.
+ * @throws Trails\Exception Someone with unfitting rights tried to call here.
*/
public function reset_changed_view_action()
{
diff --git a/app/controllers/course/contentmodules.php b/app/controllers/course/contentmodules.php
index 923c61b..d37d1bb 100644
--- a/app/controllers/course/contentmodules.php
+++ b/app/controllers/course/contentmodules.php
@@ -261,14 +261,19 @@ class Course_ContentmodulesController extends AuthenticatedController
}
}
- PageLayout::setTitle(sprintf(_('Informationen über %s'), $this->metadata['displayname']));
+ $this->metadata['icon'] = $this->getIconFromMetadata($this->metadata, $this->plugin);
+
+ PageLayout::setTitle(sprintf(
+ _('Informationen über %s'),
+ $this->metadata['displayname'] ?? $this->plugin->getPluginName()
+ ));
}
private function getModules(Range $context)
{
$list = [];
- foreach (PluginEngine::getPlugins('StudipModule') as $plugin) {
+ foreach (PluginEngine::getPlugins(StudipModule::class) as $plugin) {
if (!$plugin->isActivatableForContext($context)) {
continue;
}
@@ -291,6 +296,7 @@ class Course_ContentmodulesController extends AuthenticatedController
$visibility = $tool ? $tool->getVisibilityPermission() : 'nobody';
$metadata = $plugin->getMetadata();
+ $icon = $this->getIconFromMetadata($metadata, $plugin);
$list[$plugin_id] = [
'id' => $plugin_id,
'moduleclass' => get_class($plugin),
@@ -299,7 +305,7 @@ class Course_ContentmodulesController extends AuthenticatedController
'displayname' => $displayname,
'visibility' => $visibility,
'active' => (bool) $tool,
- 'icon' => $this->getIconFromMetadata($metadata, $plugin),
+ 'icon' => $icon ? $icon->asImagePath() : null,
'summary' => $metadata['summary'] ?? null,
'mandatory' => $this->sem_class->isModuleMandatory(get_class($plugin)),
'highlighted' => (bool) $plugin->isHighlighted(),
@@ -315,7 +321,7 @@ class Course_ContentmodulesController extends AuthenticatedController
* @param array $metadata
* @param CorePlugin|StudIPPlugin $plugin
*/
- private function getIconFromMetadata(array $metadata, $plugin): ?string
+ private function getIconFromMetadata(array $metadata, $plugin): ?Icon
{
$icon = $metadata['icon_clickable'] ?? $metadata['icon'] ?? null;
@@ -332,7 +338,7 @@ class Course_ContentmodulesController extends AuthenticatedController
$icon = Icon::create($plugin->getPluginURL() . '/' . $icon);
}
- return $icon->copyWithRole(Icon::ROLE_CLICKABLE)->asImagePath();
+ return $icon->copyWithRole(Icon::ROLE_CLICKABLE);
}
private function getCoreIcon(string $path): ?Icon
diff --git a/app/controllers/course/courseware.php b/app/controllers/course/courseware.php
index 22b124b..f0b873a 100644
--- a/app/controllers/course/courseware.php
+++ b/app/controllers/course/courseware.php
@@ -52,22 +52,20 @@ class Course_CoursewareController extends CoursewareController
public function courseware_action($unit_id = null): void
{
- global $user;
-
Navigation::activateItem('course/courseware/unit');
if ($this->unitsNotFound) {
PageLayout::postMessage(MessageBox::info(_('Es wurde kein Lernmaterial gefunden.')));
return;
}
+ $user = User::findCurrent();
$this->setCoursewareSidebar();
- $this->user_id = $user->id;
/** @var array<mixed> $last */
- $last = UserConfig::get($this->user_id)->getValue('COURSEWARE_LAST_ELEMENT');
+ $last = UserConfig::get($user->id)->getValue('COURSEWARE_LAST_ELEMENT');
$lastStructuralElement = \Courseware\StructuralElement::findOneById($last);
if ($unit_id === null) {
- if (isset($lastStructuralElement) && $lastStructuralElement->canVisit(User::findCurrent())) {
+ if (isset($lastStructuralElement) && $lastStructuralElement->canVisit($user)) {
$this->redirectToFirstUnit('course', Context::getId(), $last);
} else {
$this->redirectToFirstUnit('course', Context::getId(), []);
diff --git a/app/controllers/course/dates.php b/app/controllers/course/dates.php
index a4e18e9..f64d66b 100644
--- a/app/controllers/course/dates.php
+++ b/app/controllers/course/dates.php
@@ -80,7 +80,10 @@ class Course_DatesController extends AuthenticatedController
)->asDialog();
}
- if (Seminar::setInstance(new Seminar(Course::findCurrent()))->getSlotModule('documents') && CourseDateFolder::availableInRange(Course::findCurrent(), User::findCurrent()->id)) {
+ if (
+ Seminar::setInstance(new Seminar(Course::findCurrent()))->getSlotModule('documents')
+ && CourseDateFolder::availableInRange(Course::findCurrent(), User::findCurrent() ? User::findCurrent()->id : null)
+ ) {
$actions->addLink(
_('Sitzungsordner anlegen'),
$this->url_for('course/dates/create_folders'),
diff --git a/app/controllers/course/details.php b/app/controllers/course/details.php
index 2a330e3..e1c9493 100644
--- a/app/controllers/course/details.php
+++ b/app/controllers/course/details.php
@@ -32,7 +32,7 @@ class Course_DetailsController extends AuthenticatedController
$this->course = Course::find($course_id);
if (!$this->course) {
- throw new Trails_Exception(
+ throw new Trails\Exception(
404,
_('Es konnte keine Veranstaltung gefunden werden')
);
diff --git a/app/controllers/course/enrolment.php b/app/controllers/course/enrolment.php
index eb4428e..420b5ca 100644
--- a/app/controllers/course/enrolment.php
+++ b/app/controllers/course/enrolment.php
@@ -37,7 +37,7 @@ class Course_EnrolmentController extends AuthenticatedController
return false;
}
if (!get_object_type($this->course_id, ['sem'])) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
$course = Seminar::GetInstance($this->course_id);
$enrolment_info = $course->getEnrolmentInfo($GLOBALS['user']->id);
diff --git a/app/controllers/course/forum/forum_controller.php b/app/controllers/course/forum/forum_controller.php
index 71d1aa0..65eec63 100644
--- a/app/controllers/course/forum/forum_controller.php
+++ b/app/controllers/course/forum/forum_controller.php
@@ -23,7 +23,7 @@ abstract class ForumController extends StudipController {
parent::before_filter($action, $args);
- $this->flash = Trails_Flash::instance();
+ $this->flash = Trails\Flash::instance();
// Set help keyword for Stud.IP's user-documentation and page title
PageLayout::setHelpKeyword('Basis.Forum');
diff --git a/app/controllers/course/gradebook/lecturers.php b/app/controllers/course/gradebook/lecturers.php
index b3b1f82..7ab02e7 100644
--- a/app/controllers/course/gradebook/lecturers.php
+++ b/app/controllers/course/gradebook/lecturers.php
@@ -258,7 +258,7 @@ class Course_Gradebook_LecturersController extends AuthenticatedController
public function edit_custom_definition_action($definitionId)
{
if (!$this->definition = Definition::findOneBySQL('id = ? AND course_id = ?', [$definitionId, \Context::getId()])) {
- throw new \Trails_Exception(404);
+ throw new \Trails\Exception(404);
}
// show template
@@ -271,7 +271,7 @@ class Course_Gradebook_LecturersController extends AuthenticatedController
{
CSRFProtection::verifyUnsafeRequest();
if (!$definition = Definition::findOneBySQL('id = ? AND course_id = ?', [$definitionId, \Context::getId()])) {
- throw new \Trails_Exception(404);
+ throw new \Trails\Exception(404);
}
$name = trim(\Request::get('name', ''));
diff --git a/app/controllers/course/grouping.php b/app/controllers/course/grouping.php
index 4f35b53..3cef673 100644
--- a/app/controllers/course/grouping.php
+++ b/app/controllers/course/grouping.php
@@ -36,6 +36,11 @@ class Course_GroupingController extends AuthenticatedController
if (!$GLOBALS['perm']->have_studip_perm('tutor', $this->course->id)) {
throw new AccessDeniedException(_('Sie haben leider nicht die notwendige Berechtigung für diese Aktion.'));
}
+
+ if ($GLOBALS['perm']->have_studip_perm('admin', $this->course->id)) {
+ $widget = new CourseManagementSelectWidget();
+ Sidebar::get()->addWidget($widget);
+ }
}
/**
diff --git a/app/controllers/course/lti.php b/app/controllers/course/lti.php
index e0ca2cf..4db7776 100644
--- a/app/controllers/course/lti.php
+++ b/app/controllers/course/lti.php
@@ -1,4 +1,7 @@
<?php
+
+use Studip\OAuth2\NegotiatesWithPsr7;
+
/**
* course/lti.php - LTI consumer API for Stud.IP
*
@@ -13,6 +16,8 @@
class Course_LtiController extends StudipController
{
+ use NegotiatesWithPsr7;
+
/**
* Callback function being called before an action is executed.
*/
@@ -268,22 +273,15 @@ class Course_LtiController extends StudipController
*/
public function save_link_action($tool_id)
{
- require_once 'vendor/oauth-php/library/OAuthRequestVerifier.php';
-
$tool = LtiTool::find($tool_id);
$lti_msg = Request::get('lti_msg');
$lti_errormsg = Request::get('lti_errormsg');
$content_items = Request::get('content_items');
$content_items = json_decode($content_items, true);
- OAuthStore::instance('PDO', [
- 'dsn' => 'mysql:host=' . $GLOBALS['DB_STUDIP_HOST'] . ';dbname=' . $GLOBALS['DB_STUDIP_DATABASE'],
- 'username' => $GLOBALS['DB_STUDIP_USER'],
- 'password' => $GLOBALS['DB_STUDIP_PASSWORD']
- ]);
-
- $oarv = new OAuthRequestVerifier();
- $oarv->verifySignature($tool->consumer_secret, false, false);
+ if (!Studip\OAuth1::verifyRequest($this->getPsrRequest(), $tool->consumer_secret, '')) {
+ throw new Exception('Could not verify request.');
+ }
if (is_array($content_items) && count($content_items['@graph'])) {
// we only support selecting a single content item
@@ -452,18 +450,11 @@ class Course_LtiController extends StudipController
*/
public function outcome_action($id)
{
- require_once 'vendor/oauth-php/library/OAuthRequestVerifier.php';
-
$lti_data = LtiData::find($id);
- OAuthStore::instance('PDO', [
- 'dsn' => 'mysql:host=' . $GLOBALS['DB_STUDIP_HOST'] . ';dbname=' . $GLOBALS['DB_STUDIP_DATABASE'],
- 'username' => $GLOBALS['DB_STUDIP_USER'],
- 'password' => $GLOBALS['DB_STUDIP_PASSWORD']
- ]);
-
- $oarv = new OAuthRequestVerifier();
- $oarv->verifySignature($lti_data->getConsumerSecret(), false, false);
+ if (!Studip\OAuth1::verifyRequest($this->getPsrRequest(), $lti_data->getConsumerSecret(), '')) {
+ throw new Exception('Could not verify request.');
+ }
// fetch and parse POST data
$message = file_get_contents('php://input');
diff --git a/app/controllers/course/lvgselector.php b/app/controllers/course/lvgselector.php
index 3542a11..c8223a9 100644
--- a/app/controllers/course/lvgselector.php
+++ b/app/controllers/course/lvgselector.php
@@ -17,15 +17,13 @@ require 'config/mvv_config.php';
class Course_LvgselectorController extends AuthenticatedController
{
-
- // see Trails_Controller#before_filter
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
$this->course = Course::findCurrent();
if (!$this->course) {
- throw new Trails_Exception(404, _('Es wurde keine Veranstaltung ausgewählt!'));
+ throw new Trails\Exception(404, _('Es wurde keine Veranstaltung ausgewählt!'));
}
$this->course_id = $this->course->id;
if (!$GLOBALS['perm']->have_studip_perm('tutor', $this->course_id)) {
@@ -37,6 +35,11 @@ class Course_LvgselectorController extends AuthenticatedController
$widget = new HelpbarWidget();
$widget->addElement(new WidgetElement(_('Auf dieser Seite kann die Veranstaltung ausgewählten Lehrveranstaltungsgruppen zugeordnet werden.')));
Helpbar::get()->addWidget($widget);
+
+ if ($GLOBALS['perm']->have_studip_perm('admin', $this->course_id)) {
+ $widget = new CourseManagementSelectWidget();
+ Sidebar::get()->addWidget($widget);
+ }
}
/**
diff --git a/app/controllers/course/members.php b/app/controllers/course/members.php
index 3eae083..1ec1587 100644
--- a/app/controllers/course/members.php
+++ b/app/controllers/course/members.php
@@ -232,7 +232,7 @@ class Course_MembersController extends AuthenticatedController
$course_member = AdmissionApplication::find([$user_id, $this->course_id]);
}
if (is_null($course_member)) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
$this->comment = $course_member->comment;
$this->user = User::find($user_id);
@@ -265,7 +265,7 @@ class Course_MembersController extends AuthenticatedController
$course_member = AdmissionApplication::find([$user_id, $this->course_id]);
}
if (!Request::submitted('save') || is_null($course_member)) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
$course_member->comment = Request::get('comment');
diff --git a/app/controllers/course/messenger.php b/app/controllers/course/messenger.php
index 3e692aa..710ac87 100644
--- a/app/controllers/course/messenger.php
+++ b/app/controllers/course/messenger.php
@@ -12,16 +12,20 @@ class Course_MessengerController extends AuthenticatedController
public function course_action($thread_id = null)
{
- if (Context::get()) {
- PageLayout::setTitle(Context::get()->getFullName() . ' - ' . _('Blubber'));
+ $context = Context::get();
+
+ if (!$context) {
+ throw new CheckObjectException(_('Sie haben kein Objekt gewählt.'));
}
if (Navigation::hasItem('/course/blubber')) {
Navigation::activateItem('/course/blubber');
}
+ PageLayout::setTitle($context->getFullName() . ' - ' . _('Blubber'));
+
$this->search = '';
- $this->threads = BlubberThread::findByContext(Context::get()->id, true, Context::getType());
+ $this->threads = BlubberThread::findByContext($context->id, true, Context::getType());
$this->thread = null;
$this->threads_more_down = 0;
diff --git a/app/controllers/course/overview.php b/app/controllers/course/overview.php
index 96e7f5a..876de5a 100644
--- a/app/controllers/course/overview.php
+++ b/app/controllers/course/overview.php
@@ -58,8 +58,6 @@ class Course_OverviewController extends AuthenticatedController
// Fetch votes
if (Config::get()->VOTE_ENABLE) {
- $response = $this->relay('evaluation/display/' . $this->course_id);
- $this->evaluations = $response->body;
$response = $this->relay('questionnaire/widget/' . $this->course_id);
$this->questionnaires = $response->body;
}
@@ -113,7 +111,7 @@ class Course_OverviewController extends AuthenticatedController
$this->avatar = StudygroupAvatar::getAvatar($this->course_id);
}
- $this->plugins = PluginEngine::getPlugins('StandardPlugin', $this->course_id);
+ $this->plugins = PluginEngine::getPlugins(StandardPlugin::class, $this->course_id);
$sidebar = Sidebar::get();
diff --git a/app/controllers/course/room_requests.php b/app/controllers/course/room_requests.php
index ab802b7..b091047 100644
--- a/app/controllers/course/room_requests.php
+++ b/app/controllers/course/room_requests.php
@@ -46,7 +46,7 @@ class Course_RoomRequestsController extends AuthenticatedController
SeminarCategories::GetBySeminarId($this->course_id)->studygroup_mode ||
!$GLOBALS['perm']->have_studip_perm("tutor", $this->course_id)
) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
PageLayout::setHelpKeyword('Basis.VeranstaltungenVerwaltenAendernVonZeitenUndTerminen');
@@ -143,25 +143,15 @@ class Course_RoomRequestsController extends AuthenticatedController
// a single date or whole course
$this->request_range_id = Request::get('range_id', Context::getId());
- if (!isset($_SESSION[$this->request_id])) {
- $_SESSION[$this->request_id] = [];
- }
+ $this->init_session();
$_SESSION[$this->request_id]['range'] = $this->request_range ?: $_SESSION[$this->request_id]['range'] ?? null;
$_SESSION[$this->request_id]['range_ids'] = $this->request_range_ids ?: [$this->request_range_id];
- $_SESSION[$this->request_id]['search_by'] = '';
- $_SESSION[$this->request_id]['room_category_id'] = '';
- $_SESSION[$this->request_id]['room_id'] = '';
- $_SESSION[$this->request_id]['room_name'] = '';
- $_SESSION[$this->request_id]['selected_properties'] = [];
-
- $this->request = null;
// look for existing request or create a new one
$this->request = new RoomRequest($this->request_id);
// time ranges (start date, end date)
$this->request->setRangeFields($_SESSION[$this->request_id]['range'], $_SESSION[$this->request_id]['range_ids']);
$this->request_time_intervals = $this->request->getTimeIntervals();
-
}
/**
@@ -211,7 +201,6 @@ class Course_RoomRequestsController extends AuthenticatedController
);
}
}
-
}
/**
@@ -227,7 +216,6 @@ class Course_RoomRequestsController extends AuthenticatedController
_('Das Erstellen von Raumanfragen ist nicht erlaubt!')
);
}
-
$this->request_id = $request_id;
$this->step = (int)$step;
$this->room_name = $_SESSION[$request_id]['room_name'];
@@ -266,15 +254,17 @@ class Course_RoomRequestsController extends AuthenticatedController
$this->selected_room = Resource::find($_SESSION[$request_id]['room_id'] ?: $this->request->resource_id);
$this->selected_room_category_id = $this->selected_room->category_id ?? $_SESSION[$request_id]['room_category_id'] ?? null;
+ $this->category = $this->selected_room_category_id ? ResourceCategory::find($this->selected_room_category_id) : null;
$_SESSION[$request_id]['room_category_id'] = $_SESSION[$request_id]['room_category_id'] ?? $this->selected_room->category_id ?? null;
// after selecting a room, go to next step or stay here if no room was selected at all
if (Request::submitted('select_room')) {
$this->selected_room_id = Request::get('selected_room_id');
+ $room = Room::find($this->selected_room_id);
$_SESSION[$request_id]['room_id'] = $this->selected_room_id;
+ $_SESSION[$request_id]['room_category_id'] = $room->category_id;
$_SESSION[$request_id]['select_room'] = true;
-
$this->redirect(
'course/room_requests/request_check_properties/' . $this->request_id
);
@@ -289,8 +279,6 @@ class Course_RoomRequestsController extends AuthenticatedController
);
return;
}
-
- // or we filter via category
else if (Request::get('category_id') && Request::submitted('select_properties')) {
$_SESSION[$request_id]['search_by'] = 'category';
$_SESSION[$request_id]['room_category_id'] = Request::get('category_id');
@@ -299,74 +287,35 @@ class Course_RoomRequestsController extends AuthenticatedController
);
return;
} else if (Request::submitted('reset_category')) {
- //Delete all selected properties from the session since the category is reset
- $_SESSION[$request_id]['selected_properties'] = [];
- $_SESSION[$request_id]['room_category_id'] = '';
- $_SESSION[$request_id]['room_name'] = '';
- $_SESSION[$request_id]['room_id'] = '';
- $this->redirect('course/room_requests/request_find_available_properties/' . $this->request_id . '/1');
+ $this->init_session();
+ $this->redirect('course/room_requests/new_request');
return;
}
// for step 2: after choosing a specific room OR searching via properties
if ($this->step === 2) {
- if ($_SESSION[$request_id]['search_by'] == 'roomname') {
- // find category via room
- $this->category = ResourceCategory::find($this->selected_room_category_id);
- if ($this->category) {
- $this->available_properties = $this->category->getRequestableProperties();
- }
-
- $this->selected_properties = $_SESSION[$request_id]['selected_properties'];
- $this->room = Room::find($_SESSION[$request_id]['room_id']);
- $this->selected_properties['seats'] = $_SESSION[$request_id]['selected_properties']['seats']
- ?: $this->course->admission_turnout
- ?: Config::get()->RESOURCES_ROOM_REQUEST_DEFAULT_SEATS;
- $_SESSION[$request_id]['selected_properties']['seats'] = $this->selected_properties['seats'];
- } else if ($_SESSION[$request_id]['search_by'] === 'category') {
+ if (!empty(Request::getArray('selected_properties'))) {
+ $this->selected_properties = Request::getArray('selected_properties');
+ } else {
+ $this->selected_properties = $_SESSION[$request_id]['selected_properties'];
+ }
+ $_SESSION[$request_id]['selected_properties'] = $this->selected_properties;
+ if ($_SESSION[$request_id]['search_by'] === 'roomname') {
+ $this->selected_properties = $_SESSION[$request_id]['selected_properties'] ?? null;
$this->room = Room::find($_SESSION[$request_id]['room_id']);
- if ($this->room) {
- $this->grouped_properties = $this->room->getGroupedProperties();
- foreach ($this->grouped_properties as $properties) {
- foreach ($properties as $property) {
- $this->selected_properties[$property->name] = $property->state;
- }
- }
+ if (!isset($_SESSION[$request_id]['selected_properties']['seats'])) {
+ $this->selected_properties['seats'] = $this->course->admission_turnout ?? Config::get()->RESOURCES_ROOM_REQUEST_DEFAULT_SEATS;
}
-
+ $_SESSION[$request_id]['selected_properties']['seats'] = $this->selected_properties['seats'];
+ $_SESSION[$request_id]['room_category_id'] = $this->selected_room_category_id;
+ } else {
+ // let's find all the properties belonging to the selected category
+ $this->room_category_id = $_SESSION[$request_id]['room_category_id'];
}
- // find rooms fitting to category and properties
- if (Request::submitted('search_rooms')) {
- $this->selected_properties = Request::getArray('selected_properties');
- $_SESSION[$request_id]['selected_properties'] = $this->selected_properties;
- // no min number of seats
- if (
- (!$_SESSION[$request_id]['selected_properties']['seats'] || $_SESSION[$request_id]['selected_properties']['seats'] < 1)
- && $_SESSION[$request_id]['search_by'] === 'category'
- ) {
- PageLayout::postError(
- _('Die Mindestanzahl der Sitzplätze beträgt 1!')
- );
- $this->redirect(
- 'course/room_requests/request_find_matching_rooms/' . $request_id . '/' . $this->step
- );
- return;
- } else {
- $this->redirect(
- 'course/room_requests/request_find_matching_rooms/' . $request_id . '/' . $this->step
- );
- return;
- }
+ if ($this->category) {
+ $this->available_properties = $this->category->getRequestableProperties();
}
-
- // let's find all the properties belonging to the selected category
- $this->room_category_id = $_SESSION[$request_id]['room_category_id'];
- $this->category = ResourceCategory::find($this->room_category_id);
- $this->available_properties = $this->category->getRequestableProperties();
-
- // properties, like 'Sitzplätze', 'behindertengerecht' etc
- $this->selected_properties = $_SESSION[$request_id]['selected_properties'] ?? null;
$this->preparation_time = $_SESSION[$request_id]['preparation_time'] ?? null;
$this->comment = $_SESSION[$request_id]['comment'] ?? null;
$this->request->category_id = $_SESSION[$request_id]['room_category_id'];
@@ -375,7 +324,10 @@ class Course_RoomRequestsController extends AuthenticatedController
if (Request::submitted('show_summary')) {
$this->selected_room_id = Request::get('selected_room_id');
$_SESSION[$request_id]['room_id'] = $this->selected_room_id;
- $_SESSION[$request_id]['selected_properties'] = Request::getArray('selected_properties');
+ $room = Room::find($this->selected_room_id);
+ if ($room) {
+ $_SESSION[$request_id]['room_category_id'] = $room->category_id;
+ }
$this->redirect('course/room_requests/request_show_summary/' . $this->request_id );
}
}
@@ -394,16 +346,18 @@ class Course_RoomRequestsController extends AuthenticatedController
_('Das Erstellen von Raumanfragen ist nicht erlaubt!')
);
}
-
$this->request_id = $request_id;
$this->step = (int)$step;
$this->request = new RoomRequest($this->request_id);
- $this->request->setRangeFields($_SESSION[$this->request_id]['range'], $_SESSION[$this->request_id]['range_ids']);
+ $this->request->setRangeFields(
+ $_SESSION[$this->request_id]['range'] ?? null,
+ $_SESSION[$this->request_id]['range_ids'] ?? null
+ );
// let's find all the properties belonging to the selected category
$this->room_category_id = $_SESSION[$request_id]['room_category_id'] ?: $this->request->category_id;
- $this->room_name = $_SESSION[$request_id]['room_name'];
+ $this->room_name = $_SESSION[$request_id]['room_name'] ?? '';
$this->selected_room = Resource::find($_SESSION[$request_id]['room_id'] ?: $this->request->resource_id);
$this->category = $this->room_category_id ? ResourceCategory::find($this->room_category_id) : '';
$this->available_properties = $this->room_category_id ? $this->category->getRequestableProperties() : '';
@@ -418,7 +372,10 @@ class Course_RoomRequestsController extends AuthenticatedController
$this->comment = $_SESSION[$request_id]['comment'] ?? null;
// when searching for a room name, list found room
- if ($_SESSION[$request_id]['room_name'] !== '') {
+ if (
+ isset($_SESSION[$request_id]['room_name'])
+ && $_SESSION[$request_id]['room_name'] !== ''
+ ) {
$search_properties['room_category_id'] = $this->room_category_id;
$search_properties['seats'] = [
1,
@@ -455,11 +412,13 @@ class Course_RoomRequestsController extends AuthenticatedController
}
$this->request_id = $request_id;
-
+ $this->selected_properties = Request::getArray('selected_properties');
// select a room, search for a room name or search for rooms matching properties
if (Request::submitted('select_room')) {
$this->selected_room_id = Request::get('selected_room_id');
+ $room = Room::find($this->selected_room_id);
$_SESSION[$request_id]['room_id'] = $this->selected_room_id;
+ $_SESSION[$request_id]['room_category_id'] = $room->category_id;
$_SESSION[$request_id]['select_room'] = true;
$this->step = 2;
$this->request = new RoomRequest($this->request_id);
@@ -467,7 +426,6 @@ class Course_RoomRequestsController extends AuthenticatedController
'course/room_requests/request_find_matching_rooms/' . $this->request_id . '/' . $this->step
);
} else if (Request::get('room_name') && Request::submitted('search_by_name')) {
- $this->selected_properties = Request::getArray('selected_properties');
$this->category_id = Request::get('category_id');
$_SESSION[$request_id]['selected_properties'] = $this->selected_properties;
$_SESSION[$request_id]['room_category_id'] = $this->category_id;
@@ -479,7 +437,6 @@ class Course_RoomRequestsController extends AuthenticatedController
);
} else if (Request::submitted('search_rooms')) {
- $this->selected_properties = Request::getArray('selected_properties');
$this->category_id = Request::get('category_id');
$_SESSION[$request_id]['room_category_id'] = $this->category_id;
$_SESSION[$request_id]['selected_properties'] = $this->selected_properties;
@@ -506,8 +463,7 @@ class Course_RoomRequestsController extends AuthenticatedController
}
} else if (Request::submitted('reset_category')) {
//Delete all selected properties from the session since the category is reset
- $_SESSION[$request_id]['selected_properties'] = [];
- $_SESSION[$request_id]['room_category_id'] = '';
+ $this->init_session();
$this->redirect('course/room_requests/request_find_available_properties/' . $this->request_id . '/1');
} else if (Request::submitted('search_by_category')) {
if (Request::get('category_id') === '0') {
@@ -521,12 +477,11 @@ class Course_RoomRequestsController extends AuthenticatedController
);
} else if (Request::submitted('show_summary')) {
$this->request = new RoomRequest($this->request_id);
- $this->selected_properties = Request::getArray('selected_properties');
-
- $_SESSION[$request_id]['selected_properties'] = $this->selected_properties;
$this->selected_room_id = Request::get('selected_room_id');
+ $room = Room::find($this->selected_room_id);
$_SESSION[$request_id]['room_id'] = $this->selected_room_id;
-
+ $_SESSION[$request_id]['room_category_id'] = $room->category_id ?? $_SESSION[$request_id]['room_category_id'];
+ $_SESSION[$request_id]['selected_properties'] = $this->selected_properties;
$this->redirect('course/room_requests/request_show_summary/' . $this->request_id );
} else {
$room = Room::find($_SESSION[$request_id]['room_id']);
@@ -569,7 +524,6 @@ class Course_RoomRequestsController extends AuthenticatedController
);
$this->selected_room_category = ResourceCategory::find($_SESSION[$request_id]['room_category_id'] ?? $this->request->category_id);
-
$this->selected_room = Resource::find($_SESSION[$request_id]['room_id'] ?? $this->request->resource_id);
$this->room_id = $_SESSION[$request_id]['room_id'] ?? $this->request->resource_id;
@@ -592,7 +546,7 @@ class Course_RoomRequestsController extends AuthenticatedController
$_SESSION[$request_id]['search_by'] = $this->selected_room ? 'roomname' : 'category';
$_SESSION[$request_id]['room_category_id'] = $this->selected_room_category->id;
- $_SESSION[$request_id]['room_id'] = $this->selected_room->id;
+ $_SESSION[$request_id]['room_id'] = $this->selected_room ? $this->selected_room->id : '';
}
public function store_request_action($request_id)
@@ -629,8 +583,12 @@ class Course_RoomRequestsController extends AuthenticatedController
$this->request->store();
//Store the properties:
- foreach ($_SESSION[$request_id]['selected_properties'] as $name => $state) {
- $this->request->setProperty($name, $state);
+ if (isset($_SESSION[$request_id]['selected_properties'])) {
+ foreach ($_SESSION[$request_id]['selected_properties'] as $name => $state) {
+ if (!empty($state)) {
+ $this->request->setProperty($name, $state);
+ }
+ }
}
// once stored, we can delete the session data for this request
@@ -707,7 +665,7 @@ class Course_RoomRequestsController extends AuthenticatedController
{
$request = RoomRequest::find($request_id);
if (!$request) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if (Request::isGet()) {
PageLayout::postQuestion(sprintf(
@@ -723,4 +681,19 @@ class Course_RoomRequestsController extends AuthenticatedController
}
$this->redirect('course/timesrooms/index');
}
+
+ private function init_session()
+ {
+ $_SESSION[$this->request_id] = array_merge(
+ $_SESSION[$this->request_id] ?? [],
+ [
+ 'search_by' => '',
+ 'room_category_id' => '',
+ 'room_id' => '',
+ 'room_name' => '',
+ 'select_room' => false,
+ 'selected_properties' => [],
+ ]
+ );
+ }
}
diff --git a/app/controllers/course/scm.php b/app/controllers/course/scm.php
index 66af981..4c5d4eb 100644
--- a/app/controllers/course/scm.php
+++ b/app/controllers/course/scm.php
@@ -93,7 +93,7 @@ class Course_ScmController extends AuthenticatedController
$this->scm = $id ? $this->scms->find($id) : $this->scms->first();
if (!$this->scm && $this->scms->count() > 0) {
- throw new Trails_Exception(404, _('Es konnte keine freie Informationsseite mit der angegebenen Id gefunden werden.'));
+ throw new Trails\Exception(404, _('Es konnte keine freie Informationsseite mit der angegebenen Id gefunden werden.'));
}
if (Request::get('verify') === 'delete') {
diff --git a/app/controllers/course/statusgroups.php b/app/controllers/course/statusgroups.php
index c15733d..6f96299 100644
--- a/app/controllers/course/statusgroups.php
+++ b/app/controllers/course/statusgroups.php
@@ -762,7 +762,7 @@ class Course_StatusgroupsController extends AuthenticatedController
// Safety check if no group_id at all.
if (!$group_id) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
}
@@ -1487,4 +1487,20 @@ class Course_StatusgroupsController extends AuthenticatedController
return $members->orderBy($order);
}
+
+ public function details_action(Statusgruppen $group): void
+ {
+ $course = Course::findCurrent();
+
+ if ($course->id !== $group->range_id) {
+ throw new AccessDeniedException();
+ }
+
+ PageLayout::setTitle(sprintf(
+ _('Personen der Gruppe %s'),
+ $group->name
+ ));
+
+ $this->group = $group;
+ }
}
diff --git a/app/controllers/course/study_areas.php b/app/controllers/course/study_areas.php
index df54bb4..e951d11 100644
--- a/app/controllers/course/study_areas.php
+++ b/app/controllers/course/study_areas.php
@@ -18,7 +18,6 @@ require_once 'lib/webservices/api/studip_lecture_tree.php';
class Course_StudyAreasController extends AuthenticatedController
{
- // see Trails_Controller#before_filter
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
@@ -101,7 +100,7 @@ class Course_StudyAreasController extends AuthenticatedController
public function save_action()
{
if($this->locked) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$params = [];
diff --git a/app/controllers/course/studygroup.php b/app/controllers/course/studygroup.php
index b75d91e..cd08ba3 100644
--- a/app/controllers/course/studygroup.php
+++ b/app/controllers/course/studygroup.php
@@ -10,8 +10,6 @@ require_once 'lib/user_visible.inc.php';
*/
class Course_StudygroupController extends AuthenticatedController
{
-
- // see Trails_Controller#before_filter
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
@@ -596,6 +594,11 @@ class Course_StudygroupController extends AuthenticatedController
global $perm;
$id = Context::getId();
+
+ if (!$id) {
+ throw new CheckObjectException(_('Sie haben kein Objekt gewählt.'));
+ }
+
$user = Request::username('user');
if ($from_status === 'moderator') {
@@ -780,7 +783,7 @@ class Course_StudygroupController extends AuthenticatedController
// send invite message to user
$msg = new messaging();
$sem = new Seminar($id);
- $message = sprintf(_("%s möchte Sie auf die Studiengruppe %s aufmerksam machen. Klicken Sie auf den untenstehenden Link, um direkt zur Studiengruppe zu gelangen.\n\n %s"),
+ $message = sprintf(_("%s möchte Sie auf die Studiengruppe %s aufmerksam machen. Klicken Sie auf den folgenden Link, um direkt zur Studiengruppe zu gelangen.\n\n %s"),
get_fullname(), $sem->name, URLHelper::getlink("dispatch.php/course/studygroup/details/" . $id, ['cid' => null]));
$subject = _("Sie wurden in eine Studiengruppe eingeladen");
$msg->insert_message($message, get_username($receiver), '', '', '', '', '', $subject);
@@ -846,7 +849,7 @@ class Course_StudygroupController extends AuthenticatedController
return;
}
}
- throw new Trails_Exception(401);
+ throw new Trails\Exception(401);
}
diff --git a/app/controllers/course/timesrooms.php b/app/controllers/course/timesrooms.php
index 2e3b3fe..4788eee 100644
--- a/app/controllers/course/timesrooms.php
+++ b/app/controllers/course/timesrooms.php
@@ -14,7 +14,7 @@ class Course_TimesroomsController extends AuthenticatedController
* @param String $action Action to be executed
* @param Array $args Arguments passed to the action
*
- * @throws Trails_Exception when either no course was found or the user
+ * @throws Trails\Exception when either no course was found or the user
* may not access this area
*/
public function before_filter(&$action, &$args)
@@ -23,7 +23,7 @@ class Course_TimesroomsController extends AuthenticatedController
// Try to find a valid course
if (!Course::findCurrent()) {
- throw new Trails_Exception(404, _('Es wurde keine Veranstaltung ausgewählt!'));
+ throw new Trails\Exception(404, _('Es wurde keine Veranstaltung ausgewählt!'));
}
if (!$GLOBALS['perm']->have_studip_perm('tutor', Course::findCurrent()->id)) {
@@ -250,7 +250,7 @@ class Course_TimesroomsController extends AuthenticatedController
/**
* Edit the start-semester of a course
*
- * @throws Trails_DoubleRenderError
+ * @throws Trails\Exceptions\DoubleRenderError
*/
public function editSemester_action()
{
@@ -331,11 +331,6 @@ class Course_TimesroomsController extends AuthenticatedController
$this->date = CourseDate::find($termin_id) ?: CourseExDate::find($termin_id);
$this->attributes = [];
- if ($request = RoomRequest::findByDate($this->date->id)) {
- $this->params = ['request_id' => $request->getId()];
- } else {
- $this->params = ['new_room_request_type' => 'date_' . $this->date->id];
- }
$this->only_bookable_rooms = Request::submitted('only_bookable_rooms');
if (Config::get()->RESOURCES_ENABLE) {
@@ -373,7 +368,7 @@ class Course_TimesroomsController extends AuthenticatedController
*
* @param $termin_id
*
- * @throws Trails_DoubleRenderError
+ * @throws Trails\Exceptions\DoubleRenderError
*/
public function saveDate_action($termin_id)
{
@@ -439,7 +434,7 @@ class Course_TimesroomsController extends AuthenticatedController
}
// Set assigned groups
- $assigned_groups = Request::optionArray('assigned_groups');
+ $assigned_groups = Request::optionArray('assigned-groups');
$termin->statusgruppen = Statusgruppen::findMany($assigned_groups);
$termin->store();
@@ -449,7 +444,11 @@ class Course_TimesroomsController extends AuthenticatedController
}
// Set Room
- $old_room_id = $termin->room_booking->resource_id;
+ if ($termin->room_booking) {
+ $old_room_id = $termin->room_booking->resource_id;
+ } else {
+ $old_room_id = null;
+ }
$singledate = new SingleDate($termin);
if ($singledate->setTime($date, $end_time)) {
$singledate->store();
@@ -517,7 +516,7 @@ class Course_TimesroomsController extends AuthenticatedController
'<strong>' . htmlReady($singledate->toString()) . '</strong>'
));
}
- if ($singledate->messages['error']) {
+ if (!empty($singledate->messages['error'])) {
PageLayout::postError(
_('Die folgenden Fehler traten beim Bearbeiten des Termins auf:'),
htmlReady($singledate->messages['error'])
@@ -549,7 +548,7 @@ class Course_TimesroomsController extends AuthenticatedController
/**
* Save Single Date
*
- * @throws Trails_DoubleRenderError
+ * @throws Trails\Exceptions\DoubleRenderError
*/
public function saveSingleDate_action()
{
@@ -1490,23 +1489,10 @@ class Course_TimesroomsController extends AuthenticatedController
}
Sidebar::Get()->addWidget($widget);
- if ($GLOBALS['perm']->have_perm('admin')) {
- $list = new SelectWidget(
- _('Veranstaltungen'),
- $this->indexURL(),
- 'cid'
- );
- foreach (AdminCourseFilter::get()->getCoursesForAdminWidget() as $seminar) {
- $list->addElement(new SelectElement(
- $seminar['Seminar_id'],
- $seminar['Name'],
- $seminar['Seminar_id'] === Context::getId(),
- $seminar['VeranstaltungsNummer'] . ' ' . $seminar['Name']
- ));
- }
- $list->size = 8;
- Sidebar::Get()->addWidget($list);
+ if ($GLOBALS['perm']->have_studip_perm('admin', $this->course->id)) {
+ $widget = new CourseManagementSelectWidget();
+ Sidebar::get()->addWidget($widget);
}
}
@@ -1701,7 +1687,7 @@ class Course_TimesroomsController extends AuthenticatedController
} else {
$user_rooms = RoomManager::getUserRooms($current_user);
foreach ($user_rooms as $room) {
- if ($room->userHasBookingRights($current_user, $begin, $end)) {
+ if ($room->userHasBookingRights($current_user, $begin ?? null, $end ?? null)) {
$rooms_with_booking_permissions++;
if ($only_bookable_rooms) {
foreach ($all_time_intervals as $interval) {
diff --git a/app/controllers/course/wiki.php b/app/controllers/course/wiki.php
index 7a3a09e..4de56a7 100644
--- a/app/controllers/course/wiki.php
+++ b/app/controllers/course/wiki.php
@@ -18,7 +18,7 @@ class Course_WikiController extends AuthenticatedController
parent::before_filter($action, $args);
object_set_visit_module('wiki');
$this->range = Context::get();
- $this->plugin = PluginManager::getInstance()->getPlugin('CoreWiki');
+ $this->plugin = PluginManager::getInstance()->getPlugin(CoreWiki::class);
PageLayout::setTitle(Navigation::getItem('/course/wiki')->getTitle());
}
@@ -117,8 +117,9 @@ class Course_WikiController extends AuthenticatedController
$startPage = WikiPage::find($this->range->getConfiguration()->WIKI_STARTPAGE_ID);
$this->contentbar = ContentBar::get()
->setTOC(CoreWiki::getTOC($this->page))
- ->setIcon(Icon::create('wiki'))
- ->setInfo(sprintf(
+ ->setIcon(Icon::create('wiki'));
+ if (!$this->page->isNew()) {
+ $this->contentbar->setInfo(sprintf(
_('Version %1$s, geändert von %2$s <br> am %3$s'),
$this->page->versionnumber,
sprintf(
@@ -128,33 +129,44 @@ class Course_WikiController extends AuthenticatedController
),
date('d.m.Y H:i:s', $this->page['chdate'])
));
- $action_menu = ActionMenu::get();
- if ($this->page->isEditable()) {
- $action_menu->addLink(
- $this->editURL($this->page),
- _('Bearbeiten'),
- Icon::create('edit')
- );
+ $action_menu = ActionMenu::get();
+ if ($this->page->isEditable()) {
+ $action_menu->addLink(
+ $this->editURL($this->page),
+ _('Bearbeiten'),
+ Icon::create('edit')
+ );
+ $action_menu->addLink(
+ $this->pagesettingsURL($this->page->id),
+ _('Seiteneinstellungen'),
+ Icon::create('settings'),
+ ['data-dialog' => 'width=700']
+ );
+ if (count($this->page->versions) > 0) {
+ $action_menu->addLink(
+ $this->ask_deletingURL($this->page),
+ _('Seite / Version löschen'),
+ Icon::create('trash'),
+ ['data-dialog' => 'size=auto']
+ );
+ } else {
+ $action_menu->addButton(
+ 'delete',
+ _('Seite löschen'),
+ Icon::create('trash'),
+ ['data-confirm' => _('Wollen Sie wirklich die komplette Seite löschen?'), 'form' => 'delete_page']
+ );
+ }
+ }
$action_menu->addLink(
- $this->pagesettingsURL($this->page->id),
- _('Seiteneinstellungen'),
- Icon::create('settings'),
- ['data-dialog' => 'width=700']
- );
- $action_menu->addButton(
- 'delete',
- _('Seite löschen'),
- Icon::create('trash'),
- ['data-confirm' => _('Wollen Sie wirklich die komplette Seite löschen?'), 'form' => 'delete_page']
+ '#',
+ _('Als Vollbild anzeigen'),
+ Icon::create('screen-full'),
+ ['class' => 'fullscreen-trigger hidden-medium-down']
);
+ $this->contentbar->setActionMenu($action_menu);
}
- $action_menu->addLink(
- '#',
- _('Als Vollbild anzeigen'),
- Icon::create('screen-full'),
- ['class' => 'fullscreen-trigger hidden-medium-down']
- );
- $this->contentbar->setActionMenu($action_menu);
+
}
public function pagesettings_action(WikiPage $page)
@@ -253,7 +265,10 @@ class Course_WikiController extends AuthenticatedController
"[[ " . $values['name'],
$p2['content']
);
- $p2->store();
+ if ($p2->isDirty()) {
+ $p2['user_id'] = User::findCurrent()->id;
+ $p2->store();
+ }
}
})->validate();
if (Request::isPost()) {
@@ -269,9 +284,17 @@ class Course_WikiController extends AuthenticatedController
$this->render_form($this->form);
}
+ public function ask_deleting_action(WikiPage $page)
+ {
+ if (!$page->isEditable()) {
+ throw new AccessDeniedException();
+ }
+ PageLayout::setTitle(_('Was genau soll gelöscht werden?'));
+ }
+
public function delete_action(WikiPage $page)
{
- if (!Request::isPost() || !CSRFProtection::verifyRequest()) {
+ if (!Request::isPost() || !$page->isEditable() || !CSRFProtection::verifyRequest()) {
throw new AccessDeniedException();
}
$name = $page->name;
@@ -280,13 +303,52 @@ class Course_WikiController extends AuthenticatedController
$this->redirect($this->allpagesURL());
}
+ public function deleteversion_action(WikiPage $page, $version_id = null)
+ {
+ if (!Request::isPost() || !$page->isEditable() || !CSRFProtection::verifyRequest()) {
+ throw new AccessDeniedException();
+ }
+ if ($version_id === null) {
+ $version = $page->versions[0];
+ if ($version) {
+ $page['name'] = $version['name'];
+ $page['content'] = $version['content'];
+ $page['user_id'] = $version['user_id'];
+ $page['chdate'] = $version['mkdate'];
+ $page->store();
+ $version->delete();
+ } else {
+ $page->delete();
+ }
+ } else {
+ $version = WikiVersion::find($version_id);
+ if ($version['page_id'] === $page->id) {
+ $version->delete();
+ }
+ }
+ PageLayout::postSuccess(_('Version wurde gelöscht.'));
+ if (Request::get('redirect_to') === 'page') {
+ $this->redirect($this->page($page));
+ } else {
+ $this->redirect($this->history($page));
+ }
+
+ }
+
public function allpages_action()
{
- Navigation::activateItem('/course/wiki/allpages');
$this->pages = WikiPage::findBySQL(
"`range_id` = ? ORDER BY `name` ASC",
[$this->range->id]
);
+
+ if (count($this->pages) === 0) {
+ $this->redirect($this->pageURL());
+ return;
+ }
+
+ Navigation::activateItem('/course/wiki/allpages');
+
if ($GLOBALS['perm']->have_studip_perm('tutor', $this->range->id)) {
$actions = new ActionsWidget();
$actions->addLink(
@@ -379,7 +441,7 @@ class Course_WikiController extends AuthenticatedController
$this->redirect($this->editURL($page));
return;
}
- if (!$page->isEditable()) {
+ if ($page->isNew() || !$page->isEditable()) {
throw new AccessDeniedException();
}
Navigation::activateItem('/course/wiki/start');
@@ -393,7 +455,7 @@ class Course_WikiController extends AuthenticatedController
);
$pageData = [
'page_id' => $page->id,
- 'user_id' => $user->id
+ 'user_id' => $user ? $user->id : null,
];
$online_user = WikiOnlineEditingUser::findOneBySQL(
'`page_id` = :page_id AND `user_id` = :user_id',
@@ -404,7 +466,7 @@ class Course_WikiController extends AuthenticatedController
}
$editingUsers = WikiOnlineEditingUser::countBySQL(
"`page_id` = ? AND `editing` = 1 AND `user_id` != ?",
- [$page->id, $user->id]
+ [$page->id, $user ? $user->id : null]
);
$online_user->editing = $editingUsers === 0 ? 1 : 0;
$online_user->chdate = time();
@@ -501,6 +563,7 @@ class Course_WikiController extends AuthenticatedController
$this->render_json([
'error' => 'user_not_requested_edit_mode'
]);
+ return;
}
$online_user_me->editing = 0;
@@ -524,7 +587,19 @@ class Course_WikiController extends AuthenticatedController
}
$page->content = \Studip\Markup::markAsHtml(trim(Request::get('content')));
- $page->store();
+ $user = User::findCurrent();
+ if ($page->isDirty()) {
+ $page['user_id'] = $user->id;
+ $page->store();
+ }
+ $pageData = [
+ 'page_id' => $page->id,
+ 'user_id' => $user->id
+ ];
+ WikiOnlineEditingUser::deleteBySQL(
+ '`page_id` = :page_id AND `user_id` = :user_id',
+ $pageData
+ );
PageLayout::postSuccess(_('Die Seite wurde gespeichert.'));
$this->redirect($this->pageURL($page));
}
@@ -560,7 +635,7 @@ class Course_WikiController extends AuthenticatedController
$statement->execute([
'range_id' => $this->range->id,
'threshold' => $this->last_visit,
- 'me' => User::findCurrent()->id
+ 'me' => User::findCurrent() ? User::findCurrent()->id : null
]);
$this->num_entries = $statement->fetch(PDO::FETCH_COLUMN);
$this->pagenumber = Request::int('page', 0);
@@ -754,6 +829,10 @@ class Course_WikiController extends AuthenticatedController
'type' => 'no',
'mapper' => function () { return $this->range->id; }
],
+ 'user_id' => [
+ 'type' => 'no',
+ 'mapper' => function () { return User::findCurrent()->id; }
+ ],
'name' => [
'required' => true,
'label' => _('Name der Seite'),
@@ -808,7 +887,10 @@ class Course_WikiController extends AuthenticatedController
'[[ ' . $values['name'] . ' ]]',
$page->content
);
- $page->store();
+ if ($page->isDirty()) {
+ $page['user_id'] = User::findCurrent()->id;
+ $page->store();
+ }
}
}
}
@@ -894,6 +976,30 @@ class Course_WikiController extends AuthenticatedController
Sidebar::Get()->addWidget($search);
}
+ public function searchpage_action(WikiPage $page)
+ {
+ if (!$page->isReadable()) {
+ throw new AccessDeniedException();
+ }
+ Navigation::activateItem('/course/wiki/allpages');
+ if (!Request::get('search')) {
+ throw new Exception('No search text.');
+ }
+ $search = str_replace(['\\', '_', '%'], ['\\\\', '\\_', '\\%'], Request::get('search'));
+ $this->versions = WikiVersion::findBySQL("`page_id` = :page_id AND (`wiki_versions`.`content` LIKE :searchterm OR `wiki_versions`.`name` LIKE :searchterm) ORDER BY `mkdate` DESC ", [
+ 'page_id' => $page->id,
+ 'searchterm' => '%' . $search . '%'
+ ]);
+
+ $search = new SearchWidget($this->searchURL());
+ $search->addNeedle(
+ _('Im Wiki suchen'),
+ 'search',
+ true
+ );
+ Sidebar::Get()->addWidget($search);
+ }
+
public function pdf_action(WikiPage $page)
{
if (!$page->isReadable()) {
@@ -1135,4 +1241,41 @@ class Course_WikiController extends AuthenticatedController
return $from_end ? mb_strlen($str0) - $length : $length;
}
+
+ public function findTextualHits($text, $search, $length = 80)
+ {
+ $content = Studip\Markup::removeHtml($text);
+ $offset = 0;
+ $output = [];
+
+ // find all occurences
+ while ($offset < mb_strlen($content)) {
+ $pos = mb_stripos($content, Request::get('search'), $offset);
+ if ($pos === false) {
+ break;
+ }
+ $offset = $pos + 1;
+
+ // show max 200 chars
+ $fragment = '';
+ $split_fragment = preg_split(
+ '/(' . preg_quote(Request::get('search'), '/') . ')/i',
+ mb_substr($content, max(0, $pos - floor($length / 2)), $length),
+ -1,
+ PREG_SPLIT_DELIM_CAPTURE
+ );
+ for ($i = 0; $i < count($split_fragment); ++$i) {
+ if ($i % 2) {
+ $fragment .= '<span class="wiki_highlight">';
+ $fragment .= htmlready($split_fragment[$i], false);
+ $fragment .= '</span>';
+ } else {
+ $fragment .= htmlready($split_fragment[$i], false);
+ }
+ }
+ $found_in_fragment = (count($split_fragment) - 1) / 2; // number of hits in fragment
+ $output[] = '...' . $fragment . '...';
+ }
+ return implode('<br>', $output);
+ }
}
diff --git a/app/controllers/course/wizard.php b/app/controllers/course/wizard.php
index b45f9e5..c1571ad 100644
--- a/app/controllers/course/wizard.php
+++ b/app/controllers/course/wizard.php
@@ -25,14 +25,9 @@ class Course_WizardController extends AuthenticatedController
public function before_filter (&$action, &$args)
{
parent::before_filter($action, $args);
- global $perm;
- if (Request::isXhr()) {
- $this->dialog = true;
- }
-
- $sidebar = Sidebar::get();
- $this->studygroup = Request::int('studygroup') ?: $this->flash['studygroup'];
+ $this->dialog = Request::isXhr();
+ $this->studygroup = Request::bool('studygroup', $this->flash['studygroup'] ?? false);
if (!$this->studygroup) {
PageLayout::setTitle(_('Neue Veranstaltung anlegen'));
diff --git a/app/controllers/debugbar.php b/app/controllers/debugbar.php
new file mode 100644
index 0000000..59627f2
--- /dev/null
+++ b/app/controllers/debugbar.php
@@ -0,0 +1,24 @@
+<?php
+final class DebugbarController extends Trails_Controller
+{
+ public function __construct(
+ Trails\Dispatcher $dispatcher,
+ private readonly DebugBar\DebugBar $debugbar
+ ) {
+ parent::__construct($dispatcher);
+ }
+
+ public function css_action(): void
+ {
+ $this->set_content_type('text/css;charset=utf-8');
+ $this->render_nothing();
+ $this->debugbar->getJavascriptRenderer()->dumpCssAssets();
+ }
+
+ public function js_action(): void
+ {
+ $this->set_content_type('text/javascript;charset=utf-8');
+ $this->render_nothing();
+ $this->debugbar->getJavascriptRenderer()->setIncludeVendors(false)->dumpJsAssets();
+ }
+}
diff --git a/app/controllers/document.php b/app/controllers/document.php
index da15ebe..5057d9e 100644
--- a/app/controllers/document.php
+++ b/app/controllers/document.php
@@ -21,7 +21,7 @@ class DocumentController extends StudipController
if ($file_ref) {
$this->redirect($file_ref->getDownloadURL($disposition === 'inline' ? 'normal' : 'force'));
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
}
diff --git a/app/controllers/evaluation.php b/app/controllers/evaluation.php
deleted file mode 100644
index 4a157a9..0000000
--- a/app/controllers/evaluation.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-# Lifter010: TODO
-/**
- * vote.php - Votecontroller controller
- *
- * 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.
- */
-
-class EvaluationController extends AuthenticatedController
-{
- public function display_action($range_id)
- {
- // Bind some params
- URLHelper::bindLinkParam('show_expired', $null1);
-
- // Bind range_id
- $this->range_id = $range_id;
-
- $this->nobody = !$GLOBALS['user']->id || $GLOBALS['user']->id == 'nobody';
-
- // Check if we ned administration icons
- $this->admin = $range_id == $GLOBALS['user']->id || $GLOBALS['perm']->have_studip_perm('tutor', $range_id);
-
- // Load evaluations
- if (!$this->nobody) {
- $eval_db = new EvaluationDB();
- $this->evaluations = StudipEvaluation::findMany($eval_db->getEvaluationIDs($range_id, EVAL_STATE_ACTIVE));
- } else {
- $this->evaluations = [];
- }
- // Check if we got expired
- if (Request::get('show_expired')) {
- if ($this->admin) {
- $this->evaluations = array_merge($this->evaluations, StudipEvaluation::findMany($eval_db->getEvaluationIDs($range_id, EVAL_STATE_STOPPED)));
- }
- }
- if (!empty($this->suppress_empty_output) && count($this->evaluations) === 0) {
- $this->render_nothing();
- } else {
- $this->visit();
- }
- }
-
- public function visit()
- {
- if ($GLOBALS['user']->id && $GLOBALS['user']->id != 'nobody' && Request::option('contentbox_open') && in_array(Request::option('contentbox_type'), words('vote eval'))) {
- object_set_visit(Request::option('contentbox_open'), Request::option('contentbox_type'));
- }
- }
-
- public function visit_action()
- {
- $this->visit();
- $this->render_nothing();
- }
-
-}
diff --git a/app/controllers/extern.php b/app/controllers/extern.php
index 6cde6f3..9296a34 100644
--- a/app/controllers/extern.php
+++ b/app/controllers/extern.php
@@ -21,7 +21,7 @@ class ExternController extends StudipController
* Action shows rendered external page.
*
* @param string $config_id The id of the configuration of the external page to show.
- * @throws Trails_DoubleRenderError
+ * @throws Trails\Exceptions\DoubleRenderError
*/
public function index_action(string $config_id)
{
diff --git a/app/controllers/fachabschluss/kategorien.php b/app/controllers/fachabschluss/kategorien.php
index 205f1f1..f9ba041 100644
--- a/app/controllers/fachabschluss/kategorien.php
+++ b/app/controllers/fachabschluss/kategorien.php
@@ -114,7 +114,7 @@ class Fachabschluss_KategorienController extends MVVController
if (Request::submitted('delete')) {
CSRFProtection::verifyUnsafeRequest();
if (!MvvPerm::get('AbschlussKategorie')->haveFieldPerm('position')) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if (!count($abschluss_kategorie->abschluesse)) {
PageLayout::postSuccess(sprintf(
@@ -142,7 +142,7 @@ class Fachabschluss_KategorienController extends MVVController
$orderedIds = Request::getArray('newOrder');
if ($list === 'abschluss_kategorien') {
if (!MvvPerm::get('AbschlussKategorie')->haveFieldPerm('position')) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$kategorien = SimpleORMapCollection::createFromArray(
AbschlussKategorie::findBySql('1 ORDER BY position')
@@ -162,7 +162,7 @@ class Fachabschluss_KategorienController extends MVVController
}
} else {
if (!MvvPerm::get('AbschlussZuord')->haveFieldPerm('position')) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
list(, $kategorie_id) = explode('_', $list);
$abschluss_kategorie = AbschlussKategorie::find($kategorie_id);
diff --git a/app/controllers/file.php b/app/controllers/file.php
index 65344ef..376a74e 100644
--- a/app/controllers/file.php
+++ b/app/controllers/file.php
@@ -66,7 +66,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$folder = $plugin->getFolder($folder_id);
} else {
@@ -184,10 +184,10 @@ class FileController extends AuthenticatedController
//Plugin file area.
$plugin = PluginManager::getInstance()->getPlugin($this->to_plugin);
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
if (!($plugin instanceof FilesystemPlugin)) {
- throw new Trails_Exception(400, _('Das Plugin ist kein Dateibereich-Plugin.'));
+ throw new Trails\Exception(400, _('Das Plugin ist kein Dateibereich-Plugin.'));
}
$file_ids = Request::getArray('file_refs');
foreach ($file_ids as $file_id) {
@@ -294,7 +294,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin($this->from_plugin);
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->file = $plugin->getPreparedFile($file_id);
} else {
@@ -364,7 +364,7 @@ class FileController extends AuthenticatedController
//The file system object is a folder.
//Calculate the files and the folder size:
- list($this->folder_size, $this->folder_file_amount) = $this->getFolderSize($this->folder);
+ [$this->folder_size, $this->folder_file_amount] = $this->getFolderSize($this->folder);
PageLayout::setTitle($this->folder->name);
$this->render_action('folder_details');
}
@@ -383,7 +383,7 @@ class FileController extends AuthenticatedController
$file_ref_id = $file_id;
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->file = $plugin->getPreparedFile($file_id);
@@ -666,7 +666,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->file = $plugin->getPreparedFile($file_id);
$this->from_plugin = Request::get("from_plugin");
@@ -760,7 +760,7 @@ class FileController extends AuthenticatedController
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->file_ref = $plugin->getPreparedFile($file_id);
@@ -814,7 +814,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$foldertype = $plugin->getFolder($folder_id);
@@ -980,7 +980,7 @@ class FileController extends AuthenticatedController
);
} else {
$this->top_folder = $this->filesystemplugin->getFolder($folder_id, true);
- if (is_a($this->top_folder, 'Flexi_Template')) {
+ if ($this->top_folder instanceof Flexi\Template) {
$this->top_folder->select = true;
$this->top_folder->to_folder = $this->to_folder;
$this->render_text($this->top_folder);
@@ -1103,7 +1103,7 @@ class FileController extends AuthenticatedController
return;
}
- $this->library_plugins = $plugin_manager->getPlugins('LibraryPlugin');
+ $this->library_plugins = $plugin_manager->getPlugins(LibraryPlugin::class);
//Build the query parameter array:
$search_parameters = [];
@@ -1128,7 +1128,7 @@ class FileController extends AuthenticatedController
$this->search_id = md5(json_encode($search_parameters));
- $cache = StudipCacheFactory::getCache();
+ $cache = \Studip\Cache\Factory::getCache();
$merged_results = LibrarySearchManager::search(
$search_parameters,
@@ -1182,12 +1182,12 @@ class FileController extends AuthenticatedController
);
}
} elseif (Request::get('search_id')) {
- $this->library_plugins = $plugin_manager->getPlugins('LibraryPlugin');
+ $this->library_plugins = $plugin_manager->getPlugins(LibraryPlugin::class);
$this->search_id = Request::get('search_id');
$this->page = Request::get('page');
- $cache = StudipCacheFactory::getCache();
+ $cache = \Studip\Cache\Factory::getCache();
$cache_data = $cache->read($this->search_id);
$results = $cache_data['results'];
$this->total_results = count($results);
@@ -1247,7 +1247,7 @@ class FileController extends AuthenticatedController
}
if ($item_id) {
- $cache = StudipCacheFactory::getCache();
+ $cache = \Studip\Cache\Factory::getCache();
$documents = $cache->read($search_id);
$document = $documents['results'][$item_id];
if (!($document instanceof LibraryDocument)) {
@@ -1255,7 +1255,7 @@ class FileController extends AuthenticatedController
}
$file = LibraryFile::createFromLibraryDocument($document, $folder_id);
} else {
- $cache = StudipCacheFactory::getCache();
+ $cache = \Studip\Cache\Factory::getCache();
$search = $cache->read($search_id);
if (!$search) {
throw new Exception('Search not found in cache!');
@@ -1325,7 +1325,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$filetype = $plugin->getPreparedFile($file_id);
$folder = $filetype->getFolderType();
@@ -1335,7 +1335,7 @@ class FileController extends AuthenticatedController
$filetype = $file_ref->getFileType();
}
if (!$filetype) {
- throw new Trails_Exception(404, _('Datei nicht gefunden.'));
+ throw new Trails\Exception(404, _('Datei nicht gefunden.'));
}
if (!$filetype->isWritable($GLOBALS['user']->id)) {
@@ -1462,7 +1462,7 @@ class FileController extends AuthenticatedController
$this->current_folder = $this->to_folder_type;
$this->marked_element_ids = [];
- $plugins = PluginManager::getInstance()->getPlugins('FileUploadHook');
+ $plugins = PluginManager::getInstance()->getPlugins(FileUploadHook::class);
$redirects = [];
foreach ($plugins as $plugin) {
@@ -1505,7 +1505,7 @@ class FileController extends AuthenticatedController
$folder_id = substr($folder_id, 0, strpos($folder_id, "?"));
}
$this->top_folder = $this->filesystemplugin->getFolder($folder_id, true);
- if (is_a($this->top_folder, 'Flexi_Template')) {
+ if ($this->top_folder instanceof Flexi\Template) {
$this->top_folder->select = true;
$this->top_folder->to_folder = $this->to_folder;
$this->render_text($this->top_folder->render());
@@ -1685,7 +1685,7 @@ class FileController extends AuthenticatedController
);
}
- $plugins = PluginManager::getInstance()->getPlugins('FileUploadHook');
+ $plugins = PluginManager::getInstance()->getPlugins(FileUploadHook::class);
$redirect = null;
foreach ($plugins as $upload_hook_plugin) {
$url = $upload_hook_plugin->getAdditionalUploadWizardPage($file_ref);
@@ -1792,7 +1792,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("to_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->top_folder = $plugin->getFolder($folder_id);
} else {
@@ -1820,7 +1820,7 @@ class FileController extends AuthenticatedController
$payload['html'][] = FilesystemVueDataManager::getFileVueData($this->file, $this->top_folder);
- $plugins = PluginManager::getInstance()->getPlugins('FileUploadHook');
+ $plugins = PluginManager::getInstance()->getPlugins(FileUploadHook::class);
$redirects = [];
foreach ($plugins as $plugin) {
@@ -1857,7 +1857,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$parent_folder = $plugin->getFolder($folder_id);
} else {
@@ -1963,7 +1963,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$folder = $plugin->getFolder($folder_id);
} else {
@@ -2036,7 +2036,7 @@ class FileController extends AuthenticatedController
PageLayout::postMessage($result);
}
}
- list($this->folder_size, $this->folder_file_amount) = $this->getFolderSize($folder);
+ [$this->folder_size, $this->folder_file_amount] = $this->getFolderSize($folder);
}
public function delete_folder_action($folder_id)
@@ -2050,7 +2050,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$folder = $plugin->getFolder($folder_id);
} else {
@@ -2085,7 +2085,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$parent_folder = $plugin->getFolder($folder_id);
} else {
diff --git a/app/controllers/files.php b/app/controllers/files.php
index 3c77f4e..df4657c 100644
--- a/app/controllers/files.php
+++ b/app/controllers/files.php
@@ -68,7 +68,7 @@ class FilesController extends AuthenticatedController
$this->url_for("files/index"),
Icon::create("files", "clickable")
);
- foreach (PluginManager::getInstance()->getPlugins('FilesystemPlugin') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(FilesystemPlugin::class) as $plugin) {
if ($plugin->isPersonalFileArea()) {
$subnav = $plugin->getFileSelectNavigation();
$sources->addLink(
@@ -110,7 +110,7 @@ class FilesController extends AuthenticatedController
}
$config_urls = [];
- foreach (PluginManager::getInstance()->getPlugins('FilesystemPlugin') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(FilesystemPlugin::class) as $plugin) {
$url = $plugin->filesystemConfigurationURL();
if ($url) {
$navigation = $plugin->getFileSelectNavigation();
@@ -647,7 +647,7 @@ class FilesController extends AuthenticatedController
PageLayout::setTitle(_('Dateibereich zur Konfiguration auswählen'));
$this->configure_urls = [];
- foreach (PluginManager::getInstance()->getPlugins('FilesystemPlugin') as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(FilesystemPlugin::class) as $plugin) {
$url = $plugin->filesystemConfigurationURL();
if ($url) {
$navigation = $plugin->getFileSelectNavigation();
@@ -711,7 +711,7 @@ class FilesController extends AuthenticatedController
$destination_plugin = PluginManager::getInstance()->getPlugin($to_plugin);
if (!$destination_plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$destination_folder = $destination_plugin->getFolder($destination_id);
} else {
@@ -731,7 +731,7 @@ class FilesController extends AuthenticatedController
if ($from_plugin) {
$source_plugin = PluginManager::getInstance()->getPlugin($from_plugin);
if (!$source_plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
if (Request::get("isfolder")) {
if ($source_folder = $source_plugin->getFolder($fileref)) {
diff --git a/app/controllers/institute/basicdata.php b/app/controllers/institute/basicdata.php
index fb1ce96..9c800fd 100644
--- a/app/controllers/institute/basicdata.php
+++ b/app/controllers/institute/basicdata.php
@@ -435,7 +435,7 @@ class Institute_BasicdataController extends AuthenticatedController
}
// delete all contents in forum-modules
- foreach (PluginEngine::getPlugins('ForumModule') as $plugin) {
+ foreach (PluginEngine::getPlugins(ForumModule::class) as $plugin) {
$plugin->deleteContents($i_id); // delete content irrespective of plugin-activation in the seminar
if ($plugin->isActivated($i_id)) { // only show a message, if the plugin is activated, to not confuse the user
$details[] = sprintf(_('Einträge in %s gelöscht.'), $plugin->getPluginName());
diff --git a/app/controllers/institute/overview.php b/app/controllers/institute/overview.php
index 66d55e1..3713dcc 100644
--- a/app/controllers/institute/overview.php
+++ b/app/controllers/institute/overview.php
@@ -138,9 +138,6 @@ class Institute_OverviewController extends AuthenticatedController
// Fetch votes
if (Config::get()->VOTE_ENABLE) {
- $response = $this->relay('evaluation/display/' . $this->institute_id . '/institute');
- $this->evaluations = $response->body;
-
$response = $this->relay('questionnaire/widget/' . $this->institute_id . '/institute');
$this->questionnaires = $response->body;
}
diff --git a/app/controllers/jsupdater.php b/app/controllers/jsupdater.php
index eb6032d..a5425f9 100644
--- a/app/controllers/jsupdater.php
+++ b/app/controllers/jsupdater.php
@@ -290,71 +290,77 @@ class JsupdaterController extends AuthenticatedController
]
);
$page = WikiPage::find($page_id);
- if ($page && $page->isEditable()) {
- if (
- $pageInfo['wiki_editor_status']['focussed'] == $page_id
- && !empty($pageInfo['wiki_editor_status']['page_content'])
- ) {
- $page->content = \Studip\Markup::markAsHtml(
- $pageInfo['wiki_editor_status']['page_content']
+ if ($page) {
+ if ($page->isEditable()) {
+ if (
+ $pageInfo['wiki_editor_status']['focussed'] == $page_id
+ && !empty($pageInfo['wiki_editor_status']['page_content'])
+ ) {
+ $page->content = \Studip\Markup::markAsHtml(
+ $pageInfo['wiki_editor_status']['page_content']
+ );
+ if ($page->isDirty()) {
+ $page['user_id'] = User::findCurrent()->id;
+ $page->store();
+ }
+ }
+ $onlineData = [
+ 'user_id' => $user->id,
+ 'page_id' => $page_id
+ ];
+ $online = WikiOnlineEditingUser::findOneBySQL(
+ "`user_id` = :user_id AND `page_id` = :page_id",
+ $onlineData
);
- $page->store();
- }
- $onlineData = [
- 'user_id' => $user->id,
- 'page_id' => $page_id
- ];
- $online = WikiOnlineEditingUser::findOneBySQL(
- "`user_id` = :user_id AND `page_id` = :page_id",
- $onlineData
- );
- if (!$online) {
- $online = WikiOnlineEditingUser::build($onlineData);
- }
- $editingUsers = WikiOnlineEditingUser::countBySQL(
- "`page_id` = ? AND `editing` = 1 AND `user_id` != ?",
- [$page->id, $user->id]
- );
- if ($editingUsers > 0) {
- $online->editing = 0;
- } elseif ($online->editing && $online->editing_request) {
- // this is the mode that this user requested the editing mode and was granted to get it:
- $online->editing_request = 0;
- } elseif ($online->editing_request) {
- $other_requests = WikiOnlineEditingUser::countBySql("`page_id` = ? AND `editing_request` = 1 AND `user_id` != ?", [
- $page->id,
- $user->id,
- ]);
- if ($other_requests === 0) {
- $online->editing_request = 0;
- $online->editing = 1;
+ if (!$online) {
+ $online = WikiOnlineEditingUser::build($onlineData);
}
- } else {
- if ($pageInfo['wiki_editor_status']['focussed'] == $page_id) {
- $online->editing = 1;
- } else {
- $other_users = WikiOnlineEditingUser::countBySql("`page_id` = ? AND `user_id` != ?", [
+ $editingUsers = WikiOnlineEditingUser::countBySQL(
+ "`page_id` = ? AND `editing` = 1 AND `user_id` != ?",
+ [$page->id, $user->id]
+ );
+ if ($editingUsers > 0) {
+ $online->editing = 0;
+ } else if ($online->editing && $online->editing_request) {
+ // this is the mode that this user requested the editing mode and was granted to get it:
+ $online->editing_request = 0;
+ } else if ($online->editing_request) {
+ $other_requests = WikiOnlineEditingUser::countBySql("`page_id` = ? AND `editing_request` = 1 AND `user_id` != ?", [
$page->id,
$user->id,
]);
- if ($other_users === 0) {
- // if I'm the only user I don't need to lose the edit mode
+ if ($other_requests === 0) {
+ $online->editing_request = 0;
+ $online->editing = 1;
+ }
+ } else {
+ if ($pageInfo['wiki_editor_status']['focussed'] == $page_id) {
$online->editing = 1;
} else {
- $online->editing = 0;
+ $other_users = WikiOnlineEditingUser::countBySql("`page_id` = ? AND `user_id` != ?", [
+ $page->id,
+ $user->id,
+ ]);
+ if ($other_users === 0) {
+ // if I'm the only user I don't need to lose the edit mode
+ $online->editing = 1;
+ } else {
+ $online->editing = 0;
+ }
}
}
+ $online->chdate = time();
+ $online->store();
+ $data['contents'][$page_id] = wikiReady($page->content, true, $page->range_id, $page_id);
+ $data['wysiwyg_contents'][$page_id] = $page->content;
+ $data['pages'][$page_id]['editing'] = $online->editing;
+ }
+ else {
+ $data['pages'][$page_id]['editing'] = 0;
}
- $online->chdate = time();
- $online->store();
- $data['contents'][$page_id] = wikiReady($page->content, true, $page->range_id, $page_id);
- $data['wysiwyg_contents'][$page_id] = $page->content;
- $data['pages'][$page_id]['editing'] = $online->editing;
- } else {
- $data['pages'][$page_id]['editing'] = 0;
+ $data['pages'][$page_id]['chdate'] = $page->chdate;
+ $data['users'][$page_id] = $page->getOnlineUsers();
}
- $data['pages'][$page_id]['chdate'] = $page->chdate;
- $data['users'][$page_id] = $page->getOnlineUsers();
}
}
return $data;
diff --git a/app/controllers/loncapa.php b/app/controllers/loncapa.php
index 3119178..dd7ea40 100644
--- a/app/controllers/loncapa.php
+++ b/app/controllers/loncapa.php
@@ -1,6 +1,4 @@
<?php
-require_once 'app/controllers/authenticated_controller.php';
-
class LoncapaController extends AuthenticatedController
{
public function enter_action()
@@ -15,8 +13,8 @@ class LoncapaController extends AuthenticatedController
if ($GLOBALS['perm']->have_studip_perm('user', $course_id)
&& isset($GLOBALS['ELEARNING_INTERFACE_MODULES'][$cms_type]))
{
- require_once 'lib/elearning/ELearningUtils.class.php';
- require_once 'lib/elearning/ObjectConnections.class.php';
+ require_once 'lib/elearning/ELearningUtils.php';
+ require_once 'lib/elearning/ObjectConnections.php';
$object_connections = new ObjectConnections($course_id);
$connected_modules = $object_connections->getConnections();
diff --git a/app/controllers/lvgruppen/lvgruppen.php b/app/controllers/lvgruppen/lvgruppen.php
index 5bac0fd..8562836 100644
--- a/app/controllers/lvgruppen/lvgruppen.php
+++ b/app/controllers/lvgruppen/lvgruppen.php
@@ -149,10 +149,12 @@ class Lvgruppen_LvgruppenController extends MVVController
$semester = Semester::find($this->semester_filter);
if ($semester && $semester->isCurrent()) {
$this->next_sem = Semester::findNext();
- $this->display_semesters[] = $this->next_sem;
- $this->courses = array_merge($this->courses,
- $this->lvgruppe->getAllAssignedCourses(false, $this->next_sem->id)
- );
+ if ($this->next_sem) {
+ $this->display_semesters[] = $this->next_sem;
+ $this->courses = array_merge($this->courses,
+ $this->lvgruppe->getAllAssignedCourses(false, $this->next_sem->id)
+ );
+ }
}
$this->current_sem = $semester;
$this->display_semesters[] = $semester;
@@ -451,7 +453,7 @@ class Lvgruppen_LvgruppenController extends MVVController
);
$widget->class = 'nested-select';
$widget->addElement(
- new SelectElement('select-none', _('Alle'), $selected_abschlussh === '')
+ new SelectElement('select-none', _('Alle'), $selected_abschluss === '')
);
$abschluesse = Abschluss::findBySQL(' 1 ORDER BY `name`');
foreach ($abschluesse as $abschluss) {
@@ -533,11 +535,12 @@ class Lvgruppen_LvgruppenController extends MVVController
private function set_trails_filter($start, $end)
{
// show only pathes with modules valid in the selected semester
- ModuleManagementModelTreeItem::setObjectFilter('Modulteil',
+ ModuleManagementModelTreeItem::setObjectFilter(
+ Modulteil::class,
function ($mt) use ($start, $end) {
- $modul_start = Semester::find($mt->modul->start)->beginn ?: 0;
- $modul_end = Semester::find($mt->modul->end)->ende ?: PHP_INT_MAX;
- return ($modul_start <= $end && $modul_end >= $start);
+ $modul_start = Semester::find($mt->modul->start)->beginn ?? 0;
+ $modul_end = Semester::find($mt->modul->end)->ende ?? PHP_INT_MAX;
+ return $modul_start <= $end && $modul_end >= $start;
}
);
}
diff --git a/app/controllers/materialien/files.php b/app/controllers/materialien/files.php
index 804668e..429a98c 100644
--- a/app/controllers/materialien/files.php
+++ b/app/controllers/materialien/files.php
@@ -362,29 +362,37 @@ class Materialien_FilesController extends MVVController
public function upload_attachment_action()
{
- if ($GLOBALS['user']->id === "nobody") {
+ $user = User::findCurrent();
+ if (!$user) {
throw new AccessDeniedException();
}
- $file = $_FILES['file'];
- $output = [
- 'name' => $file['name'],
- 'size' => $file['size']];
-
$mvvfile_id = Request::option('mvvfile_id');
- $output['mvvfile_id'] = $mvvfile_id;
- $range_id = Request::option('range_id', $mvvfile_id);
- $output['range_id'] = $range_id;
- $file_language = Request::option('file_language');
+ $document_id = Request::option('document_id');
- $top_folder = $this->getTopFolder($mvvfile_id);
-
- $user = User::findCurrent();
-
- $file = StandardFile::create($_FILES['file']);
- $error = $top_folder->validateUpload($file, $GLOBALS['user']->id);
- if ($error != null) {
- $file->delete();
+ $file = $_FILES['file'];
+ $output = [
+ 'name' => $file['name'],
+ 'size' => $file['size'],
+ 'mvvfile_id' => $mvvfile_id,
+ 'range_id' => Request::option('range_id', $mvvfile_id),
+ ];
+
+ $top_folder = $this->getTopFolder($output['mvvfile_id']);
+
+ if ($document_id) {
+ $file = File::find($document_id);
+ $file->mime_type = $_FILES['file']['type'] ?? get_mime_type($_FILES['file']['name']);
+ $file->size = $_FILES['file']['size'] ?? filesize($_FILES['file']['tmp_name']);
+ $file->connectWithDataFile($_FILES['file']['tmp_name']);
+ } else {
+ $file = StandardFile::create($_FILES['file']);
+ }
+ $error = $top_folder->validateUpload($file, $user->id);
+ if ($error !== null) {
+ if (!$document_id) {
+ $file->delete();
+ }
$this->response->set_status(400);
$this->render_json(compact('error'));
return;
@@ -399,18 +407,15 @@ class Materialien_FilesController extends MVVController
return;
}
- $mvv_file_fileref = new MvvFileFileref([$mvvfile_id, $file_language]);
- $mvv_file_fileref->fileref_id = $file->getId();
+ $mvv_file_fileref = new MvvFileFileref([
+ $output['mvvfile_id'],
+ Request::option('file_language'),
+ ]);
+ $mvv_file_fileref->fileref_id = $file->id;
$mvv_file_fileref->store();
- $output['document_id'] = $file->getId();
-
- $output['icon'] = Icon::create(
- FileManager::getIconNameForMimeType(
- $file->getMimeType()
- ),
- 'clickable'
- )->asImg(['class' => "text-bottom"]);
+ $output['document_id'] = $file->id;
+ $output['icon'] = $file->getIcon(Icon::ROLE_CLICKABLE)->asImg(['class' => 'text-bottom']);
$this->render_json($output);
}
@@ -510,7 +515,7 @@ class Materialien_FilesController extends MVVController
$mvv_file = MvvFile::find($mvvfile_id);
if (!$mvv_file) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->doc_year = $mvv_file->year;
diff --git a/app/controllers/media_proxy.php b/app/controllers/media_proxy.php
index 50dc3df..b98b49c 100644
--- a/app/controllers/media_proxy.php
+++ b/app/controllers/media_proxy.php
@@ -46,7 +46,7 @@ class MediaProxyController extends StudipController
ini_set('default_socket_timeout', 5);
$this->render_nothing();
- //stop output buffering started in Trails_Dispatcher::dispatch()
+ //stop output buffering started in Trails\Dispatcher::dispatch()
while (ob_get_level()) {
ob_end_clean();
}
diff --git a/app/controllers/module/module.php b/app/controllers/module/module.php
index 2f6ba4c..854b045 100644
--- a/app/controllers/module/module.php
+++ b/app/controllers/module/module.php
@@ -53,7 +53,7 @@ class Module_ModuleController extends MVVController
if (count($search_result) > 0) {
$module_ids = $search_result;
} else {
- if ($_SESSION['mvv_filter_module_fach_id']) {
+ if (!empty($_SESSION['mvv_filter_module_fach_id'])) {
$module_ids = $this->findModuleIdsByFach($_SESSION['mvv_filter_module_fach_id']);
}
if (!empty($_SESSION['mvv_filter_module_abschluss_id'])) {
@@ -395,17 +395,17 @@ class Module_ModuleController extends MVVController
* Deletes a descriptor from module
*
* @param type $deskriptor_id
- * @throws Trails_Exception
+ * @throws Trails\Exception
*/
public function delete_modul_deskriptor_action($deskriptor_id, $language)
{
$deskriptor = ModulDeskriptor::find($deskriptor_id);
if (is_null($deskriptor)) {
- throw new Trails_Exception(404, _('Unbekannter Deskriptor'));
+ throw new Trails\Exception(404, _('Unbekannter Deskriptor'));
}
$def_lang = $deskriptor->modul->getDefaultLanguage();
if ($language === $def_lang) {
- throw new Trails_Exception(403, _('Ein Deskriptor in der Original-Sprache kann nicht gelöscht werden.'));
+ throw new Trails\Exception(403, _('Ein Deskriptor in der Original-Sprache kann nicht gelöscht werden.'));
}
if (Request::submitted('delete')) {
CSRFProtection::verifyUnsafeRequest();
@@ -819,17 +819,17 @@ class Module_ModuleController extends MVVController
* Deletes a descriptor from Modulteil
*
* @param type $deskriptor_id
- * @throws Trails_Exception
+ * @throws Trails\Exception
*/
public function delete_modulteil_deskriptor_action($deskriptor_id, $language)
{
$deskriptor = ModulteilDeskriptor::find($deskriptor_id);
if (is_null($deskriptor)) {
- throw new Trails_Exception(404, _('Unbekannter Deskriptor'));
+ throw new Trails\Exception(404, _('Unbekannter Deskriptor'));
}
$def_lang = $deskriptor->modulteil->getDefaultLanguage();
if ($language === $def_lang) {
- throw new Trails_Exception(403, _('Ein Deskriptor in der Original-Sprache kann nicht gelöscht werden.'));
+ throw new Trails\Exception(403, _('Ein Deskriptor in der Original-Sprache kann nicht gelöscht werden.'));
}
if (Request::submitted('delete')) {
CSRFProtection::verifyUnsafeRequest();
diff --git a/app/controllers/module/mvv_controller.php b/app/controllers/module/mvv_controller.php
index e84b37c..b70ddef 100644
--- a/app/controllers/module/mvv_controller.php
+++ b/app/controllers/module/mvv_controller.php
@@ -77,7 +77,7 @@ abstract class MVVController extends AuthenticatedController
PageLayout::setTitle(_('Module'));
// Setup flash instance
- $this->flash = Trails_Flash::instance();
+ $this->flash = Trails\Flash::instance();
$this->me = 'mvv';
self::$items_per_page = Config::get()->getValue('ENTRIES_PER_PAGE');
@@ -218,7 +218,7 @@ abstract class MVVController extends AuthenticatedController
* This action is used to show a select box instead of an input field
* if the user has clicked on the magnifier icon of a quicksearch.
*
- * @throws Trails_Exception
+ * @throws Trails\Exception
*/
public function qs_result_action()
{
@@ -228,7 +228,7 @@ abstract class MVVController extends AuthenticatedController
Request::get('qs_term')
));
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
diff --git a/app/controllers/my_courses.php b/app/controllers/my_courses.php
index 410947b..8205c12 100644
--- a/app/controllers/my_courses.php
+++ b/app/controllers/my_courses.php
@@ -131,26 +131,16 @@ class MyCoursesController extends AuthenticatedController
throw new AccessDeniedException();
}
- $this->with_modules = Request::bool('modules');
-
- $this->sem_data = Semester::getAllAsArray();
-
- $this->group_field = 'sem_number';
-
- // Needed parameters for selecting courses
- $params = [
- 'group_field' => $this->group_field,
+ $template = $this->get_template_factory()->open('my_courses/courseexport');
+ $template->sem_courses = MyRealmModel::getPreparedCourses('', [
+ 'group_field' => 'sem_number',
'order_by' => null,
'order' => 'asc',
'studygroups_enabled' => Config::get()->MY_COURSES_ENABLE_STUDYGROUPS,
'deputies_enabled' => Config::get()->DEPUTIES_ENABLE,
- ];
-
- $this->sem_courses = MyRealmModel::getPreparedCourses('all', $params);
-
- $factory = $this->get_template_factory();
- $template = $factory->open('my_courses/courseexport');
- $template->set_attributes($this->get_assigned_variables());
+ ]);
+ $template->sem_data = Semester::getAllAsArray();
+ $template->with_modules = Request::bool('modules');
$template->image_style = 'height: 6px; width: 8px;';
$doc = new ExportPDF();
@@ -200,7 +190,7 @@ class MyCoursesController extends AuthenticatedController
LEFT JOIN `mvv_lvgruppe` AS ml ON (mls.`lvgruppe_id` = ml.`lvgruppe_id`)
LEFT JOIN `mvv_lvgruppe_modulteil` AS mlm on(mls.`lvgruppe_id` = mlm.`lvgruppe_id`)
LEFT JOIN `mvv_modulteil` AS mmt ON (mlm.`modulteil_id` = mmt.`modulteil_id`)
- LEFT JOIN `mvv_modul` AS mm ON (mmt.`modul_id` = mm.`modul_id`)";
+ LEFT JOIN `mvv_modul` AS mm ON (mmt.`modul_id` = mm.`modul_id` AND mm.`stat` = 'genehmigt')";
}
@@ -354,7 +344,10 @@ class MyCoursesController extends AuthenticatedController
$semesters = MyRealmModel::getSelectedSemesters($sem);
$min_sem_key = min($semesters);
$max_sem_key = max($semesters);
- $courses = MyRealmModel::getCourses($min_sem_key, $max_sem_key, compact('deputies_enabled'));
+ $courses = MyRealmModel::getCourses($min_sem_key, $max_sem_key, [
+ 'deputies_enabled' => $deputies_enabled,
+ 'exactly' => $semesters,
+ ]);
foreach ($courses as $index => $course) {
MyRealmModel::setObjectVisits($course, $GLOBALS['user']->id, $timestamp);
}
@@ -1178,6 +1171,7 @@ class MyCoursesController extends AuthenticatedController
'future' => _('Aktuelles und nächstes Semester'),
'last' => _('Aktuelles und letztes Semester'),
'lastandnext' => _('Letztes, aktuelles, nächstes Semester'),
+ 'lastbutone' => _('Aktuelles und vorletztes Semester'),
];
if (Config::get()->MY_COURSES_ENABLE_ALL_SEMESTERS) {
diff --git a/app/controllers/new_password.php b/app/controllers/new_password.php
index 525d73b..1e58659 100644
--- a/app/controllers/new_password.php
+++ b/app/controllers/new_password.php
@@ -41,36 +41,32 @@ class NewPasswordController extends StudipController
$users = User::findByEmail(Request::get('mail'));
- if (sizeof($users) == 1) {
- $user = $users[0];
- } else if (sizeof($users) > 1) {
- setTempLanguage($users[0]->id);
-
- // there are mutliple accounts with this mail addresses!
- $subject = sprintf(
- _("[Stud.IP - %s] Passwortänderung angefordert"),
- Config::get()->UNI_NAME_CLEAN
- );
-
- $mailbody = sprintf(
- _("Dies ist eine Informationsmail des Stud.IP-Systems\n"
- ."(Studienbegleitender Internetsupport von Präsenzlehre)\n- %s -\n\n"
- . "Für die Mail-Adresse %s wurde ein Link angefordert\n"
- . "um das Passwort zurückzusetzen.\n"
- . "Dieser Mail-Adresse sind jedoch mehrere Zugänge zugeordnet,\n"
- . "deshalb ist es nicht möglich, das Passwort hierüber zurückzusetzen.\n"
- . "Wenden sie sich bitte stattdessen an\n%s"
- ),
- Config::get()->UNI_NAME_CLEAN,
- $users[0]->email,
- $GLOBALS['UNI_CONTACT']
- );
-
- StudipMail::sendMessage($users[0]->email, $subject, $mailbody);
-
- restoreLanguage();
- }
-
+ $user = $users[0];
+ setTempLanguage($user->id);
+
+ // there are mutliple accounts with this mail addresses!
+ $subject = sprintf(
+ _("[Stud.IP - %s] Passwortänderung angefordert"),
+ Config::get()->UNI_NAME_CLEAN
+ );
+
+ $mailbody = sprintf(
+ _("Dies ist eine Informationsmail des Stud.IP-Systems\n"
+ ."(Studienbegleitender Internetsupport von Präsenzlehre)\n- %s -\n\n"
+ . "Für die Mail-Adresse %s wurde ein Link angefordert\n"
+ . "um das Passwort zurückzusetzen.\n"
+ . "Dieser Mail-Adresse sind jedoch mehrere Zugänge zugeordnet,\n"
+ . "deshalb ist es nicht möglich, das Passwort hierüber zurückzusetzen.\n"
+ . "Wenden sie sich bitte stattdessen an\n%s"
+ ),
+ Config::get()->UNI_NAME_CLEAN,
+ $users[0]->email,
+ $GLOBALS['UNI_CONTACT']
+ );
+
+ StudipMail::sendMessage($user->email, $subject, $mailbody);
+
+ restoreLanguage();
if ($user) {
// spam/abuse-protection
// if there are more than 5 tokens present, do NOT send another mail
diff --git a/app/controllers/notifications.php b/app/controllers/notifications.php
index b206df1..dc31aab 100644
--- a/app/controllers/notifications.php
+++ b/app/controllers/notifications.php
@@ -13,9 +13,6 @@
* @since 3.0
*/
-require_once 'app/controllers/authenticated_controller.php';
-
-
class NotificationsController extends AuthenticatedController
{
/**
diff --git a/app/controllers/oer/endpoints.php b/app/controllers/oer/endpoints.php
index 417f1e8..1ce9626 100644
--- a/app/controllers/oer/endpoints.php
+++ b/app/controllers/oer/endpoints.php
@@ -45,7 +45,7 @@ class Oer_EndpointsController extends StudipController
$this->render_json([
'name' => Config::get()->UNI_NAME_CLEAN,
'public_key' => $host['public_key'],
- 'url' => $GLOBALS['OER_PREFERRED_URI'] ?: $GLOBALS['ABSOLUTE_URI_STUDIP']."dispatch.php/oer/endpoints/",
+ 'url' => ($GLOBALS['OER_PREFERRED_URI'] ?? $GLOBALS['ABSOLUTE_URI_STUDIP']) . 'dispatch.php/oer/endpoints/',
'index_server' => $host['index_server']
]);
}
@@ -254,7 +254,7 @@ class Oer_EndpointsController extends StudipController
'description' => $material['description'],
'content_type' => $material['content_type'],
'front_image_content_type' => $material['front_image_content_type'],
- 'url' => ($GLOBALS['OER_PREFERRED_URI'] ?: $GLOBALS['ABSOLUTE_URI_STUDIP'])."dispatch.php/oer/market/download/".$item_id,
+ 'url' => ($GLOBALS['OER_PREFERRED_URI'] ?? $GLOBALS['ABSOLUTE_URI_STUDIP']) . 'dispatch.php/oer/market/download/' . $item_id,
'player_url' => $material['player_url'],
'tool' => $material['tool'],
'structure' => ($material['structure'] ? $material['structure']->getArrayCopy() : null),
@@ -374,7 +374,7 @@ class Oer_EndpointsController extends StudipController
header("Expires: Mon, 12 Dec 2001 08:00:00 GMT");
header("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT");
- if ($_SERVER['HTTPS'] == "on") {
+ if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
header("Pragma: public");
header("Cache-Control: private");
} else {
@@ -410,7 +410,7 @@ class Oer_EndpointsController extends StudipController
$this->response->add_header('Content-Length', filesize($this->material->getFrontImageFilePath()));
$this->render_text(file_get_contents($this->material->getFrontImageFilePath()));
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
diff --git a/app/controllers/plugin_controller.php b/app/controllers/plugin_controller.php
deleted file mode 100644
index d57a90d..0000000
--- a/app/controllers/plugin_controller.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-/**
- * Copyright (c) 2014 Rasmus Fuhse <fuhse@data-quest.de>
- *
- * 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.
- */
-
-class PluginController extends StudipController
-{
- public function __construct($dispatcher)
- {
- parent::__construct($dispatcher);
-
- if (!isset($dispatcher->current_plugin)) {
- throw new Exception('Plugin missing for plugin controller!');
- }
- $this->plugin = $dispatcher->current_plugin;
-
- if ($this->plugin && $this->plugin->hasTranslation()) {
- // Localization
- $this->_ = function ($string) {
- return call_user_func_array(
- [$this->plugin, '_'],
- func_get_args()
- );
- };
-
- $this->_n = function ($string0, $tring1, $n) {
- return call_user_func_array(
- [$this->plugin, '_n'],
- func_get_args()
- );
- };
- }
- }
-
- /**
- * Creates the body element id for this controller a given action.
- *
- * @param string $unconsumed_path Unconsumed path to extract action from
- * @return string
- */
- protected function getBodyElementIdForControllerAndAction($unconsumed_path)
- {
- $body_id = implode('-', [
- 'plugin',
- strtosnakecase(get_class($this->plugin)),
- parent::getBodyElementIdForControllerAndAction($unconsumed_path),
- ]);
-
- return $body_id;
- }
-
- /**
- * Intercepts all non-resolvable method calls in order to correctly handle
- * calls to _ and _n.
- *
- * @param string $method
- * @param array $arguments
- * @return mixed
- */
- public function __call($method, $arguments)
- {
- if (isset($this->_template_variables[$method]) && is_callable($this->_template_variables[$method])) {
- return call_user_func_array($this->_template_variables[$method], $arguments);
- }
- return parent::__call($method, $arguments);
- }
-}
diff --git a/app/controllers/privacy.php b/app/controllers/privacy.php
index ba8e6f1..d50b1f1 100644
--- a/app/controllers/privacy.php
+++ b/app/controllers/privacy.php
@@ -305,7 +305,7 @@ class PrivacyController extends AuthenticatedController
$storage->addFileRef($fileref);
}
- foreach (PluginEngine::getPlugins('PrivacyPlugin') as $plugin) {
+ foreach (PluginEngine::getPlugins(PrivacyPlugin::class) as $plugin) {
$plugin->exportUserData($storage);
}
diff --git a/app/controllers/profile.php b/app/controllers/profile.php
index a4e7c56a..1412c9c 100644
--- a/app/controllers/profile.php
+++ b/app/controllers/profile.php
@@ -37,22 +37,17 @@ class ProfileController extends AuthenticatedController
'username',
$this->user ? $this->user->username : null
));
- // get additional informations to selected user
- $this->profile = new ProfileModel(
- $this->current_user ? $this->current_user->id : null,
- $this->user ? $this->user->id : null
- );
// set the page title depending on user selection
if (
- $this->user
+ isset($this->user, $this->current_user)
&& $this->current_user->id === $this->user->id
&& !$this->current_user->locked
) {
PageLayout::setTitle(_('Mein Profil'));
UserConfig::get($this->user->id)->store('PROFILE_LAST_VISIT', time());
} elseif (
- $this->current_user->id
+ !empty($this->current_user->id)
&& (
$this->perm->have_perm('root')
|| (
@@ -106,11 +101,11 @@ class ProfileController extends AuthenticatedController
// Additional user information
$this->public_email = get_visible_email($this->current_user->user_id);
- $this->motto = $this->profile->getVisibilityValue('motto');
- $this->private_nr = $this->profile->getVisibilityValue('privatnr', 'private_phone');
- $this->private_cell = $this->profile->getVisibilityValue('privatcell', 'private_cell');
- $this->privadr = $this->profile->getVisibilityValue('privadr', 'privadr');
- $this->homepage = $this->profile->getVisibilityValue('Home', 'homepage');
+ $this->motto = $this->getVisibilityValue('motto');
+ $this->private_nr = $this->getVisibilityValue('privatnr', 'private_phone');
+ $this->private_cell = $this->getVisibilityValue('privatcell', 'private_cell');
+ $this->privadr = $this->getVisibilityValue('privadr', 'privadr');
+ $this->homepage = $this->getVisibilityValue('Home', 'homepage');
// skype informations
$this->skype_name = '';
@@ -119,8 +114,8 @@ class ProfileController extends AuthenticatedController
}
// get generic datafield entries
- $this->shortDatafields = $this->profile->getShortDatafields();
- $this->longDatafields = $this->profile->getLongDatafields();
+ $this->shortDatafields = $this->getShortDatafields();
+ $this->longDatafields = $this->getLongDatafields();
// get working station of an user (institutes)
$this->institutes = $this->getInstitutInformation();
@@ -144,24 +139,20 @@ class ProfileController extends AuthenticatedController
}
// calendar
- $this->dates = '';
- if (Config::get()->CALENDAR_ENABLE) {
- if (!in_array($this->current_user->perms, ['admin', 'root'])) {
- if (Visibility::verify('termine', $this->current_user->user_id)) {
- $start = time();
- $end = strtotime('+1 week 23:59:59');
-
- $response = $this->relay('calendar/contentbox/display/' . $this->current_user->user_id . '/' . ($end - $start));
- $this->dates = $response->body;
- }
- }
+ if (
+ Config::get()->CALENDAR_ENABLE
+ && !in_array($this->current_user->perms, ['admin', 'root'])
+ && Visibility::verify('termine', $this->current_user->user_id)
+ ) {
+ $start = time();
+ $end = strtotime('+1 week 23:59:59');
+
+ $response = $this->relay('calendar/contentbox/display/' . $this->current_user->user_id . '/' . ($end - $start));
+ $this->dates = $response->body;
}
// include and show votes and tests
if (Config::get()->VOTE_ENABLE && Visibility::verify('votes', $this->current_user->user_id)) {
- $response = $this->relay('evaluation/display/' . $this->current_user->user_id);
- $this->evaluations = $response->body;
-
$response = $this->relay('questionnaire/widget/' . $this->current_user->user_id . "/user");
$this->questionnaires = $response->body;
}
@@ -209,11 +200,11 @@ class ProfileController extends AuthenticatedController
// Anzeige der Seminare, falls User = dozent
if ($this->current_user['perms'] == 'dozent') {
- $this->seminare = array_filter($this->profile->getDozentSeminars());
+ $this->seminare = array_filter($this->getTeacherSeminars());
}
// Hompageplugins
- $homepageplugins = PluginEngine::getPlugins('HomepagePlugin');
+ $homepageplugins = PluginEngine::getPlugins(HomepagePlugin::class);
$render = '';
$layout = $GLOBALS['template_factory']->open('shared/content_box');
@@ -223,7 +214,7 @@ class ProfileController extends AuthenticatedController
$template = $homepageplugin->getHomepageTemplate($this->current_user->user_id);
// create output of the plugins
if (!empty($template)) {
- $render .= $template->render(null, $layout);
+ $render .= $template->render(layout: $layout);
}
$layout->clear_attributes();
}
@@ -237,7 +228,7 @@ class ProfileController extends AuthenticatedController
foreach ($category as $cat) {
$head = $cat->name;
$body = $cat->content;
- $vis_text = "";
+ $vis_text = '';
if ($this->user->user_id == $this->current_user->user_id) {
$vis_text .= ' (' . Visibility::getStateDescription('kat_' . $cat->kategorie_id) . ')';
@@ -524,4 +515,155 @@ class ProfileController extends AuthenticatedController
PageLayout::setTitle(sprintf(_('Profil von %s'), $external_user['name']));
$this->user = $external_user;
}
+
+ /**
+ * Collect user datafield informations
+ *
+ * @return array
+ */
+ private function getDatafields(): array
+ {
+ $short_datafields = [];
+ $long_datafields = [];
+ foreach (DataFieldEntry::getDataFieldEntries($this->current_user->user_id, 'user') as $entry) {
+ if ($entry->isVisible() && $entry->getDisplayValue()
+ && Visibility::verify($entry->getID(), $this->current_user->user_id))
+ {
+ if ($entry instanceof DataFieldTextareaEntry) {
+ $long_datafields[] = $entry;
+ } else {
+ $short_datafields[] = $entry;
+ }
+ }
+ }
+
+ return [
+ 'long' => $long_datafields,
+ 'short' => $short_datafields,
+ ];
+ }
+
+ /**
+ * Filter long datafiels from the datafields
+ *
+ * @return array
+ */
+ private function getLongDatafields(): array
+ {
+ $datafields = $this->getDatafields();
+ $array = [];
+
+ if (!empty($datafields)) {
+ foreach ($datafields['long'] as $entry) {
+ $array[(string)$entry->getName()] = [
+ 'content' => $entry->getDisplayValue(),
+ 'visible' => '(' . $entry->getPermsDescription() . ')',
+ ];
+ }
+ }
+
+ return $array;
+ }
+
+ /**
+ * Filter short datafiels from the datafields
+ *
+ * @return array
+ */
+ private function getShortDatafields(): array
+ {
+ $shortDatafields = $this->getDatafields();
+ $array = [];
+
+ if (!empty($shortDatafields)) {
+ foreach ($shortDatafields['short'] as $entry) {
+ $array[(string)$entry->getName()] = [
+ 'content' => $entry->getDisplayValue(),
+ 'visible' => '(' . $entry->getPermsDescription() . ')',
+ ];
+ }
+ }
+ return $array;
+ }
+
+ /**
+ * Creates an array with all seminars
+ *
+ * @return array
+ */
+ private function getTeacherSeminars(): array
+ {
+ $courses = [];
+ $semester = [];
+ $next_semester = Semester::findNext();
+ $current_semester = Semester::findCurrent();
+ $previous_semester = Semester::findPrevious();
+ if ($next_semester) {
+ $semester[$next_semester->id] = $next_semester;
+ }
+ if ($current_semester) {
+ $semester[$current_semester->id] = $current_semester;
+ }
+ if ($previous_semester) {
+ $semester[$previous_semester->id] = $previous_semester;
+ }
+ $field = 'name';
+ if (Config::get()->IMPORTANT_SEMNUMBER) {
+ $field = "veranstaltungsnummer,{$field}";
+ }
+ $allcourses = new SimpleCollection(
+ Course::findBySQL(
+ "INNER JOIN seminar_user USING(Seminar_id) WHERE user_id=? AND seminar_user.status='dozent' AND seminare.visible=1",
+ [
+ $this->current_user->id
+ ]
+ )
+ );
+ foreach (array_filter($semester) as $one) {
+ $courses[(string) $one->name] = $allcourses->filter(function ($c) use ($one) {
+ if (Config::get()->HIDE_STUDYGROUPS_FROM_PROFILE && $c->isStudygroup()) {
+ return false;
+ }
+ if (!$c->isOpenEnded()) {
+ return $c->isInSemester($one);
+ } elseif ($one->isCurrent()) {
+ return $c;
+ }
+ return false;
+ })->orderBy($field);
+
+ if (!$courses[(string) $one->name]->count()) {
+ unset($courses[(string) $one->name]);
+ }
+ }
+ return $courses;
+ }
+
+ /**
+ * Get the homepagevisibilities
+ *
+ * @return array
+ */
+ private function getHomepageVisibilities(): array
+ {
+ $visibilities = get_local_visibility_by_id(
+ $this->current_user ? $this->current_user->id : null,
+ 'homepage'
+ );
+ if (is_array(json_decode($visibilities, true))) {
+ return json_decode($visibilities, true);
+ }
+ return [];
+ }
+
+ /**
+ * Returns the visibility value
+ */
+ private function getVisibilityValue(string $param, string $visibility = ''): mixed
+ {
+ if (Visibility::verify($visibility ?: $param, $this->current_user->user_id)) {
+ return $this->current_user->$param;
+ }
+ return false;
+ }
}
diff --git a/app/controllers/profilemodules.php b/app/controllers/profilemodules.php
index 201c4ff..c24d4f4 100644
--- a/app/controllers/profilemodules.php
+++ b/app/controllers/profilemodules.php
@@ -106,7 +106,7 @@ class ProfileModulesController extends AuthenticatedController
$plugins = [];
// Get homepage plugins from database.
- foreach (PluginEngine::getPlugins('HomepagePlugin') as $plugin) {
+ foreach (PluginEngine::getPlugins(HomepagePlugin::class) as $plugin) {
if ($plugin->isActivatableForContext($this->user)) {
$plugins[$plugin->getPluginId()] = $plugin;
}
diff --git a/app/controllers/questionnaire.php b/app/controllers/questionnaire.php
index 66a4e0b..94e4d04 100644
--- a/app/controllers/questionnaire.php
+++ b/app/controllers/questionnaire.php
@@ -1,7 +1,5 @@
<?php
-require_once 'lib/classes/QuestionType.interface.php';
-
class QuestionnaireController extends AuthenticatedController
{
protected $allow_nobody = true; //nobody is allowed
@@ -48,11 +46,24 @@ class QuestionnaireController extends AuthenticatedController
public function courseoverview_action()
{
$this->range_id = Context::getId();
+
+ if (!$this->range_id) {
+ throw new CheckObjectException(_('Sie haben kein Objekt gewählt.'));
+ }
$this->range_type = Context::getType();
if (!$GLOBALS['perm']->have_studip_perm("tutor", $this->range_id)) {
throw new AccessDeniedException("Only for logged in users.");
}
+
Navigation::activateItem("/course/admin/questionnaires");
+ if ($GLOBALS['perm']->have_studip_perm('admin', $this->range_id)) {
+ // Ensure the select widget is added last
+ NotificationCenter::on('SidebarWillRender', function () {
+ $widget = new CourseManagementSelectWidget();
+ Sidebar::get()->addWidget($widget);
+ });
+ }
+
$this->statusgruppen = Statusgruppen::findByRange_id($this->range_id);
$this->questionnaires = Questionnaire::findBySQL(
"INNER JOIN questionnaire_assignments USING (questionnaire_id) WHERE (questionnaire_assignments.range_id = ? AND questionnaire_assignments.range_type = ?) OR (questionnaire_assignments.range_id IN (?) AND questionnaire_assignments.range_type = 'statusgruppe') ORDER BY questionnaires.chdate DESC",
@@ -148,7 +159,7 @@ class QuestionnaireController extends AuthenticatedController
: null;
$this->questionnaire['user_id'] = User::findCurrent()->id;
- $questions_data = Request::getArray('questions_data');
+ $questions_data = json_decode(Request::get('questions_data'), true);
$questions = [];
foreach ($questions_data as $index => $question_data) {
$class = $question_data['questiontype'];
@@ -480,7 +491,7 @@ class QuestionnaireController extends AuthenticatedController
$course_assignment['user_id'] = $GLOBALS['user']->id;
$course_assignment->store();
}
- foreach (PluginManager::getInstance()->getPlugins("QuestionnaireAssignmentPlugin") as $plugin) {
+ foreach (PluginManager::getInstance()->getPlugins(QuestionnaireAssignmentPlugin::class) as $plugin) {
$plugin->storeQuestionnaireAssignments($this->questionnaire);
}
@@ -584,8 +595,8 @@ class QuestionnaireController extends AuthenticatedController
}
$this->statusgruppen_ids = [];
if (in_array($this->range_type, ["course", "institute"])) {
- if ($GLOBALS['perm']->have_studip_perm("tutor", $this->range_id)) {
- $statusgruppen = Statusgruppen::findByRange_id(Context::get()->id);
+ if ($this->range_id && $GLOBALS['perm']->have_studip_perm("tutor", $this->range_id)) {
+ $statusgruppen = Statusgruppen::findByRange_id($this->range_id);
} else {
$statusgruppen = Statusgruppen::findBySQL("INNER JOIN statusgruppe_user USING (statusgruppe_id) WHERE statusgruppen.range_id = ? AND statusgruppe_user.user_id = ? ", [
Context::get()->id,
@@ -634,6 +645,7 @@ class QuestionnaireController extends AuthenticatedController
object_set_visit($questionnaire['questionnaire_id'], 'vote');
}
if (in_array($this->range_type, ["course", "institute"])
+ && $this->range_id
&& !$GLOBALS['perm']->have_studip_perm("tutor", $this->range_id)
&& !($stopped_visible || count($this->questionnaire_data))) {
$this->render_nothing();
diff --git a/app/controllers/quicksearch.php b/app/controllers/quicksearch.php
index 194f317..c086498 100644
--- a/app/controllers/quicksearch.php
+++ b/app/controllers/quicksearch.php
@@ -14,7 +14,7 @@
/**
* Controller for the ajax-response of the QuickSearch class found in
- * lib/classes/QuickSearch.class.php
+ * lib/classes/QuickSearch.php
*/
class QuicksearchController extends AuthenticatedController
{
@@ -94,7 +94,7 @@ class QuicksearchController extends AuthenticatedController
if (!empty($result[3])) {
$formatted['item_description'] = sprintf('%s (%s)', $result[2], $result[3]);
} else {
- $formatted['item_description'] = $result[2];
+ $formatted['item_description'] = $result[2] ?? '';
}
} else if ($this->search instanceof SearchType) {
$formatted['item_name'] = $this->search->getAvatarImageTag($result[0], Avatar::SMALL, ['title' => '']) . $formatted['item_name'];
diff --git a/app/controllers/quickselection.php b/app/controllers/quickselection.php
index 1899e53..a53eb08 100644
--- a/app/controllers/quickselection.php
+++ b/app/controllers/quickselection.php
@@ -27,7 +27,7 @@ class QuickselectionController extends AuthenticatedController
UserConfig::get($GLOBALS['user']->id)->store('QUICK_SELECTION', $names);
- $template = PluginEngine::getPlugin('QuickSelection')->getPortalTemplate();
+ $template = PluginEngine::getPlugin(QuickSelection::class)->getPortalTemplate();
$this->response->add_header('X-Dialog-Close', 1);
$this->response->add_header('X-Dialog-Execute', 'STUDIP.QuickSelection.update');
diff --git a/app/controllers/resources/ajax.php b/app/controllers/resources/ajax.php
index 6ff3942..cffd878 100644
--- a/app/controllers/resources/ajax.php
+++ b/app/controllers/resources/ajax.php
@@ -16,22 +16,22 @@ class Resources_AjaxController extends AuthenticatedController
{
public function toggle_marked_action($request_id)
{
- $request = \ResourceRequest::find($request_id);
+ $request = ResourceRequest::find($request_id);
if (!$request) {
throw new Exception('Resource request object not found!');
}
- $current_user = \User::findCurrent();
+ $current_user = User::findCurrent();
if ($request->isReadOnlyForUser($current_user)) {
- throw new \AccessDeniedException();
+ throw new AccessDeniedException();
}
//Switch to the next marking state or return to the unmarked state
//if the next marking state would be after the last defined
//marking state.
- $request->marked = ($request->marked + 1) % \ResourceRequest::MARKING_STATES;
+ $request->marked = ($request->marked + 1) % ResourceRequest::MARKING_STATES;
$request->store();
$this->render_json($request->toArray());
@@ -39,46 +39,46 @@ class Resources_AjaxController extends AuthenticatedController
public function get_resource_booking_intervals_action($booking_id)
{
- $booking = \ResourceBooking::find($booking_id);
+ $booking = ResourceBooking::find($booking_id);
if (!$booking) {
throw new Exception('Resource booking object not found!');
}
$resource = $booking->resource->getDerivedClassInstance();
- if (!$resource->bookingPlanVisibleForUser(\User::findCurrent())) {
- throw new \AccessDeniedException();
+ if (!$resource->bookingPlanVisibleForUser(User::findCurrent())) {
+ throw new AccessDeniedException();
}
//Get begin and end:
- $begin_str = \Request::get('begin');
- $end_str = \Request::get('end');
+ $begin_str = Request::get('begin');
+ $end_str = Request::get('end');
$begin = null;
$end = null;
if ($begin_str && $end_str) {
//Try the ISO format first: YYYY-MM-DDTHH:MM:SS±ZZ:ZZ
- $begin = \DateTime::createFromFormat(\DateTime::RFC3339, $begin_str);
- $end = \DateTime::createFromFormat(\DateTime::RFC3339, $end_str);
- if (!($begin instanceof \DateTime) || !($end instanceof \DateTime)) {
- $tz = new \DateTime();
+ $begin = DateTime::createFromFormat(DateTime::RFC3339, $begin_str);
+ $end = DateTime::createFromFormat(DateTime::RFC3339, $end_str);
+ if (!($begin instanceof DateTime) || !($end instanceof DateTime)) {
+ $tz = new DateTime();
$tz = $tz->getTimezone();
//Try the ISO format without timezone:
- $begin = \DateTime::createFromFormat('Y-m-d\TH:i:s', $begin_str, $tz);
- $end = \DateTime::createFromFormat('Y-m-d\TH:i:s', $end_str, $tz);
+ $begin = DateTime::createFromFormat('Y-m-d\TH:i:s', $begin_str, $tz);
+ $end = DateTime::createFromFormat('Y-m-d\TH:i:s', $end_str, $tz);
}
}
$sql = "booking_id = :booking_id ";
$sql_data = ['booking_id' => $booking->id];
- if ($begin instanceof \DateTime && $end instanceof \DateTime) {
+ if ($begin instanceof DateTime && $end instanceof DateTime) {
$sql .= "AND begin >= :begin AND end <= :end ";
$sql_data['begin'] = $begin->getTimestamp();
$sql_data['end'] = $end->getTimestamp();
}
- if (\Request::submitted('exclude_cancelled_intervals')) {
+ if (Request::submitted('exclude_cancelled_intervals')) {
$sql .= "AND takes_place = '1' ";
}
$sql .= "ORDER BY begin ASC, end ASC";
- $intervals = \ResourceBookingInterval::findBySql($sql, $sql_data);
+ $intervals = ResourceBookingInterval::findBySql($sql, $sql_data);
$result = [];
foreach ($intervals as $interval) {
@@ -90,7 +90,7 @@ class Resources_AjaxController extends AuthenticatedController
public function toggle_takes_place_field_action($interval_id)
{
- $interval = \ResourceBookingInterval::find($interval_id);
+ $interval = ResourceBookingInterval::find($interval_id);
if (!$interval) {
throw new Exception('ResourceBookingInterval object not found!');
}
@@ -103,13 +103,13 @@ class Resources_AjaxController extends AuthenticatedController
$resource = $resource->getDerivedClassInstance();
- if (!$resource->userHasPermission(\User::findCurrent(), 'autor', [$interval->begin, $interval->end])) {
+ if (!$resource->userHasPermission(User::findCurrent(), 'autor', [$interval->begin, $interval->end])) {
throw new Exception('You do not have sufficient permissions to modify the interval!');
}
if (
!$interval->takes_place
- && $resource->isAssigned(new \DateTime('@' . $interval->begin), new \DateTime('@' . $interval->end))
+ && $resource->isAssigned(new DateTime('@' . $interval->begin), new DateTime('@' . $interval->end))
) {
throw new Exception('Already booked');
}
@@ -121,13 +121,14 @@ class Resources_AjaxController extends AuthenticatedController
'takes_place' => $interval->takes_place
]);
} else {
- throw new Exception('Error while storing the interval!');
+ $this->set_status(500);
+ $this->render_text('Error while storing the interval!');
}
}
public function get_semester_booking_plan_action($resource_id)
{
- $resource = \Resource::find($resource_id);
+ $resource = Resource::find($resource_id);
if (!$resource) {
throw new Exception('Resource object not found!');
}
@@ -143,8 +144,8 @@ class Resources_AjaxController extends AuthenticatedController
$display_requests = Request::get('display_requests');
$display_all_requests = Request::get('display_all_requests');
- $begin = new \DateTime();
- $end = new \DateTime();
+ $begin = new DateTime();
+ $end = new DateTime();
$semester_id = Request::get('semester_id');
@@ -190,11 +191,11 @@ class Resources_AjaxController extends AuthenticatedController
'resource_id' => $resource->id
];
if (!$display_all_requests) {
- $requests_sql .= "AND user_id = :user_id ";
+ $requests_sql .= " AND user_id = :user_id ";
$requests_sql_params['user_id'] = $current_user->id;
}
- $requests = \ResourceRequest::findBySql(
+ $requests = ResourceRequest::findBySql(
$requests_sql,
$requests_sql_params
);
@@ -207,7 +208,7 @@ class Resources_AjaxController extends AuthenticatedController
$booking->resource = $resource;
$irrelevant_booking = $booking->getRepetitionType() !== 'weekly'
&& (
- !\Request::get('display_single_bookings')
+ !Request::get('display_single_bookings')
|| $booking->end < strtotime('today')
);
if ($booking->getAssignedUserType() === 'course' && in_array($booking->assigned_course_date->metadate_id, $meta_dates)) {
@@ -261,7 +262,7 @@ class Resources_AjaxController extends AuthenticatedController
$relevant_request = false;
foreach ($requests as $request) {
- if ($request->cycle instanceof \SeminarCycleDate) {
+ if ($request->cycle instanceof SeminarCycleDate) {
$cycle_dates = $request->cycle->getAllDates();
foreach ($cycle_dates as $cycle_date) {
$relevant_request = $semester->beginn <= $cycle_date->date
@@ -488,7 +489,7 @@ class Resources_AjaxController extends AuthenticatedController
$clipboard = Clipboard::find($clipboard_id);
if (!empty($_SESSION['selected_clipboard_id'])) {
- $clipboard = \Clipboard::find($_SESSION['selected_clipboard_id']);
+ $clipboard = Clipboard::find($_SESSION['selected_clipboard_id']);
}
if (!$clipboard) {
throw new Exception('Clipboard object not found!');
@@ -497,7 +498,7 @@ class Resources_AjaxController extends AuthenticatedController
//Permission check:
if ($clipboard->user_id !== $current_user->id) {
- throw new \AccessDeniedException();
+ throw new AccessDeniedException();
}
$display_requests = Request::bool('display_requests');
@@ -656,4 +657,186 @@ class Resources_AjaxController extends AuthenticatedController
$this->render_json($data);
}
+
+ public function move_booking_action($booking_id): void
+ {
+ $booking = ResourceBooking::find($booking_id);
+ if (!$booking) {
+ $this->notFound('Resource booking object not found!');
+ return;
+ }
+
+ $current_user = User::findCurrent();
+
+ if ($booking->isReadOnlyForUser($current_user)) {
+ throw new AccessDeniedException();
+ }
+
+ $resource_id = Request::get('resource_id');
+ $interval_id = Request::get('interval_id');
+
+ $begin = $this->convertDatetime(Request::get('begin'));
+ $end = $this->convertDatetime(Request::get('end'));
+
+ //Check if a specific interval has been moved:
+ if ($interval_id) {
+ $interval = ResourceBookingInterval::findOneBySql(
+ 'interval_id = ? AND booking_id = ?',
+ [$interval_id, $booking->id]
+ );
+ if (!$interval) {
+ $this->notFound('Resource booking interval not found!');
+ return;
+ }
+ $interval_begin = new DateTime();
+ $interval_begin->setTimestamp($interval->begin);
+ $interval_end = new DateTime();
+ $interval_end->setTimestamp($interval->end);
+
+ //Calculate the difference from the interval time range
+ //to the time range from the request. That difference
+ //is then applied to the booking.
+ $begin_diff = $interval_begin->diff($begin);
+ $end_diff = $interval_end->diff($end);
+
+ $new_booking_begin = new DateTime();
+ $new_booking_begin->setTimestamp($booking->begin);
+ $new_booking_end = new DateTime();
+ $new_booking_end->setTimestamp($booking->end);
+
+ $new_booking_begin = $new_booking_begin->add($begin_diff);
+ $new_booking_end = $new_booking_end->add($end_diff);
+ //We must substract the preparation time to the begin timestamp
+ //to get the real begin:
+ $real_begin = clone $new_booking_begin;
+ if ($booking->preparation_time > 0) {
+ $real_begin->sub(new DateInterval('PT' . ($booking->preparation_time / 60 ) . 'M'));
+ }
+ $booking->begin = $real_begin->getTimestamp();
+ $booking->end = $new_booking_end->getTimestamp();
+ } else {
+ //We must substract the preparation time to the begin timestamp
+ //to get the real begin:
+ $real_begin = clone $begin;
+ if ($booking->preparation_time > 0) {
+ $real_begin->sub(new DateInterval('PT' . ($booking->preparation_time / 60 ) . 'M'));
+ }
+ $booking->begin = $real_begin->getTimestamp();
+ $booking->end = $end->getTimestamp();
+ }
+ if ($resource_id) {
+ //The resource-ID has changed:
+ //The booking was moved from one resource to another.
+ $booking->resource_id = $resource_id;
+ }
+
+ //Update the booking_user_id field:
+ $booking->booking_user_id = User::findCurrent()->id;
+
+ try {
+ $booking->store();
+
+ if (Request::bool('quiet')) {
+ $this->render_nothing();
+ } else {
+ $this->render_json($booking->toRawArray());
+ }
+ } catch (Exception $e) {
+ $this->set_status(500);
+ $this->render_text($e->getMessage());
+ }
+ }
+
+ public function move_request_action($request_id): void
+ {
+ $request = ResourceRequest::find($request_id);
+ if (!$request) {
+ $this->notFound('Resource request object not found!');
+ return;
+ }
+
+ $current_user = User::findCurrent();
+
+ if ($request->isReadOnlyForUser($current_user)) {
+ throw new AccessDeniedException();
+ }
+
+ $request->begin = $this->convertDatetime(Request::get('begin'));
+ $request->end = $this->convertDatetime(Request::get('end'));
+
+ try {
+ $request->store();
+ $this->renderObject($request);
+ } catch (\Exception $e) {
+ $this->set_status(500);
+ $this->render_text($e->getMessage());
+ }
+ }
+
+ public function semester_week_action($timestamp)
+ {
+ $semester = \Semester::findByTimestamp($timestamp);
+ if (!$semester) {
+ $this->notFound('No semester found for given timestamp');
+ throw new RecordNotFoundException();
+ }
+
+ $timestamp = strtotime('today', $timestamp);
+ $week_begin_timestamp = strtotime('monday this week', $semester->vorles_beginn);
+ $end_date = $semester->vorles_ende;
+
+ $i = 0;
+ $result = [
+ 'semester_name' => (string)$semester->name,
+ 'week_number' => sprintf(_('KW %u'), date('W', $timestamp)),
+ 'current_day' => strftime('%x', $timestamp)
+ ];
+ while ($week_begin_timestamp < $end_date) {
+ $next_week_timestamp = strtotime('+1 week', $week_begin_timestamp);
+ if ($week_begin_timestamp <= $timestamp && $timestamp < $next_week_timestamp) {
+ $result['sem_week'] = sprintf(
+ _('%u. Vorlesungswoche (ab %s)'),
+ $i + 1,
+ strftime('%x', $week_begin_timestamp));
+ break;
+ }
+ $i += 1;
+
+ $week_begin_timestamp = $next_week_timestamp;
+ }
+
+ $this->render_json($result);
+ }
+
+ private function notFound(string $message = ''): void
+ {
+ $this->set_status(404);
+ $this->render_text($message);
+ }
+
+ private function renderObject(SimpleORMap $object): void
+ {
+ if (Request::bool('quiet')) {
+ $this->render_nothing();
+ } else{
+ $this->render_json($object->toArray());
+ }
+ }
+
+ /**
+ * Tries the ISO format first: YYYY-MM-DDTHH:MM:SS±ZZ:ZZ
+ */
+ private function convertDatetime(?string $input): ?Datetime
+ {
+ if (!$input) {
+ return null;
+ }
+
+ return DateTime::createFromFormat(DateTime::RFC3339, $input)
+ ?? DateTime::createFromFormat(
+ 'Y-m-d\TH:i:s',
+ $input,
+ (new DateTime())->getTimezone()
+ );
+ }
}
diff --git a/app/controllers/resources/booking.php b/app/controllers/resources/booking.php
index 294aeaa..a4722ed 100644
--- a/app/controllers/resources/booking.php
+++ b/app/controllers/resources/booking.php
@@ -242,9 +242,7 @@ class Resources_BookingController extends AuthenticatedController
return true;
}
- $template_factory = new Flexi_TemplateFactory(
- $GLOBALS['STUDIP_BASE_PATH'] . '/locale/'
- );
+ $template_factory = new Flexi\Factory($GLOBALS['STUDIP_BASE_PATH'] . '/locale/');
$derived_resource = $booking->resource->getDerivedClassInstance();
$system_lang = $_SESSION['_language'];
@@ -1354,7 +1352,7 @@ class Resources_BookingController extends AuthenticatedController
$resource,
$time_intervals,
[1, 3],
- ($this->booking->id ? [$this->booking->id] : [])
+ isset($this->booking->id) ? [$this->booking->id] : []
);
$reservations_to_overwrite = array_merge(
$reservations_to_overwrite,
diff --git a/app/controllers/resources/room_request.php b/app/controllers/resources/room_request.php
index 6421f23..4c51beb 100644
--- a/app/controllers/resources/room_request.php
+++ b/app/controllers/resources/room_request.php
@@ -1739,8 +1739,8 @@ class Resources_RoomRequestController extends AuthenticatedController
if ($save_only) {
// redirect to reload all infos and showing the most current ones
$this->redirect('resources/room_request/resolve/' . $request_id);
- } elseif (Request::isDialog() && Context::get()) {
- $this->response->add_header('X-Dialog-Execute', '{"func": "STUDIP.AdminCourses.App.loadCourse", "payload": "'.Context::get()->id.'"}');
+ } elseif (Request::isDialog() && Context::get()->id) {
+ $this->response->add_header('X-Dialog-Execute', '{"func": "STUDIP.AdminCourses.App.loadCourse", "payload": "' . Context::get()->id . '"}');
}
}
diff --git a/app/controllers/room_management/planning.php b/app/controllers/room_management/planning.php
index c450c64..3da7904 100644
--- a/app/controllers/room_management/planning.php
+++ b/app/controllers/room_management/planning.php
@@ -38,7 +38,7 @@ class RoomManagement_PlanningController extends AuthenticatedController
if ($selected_clipboard_id) {
$_SESSION['selected_clipboard_id'] = $selected_clipboard_id;
} else {
- $selected_clipboard_id = $_SESSION['selected_clipboard_id'];
+ $selected_clipboard_id = $_SESSION['selected_clipboard_id'] ?? null;
}
$this->display_all_requests = Request::get('display_all_requests');
@@ -282,7 +282,7 @@ class RoomManagement_PlanningController extends AuthenticatedController
if ($selected_clipboard_id) {
$_SESSION['selected_clipboard_id'] = $selected_clipboard_id;
} else {
- $selected_clipboard_id = $_SESSION['selected_clipboard_id'];
+ $selected_clipboard_id = $_SESSION['selected_clipboard_id'] ?? null;
}
$this->display_all_requests = Request::get('display_all_requests');
@@ -411,7 +411,7 @@ class RoomManagement_PlanningController extends AuthenticatedController
}
//Check if a clipboard is selected:
- $selected_clipboard_id = $_SESSION['selected_clipboard_id'];
+ $selected_clipboard_id = $_SESSION['selected_clipboard_id'] ?? null;
$rooms = [];
if ($selected_clipboard_id) {
$clipboard = Clipboard::find($selected_clipboard_id);
@@ -1075,7 +1075,7 @@ class RoomManagement_PlanningController extends AuthenticatedController
if ($selected_clipboard_id) {
$_SESSION['selected_clipboard_id'] = $selected_clipboard_id;
} else {
- $selected_clipboard_id = $_SESSION['selected_clipboard_id'];
+ $selected_clipboard_id = $_SESSION['selected_clipboard_id'] ?? null;
}
//Get the selected date or use the current date, if none specified:
@@ -1371,7 +1371,7 @@ class RoomManagement_PlanningController extends AuthenticatedController
$export = Request::get('export');
if ($export == 'html') {
//Load the export template:
- $factory = new Flexi_TemplateFactory(
+ $factory = new Flexi\Factory(
$GLOBALS['STUDIP_BASE_PATH'] . '/app/views/room_management/planning/'
);
diff --git a/app/controllers/search/courses.php b/app/controllers/search/courses.php
index 6ae9d6a..a6a4d27 100644
--- a/app/controllers/search/courses.php
+++ b/app/controllers/search/courses.php
@@ -40,6 +40,7 @@ class Search_CoursesController extends AuthenticatedController
public function index_action()
{
$nodeClass = '';
+ $title = _('Vorlesungsverzeichnis');
if (Request::option('type', 'semtree') === 'semtree') {
Navigation::activateItem('/search/courses/semtree');
$nodeClass = StudipStudyArea::class;
@@ -52,22 +53,12 @@ class Search_CoursesController extends AuthenticatedController
$this->treeTitle = _('Einrichtungen');
$this->breadcrumbIcon = 'institute';
$this->editUrl = $this->url_for('rangetree/edit');
+ $title = _('Einrichtungsverzeichnis');
}
$this->startId = Request::option('node_id', $nodeClass . '_root');
$this->setupSidebar();
- }
-
- public function export_results_action()
- {
- $sem_browse_obj = new SemBrowse();
- $tmpfile = basename($sem_browse_obj->create_result_xls());
- if ($tmpfile) {
- $this->redirect(FileManager::getDownloadURLForTemporaryFile(
- $tmpfile, _('ErgebnisVeranstaltungssuche.xls'), 4));
- } else {
- $this->render_nothing();
- }
+ PageLayout::setTitle($title);
}
private function setupSidebar()
@@ -110,17 +101,7 @@ class Search_CoursesController extends AuthenticatedController
}
$sidebar->addWidget(new VueWidget('search-widget'));
+ $sidebar->addWidget(new VueWidget('views-widget'));
$sidebar->addWidget(new VueWidget('export-widget'));
-
- $views = new ViewsWidget();
- $views->addLink(
- _('Als Liste'),
- $this->url_for('search/courses', array_merge($params, ['show_as' => 'list']))
- )->setActive($this->show_as === 'list');
- $views->addLink(
- _('Als Tabelle'),
- $this->url_for('search/courses', array_merge($params, ['show_as' => 'table']))
- )->setActive($this->show_as === 'table');
- $sidebar->addWidget($views);
}
}
diff --git a/app/controllers/search/globalsearch.php b/app/controllers/search/globalsearch.php
index ed4ed6e..05fcda2 100644
--- a/app/controllers/search/globalsearch.php
+++ b/app/controllers/search/globalsearch.php
@@ -72,37 +72,40 @@ class Search_GlobalsearchController extends AuthenticatedController
}
}
- $semester_filter = $sidebar->addWidget(new OptionsWidget(_('Semester')));
- $semester_filter->id = 'semester_filter';
- $semester_filter->addSelect(
- _('Semester'),
- null,
- 'semester',
- $this->getSemesters(),
- 'future',
- ['id' => 'semester_select']
+ $filter_widget = $sidebar->addWidget(new OptionsWidget(_('Filter')));
+ $filter_widget->id = 'filter_widget';
+
+ $filter_widget->addElement(
+ new SelectListElement(
+ _('Semester'),
+ 'semester',
+ $this->getSemesters(),
+ 'future',
+ ['id' => 'semester_select']
+ ),
+ 'semester_filter'
);
- $seminar_type_filter = $sidebar->addWidget(new OptionsWidget(_('Veranstaltungstypen')));
- $seminar_type_filter->id = 'seminar_type_filter';
- $seminar_type_filter->addSelect(
- _('Typ der Veranstaltung'),
- null,
- 'seminar_type',
- $this->getSemClasses(),
- '',
- ['id' => 'seminar_type_select']
+ $filter_widget->addElement(
+ new SelectListElement(
+ _('Typ der Veranstaltung'),
+ 'seminar_type',
+ $this->getSemClasses(),
+ '',
+ ['id' => 'seminar_type_select']
+ ),
+ 'seminar_type_filter'
);
- $institute_filter = $sidebar->addWidget(new OptionsWidget(_('Einrichtungen')));
- $institute_filter->id = 'institute_filter';
- $institute_filter->addSelect(
- _('Einrichtung'),
- null,
- 'institute',
- $this->getInstitutes(),
- '',
- ['id' => 'institute_select']
+ $filter_widget->addElement(
+ new SelectListElement(
+ _('Einrichtung'),
+ 'institute',
+ $this->getInstitutes(),
+ '',
+ ['id' => 'institute_select']
+ ),
+ 'institute_filter'
);
}
diff --git a/app/controllers/search/studiengaenge.php b/app/controllers/search/studiengaenge.php
index a075ce9..e17eb2a 100644
--- a/app/controllers/search/studiengaenge.php
+++ b/app/controllers/search/studiengaenge.php
@@ -228,7 +228,7 @@ class Search_StudiengaengeController extends MVVController
} else {
$this->active_sem = Semester::find($this->sessGet('selected_semester', Semester::findCurrent()->id));
}
- $this->active_sem = $this->semesters[$this->active_sem->id] ? $this->active_sem : null;
+ $this->active_sem = !empty($this->semesters[$this->active_sem->id]) ? $this->active_sem : null;
if (!$this->active_sem && count($this->semesters)) {
$active_sem = reset($this->semesters);
$this->active_sem = Semester::find($active_sem['semester_id']);
@@ -423,7 +423,7 @@ class Search_StudiengaengeController extends MVVController
{
$this->abschnitt = StgteilAbschnitt::find($abschnitt_id);
if (!$this->abschnitt) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->render_template('search/studiengaenge/kommentar', $this->layout);
}
diff --git a/app/controllers/settings/general.php b/app/controllers/settings/general.php
index 734cca1..0e8ec70 100644
--- a/app/controllers/settings/general.php
+++ b/app/controllers/settings/general.php
@@ -44,6 +44,7 @@ class Settings_GeneralController extends Settings_SettingsController
public function index_action()
{
$this->user_language = getUserLanguage($this->user->id);
+ $this->notifications_placement = User::findCurrent()->getConfiguration()->SYSTEM_NOTIFICATIONS_PLACEMENT;
}
/**
@@ -80,6 +81,7 @@ class Settings_GeneralController extends Settings_SettingsController
} else {
PersonalNotifications::deactivateAudioFeedback($this->user->id);
}
+ $this->config->store('SYSTEM_NOTIFICATIONS_PLACEMENT', Request::get('system_notifications_placement'));
PageLayout::postSuccess(_('Die Einstellungen wurden gespeichert.'));
$this->redirect('settings/general');
diff --git a/app/controllers/settings/settings.php b/app/controllers/settings/settings.php
index 0346c24..9cd00c0 100644
--- a/app/controllers/settings/settings.php
+++ b/app/controllers/settings/settings.php
@@ -46,11 +46,11 @@ abstract class Settings_SettingsController extends AuthenticatedController
$exception = new AccessDeniedException(_('Sie dürfen dieses Profil nicht bearbeiten'));
$exception->setDetails([
_("Wahrscheinlich ist Ihre Session abgelaufen. Bitte "
- ."nutzen Sie in diesem Fall den untenstehenden Link, "
+ ."nutzen Sie in diesem Fall den folgenden Link, "
."um zurück zur Anmeldung zu gelangen.\n\n"
."Eine andere Ursache kann der Versuch des Zugriffs "
."auf Userdaten, die Sie nicht bearbeiten dürfen, sein. "
- ."Nutzen Sie den untenstehenden Link, um zurück auf "
+ ."Nutzen Sie den folgenden Link, um zurück auf "
."die Startseite zu gelangen."),
]);
throw $exception;
@@ -121,7 +121,7 @@ abstract class Settings_SettingsController extends AuthenticatedController
public function get_default_template($action)
{
$class = get_class($this);
- $controller_name = Trails_Inflector::underscore(mb_substr($class, 0, -10));
+ $controller_name = Trails\Inflector::underscore(mb_substr($class, 0, -10));
return file_exists($this->dispatcher->trails_root . '/views/' . $controller_name . '.php')
? $controller_name
: $controller_name . '/' . $action;
diff --git a/app/controllers/shared/contacts.php b/app/controllers/shared/contacts.php
index 98670f4..820d2ab 100644
--- a/app/controllers/shared/contacts.php
+++ b/app/controllers/shared/contacts.php
@@ -114,7 +114,7 @@ class Shared_ContactsController extends MVVController
if ($this->contact_id) {
$contact_range = MvvContactRange::findOneBySQL('contact_id=?', [$this->contact_id]);
if (!$contact_range) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->relations = $contact_range->getRelations($this->filter);
$this->origin = 'index';
@@ -155,7 +155,7 @@ class Shared_ContactsController extends MVVController
{
$this->contact_range = MvvContactRange::findOneBySQL('contact_id = ?', [$contact_id]);
if (!$this->contact_range) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->relations = $this->contact_range->getRelations($this->filter);
@@ -725,7 +725,7 @@ class Shared_ContactsController extends MVVController
$this->mvvcontact_id = $user_id;
$this->selected_sem_end = $this->filter['end_sem.ende'];
- $this->selected_inst = $this->filter['mvv_studiengang.institut_id'];
+ $this->selected_inst = $this->filter['mvv_studiengang.institut_id'] ?? null;
if (Request::submitted('store')) {
$selected = Request::getArray('ranges');
@@ -871,7 +871,7 @@ class Shared_ContactsController extends MVVController
));
$filter = [
'mvv_modul.stat' => $stat,
- 'mvv_modul_inst.institut_id' => $this->filter['mvv_modul_inst.institut_id'],
+ 'mvv_modul_inst.institut_id' => $this->filter['mvv_modul_inst.institut_id'] ?? '',
'start_sem.beginn' => $this->filter['start_sem.beginn'],
'end_sem.ende' => $this->filter['end_sem.ende']
];
diff --git a/app/controllers/shared/download.php b/app/controllers/shared/download.php
index 92d15d9..f94bc86 100644
--- a/app/controllers/shared/download.php
+++ b/app/controllers/shared/download.php
@@ -158,7 +158,7 @@ class Shared_DownloadController extends AuthenticatedController
}
$path = $GLOBALS['STUDIP_BASE_PATH'] . '/app/views/shared/modul/';
- $factory = new Flexi_TemplateFactory($path);
+ $factory = new Flexi\Factory($path);
$template = $factory->open('_modul');
$template->_ = function ($string) { return $this->_($string); };
@@ -166,7 +166,7 @@ class Shared_DownloadController extends AuthenticatedController
$template->display_language = $display_language;
$content = $template->render();
- $factory = new \Flexi_TemplateFactory($path);
+ $factory = new Flexi\Factory($path);
$type = 1;
if (count($modul->modulteile) == 1) {
$modulteil = $modul->modulteile->first();
diff --git a/app/controllers/shared/log_event.php b/app/controllers/shared/log_event.php
index 0355e45..3d8af7e 100644
--- a/app/controllers/shared/log_event.php
+++ b/app/controllers/shared/log_event.php
@@ -122,12 +122,12 @@ class Shared_LogEventController extends MVVController
$search_action .= " AND `log_actions`.`name` LIKE CONCAT('%_'," . DBManager::get()->quote($log_action) . ")";
}
- $statement = DBManager::get()->prepare("SELECT *, `log_actions`.`name`
+ $statement = DBManager::get()->prepare("SELECT *
FROM `log_events`
LEFT JOIN `log_actions` ON `log_events`.`action_id` = `log_actions`.`action_id`
WHERE `info` = ?
" . $search_action . "
- ORDER BY `log_events`.`mkdate` DESC");
+ ORDER BY `log_events`.`event_id` DESC");
$statement->execute([$mvv_field]);
$res = $statement->fetchOne();
if ($res) {
diff --git a/app/controllers/siteinfo.php b/app/controllers/siteinfo.php
index ab81660..7bc95cb 100644
--- a/app/controllers/siteinfo.php
+++ b/app/controllers/siteinfo.php
@@ -37,7 +37,7 @@ class SiteinfoController extends StudipController
} else {
$action = 'show';
if ($this->page_is_draft || ($this->page_disabled_nobody && $GLOBALS['user']->id === 'nobody')) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
$this->add_navigation($action);
diff --git a/app/controllers/start.php b/app/controllers/start.php
index 53a87dc..8231095 100644
--- a/app/controllers/start.php
+++ b/app/controllers/start.php
@@ -53,10 +53,13 @@ class StartController extends AuthenticatedController
}
}
+ $this->widget_layout = $this->get_template_factory()->open('start/_widget.php');
+
$sidebar = Sidebar::get();
$nav = $sidebar->addWidget(new NavigationWidget());
$nav->setTitle(_('Sprungmarken'));
+ $nav->setId('navigation-layer-3');
foreach (array_merge(...$this->columns) as $widget) {
$nav->addLink(
$widget->getPluginName(),
@@ -132,7 +135,7 @@ class StartController extends AuthenticatedController
*/
private function getAvailableWidgets($user_id)
{
- $all_widgets = PluginEngine::getPlugins('PortalPlugin');
+ $all_widgets = PluginEngine::getPlugins(PortalPlugin::class);
$user_widgets = WidgetUser::getWidgets($user_id);
$used_widgets = array_merge(...$user_widgets);
$available = [];
@@ -190,7 +193,7 @@ class StartController extends AuthenticatedController
PageLayout::setTitle(sprintf(_('Standard-Startseite für "%s" bearbeiten'), ucfirst($permission)));
- $this->widgets = PluginEngine::getPlugins('PortalPlugin');
+ $this->widgets = PluginEngine::getPlugins(PortalPlugin::class);
$this->initial_widgets = WidgetDefault::getWidgets($permission);
$this->permission = $permission;
}
diff --git a/app/controllers/studiengaenge/abschluesse.php b/app/controllers/studiengaenge/abschluesse.php
index 8ec055b..60bc091 100644
--- a/app/controllers/studiengaenge/abschluesse.php
+++ b/app/controllers/studiengaenge/abschluesse.php
@@ -50,7 +50,7 @@ class Studiengaenge_AbschluesseController extends Studiengaenge_StudiengaengeCon
$perm_institutes = MvvPerm::getOwnInstitutes();
$abschluss = Abschluss::find($abschluss_id);
if (!$abschluss) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->abschluss_id = $abschluss->id;
if (count($perm_institutes)) {
@@ -59,7 +59,7 @@ class Studiengaenge_AbschluesseController extends Studiengaenge_StudiengaengeCon
$perm_institutes
);
if (!count($institutes_abschluss)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$this->studiengaenge = SimpleORMapCollection::createFromArray(
Studiengang::findByAbschluss_id($this->abschluss_id)
@@ -91,4 +91,4 @@ class Studiengaenge_AbschluesseController extends Studiengaenge_StudiengaengeCon
$this->perform_relayed('index');
}
}
-} \ No newline at end of file
+}
diff --git a/app/controllers/studiengaenge/fachbereiche.php b/app/controllers/studiengaenge/fachbereiche.php
index 970c8d9..35f997b 100644
--- a/app/controllers/studiengaenge/fachbereiche.php
+++ b/app/controllers/studiengaenge/fachbereiche.php
@@ -51,7 +51,7 @@ class Studiengaenge_FachbereicheController extends Studiengaenge_StudiengaengeCo
$this->fachbereich_id = $fachbereich_id;
if (count($perm_institutes)) {
if (!in_array($this->fachbereich_id, $perm_institutes)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
diff --git a/app/controllers/studiengaenge/fachbereichestgteile.php b/app/controllers/studiengaenge/fachbereichestgteile.php
index c8037dc..73ad2aa 100644
--- a/app/controllers/studiengaenge/fachbereichestgteile.php
+++ b/app/controllers/studiengaenge/fachbereichestgteile.php
@@ -67,7 +67,7 @@ class Studiengaenge_FachbereichestgteileController extends Studiengaenge_Studien
$this->fachbereich = $fachbereich;
$this->perform_relayed('stgteil');
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
}
diff --git a/app/controllers/studiengaenge/faecher.php b/app/controllers/studiengaenge/faecher.php
index c9546a3..9990f7d 100644
--- a/app/controllers/studiengaenge/faecher.php
+++ b/app/controllers/studiengaenge/faecher.php
@@ -83,7 +83,7 @@ class Studiengaenge_FaecherController extends Studiengaenge_StudiengangteileCont
$this->stgteil = StudiengangTeil::get();
$this->stgteil->assignFach($fach->getId());
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->perform_relayed('stgteil');
}
diff --git a/app/controllers/studiengaenge/kategorien.php b/app/controllers/studiengaenge/kategorien.php
index 03d28fc..8f6a98d 100644
--- a/app/controllers/studiengaenge/kategorien.php
+++ b/app/controllers/studiengaenge/kategorien.php
@@ -73,7 +73,7 @@ class Studiengaenge_KategorienController extends Studiengaenge_StudiengaengeCont
if (count($perm_institutes)) {
if (!in_array($studiengang->institut_id, $perm_institutes)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
@@ -98,4 +98,4 @@ class Studiengaenge_KategorienController extends Studiengaenge_StudiengaengeCont
$this->perform_relayed('index');
}
}
-} \ No newline at end of file
+}
diff --git a/app/controllers/studiengaenge/shared_version.php b/app/controllers/studiengaenge/shared_version.php
index 696fac0..a6265b0 100644
--- a/app/controllers/studiengaenge/shared_version.php
+++ b/app/controllers/studiengaenge/shared_version.php
@@ -11,18 +11,18 @@ abstract class SharedVersionController extends MVVController
{
$this->stgteil = StudiengangTeil::find($stgteil_id);
if (!$this->stgteil) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
if (!MvvPerm::haveFieldPermVersionen($this->stgteil, MvvPerm::PERM_READ)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if (!isset($this->version)) {
$this->version = StgteilVersion::find($version_id);
if (!$this->version) {
if (!MvvPerm::haveFieldPermVersionen($this->stgteil, MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$this->version = new StgteilVersion();
}
@@ -51,7 +51,7 @@ abstract class SharedVersionController extends MVVController
if (Request::submitted('store')) {
CSRFProtection::verifyUnsafeRequest();
if (!MvvPerm::haveFieldPermVersionen($this->stgteil)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$stored = false;
$this->version->stgteil_id = $this->stgteil->getId();
@@ -220,7 +220,7 @@ abstract class SharedVersionController extends MVVController
{
$version = StgteilVersion::find($version_id);
if (!$version) {
- throw new Trails_Exception(404, _('Unbekannte Version'));
+ throw new Trails\Exception(404, _('Unbekannte Version'));
}
if (Request::isPost()) {
CSRFProtection::verifyUnsafeRequest();
@@ -267,16 +267,16 @@ abstract class SharedVersionController extends MVVController
$perm = MvvPerm::get($this->version);
if (!$perm->haveFieldPerm('abschnitte', MvvPerm::PERM_READ)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if ($this->abschnitt->isNew() && !$perm->haveFieldPerm('abschnitte', MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if (Request::submitted('store')) {
CSRFProtection::verifyUnsafeRequest();
if (!$perm->haveFieldPerm('abschnitte', MvvPerm::PERM_WRITE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$this->abschnitt->version_id = $this->version->getId();
$this->abschnitt->name = Request::i18n('name')->trim();
@@ -494,7 +494,7 @@ abstract class SharedVersionController extends MVVController
$abschnitt = StgteilAbschnitt::find($abschnitt_id);
if ($abschnitt) {
if (!MvvPerm::haveFieldPermModul_zuordnungen($abschnitt, MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$modul = Modul::find($modul_id);
if (!$modul) {
@@ -614,7 +614,7 @@ abstract class SharedVersionController extends MVVController
{
$version = StgteilVersion::find($version_id);
if (!$version) {
- throw new Trails_Exception(404, _('Unbekannte Version'));
+ throw new Trails\Exception(404, _('Unbekannte Version'));
} else {
if (Request::isPost()) {
CSRFProtection::verifyUnsafeRequest();
@@ -754,7 +754,7 @@ abstract class SharedVersionController extends MVVController
$this->redirect($this->action_url('abschnitte/' . $version_id));
}
} else {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
if (Request::isXhr()) {
diff --git a/app/controllers/studiengaenge/studiengaenge.php b/app/controllers/studiengaenge/studiengaenge.php
index d053f48..8465665 100644
--- a/app/controllers/studiengaenge/studiengaenge.php
+++ b/app/controllers/studiengaenge/studiengaenge.php
@@ -541,7 +541,7 @@ class Studiengaenge_StudiengaengeController extends MVVController
if (Request::isPost()) {
CSRFProtection::verifyRequest();
if (!MvvPerm::haveFieldPermStudiengangteile($studiengang, MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$stgteil_name = $this->stg_stgteil->stgteil_name;
$stgbez_name = $this->stg_stgteil->stgbez_name;
@@ -588,7 +588,7 @@ class Studiengaenge_StudiengaengeController extends MVVController
if (Request::isPost()) {
CSRFProtection::verifyUnsafeRequest();
if (!MvvPerm::haveFieldPermStudiengangteile($studiengang, MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$stgteil_name = $stg_stgteil->stgteil_name;
$stgbez_name = $stg_stgteil->stgbez_name;
diff --git a/app/controllers/studiengaenge/studiengangteile.php b/app/controllers/studiengaenge/studiengangteile.php
index 0fddd44..bc1449f 100644
--- a/app/controllers/studiengaenge/studiengangteile.php
+++ b/app/controllers/studiengaenge/studiengangteile.php
@@ -144,7 +144,7 @@ class Studiengaenge_StudiengangteileController extends SharedVersionController
$this->stgteil->contact_assignments = $stgteil_orig->contact_assignments;
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->perform_relayed('stgteil');
}
diff --git a/app/controllers/studiengaenge/versionen.php b/app/controllers/studiengaenge/versionen.php
index 9b60b3d..41625bf 100644
--- a/app/controllers/studiengaenge/versionen.php
+++ b/app/controllers/studiengaenge/versionen.php
@@ -52,7 +52,7 @@ class Studiengaenge_VersionenController extends SharedVersionController
$this->redirect($this->action_url('index/' . $this->chooser_filter['stgteile']));
return;
default :
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
$this->name = $list;
if (!empty($this->lists[$list]['elements'])) {
@@ -218,7 +218,7 @@ class Studiengaenge_VersionenController extends SharedVersionController
if ($stgteil_id) {
$this->stgteil = StudiengangTeil::find($stgteil_id);
if (!$this->stgteil) {
- throw new Trails_Exception(404, _('Unbekannter Studiengangteil'));
+ throw new Trails\Exception(404, _('Unbekannter Studiengangteil'));
}
$this->initPageParams();
diff --git a/app/controllers/studip_controller.php b/app/controllers/studip_controller.php
deleted file mode 100644
index 9e238a1..0000000
--- a/app/controllers/studip_controller.php
+++ /dev/null
@@ -1,875 +0,0 @@
-<?php
-/*
- * studip_controller.php - studip controller base class
- * Copyright (c) 2009 Elmar Ludwig
- *
- * 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.
- */
-
-use PhpOffice\PhpSpreadsheet\Spreadsheet;
-use PhpOffice\PhpSpreadsheet\Writer\Csv;
-use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
-
-require_once 'studip_controller_properties_trait.php';
-require_once 'studip_response.php';
-
-/**
- * @property StudipResponse $response
- */
-abstract class StudipController extends Trails_Controller
-{
- use StudipControllerPropertiesTrait;
-
- protected $with_session = false; //do we need to have a session for this controller
- protected $allow_nobody = true; //should 'nobody' allowed for this controller or redirected to login?
- protected $_autobind = false;
-
- /**
- * @return false|void
- */
- public function before_filter(&$action, &$args)
- {
- $this->current_action = $action;
- // allow only "word" characters in arguments
- $this->validate_args($args);
-
- parent::before_filter($action, $args);
-
- if ($this->with_session) {
- # open session
- page_open([
- 'sess' => 'Seminar_Session',
- 'auth' => $this->allow_nobody ? 'Seminar_Default_Auth' : 'Seminar_Auth',
- 'perm' => 'Seminar_Perm',
- 'user' => 'Seminar_User'
- ]);
-
- // show login-screen, if authentication is "nobody"
- $GLOBALS['auth']->login_if((Request::get('again') || !$this->allow_nobody) && $GLOBALS['user']->id == 'nobody');
-
- // Setup flash instance
- $this->flash = Trails_Flash::instance();
-
- // set up user session
- include 'lib/seminar_open.php';
- }
-
- // Set generic attribute that indicates whether the request was sent
- // via ajax or not
- $this->via_ajax = Request::isXhr();
-
- # Set base layout
- #
- # If your controller needs another layout, overwrite your controller's
- # before filter:
- #
- # class YourController extends AuthenticatedController {
- # function before_filter(&$action, &$args) {
- # parent::before_filter($action, $args);
- # $this->set_layout("your_layout");
- # }
- # }
- #
- # or unset layout by sending:
- #
- # $this->set_layout(NULL)
- #
- $layout_file = Request::isXhr()
- ? 'layouts/dialog.php'
- : 'layouts/base.php';
- $layout = $GLOBALS['template_factory']->open($layout_file);
- $this->set_layout($layout);
-
- $this->set_content_type('text/html;charset=utf-8');
- }
-
- /**
- * Extended method to inject extended response object.
- */
- public function erase_response()
- {
- parent::erase_response();
-
- $this->response = new StudipResponse();
- }
-
- /**
- * Hooked perform method in order to inject body element id creation.
- *
- * In order to avoid clashes, these body element id will be joined
- * with a minus sign. Otherwise the controller "x" with action
- * "y_z" would be given the same id as the controller "x/y" with
- * the action "z", namely "x_y_z". With the minus sign this will
- * result in the ids "x-y_z" and "x_y-z".
- *
- * Plugins will always have a leading 'plugin-' and the decamelized
- * plugin name in front of the id.
- *
- * @param String $unconsumed_path Path segment containing action and
- * optionally arguments or format
- * @return Trails_Response from parent controller
- */
- public function perform($unconsumed_path)
- {
- // Set body element id if it has not already been set
- if (!PageLayout::hasBodyElementId()) {
- $body_id = $this->getBodyElementIdForControllerAndAction($unconsumed_path);
- PageLayout::setBodyElementId($body_id);
- }
-
- return parent::perform($unconsumed_path);
- }
-
- /**
- * Callback function being called after an action is executed.
- *
- * @param string Name of the action to perform.
- * @param array An array of arguments to the action.
- *
- * @return void
- */
- public function after_filter($action, $args)
- {
- parent::after_filter($action, $args);
-
- if (Request::isXhr() && !isset($this->response->headers['X-Title']) && PageLayout::hasTitle()) {
- $this->response->add_header('X-Title', rawurlencode(PageLayout::getTitle()));
- }
- if (Request::isXhr() && !isset($this->response->headers['X-WikiLink']) && PageLayout::getHelpKeyword()) {
- $this->response->add_header('X-WikiLink', format_help_url(PageLayout::getHelpKeyword()));
- }
-
- if ($this->with_session) {
- page_close();
- }
- }
-
- /**
- * Validate arguments based on a list of given types. The types are:
- * 'int', 'float', 'option' and 'string'. If the list of types is NULL
- * or shorter than the argument list, 'option' is assumed for all
- * remaining arguments. 'option' differs from Request::option() in
- * that it also accepts the charaters '-' and ',' in addition to all
- * word characters.
- *
- * Since Stud.IP 4.0 it is also possible to directly inject
- * SimpleORMap objects. If types is NULL, the signature of the called
- * action is analyzed and any type hint that matches a sorm class
- * will be used to create an object using the argument as the id
- * that is passed to the object's constructor.
- *
- * If $_autobind is set to true, the created object is also assigned
- * to the controller so that it is available in a view.
- *
- * @param array $args an array of arguments to the action
- * @param array $types list of argument types (optional)
- */
- public function validate_args(&$args, $types = null)
- {
- $class_infos = [];
-
- if ($types === null) {
- $types = [];
- }
-
- if ($this->has_action($this->current_action)) {
- $reflection = new ReflectionMethod($this, $this->current_action . '_action');
- $parameters = $reflection->getParameters();
- foreach ($parameters as $i => $parameter) {
- $class_type = $parameter->getType();
-
- if (
- !$class_type
- || !class_exists($class_type->getName())
- || !is_a($class_type->getName(), SimpleORMap::class, true)
- ) {
- continue;
- }
-
- $types[$i] = 'sorm';
- $class_infos[$i] = [
- 'model' => $class_type->getName(),
- 'var' => $parameter->getName(),
- 'optional' => $parameter->isOptional(),
- ];
-
- if ($parameter->isOptional() && !isset($args[$i])) {
- $args[$i] = $parameter->getDefaultValue();
- }
- }
- }
-
- foreach ($args as $i => &$arg) {
- $type = $types[$i] ?? 'option';
- switch ($type) {
- case 'int':
- $arg = (int) $arg;
- break;
-
- case 'float':
- $arg = (float) strtr($arg, ',', '.');
- break;
-
- case 'option':
- if (preg_match('/[^\\w,-]/', $arg)) {
- throw new Trails_Exception(400);
- }
- break;
-
- case 'sorm':
- $info = $class_infos[$i];
-
- $id = null;
- if ($arg != -1) {
- $id = $arg;
- }
- if (mb_strpos($id, SimpleORMap::ID_SEPARATOR) !== false) {
- $id = explode(SimpleORMap::ID_SEPARATOR, $id);
- }
-
- $reflection = new ReflectionClass($info['model']);
-
- $sorm = $reflection->newInstance($id);
- if (!$info['optional'] && $sorm->isNew()) {
- throw new Trails_Exception(
- 404,
- "Parameter {$info['var']} could not be resolved with value {$arg}"
- );
- }
-
- $arg = $sorm;
- if ($this->_autobind) {
- $this->{$info['var']} = $arg;
- }
- break;
-
- case 'string':
- break;
-
- default:
- throw new Trails_Exception(500, 'Unknown type "' . $type . '"');
- }
- }
-
- reset($args);
- }
-
- /**
- * Returns a URL to a specified route to your Trails application.
- * without first parameter the current action is used
- * if route begins with a / then the current controller ist prepended
- * if second parameter is an array it is passed to URLHeper
- *
- * @param string a string containing a controller and optionally an action
- * @param string[] optional arguments
- *
- * @return string a URL to this route
- */
- public function url_for($to = ''/* , ... */)
- {
- $args = func_get_args();
-
- // Try to create route if none given
- if ($to === '') {
- $args[0] = isset($this->parent_controller)
- ? $this->parent_controller->current_action
- : $this->current_action;
- return $this->action_url(...$args);
- }
-
- // Create url for a specific action
- // TODO: This seems odd. You kinda specify an absolute path
- // to receive a relative url. Meh...
- //
- // @deprecated Do not use this, please!
- if ($to[0] === '/') {
- $args[0] = substr($to, 1);
- return $this->action_url(...$args);
- }
-
- // Check for absolute URL
- if ($this->isURL($to)) {
- throw new InvalidArgumentException(__METHOD__ . ' cannot be used with absolute URLs');
- }
-
- // Extract fragment (if any)
- if (strpos($to, '#') !== false) {
- list($args[0], $fragment) = explode('#', $to);
- }
-
- // Extract parameters (if any)
- $params = [];
- if (is_array(end($args))) {
- $params = array_pop($args);
- }
-
- // Map any sorm objects to their ids
- $args = array_map(function ($arg) {
- if (is_object($arg) && $arg instanceof SimpleORMap) {
- return $arg->isNew() ? -1 : $arg->id;
- }
- return $arg;
- }, $args);
-
- $url = parent::url_for(...$args);
-
- if (isset($fragment)) {
- $url .= '#' . $fragment;
- }
- return URLHelper::getURL($url, $params);
- }
-
- /**
- * Returns an escaped URL to a specified route to your Trails application.
- * without first parameter the current action is used
- * if route begins with a / then the current controller ist prepended
- * if second parameter is an array it is passed to URLHeper
- *
- * @param string a string containing a controller and optionally an action
- * @param strings optional arguments
- *
- * @return string a URL to this route
- */
- public function link_for($to = ''/* , ... */)
- {
- return htmlReady($this->url_for(...func_get_args()));
- }
-
- /**
- * Redirects the user another page. Accepts multiple parameters just like
- * url_for().
- *
- * @param string $to
- * @see StudipController::url_for()
- */
- public function redirect($to)
- {
- $to = $this->adjustToArguments(...func_get_args());
-
- parent::redirect($to);
- }
-
- /**
- * Relocate the user to another location. This is a specialized version
- * of redirect that differs in two points:
- *
- * - relocate() will force the browser to leave the current dialog while
- * redirect would refresh the dialog's contents
- * - relocate() accepts all the parameters that url_for() accepts so it's
- * no longer neccessary to chain url_for() and redirect()
- *
- * @param String $to Location to redirect to
- */
- public function relocate($to)
- {
- $to = $this->adjustToArguments(...func_get_args());
-
- if (Request::isDialog()) {
- $this->response->add_header('X-Location', encodeURI($to));
- $this->render_nothing();
- } else {
- parent::redirect($to);
- }
- }
-
- /**
- * Returns a URL to a specified route to your Trails application, unless
- * the parameter is already a valid URL (which is returned unchanged).
- *
- * If no absolute url or more than one argument is given, url_for() is
- * used.
- */
- private function adjustToArguments(...$args): string
- {
- if (count($args) > 1 && $this->isURL($args[0])) {
- throw new InvalidArgumentException('Method may not be used with a URL and multiple parameters');
- }
-
- if (count($args) === 1 && $this->isURL($args[0])) {
- return $args[0];
- }
-
- return $this->url_for(...$args);
- }
-
- /**
- * Returns whether the given parameter is a valid url.
- *
- * @param string $to
- * @return bool
- */
- private function isURL(string $to): bool
- {
- return preg_match('#^(/|\w+://)#', $to);
- }
-
- /**
- * Exception handler called when the performance of an action raises an
- * exception.
- *
- * @param object the thrown exception
- */
- public function rescue($exception)
- {
- throw $exception;
- }
-
- /**
- * render given data as json, data is converted to utf-8
- *
- * @param mixed $data
- */
- public function render_json($data)
- {
- $json = json_encode($data);
-
- $this->set_content_type('application/json;charset=utf-8');
- $this->response->add_header('Content-Length', strlen($json));
- $this->render_text($json);
- }
-
- /**
- * Render given data as csv, data is assumed to be utf-8.
- * The first row of data may contain column titles.
- *
- * @param array $data data as two dimensional array
- * @param string $filename download file name (optional)
- * @param string $delimiter field delimiter char (optional)
- * @param string $enclosure field enclosure char (optional)
- */
- public function render_csv($data, $filename = null, $delimiter = ';', $enclosure = '"')
- {
- $this->set_content_type('text/csv; charset=UTF-8');
-
- $output = fopen('php://temp', 'rw');
- fputs($output, "\xEF\xBB\xBF");
-
- foreach ($data as $row) {
- fputcsv($output, $row, $delimiter, $enclosure);
- }
-
- rewind($output);
- $csv_data = stream_get_contents($output);
- fclose($output);
-
- if (isset($filename)) {
- $this->response->add_header('Content-Disposition', 'attachment; ' . encode_header_parameter('filename', $filename));
- }
-
- $this->response->add_header('Content-Length', strlen($csv_data));
-
- $this->render_text($csv_data);
- }
-
- /**
- * Renders a pdf file given by a TCPDF/ExportPDF object.
- *
- * @param TCPDF $pdf TCPDF object to render
- * @param string $filename Filename
- * @param bool $inline Should the pdf be displayed inline (default: no)
- */
- protected function render_pdf(TCPDF $pdf, $filename, $inline = false)
- {
- $temp_file = $GLOBALS['TMP_PATH'] . '/' . md5(uniqid('pdf-file', true));
- $pdf->Output($temp_file, 'F');
-
- $disposition = $inline ? 'inline' : 'attachment';
-
- $this->render_temporary_file($temp_file, $filename, 'application/pdf', $disposition);
- }
-
- /**
- * Renders a file
- * @param string $file Path of the file to render
- * @param string $filename Name of the file displayed to user
- * (will equal $file when missing)
- * @param string $content_type Optional content type (will be determined if missing)
- * @param string $content_disposition Either attachment (default) or inline
- * @param Closure $callback Optional callback when download has finished
- * @param int $chunk_size Optional size of chunks to send (default: 256k)
- */
- public function render_file(
- $file,
- $filename = null,
- $content_type = null,
- $content_disposition = 'attachment',
- Closure $callback = null,
- $chunk_size = 262144
- ) {
- if (!file_exists($file)) {
- throw new Trails_Exception(404);
- }
-
- if (!is_readable($file)) {
- throw new Trails_Exception(500);
- }
-
- if ($content_type === null) {
- $content_type = get_mime_type($filename ?: $file);
- }
-
- if (!in_array($content_type, get_mime_types())) {
- $content_type = 'application/octet-stream';
- }
-
- if ($content_type === 'application/octet-stream') {
- $content_disposition = 'attachment';
- }
-
- $this->set_content_type($content_type);
- $this->response->add_header(
- 'Content-Disposition',
- "{$content_disposition}; " . encode_header_parameter(
- 'filename',
- FileManager::cleanFileName($filename ?: basename($file))
- )
- );
- $this->response->add_header('Content-Length', filesize($file));
- $this->response->add_header('Content-Transfer-Encoding', 'binary');
- $this->response->add_header('Pragma', 'public');
- $this->render_text(function () use ($file, $chunk_size, $callback) {
- $fp = fopen($file, 'rb');
-
- while (!feof($fp)) {
- yield fgets($fp, $chunk_size);
- }
-
- fclose($fp);
-
- if ($callback) {
- $callback($file);
- }
- });
- }
-
- /**
- * Renders a temporary file which will be deleted after transmission.
- * This is just a convenience method so you don't have to write the delete
- * callback.
- *
- * @param string $file Path of the file to render
- * @param string $filename Name of the file displayed to user
- * (will equal $file when missing)
- * @param string $content_type Optional content type (will be determined if missing)
- * @param string $content_disposition Either attachment (default) or inline
- * @param Closure $callback Optional callback when download has finished
- * @param int $chunk_size Optional size of chunks to send (default: 256k)
- */
- public function render_temporary_file(
- $file,
- $filename = null,
- $content_type = null,
- $content_disposition = 'attachment',
- Closure $callback = null,
- $chunk_size = 262144
-
- ) {
- $delete_callback = function ($file) use ($callback) {
- unlink($file);
-
- if ($callback) {
- $callback($file);
- }
- };
-
- $this->render_file(
- $file,
- $filename,
- $content_type,
- $content_disposition,
- $delete_callback,
- $chunk_size
- );
- }
-
- public function render_form(\Studip\Forms\Form $form)
- {
- $this->render_text($form->render());
- }
-
- /**
- * relays current request to another controller and returns the response
- * the other controller is given all assigned properties, additional parameters are passed
- * through
- *
- * @param string $to_uri a trails route
- * @return Trails_Response
- */
- public function relay($to_uri/* , ... */)
- {
- $args = func_get_args();
- $uri = array_shift($args);
- [$controller_path, $unconsumed] = '' === $uri ? $this->dispatcher->default_route() : $this->dispatcher->parse($uri);
-
- $controller = $this->dispatcher->load_controller($controller_path);
- $assigns = $this->get_assigned_variables();
- unset($assigns['controller']);
- foreach ($assigns as $k => $v) {
- $controller->$k = $v;
- }
- $controller->layout = null;
- $controller->parent_controller = $this;
- array_unshift($args, $unconsumed);
- return $controller->perform_relayed(...$args);
- }
-
- /**
- * Relays current request and performs redirect if neccessary.
- *
- * @param string $to_uri a trails route
- * @return Trails_Response
- *
- * @see StudipController::relay()
- */
- public function relayWithRedirect(...$args): Trails_Response
- {
- $response = $this->relay(...$args);
-
- // If the relayed action should perform a redirect, do so
- if (isset($response->headers['Location'])) {
- header("Location: {$response->headers['Location']}");
- page_close();
- die;
- }
-
- return $response;
- }
-
- /**
- * perform a given action/parameter string from an relayed request
- * before_filter and after_filter methods are not called
- *
- * @see perform
- * @param string $unconsumed
- * @return Trails_Response
- */
- public function perform_relayed($unconsumed/* , ... */)
- {
- $args = func_get_args();
- $unconsumed = array_shift($args);
-
- [$action, $extracted_args, $format] = $this->extract_action_and_args($unconsumed);
- $this->format = isset($format) ? $format : 'html';
- $this->current_action = $action;
- $args = array_merge($extracted_args, $args);
- $callable = $this->map_action($action);
-
- if (is_callable($callable)) {
- $callable(...$args);
- } else {
- $this->does_not_understand($action, $args);
- }
-
- if (!$this->performed) {
- $this->render_action($action);
- }
- return $this->response;
- }
-
- /**
- * Renders a given template and returns the resulting string.
- *
- * @param string $template Name of the template file
- * @param mixed $layout Optional layout
- * @return string
- */
- public function render_template_as_string($template, $layout = null)
- {
- $template = $this->get_template_factory()->open($template);
- $template->set_layout($layout);
- $template->set_attributes($this->get_assigned_variables());
- return $template->render();
- }
-
- /**
- * Magic methods that intercepts all unknown method calls.
- * If a method is called that matches an action on this controller,
- * an url to that action is generated.
- *
- * Basically, this:
- *
- * <code>$controller->url_for('foo/bar/baz/' . $param)</code>
- *
- * is equal to calling this on the Foo_BarController:
- *
- * <code>$controller->baz($param)</code>
- *
- * @param String $method Called method name
- * @param array $argumetns Provided arguments
- * @return url to the requested action
- * @throws Trails_UnknownAction if no action matches the method
- */
- public function __call($method, $arguments)
- {
- $function = 'action_link';
- if (mb_strpos($method, 'Link') === mb_strlen($method) - 4) {
- $method = mb_substr($method, 0, -4);
- } elseif (mb_strpos($method, 'URL') === mb_strlen($method) - 3) {
- $function = 'action_url';
- $method = mb_substr($method, 0, -3);
- }
-
- if (!$this->has_action($method)) {
- throw new Trails_UnknownAction("Unknown action '{$method}'");
- }
-
- array_unshift($arguments, $method);
- return call_user_func_array([$this, $function], $arguments);
- }
-
- /**
- * Returns whether this controller has the specificed action.
- *
- * @param string $action Name of the action
- * @return true if action is defined, false otherwise
- */
- public function has_action($action)
- {
- return method_exists($this, $action . '_action')
- || ($this->parent_controller
- && $this->parent_controller->has_action($action));
- }
-
- /**
- * Generates the url for an action on this controller without the
- * neccessity to provide the full "path" to the action (since it
- * is implicitely known).
- *
- * Basically, this:
- *
- * <code>$controller->url_for('foo/bar/baz/' . $param)</code>
- *
- * is equal to calling this on the Foo_BarController:
- *
- * <code>$controller->action_url('baz/' . $param)</code>
- *
- * @param string $action Name of the action
- * @return string url to the requested action
- */
- public function action_url($action)
- {
- $arguments = func_get_args();
- $arguments[0] = $this->controller_path() . '/' . $arguments[0];
-
- return $this->url_for(...$arguments);
- }
-
- /**
- * Generates the link for an action on this controller without the
- * neccessity to provide the full "path" to the action (since it
- * is implicitely known).
- *
- * Basically, this:
- *
- * <code>$controller->link_for('foo/bar/baz/' . $param)</code>
- *
- * is equal to calling this on the Foo_BarController:
- *
- * <code>$controller->action_link('baz/' . $param)</code>
- *
- * @param string $action Name of the action
- * @return string to the requested action
- */
- public function action_link($action)
- {
- return htmlReady($this->action_url(...func_get_args()));
- }
-
- /**
- * Returns the url path to this controller.
- *
- * @return string url path to this controller
- */
- protected function controller_path()
- {
- $class = get_class($this->parent_controller ?? $this);
- $controller = mb_substr($class, 0, -mb_strlen('Controller'));
- $controller = strtosnakecase($controller);
- return preg_replace('/_{2,}/', '/', $controller);
- }
-
-
- /**
- * Validate the datetime according to specific format.
- *
- * @param string $datetime the datetime which should be validate
- * @param string $format the format that the datetime should have by default H:i for time
- *
- * @return bool result of validation
- */
- public function validate_datetime($datetime, $format = 'H:i')
- {
- $dt = DateTime::createFromFormat($format, $datetime);
- return $dt && $dt->format($format) == date('H:i',strtotime($datetime));
- }
-
- /**
- * Export xlsx and csv files via PhpSpreadsheet
- *
- * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
- */
- public function render_spreadsheet(
- array $header,
- array $data,
- string $format,
- string $filename,
- ?string $filepath = null
- ): void {
- $render_to_browser = false;
- if ($filepath == null) {
- $render_to_browser = true;
- $filepath = tempnam($GLOBALS['TMP_PATH'], 'spreadsheet');
- }
- $spreadsheet = new Spreadsheet();
- $activeWorksheet = $spreadsheet->getActiveSheet();
- $activeWorksheet->fromArray($header);
- $activeWorksheet->fromArray($data, null, 'A2');
-
- if ($format === 'xlsx') {
- $writer = new Xlsx($spreadsheet);
- } elseif ($format === 'csv') {
- $writer = new Csv($spreadsheet);
- } else {
- throw new Exception("Format {$format} is not supported");
- }
-
- $writer->save($filepath);
-
- if ($render_to_browser) {
- $this->response->add_header('Cache-Control', 'cache, must-revalidate');
- $this->render_temporary_file(
- $filepath,
- $filename,
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
- );
- }
- }
-
- /**
- * Creates the body element id for this controller a given action.
- *
- * @param string $unconsumed_path Unconsumed path to extract action from
- * @return string
- */
- protected function getBodyElementIdForControllerAndAction($unconsumed_path)
- {
- // Extract action from unconsumed path segment
- [$action] = $this->extract_action_and_args($unconsumed_path);
-
- // Extract controller name from class name
- $controller = preg_replace('/Controller$/', '', get_class($this));
- $controller = Trails_Inflector::underscore($controller);
-
- // Build main parts of the body element id
- $body_id_parts = explode('/', $controller);
- $body_id_parts[] = $action;
-
- // Create and set body element id
- $body_id = implode('-', $body_id_parts);
-
- return $body_id;
- }
-}
diff --git a/app/controllers/studip_controller_properties_trait.php b/app/controllers/studip_controller_properties_trait.php
deleted file mode 100644
index 4e906fa..0000000
--- a/app/controllers/studip_controller_properties_trait.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-/**
- * This trait manages all variable assignments to the controller and templates.
- *
- * @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
- * @license GPL2 or any later version
- * @since Stud.IP 5.2
- */
-trait StudipControllerPropertiesTrait
-{
- /**
- * Stores the assigned variables.
- * @var array
- */
- protected $_template_variables = [];
-
- /**
- * Returns whether a variable is set.
- *
- * @param string $offset
- * @return bool
- */
- public function __isset(string $offset): bool
- {
- return isset($this->_template_variables[$offset]);
- }
-
- /**
- * Stores a variable.
- *
- * @param string $offset
- * @param mixed $value
- */
- public function __set(string $offset, $value): void
- {
- $this->_template_variables[$offset] = $value;
- }
-
- /**
- * Returns a previously set variable.
- *
- * @param string $offset
- * @return mixed
- */
- public function &__get(string $offset)
- {
- if (!isset($this->_template_variables[$offset])) {
- $this->_template_variables[$offset] = null;
- }
- return $this->_template_variables[$offset];
- }
-
- /**
- * Unsets a previously set variable
- *
- * @param string $offset
- */
- public function __unset(string $offset): void
- {
- unset($this->_template_variables[$offset]);
- }
-
- public function get_assigned_variables(): array
- {
- $variables = $this->_template_variables;
- $variables['controller'] = $this;
- return $variables;
- }
-}
diff --git a/app/controllers/studip_response.php b/app/controllers/studip_response.php
deleted file mode 100644
index 1c15326..0000000
--- a/app/controllers/studip_response.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-class StudipResponse extends Trails_Response
-{
- /**
- * Outputs this response to the client using "echo" and "header".
- *
- * This extension allows the body to be a callable and handles generators
- * by outputting the chunks yielded by the generator.
- */
- public function output()
- {
- if (isset($this->status)) {
- $this->send_header(
- "{$_SERVER['SERVER_PROTOCOL']} {$this->status} {$this->reason}",
- true,
- $this->status
- );
- }
-
- // Send headers
- foreach ($this->headers as $k => $v) {
- $this->send_header("{$k}: {$v}");
- }
-
- // Determine output
- if (is_callable($this->body)) {
- $output = call_user_func($this->body);
- } else {
- $output = $this->body;
- }
-
- if ($output instanceof Generator) {
- // Clear output buffer
- while (ob_get_level()) {
- ob_end_clean();
- }
-
- // Ensure generator will run to the end
- $abort = ignore_user_abort(true);
-
- // Output chunks yielded by generator
- foreach ($output as $chunk) {
- if (!connection_aborted()) {
- echo $chunk;
- flush();
- }
- }
-
- // Reset user abort to previous state
- ignore_user_abort($abort);
- } else {
- echo $output;
- }
- }
-}
diff --git a/app/controllers/vote.php b/app/controllers/vote.php
deleted file mode 100644
index 19f92a2..0000000
--- a/app/controllers/vote.php
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-
-# Lifter010: TODO
-/**
- * vote.php - Votecontroller controller
- *
- * 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.
- */
-
-class VoteController extends AuthenticatedController {
-
- public function display_action($range_id) {
-
- // Bind some params
- URLHelper::bindLinkParam('show_expired', $null1);
- URLHelper::bindLinkParam('preview', $null2);
- URLHelper::bindLinkParam('revealNames', $null3);
- URLHelper::bindLinkParam('sort', $null4);
-
- // Bind range_id
- $this->range_id = $range_id;
-
- $this->nobody = !$GLOBALS['user']->id || $GLOBALS['user']->id == 'nobody';
-
- /*
- * Insert vote
- */
- if ($vote = Request::get('vote')) {
- $vote = new Vote($vote);
- if (!$this->nobody && $vote && $vote->isRunning() && (!$vote->userVoted() || $vote->changeable)) {
- try {
- $vote->insertVote(Request::getArray('vote_answers'), $GLOBALS['user']->id);
- } catch (Exception $exc) {
- $GLOBALS['vote_message'][$vote->id] = MessageBox::error($exc->getMessage());
- }
- }
- }
-
- // Check if we need administration icons
- $this->admin = $range_id == $GLOBALS['user']->id || $GLOBALS['perm']->have_studip_perm('tutor', $range_id);
-
-
- // Load evaluations
- if (!$this->nobody) {
- $eval_db = new EvaluationDB();
- $this->evaluations = StudipEvaluation::findMany($eval_db->getEvaluationIDs($range_id, EVAL_STATE_ACTIVE));
- } else {
- $this->evaluations = [];
- }
- $show_votes[] = 'active';
- // Check if we got expired
- if (Request::get('show_expired')) {
- $show_votes[] = 'stopvis';
- if ($this->admin) {
- $this->evaluations = array_merge($this->evaluations, StudipEvaluation::findMany($eval_db->getEvaluationIDs($range_id, EVAL_STATE_STOPPED)));
- $show_votes[] = 'stopinvis';
- }
- }
-
- $this->votes = Vote::findBySQL('range_id = ? AND state IN (?) ORDER BY mkdate desc', [$range_id,$show_votes]);
- $this->visit();
-
- }
-
- function visit()
- {
- if ($GLOBALS['user']->id && $GLOBALS['user']->id != 'nobody' && Request::option('contentbox_open') && in_array(Request::option('contentbox_type'), words('vote eval'))) {
- object_set_visit(Request::option('contentbox_open'), Request::option('contentbox_type'));
- }
- }
-
- function visit_action()
- {
- $this->visit();
- $this->render_nothing();
- }
-
- /**
- * Determines if a vote should show its result
- *
- * @param Vote $vote the vote to check
- * @return boolean true if result should be shown
- */
- public function showResult($vote) {
- if (Request::submitted('change') && $vote->changeable) {
- return false;
- }
- return $vote->userVoted() || in_array($vote->id, Request::getArray('preview'));
- }
-
-}