diff --git a/app/controllers/course/topics.php b/app/controllers/course/topics.php
index fbae33d704bd5d84aa7d03fb98f9210722c7918c..f40c4db78221fe558b73cf1f75b59e53234f7e71 100644
--- a/app/controllers/course/topics.php
+++ b/app/controllers/course/topics.php
@@ -3,6 +3,7 @@
 class Course_TopicsController extends AuthenticatedController
 {
     protected $allow_nobody = true;
+    protected $_autobind = true;
 
     public function before_filter(&$action, &$args)
     {
@@ -13,136 +14,123 @@ class Course_TopicsController extends AuthenticatedController
         checkObject();
         checkObjectModule("schedule");
 
+        Navigation::activateItem('/course/schedule/topics');
         PageLayout::setTitle(sprintf('%s - %s', Course::findCurrent()->getFullname(), _("Themen")));
 
         $seminar = new Seminar(Course::findCurrent());
         $this->forum_activated = $seminar->getSlotModule('forum');
         $this->documents_activated = $seminar->getSlotModule('documents');
 
+        if ($action !== 'index' && !$GLOBALS['perm']->have_studip_perm('tutor', Context::getId())) {
+            throw new AccessDeniedException();
+        }
+
         $this->setupSidebar($action);
     }
 
     public function index_action()
     {
-        if (Request::isPost() && Request::get("edit") && $GLOBALS['perm']->have_studip_perm("tutor", Context::getId())) {
-            $topic = new CourseTopic(Request::option("issue_id"));
-            if ($topic['seminar_id'] && ($topic['seminar_id'] !== Context::getId())) {
-                throw new AccessDeniedException();
-            }
+        $this->topics = CourseTopic::findBySeminar_id(Context::getId());
+        $this->cancelled_dates_locked = LockRules::Check(Context::getId(), 'cancelled_dates');
+    }
 
-            $topic['title']         = Request::get("title");
-            $topic['description']   = Studip\Markup::purifyHtml(Request::get("description"));
-            $topic['paper_related'] = (bool) Request::int('paper_related');
-            if ($topic->isNew()) {
-                $topic['seminar_id'] = Context::getId();
-            }
-            $topic->store();
+    public function delete_action(CourseTopic $topic)
+    {
+        if (!Request::isPost()) {
+            throw new MethodNotAllowedException();
+        }
 
-            //change dates for this topic
-            $former_date_ids = $topic->dates->pluck("termin_id");
-            $new_date_ids = array_keys(Request::getArray("date"));
-            foreach (array_diff($former_date_ids, $new_date_ids) as $delete_termin_id) {
-                $topic->dates->unsetByPk($delete_termin_id);
-            }
-            foreach (array_diff($new_date_ids, $former_date_ids) as $add_termin_id) {
-                $date = CourseDate::find($add_termin_id);
-                if ($date) {
-                    $topic->dates[] = $date;
-                }
-            }
-            $topic->store();
+        if ($topic->seminar_id && ($topic->seminar_id !== Context::getId())) {
+            throw new AccessDeniedException();
+        }
 
-            if (Request::get("folder")) {
-                $topic->connectWithDocumentFolder();
-            }
+        if ($topic->delete()) {
+            PageLayout::postSuccess(_('Thema gelöscht.'));
+        }
 
-            // create a connection to the module forum (can be anything)
-            // will update title and description automagically
-            if (Request::get("forumthread")) {
-                $topic->connectWithForumThread();
-            }
+        $this->redirect('course/topics');
+    }
 
-            if (Request::option("issue_id") === "new") {
-                Request::set("open", $topic->getId());
-            }
-            PageLayout::postMessage(MessageBox::success(_("Thema gespeichert.")));
-            $this->redirect("course/topics/index");
+    public function edit_action(CourseTopic $topic = null)
+    {
+        PageLayout::setTitle($topic->isNew() ? _('Neues Thema erstellen') : sprintf(_('Bearbeiten: %s'), $topic->title));
+
+        $this->dates = CourseDate::findBySeminar_id(Context::getId());
+    }
+
+    public function store_action(CourseTopic $topic = null)
+    {
+        if (!Request::isPost()) {
+            throw new MethodNotAllowedException();
         }
 
-        if (Request::isPost() && Request::option("move_down")) {
-            $topics = CourseTopic::findBySeminar_id(Context::getId());
-            $mainkey = null;
-            foreach ($topics as $key => $topic) {
-                if ($topic->getId() === Request::option("move_down")) {
-                    $mainkey = $key;
-                }
-                $topic['priority'] = $key + 1;
-            }
-            if ($mainkey !== null && $mainkey < count($topics)) {
-                $topics[$mainkey]->priority++;
-                $topics[$mainkey + 1]->priority--;
-            }
-            foreach ($topics as $key => $topic) {
-                $topic->store();
-            }
+        if ($topic->seminar_id && ($topic->seminar_id !== Context::getId())) {
+            throw new AccessDeniedException();
         }
-        if (Request::isPost() && Request::option("move_up")) {
-            $topics = CourseTopic::findBySeminar_id(Context::getId());
-            foreach ($topics as $key => $topic) {
-                if (($topic->getId() === Request::option("move_up")) && $key > 0) {
-                    $topic['priority'] = $key;
-                    $topics[$key - 1]->priority = $key + 1;
-                    $topics[$key - 1]->store();
-                } else {
-                    $topic['priority'] = $key + 1;
-                }
-                $topic->store();
+
+        $topic->title         = Request::i18n("title");
+        $topic->description   = Request::i18n('description', null, function ($string) {
+            return Studip\Markup::purifyHtml($string);
+
+        });
+        $topic->paper_related = Request::bool('paper_related', false);
+        if ($topic->isNew()) {
+            $topic->seminar_id = Context::getId();
+        }
+        $topic->store();
+
+        //change dates for this topic
+        $former_date_ids = $topic->dates->pluck('termin_id');
+        $new_date_ids = array_keys(Request::getArray('date'));
+        foreach (array_diff($former_date_ids, $new_date_ids) as $delete_termin_id) {
+            $topic->dates->unsetByPk($delete_termin_id);
+        }
+        foreach (array_diff($new_date_ids, $former_date_ids) as $add_termin_id) {
+            $date = CourseDate::find($add_termin_id);
+            if ($date) {
+                $topic->dates[] = $date;
             }
         }
+        $topic->store();
 
-        Navigation::activateItem('/course/schedule/topics');
-        $this->topics = CourseTopic::findBySeminar_id(Context::getId());
-        $this->cancelled_dates_locked = LockRules::Check(Context::getId(), 'cancelled_dates');
-    }
+        if (Request::bool('folder')) {
+            $topic->connectWithDocumentFolder();
+        }
 
-    public function delete_action($topic_id)
-    {
-        if (!$GLOBALS['perm']->have_studip_perm("tutor", Context::getId())) {
-            throw new AccessDeniedException();
+        // create a connection to the module forum (can be anything)
+        // will update title and description automagically
+        if (Request::bool('forumthread')) {
+            $topic->connectWithForumThread();
         }
 
-        $topic = new CourseTopic($topic_id);
+        PageLayout::postSuccess(_('Thema gespeichert.'));
+        $this->redirect($this->indexURL(['open' => $topic->id]));
+    }
 
-        if ($topic['seminar_id'] && ($topic['seminar_id'] !== Context::getId())) {
-            throw new AccessDeniedException();
+    public function move_up_action(CourseTopic $topic)
+    {
+        if (!Request::isPost()) {
+            throw new MethodNotAllowedException();
         }
 
-        $topic->delete();
-        PageLayout::postSuccess(_('Thema gelöscht.'));
+        $topic->increasePriority();
 
-        $this->redirect('course/topics');
+        $this->redirect($this->indexURL(['open' => $topic->id]));
     }
 
-    public function edit_action($topic_id = null)
+    public function move_down_action(CourseTopic $topic)
     {
-        if (!$GLOBALS['perm']->have_studip_perm("tutor", Context::getId())) {
-            throw new AccessDeniedException();
+        if (!Request::isPost()) {
+            throw new MethodNotAllowedException();
         }
-        $this->topic = new CourseTopic($topic_id);
-        $this->dates = CourseDate::findBySeminar_id(Context::getId());
 
-        if (Request::isXhr()) {
-            PageLayout::setTitle($topic_id ? sprintf(_('Bearbeiten: %s'), $this->topic['title']) : _("Neues Thema erstellen"));
-        } else {
-            Navigation::activateItem('/course/schedule/topics');
-        }
+        $topic->decreasePriority();
+
+        $this->redirect($this->indexURL(['open' => $topic->id]));
     }
 
     public function allow_public_action()
     {
-        if (!$GLOBALS['perm']->have_studip_perm("tutor", Context::getId())) {
-            throw new AccessDeniedException();
-        }
         $config = CourseConfig::get(Context::getId());
         $config->store('COURSE_PUBLIC_TOPICS', !$config->COURSE_PUBLIC_TOPICS);
         $this->redirect("course/topics");
@@ -150,9 +138,6 @@ class Course_TopicsController extends AuthenticatedController
 
     public function copy_action()
     {
-        if (!$GLOBALS['perm']->have_studip_perm("tutor", Context::getId())) {
-            throw new AccessDeniedException();
-        }
         if (Request::submitted("copy")) {
             $prio = 1;
             foreach (Course::find(Context::getId())->topics as $topic) {
@@ -227,9 +212,6 @@ class Course_TopicsController extends AuthenticatedController
 
     public function fetch_topics_action()
     {
-        if (!$GLOBALS['perm']->have_studip_perm("tutor", Request::option("seminar_id"))) {
-            throw new AccessDeniedException();
-        }
         $this->topics = CourseTopic::findBySeminar_id(Request::option("seminar_id"));
         $output = [
             'html' => $this->render_template_as_string("course/topics/_topiclist.php")
@@ -272,8 +254,8 @@ class Course_TopicsController extends AuthenticatedController
         if ($GLOBALS['perm']->have_studip_perm('tutor', Context::getId())) {
             $options = $sidebar->addWidget(new OptionsWidget());
             $options->addCheckbox(
-                _("Themen öffentlich einsehbar"),
-                CourseConfig::get(Context::getId())->COURSE_PUBLIC_TOPICS,
+                _('Themen öffentlich einsehbar'),
+                (bool) CourseConfig::get(Context::getId())->COURSE_PUBLIC_TOPICS,
                 $this->url_for('course/topics/allow_public')
             );
         }
diff --git a/app/views/course/topics/edit.php b/app/views/course/topics/edit.php
index 43a5c74feb1529878f8e4a7e046e464822140628..9d04927fa3ec3a90e88da090cc13a51907cb5dcc 100644
--- a/app/views/course/topics/edit.php
+++ b/app/views/course/topics/edit.php
@@ -1,67 +1,66 @@
 <? $date_ids = $topic->dates->pluck("termin_id") ?>
-<form action="<?= URLHelper::getLink("dispatch.php/course/topics") ?>" method="post" class="default">
+<form action="<?= $controller->store($topic) ?>" method="post" class="default">
     <?= CSRFProtection::tokenTag() ?>
 
-    <input type="hidden" name="issue_id" value="<?=htmlReady($topic->getId())  ?>">
-    <input type="hidden" name="open" value="<?=htmlReady($topic->getId())  ?>">
+    <input type="hidden" name="open" value="<?= htmlReady($topic->getId()) ?>">
     <input type="hidden" name="edit" value="1">
 
     <fieldset>
         <legend><?= _('Thema bearbeiten') ?></legend>
 
-        <label for="topic_title">
-            <span class="required"><?= _("Titel") ?></span>
-            <input type="text" name="title" id="topic_title" value="<?= htmlReady($topic['title']) ?>" required>
+        <label>
+            <span class="required"><?= _('Titel') ?></span>
+            <?= I18N::input('title', $topic->title, ['required' => '']) ?>
         </label>
 
 
-        <label for="topic_description">
+        <label>
             <?= _("Beschreibung") ?>
 
-            <textarea class="add_toolbar wysiwyg size-l" name="description" id="topic_description"><?= wysiwygReady($topic['description']) ?></textarea>
-            <? if (Request::isAjax()) : ?>
-            <script>jQuery('.add_toolbar').addToolbar();</script>
-            <? endif ?>
+            <?= I18N::textarea('description', $topic->description, [
+                'class' => 'add_toolbar wysiwyg size-l',
+            ]) ?>
         </label>
 
-        <? if ($documents_activated) : ?>
-            <label>
-            <? $folder = $topic->folders->first() ?>
-            <? if ($folder) : ?>
-                <?= Icon::create('accept', 'accept')->asImg(['class' => "text-bottom"]) ?>
-                <?= _("Dateiordner vorhanden ") ?>
-            <? else : ?>
-                <input type="checkbox" name="folder" id="topic_folder">
-                <?= _("Dateiordner anlegen") ?>
-            <? endif ?>
-            </label>
+    <? if ($documents_activated) : ?>
+        <label>
+        <? $folder = $topic->folders->first() ?>
+        <? if ($folder) : ?>
+            <?= Icon::create('accept', Icon::ROLE_ACCEPT)->asImg(['class' => 'text-bottom']) ?>
+            <?= _('Dateiordner vorhanden ') ?>
+        <? else : ?>
+            <input type="checkbox" name="folder" id="topic_folder" value="1">
+            <?= _('Dateiordner anlegen') ?>
         <? endif ?>
+        </label>
+    <? endif ?>
 
-        <? if ($forum_activated) : ?>
-            <label>
-            <? if ($topic->forum_thread_url) : ?>
-                <?= Icon::create('accept', 'accept')->asImg(['class' => "text-bottom"]) ?>
-                <?= _("Forenthema vorhanden ") ?>
-            <? else : ?>
-                <input type="checkbox" name="forumthread" id="topic_forumthread">
-                <?= _("Forenthema anlegen") ?>
-            <? endif ?>
-            </label>
+    <? if ($forum_activated) : ?>
+        <label>
+        <? if ($topic->forum_thread_url) : ?>
+            <?= Icon::create('accept', Icon::ROLE_ACCEPT)->asImg(['class' => 'text-bottom']) ?>
+            <?= _('Forenthema vorhanden ') ?>
+        <? else : ?>
+            <input type="checkbox" name="forumthread" id="topic_forumthread" value="1">
+            <?= _('Forenthema anlegen') ?>
         <? endif ?>
+        </label>
+    <? endif ?>
 
-        <h2><?= _("Termine") ?></h2>
+        <h2><?= _('Termine') ?></h2>
         <? foreach ($dates as $date) : ?>
             <label>
-                <input type="checkbox" name="date[<?= $date->getId() ?>]" value="1" class="text-bottom"<?= in_array($date->getId(), $date_ids) ? " checked" : "" ?>>
-                <?= Icon::create('date', 'info')->asImg(['class' => "text-bottom"]) ?>
-                <?= (floor($date['date'] / 86400) !== floor($date['end_time'] / 86400)) ? date("d.m.Y, H:i", $date['date'])." - ".date("d.m.Y, H:i", $date['end_time']) : date("d.m.Y, H:i", $date['date'])." - ".date("H:i", $date['end_time']) ?>
-            <? $localtopics = $date->topics ?>
-            <? if (count($localtopics)) : ?>
+                <input type="checkbox" name="date[<?= htmlReady($date->id) ?>]" value="1" class="text-bottom"
+                       <? if (in_array($date->id, $date_ids)) echo 'checked'; ?>>
+                <?= Icon::create('date', Icon::ROLE_INFO)->asImg(['class' => 'text-bottom']) ?>
+                <?= floor($date['date'] / 86400) !== floor($date['end_time'] / 86400) ? date("d.m.Y, H:i", $date['date'])." - ".date("d.m.Y, H:i", $date['end_time']) : date("d.m.Y, H:i", $date['date'])." - ".date("H:i", $date['end_time']) ?>
+
+            <? if (count($date->topics) > 0) : ?>
             (
-                <? foreach ($localtopics as $key => $localtopic) : ?>
-                    <a href="<?= URLHelper:: getLink("dispatch.php/course/topics/index", ['open' => $localtopic->getId()]) ?>">
-                        <?= Icon::create('topic', 'clickable')->asImg(['class' => "text-bottom"]) ?>
-                        <?= htmlReady($localtopic['title']) ?>
+                <? foreach ($date->topics as $key => $localtopic) : ?>
+                    <a href="<?= $controller->index(['open' => $localtopic->id]) ?>">
+                        <?= Icon::create('topic')->asImg(['class' => 'text-bottom']) ?>
+                        <?= htmlReady($localtopic->title) ?>
                     </a>
                 <? endforeach ?>
             )
@@ -90,5 +89,3 @@
         </div>
     </footer>
 </form>
-
-<br>
diff --git a/app/views/course/topics/index.php b/app/views/course/topics/index.php
index 79b74a252cd987326367aaac5723b4c6104c02d2..39635d17586422698a3fe913452ab907669f354c 100644
--- a/app/views/course/topics/index.php
+++ b/app/views/course/topics/index.php
@@ -83,34 +83,36 @@
                     </table>
                     <div style="text-align: center;">
                         <? if ($GLOBALS['perm']->have_studip_perm("tutor", Context::getId())) : ?>
-                            <?= \Studip\LinkButton::createEdit(_('Bearbeiten'),
-                                $controller->url_for('course/topics/edit/' . $topic->getId()), [
-                                    'data-dialog' => ''
-                                ]) ?>
-
-                            <?= Studip\LinkButton::create(
-                                _('Löschen'),
-                                $controller->url_for('course/topics/delete/' . $topic->getId()),
-                                ['data-confirm' => _('Wirklich löschen?')]
+                            <?= Studip\LinkButton::createEdit(
+                                _('Bearbeiten'),
+                                $controller->editURL($topic),
+                                ['data-dialog' => '']
                             ) ?>
 
+                            <form action="<?= $controller->delete($topic) ?>" method="post" style="display: inline">
+                                <?= Studip\Button::create(
+                                    _('Löschen'),
+                                    'delete',
+                                    ['data-confirm' => _('Wirklich löschen?')]
+                                ) ?>
+                            </form>
+
                             <? if (!$cancelled_dates_locked && $topic->dates->count()) : ?>
                                 <?= \Studip\LinkButton::create(_("Alle Termine ausfallen lassen"), URLHelper::getURL("dispatch.php/course/cancel_dates", ['issue_id' => $topic->getId()]), ['data-dialog' => '']) ?>
                             <? endif ?>
+
+                            <span class="button-group">
                             <? if ($key > 0) : ?>
-                                <form action="<?=$controller->link_for()?>" method="post" style="display: inline;">
-                                    <input type="hidden" name="move_up" value="<?= $topic->getId() ?>">
-                                    <input type="hidden" name="open" value="<?= $topic->getId() ?>">
-                                    <?= \Studip\Button::createMoveUp(_("nach oben verschieben")) ?>
+                                <form action="<?= $controller->move_up($topic) ?>" method="post" style="display: inline;">
+                                    <?= Studip\Button::createMoveUp(_('nach oben verschieben')) ?>
                                 </form>
                             <? endif ?>
                             <? if ($key < count($topics) - 1) : ?>
-                            <form action="<?=$controller->link_for()?>" method="post" style="display: inline;">
-                                <input type="hidden" name="move_down" value="<?= $topic->getId() ?>">
-                                <input type="hidden" name="open" value="<?= $topic->getId() ?>">
-                                <?= \Studip\Button::createMoveDown(_("nach unten verschieben")) ?>
-                            </form>
+                                <form action="<?=$controller->move_down($topic)?>" method="post" style="display: inline;">
+                                    <?= Studip\Button::createMoveDown(_('nach unten verschieben')) ?>
+                                </form>
                             <? endif ?>
+                            </span>
                         <? endif ?>
                     </div>
                 </div>
diff --git a/lib/models/CourseTopic.class.php b/lib/models/CourseTopic.class.php
index adad4d167e976ed13c950923eb90d0d61159d16d..56a060d16df369aced98064e050d9e0b144fb03b 100644
--- a/lib/models/CourseTopic.class.php
+++ b/lib/models/CourseTopic.class.php
@@ -19,57 +19,33 @@
  * @property string priority database column
  * @property string mkdate database column
  * @property string chdate database column
- * @property DocumentFolder folder belongs_to DocumentFolder
+ * @property Folder folder belongs_to DocumentFolder
  * @property Course course belongs_to Course
  * @property User author belongs_to User
  * @property SimpleORMapCollection dates has_and_belongs_to_many CourseDate
  */
 class CourseTopic extends SimpleORMap
 {
-    public static function findByTermin_id($termin_id)
-    {
-        return self::findBySQL("INNER JOIN themen_termine USING (issue_id)
-            WHERE themen_termine.termin_id = ?
-            ORDER BY priority ASC",
-            [$termin_id]
-        );
-    }
-
-    public static function findBySeminar_id($seminar_id, $order_by = 'ORDER BY priority')
-    {
-        return parent::findBySeminar_id($seminar_id, $order_by);
-    }
-
-    public static function findByTitle($seminar_id, $name)
-    {
-        return self::findOneBySQL("seminar_id = ? AND title = ?", [$seminar_id, $name]);
-    }
-
-    public static function getMaxPriority($seminar_id)
-    {
-        return DBManager::get()->fetchColumn("SELECT MAX(priority) FROM themen WHERE seminar_id=?", [$seminar_id]);
-    }
-
     protected static function configure($config = [])
     {
         $config['db_table'] = 'themen';
         $config['has_and_belongs_to_many']['dates'] = [
-            'class_name' => 'CourseDate',
+            'class_name' => CourseDate::class,
             'thru_table' => 'themen_termine',
             'order_by'   => 'ORDER BY date',
             'on_delete'  => 'delete',
             'on_store'   => 'store'
         ];
         $config['has_many']['folders'] = [
-            'class_name'  => 'Folder',
+            'class_name'  => Folder::class,
             'assoc_func' => 'findByTopic_id'
         ];
         $config['belongs_to']['course'] = [
-            'class_name'  => 'Course',
+            'class_name'  => Course::class,
             'foreign_key' => 'seminar_id'
         ];
         $config['belongs_to']['author'] = [
-            'class_name'  => 'User',
+            'class_name'  => User::class,
             'foreign_key' => 'author_id'
         ];
 
@@ -79,9 +55,36 @@ class CourseTopic extends SimpleORMap
         $config['registered_callbacks']['after_store'][] = 'cbUpdateConnectedContentModules';
         $config['registered_callbacks']['before_delete'][] = 'cbUnlinkConnectedContentModules';
 
+        $config['i18n_fields']['title'] = true;
+        $config['i18n_fields']['description'] = true;
+
         parent::configure($config);
     }
 
+    public static function findByTermin_id($termin_id)
+    {
+        return self::findBySQL("INNER JOIN themen_termine USING (issue_id)
+            WHERE themen_termine.termin_id = ?
+            ORDER BY priority ASC",
+            [$termin_id]
+        );
+    }
+
+    public static function findBySeminar_id($seminar_id, $order_by = 'ORDER BY priority')
+    {
+        return parent::findBySeminar_id($seminar_id, $order_by);
+    }
+
+    public static function findByTitle($seminar_id, $name)
+    {
+        return self::findOneBySQL("seminar_id = ? AND title = ?", [$seminar_id, $name]);
+    }
+
+    public static function getMaxPriority($seminar_id)
+    {
+        return DBManager::get()->fetchColumn("SELECT MAX(priority) FROM themen WHERE seminar_id=?", [$seminar_id]);
+    }
+
     /**
     * set or update connection with document folder
     */
@@ -179,7 +182,7 @@ class CourseTopic extends SimpleORMap
             $folders = array_merge($folders, $date->folders->getArrayCopy());
         }
         foreach ($folders as $folder) {
-            list($files, $typed_folders) = array_values(FileManager::getFolderFilesRecursive($folder->getTypedFolder(), $user_id));
+            [$files, $typed_folders] = array_values(FileManager::getFolderFilesRecursive($folder->getTypedFolder(), $user_id));
             foreach ($files as $file) {
                 $all_files[$file->id] = $file;
             }
@@ -187,4 +190,67 @@ class CourseTopic extends SimpleORMap
         }
         return ['files' => $all_files, 'folders' => $all_folders];
     }
+
+    /**
+     * Increases the priority of this topic. Meaning the topic will be sorted further up.
+     * Be aware that this actually decreases the priority property since lower numbers
+     * mean higher priority.
+     *
+     * @return boolean
+     */
+    public function increasePriority()
+    {
+        // Update all the course's topics with a lower priority than this one
+        $query = "UPDATE `themen`
+                  SET `priority` = `priority` + 1
+                  WHERE `seminar_id` = :course_id
+                    AND `priority` < :current_priority
+                  ORDER BY `priority` DESC
+                  LIMIT 1";
+        $changed = DBManager::get()->execute($query, [
+            ':course_id'        => $this->seminar_id,
+            ':current_priority' => $this->priority,
+        ]);
+
+        // If anything has changed, decrease priority. Otherwise the current
+        // topic is already at top.
+        if ($changed) {
+            $this->priority -= 1;
+            $this->store();
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Decreases the priority of this topic. Meaning the topic will be sorted further down.
+     * Be aware that this actually increases the priority property since higher numbers
+     * mean lower priority.
+     */
+    public function decreasePriority()
+    {
+        // Update all the course's topics with a higher priority than this one
+        $query = "UPDATE `themen`
+                 SET `priority` = `priority` - 1
+                  WHERE `seminar_id` = :course_id
+                    AND `priority` > :current_priority
+                 ORDER BY `priority` ASC
+                 LIMIT 1";
+        $changed = DBManager::get()->execute($query, [
+            ':course_id'        => $this->seminar_id,
+            ':current_priority' => $this->priority,
+        ]);
+
+        // If anything has changed, increase priority. Otherwise the current
+        // topic is already at bottom.
+        if ($changed) {
+            $this->priority += 1;
+            $this->store();
+            return true;
+        }
+
+        return false;
+
+    }
 }