- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(dirname(dirname(dirname(__FILE__))).'/config.php');
@@ -36,16 +36,10 @@
echo $OUTPUT->header();
echo $OUTPUT->heading('Moodle developers chat');
echo $OUTPUT->box_start('text-center lead');
-?>
+echo html_writer::tag('p', get_string('infohistory', 'local_chatlogs'));
-Historically, Moodle developers used a Jabber chat room for synchronous
-discussions. Since February 1st 2017, the chat has been moved to Telegram. Developers are encouraged to join
-the chat at telegram.me/moodledev.
+echo html_writer::tag('hr', '');
-
-
-pix_icon('telegram', 'Moodle dev and Telegram logos', 'local_chatlogs',
['width' => 118, 'class' => 'img-responsive']);
echo $OUTPUT->box_end();
diff --git a/lang/en/local_chatlogs.php b/lang/en/local_chatlogs.php
index e447688..553f30d 100644
--- a/lang/en/local_chatlogs.php
+++ b/lang/en/local_chatlogs.php
@@ -1,5 +1,5 @@
.
+// along with Moodle. If not, see .
/**
* Lang file for local_chatlogs plugin
@@ -20,7 +20,7 @@
* @package local_chatlogs
* @category string
* @copyright 2012 Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
@@ -33,14 +33,20 @@
$string['chatlogs:manage'] = 'Manage the developer chat logs plugin';
$string['chatlogs:view'] = 'View developer chat logs irrespective of cohort membership';
$string['chatlogs:viewifdeveloper'] = 'View developer chat logs if in developer cohort';
-$string['developerconversations'] = 'Chat history';
$string['developercohort'] = 'Developer cohort';
$string['developercohortdescription'] = 'Select the cohort which developers are in. Users in this cohort and with the local/chatlogs:viewifdeveloper capability will be able to view the chatlogs';
+$string['developerconversations'] = 'Chat history';
$string['info'] = 'Info';
+$string['infohistory'] = 'Historically, Moodle developers used a Jabber chat room for synchronous
+discussions. Since 2017, the chat was moved to Telegram.
+And later, in 2022, it was decided to move everything to Matrix.
+Developers are encouraged to join the chat at telegram.me/moodledev or
+matrix.to/#/#moodledev:moodle.com.
+Both rooms are bridged, so you can use either one.';
$string['jabberaliases'] = 'Aliases';
$string['jabberaliasesassign'] = 'Assign user';
-$string['jabberid'] = 'ID';
$string['jabberfullname'] = 'Nick';
+$string['jabberid'] = 'ID';
$string['pluginname'] = 'Developer chat';
$string['privacy:metadata:db:messages'] = 'Stores copies of developer chat discussions';
$string['privacy:metadata:db:messages:conversationid'] = 'Internal identifier of the conversation';
diff --git a/lib.php b/lib.php
index c4e6420..8c8a912 100644
--- a/lib.php
+++ b/lib.php
@@ -1,5 +1,5 @@
.
+// along with Moodle. If not, see .
/**
* The plugin's external API is defined here
*
* @package local_chatlogs
* @copyright 2012 Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-defined('MOODLE_INTERNAL') || die();
-
/**
* Determines whether the current user can access chatlogs
*
@@ -43,7 +41,7 @@ function local_chatlogs_can_access() {
if ($cohortid = get_config('local_chatlogs', 'cohortid')) {
if ($cohortid > 0) {
// Only allowed to view if in developer cohort.
- if ($DB->get_record('cohort_members', array('cohortid' => $cohortid, 'userid' => $USER->id))) {
+ if ($DB->get_record('cohort_members', ['cohortid' => $cohortid, 'userid' => $USER->id])) {
return true;
}
}
diff --git a/locallib.php b/locallib.php
index 6619c19..85db752 100644
--- a/locallib.php
+++ b/locallib.php
@@ -1,5 +1,5 @@
.
+// along with Moodle. If not, see .
/**
* Provides library functions used by plugin
*
* @package local_chatlogs
* @copyright 2012 Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
@@ -31,7 +31,7 @@
* Table listing jabber conversations
*
* @copyright 2012 Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class local_chatlogs_converations_table extends table_sql {
@@ -49,10 +49,10 @@ public function __construct($uniqueid) {
$this->sql->fields = 'conversationid, messagecount, timestart, timeend, (timestart - timeend) AS duration';
$this->sql->from = '{local_chatlogs_conversations}';
$this->sql->where = 'messagecount > 0';
- $this->sql->params = array();
+ $this->sql->params = [];
- $this->define_columns(array('conversationid', 'participants', 'messagecount', 'timestart', 'timeend', 'duration'));
- $this->define_headers(array('ID', 'Participants', 'Messages', 'Start', 'End', 'Duration'));
+ $this->define_columns(['conversationid', 'participants', 'messagecount', 'timestart', 'timeend', 'duration']);
+ $this->define_headers(['ID', 'Participants', 'Messages', 'Start', 'End', 'Duration']);
$this->no_sorting('participants');
$this->collapsible(false);
$this->sortable(true, 'timeend', SORT_DESC);
@@ -77,7 +77,7 @@ public function col_participants($row) {
LEFT JOIN {user} u ON p.userid = u.id
WHERE m.conversationid = ?
GROUP BY p.fromemail, p.nickname, u.firstname, u.lastname';
- $participants = $DB->get_records_sql_menu($sql, array($row->conversationid));
+ $participants = $DB->get_records_sql_menu($sql, [$row->conversationid]);
$participants = implode(', ', $participants);
return $this->conversation_link($row->conversationid, $participants);
@@ -141,7 +141,7 @@ public function col_timeend($row) {
* @return string HTML of link
*/
private function conversation_link($id, $text) {
- $url = new moodle_url('/local/chatlogs/index.php', array('conversationid' => $id));
+ $url = new moodle_url('/local/chatlogs/index.php', ['conversationid' => $id]);
return html_writer::link($url, $text);
}
@@ -152,7 +152,7 @@ private function conversation_link($id, $text) {
* A jabber conversation
*
* @copyright 2012 Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class local_chatlogs_conversation {
/** @var object From from the chatlogs_conversations table */
@@ -183,7 +183,7 @@ public function __construct($conversationid) {
$this->urlfilter = new local_chatlogs\urlfilter();
$this->conversation = $DB->get_record('local_chatlogs_conversations',
- array('conversationid' => $conversationid), '*', MUST_EXIST);
+ ['conversationid' => $conversationid], '*', MUST_EXIST);
}
/**
@@ -202,13 +202,13 @@ private function get_previous_link() {
$sql = 'SELECT * FROM {local_chatlogs_conversations}
WHERE id != ? AND timeend < ? AND messagecount > 0
ORDER BY timeend DESC LIMIT 1';
- $previous = $DB->get_record_sql($sql, array($this->conversation->id, $this->conversation->timeend));
+ $previous = $DB->get_record_sql($sql, [$this->conversation->id, $this->conversation->timeend]);
if ($previous) {
$url = new moodle_url('/local/chatlogs/index.php',
- array('conversationid' => $previous->conversationid));
+ ['conversationid' => $previous->conversationid]);
$this->previouslink = html_writer::link($url, '◄ '.$previous->messagecount.' messages',
- array('class' => 'previouslink'));
+ ['class' => 'previouslink']);
}
return $this->previouslink;
@@ -230,12 +230,12 @@ private function get_next_link() {
$sql = 'SELECT * FROM {local_chatlogs_conversations}
WHERE id != ? AND timeend > ? AND messagecount > 0
ORDER BY timeend ASC LIMIT 1';
- $next = $DB->get_record_sql($sql, array($this->conversation->id, $this->conversation->timeend));
+ $next = $DB->get_record_sql($sql, [$this->conversation->id, $this->conversation->timeend]);
if ($next) {
- $url = new moodle_url('/local/chatlogs/index.php', array('conversationid' => $next->conversationid));
+ $url = new moodle_url('/local/chatlogs/index.php', ['conversationid' => $next->conversationid]);
$this->nextlink = html_writer::link($url, $next->messagecount.' messages ►',
- array('class' => 'nextlink'));
+ ['class' => 'nextlink']);
}
return $this->nextlink;
@@ -254,13 +254,13 @@ public function conversation_header() {
$header = new html_table();
$header->width = '100%';
- $header->wrap = array('nowrap', '', 'nowrap');
- $header->size = array('', '100%', '');
- $header->data[] = array(
+ $header->wrap = ['nowrap', '', 'nowrap'];
+ $header->size = ['', '100%', ''];
+ $header->data[] = [
$OUTPUT->heading($this->get_previous_link()),
$OUTPUT->heading("$starttime, for $duration"),
$OUTPUT->heading($this->get_next_link()),
- );
+ ];
return html_writer::table($header);
}
@@ -274,15 +274,15 @@ public function conversation_footer() {
global $OUTPUT;
$footer = new html_table();
- $footer->wrap = array('nowrap', '', 'nowrap');
+ $footer->wrap = ['nowrap', '', 'nowrap'];
$footer->width = '100%';
- $footer->size = array('', '100%', '');
- $footer->data[] = array(
+ $footer->size = ['', '100%', ''];
+ $footer->data[] = [
$OUTPUT->heading($this->get_previous_link()),
$OUTPUT->heading(html_writer::link(new moodle_url('/local/chatlogs/index.php'),
get_string('allconversations', 'local_chatlogs'))),
$OUTPUT->heading($this->get_next_link()),
- );
+ ];
return html_writer::table($footer);
}
@@ -308,12 +308,12 @@ public function render() {
WHERE m.conversationid = :conversationid
ORDER BY m.timesent';
- $rs = $DB->get_recordset_sql($sql, array('conversationid' => $this->conversation->conversationid));
+ $rs = $DB->get_recordset_sql($sql, ['conversationid' => $this->conversation->conversationid]);
echo $this->conversation_header();
$table = new html_table();
$table->attributes['class'] = 'devchat';
- $table->wrap = array('nowrap', 'nowrap', '');
+ $table->wrap = ['nowrap', 'nowrap', ''];
foreach ($rs as $message) {
$time = userdate($message->timesent, "%I:%M:%S %P");
@@ -326,7 +326,7 @@ public function render() {
} else {
$namecell->text = $message->nickname . html_writer::empty_tag('br');
}
- $namecell->text .= html_writer::link('#c'.$message->messageid, $time, array('class' => 'jabbertime'));
+ $namecell->text .= html_writer::link('#c'.$message->messageid, $time, ['class' => 'jabbertime']);
$messagecell = new html_table_cell();
$messagecell->attributes['class'] = 'talkmessage';
@@ -339,7 +339,7 @@ public function render() {
}
// This is a bit of a hack to make the format plain, but have clickable links..
- $formatedmessage = format_text($message->message, FORMAT_PLAIN, array('para' => false));
+ $formatedmessage = format_text($message->message, FORMAT_PLAIN, ['para' => false]);
$this->urlfilter->convert_urls_into_links($formatedmessage);
$messagecell->text .= $formatedmessage;
@@ -351,7 +351,7 @@ public function render() {
$row = new html_table_row();
$row->id = 'c'.$message->messageid;
- $row->cells = array($imagecell, $namecell, $messagecell);
+ $row->cells = [$imagecell, $namecell, $messagecell];
$table->data[] = $row;
}
$rs->close();
@@ -363,12 +363,15 @@ public function render() {
}
/**
- * Table listing jabber search results
+ * Table listing chat search results
*
* @copyright 2012 Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class local_chatlogs_search_table extends table_sql {
+ /**
+ * @var string Search term used to search the logs.
+ */
private $searchterm = null;
/**
@@ -399,10 +402,10 @@ public function __construct($uniqueid, $searchterm) {
LEFT JOIN {user} u ON p.userid = u.id';
$this->sql->where = $DB->sql_like('m.message', ':search');
- $this->sql->params = array('search' => '%'.$searchterm.'%');
+ $this->sql->params = ['search' => '%'.$searchterm.'%'];
- $this->define_columns(array('timesent', 'userpic', 'userid', 'message'));
- $this->define_headers(array('Timesent', '', 'User', 'Message'));
+ $this->define_columns(['timesent', 'userpic', 'userid', 'message']);
+ $this->define_headers(['Timesent', '', 'User', 'Message']);
$this->column_class('timesent', 'userinfo');
$this->column_class('userpic', 'userpic');
$this->column_class('userid', 'userinfo usersays');
@@ -420,10 +423,10 @@ public function __construct($uniqueid, $searchterm) {
*/
public function col_timesent($row) {
$link = new moodle_url('/local/chatlogs/index.php');
- $link->params( array('conversationid' => $row->conversationid));
+ $link->params( ['conversationid' => $row->conversationid]);
$link->set_anchor('c'.$row->messageid);
- return html_writer::link($link, userdate($row->timesent), array('class' => 'jabbertime'));
+ return html_writer::link($link, userdate($row->timesent), ['class' => 'jabbertime']);
}
/**
@@ -469,7 +472,7 @@ public function col_message($row) {
$row->message = substr(trim($row->message), 4);
}
- $message = format_text($row->message, FORMAT_MOODLE, array('para' => false));
+ $message = format_text($row->message, FORMAT_MOODLE, ['para' => false]);
$text .= highlight($this->searchterm, $message);
return $text;
@@ -486,11 +489,11 @@ public static function form($searchtext = '') {
$url = new moodle_url('/local/chatlogs/index.php');
- $o .= html_writer::start_tag('div', array('class' => 'searchform'));
- $o .= html_writer::start_tag('form', array('method' => 'get', 'action' => $url->out()));
- $o .= html_writer::empty_tag('input', array('type' => 'text', 'name' => 'q',
- 'value' => $searchtext, 'maxlength' => 100, 'size' => 20));
- $o .= html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('searchmessages', 'local_chatlogs')));
+ $o .= html_writer::start_tag('div', ['class' => 'searchform']);
+ $o .= html_writer::start_tag('form', ['method' => 'get', 'action' => $url->out()]);
+ $o .= html_writer::empty_tag('input', ['type' => 'text', 'name' => 'q',
+ 'value' => $searchtext, 'maxlength' => 100, 'size' => 20]);
+ $o .= html_writer::empty_tag('input', ['type' => 'submit', 'value' => get_string('searchmessages', 'local_chatlogs')]);
$o .= html_writer::end_tag('form');
$o .= html_writer::end_tag('div');
@@ -506,7 +509,7 @@ public static function form($searchtext = '') {
*/
function local_chatlogs_require_capability() {
if (!local_chatlogs_can_access()) {
- print_error('nopermissions', 'error', '', get_string('viewchatlogs', 'local_chatlogs'));
+ throw new moodle_exception('nopermissions', 'error', '', get_string('viewchatlogs', 'local_chatlogs'));
die;
}
}
diff --git a/settings.php b/settings.php
index 9323687..281a6e2 100644
--- a/settings.php
+++ b/settings.php
@@ -1,5 +1,5 @@
.
+// along with Moodle. If not, see .
/**
* Settings for local_chatlogs plugin
*
* @package local_chatlogs
* @copyright 2012 Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/syncchatlogs.php b/syncchatlogs.php
index 2ec115c..9945204 100644
--- a/syncchatlogs.php
+++ b/syncchatlogs.php
@@ -1,5 +1,5 @@
.
+// along with Moodle. If not, see .
+
+/**
+ * CLI script to perform the fetch all the new chat logs to the plugin
+ *
+ * @package local_chatlogs
+ * @copyright 2012 Dan Poltawski
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
@@ -20,7 +28,7 @@
// Only php cli allowed.
if (isset($_SERVER['REMOTE_ADDR'])) {
if ($_SERVER['REMOTE_ADDR'] != "174.123.154.58") {
- print_error('cronerrorclionly', 'admin');
+ throw new moodle_exception('cronerrorclionly', 'admin');
exit;
} else {
$ismoodlebot = true;
@@ -87,7 +95,7 @@
$message->conversationid = $lastmessage->conversationid; // Same.
$conversation = $DB->get_record('local_chatlogs_conversations',
- array('conversationid' => $message->conversationid), '*', MUST_EXIST);
+ ['conversationid' => $message->conversationid], '*', MUST_EXIST);
$conversation->timeend = $message->timesent;
$conversation->messagecount = $conversation->messagecount + 1;
if (!$DB->update_record('local_chatlogs_conversations', $conversation)) {
@@ -120,7 +128,7 @@
// Now check that they have a registered name and if not, register them.
if (empty($currentparticipant[$message->fromemail])) {
- if (!$participant = $DB->get_record('local_chatlogs_participants', array('fromemail' => $message->fromemail))) {
+ if (!$participant = $DB->get_record('local_chatlogs_participants', ['fromemail' => $message->fromemail])) {
$participant = new object;
$participant->fromemail = $message->fromemail;
$participant->nickname = $message->fromnick;
@@ -140,7 +148,7 @@
} else {
$conversationid = $DB->get_field_sql(
"SELECT conversationid FROM {local_chatlogs_conversations} ORDER BY conversationid desc LIMIT 1");
- echo "Synchronised chat logs ($count new messages) - URL: http://moodle.org/local/chatlogs/index.php?conversationid=" .
+ echo "Synchronised chat logs ($count new messages) - URL: https://moodle.org/local/chatlogs/index.php?conversationid=" .
$conversationid."\n";
}
@@ -156,10 +164,10 @@
if ($pushtonext) { // Copy those to this.
$DB->execute(
"UPDATE {local_chatlogs_messages} SET conversationid = $conversation->conversationid WHERE conversationid = ?",
- array($pushtonext));
+ [$pushtonext]);
$DB->execute(
"UPDATE {local_chatlogs_conversations} SET messagecount = 0 WHERE conversationid = ?",
- array($pushtonext));
+ [$pushtonext]);
$pushtonext = 0;
}
diff --git a/tests/telegram_importer_test.php b/tests/telegram_importer_test.php
index 82c82c1..6caa29c 100644
--- a/tests/telegram_importer_test.php
+++ b/tests/telegram_importer_test.php
@@ -1,5 +1,5 @@
.
+// along with Moodle. If not, see .
+
+/**
+ * Telegram importer tests.
+ *
+ * @package local_chatlogs
+ * @copyright 2017 Dan Poltawski
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_chatlogs;
defined('MOODLE_INTERNAL') || die();
@@ -23,11 +33,12 @@
*
* @package local_chatlogs
* @copyright 2017 Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @covers \local_chatlogs_testable_telegram_importer
*/
-class local_chatlogs_telegram_importer_test extends advanced_testcase {
+final class telegram_importer_test extends \advanced_testcase {
- public function test_import_when_empty() {
+ public function test_import_when_empty(): void {
$this->resetAfterTest();
$importer = new local_chatlogs_testable_telegram_importer();
@@ -36,16 +47,16 @@ public function test_import_when_empty() {
$this->assertEmpty($importedcount);
}
- public function test_import_fails_on_bad_json() {
+ public function test_import_fails_on_bad_json(): void {
$this->resetAfterTest();
$importer = new local_chatlogs_testable_telegram_importer();
$importer->set_mock_response('{sdfs:sdf');
- $this->expectException(moodle_exception::class);
+ $this->expectException(\moodle_exception::class);
$importer->import();
}
- public function test_import() {
+ public function test_import(): void {
global $DB;
$this->resetAfterTest();
@@ -109,7 +120,7 @@ public function test_import() {
$this->assertSame(2, $DB->count_records('local_chatlogs_conversations'));
}
- public function test_import_with_existing_data() {
+ public function test_import_with_existing_data(): void {
global $DB;
$this->resetAfterTest();
// Insert some chatlog data.
@@ -157,7 +168,7 @@ public function test_import_with_existing_data() {
$this->assertSame(2, $DB->count_records('local_chatlogs_participants'));
}
- public function test_problematic_mysql_emojis() {
+ public function test_problematic_mysql_emojis(): void {
global $DB;
$this->resetAfterTest();
@@ -180,9 +191,9 @@ public function test_problematic_mysql_emojis() {
* Testable importer which generates mock server response.
* @package local_chatlogs
* @copyright 2017 Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-class local_chatlogs_testable_telegram_importer extends local_chatlogs\telegram_importer {
+class local_chatlogs_testable_telegram_importer extends telegram_importer {
/** @var string|array mock response */
private $mockresponse = null;
@@ -206,9 +217,9 @@ protected function call_api(\moodle_url $url) {
// Simulate server-side filtering of timestamp.
if ($timestamp = $url->param('aftertimestamp')) {
- $afterdate = new DateTime($timestamp);
+ $afterdate = new \DateTime($timestamp);
$resp = array_filter($this->mockresponse, function ($row) use($afterdate) {
- return new DateTime($row->timestamp) > $afterdate;
+ return new \DateTime($row->timestamp) > $afterdate;
});
return json_encode(array_values($resp));
}
diff --git a/version.php b/version.php
index 5a9932b..4428b75 100644
--- a/version.php
+++ b/version.php
@@ -1,5 +1,5 @@
.
+// along with Moodle. If not, see .
/**
* Version details.
*
* @package local_chatlogs
* @copyright Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
@@ -29,6 +29,6 @@
$plugin->version = 2021051000;
$plugin->requires = 2021050700;
$plugin->maturity = MATURITY_STABLE;
-$plugin->dependencies = array(
+$plugin->dependencies = [
'filter_urltolink' => ANY_VERSION,
-);
+];
diff --git a/yui/jabberaliases/jabberaliases.js b/yui/jabberaliases/jabberaliases.js
index 354c46c..5e0e562 100644
--- a/yui/jabberaliases/jabberaliases.js
+++ b/yui/jabberaliases/jabberaliases.js
@@ -3,7 +3,7 @@
* Shamelessly stolen from the dev plugin by Dan
*
* @author David Mudrak
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
YUI.add('moodle-local_chatlogs-jabberaliases', function(Y) {
diff --git a/yui/keyboard/keyboard.js b/yui/keyboard/keyboard.js
index 89d5656..d83fd99 100644
--- a/yui/keyboard/keyboard.js
+++ b/yui/keyboard/keyboard.js
@@ -3,7 +3,7 @@
* between chats.
*
* @author Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
YUI.add('moodle-local_chatlogs-keyboard', function(Y) {