diff --git a/app/controllers/course/history.php b/app/controllers/course/history.php new file mode 100644 index 0000000000000000000000000000000000000000..9a8e4e9492dd3089ef40fb53488b564a18974373 --- /dev/null +++ b/app/controllers/course/history.php @@ -0,0 +1,49 @@ +<?php +final class Course_HistoryController extends AuthenticatedController +{ + public function before_filter(&$action, &$args) + { + parent::before_filter($action, $args); + + if (!Context::isCourse()) { + throw new Exception('History view is only available for courses'); + } + if (!$GLOBALS['perm']->have_studip_perm('admin', Context::getId())) { + throw new AccessDeniedException(); + } + + Navigation::activateItem('/course/main/history'); + PageLayout::setTitle(_('Änderungsverlauf')); + } + + public function index_action() + { + $this->history = $this->getHistory(Context::get()); + } + + private function getHistory(Course $course): array + { + $result = []; + LogEvent::findEachBySQL( + function (LogEvent $event) use (&$result) { + if (!isset($result[$event->action_id])) { + $result[$event->action_id] = [ + 'name' => "{$event->action->name}: {$event->action->description}", + 'events' => [], + ]; + } + + $result[$event->action_id]['events'][] = $event; + }, + "? IN (affected_range_id, coaffected_range_id, user_id) ORDER BY mkdate DESC", + [$course->id] + ); + + $result = array_values($result); + usort($result, function ($a, $b) { + return strcasecmp($a['name'], $b['name']); + }); + + return $result; + } +} diff --git a/app/views/course/history/index.php b/app/views/course/history/index.php new file mode 100644 index 0000000000000000000000000000000000000000..42deca916ca5f193ef5e5cd947cb98d0d6343b79 --- /dev/null +++ b/app/views/course/history/index.php @@ -0,0 +1,45 @@ +<?php +$sanitizeEvent = function (LogEvent $event) { + $info = preg_replace('/chdate:\s+(\d+)\s+=>\s+(\d+)/', '', $event->formatEvent()); + $info = str_replace('admission_turnout', _('max. Teilnehmerzahl'), $info); + $info = str_replace('=>', '→', $info); + + return $info; + +}; +?> +<? if (!$history): ?> + <?= MessageBox::info(_('Es konnten keine Logeinträge gefunden werden.'))->hideClose() ?> +<? else: ?> + <table class="default collapsable"> + <colgroup> + <col style="width: 150px"> + <col> + </colgroup> + <? foreach ($history as $index => $type): ?> + <tbody <? if ($index > 0) echo 'class="collapsed"'; ?>> + <tr class="header-row"> + <th colspan="2" class="toggle-indicator"> + <a class="toggler"> + <?= htmlReady($type['name']) ?> + </a> + </th> + </tr> + <? foreach ($type['events'] as $event): ?> + <tr> + <td><?= strftime('%x %X', $event->mkdate) ?></td> + <td> + <?= $sanitizeEvent($event) ?> + <? if ($event->info && $GLOBALS['perm']->have_perm('root')): ?> + <br><?= _('Info') ?>: <?= htmlReady($event->info) ?> + <? endif ?> + <? if ($event->dbg_info && $GLOBALS['perm']->have_perm('root')): ?> + <br><?= _('Debug') ?>: <?= htmlReady($event->dbg_info) ?> + <? endif ?> + </td> + </tr> + <? endforeach ?> + </tbody> + <? endforeach ?> + </table> +<? endif; ?> diff --git a/lib/modules/CoreOverview.class.php b/lib/modules/CoreOverview.class.php index 39145aea83b6270e14747f94301436462b3cef55..fff3050a90005e44ef1f47cad33deb700b5bc3d9 100644 --- a/lib/modules/CoreOverview.class.php +++ b/lib/modules/CoreOverview.class.php @@ -100,6 +100,9 @@ class CoreOverview extends CorePlugin implements StudipModule if (!$sem_class['studygroup_mode']) { $navigation->addSubNavigation('details', new Navigation(_('Details'), 'dispatch.php/course/details/')); } + if ($GLOBALS['perm']->have_studip_perm('admin', $course_id)) { + $navigation->addSubNavigation('history', new Navigation(_('Änderungsverlauf'), 'dispatch.php/course/history')); + } } return ['main' => $navigation]; }