diff options
Diffstat (limited to 'app/controllers/course')
| -rw-r--r-- | app/controllers/course/forum/admin.php | 126 | ||||
| -rw-r--r-- | app/controllers/course/forum/area.php | 80 | ||||
| -rw-r--r-- | app/controllers/course/forum/forum_controller.php | 45 | ||||
| -rw-r--r-- | app/controllers/course/forum/index.php | 835 | ||||
| -rw-r--r-- | app/controllers/course/messenger.php | 78 |
5 files changed, 1164 insertions, 0 deletions
diff --git a/app/controllers/course/forum/admin.php b/app/controllers/course/forum/admin.php new file mode 100644 index 0000000..a7fff71 --- /dev/null +++ b/app/controllers/course/forum/admin.php @@ -0,0 +1,126 @@ +<?php + +/* + * Copyright (C) 2011 - Till Glöggler <tgloeggl@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. + */ + +require_once 'forum_controller.php'; + +class Course_Forum_AdminController extends ForumController +{ + /* * * * * * * * * * * * * * * * * * * * */ + /* * * A D M I N M E T H O D S * * */ + /* * * * * * * * * * * * * * * * * * * * */ + + /** + * show the administration page for mass-editing forum-entries + */ + function index_action() + { + ForumPerm::check('admin', $this->getId()); + $nav = Navigation::getItem('course/forum2'); + $nav->setImage(Icon::create('forum', 'info')); + Navigation::activateItem('course/forum2/admin'); + + $list = ForumEntry::getList('flat', $this->getId()); + + // sort by cat + $new_list = []; + // iterate over all categories and add the belonging areas to them + foreach ($categories = ForumCat::getListWithAreas($this->getId(), false) as $category) { + if ($category['topic_id']) { + $new_list[$category['category_id']][$category['topic_id']] = $list['list'][$category['topic_id']]; + unset($list['list'][$category['topic_id']]); + } else if (ForumPerm::has('add_area', $this->seminar_id)) { + $new_list[$category['category_id']] = []; + } + $this->categories[$category['category_id']] = $category['entry_name']; + } + + if (!empty($list['list'])) { + // append the remaining entries to the standard category + $new_list[$this->getId()] = array_merge((array)$new_list[$this->getId()], $list['list']); + } + + $this->list = $new_list; + + } + + /** + * show child entries for the passed entry + * + * @param string $parent_id id of entry to get the childs for + */ + function childs_action($parent_id) + { + $this->set_layout(null); + + // if the parent-id is a category-id, get all areas for this category + if ($cat = ForumCat::get($parent_id)) { + ForumPerm::check('admin', $cat['seminar_id']); // check the perms in the categories seminar + $this->entries = ForumEntry::parseEntries(ForumCat::getAreas($parent_id)); + } else { + ForumPerm::check('admin', $this->getId(), $parent_id); + $entries = ForumEntry::getList('flat', $parent_id); + $this->entries = $entries['list']; + } + } + + /** + * move the submitted topics[] to the passed destination + * + * @param string $destination id of seminar to move topics to + */ + function move_action($destination) + { + // check if destination is a category_id. if yes, use seminar_id instead + if (ForumCat::get($destination)) { + $category_id = $destination; + $destination = $this->getId(); + } + + ForumPerm::check('admin', $this->getId(), $destination); + + foreach (Request::getArray('topics') as $topic_id) { + // make sure every passed topic_id is checked against the current seminar + ForumPerm::check('admin', $this->getId(), $topic_id); + + // if the source is an area and the target a category, just move this area to the category + $entry = ForumEntry::getEntry($topic_id); + if ($entry['depth'] == 1 && $category_id) { + ForumCat::removeArea($topic_id); + ForumCat::addArea($category_id, $topic_id); + } else { + // first step: move the whole topic with all childs + ForumEntry::move($topic_id, $destination); + + // if the current topic id is an area, remove it from any categories + ForumCat::removeArea($topic_id); + + // second step: move all to deep childs a level up (depth > 3) + $data = ForumEntry::getList('depth_to_large', $topic_id); + foreach ($data['list'] as $entry) { + $path = ForumEntry::getPathToPosting($entry['topic_id']); + array_shift($path); // Category + array_shift($path); // Area + + $thread = array_shift($path); // Thread + + ForumEntry::move($entry['topic_id'], $thread['id']); + } + + // add entry to passed category when moving to the top + if ($category_id) { + ForumCat::addArea($category_id, $topic_id); + } + } + } + + $this->render_nothing(); + } +} diff --git a/app/controllers/course/forum/area.php b/app/controllers/course/forum/area.php new file mode 100644 index 0000000..a93860a --- /dev/null +++ b/app/controllers/course/forum/area.php @@ -0,0 +1,80 @@ +<?php + +/* + * Copyright (C) 2011 - Till Glöggler <tgloeggl@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. + */ + +require_once 'forum_controller.php'; + +class Course_Forum_AreaController extends ForumController +{ + function add_action($category_id) + { + ForumPerm::check('add_area', $this->getId()); + + $new_id = md5(uniqid(rand())); + + $name = Request::get('name', _('Kein Titel')); + $content = Request::get('content'); + + ForumEntry::insert([ + 'topic_id' => $new_id, + 'seminar_id' => $this->getId(), + 'user_id' => $GLOBALS['user']->id, + 'name' => $name, + 'content' => $content, + 'author' => get_fullname($GLOBALS['user']->id), + 'author_host' => ($GLOBALS['user']->id == 'nobody') ? getenv('REMOTE_ADDR') : '' + ], $this->getId()); + + ForumCat::addArea($category_id, $new_id); + + if (Request::isXhr()) { + $this->set_layout(null); + $entries = ForumEntry::parseEntries([ForumEntry::getEntry($new_id)]); + $this->entry = array_pop($entries); + $this->visitdate = ForumVisit::getLastVisit($this->getId()); + } else { + $this->redirect('course/forum/index/index/'); + } + } + + function edit_action($area_id) + { + ForumPerm::check('edit_area', $this->getId(), $area_id); + + if (Request::isAjax()) { + ForumEntry::update($area_id, Request::get('name'), Request::get('content')); + $this->render_json(['content' => ForumEntry::killFormat(ForumEntry::killEdit(Request::get('content')))]); + } else { + ForumEntry::update($area_id, Request::get('name'), Request::get('content')); + $this->flash['messages'] = ['success' => _('Die Änderungen am Bereich wurden gespeichert.')]; + $this->redirect('course/forum/index/index'); + } + + } + + function save_order_action() + { + ForumPerm::check('sort_area', $this->getId()); + + foreach (Request::getArray('areas') as $category_id => $areas) { + $pos = 0; + foreach ($areas as $area_id) { + ForumPerm::checkCategoryId($this->getId(), $category_id); + ForumPerm::check('sort_area', $this->getId(), $area_id); + + ForumCat::addArea($category_id, $area_id); + ForumCat::setAreaPosition($area_id, $pos); + $pos++; + } + } + + $this->render_nothing(); + } +} diff --git a/app/controllers/course/forum/forum_controller.php b/app/controllers/course/forum/forum_controller.php new file mode 100644 index 0000000..1812be9 --- /dev/null +++ b/app/controllers/course/forum/forum_controller.php @@ -0,0 +1,45 @@ +<?php + +class ForumController extends StudipController { + protected $with_session = true; + + /* * * * * * * * * * * * * * * * * * * * * * * * * */ + /* * * * * H E L P E R F U N C T I O N S * * * * */ + /* * * * * * * * * * * * * * * * * * * * * * * * * */ + function getId() + { + return ForumHelpers::getSeminarId(); + } + + /** + * Common code for all actions: set default layout and page title. + * + * @param type $action + * @param type $args + */ + function before_filter(&$action, &$args) + { + $this->validate_args($args, ['option', 'option']); + + parent::before_filter($action, $args); + + $this->flash = Trails_Flash::instance(); + + // Set help keyword for Stud.IP's user-documentation and page title + PageLayout::setHelpKeyword('Basis.Forum'); + PageLayout::setTitle(Context::getHeaderLine() .' - '. _('Forum')); + + // the default for displaying timestamps + $this->time_format_string = "%a %d. %B %Y, %H:%M"; + $this->time_format_string_short = "%d.%m.%Y, %H:%M"; + + //$this->getId() depends on Context::get() + checkObject(); + ForumVisit::setVisit($this->getId()); + if (Request::int('page')) { + ForumHelpers::setPage(Request::int('page')); + } + + $this->seminar_id = $this->getId(); + } +} diff --git a/app/controllers/course/forum/index.php b/app/controllers/course/forum/index.php new file mode 100644 index 0000000..c3b665e --- /dev/null +++ b/app/controllers/course/forum/index.php @@ -0,0 +1,835 @@ +<?php + +/* + * Copyright (C) 2011 - Till Glöggler <tgloeggl@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. + */ + +require_once 'forum_controller.php'; + +class Course_Forum_IndexController extends ForumController +{ + /* * * * * * * * * * * * * * * * * * * * * * * * * */ + /* V I E W - A C T I O N S */ + /* * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * redirect to correct page (overview or newest entries), + * depending on whether there are any entries. + */ + function enter_seminar_action() { + if (ForumPerm::has('fav_entry', $this->getId()) + && ForumVisit::getCount($this->getId(), ForumVisit::getVisit($this->getId())) > 0) { + $this->redirect('course/forum/index/newest'); + } else { + $this->redirect('course/forum/index/index'); + } + } + + /** + * the main action for the forum. May be called with a topic_id to be displayed + * and optionally the page to display + * + * @param type $topic_id the topic to display, defaults to the main + * view of the current seminar + * @param type $page the page to be displayed (for thread-view) + */ + function index_action($topic_id = null, $page = null) + { + $nav = Navigation::getItem('course/forum2'); + $nav->setImage(Icon::create('forum', 'info')); + Navigation::activateItem('course/forum2/index'); + + // check, if the root entry is present + ForumEntry::checkRootEntry($this->getId()); + + /* * * * * * * * * * * * * * * * * * * + * V A R I A B L E N F U E L L E N * + * * * * * * * * * * * * * * * * * * */ + + $this->section = 'index'; + + $this->topic_id = $topic_id ? $topic_id : $this->getId(); + $this->constraint = ForumEntry::getConstraints($this->topic_id); + + // check if there has been submitted an invalid id and use seminar_id in case + if (!$this->constraint) { + $this->topic_id = $this->getId(); + $this->constraint = ForumEntry::getConstraints($this->topic_id); + } + + $this->highlight_topic = Request::option('highlight_topic', null); + + // set page to which we shall jump + if ($page) { + ForumHelpers::setPage($page); + } + + // we do not crawl deeper than level 2, we show a page chooser instead + if ($this->constraint['depth'] > 2) { + ForumHelpers::setPage(ForumEntry::getPostingPage($this->topic_id, $this->constraint)); + + $path = ForumEntry::getPathToPosting($this->topic_id); + array_shift($path);array_shift($path);$path_element = array_shift($path); + $this->child_topic = $this->topic_id; + $this->topic_id = $path_element['id']; + $this->constraint = ForumEntry::getConstraints($this->topic_id); + } + + // check if the topic_id matches the currently selected seminar + ForumPerm::checkTopicId($this->getId(), $this->topic_id); + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * B E R E I C H E / T H R E A D S / P O S T I N G S L A D E N * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + // load list of areas for use in thread-movement + if (ForumPerm::has('move_thread', $this->getId())) { + $this->areas = ForumEntry::getList('flat', $this->getId()); + } + + if ($this->constraint['depth'] > 1) { // POSTINGS + $list = ForumEntry::getList('postings', $this->topic_id); + if (!empty($list['list'])) { + $this->postings = $list['list']; + $this->number_of_entries = $list['count']; + } + } else { + if ($this->constraint['depth'] == 0) { // BEREICHE + $list = ForumEntry::getList('area', $this->topic_id); + } else { + $list = ForumEntry::getList('list', $this->topic_id); + } + + if ($this->constraint['depth'] == 0) { // BEREICHE + $new_list = []; + // iterate over all categories and add the belonging areas to them + foreach ($categories = ForumCat::getListWithAreas($this->getId(), false) as $category) { + if ($category['topic_id']) { + $new_list[$category['category_id']][$category['topic_id']] = $list['list'][$category['topic_id']]; + unset($list['list'][$category['topic_id']]); + } else if (ForumPerm::has('add_area', $this->seminar_id)) { + $new_list[$category['category_id']] = []; + } + $this->categories[$category['category_id']] = $category['entry_name']; + } + + if (!empty($list['list'])) { + // append the remaining entries to the standard category + $new_list[$this->getId()] = array_merge((array)$new_list[$this->getId()], $list['list']); + } + + // check, if there are any orphaned entries + foreach ($new_list as $key1 => $list_item) { + foreach ($list_item as $key2 => $contents) { + if (empty($contents)) { + // remove the orphaned entry from the list and from the database + unset($new_list[$key1][$key2]); + ForumCat::removeArea($key2); + } + } + } + + $this->list = $new_list; + + } else if ($this->constraint['depth'] == 1) { // THREADS + if (!empty($list['list'])) { + $this->list = [$list['list']]; + } + } + $this->number_of_entries = $list['count']; + } + + // set the visit-date and get the stored last_visitdate + $this->visitdate = ForumVisit::getLastVisit($this->getId()); + + $this->seminar_id = $this->getId(); + + // highlight text if passed some words to highlight + if (Request::getArray('highlight')) { + $this->highlight = Request::optionArray('highlight'); + } + + if (($this->edit_posting = Request::get('edit_posting', null)) + && !ForumPerm::hasEditPerms($this->edit_posting)) { + $this->edit_posting = null; + } + + // trigger a javascript action, like creating an answer or citing a thread + if (Request::submitted('answer')) { + $this->js = 'answer'; + } else if (Request::option('cite')) { + $this->js = 'cite'; + $this->cite_id = $topic_id; + } + + } + + /** + * show newest entries + * + * @param int $page show entries on submitted page + */ + function newest_action($page = null) + { + $nav = Navigation::getItem('course/forum2'); + $nav->setImage(Icon::create('forum', 'info')); + Navigation::activateItem('course/forum2/newest'); + + // set page to which we shall jump + if ($page) { + ForumHelpers::setPage($page); + } + + $this->section = 'newest'; + $this->topic_id = $this->getId(); + + // set the visitdate of the seminar as the last visitdate + $this->visitdate = ForumVisit::getLastVisit($this->getId()); + + $list = ForumEntry::getList('newest', $this->topic_id); + $this->postings = $list['list']; + $this->number_of_entries = $list['count']; + $this->show_full_path = true; + + if (empty($this->postings)) { + $this->no_entries = true; + } + + $this->render_action('index'); + } + + /** + * show all latest entries as flat list + * + * @param int $page show entries on submitted page + */ + function latest_action($page = null) + { + $nav = Navigation::getItem('course/forum2'); + $nav->setImage(Icon::create('forum', 'info')); + Navigation::activateItem('course/forum2/latest'); + + // set page to which we shall jump + if ($page) { + ForumHelpers::setPage($page); + } + + $this->section = 'latest'; + $this->topic_id = $this->getId(); + + // set the visitdate of the seminar as the last visitdate + $this->visitdate = ForumVisit::getLastVisit($this->getId()); + + $list = ForumEntry::getList('latest', $this->topic_id); + $this->postings = $list['list']; + $this->number_of_entries = $list['count']; + $this->show_full_path = true; + + if (empty($this->postings)) { + $this->no_entries = true; + } + + $this->render_action('index'); + } + + /** + * show the current users favorized entries + * + * @param int $page show entries on submitted page + */ + function favorites_action($page = null) + { + $nav = Navigation::getItem('course/forum2'); + $nav->setImage(Icon::create('forum', 'info')); + Navigation::activateItem('course/forum2/favorites'); + + // set page to which we shall jump + if ($page) { + ForumHelpers::setPage($page); + } + + $this->section = 'favorites'; + $this->topic_id = $this->getId(); + + $list = ForumEntry::getList('favorites', $this->topic_id); + $this->postings = $list['list']; + $this->number_of_entries = $list['count']; + $this->show_full_path = true; + + if (empty($this->postings)) { + $this->no_entries = true; + } + + // exploit the visitdate for this view + $this->visitdate = ForumVisit::getLastVisit($this->getId()); + + $this->render_action('index'); + } + + /** + * show search results + * + * @param int $page show entries on submitted page + */ + function search_action($page = null) + { + if (Request::submitted('reset-search')) { + $this->redirect('index'); + return; + } + + ForumPerm::check('search', $this->getId()); + + $nav = Navigation::getItem('course/forum2'); + $nav->setImage(Icon::create('forum', 'info')); + Navigation::activateItem('course/forum2/index'); + + // set page to which we shall jump + if ($page) { + ForumHelpers::setPage($page); + } + + $this->section = 'search'; + $this->topic_id = $this->getId(); + $this->show_full_path = true; + + // parse filter-options + foreach (['search_title', 'search_content', 'search_author'] as $option) { + $this->options[$option] = Request::option($option); + } + + $this->searchfor = Request::get('searchfor'); + if (mb_strlen($this->searchfor) < 3) { + $this->flash['messages'] = ['error' => _('Ihr Suchbegriff muss mindestens 3 Zeichen lang sein und darf nur Buchstaben und Zahlen enthalten!')]; + } else { + // get search-results + $list = ForumEntry::getSearchResults($this->getId(), $this->searchfor, $this->options); + + $this->postings = $list['list']; + $this->number_of_entries = $list['count']; + $this->highlight = $list['highlight']; + + if (empty($this->postings)) { + $this->flash['messages'] = ['info' => _('Es wurden keine Beiträge gefunden, die zu Ihren Suchkriterien passen!')]; + } + } + + // exploit the visitdate for this view + $this->visitdate = ForumVisit::getLastVisit($this->getId()); + + $this->render_action('index'); + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * */ + /* * * * P O S T I N G - A C T I O N S * * * */ + /* * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * this action renders a preview of the submitted text + */ + function preview_action() { + if (Request::isXhr()) { + $this->set_content_type('text/html; charset=UTF-8'); + $this->render_text(formatReady(transformBeforeSave(Request::get('posting')))); + } else { + $this->render_text( + ForumEntry::getContentAsHtml( + transformBeforeSave(Request::get('posting')) + ) + ); + } + } + + /** + * Add a new entry. Has a simple spambot protection and checks + * the parent_id to add the entry to, throwing an exception if missing. + * + * @throws Exception + */ + function add_entry_action() + { + CSRFProtection::verifyUnsafeRequest(); + // Schutz vor Spambots - diese füllen meistens alle Felder aus, auch "versteckte". + // Ist dieses Feld gefüllt, war das vermutlich kein Mensch + if (Request::get('nixda')) { + throw new Exception('Access denied!'); + } + + if (!$parent_id = Request::option('parent')) { + throw new Exception('missing seminar_id/topic_id while adding a new entry!'); + } + + if ($this->seminar_id == $parent_id) { + ForumPerm::check('add_area', $this->getId(), $parent_id); + } else { + ForumPerm::check('add_entry', $this->getId(), $parent_id); + } + + $constraints = ForumEntry::getConstraints($parent_id); + + // if we are answering/citing a posting, we want to add it to the thread + // (which is the parent of passed posting id) + if ($constraints['depth'] == 3) { + $parent_id = ForumEntry::getParentTopicId($parent_id); + } + + $new_id = md5(uniqid(rand())); + + if ($GLOBALS['user']->id == 'nobody') { + $fullname = Request::get('author', 'unbekannt'); + } else { + $fullname = get_fullname($GLOBALS['user']->id); + } + + ForumEntry::insert([ + 'topic_id' => $new_id, + 'seminar_id' => $this->getId(), + 'user_id' => $GLOBALS['user']->id, + 'name' => Request::get('name') ?: '', + 'content' => Studip\Markup::purifyHtml(Request::get('content')), + 'author' => $fullname, + 'author_host' => ($GLOBALS['user']->id == 'nobody') ? getenv('REMOTE_ADDR') : '', + 'anonymous' => Config::get()->FORUM_ANONYMOUS_POSTINGS ? Request::get('anonymous') ? : 0 : 0 + ], $parent_id); + + $this->flash['notify'] = $new_id; + + $this->redirect('course/forum/index/index/' . $new_id .'#'. $new_id); + } + + /** + * Delete the submitted entry. + * + * @param string $topic_id the entry to delete + */ + function delete_entry_action($topic_id) + { + // get the page of the posting to be able to jump there again + $page = ForumEntry::getPostingPage($topic_id); + URLHelper::addLinkParam('page', $page); + + if (ForumPerm::hasEditPerms($topic_id) || ForumPerm::check('remove_entry', $this->getId(), $topic_id)) { + $path = ForumEntry::getPathToPosting($topic_id); + $topic = array_pop($path); + $parent = array_pop($path); + + if ($topic_id != $this->getId()) { + // only delete directly if passed by ajax, otherwise ask for confirmation + if (Request::isXhr() || Request::isPost() || Request::get('approve_delete')) { + CSRFProtection::verifyUnsafeRequest(); + ForumEntry::delete($topic_id); + $this->flash['messages'] = ['success' => sprintf(_('Der Eintrag %s wurde gelöscht!'), $topic['name'])]; + } else { + $this->flash['messages'] = ['info_html' => + sprintf(_('Sind sie sicher dass Sie den Eintrag %s löschen möchten?'), $topic['name']) + . '<br>'. \Studip\LinkButton::createAccept(_('Ja'), $this->url_for('course/forum/index/delete_entry/'. $topic_id .'?approve_delete=1')) + . \Studip\LinkButton::createCancel(_('Nein'), $this->url_for('course/forum/index/index/'. ForumEntry::getParentTopicId($topic_id) .'/'. $page)) + ]; + } + } else { + $this->flash['messages'] = ['success' => _('Sie können nicht die gesamte Veranstaltung löschen!')]; + } + } + + if (Request::isXhr()) { + $this->render_template('course/forum/messages'); + $this->flash['messages'] = null; + } else { + $this->redirect('course/forum/index/index/' . $parent['id'] .'/'. $page); + } + } + + /** + * Update the submitted entry. + * + * @param string $topic_id id of the entry to update + * @throws AccessDeniedException + */ + function update_entry_action($topic_id) + { + CSRFProtection::verifyUnsafeRequest(); + + $name = Request::get('name', _('Kein Titel')); + $content = Studip\Markup::purifyHtml(Request::get('content', _('Keine Beschreibung'))); + + ForumPerm::check('add_entry', $this->getId(), $topic_id); + + if (ForumPerm::hasEditPerms($topic_id)) { + ForumEntry::update($topic_id, $name, $content); + } else { + throw new AccessDeniedException(_('Sie haben keine Berechtigung, diesen Eintrag zu editieren!')); + } + + if (Request::isXhr()) { + $this->render_text(json_encode([ + 'name' => htmlReady($name), + 'content' => formatReady($content) + ])); + } else { + $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id); + } + } + + /** + * Move the submitted thread to the submitted parent + * + * @param string $thread_id the thread to move + * @param string $destination the threads new parent + */ + function move_thread_action($thread_id, $destination) { + ForumPerm::check('move_thread', $this->getId(), $thread_id); + ForumPerm::check('move_thread', $this->getId(), $destination); + + $current_area = ForumEntry::getParentTopicId($thread_id); + + ForumEntry::move($thread_id, $destination); + + $this->redirect('course/forum/index/index/' . $current_area .'/'. ForumHelpers::getPage()); + } + + /** + * Mark the submitted entry as favorite + * + * @param string $topic_id the entry to mark + */ + function set_favorite_action($topic_id) + { + ForumPerm::check('fav_entry', $this->getId(), $topic_id); + + ForumFavorite::set($topic_id); + + if (Request::isXhr()) { + $this->topic_id = $topic_id; + $this->favorite = true; + $this->render_template('course/forum/index/_favorite'); + } else { + $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id); + } + } + + /** + * Remove the submtted entry as favorite + * + * @param string $topic_id the entry to unmark + */ + function unset_favorite_action($topic_id) { + ForumPerm::check('fav_entry', $this->getId(), $topic_id); + + ForumFavorite::remove($topic_id); + + if (Request::isXhr()) { + $this->topic_id = $topic_id; + $this->favorite = false; + $this->render_template('course/forum/index/_favorite'); + } else { + $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id); + } + } + + /** + * Jump to page in the entries of the submitted parent-entry + * denoted by the submitted context (section) + * + * @param string $topic_id the parent-topic to goto + * @param string $section the type of view (one of index/search) + * @param int $page the page to jump to + */ + function goto_page_action($topic_id, $section, $page) + { + switch ($section) { + case 'index': + $this->redirect('course/forum/index/index/' . $topic_id .'/'. (int)$page .'#'. $topic_id); + break; + + case 'search': + $optionlist = []; + + foreach (['search_title', 'search_content', 'search_author'] as $option) { + if (Request::option($option)) { + $optionlist[] = $option .'='. 1; + } + } + + $this->redirect('course/forum/index/'. $section .'/'. (int)$page + .'/?searchfor='. Request::get('searchfor') .'&'. implode('&', $optionlist)); + break; + + default: + $this->redirect('course/forum/index/'. $section .'/'. (int)$page); + break; + } + } + + /** + * Like the submitted topic + * + * @param string $topic_id the topic to like + */ + function like_action($topic_id) + { + ForumPerm::check('like_entry', $this->getId(), $topic_id); + + ForumLike::like($topic_id); + + if (Request::isXhr()) { + $this->topic_id = $topic_id; + $this->render_template('course/forum/index/_like'); + } else { + $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id); + } + } + + /** + * Remove like for the submitted topic + * + * @param string $topic_id the topic to unlike + */ + function dislike_action($topic_id) + { + ForumPerm::check('like_entry', $this->getId(), $topic_id); + + ForumLike::dislike($topic_id); + + if (Request::isXhr()) { + $this->topic_id = $topic_id; + $this->render_template('course/forum/index/_like'); + } else { + $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id); + } + } + + /** + * This action is used to close a thread. + * + * @param string $topic_id the topic which will be closed + * @param string $redirect the topic which will be shown after closing the thread + * @param int $page the page number of the topic $redirect + */ + function close_thread_action($topic_id, $redirect, $page = 0) + { + ForumPerm::check('close_thread', $this->getId(), $topic_id); + + ForumEntry::close($topic_id); + + $success_text = _('Das Thema wurde erfolgreich geschlossen.'); + + if (Request::isXhr()) { + $this->render_text(MessageBox::success($success_text)); + } else { + $this->flash['messages'] = ['success' => $success_text]; + $this->redirect('course/forum/index/index/' . $redirect . '/' . $page); + } + } + + /** + * This action is used to open a thread. + * + * @param string $topic_id the topic which will be opened + * @param string $redirect the topic which will be shown after opening the thread + * @param int $page the page number of the topic $redirect + */ + function open_thread_action($topic_id, $redirect, $page = 0) + { + ForumPerm::check('close_thread', $this->getId(), $topic_id); + + ForumEntry::open($topic_id); + + $success_text = _('Das Thema wurde erfolgreich geöffnet.'); + + if (Request::isXhr()) { + $this->render_text(MessageBox::success($success_text)); + } else { + $this->flash['messages'] = ['success' => $success_text]; + $this->redirect('course/forum/index/index/' . $redirect . '/' . $page); + } + } + + /** + * This action is used to mark a thread as sticky. + * + * @param string $topic_id the topic which will be marked as sticky. + * @param string $redirect the topic which will be shown afterwards + * @param int $page the page number of the topic $redirect + */ + function make_sticky_action($topic_id, $redirect, $page = 0) + { + ForumPerm::check('make_sticky', $this->getId(), $topic_id); + + ForumEntry::sticky($topic_id); + + $success_text = _('Das Thema wurde erfolgreich in der Themenliste hervorgehoben.'); + + if (Request::isXhr()) { + $this->render_text(MessageBox::success($success_text)); + } else { + $this->flash['messages'] = ['success' => $success_text]; + $this->redirect('course/forum/index/index/' . $redirect . '/' . $page); + } + } + + /** + * This action is used to remove the sticky attribute from a topic. + * + * @param string $topic_id the topic which will be marked as unsticky. + * @param string $redirect the topic which will be shown afterwards + * @param int $page the page number of the topic $redirect + */ + function make_unsticky_action($topic_id, $redirect, $page = 0) + { + ForumPerm::check('make_sticky', $this->getId(), $topic_id); + + ForumEntry::unsticky($topic_id); + + $success_text = _('Die Hervorhebung des Themas in der Themenliste wurde entfernt.'); + + if (Request::isXhr()) { + $this->render_text(MessageBox::success($success_text)); + } else { + $this->flash['messages'] = ['success' => $success_text]; + $this->redirect('course/forum/index/index/' . $redirect . '/' . $page); + } + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * */ + /* * * * C O N F I G - A C T I O N S * * * */ + /* * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * Add submitted category to current course + */ + function add_category_action() + { + CSRFProtection::verifyUnsafeRequest(); + + ForumPerm::check('add_category', $this->getId()); + + $category_id = ForumCat::add($this->getId(), Request::get('category')); + + ForumPerm::checkCategoryId($this->getId(), $category_id); + + $this->redirect('course/forum/index#cat_'. $category_id); + } + + /* + * Remove submitted category from current course + */ + function remove_category_action($category_id) + { + CSRFProtection::verifyUnsafeRequest(); + + ForumPerm::checkCategoryId($this->getId(), $category_id); + ForumPerm::check('remove_category', $this->getId()); + + $this->flash['messages'] = ['success' => _('Die Kategorie wurde gelöscht!')]; + ForumCat::remove($category_id, $this->getId()); + + if (Request::isXhr()) { + $this->render_template('course/forum/messages'); + } else { + $this->redirect('course/forum/index/index'); + } + + } + + /** + * Change the name of the submitted category + * + * @param string $category_id the category to edit + */ + function edit_category_action($category_id) { + CSRFProtection::verifyUnsafeRequest(); + + ForumPerm::checkCategoryId($this->getId(), $category_id); + ForumPerm::check('edit_category', $this->getId()); + + if (Request::isXhr()) { + ForumCat::setName($category_id, Request::get('name')); + $this->render_nothing(); + } else { + ForumCat::setName($category_id, Request::get('name')); + $this->flash['messages'] = ['success' => _('Der Name der Kategorie wurde geändert.')]; + $this->redirect('course/forum/index/index#cat_' . $category_id); + } + + } + + /** + * Save the ordering of the categories + */ + function savecats_action() + { + ForumPerm::check('sort_category', $this->getId()); + + $pos = 0; + foreach (Request::getArray('categories') as $category_id) { + ForumPerm::checkCategoryId($this->getId(), $category_id); + ForumCat::setPosition($category_id, $pos); + $pos++; + } + + $this->render_nothing(); + } + + /* + * Subscribe to the submitted topic and receive mails on new postings + * + * @param string $topic_id + */ + function abo_action($topic_id) + { + ForumPerm::check('abo', $this->getId(), $topic_id); + + ForumAbo::add($topic_id); + $this->constraint = ForumEntry::getConstraints($topic_id); + + if (Request::isXhr()) { + $this->render_template('course/forum/index/_abo_link'); + } else { + switch ($this->constraint['depth']) { + case 0: $msg = _('Sie haben das gesamte Forum abonniert!');break; + case 1: $msg = _('Sie haben diesen Bereich abonniert.');break; + default: $msg = _('Sie haben dieses Thema abonniert');break; + } + $this->flash['messages'] = ['success' => $msg .' '. _('Sie werden nun über jeden neuen Beitrag informiert.')]; + $this->redirect('course/forum/index/index/' . $topic_id); + } + } + + /** + * Unsubscribe from the passed topic + * + * @param string $topic_id + */ + function remove_abo_action($topic_id) + { + ForumPerm::check('abo', $this->getId(), $topic_id); + + ForumAbo::delete($topic_id); + + if (Request::isXhr()) { + $this->constraint = ForumEntry::getConstraints($topic_id); + $this->render_template('course/forum/index/_abo_link'); + } else { + $this->flash['messages'] = ['success' => _('Abonnement aufgehoben.')]; + $this->redirect('course/forum/index/index/' . $topic_id); + } + } + + /** + * Generate a pdf-export for the whole forum or the passed subtree + * + * @param string $parent_id + */ + function pdfexport_action($parent_id = null) + { + ForumPerm::check('pdfexport', $this->getId(), $parent_id); + + ForumHelpers::createPDF($this->getId(), $parent_id); + } +} diff --git a/app/controllers/course/messenger.php b/app/controllers/course/messenger.php new file mode 100644 index 0000000..0bfd3f5 --- /dev/null +++ b/app/controllers/course/messenger.php @@ -0,0 +1,78 @@ +<?php +class Course_MessengerController extends AuthenticatedController +{ + public function before_filter(&$action, &$args) + { + parent::before_filter($action, $args); + + PageLayout::setBodyElementId('blubber-index'); + PageLayout::setHelpKeyword("Basis/InteraktionBlubber"); + } + + public function course_action($thread_id = null) + { + PageLayout::setTitle(_("Blubber")); + + if (Navigation::hasItem('/course/blubber')) { + Navigation::activateItem("/course/blubber"); + } + + $this->threads = BlubberThread::findByContext(Context::get()->id, true, Context::getType()); + + if (!$thread_id) { + $thread_id = $GLOBALS['user']->cfg->BLUBBER_DEFAULT_THREAD; + } + if ($thread_id) { + foreach ($this->threads as $thread) { + if ($thread->getId() === $thread_id) { + $this->thread = $thread; + break; + } + } + } + if (!$this->thread || Request::get("thread") === "new") { + $this->thread = array_pop(array_reverse($this->threads)); + } + $this->thread->markAsRead(); + + $this->thread_data = $this->thread->getJSONData(); + + if (!Avatar::getAvatar($GLOBALS['user']->id)->is_customized() && !$_SESSION['already_asked_for_avatar']) { + $_SESSION['already_asked_for_avatar'] = true; + PageLayout::postInfo(sprintf(_("Wollen Sie ein Avatar-Bild nutzen? %sLaden Sie jetzt ein Bild hoch%s."), '<a href="'.URLHelper::getURL("dispatch.php/avatar/update/user/".$GLOBALS['user']->id).'" data-dialog>', '</a>')); + } + $this->buildSidebar(); + + if (Request::isDialog()) { + PageLayout::setTitle($this->thread->getName()); + $this->render_template('blubber/dialog'); + } else { + $this->render_template('blubber/index', $this->layout); + } + } + + protected function buildSidebar() + { + $sidebar = Sidebar::Get(); + $search = new SearchWidget("#"); + $search->addNeedle( + _("Suche nach ..."), + "search", + true, + null, + null, + null, + [] + ); + $sidebar->addWidget($search, "blubbersearch"); + + $threads_widget = new BlubberThreadsWidget(); + foreach ($this->threads as $thread) { + $threads_widget->addThread($thread); + } + if ($this->thread) { + $threads_widget->setActive($this->thread->getId()); + } + $sidebar->addWidget($threads_widget, "threads"); + } +} |
