diff --git a/app/controllers/my_courses.php b/app/controllers/my_courses.php index e42b2c86387b2703548dc3e1ce35889ca0a09bbe..ee356164973d20dc8814c0952a34dfde7149ec70 100644 --- a/app/controllers/my_courses.php +++ b/app/controllers/my_courses.php @@ -81,8 +81,6 @@ class MyCoursesController extends AuthenticatedController PageLayout::setHelpKeyword('Basis.MeineVeranstaltungen'); PageLayout::setTitle(_('Meine Veranstaltungen')); - $this->sem_data = Semester::getAllAsArray(); - $sem_key = $this->getSemesterKey(); $group_field = $this->getGroupField(); @@ -115,89 +113,7 @@ class MyCoursesController extends AuthenticatedController } $this->setupSidebar($sem_key, $group_field, $this->check_for_new($sem_courses, $group_field)); - - $temp_courses = []; - $groups = []; - if (is_array($sem_courses)) { - foreach ($sem_courses as $_outer_index => $_outer) { - if ($group_field === 'sem_number') { - $_courses = []; - - foreach ($_outer as $course) { - $_courses[$course['seminar_id']] = $course; - if (!empty($course['children']) && is_array($course['children'])) { - foreach ($course['children'] as $child) { - $_courses[$child['seminar_id']] = $child; - } - } - } - - $groups[] = [ - 'id' => $_outer_index, - 'name' => (string)$this->sem_data[$_outer_index]['name'], - 'data' => [ - [ - 'id' => md5($_outer_index), - 'label' => false, - 'ids' => array_keys($_courses), - ], - ], - ]; - $temp_courses = array_merge($temp_courses, $_courses); - } else { - $count = 1; - $_groups = []; - foreach ($_outer as $_inner_index => $_inner) { - $_courses = []; - - foreach ($_inner as $course) { - $_courses[$course['seminar_id']] = $course; - if ($course['children']) { - foreach ($course['children'] as $child) { - $_courses[$child['seminar_id']] = $child; - } - } - } - - $label = $_inner_index; - if ($group_field === 'sem_tree_id' && !$label) { - $label = _('keine Zuordnung'); - } elseif ($group_field === 'gruppe') { - $label = _('Gruppe') . ' ' . $count++; - } - - $_groups[] = [ - 'id' => md5($_outer_index . $_inner_index), - 'label' => $label, - 'ids' => array_keys($_courses), - ]; - - $temp_courses = array_merge($temp_courses, $_courses); - } - - $groups[] = [ - 'id' => $_outer_index, - 'name' => (string)$this->sem_data[$_outer_index]['name'], - 'data' => $_groups, - ]; - } - } - } - - $data = [ - 'courses' => $this->sanitizeNavigations(array_map([$this, 'convertCourse'], $temp_courses)), - 'groups' => $groups, - 'user_id' => $GLOBALS['user']->id, - 'config' => [ - 'allow_dozent_visibility' => Config::get()->ALLOW_DOZENT_VISIBILITY, - 'open_groups' => array_values($GLOBALS['user']->cfg->MY_COURSES_OPEN_GROUPS), - 'sem_number' => Config::get()->IMPORTANT_SEMNUMBER, - 'display_type' => $GLOBALS['user']->cfg->MY_COURSES_TILED_DISPLAY ? 'tiles' : 'tables', - 'responsive_type' => $GLOBALS['user']->cfg->MY_COURSES_TILED_DISPLAY_RESPONSIVE ? 'tiles' : 'tables', - 'navigation_show_only_new' => $GLOBALS['user']->cfg->MY_COURSES_SHOW_NEW_ICONS_ONLY, - 'group_by' => $this->getGroupField(), - ], - ]; + $data = $this->getMyCoursesData($sem_courses, $group_field); PageLayout::addHeadElement( 'script', @@ -768,6 +684,119 @@ class MyCoursesController extends AuthenticatedController $this->redirect($this->url_for('my_courses')); } + /** + * Get the data array for presenting the course list in the portal widget. + */ + public function getPortalWidgetData() + { + $sem_key = $this->getSemesterKey(); + $group_field = $this->getGroupField(); + + $sem_courses = MyRealmModel::getPreparedCourses($sem_key, [ + 'group_field' => $group_field, + 'order_by' => null, + 'order' => 'asc', + 'studygroups_enabled' => Config::get()->MY_COURSES_ENABLE_STUDYGROUPS, + 'deputies_enabled' => Config::get()->DEPUTIES_ENABLE, + ]); + + return $this->getMyCoursesData($sem_courses, $group_field); + } + + /** + * Get the data array for presenting the course list in Vue. + * + * @param array $sem_courses + * @param string $group_field + */ + private function getMyCoursesData($sem_courses, $group_field) + { + $sem_data = Semester::getAllAsArray(); + $temp_courses = []; + $groups = []; + + if (is_array($sem_courses)) { + foreach ($sem_courses as $_outer_index => $_outer) { + if ($group_field === 'sem_number') { + $_courses = []; + + foreach ($_outer as $course) { + $_courses[$course['seminar_id']] = $course; + if (!empty($course['children']) && is_array($course['children'])) { + foreach ($course['children'] as $child) { + $_courses[$child['seminar_id']] = $child; + } + } + } + + $groups[] = [ + 'id' => $_outer_index, + 'name' => (string) $sem_data[$_outer_index]['name'], + 'data' => [ + [ + 'id' => md5($_outer_index), + 'label' => false, + 'ids' => array_keys($_courses), + ], + ], + ]; + $temp_courses = array_merge($temp_courses, $_courses); + } else { + $count = 1; + $_groups = []; + foreach ($_outer as $_inner_index => $_inner) { + $_courses = []; + + foreach ($_inner as $course) { + $_courses[$course['seminar_id']] = $course; + if ($course['children']) { + foreach ($course['children'] as $child) { + $_courses[$child['seminar_id']] = $child; + } + } + } + + $label = $_inner_index; + if ($group_field === 'sem_tree_id' && !$label) { + $label = _('keine Zuordnung'); + } elseif ($group_field === 'gruppe') { + $label = _('Gruppe') . ' ' . $count++; + } + + $_groups[] = [ + 'id' => md5($_outer_index . $_inner_index), + 'label' => $label, + 'ids' => array_keys($_courses), + ]; + + $temp_courses = array_merge($temp_courses, $_courses); + } + + $groups[] = [ + 'id' => $_outer_index, + 'name' => (string) $sem_data[$_outer_index]['name'], + 'data' => $_groups, + ]; + } + } + } + + return [ + 'courses' => $this->sanitizeNavigations(array_map([$this, 'convertCourse'], $temp_courses)), + 'groups' => $groups, + 'user_id' => $GLOBALS['user']->id, + 'config' => [ + 'allow_dozent_visibility' => Config::get()->ALLOW_DOZENT_VISIBILITY, + 'open_groups' => array_values($GLOBALS['user']->cfg->MY_COURSES_OPEN_GROUPS), + 'sem_number' => Config::get()->IMPORTANT_SEMNUMBER, + 'display_type' => $GLOBALS['user']->cfg->MY_COURSES_TILED_DISPLAY ? 'tiles' : 'tables', + 'responsive_type' => $GLOBALS['user']->cfg->MY_COURSES_TILED_DISPLAY_RESPONSIVE ? 'tiles' : 'tables', + 'navigation_show_only_new' => $GLOBALS['user']->cfg->MY_COURSES_SHOW_NEW_ICONS_ONLY, + 'group_by' => $this->getGroupField(), + ], + ]; + } + /** * Get widget for grouping selected courses (e.g. by colors, ...) * diff --git a/db/migrations/5.3.7_add_my_courses_widget.php b/db/migrations/5.3.7_add_my_courses_widget.php new file mode 100644 index 0000000000000000000000000000000000000000..5837e35b7ebd24d9d9173a0d628833e5d562a7c9 --- /dev/null +++ b/db/migrations/5.3.7_add_my_courses_widget.php @@ -0,0 +1,44 @@ +<?php + +class AddMyCoursesWidget extends Migration +{ + public function description() + { + return 'add MyCoursesWidget (if not previously installed)'; + } + + public function up() + { + $db = DBManager::get(); + + // check for previous installation + $plugin_id = $db->fetchColumn('SELECT pluginid FROM plugins WHERE pluginclassname = ?', ['MyCoursesWidget']); + + if ($plugin_id) { + $db->execute("UPDATE plugins SET pluginpath = '' WHERE pluginid = ?", [$plugin_id]); + } else { + // get position + $pos = $db->fetchColumn("SELECT MAX(navigationpos) + 1 FROM plugins WHERE plugintype = 'PortalPlugin'"); + + // install as portal plugin + $sql = "INSERT INTO plugins (pluginclassname, pluginname, plugintype, enabled, navigationpos) VALUES (?)"; + $db->execute($sql, [['MyCoursesWidget', 'MyCoursesWidget', 'PortalPlugin', 'yes', $pos]]); + + $sql = "INSERT INTO roles_plugins (roleid, pluginid) + SELECT roleid, ? FROM roles WHERE `system` = 'y' AND rolename != 'Nobody'"; + $db->execute($sql, [$db->lastInsertId()]); + } + } + + public function down() + { + $db = DBManager::get(); + + $plugin_id = $db->fetchColumn('SELECT pluginid FROM plugins WHERE pluginclassname = ?', ['MyCoursesWidget']); + + $db->execute('DELETE FROM widget_default WHERE pluginid = ?', [$plugin_id]); + $db->execute('DELETE FROM widget_user WHERE pluginid = ?', [$plugin_id]); + $db->execute('DELETE FROM roles_plugins WHERE pluginid = ?', [$plugin_id]); + $db->execute('DELETE FROM plugins WHERE pluginid = ?', [$plugin_id]); + } +} diff --git a/lib/modules/MyCoursesWidget.php b/lib/modules/MyCoursesWidget.php new file mode 100644 index 0000000000000000000000000000000000000000..81aceeda0d7103bed8983241955866fe1f629cdc --- /dev/null +++ b/lib/modules/MyCoursesWidget.php @@ -0,0 +1,37 @@ +<?php +/** + * My courses widget. Displays a user's courses on the start page. + * + * @author Viktoria Wiebe <viktoria.wiebe@web.de> + * @license GPL2 or any later version + * @since Stud.IP 5.3 + */ + +require_once 'app/controllers/my_courses.php'; + +class MyCoursesWidget extends CorePlugin implements PortalPlugin +{ + public function getPluginName() + { + return _('Meine Veranstaltungen'); + } + + public function getMetadata() + { + return [ + 'description' => _('Dieses Widget zeigt eine Liste Ihrer Veranstaltungen an.') + ]; + } + + public function getPortalTemplate() + { + // get the MyCoursesController in order to prepare the correct data for the overview + $controller = app(MyCoursesController::class, ['dispatcher' => app(\Trails_Dispatcher::class)]); + $data = $controller->getPortalWidgetData(); + + // add the json data to the head so vue can grab it + PageLayout::addHeadElement('script', [], 'STUDIP.MyCoursesData = ' . json_encode($data) . ';'); + + return $GLOBALS['template_factory']->open('start/my_courses'); + } +} diff --git a/templates/start/my_courses.php b/templates/start/my_courses.php new file mode 100644 index 0000000000000000000000000000000000000000..cf060340290656499177df444ea5f5764f502a4e --- /dev/null +++ b/templates/start/my_courses.php @@ -0,0 +1,3 @@ +<div class="my-courses-vue-app" style="margin: 10px;"> + <my-courses /> +</div>