Skip to content
Snippets Groups Projects
Select Git revision
  • 63aa7084f9ae149d9bddcb9f93ad6a226a53a38f
  • master default protected
  • v1.5
  • v1.4.7
  • v1.4.6
  • v1.4.5
  • v1.4.4
  • v1.4.3
  • v1.4.2
  • v1.4.1
  • v1.4
  • v1.3
  • v1.2.1
  • v1.2
  • v1.1.2
  • v1.1.1
  • v1.0
17 results

MatrixPlugin.php

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    MatrixPlugin.php 6.96 KiB
    <?php
    
    /**
     * Class MatrixPlugin
     * Plugin for integrating a Matrix chat into Stud.IP.
     *
     * 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.
     *
     * @author      Thomas Hackl <hackl@data-quest.de>
     * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
     * @category    Matrix
     */
    
    require_once(__DIR__ . '/vendor/libpatrix/MatrixClient.php');
    
    class MatrixPlugin extends StudIPPlugin implements StandardPlugin
    {
    
        public function __construct() {
            parent::__construct();
    
            StudipAutoloader::addAutoloadPath(__DIR__ . '/models');
    
            // Localization
            bindtextdomain('matrix', realpath(__DIR__.'/locale'));
    
            // Add Observers for several actions on user or course membership modification
            NotificationCenter::addObserver($this, 'invite', 'CourseMemberDidCreate');
            NotificationCenter::addObserver($this, 'uninvite', 'CourseMemberDidDelete');
            NotificationCenter::addObserver($this, 'unregister', 'UserDidDelete');
            NotificationCenter::addObserver($this, 'deleteRoom', 'CourseDidDelete');
            NotificationCenter::addObserver($this, 'updateCronjob', 'StudipNewsWillUpdate');
            NotificationCenter::addObserver($this, 'updateCronjob', 'StudipNewsDidDelete');
    
            $this->addScript('assets/javascripts/matrixchat.js');
            $this->addStylesheet('assets/stylesheets/matrixchat.scss');
        }
    
        /**
         * Plugin name to show in navigation.
         */
        public function getDisplayName()
        {
            return dgettext('matrix', 'Matrix-Chat');
        }
    
        public function getVersion()
        {
            $metadata = $this->getMetadata();
            return $metadata['version'];
        }
    
        public function getIconNavigation($course_id, $last_visit, $user_id)
        {
            $num_entries = 0;
            $text = $this->getDisplayName();
    
            $navigation = new Navigation('matrix', PluginEngine::getURL($this, [], 'matrix_chat'));
            $navigation->setBadgeNumber($num_entries);
    
            $account = MatrixAccount::find(User::findCurrent()->id);
            if ($account) {
                //$news = MatrixClient::get()->getNews($account->getLinkedAccount());
            }
    
            if ($num_entries > 0) {
                $navigation->setImage(Icon::create('consultation+new', Icon::ROLE_ATTENTION, ["title" => $text]));
            } else {
                $navigation->setImage(Icon::create('consultation', Icon::ROLE_INACTIVE, ["title" => $text]));
            }
    
            return $navigation;
        }
    
        public function getTabNavigation($course_id)
        {
            if ($GLOBALS['user']->id == 'nobody') {
                return [];
            }
    
            $matrix = new Navigation($this->getDisplayName());
            $matrix->addSubNavigation('matrix_chat', new Navigation(dgettext('matrix', 'Matrix-Chat'),
                PluginEngine::getURL($this, [], 'matrix_chat')));
    
            return compact('matrix');
        }
    
        /**
         * @see StudipModule::getMetadata()
         */
        public function getMetadata()
        {
            $metadata = parent::getMetadata();
    
            $metadata['summary'] = dgettext('matrix', 'Chat via Matrix');
            $metadata['description'] = dgettext('matrix', 'Matrix-Chaträume für Veranstaltungen');
            $metadata['category'] = _('Kommunikation und Zusammenarbeit');
            $metadata['icon'] = Icon::create('consultation', Icon::ROLE_INFO);
    
            return $metadata;
        }
    
        /**
         * @see StandardPlugin::getInfoTemplate()
         */
        public function getInfoTemplate($course_id)
        {
            return null;
        }
    
        public function perform($unconsumed_path) {
            $range_id = Request::option('cid', Context::get()->id);
    
            URLHelper::removeLinkParam('cid');
            $dispatcher = new Trails_Dispatcher(
                $this->getPluginPath(),
                rtrim(PluginEngine::getLink($this, [], null), '/'),
                'matrix_chat'
            );
            URLHelper::addLinkParam('cid', $range_id);
    
            $dispatcher->current_plugin = $this;
            $dispatcher->range_id       = $range_id;
            $dispatcher->dispatch($unconsumed_path);
        }
    
        /**
         * User is now member of a course, send invitation to Matrix room if necessary.
         *
         * @param string $event
         * @param CourseMember $membership
         */
        public function invite($event, $membership)
        {
            if ($matrix = MatrixAccount::findOneByUser_id($membership->user_id) &&
                    $room = MatrixRoom::findOneByRange_id($membership->seminar_id)) {
                MatrixClient::get()->inviteIntoRoom(
                    MatrixAccount::requireSystemAccount(),
                    $room->getLinkedRoom(),
                    $matrix->matrix_account_id
                );
            }
        }
    
        /**
         * User has left a course, remove from course Matrix room if necessary.
         *
         * @param string $event
         * @param CourseMember $membership
         */
        public function uninvite($event, $membership)
        {
            if ($matrix = MatrixAccount::findOneByUser_id($membership->user_id) &&
                $room = MatrixRoom::findOneByRange_id($membership->seminar_id)) {
                MatrixClient::get()->leaveRoom(
                    $matrix->getLinkedAccount(),
                    $room->getLinkedRoom()
                );
            }
        }
    
        /**
         * User has been deleted, remove assigned Matrix account
         * (TODO: only Stud.IP mapping or whole account?)
         *
         * @param string $event
         * @param User $user
         */
        public function unregister($event, $user)
        {
            if ($account = MatrixAccount::findOneByUser_id($user->id)) {
                if (MatrixClient::get()->deactivateAccount($account->getLinkedAccount())) {
                    $account->delete();
                }
            }
        }
    
        /**
         * A Course has been deleted, remove assigned Matrix room
         *
         * @param string $event
         * @param Course $course
         */
        public function deleteRoom($event, $course)
        {
            if ($room = MatrixRoom::findOneByRange_id($course->id)) {
                MatrixClient::get()->deleteRoom(
                    MatrixAccount::requireSystemAccount(),
                    $room->getLinkedRoom()
                );
            }
        }
    
        /**
         * Remove news from entries relevant for cronjob.
         *
         * @param string $event
         * @param StudipNews $news
         */
        public function updateCronjob($event, $news)
        {
            switch ($event) {
                case 'StudipNewsWillUpdate':
                    if ($news->isFieldDirty('date')) {
                        DBManager::get()->execute(
                            "UPDATE `matrix_upcoming_news` SET `publish_at` = :publish WHERE `news_id` = :id",
                            ['publish' => $news->date, 'id' => $news->id]
                        );
                    }
                    break;
                case 'StudipNewsDidDelete':
                    DBManager::get()->execute(
                        "DELETE FROM `matrix_upcoming_news` WHERE `news_id` = :id",
                        ['id' => $news->id]
                    );
                    break;
            }
        }
    
    }