Skip to content
Snippets Groups Projects
Commit c1b760e7 authored by Viktoria Wiebe's avatar Viktoria Wiebe Committed by Elmar Ludwig
Browse files

implementation of course overview portal widget, fixes #1080

Closes #1080

Merge request studip/studip!757
parent 470d57a8
No related branches found
No related tags found
No related merge requests found
...@@ -81,8 +81,6 @@ class MyCoursesController extends AuthenticatedController ...@@ -81,8 +81,6 @@ class MyCoursesController extends AuthenticatedController
PageLayout::setHelpKeyword('Basis.MeineVeranstaltungen'); PageLayout::setHelpKeyword('Basis.MeineVeranstaltungen');
PageLayout::setTitle(_('Meine Veranstaltungen')); PageLayout::setTitle(_('Meine Veranstaltungen'));
$this->sem_data = Semester::getAllAsArray();
$sem_key = $this->getSemesterKey(); $sem_key = $this->getSemesterKey();
$group_field = $this->getGroupField(); $group_field = $this->getGroupField();
...@@ -115,89 +113,7 @@ class MyCoursesController extends AuthenticatedController ...@@ -115,89 +113,7 @@ class MyCoursesController extends AuthenticatedController
} }
$this->setupSidebar($sem_key, $group_field, $this->check_for_new($sem_courses, $group_field)); $this->setupSidebar($sem_key, $group_field, $this->check_for_new($sem_courses, $group_field));
$data = $this->getMyCoursesData($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(),
],
];
PageLayout::addHeadElement( PageLayout::addHeadElement(
'script', 'script',
...@@ -768,6 +684,119 @@ class MyCoursesController extends AuthenticatedController ...@@ -768,6 +684,119 @@ class MyCoursesController extends AuthenticatedController
$this->redirect($this->url_for('my_courses')); $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, ...) * Get widget for grouping selected courses (e.g. by colors, ...)
* *
......
<?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]);
}
}
<?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');
}
}
<div class="my-courses-vue-app" style="margin: 10px;">
<my-courses />
</div>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment