Select Git revision
actionmenu.js
Forked from
Stud.IP / Stud.IP
Source project has a limited visibility.
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;
}
}
}