diff options
| author | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
|---|---|---|
| committer | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
| commit | 4459dd7917f4d1c34f40bb68f0e991e9c3d53e4c (patch) | |
| tree | 5c07151ae61276d334e88f6309c30d439a85c12e /app/controllers/course | |
| parent | da0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff) | |
| parent | 97a188592c679890a25c37ab78463add76a52ff7 (diff) | |
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'app/controllers/course')
26 files changed, 375 insertions, 235 deletions
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')); |
