Rename marketplace plugin to meetletacbfree (mdl_modules.name limit + CI table prefixes)

This commit is contained in:
2026-09-01 23:24:11 +03:30
parent 555cd725f7
commit d987994ded
77 changed files with 1497 additions and 1322 deletions
+9 -9
View File
@@ -1,7 +1,7 @@
# MeetLet Adobe Connect Bridge — Marketplace Edition
**Component:** `mod_meetletacbmarketplace`
**Release:** 1.0.2-marketplace
**Component:** `mod_meetletacbfree`
**Release:** 1.0.9-marketplace
**License:** [GNU GPL v3 or later](COPYING.txt)
Connect Moodle to Adobe Connect for live classes, single sign-on (SSO), recordings, and shared meeting content — without a separate Windows agent or commercial license.
@@ -92,17 +92,17 @@ Standard Moodle PHP requirements also apply.
### From a ZIP package (recommended for production)
1. Download or build a ZIP whose **top-level folder** is named `meetletacbmarketplace` (not `mod_meetletacbmarketplace`).
1. Download or build a ZIP whose **top-level folder** is named `meetletacbfree` (not `mod_meetletacbfree`).
2. In Moodle, go to **Site administration → Plugins → Install plugins**.
3. Upload the ZIP and follow the on-screen prompts.
4. Complete the upgrade when prompted.
### Manual copy
1. Copy the `meetletacbmarketplace` folder into your Moodle `mod/` directory:
1. Copy the `meetletacbfree` folder into your Moodle `mod/` directory:
```
mod/meetletacbmarketplace/
mod/meetletacbfree/
```
2. Log in as administrator and open **Site administration → Notifications** to run the upgrade.
@@ -169,8 +169,8 @@ This plugin is free software licensed under the **GNU General Public License v3.
# پل Adobe Connect میت‌لت — نسخه Marketplace
**کامپوننت:** `mod_meetletacbmarketplace`
**نسخه:** 1.0.2-marketplace
**کامپوننت:** `mod_meetletacbfree`
**نسخه:** 1.0.9-marketplace
**مجوز:** [GNU GPL v3 یا بالاتر](COPYING.txt)
اتصال مودل به Adobe Connect برای کلاس آنلاین، ورود یک‌مرحله‌ای (SSO)، ضبط جلسات و محتوای اشتراکی — بدون نیاز به Agent ویندوز یا لایسنس تجاری.
@@ -256,14 +256,14 @@ This plugin is free software licensed under the **GNU General Public License v3.
### از فایل ZIP (توصیه‌شده)
1. ZIP را طوری آماده کنید که پوشه سطح اول آن `meetletacbmarketplace` باشد.
1. ZIP را طوری آماده کنید که پوشه سطح اول آن `meetletacbfree` باشد.
2. در مودل: **مدیریت سایت → افزونه‌ها → نصب افزونه‌ها**.
3. ZIP را آپلود و مراحل را تکمیل کنید.
4. ارتقای پایگاه داده را اجرا کنید.
### کپی دستی
پوشه `meetletacbmarketplace` را در `mod/` قرار دهید و از **مدیریت سایت → اعلان‌ها** ارتقا را اجرا کنید.
پوشه `meetletacbfree` را در `mod/` قرار دهید و از **مدیریت سایت → اعلان‌ها** ارتقا را اجرا کنید.
### پس از نصب
+3 -3
View File
@@ -17,7 +17,7 @@
/**
* Ajax endpoint: run one Adobe Connect connection-test step.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -26,13 +26,13 @@ define('AJAX_SCRIPT', true);
require_once('../../../config.php');
use mod_meetletacbmarketplace\local\conntest_runner;
use mod_meetletacbfree\local\conntest_runner;
require_login();
require_capability('moodle/site:config', context_system::instance());
require_sesskey();
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$step = required_param('step', PARAM_ALPHA);
$result = conntest_runner::run_step($step);
+8 -8
View File
@@ -4,7 +4,7 @@
/**
* Ajax endpoint: activate / recheck / deactivate MeetLet site registration.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -13,9 +13,9 @@ define('AJAX_SCRIPT', true);
require_once('../../../config.php');
use mod_meetletacbmarketplace\registration\error_mapper;
use mod_meetletacbmarketplace\registration\manager;
use mod_meetletacbmarketplace\registration\registration_exception;
use mod_meetletacbfree\registration\error_mapper;
use mod_meetletacbfree\registration\manager;
use mod_meetletacbfree\registration\registration_exception;
require_login();
require_capability('moodle/site:config', context_system::instance());
@@ -28,14 +28,14 @@ header('Content-Type: application/json; charset=utf-8');
try {
if ($apiurl !== '') {
set_config(manager::CONFIG_API_URL, rtrim($apiurl, '/'), 'meetletacbmarketplace');
set_config(manager::CONFIG_API_URL, rtrim($apiurl, '/'), 'meetletacbfree');
}
if ($action === 'activate') {
manager::activate();
echo json_encode([
'success' => true,
'message' => get_string('registration_activated', 'meetletacbmarketplace'),
'message' => get_string('registration_activated', 'meetletacbfree'),
'summary' => manager::status_summary(),
]);
exit;
@@ -45,7 +45,7 @@ try {
manager::recheck(true);
echo json_encode([
'success' => true,
'message' => get_string('registration_rechecked', 'meetletacbmarketplace'),
'message' => get_string('registration_rechecked', 'meetletacbfree'),
'summary' => manager::status_summary(),
]);
exit;
@@ -55,7 +55,7 @@ try {
manager::deactivate();
echo json_encode([
'success' => true,
'message' => get_string('registration_deactivated', 'meetletacbmarketplace'),
'message' => get_string('registration_deactivated', 'meetletacbfree'),
'summary' => manager::status_summary(),
]);
exit;
+9 -9
View File
@@ -4,7 +4,7 @@
/**
* Reset site access settings (role mapping or feature matrix) to built-in defaults.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -13,14 +13,14 @@ define('AJAX_SCRIPT', true);
require_once('../../../config.php');
use mod_meetletacbmarketplace\local\featureaccess;
use mod_meetletacbmarketplace\local\roles;
use mod_meetletacbfree\local\featureaccess;
use mod_meetletacbfree\local\roles;
require_login();
require_capability('moodle/site:config', context_system::instance());
require_sesskey();
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$section = required_param('section', PARAM_ALPHA);
@@ -30,12 +30,12 @@ try {
if ($section === 'rolemapping') {
$rules = roles::builtin_site_defaults();
$json = json_encode($rules, JSON_UNESCAPED_UNICODE);
set_config('default_participants', $json, 'meetletacbmarketplace');
set_config('default_participants', $json, 'meetletacbfree');
echo json_encode([
'success' => true,
'section' => 'rolemapping',
'matrix' => roles::matrix_from_rules($rules),
'message' => get_string('reset_success_rolemapping', 'meetletacbmarketplace'),
'message' => get_string('reset_success_rolemapping', 'meetletacbfree'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
}
@@ -43,12 +43,12 @@ try {
if ($section === 'featureaccess') {
$matrix = featureaccess::builtin_defaults();
$json = json_encode($matrix, JSON_UNESCAPED_UNICODE);
set_config('featureaccess', $json, 'meetletacbmarketplace');
set_config('featureaccess', $json, 'meetletacbfree');
echo json_encode([
'success' => true,
'section' => 'featureaccess',
'matrix' => $matrix,
'message' => get_string('reset_success_featureaccess', 'meetletacbmarketplace'),
'message' => get_string('reset_success_featureaccess', 'meetletacbfree'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
}
@@ -64,6 +64,6 @@ try {
}
echo json_encode([
'success' => false,
'error' => $error !== '' ? $error : get_string('reset_error', 'meetletacbmarketplace'),
'error' => $error !== '' ? $error : get_string('reset_error', 'meetletacbfree'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
@@ -2,32 +2,32 @@
// This file is part of Moodle - http://moodle.org/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/meetletacbmarketplace/backup/moodle2/backup_meetletacbmarketplace_stepslib.php');
require_once($CFG->dirroot . '/mod/meetletacbfree/backup/moodle2/backup_meetletacbfree_stepslib.php');
/**
* Backup task.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class backup_meetletacbmarketplace_activity_task extends backup_activity_task {
class backup_meetletacbfree_activity_task extends backup_activity_task {
protected function define_my_settings() {
}
protected function define_my_steps() {
$this->add_step(new backup_meetletacbmarketplace_activity_structure_step(
'meetletacbmarketplace_structure',
'meetletacbmarketplace.xml'
$this->add_step(new backup_meetletacbfree_activity_structure_step(
'meetletacbfree_structure',
'meetletacbfree.xml'
));
}
public static function encode_content_links($content) {
global $CFG;
$base = preg_quote($CFG->wwwroot, '/');
$content = preg_replace("/($base\/mod\/meetletacbmarketplace\/index.php\?id=)([0-9]+)/",
$content = preg_replace("/($base\/mod\/meetletacbfree\/index.php\?id=)([0-9]+)/",
'$@MEETLETACBINDEX*$2@$', $content);
$content = preg_replace("/($base\/mod\/meetletacbmarketplace\/view.php\?id=)([0-9]+)/",
$content = preg_replace("/($base\/mod\/meetletacbfree\/view.php\?id=)([0-9]+)/",
'$@MEETLETACBVIEWBYID*$2@$', $content);
$content = preg_replace("/($base\/mod\/meetletadobeconnectbridge\/index.php\?id=)([0-9]+)/",
'$@MEETLETACBINDEX*$2@$', $content);
@@ -5,15 +5,15 @@ defined('MOODLE_INTERNAL') || die();
/**
* Backup structure.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class backup_meetletacbmarketplace_activity_structure_step extends backup_activity_structure_step {
class backup_meetletacbfree_activity_structure_step extends backup_activity_structure_step {
protected function define_structure() {
$userinfo = $this->get_setting_value('userinfo');
$meetlet = new backup_nested_element('meetletacbmarketplace', ['id'], [
$meetlet = new backup_nested_element('meetletacbfree', ['id'], [
'name', 'intro', 'introformat', 'userid', 'templatescoid', 'meeturl',
'starttime', 'endtime', 'meetingpublic', 'participants', 'grade',
'autooffline', 'showzip', 'showofflineplayer', 'showrecordingstab', 'showcontenttab', 'showmp4',
@@ -30,8 +30,8 @@ class backup_meetletacbmarketplace_activity_structure_step extends backup_activi
$meetlet->add_child($meetings);
$meetings->add_child($meeting);
$meetlet->set_source_table('meetletacbmarketplace', ['id' => backup::VAR_ACTIVITYID]);
$meeting->set_source_table('meetlet_marketplace_meetings', ['instanceid' => backup::VAR_PARENTID]);
$meetlet->set_source_table('meetletacbfree', ['id' => backup::VAR_ACTIVITYID]);
$meeting->set_source_table('meetletacbfree_meetings', ['instanceid' => backup::VAR_PARENTID]);
return $this->prepare_activity_structure($meetlet);
}
@@ -2,47 +2,47 @@
// This file is part of Moodle - http://moodle.org/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/meetletacbmarketplace/backup/moodle2/restore_meetletacbmarketplace_stepslib.php');
require_once($CFG->dirroot . '/mod/meetletacbfree/backup/moodle2/restore_meetletacbfree_stepslib.php');
/**
* Restore task.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_meetletacbmarketplace_activity_task extends restore_activity_task {
class restore_meetletacbfree_activity_task extends restore_activity_task {
protected function define_my_settings() {
}
protected function define_my_steps() {
$filename = 'meetletacbmarketplace.xml';
$filename = 'meetletacbfree.xml';
$base = $this->get_taskbasepath();
if ($base) {
foreach (['meetletacbmarketplace.xml', 'meetletadobeconnectbridge.xml', 'meetlet.xml'] as $candidate) {
foreach (['meetletacbfree.xml', 'meetletadobeconnectbridge.xml', 'meetlet.xml'] as $candidate) {
if (file_exists($base . '/' . $candidate)) {
$filename = $candidate;
break;
}
}
}
$this->add_step(new restore_meetletacbmarketplace_activity_structure_step(
'meetletacbmarketplace_structure',
$this->add_step(new restore_meetletacbfree_activity_structure_step(
'meetletacbfree_structure',
$filename
));
}
public static function define_decode_contents() {
return [new restore_decode_content('meetletacbmarketplace', ['intro'], 'meetletacbmarketplace')];
return [new restore_decode_content('meetletacbfree', ['intro'], 'meetletacbfree')];
}
public static function define_decode_rules() {
return [
new restore_decode_rule('MEETLETACBVIEWBYID', '/mod/meetletacbmarketplace/view.php?id=$1', 'course_module'),
new restore_decode_rule('MEETLETACBINDEX', '/mod/meetletacbmarketplace/index.php?id=$1', 'course'),
new restore_decode_rule('MEETLETACBVIEWBYID', '/mod/meetletacbfree/view.php?id=$1', 'course_module'),
new restore_decode_rule('MEETLETACBINDEX', '/mod/meetletacbfree/index.php?id=$1', 'course'),
// Legacy tokens from pre-rename backups.
new restore_decode_rule('MEETLETVIEWBYID', '/mod/meetletacbmarketplace/view.php?id=$1', 'course_module'),
new restore_decode_rule('MEETLETINDEX', '/mod/meetletacbmarketplace/index.php?id=$1', 'course'),
new restore_decode_rule('MEETLETVIEWBYID', '/mod/meetletacbfree/view.php?id=$1', 'course_module'),
new restore_decode_rule('MEETLETINDEX', '/mod/meetletacbfree/index.php?id=$1', 'course'),
];
}
}
@@ -0,0 +1,104 @@
<?php
// This file is part of Moodle - http://moodle.org/
defined('MOODLE_INTERNAL') || die();
/**
* Restore structure.
*
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_meetletacbfree_activity_structure_step extends restore_activity_structure_step {
protected function define_structure() {
$paths = [];
// Current format.
$paths[] = new restore_path_element('meetletacbfree', '/activity/meetletacbfree');
$paths[] = new restore_path_element('meetletacbfree_meeting',
'/activity/meetletacbfree/meetings/meeting');
$paths[] = new restore_path_element('meetletacbfree_long', '/activity/meetletadobeconnectbridge');
$paths[] = new restore_path_element('meetletacbfree_long_meeting',
'/activity/meetletadobeconnectbridge/meetings/meeting');
// Legacy format from pre-rename backups.
$paths[] = new restore_path_element('meetlet_legacy', '/activity/meetlet');
$paths[] = new restore_path_element('meetlet_legacy_meeting', '/activity/meetlet/meetings/meeting');
return $this->prepare_activity_structure($paths);
}
protected function process_meetletacbfree($data) {
$this->process_instance_record($data);
}
protected function process_meetletacbfree_long($data) {
$this->process_instance_record($data);
}
protected function process_meetlet_legacy($data) {
$this->process_instance_record($data);
}
protected function process_instance_record($data) {
global $DB;
$data = (object)$data;
$data->course = $this->get_courseid();
if (!isset($data->showmakeoffline)) {
$data->showmakeoffline = 1;
}
if (!isset($data->settingoverrides)) {
$data->settingoverrides = \mod_meetletacbfree\local\config::setting_overrides_json([
'waitforhost' => !empty($data->waitforhost)
? \mod_meetletacbfree\local\config::OVERRIDE_ON
: \mod_meetletacbfree\local\config::OVERRIDE_OFF,
'autooffline' => !empty($data->autooffline)
? \mod_meetletacbfree\local\config::OVERRIDE_ON
: \mod_meetletacbfree\local\config::OVERRIDE_OFF,
'showzip' => !empty($data->showzip)
? \mod_meetletacbfree\local\config::OVERRIDE_ON
: \mod_meetletacbfree\local\config::OVERRIDE_OFF,
'showrecordingstab' => !empty($data->showrecordingstab)
? \mod_meetletacbfree\local\config::OVERRIDE_ON
: \mod_meetletacbfree\local\config::OVERRIDE_OFF,
'showcontenttab' => !empty($data->showcontenttab)
? \mod_meetletacbfree\local\config::OVERRIDE_ON
: \mod_meetletacbfree\local\config::OVERRIDE_OFF,
'showmp4' => !empty($data->showmp4)
? \mod_meetletacbfree\local\config::OVERRIDE_ON
: \mod_meetletacbfree\local\config::OVERRIDE_OFF,
'showmakeoffline' => !empty($data->showmakeoffline)
? \mod_meetletacbfree\local\config::OVERRIDE_ON
: \mod_meetletacbfree\local\config::OVERRIDE_OFF,
]);
}
if (!isset($data->participantsmode)) {
$data->participantsmode = 1;
}
$newid = $DB->insert_record('meetletacbfree', $data);
$this->apply_activity_instance($newid);
}
protected function process_meetletacbfree_meeting($data) {
$this->process_meeting_record($data, 'meetletacbfree');
}
protected function process_meetletacbfree_long_meeting($data) {
$this->process_meeting_record($data, 'meetletacbfree_long');
}
protected function process_meetlet_legacy_meeting($data) {
$this->process_meeting_record($data, 'meetlet_legacy');
}
protected function process_meeting_record($data, string $parentname) {
global $DB;
$data = (object)$data;
$data->instanceid = $this->get_new_parentid($parentname);
if (!empty($data->groupid)) {
$data->groupid = $this->get_mappingid('group', $data->groupid);
}
$DB->insert_record('meetletacbfree_meetings', $data);
}
protected function after_execute() {
$this->add_related_files('mod_meetletacbfree', 'intro', null);
}
}
@@ -1,104 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
defined('MOODLE_INTERNAL') || die();
/**
* Restore structure.
*
* @package mod_meetletacbmarketplace
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_meetletacbmarketplace_activity_structure_step extends restore_activity_structure_step {
protected function define_structure() {
$paths = [];
// Current format.
$paths[] = new restore_path_element('meetletacbmarketplace', '/activity/meetletacbmarketplace');
$paths[] = new restore_path_element('meetletacbmarketplace_meeting',
'/activity/meetletacbmarketplace/meetings/meeting');
$paths[] = new restore_path_element('meetletacbmarketplace_long', '/activity/meetletadobeconnectbridge');
$paths[] = new restore_path_element('meetletacbmarketplace_long_meeting',
'/activity/meetletadobeconnectbridge/meetings/meeting');
// Legacy format from pre-rename backups.
$paths[] = new restore_path_element('meetlet_legacy', '/activity/meetlet');
$paths[] = new restore_path_element('meetlet_legacy_meeting', '/activity/meetlet/meetings/meeting');
return $this->prepare_activity_structure($paths);
}
protected function process_meetletacbmarketplace($data) {
$this->process_instance_record($data);
}
protected function process_meetletacbmarketplace_long($data) {
$this->process_instance_record($data);
}
protected function process_meetlet_legacy($data) {
$this->process_instance_record($data);
}
protected function process_instance_record($data) {
global $DB;
$data = (object)$data;
$data->course = $this->get_courseid();
if (!isset($data->showmakeoffline)) {
$data->showmakeoffline = 1;
}
if (!isset($data->settingoverrides)) {
$data->settingoverrides = \mod_meetletacbmarketplace\local\config::setting_overrides_json([
'waitforhost' => !empty($data->waitforhost)
? \mod_meetletacbmarketplace\local\config::OVERRIDE_ON
: \mod_meetletacbmarketplace\local\config::OVERRIDE_OFF,
'autooffline' => !empty($data->autooffline)
? \mod_meetletacbmarketplace\local\config::OVERRIDE_ON
: \mod_meetletacbmarketplace\local\config::OVERRIDE_OFF,
'showzip' => !empty($data->showzip)
? \mod_meetletacbmarketplace\local\config::OVERRIDE_ON
: \mod_meetletacbmarketplace\local\config::OVERRIDE_OFF,
'showrecordingstab' => !empty($data->showrecordingstab)
? \mod_meetletacbmarketplace\local\config::OVERRIDE_ON
: \mod_meetletacbmarketplace\local\config::OVERRIDE_OFF,
'showcontenttab' => !empty($data->showcontenttab)
? \mod_meetletacbmarketplace\local\config::OVERRIDE_ON
: \mod_meetletacbmarketplace\local\config::OVERRIDE_OFF,
'showmp4' => !empty($data->showmp4)
? \mod_meetletacbmarketplace\local\config::OVERRIDE_ON
: \mod_meetletacbmarketplace\local\config::OVERRIDE_OFF,
'showmakeoffline' => !empty($data->showmakeoffline)
? \mod_meetletacbmarketplace\local\config::OVERRIDE_ON
: \mod_meetletacbmarketplace\local\config::OVERRIDE_OFF,
]);
}
if (!isset($data->participantsmode)) {
$data->participantsmode = 1;
}
$newid = $DB->insert_record('meetletacbmarketplace', $data);
$this->apply_activity_instance($newid);
}
protected function process_meetletacbmarketplace_meeting($data) {
$this->process_meeting_record($data, 'meetletacbmarketplace');
}
protected function process_meetletacbmarketplace_long_meeting($data) {
$this->process_meeting_record($data, 'meetletacbmarketplace_long');
}
protected function process_meetlet_legacy_meeting($data) {
$this->process_meeting_record($data, 'meetlet_legacy');
}
protected function process_meeting_record($data, string $parentname) {
global $DB;
$data = (object)$data;
$data->instanceid = $this->get_new_parentid($parentname);
if (!empty($data->groupid)) {
$data->groupid = $this->get_mappingid('group', $data->groupid);
}
$DB->insert_record('meetlet_marketplace_meetings', $data);
}
protected function after_execute() {
$this->add_related_files('mod_meetletacbmarketplace', 'intro', null);
}
}
+20 -20
View File
@@ -17,14 +17,14 @@
/**
* Reset-to-default controls for access settings (role mapping + feature matrix).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\admin;
namespace mod_meetletacbfree\admin;
use mod_meetletacbmarketplace\local\icons;
use mod_meetletacbfree\local\icons;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
@@ -41,9 +41,9 @@ class access_reset_ui {
*/
public static function toolbar(string $section): string {
if ($section === 'rolemapping') {
$label = get_string('reset_rolemapping', 'meetletacbmarketplace');
$label = get_string('reset_rolemapping', 'meetletacbfree');
} else if ($section === 'featureaccess') {
$label = get_string('reset_featureaccess', 'meetletacbmarketplace');
$label = get_string('reset_featureaccess', 'meetletacbfree');
} else {
return '';
}
@@ -88,18 +88,18 @@ class access_reset_ui {
*/
public static function client_strings(): array {
return [
'modal_cancel' => get_string('accessreset_modal_cancel', 'meetletacbmarketplace'),
'modal_close' => get_string('accessreset_modal_close', 'meetletacbmarketplace'),
'modal_ok' => get_string('accessreset_modal_ok', 'meetletacbmarketplace'),
'confirm_reset' => get_string('accessreset_confirm_reset', 'meetletacbmarketplace'),
'confirm_rolemapping_title' => get_string('reset_rolemapping_confirm_title', 'meetletacbmarketplace'),
'confirm_rolemapping' => get_string('reset_rolemapping_confirm', 'meetletacbmarketplace'),
'confirm_featureaccess_title' => get_string('reset_featureaccess_confirm_title', 'meetletacbmarketplace'),
'confirm_featureaccess' => get_string('reset_featureaccess_confirm', 'meetletacbmarketplace'),
'success_rolemapping' => get_string('reset_success_rolemapping', 'meetletacbmarketplace'),
'success_featureaccess' => get_string('reset_success_featureaccess', 'meetletacbmarketplace'),
'error' => get_string('reset_error', 'meetletacbmarketplace'),
'busy' => get_string('accessreset_busy', 'meetletacbmarketplace'),
'modal_cancel' => get_string('accessreset_modal_cancel', 'meetletacbfree'),
'modal_close' => get_string('accessreset_modal_close', 'meetletacbfree'),
'modal_ok' => get_string('accessreset_modal_ok', 'meetletacbfree'),
'confirm_reset' => get_string('accessreset_confirm_reset', 'meetletacbfree'),
'confirm_rolemapping_title' => get_string('reset_rolemapping_confirm_title', 'meetletacbfree'),
'confirm_rolemapping' => get_string('reset_rolemapping_confirm', 'meetletacbfree'),
'confirm_featureaccess_title' => get_string('reset_featureaccess_confirm_title', 'meetletacbfree'),
'confirm_featureaccess' => get_string('reset_featureaccess_confirm', 'meetletacbfree'),
'success_rolemapping' => get_string('reset_success_rolemapping', 'meetletacbfree'),
'success_featureaccess' => get_string('reset_success_featureaccess', 'meetletacbfree'),
'error' => get_string('reset_error', 'meetletacbfree'),
'busy' => get_string('accessreset_busy', 'meetletacbfree'),
];
}
@@ -116,7 +116,7 @@ class access_reset_ui {
'type' => 'button',
'class' => 'meetlet-modal__close',
'data-meetlet-modal-dismiss' => '1',
'aria-label' => get_string('accessreset_modal_close', 'meetletacbmarketplace'),
'aria-label' => get_string('accessreset_modal_close', 'meetletacbfree'),
]),
'meetlet-modal__head'
) .
@@ -124,12 +124,12 @@ class access_reset_ui {
'id' => 'meetlet-access-reset-modal-body',
]) .
\html_writer::div(
\html_writer::tag('button', get_string('accessreset_modal_cancel', 'meetletacbmarketplace'), [
\html_writer::tag('button', get_string('accessreset_modal_cancel', 'meetletacbfree'), [
'type' => 'button',
'class' => 'btn btn-outline-secondary',
'data-meetlet-modal-dismiss' => '1',
]) .
\html_writer::tag('button', get_string('accessreset_confirm_reset', 'meetletacbmarketplace'), [
\html_writer::tag('button', get_string('accessreset_confirm_reset', 'meetletacbfree'), [
'type' => 'button',
'class' => 'btn btn-outline-danger',
'id' => 'meetlet-access-reset-modal-confirm',
+7 -7
View File
@@ -17,15 +17,15 @@
/**
* Admin setting: site-wide role × feature access matrix.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\admin;
namespace mod_meetletacbfree\admin;
use admin_setting;
use mod_meetletacbmarketplace\local\featureaccess;
use mod_meetletacbfree\local\featureaccess;
defined('MOODLE_INTERNAL') || die();
@@ -35,9 +35,9 @@ defined('MOODLE_INTERNAL') || die();
class setting_featureaccess extends admin_setting {
public function __construct() {
parent::__construct(
'meetletacbmarketplace/featureaccess',
get_string('featureaccess', 'meetletacbmarketplace'),
get_string('featureaccess_desc', 'meetletacbmarketplace'),
'meetletacbfree/featureaccess',
get_string('featureaccess', 'meetletacbfree'),
get_string('featureaccess_desc', 'meetletacbfree'),
json_encode(featureaccess::builtin_defaults(), JSON_UNESCAPED_UNICODE)
);
}
@@ -78,7 +78,7 @@ class setting_featureaccess extends admin_setting {
$this->description,
true,
'',
get_string('featureaccess_usesite', 'meetletacbmarketplace'),
get_string('featureaccess_usesite', 'meetletacbfree'),
$query
);
}
+45 -45
View File
@@ -4,16 +4,16 @@
/**
* Admin UI for voluntary MeetLet site registration (Marketplace free edition).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\admin;
namespace mod_meetletacbfree\admin;
use admin_setting;
use mod_meetletacbmarketplace\local\icons;
use mod_meetletacbmarketplace\registration\manager;
use mod_meetletacbfree\local\icons;
use mod_meetletacbfree\registration\manager;
defined('MOODLE_INTERNAL') || die();
@@ -23,7 +23,7 @@ defined('MOODLE_INTERNAL') || die();
class setting_registration extends admin_setting {
public function __construct() {
parent::__construct(
'meetletacbmarketplace/registration_panel',
'meetletacbfree/registration_panel',
'',
'',
''
@@ -45,11 +45,11 @@ class setting_registration extends admin_setting {
$summary = manager::status_summary();
$active = !empty($summary['active']);
$candeactivate = !empty($summary['can_deactivate']);
$ajaxurl = new \moodle_url('/mod/meetletacbmarketplace/ajax/registration.php');
$scrolljsurl = new \moodle_url('/mod/meetletacbmarketplace/javascript/meetlet_modal_scroll.js', [
$ajaxurl = new \moodle_url('/mod/meetletacbfree/ajax/registration.php');
$scrolljsurl = new \moodle_url('/mod/meetletacbfree/javascript/meetlet_modal_scroll.js', [
'v' => '2026090146',
]);
$jsurl = new \moodle_url('/mod/meetletacbmarketplace/javascript/settings_registration.js', [
$jsurl = new \moodle_url('/mod/meetletacbfree/javascript/settings_registration.js', [
'v' => '2026090146',
]);
$privacytaburl = manager::privacy_tab_url();
@@ -58,37 +58,37 @@ class setting_registration extends admin_setting {
$statusbadge = \html_writer::span(
s($summary['status_label'] ?? ($active
? get_string('registration_status_active', 'meetletacbmarketplace')
: get_string('registration_status_inactive', 'meetletacbmarketplace'))),
? get_string('registration_status_active', 'meetletacbfree')
: get_string('registration_status_inactive', 'meetletacbfree'))),
'badge meetlet-license-badge ' . ($active ? 'meetlet-license-badge--active' : 'meetlet-license-badge--inactive'),
['id' => 'meetlet-registration-status-badge']
);
$datalist = \html_writer::tag('ul',
\html_writer::tag('li', get_string('registration_data_item_domain', 'meetletacbmarketplace', s($summary['domain']))) .
\html_writer::tag('li', get_string('registration_data_item_moodle', 'meetletacbmarketplace', s($summary['moodle_release']))) .
\html_writer::tag('li', get_string('registration_data_item_plugin', 'meetletacbmarketplace', s($summary['plugin_release']))) .
\html_writer::tag('li', get_string('registration_data_item_installation', 'meetletacbmarketplace', s($summary['installation_id']))) .
\html_writer::tag('li', get_string('registration_data_item_sitename', 'meetletacbmarketplace', s($summary['site_company']))) .
\html_writer::tag('li', get_string('registration_data_item_email', 'meetletacbmarketplace',
$summary['site_admin_email'] !== '' ? s($summary['site_admin_email']) : get_string('registration_data_optional', 'meetletacbmarketplace'))),
\html_writer::tag('li', get_string('registration_data_item_domain', 'meetletacbfree', s($summary['domain']))) .
\html_writer::tag('li', get_string('registration_data_item_moodle', 'meetletacbfree', s($summary['moodle_release']))) .
\html_writer::tag('li', get_string('registration_data_item_plugin', 'meetletacbfree', s($summary['plugin_release']))) .
\html_writer::tag('li', get_string('registration_data_item_installation', 'meetletacbfree', s($summary['installation_id']))) .
\html_writer::tag('li', get_string('registration_data_item_sitename', 'meetletacbfree', s($summary['site_company']))) .
\html_writer::tag('li', get_string('registration_data_item_email', 'meetletacbfree',
$summary['site_admin_email'] !== '' ? s($summary['site_admin_email']) : get_string('registration_data_optional', 'meetletacbfree'))),
['class' => 'meetlet-registration-data']
);
$why = \html_writer::div(
\html_writer::tag('h4', get_string('registration_why_title', 'meetletacbmarketplace')) .
\html_writer::tag('p', get_string('registration_why', 'meetletacbmarketplace')),
\html_writer::tag('h4', get_string('registration_why_title', 'meetletacbfree')) .
\html_writer::tag('p', get_string('registration_why', 'meetletacbfree')),
'meetlet-guide__section'
);
$what = \html_writer::div(
\html_writer::tag('h4', get_string('registration_data_title', 'meetletacbmarketplace')) .
\html_writer::tag('p', get_string('registration_data_sent', 'meetletacbmarketplace')) .
\html_writer::tag('h4', get_string('registration_data_title', 'meetletacbfree')) .
\html_writer::tag('p', get_string('registration_data_sent', 'meetletacbfree')) .
$datalist .
\html_writer::tag('p',
get_string(
'registration_privacy',
'meetletacbmarketplace',
\html_writer::link($privacytaburl, get_string('registration_privacy_tablink', 'meetletacbmarketplace'))
'meetletacbfree',
\html_writer::link($privacytaburl, get_string('registration_privacy_tablink', 'meetletacbfree'))
),
['class' => 'mb-0']
),
@@ -108,12 +108,12 @@ class setting_registration extends admin_setting {
$why .
$what .
\html_writer::div(
\html_writer::tag('p', get_string('registration_status_label', 'meetletacbmarketplace') . ' ' .
\html_writer::tag('p', get_string('registration_status_label', 'meetletacbfree') . ' ' .
\html_writer::span($statusbadge, '', ['id' => 'meetlet-registration-status-badge'])) .
\html_writer::tag('p', get_string('registration_domain', 'meetletacbmarketplace', s($summary['domain'])), [
\html_writer::tag('p', get_string('registration_domain', 'meetletacbfree', s($summary['domain'])), [
'id' => 'meetlet-registration-domain',
]) .
\html_writer::tag('p', get_string('registration_installation', 'meetletacbmarketplace', s($summary['installation_id'])), [
\html_writer::tag('p', get_string('registration_installation', 'meetletacbfree', s($summary['installation_id'])), [
'id' => 'meetlet-registration-installation',
]) .
\html_writer::tag('p', s($summary['product_label'] ?? ''), [
@@ -131,12 +131,12 @@ class setting_registration extends admin_setting {
\html_writer::tag('button',
'<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">'
. '<path fill="currentColor" d="M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z"/></svg>'
. \html_writer::span(get_string('registration_activate', 'meetletacbmarketplace'), 'meetlet-btn-with-icon__label'),
. \html_writer::span(get_string('registration_activate', 'meetletacbfree'), 'meetlet-btn-with-icon__label'),
[
'type' => 'button',
'class' => 'meetlet-settings-btn meetlet-btn-with-icon meetlet-license-btn--free',
'id' => 'meetlet-registration-activate',
'title' => get_string('registration_activate_help', 'meetletacbmarketplace'),
'title' => get_string('registration_activate_help', 'meetletacbfree'),
]
),
'',
@@ -145,7 +145,7 @@ class setting_registration extends admin_setting {
\html_writer::div(
\html_writer::tag('button',
icons::svg('refresh')
. \html_writer::span(get_string('registration_recheck', 'meetletacbmarketplace'), 'meetlet-btn-with-icon__label'),
. \html_writer::span(get_string('registration_recheck', 'meetletacbfree'), 'meetlet-btn-with-icon__label'),
[
'type' => 'button',
'class' => 'btn btn-secondary meetlet-btn-with-icon',
@@ -156,7 +156,7 @@ class setting_registration extends admin_setting {
\html_writer::tag('button',
'<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">'
. '<path fill="currentColor" d="M12 2a10 10 0 1 0 10 10h-2a8 8 0 1 1-8-8V2zm1 5v5.6l3.2 1.9-.8 1.4L11 13.2V7h2z"/></svg>'
. \html_writer::span(get_string('registration_deactivate', 'meetletacbmarketplace'), 'meetlet-btn-with-icon__label'),
. \html_writer::span(get_string('registration_deactivate', 'meetletacbfree'), 'meetlet-btn-with-icon__label'),
[
'type' => 'button',
'class' => 'btn btn-outline-danger meetlet-btn-with-icon',
@@ -171,16 +171,16 @@ class setting_registration extends admin_setting {
'id' => 'meetlet-registration-config',
'data-ajaxurl' => $ajaxurl->out(false),
'data-sesskey' => sesskey(),
'data-api-input' => 'id_s_meetletacbmarketplace_registration_api_url',
'data-label-active' => get_string('registration_status_active', 'meetletacbmarketplace'),
'data-label-inactive' => get_string('registration_status_inactive', 'meetletacbmarketplace'),
'data-label-domain' => get_string('registration_domain', 'meetletacbmarketplace', '__V__'),
'data-label-installation' => get_string('registration_installation', 'meetletacbmarketplace', '__V__'),
'data-confirm-activate-title' => get_string('registration_activate_confirm_title', 'meetletacbmarketplace'),
'data-confirm-activate-ok' => get_string('registration_activate_confirm_ok', 'meetletacbmarketplace'),
'data-confirm-deactivate-title' => get_string('registration_deactivate_confirm_title', 'meetletacbmarketplace'),
'data-confirm-deactivate-ok' => get_string('registration_deactivate_confirm_ok', 'meetletacbmarketplace'),
'data-confirm-deactivate' => get_string('registration_deactivate_confirm', 'meetletacbmarketplace'),
'data-api-input' => 'id_s_meetletacbfree_registration_api_url',
'data-label-active' => get_string('registration_status_active', 'meetletacbfree'),
'data-label-inactive' => get_string('registration_status_inactive', 'meetletacbfree'),
'data-label-domain' => get_string('registration_domain', 'meetletacbfree', '__V__'),
'data-label-installation' => get_string('registration_installation', 'meetletacbfree', '__V__'),
'data-confirm-activate-title' => get_string('registration_activate_confirm_title', 'meetletacbfree'),
'data-confirm-activate-ok' => get_string('registration_activate_confirm_ok', 'meetletacbfree'),
'data-confirm-deactivate-title' => get_string('registration_deactivate_confirm_title', 'meetletacbfree'),
'data-confirm-deactivate-ok' => get_string('registration_deactivate_confirm_ok', 'meetletacbfree'),
'data-confirm-deactivate' => get_string('registration_deactivate_confirm', 'meetletacbfree'),
'hidden' => 'hidden',
]) .
self::confirm_modal_html(),
@@ -191,17 +191,17 @@ class setting_registration extends admin_setting {
}
protected static function confirm_modal_html(): string {
$activatebody = \html_writer::tag('p', get_string('registration_activate_confirm_lead', 'meetletacbmarketplace'), [
$activatebody = \html_writer::tag('p', get_string('registration_activate_confirm_lead', 'meetletacbfree'), [
'class' => 'meetlet-modal__lead',
]) .
\html_writer::tag('p', get_string('registration_activate_confirm_data', 'meetletacbmarketplace'), [
\html_writer::tag('p', get_string('registration_activate_confirm_data', 'meetletacbfree'), [
'class' => 'meetlet-modal__keep',
]);
$deactivatebody = \html_writer::tag('p', get_string('registration_deactivate_confirm_lead', 'meetletacbmarketplace'), [
$deactivatebody = \html_writer::tag('p', get_string('registration_deactivate_confirm_lead', 'meetletacbfree'), [
'class' => 'meetlet-modal__lead',
]) .
\html_writer::div(
\html_writer::tag('p', get_string('registration_deactivate_confirm_warning', 'meetletacbmarketplace'), [
\html_writer::tag('p', get_string('registration_deactivate_confirm_warning', 'meetletacbfree'), [
'class' => 'meetlet-modal__callout-title',
]),
'meetlet-modal__callout'
@@ -219,7 +219,7 @@ class setting_registration extends admin_setting {
'type' => 'button',
'class' => 'meetlet-modal__close',
'data-meetlet-modal-dismiss' => '1',
'aria-label' => get_string('registration_modal_close', 'meetletacbmarketplace'),
'aria-label' => get_string('registration_modal_close', 'meetletacbfree'),
]),
'meetlet-modal__head'
) .
+7 -7
View File
@@ -17,15 +17,15 @@
/**
* Admin setting: default Moodle role → Adobe Connect role mapping.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\admin;
namespace mod_meetletacbfree\admin;
use admin_setting;
use mod_meetletacbmarketplace\local\roles;
use mod_meetletacbfree\local\roles;
defined('MOODLE_INTERNAL') || die();
@@ -35,9 +35,9 @@ defined('MOODLE_INTERNAL') || die();
class setting_rolemapping extends admin_setting {
public function __construct() {
parent::__construct(
'meetletacbmarketplace/default_participants',
get_string('siterolemapping', 'meetletacbmarketplace'),
get_string('siterolemapping_desc', 'meetletacbmarketplace'),
'meetletacbfree/default_participants',
get_string('siterolemapping', 'meetletacbfree'),
get_string('siterolemapping_desc', 'meetletacbfree'),
json_encode(roles::builtin_site_defaults(), JSON_UNESCAPED_UNICODE)
);
}
@@ -81,7 +81,7 @@ class setting_rolemapping extends admin_setting {
$this->description,
true,
'',
get_string('siterolemapping_defaultinfo', 'meetletacbmarketplace'),
get_string('siterolemapping_defaultinfo', 'meetletacbfree'),
$query
);
}
+2 -2
View File
@@ -17,12 +17,12 @@
/**
* Admin settings tabs with a fixed hero above the tab bar.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\admin;
namespace mod_meetletacbfree\admin;
defined('MOODLE_INTERNAL') || die();
+13 -13
View File
@@ -17,14 +17,14 @@
/**
* Adobe Connect XML API client.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\api;
namespace mod_meetletacbfree\api;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbfree\local\config;
use moodle_exception;
use SimpleXMLElement;
@@ -58,11 +58,11 @@ class client {
* @return self
*/
public function login_admin(): self {
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$info = $this->request(['action' => 'common-info']);
$this->cookie = (string)($info->common->cookie ?? '');
if ($this->cookie === '') {
throw new moodle_exception('erroremptyxml', 'meetletacbmarketplace');
throw new moodle_exception('erroremptyxml', 'meetletacbfree');
}
$result = $this->request([
@@ -72,7 +72,7 @@ class client {
]);
if ((string)$result->status['code'] !== 'ok') {
throw new moodle_exception('errorlogin', 'meetletacbmarketplace');
throw new moodle_exception('errorlogin', 'meetletacbfree');
}
return $this;
@@ -85,7 +85,7 @@ class client {
* @return string BREEZESESSION cookie value
*/
public function login_external(string $connectlogin): string {
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$headername = config::get_http_auth_header();
$candidates = array_values(array_unique(array_filter([
@@ -113,7 +113,7 @@ class client {
'adobe_code' => (string)($lastfail['code'] ?? ''),
'adobe_subcode' => (string)($lastfail['subcode'] ?? 'no-login'),
];
throw new \mod_meetletacbmarketplace\local\usererror(
throw new \mod_meetletacbfree\local\usererror(
'sso_01',
'errorhttpauth',
array_filter($facts),
@@ -176,7 +176,7 @@ class client {
'login' => $login,
'code' => $code,
'subcode' => $sub,
'xml' => \mod_meetletacbmarketplace\local\usererror::format_xml($raw),
'xml' => \mod_meetletacbfree\local\usererror::format_xml($raw),
];
}
@@ -227,7 +227,7 @@ class client {
if ($result === false) {
$err = curl_error($ch);
curl_close($ch);
throw new moodle_exception('erroremptyxml', 'meetletacbmarketplace', '', null, $err);
throw new moodle_exception('erroremptyxml', 'meetletacbfree', '', null, $err);
}
curl_close($ch);
return (string)$result;
@@ -266,12 +266,12 @@ class client {
$body = ($xmlstart === false) ? $raw : substr($raw, $xmlstart);
if ($body === '' || $body === false) {
throw new moodle_exception('erroremptyxml', 'meetletacbmarketplace');
throw new moodle_exception('erroremptyxml', 'meetletacbfree');
}
$sx = @simplexml_load_string($body);
if ($sx === false) {
throw new moodle_exception('erroremptyxml', 'meetletacbmarketplace');
throw new moodle_exception('erroremptyxml', 'meetletacbfree');
}
return $sx;
@@ -377,7 +377,7 @@ class client {
if ($result === false) {
$err = curl_error($ch);
curl_close($ch);
throw new moodle_exception('erroremptyxml', 'meetletacbmarketplace', '', null, $err);
throw new moodle_exception('erroremptyxml', 'meetletacbfree', '', null, $err);
}
curl_close($ch);
return (string)$result;
+13 -13
View File
@@ -17,15 +17,15 @@
/**
* High-level Adobe Connect service operations.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\api;
namespace mod_meetletacbfree\api;
use cache;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbfree\local\config;
use moodle_exception;
use stdClass;
@@ -63,7 +63,7 @@ class service {
* Resolve a sco-shortcuts folder id (cached).
*/
public function get_folder_scoid(string $type): int {
$cache = cache::make('mod_meetletacbmarketplace', 'folders');
$cache = cache::make('mod_meetletacbfree', 'folders');
$key = 'folder_' . str_replace('-', '_', $type);
$cached = $cache->get($key);
if ($cached !== false && $cached !== null) {
@@ -92,7 +92,7 @@ class service {
* @return array scoid => name
*/
public function get_templates(): array {
$cache = cache::make('mod_meetletacbmarketplace', 'templates');
$cache = cache::make('mod_meetletacbfree', 'templates');
$cached = $cache->get('all');
if (is_array($cached)) {
return $cached;
@@ -142,7 +142,7 @@ class service {
$xml = $this->client->request($params);
if ((string)$xml->status['code'] !== 'ok') {
throw new moodle_exception('errorcreatemeeting', 'meetletacbmarketplace');
throw new moodle_exception('errorcreatemeeting', 'meetletacbfree');
}
$scoid = (int)$xml->sco['sco-id'];
$this->apply_meeting_options($scoid, $data);
@@ -165,7 +165,7 @@ class service {
$xml = $this->client->request($params);
$ok = (string)$xml->status['code'] === 'ok';
if ($ok) {
cache::make('mod_meetletacbmarketplace', 'meetinginfo')->delete((string)$scoid);
cache::make('mod_meetletacbfree', 'meetinginfo')->delete((string)$scoid);
$this->apply_meeting_options($scoid, $data);
}
return $ok;
@@ -557,7 +557,7 @@ class service {
* Prefer sco-info (fast) over sco-contents listing.
*/
public function meeting_info(int $scoid): ?stdClass {
$cache = cache::make('mod_meetletacbmarketplace', 'meetinginfo');
$cache = cache::make('mod_meetletacbfree', 'meetinginfo');
$cached = $cache->get((string)$scoid);
if (is_object($cached)) {
return $cached;
@@ -682,7 +682,7 @@ class service {
}
}
throw new moodle_exception('errorcreateuser', 'meetletacbmarketplace', '', null, $lastdetail);
throw new moodle_exception('errorcreateuser', 'meetletacbfree', '', null, $lastdetail);
}
/**
@@ -694,7 +694,7 @@ class service {
if ($this->is_reserved_connect_login((string)($adobeuser->login ?? ''))) {
throw new moodle_exception(
'errorcreateuser',
'meetletacbmarketplace',
'meetletacbfree',
'',
null,
'refusing to align reserved principal login=' . $adobeuser->login
@@ -1321,11 +1321,11 @@ class service {
}
foreach ($candidates as $key) {
$stringkey = 'contenticon_' . $key;
if (get_string_manager()->string_exists($stringkey, 'meetletacbmarketplace')) {
return get_string($stringkey, 'meetletacbmarketplace');
if (get_string_manager()->string_exists($stringkey, 'meetletacbfree')) {
return get_string($stringkey, 'meetletacbfree');
}
}
return $icon !== '' && $icon !== 'content' ? $icon : get_string('contenticon_content', 'meetletacbmarketplace');
return $icon !== '' && $icon !== 'content' ? $icon : get_string('contenticon_content', 'meetletacbfree');
}
/**
+3 -3
View File
@@ -14,20 +14,20 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace mod_meetletacbmarketplace\event;
namespace mod_meetletacbfree\event;
defined('MOODLE_INTERNAL') || die();
/**
* Course module viewed event.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_viewed extends \core\event\course_module_viewed {
protected function init() {
$this->data['objecttable'] = 'meetletacbmarketplace';
$this->data['objecttable'] = 'meetletacbfree';
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
+5 -5
View File
@@ -14,26 +14,26 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace mod_meetletacbmarketplace\event;
namespace mod_meetletacbfree\event;
defined('MOODLE_INTERNAL') || die();
/**
* User joined a MeetLet meeting.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class meeting_joined extends \core\event\base {
protected function init() {
$this->data['objecttable'] = 'meetletacbmarketplace';
$this->data['objecttable'] = 'meetletacbfree';
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
public static function get_name() {
return get_string('joinmeeting', 'meetletacbmarketplace');
return get_string('joinmeeting', 'meetletacbfree');
}
public function get_description() {
@@ -41,6 +41,6 @@ class meeting_joined extends \core\event\base {
}
public function get_url() {
return new \moodle_url('/mod/meetletacbmarketplace/view.php', ['id' => $this->contextinstanceid]);
return new \moodle_url('/mod/meetletacbfree/view.php', ['id' => $this->contextinstanceid]);
}
}
+13 -13
View File
@@ -17,25 +17,25 @@
/**
* Ajax: SSO URL to view uploaded meeting content in Adobe Connect.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\external;
namespace mod_meetletacbfree\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbmarketplace\local\content;
use mod_meetletacbmarketplace\local\featureaccess;
use mod_meetletacbmarketplace\local\instance;
use mod_meetletacbmarketplace\local\roles;
use mod_meetletacbmarketplace\local\sso;
use mod_meetletacbmarketplace\local\usererror;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\config;
use mod_meetletacbfree\local\content;
use mod_meetletacbfree\local\featureaccess;
use mod_meetletacbfree\local\instance;
use mod_meetletacbfree\local\roles;
use mod_meetletacbfree\local\sso;
use mod_meetletacbfree\local\usererror;
use moodle_exception;
defined('MOODLE_INTERNAL') || die();
@@ -61,11 +61,11 @@ class get_content_launch_url extends external_api {
'groupid' => $groupid,
]);
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$inst = instance::get_from_cmid($params['cmid'], $params['groupid']);
self::validate_context($inst->context);
require_capability('mod/meetletacbmarketplace:view', $inst->context);
require_capability('mod/meetletacbfree:view', $inst->context);
featureaccess::require_feature(featureaccess::CONTENT, $inst->context, $inst->record);
$service = new service();
@@ -74,7 +74,7 @@ class get_content_launch_url extends external_api {
$service->logout();
if (!$item || empty($item->urlpath)) {
throw new moodle_exception('nocontent', 'meetletacbmarketplace');
throw new moodle_exception('nocontent', 'meetletacbfree');
}
try {
+19 -19
View File
@@ -17,23 +17,23 @@
/**
* Ajax: build SSO join URL.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\external;
namespace mod_meetletacbfree\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbmarketplace\local\instance;
use mod_meetletacbmarketplace\local\roles;
use mod_meetletacbmarketplace\local\sso;
use mod_meetletacbmarketplace\local\usererror;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\config;
use mod_meetletacbfree\local\instance;
use mod_meetletacbfree\local\roles;
use mod_meetletacbfree\local\sso;
use mod_meetletacbfree\local\usererror;
use moodle_exception;
defined('MOODLE_INTERNAL') || die();
@@ -57,17 +57,17 @@ class get_join_url extends external_api {
'groupid' => $groupid,
]);
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$inst = instance::get_from_cmid($params['cmid'], $params['groupid']);
self::validate_context($inst->context);
require_capability('mod/meetletacbmarketplace:view', $inst->context);
if (!\mod_meetletacbmarketplace\local\featureaccess::allowed(
\mod_meetletacbmarketplace\local\featureaccess::JOIN,
require_capability('mod/meetletacbfree:view', $inst->context);
if (!\mod_meetletacbfree\local\featureaccess::allowed(
\mod_meetletacbfree\local\featureaccess::JOIN,
$inst->context,
$inst->record
)) {
throw new moodle_exception('notparticipant', 'meetletacbmarketplace');
throw new moodle_exception('notparticipant', 'meetletacbfree');
}
if ($inst->cm->groupmode != NOGROUPS) {
@@ -75,21 +75,21 @@ class get_join_url extends external_api {
$usrgroups = $usrgroups[0] ?? [];
$aag = has_capability('moodle/site:accessallgroups', $inst->context);
if (!$aag && $params['groupid'] && !in_array($params['groupid'], $usrgroups, false)) {
throw new moodle_exception('usergrouprequired', 'meetletacbmarketplace');
throw new moodle_exception('usergrouprequired', 'meetletacbfree');
}
}
$adoberole = roles::resolve_adobe_role($inst->record, $inst->context, $USER->id);
if ($adoberole === null) {
throw new moodle_exception('notparticipant', 'meetletacbmarketplace');
throw new moodle_exception('notparticipant', 'meetletacbfree');
}
try {
// Gate join before any Adobe user provisioning / SSO.
$lifecycle = \mod_meetletacbmarketplace\local\meetingstatus::resolve($inst, (int)$USER->id, true);
$lifecycle = \mod_meetletacbfree\local\meetingstatus::resolve($inst, (int)$USER->id, true);
if (empty($lifecycle['joinable'])) {
$code = !empty($lifecycle['errorcode']) ? $lifecycle['errorcode'] : 'meetingended';
throw new moodle_exception($code, 'meetletacbmarketplace');
throw new moodle_exception($code, 'meetletacbfree');
}
$scoid = $inst->require_meeting();
@@ -98,13 +98,13 @@ class get_join_url extends external_api {
$info = $service->meeting_info($scoid);
$service->logout();
if (!$info) {
throw new moodle_exception('nomeeting', 'meetletacbmarketplace');
throw new moodle_exception('nomeeting', 'meetletacbfree');
}
$auth = sso::provision_and_login($USER, $scoid, $adoberole);
$url = config::with_html_client(config::public_url($info->url, $auth['cookie']));
$event = \mod_meetletacbmarketplace\event\meeting_joined::create([
$event = \mod_meetletacbfree\event\meeting_joined::create([
'context' => $inst->context,
'objectid' => $inst->record->id,
'relateduserid' => $USER->id,
+7 -7
View File
@@ -17,20 +17,20 @@
/**
* Ajax: poll meeting join status.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\external;
namespace mod_meetletacbfree\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use mod_meetletacbmarketplace\local\featureaccess;
use mod_meetletacbmarketplace\local\instance;
use mod_meetletacbmarketplace\local\meetingstatus;
use mod_meetletacbfree\local\featureaccess;
use mod_meetletacbfree\local\instance;
use mod_meetletacbfree\local\meetingstatus;
defined('MOODLE_INTERNAL') || die();
@@ -53,11 +53,11 @@ class get_meeting_status extends external_api {
'groupid' => $groupid,
]);
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$inst = instance::get_from_cmid($params['cmid'], $params['groupid']);
self::validate_context($inst->context);
require_capability('mod/meetletacbmarketplace:view', $inst->context);
require_capability('mod/meetletacbfree:view', $inst->context);
$info = meetingstatus::resolve($inst, (int)$USER->id, true);
$featurejoin = featureaccess::allowed(featureaccess::JOIN, $inst->context, $inst->record);
+14 -14
View File
@@ -17,24 +17,24 @@
/**
* Ajax: SSO URL to play or edit a recording in Adobe Connect.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\external;
namespace mod_meetletacbfree\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbmarketplace\local\featureaccess;
use mod_meetletacbmarketplace\local\instance;
use mod_meetletacbmarketplace\local\roles;
use mod_meetletacbmarketplace\local\sso;
use mod_meetletacbmarketplace\local\usererror;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\config;
use mod_meetletacbfree\local\featureaccess;
use mod_meetletacbfree\local\instance;
use mod_meetletacbfree\local\roles;
use mod_meetletacbfree\local\sso;
use mod_meetletacbfree\local\usererror;
use moodle_exception;
defined('MOODLE_INTERNAL') || die();
@@ -64,26 +64,26 @@ class get_recording_launch_url extends external_api {
$mode = strtolower($params['mode']);
if (!in_array($mode, ['play', 'edit'], true)) {
throw new moodle_exception('error', 'meetletacbmarketplace');
throw new moodle_exception('error', 'meetletacbfree');
}
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$inst = instance::get_from_cmid($params['cmid'], $params['groupid']);
self::validate_context($inst->context);
require_capability('mod/meetletacbmarketplace:view', $inst->context);
require_capability('mod/meetletacbfree:view', $inst->context);
featureaccess::require_feature(featureaccess::RECORDINGS, $inst->context, $inst->record);
if ($mode === 'edit') {
featureaccess::require_feature(featureaccess::ADOBEEDITOR, $inst->context, $inst->record);
}
$record = $DB->get_record('meetlet_marketplace_recordings', [
$record = $DB->get_record('meetletacbfree_recordings', [
'instanceid' => $inst->record->id,
'recordingscoid' => $params['recordingscoid'],
]);
if (!$record || empty($record->urlpath)) {
throw new moodle_exception('norecordings', 'meetletacbmarketplace');
throw new moodle_exception('norecordings', 'meetletacbfree');
}
try {
+31 -31
View File
@@ -17,24 +17,24 @@
/**
* Ajax: load tab HTML/data.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\external;
namespace mod_meetletacbfree\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbmarketplace\local\content;
use mod_meetletacbmarketplace\local\featureaccess;
use mod_meetletacbmarketplace\local\icons;
use mod_meetletacbmarketplace\local\instance;
use mod_meetletacbmarketplace\local\recordings;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\config;
use mod_meetletacbfree\local\content;
use mod_meetletacbfree\local\featureaccess;
use mod_meetletacbfree\local\icons;
use mod_meetletacbfree\local\instance;
use mod_meetletacbfree\local\recordings;
use moodle_exception;
defined('MOODLE_INTERNAL') || die();
@@ -60,16 +60,16 @@ class get_tab extends external_api {
'groupid' => $groupid,
]);
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$inst = instance::get_from_cmid($params['cmid'], $params['groupid']);
self::validate_context($inst->context);
require_capability('mod/meetletacbmarketplace:view', $inst->context);
require_capability('mod/meetletacbfree:view', $inst->context);
$PAGE->set_context($inst->context);
if (!config::is_configured()) {
return [
'html' => \html_writer::div(get_string('notconfigured', 'meetletacbmarketplace'), 'meetlet-alert'),
'html' => \html_writer::div(get_string('notconfigured', 'meetletacbfree'), 'meetlet-alert'),
'tab' => $params['tab'],
];
}
@@ -78,11 +78,11 @@ class get_tab extends external_api {
switch ($params['tab']) {
case 'details':
// Served locally in the activity page; keep endpoint defensive.
$html = \html_writer::div(get_string('emptydetails', 'meetletacbmarketplace'), 'meetlet-empty');
$html = \html_writer::div(get_string('emptydetails', 'meetletacbfree'), 'meetlet-empty');
break;
case 'info':
// Legacy tab id — no Adobe call.
$html = \html_writer::div(get_string('emptydetails', 'meetletacbmarketplace'), 'meetlet-empty');
$html = \html_writer::div(get_string('emptydetails', 'meetletacbfree'), 'meetlet-empty');
break;
case 'recordings':
featureaccess::require_feature(featureaccess::RECORDINGS, $inst->context, $inst->record);
@@ -93,7 +93,7 @@ class get_tab extends external_api {
$html = self::render_content($inst);
break;
default:
throw new moodle_exception('error', 'meetletacbmarketplace');
throw new moodle_exception('error', 'meetletacbfree');
}
return ['html' => $html, 'tab' => $params['tab']];
@@ -110,7 +110,7 @@ class get_tab extends external_api {
* Toolbar with refresh for cacheable Adobe tabs.
*/
protected static function wrap_refreshable(string $html, string $tab, bool $pending = false): string {
$refreshlabel = get_string('refreshtab', 'meetletacbmarketplace');
$refreshlabel = get_string('refreshtab', 'meetletacbfree');
$refreshcontent = icons::svg('refresh')
. \html_writer::span($refreshlabel, 'meetlet-btn-with-icon__label');
$bits = [
@@ -125,7 +125,7 @@ class get_tab extends external_api {
];
if ($pending) {
$bits[] = \html_writer::div(
\html_writer::span(get_string('jobpollwait', 'meetletacbmarketplace'), 'meetlet-jobpoll__label') .
\html_writer::span(get_string('jobpollwait', 'meetletacbfree'), 'meetlet-jobpoll__label') .
\html_writer::div(\html_writer::div('', 'meetlet-jobpoll__bar'), 'meetlet-jobpoll__track'),
'meetlet-jobpoll',
['aria-live' => 'polite']
@@ -206,7 +206,7 @@ class get_tab extends external_api {
$rows = recordings::for_tab($inst);
if (empty($rows)) {
return self::wrap_refreshable(
\html_writer::div(get_string('norecordings', 'meetletacbmarketplace'), 'meetlet-empty'),
\html_writer::div(get_string('norecordings', 'meetletacbfree'), 'meetlet-empty'),
'recordings'
);
}
@@ -215,21 +215,21 @@ class get_tab extends external_api {
$table = new \html_table();
$table->attributes['class'] = 'generaltable meetlet-table meetlet-table--recordings';
$table->head = [
get_string('recordingname', 'meetletacbmarketplace'),
get_string('recordingdate', 'meetletacbmarketplace'),
get_string('duration', 'meetletacbmarketplace'),
get_string('sessiondetails', 'meetletacbmarketplace'),
get_string('recordingname', 'meetletacbfree'),
get_string('recordingdate', 'meetletacbfree'),
get_string('duration', 'meetletacbfree'),
get_string('sessiondetails', 'meetletacbfree'),
];
foreach ($rows as $r) {
$actions = [];
$actions[] = self::icon_action('play', get_string('play', 'meetletacbmarketplace'), [
$actions[] = self::icon_action('play', get_string('play', 'meetletacbfree'), [
'class' => 'meetlet-iconbtn--play',
'data-action' => 'launch-recording',
'data-mode' => 'play',
'data-recording' => $r->recordingscoid,
]);
if ($canadobeedit && !empty($r->urlpath)) {
$actions[] = self::icon_action('adobeedit', get_string('adobeeditor', 'meetletacbmarketplace'), [
$actions[] = self::icon_action('adobeedit', get_string('adobeeditor', 'meetletacbfree'), [
'class' => 'meetlet-iconbtn--adobeedit',
'data-action' => 'launch-recording',
'data-mode' => 'edit',
@@ -257,7 +257,7 @@ class get_tab extends external_api {
if (!$canedit) {
return \html_writer::div($text, 'meetlet-recname');
}
$pencil = self::icon_action('edit', get_string('editrecording', 'meetletacbmarketplace'), [
$pencil = self::icon_action('edit', get_string('editrecording', 'meetletacbfree'), [
'class' => 'meetlet-iconbtn--edit meetlet-iconbtn--inline',
'data-action' => 'inline-rename',
]);
@@ -283,7 +283,7 @@ class get_tab extends external_api {
$service->logout();
if (empty($items)) {
return self::wrap_refreshable(
\html_writer::div(get_string('nocontent', 'meetletacbmarketplace'), 'meetlet-empty'),
\html_writer::div(get_string('nocontent', 'meetletacbfree'), 'meetlet-empty'),
'content'
);
}
@@ -291,10 +291,10 @@ class get_tab extends external_api {
$table->attributes['class'] = 'generaltable meetlet-table meetlet-table--content';
$table->head = [
get_string('name'),
get_string('contenttype', 'meetletacbmarketplace'),
get_string('contentsize', 'meetletacbmarketplace'),
get_string('contentdate', 'meetletacbmarketplace'),
get_string('sessiondetails', 'meetletacbmarketplace'),
get_string('contenttype', 'meetletacbfree'),
get_string('contentsize', 'meetletacbfree'),
get_string('contentdate', 'meetletacbfree'),
get_string('sessiondetails', 'meetletacbfree'),
];
foreach ($items as $item) {
$scoid = (int)($item->scoid ?? 0);
@@ -307,7 +307,7 @@ class get_tab extends external_api {
];
if ($scoid > 0 && !empty($item->name)) {
$dlurl = content::download_url((int)$USER->id, (int)$inst->cm->id, $scoid)->out(false);
$actions[] = self::icon_action('download', get_string('downloadcontent', 'meetletacbmarketplace'), [
$actions[] = self::icon_action('download', get_string('downloadcontent', 'meetletacbfree'), [
'href' => $dlurl,
'class' => 'meetlet-iconbtn--download',
'target' => '_self',
+13 -13
View File
@@ -17,19 +17,19 @@
/**
* Ajax: rename a recording SCO.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\external;
namespace mod_meetletacbfree\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\instance;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\instance;
use moodle_exception;
defined('MOODLE_INTERNAL') || die();
@@ -57,20 +57,20 @@ class rename_recording extends external_api {
'groupid' => $groupid,
]);
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$inst = instance::get_from_cmid($params['cmid'], $params['groupid']);
self::validate_context($inst->context);
require_capability('mod/meetletacbmarketplace:view', $inst->context);
\mod_meetletacbmarketplace\local\featureaccess::require_feature(
\mod_meetletacbmarketplace\local\featureaccess::EDITRECORDING,
require_capability('mod/meetletacbfree:view', $inst->context);
\mod_meetletacbfree\local\featureaccess::require_feature(
\mod_meetletacbfree\local\featureaccess::EDITRECORDING,
$inst->context,
$inst->record
);
$name = trim($params['name']);
if ($name === '') {
throw new moodle_exception('error', 'meetletacbmarketplace');
throw new moodle_exception('error', 'meetletacbfree');
}
$service = new service();
@@ -78,23 +78,23 @@ class rename_recording extends external_api {
$ok = $service->rename_sco((int)$params['recordingscoid'], $name);
$service->logout();
if (!$ok) {
throw new moodle_exception('errorrenamerecording', 'meetletacbmarketplace');
throw new moodle_exception('errorrenamerecording', 'meetletacbfree');
}
$record = $DB->get_record('meetlet_marketplace_recordings', [
$record = $DB->get_record('meetletacbfree_recordings', [
'instanceid' => $inst->record->id,
'recordingscoid' => (int)$params['recordingscoid'],
]);
if ($record) {
$record->name = $name;
$record->timemodified = time();
$DB->update_record('meetlet_marketplace_recordings', $record);
$DB->update_record('meetletacbfree_recordings', $record);
}
return [
'success' => true,
'name' => $name,
'message' => get_string('recordingrenamed', 'meetletacbmarketplace'),
'message' => get_string('recordingrenamed', 'meetletacbfree'),
];
}
+7 -7
View File
@@ -17,20 +17,20 @@
/**
* Ajax: search/list existing Adobe meetings for the mod form.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\external;
namespace mod_meetletacbfree\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\config;
use moodle_exception;
defined('MOODLE_INTERNAL') || die();
@@ -54,7 +54,7 @@ class search_server_meetings extends external_api {
'courseid' => $courseid,
]);
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
if (!empty($params['courseid'])) {
$context = \context_course::instance((int)$params['courseid']);
@@ -63,12 +63,12 @@ class search_server_meetings extends external_api {
}
self::validate_context($context);
if (!has_capability('moodle/course:manageactivities', $context)
&& !has_capability('mod/meetletacbmarketplace:addinstance', $context)) {
&& !has_capability('mod/meetletacbfree:addinstance', $context)) {
throw new moodle_exception('nopermissions', 'error', '', 'search meetings');
}
if (!config::is_configured()) {
throw new moodle_exception('notconfigured', 'meetletacbmarketplace');
throw new moodle_exception('notconfigured', 'meetletacbfree');
}
$limit = max(1, min(50, (int)$params['limit']));
+25 -25
View File
@@ -17,12 +17,12 @@
/**
* Plugin config helpers.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
/**
* Read MeetLet / Adobe Connect global settings.
@@ -38,35 +38,35 @@ class config {
* API endpoint URL (may already include https://.../api/xml).
*/
public static function get_api_url(): string {
return trim((string)get_config('meetletacbmarketplace', 'host'));
return trim((string)get_config('meetletacbfree', 'host'));
}
/**
* Meeting host domain (no protocol).
*/
public static function get_meet_host(): string {
return trim((string)get_config('meetletacbmarketplace', 'meethost'));
return trim((string)get_config('meetletacbfree', 'meethost'));
}
public static function get_port(): int {
$port = (int)get_config('meetletacbmarketplace', 'port');
$port = (int)get_config('meetletacbfree', 'port');
return $port > 0 ? $port : 443;
}
public static function use_https(): bool {
return (bool)get_config('meetletacbmarketplace', 'https');
return (bool)get_config('meetletacbfree', 'https');
}
public static function get_admin_login(): string {
return (string)get_config('meetletacbmarketplace', 'admin_login');
return (string)get_config('meetletacbfree', 'admin_login');
}
public static function get_admin_password(): string {
return (string)get_config('meetletacbmarketplace', 'admin_password');
return (string)get_config('meetletacbfree', 'admin_password');
}
public static function get_http_auth_header(): string {
$h = trim((string)get_config('meetletacbmarketplace', 'admin_httpauth'));
$h = trim((string)get_config('meetletacbfree', 'admin_httpauth'));
return $h !== '' ? $h : 'Generate-Safe-Random-Token';
}
@@ -75,7 +75,7 @@ class config {
* and realign them to mlu{id}. SSO identity itself is always Moodle id.
*/
public static function use_email_login(): bool {
return (bool)get_config('meetletacbmarketplace', 'email_login');
return (bool)get_config('meetletacbfree', 'email_login');
}
/**
@@ -86,14 +86,14 @@ class config {
if (!self::offline_render_active()) {
return false;
}
return (bool)get_config('meetletacbmarketplace', 'auto_offline');
return (bool)get_config('meetletacbfree', 'auto_offline');
}
/**
* Minutes between recording-sync / auto-MP4 cron runs (1–60, default 5).
*/
public static function cron_interval_minutes(): int {
$v = (int)get_config('meetletacbmarketplace', 'cron_interval');
$v = (int)get_config('meetletacbfree', 'cron_interval');
if ($v < 1) {
$v = 5;
}
@@ -114,7 +114,7 @@ class config {
* How auto-MP4 jobs are handed to the Agent.
*/
public static function agent_dispatch_mode(): string {
$v = trim((string)get_config('meetletacbmarketplace', 'agent_dispatch'));
$v = trim((string)get_config('meetletacbfree', 'agent_dispatch'));
return $v === self::DISPATCH_WINDOW ? self::DISPATCH_WINDOW : self::DISPATCH_IMMEDIATE;
}
@@ -124,7 +124,7 @@ class config {
* @return int[]
*/
public static function agent_dispatch_hours(): array {
$raw = (string)get_config('meetletacbmarketplace', 'agent_dispatch_hours');
$raw = (string)get_config('meetletacbfree', 'agent_dispatch_hours');
if ($raw === '') {
$raw = self::DEFAULT_DISPATCH_HOURS;
}
@@ -200,7 +200,7 @@ class config {
public static function apply_cron_interval(): void {
global $DB;
$mins = self::cron_interval_minutes();
$row = $DB->get_record('task_scheduled', ['classname' => '\\mod_meetletacbmarketplace\\task\\sync_recordings']);
$row = $DB->get_record('task_scheduled', ['classname' => '\\mod_meetletacbfree\\task\\sync_recordings']);
if (!$row) {
return;
}
@@ -221,14 +221,14 @@ class config {
* Configured Render Agent / offline listener base URL (may be empty).
*/
public static function agent_url(): string {
return trim((string)get_config('meetletacbmarketplace', 'agent_url'));
return trim((string)get_config('meetletacbfree', 'agent_url'));
}
/**
* Site-wide default meeting UI language (Adobe Connect), empty = server default.
*/
public static function default_meeting_lang(): string {
$v = get_config('meetletacbmarketplace', 'default_meetinglang');
$v = get_config('meetletacbfree', 'default_meetinglang');
if ($v === false || $v === null) {
return '';
}
@@ -239,7 +239,7 @@ class config {
* Site-wide default: block participants until host joins.
*/
public static function default_wait_for_host(): bool {
return (bool)get_config('meetletacbmarketplace', 'default_waitforhost');
return (bool)get_config('meetletacbfree', 'default_waitforhost');
}
/**
@@ -249,7 +249,7 @@ class config {
*/
public static function meeting_lang_options(): array {
return [
'' => get_string('meetinglang_default', 'meetletacbmarketplace'),
'' => get_string('meetinglang_default', 'meetletacbfree'),
'en' => 'English',
'fa' => 'فارسی',
'ar' => 'العربية',
@@ -286,9 +286,9 @@ class config {
return false;
}
$key = 'enable_' . $feature;
$v = get_config('meetletacbmarketplace', $key);
$v = get_config('meetletacbfree', $key);
if ($v === false && $feature === 'mp4') {
$legacy = get_config('meetletacbmarketplace', 'allow_manual_offline');
$legacy = get_config('meetletacbfree', 'allow_manual_offline');
return $legacy === false ? true : (bool)$legacy;
}
// ZIP is opt-in; other features default on when unset.
@@ -305,7 +305,7 @@ class config {
*/
public static function feature_allow_override(string $feature): bool {
$key = 'allow_override_' . $feature;
$v = get_config('meetletacbmarketplace', $key);
$v = get_config('meetletacbfree', $key);
return $v === false ? true : (bool)$v;
}
@@ -367,9 +367,9 @@ class config {
*/
public static function override_state_options(): array {
return [
self::OVERRIDE_INHERIT => get_string('settingstate_inherit', 'meetletacbmarketplace'),
self::OVERRIDE_OFF => get_string('settingstate_disable', 'meetletacbmarketplace'),
self::OVERRIDE_ON => get_string('settingstate_enable', 'meetletacbmarketplace'),
self::OVERRIDE_INHERIT => get_string('settingstate_inherit', 'meetletacbfree'),
self::OVERRIDE_OFF => get_string('settingstate_disable', 'meetletacbfree'),
self::OVERRIDE_ON => get_string('settingstate_enable', 'meetletacbfree'),
];
}
+22 -22
View File
@@ -17,18 +17,18 @@
/**
* Stepwise Adobe Connect connection tests for admin Ajax UI.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
defined('MOODLE_INTERNAL') || die();
use mod_meetletacbmarketplace\api\client;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\usererror;
use mod_meetletacbfree\api\client;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\usererror;
use Throwable;
/**
@@ -42,7 +42,7 @@ class conntest_runner {
*/
public static function reset(): void {
global $SESSION;
$SESSION->meetletacbmarketplace_conntest = [
$SESSION->meetletacbfree_conntest = [
'service' => null,
'meetings' => null,
'scoid' => null,
@@ -58,19 +58,19 @@ class conntest_runner {
public static function run_step(string $step): array {
global $SESSION;
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
if (empty($SESSION->meetletacbmarketplace_conntest) || $step === 'login') {
if (empty($SESSION->meetletacbfree_conntest) || $step === 'login') {
self::reset();
}
$state = &$SESSION->meetletacbmarketplace_conntest;
$state = &$SESSION->meetletacbfree_conntest;
if (!config::is_configured()) {
return [
'step' => $step,
'label' => get_string('error', 'meetletacbmarketplace'),
'label' => get_string('error', 'meetletacbfree'),
'ok' => false,
'detail' => get_string('notconfigured', 'meetletacbmarketplace'),
'detail' => get_string('notconfigured', 'meetletacbfree'),
'done' => true,
'abort' => true,
];
@@ -91,7 +91,7 @@ class conntest_runner {
default:
return [
'step' => $step,
'label' => get_string('error', 'meetletacbmarketplace'),
'label' => get_string('error', 'meetletacbfree'),
'ok' => false,
'detail' => 'Unknown step',
'done' => true,
@@ -102,7 +102,7 @@ class conntest_runner {
$state['failed'] = true;
return [
'step' => $step,
'label' => get_string('error', 'meetletacbmarketplace'),
'label' => get_string('error', 'meetletacbfree'),
'ok' => false,
'detail' => $e->getMessage(),
'done' => false,
@@ -127,7 +127,7 @@ class conntest_runner {
$service->logout();
return [
'step' => 'login',
'label' => get_string('testlogin', 'meetletacbmarketplace'),
'label' => get_string('testlogin', 'meetletacbfree'),
'ok' => true,
'detail' => '',
'done' => false,
@@ -148,7 +148,7 @@ class conntest_runner {
$service->logout();
return [
'step' => 'folders',
'label' => get_string('testfolders', 'meetletacbmarketplace'),
'label' => get_string('testfolders', 'meetletacbfree'),
'ok' => (bool)$ok,
'detail' => "content={$content} · archives={$archives} · meetings={$meetings}",
'done' => false,
@@ -189,7 +189,7 @@ class conntest_runner {
}
return [
'step' => 'user',
'label' => get_string('testuser', 'meetletacbmarketplace'),
'label' => get_string('testuser', 'meetletacbfree'),
'ok' => (bool)$assigned,
'detail' => '',
'done' => false,
@@ -204,18 +204,18 @@ class conntest_runner {
$sso = new client();
$cookie = $sso->login_external(config::get_admin_login());
$directok = ($cookie !== '');
$directdetail = get_string('testsso_direct_ok', 'meetletacbmarketplace');
$directdetail = get_string('testsso_direct_ok', 'meetletacbfree');
} catch (Throwable $e) {
$msg = $e->getMessage();
$directdetail = get_string('testsso_direct_fail', 'meetletacbmarketplace', usererror::label('sso_01') . ': ' . $msg);
$directdetail = get_string('testsso_direct_fail', 'meetletacbfree', usererror::label('sso_01') . ': ' . $msg);
}
if ($directok && !empty($state['login'])) {
try {
$sso2 = new client();
$sso2->login_external($state['login']);
$directdetail .= ' · ' . get_string('testsso_userok', 'meetletacbmarketplace');
$directdetail .= ' · ' . get_string('testsso_userok', 'meetletacbfree');
} catch (Throwable $e) {
$directdetail .= ' · ' . get_string('testsso_userwarn', 'meetletacbmarketplace');
$directdetail .= ' · ' . get_string('testsso_userwarn', 'meetletacbfree');
}
}
@@ -225,7 +225,7 @@ class conntest_runner {
return [
'step' => 'sso',
'label' => get_string('testsso', 'meetletacbmarketplace'),
'label' => get_string('testsso', 'meetletacbfree'),
'ok' => $directok,
'detail' => $directdetail,
'done' => false,
@@ -253,7 +253,7 @@ class conntest_runner {
self::reset();
return [
'step' => 'cleanup',
'label' => get_string('testmeeting', 'meetletacbmarketplace'),
'label' => get_string('testmeeting', 'meetletacbfree'),
'ok' => $ok,
'detail' => $detail,
'done' => true,
+12 -12
View File
@@ -17,14 +17,14 @@
/**
* Meeting content download helpers (Adobe Connect proxy).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbfree\api\service;
use stdClass;
defined('MOODLE_INTERNAL') || die();
@@ -37,7 +37,7 @@ class content {
* Opaque, HMAC-signed, current-user download URL.
*/
public static function download_url(int $userid, int $cmid, int $scoid): \moodle_url {
return new \moodle_url('/mod/meetletacbmarketplace/download_content.php', [
return new \moodle_url('/mod/meetletacbfree/download_content.php', [
'k' => self::make_download_token($userid, $cmid, $scoid),
]);
}
@@ -50,7 +50,7 @@ class content {
public static function unpack_download_token(string $token): array {
$token = trim($token);
if (!preg_match('/^[A-Za-z0-9_-]+$/', $token)) {
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbmarketplace');
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbfree');
}
$b64 = strtr($token, '-_', '+/');
$pad = strlen($b64) % 4;
@@ -59,12 +59,12 @@ class content {
}
$raw = base64_decode($b64, true);
if ($raw === false || strlen($raw) < 44) {
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbmarketplace');
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbfree');
}
$mac = substr($raw, 0, 32);
$payload = substr($raw, 32);
if (strlen($payload) < 32) {
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbmarketplace');
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbfree');
}
$ids = unpack('Nuid/Ncmid/Ncid/Nexp', substr($payload, 0, 16));
@@ -75,15 +75,15 @@ class content {
$expires = (int)$ids['exp'];
$expected = hash_hmac(
'sha256',
'meetletacbmarketplace-content-v1|' . $userid . ':' . $cmid . ':' . $cid . ':' . $expires . '|' . $nonce,
'meetletacbfree-content-v1|' . $userid . ':' . $cmid . ':' . $cid . ':' . $expires . '|' . $nonce,
self::download_secret(),
true
);
if (!hash_equals($expected, $mac)) {
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbmarketplace');
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbfree');
}
if ($expires < time() || $userid <= 0 || $cmid <= 0 || $cid <= 0) {
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbmarketplace');
throw new \moodle_exception('errorbadcontenttoken', 'meetletacbfree');
}
return ['userid' => $userid, 'cmid' => $cmid, 'cid' => $cid];
}
@@ -183,7 +183,7 @@ class content {
$payload = pack('N4', $userid, $cmid, $scoid, $expires) . $nonce;
$mac = hash_hmac(
'sha256',
'meetletacbmarketplace-content-v1|' . $userid . ':' . $cmid . ':' . $scoid . ':' . $expires . '|' . $nonce,
'meetletacbfree-content-v1|' . $userid . ':' . $cmid . ':' . $scoid . ':' . $expires . '|' . $nonce,
self::download_secret(),
true
);
@@ -191,6 +191,6 @@ class content {
}
protected static function download_secret(): string {
return 'mod_meetletacbmarketplace/content/' . get_site_identifier();
return 'mod_meetletacbfree/content/' . get_site_identifier();
}
}
+15 -15
View File
@@ -17,12 +17,12 @@
/**
* Role-based feature access matrix (site + activity).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
use context;
use stdClass;
@@ -42,7 +42,7 @@ defined('MOODLE_INTERNAL') || die();
* AND optional site/activity visibility switch when mapped.
*
* Do NOT grant access via Moodle capabilities alone (except the base
* mod/meetletacbmarketplace:view gate to open the activity page).
* mod/meetletacbfree:view gate to open the activity page).
* Do NOT special-case admins/hosts outside the matrix.
*
* Adding a new feature:
@@ -245,7 +245,7 @@ class featureaccess {
* Whether the activity form may show a per-activity access matrix.
*/
public static function activity_override_enabled(): bool {
$raw = get_config('meetletacbmarketplace', 'activity_featureaccess');
$raw = get_config('meetletacbfree', 'activity_featureaccess');
if ($raw === false || $raw === null || $raw === '') {
return true;
}
@@ -302,7 +302,7 @@ class featureaccess {
* @return array<string,array<string,int>>
*/
public static function site_matrix(): array {
$raw = get_config('meetletacbmarketplace', 'featureaccess');
$raw = get_config('meetletacbfree', 'featureaccess');
if ($raw === false || $raw === null || $raw === '') {
return self::builtin_defaults();
}
@@ -374,7 +374,7 @@ class featureaccess {
* Use this for tabs, buttons, links, and web-service actions.
*/
public static function allowed(string $feature, context $context, ?stdClass $activity = null, ?int $userid = null): bool {
if (!\mod_meetletacbmarketplace\registration\manager::is_registered()) {
if (!\mod_meetletacbfree\registration\manager::is_registered()) {
return false;
}
$vis = self::visibility_feature($feature);
@@ -388,21 +388,21 @@ class featureaccess {
* Require allowed() or throw.
*/
public static function require_feature(string $feature, context $context, ?stdClass $activity = null): void {
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
if (self::allowed($feature, $context, $activity)) {
return;
}
$vis = self::visibility_feature($feature);
if ($vis !== null && !config::show_feature($vis, $activity)) {
throw new \moodle_exception('featuredisabled', 'meetletacbmarketplace');
throw new \moodle_exception('featuredisabled', 'meetletacbfree');
}
throw new \moodle_exception('nopermissions', 'error', '', self::feature_label($feature));
}
public static function feature_label(string $feature): string {
$key = 'accessfeature_' . $feature;
if (get_string_manager()->string_exists($key, 'meetletacbmarketplace')) {
return get_string($key, 'meetletacbmarketplace');
if (get_string_manager()->string_exists($key, 'meetletacbfree')) {
return get_string($key, 'meetletacbfree');
}
return $feature;
}
@@ -430,7 +430,7 @@ class featureaccess {
}
protected static function view_capability_for_context(context $context): string {
return 'mod/meetletacbmarketplace:view';
return 'mod/meetletacbfree:view';
}
/**
@@ -444,14 +444,14 @@ class featureaccess {
$matrix = self::normalize($matrix);
$roles = self::role_labels();
$features = self::feature_labels();
$strtogglerow = get_string('accessmatrix_toggle_row', 'meetletacbmarketplace');
$strtogglecol = get_string('accessmatrix_toggle_col', 'meetletacbmarketplace');
$strall = get_string('accessmatrix_all', 'meetletacbmarketplace');
$strtogglerow = get_string('accessmatrix_toggle_row', 'meetletacbfree');
$strtogglecol = get_string('accessmatrix_toggle_col', 'meetletacbfree');
$strall = get_string('accessmatrix_all', 'meetletacbfree');
$html = \html_writer::start_div('meetlet-access-matrix', ['data-meetlet-access-matrix' => '1']);
$html .= \html_writer::start_tag('table', ['class' => 'generaltable meetlet-access-table']);
$head = \html_writer::tag('th', get_string('accessrole', 'meetletacbmarketplace'));
$head = \html_writer::tag('th', get_string('accessrole', 'meetletacbfree'));
foreach ($features as $fkey => $flabel) {
$toggle = \html_writer::tag('button', s($strall), [
'type' => 'button',
+2 -2
View File
@@ -17,12 +17,12 @@
/**
* Local inline SVG icons (air-gapped — no CDN).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
defined('MOODLE_INTERNAL') || die();
+8 -8
View File
@@ -17,12 +17,12 @@
/**
* Activity instance helpers.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
use cm_info;
use context_module;
@@ -49,12 +49,12 @@ class instance {
public $meetingmap;
public static function get_from_cmid(int $cmid, int $groupid = 0): self {
list($course, $cm) = get_course_and_cm_from_cmid($cmid, 'meetletacbmarketplace');
list($course, $cm) = get_course_and_cm_from_cmid($cmid, 'meetletacbfree');
return self::from_cm($cm, $course, $groupid);
}
public static function get_from_instanceid(int $instanceid, int $groupid = 0): self {
list($course, $cm) = get_course_and_cm_from_instance($instanceid, 'meetletacbmarketplace');
list($course, $cm) = get_course_and_cm_from_instance($instanceid, 'meetletacbfree');
return self::from_cm($cm, $course, $groupid);
}
@@ -64,15 +64,15 @@ class instance {
$inst->cm = $cm;
$inst->course = $course;
$inst->context = context_module::instance($cm->id);
$inst->record = $DB->get_record('meetletacbmarketplace', ['id' => $cm->instance], '*', MUST_EXIST);
$inst->record = $DB->get_record('meetletacbfree', ['id' => $cm->instance], '*', MUST_EXIST);
$inst->groupid = $groupid;
$inst->meetingmap = $DB->get_record('meetlet_marketplace_meetings', [
$inst->meetingmap = $DB->get_record('meetletacbfree_meetings', [
'instanceid' => $inst->record->id,
'groupid' => $groupid,
]);
if (!$inst->meetingmap && $groupid !== 0) {
// Fallback to no-group mapping.
$inst->meetingmap = $DB->get_record('meetlet_marketplace_meetings', [
$inst->meetingmap = $DB->get_record('meetletacbfree_meetings', [
'instanceid' => $inst->record->id,
'groupid' => 0,
]);
@@ -87,7 +87,7 @@ class instance {
public function require_meeting(): int {
$scoid = $this->meetingscoid();
if (!$scoid) {
throw new moodle_exception('nomeeting', 'meetletacbmarketplace');
throw new moodle_exception('nomeeting', 'meetletacbfree');
}
return $scoid;
}
+19 -19
View File
@@ -17,14 +17,14 @@
/**
* Meeting lifecycle status (schedule + live presence + wait-for-host).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbfree\api\service;
defined('MOODLE_INTERNAL') || die();
@@ -74,30 +74,30 @@ class meetingstatus {
$status = self::CHECKING;
$errorcode = '';
$message = get_string('statuschecking_help', 'meetletacbmarketplace');
$message = get_string('statuschecking_help', 'meetletacbfree');
// Never allow join before Adobe confirms room state.
$joinable = false;
if ($endts > 0 && $endts < $now) {
$status = self::ENDED;
$message = get_string('meetingended', 'meetletacbmarketplace');
$message = get_string('meetingended', 'meetletacbfree');
$errorcode = 'meetingended';
$joinable = $canbypass;
} else if ($startts > $now) {
$status = self::SCHEDULED;
$message = get_string('meetingnotstarted', 'meetletacbmarketplace');
$message = get_string('meetingnotstarted', 'meetletacbfree');
$errorcode = 'meetingnotstarted';
$joinable = $canbypass;
} else if ($waitforhost && !$canbypass) {
// Provisional: assume waiting until Adobe poll confirms a live/open room.
$status = self::WAITINGHOST;
$message = get_string('joinblocked_waitinghost', 'meetletacbmarketplace');
$message = get_string('joinblocked_waitinghost', 'meetletacbfree');
$errorcode = 'waitingforhost';
$joinable = false;
} else if (!$canbypass) {
// Until Adobe confirms the room is live, keep Join disabled for participants.
$status = self::CHECKING;
$message = get_string('statuschecking_help', 'meetletacbmarketplace');
$message = get_string('statuschecking_help', 'meetletacbfree');
$joinable = false;
}
@@ -190,14 +190,14 @@ class meetingstatus {
if (!$canbypass) {
$joinable = false;
$errorcode = 'meetingended';
$message = get_string('meetingended', 'meetletacbmarketplace');
$message = get_string('meetingended', 'meetletacbfree');
}
} else if ($startts > $now) {
$status = self::SCHEDULED;
if (!$canbypass) {
$joinable = false;
$errorcode = 'meetingnotstarted';
$message = get_string('meetingnotstarted', 'meetletacbmarketplace');
$message = get_string('meetingnotstarted', 'meetletacbfree');
}
} else if (!$islive && $checkhost && !$canbypass) {
// Nobody is in the Adobe room yet. Participants must not get a join URL —
@@ -206,12 +206,12 @@ class meetingstatus {
$status = self::WAITINGHOST;
$joinable = false;
$errorcode = 'waitingforhost';
$message = get_string('joinblocked_waitinghost', 'meetletacbmarketplace');
$message = get_string('joinblocked_waitinghost', 'meetletacbfree');
} else if (!$islive && $canbypass && ($waitforhost || $adobehold)) {
// Host/moderator may enter; still show waiting-for-host for clarity.
$status = self::WAITINGHOST;
$joinable = true;
$message = get_string('joinblocked_waitinghost', 'meetletacbmarketplace');
$message = get_string('joinblocked_waitinghost', 'meetletacbfree');
}
if ($service instanceof service) {
@@ -236,7 +236,7 @@ class meetingstatus {
'status' => $status,
'statuslabel' => self::label($status),
'joinable' => $joinable,
'message' => $message !== '' ? $message : get_string('statushelp', 'meetletacbmarketplace'),
'message' => $message !== '' ? $message : get_string('statushelp', 'meetletacbfree'),
'errorcode' => $errorcode,
'starttime' => $startts,
'endtime' => $endts,
@@ -247,17 +247,17 @@ class meetingstatus {
public static function label(string $status): string {
switch ($status) {
case self::LIVE:
return get_string('statuslive', 'meetletacbmarketplace');
return get_string('statuslive', 'meetletacbfree');
case self::ENDED:
return get_string('statusended', 'meetletacbmarketplace');
return get_string('statusended', 'meetletacbfree');
case self::SCHEDULED:
return get_string('statusscheduled', 'meetletacbmarketplace');
return get_string('statusscheduled', 'meetletacbfree');
case self::WAITINGHOST:
return get_string('statuswaitinghost', 'meetletacbmarketplace');
return get_string('statuswaitinghost', 'meetletacbfree');
case self::CHECKING:
return get_string('statuschecking', 'meetletacbmarketplace');
return get_string('statuschecking', 'meetletacbfree');
default:
return get_string('statusopen', 'meetletacbmarketplace');
return get_string('statusopen', 'meetletacbfree');
}
}
}
+4 -4
View File
@@ -17,12 +17,12 @@
/**
* Admin HTML for the in-plugin privacy policy tab (Marketplace edition).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
defined('MOODLE_INTERNAL') || die();
@@ -35,7 +35,7 @@ class privacy_policy {
* Build privacy policy HTML (safe for admin settings heading).
*/
public static function render(): string {
$plugin = 'meetletacbmarketplace';
$plugin = 'meetletacbfree';
$sections = [
self::section('scope', 'privacy_tab_scope_title', 'privacy_tab_scope_body'),
@@ -67,7 +67,7 @@ class privacy_policy {
* @param string $bodykey Lang string key or pre-formatted body HTML.
*/
protected static function section(string $id, string $titlekey, string $bodykey): string {
$plugin = 'meetletacbmarketplace';
$plugin = 'meetletacbfree';
$title = get_string($titlekey, $plugin);
$body = strpos($bodykey, '<') !== false
? $bodykey
+7 -7
View File
@@ -17,14 +17,14 @@
/**
* Recording list sync (community edition — no offline MP4 / agent).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbfree\api\service;
use stdClass;
defined('MOODLE_INTERNAL') || die();
@@ -58,7 +58,7 @@ class recordings {
$out = [];
foreach ($remote as $rec) {
$record = $DB->get_record('meetlet_marketplace_recordings', [
$record = $DB->get_record('meetletacbfree_recordings', [
'instanceid' => $instance->record->id,
'recordingscoid' => $rec->scoid,
]);
@@ -77,7 +77,7 @@ class recordings {
$record->timestart = $rec->datebegin ? strtotime($rec->datebegin) : 0;
$record->timeend = $rec->dateend ? strtotime($rec->dateend) : 0;
$record->timemodified = $now;
$record->id = $DB->insert_record('meetlet_marketplace_recordings', $record);
$record->id = $DB->insert_record('meetletacbfree_recordings', $record);
} else {
$record->name = $rec->name;
$record->urlpath = $rec->urlpath;
@@ -86,7 +86,7 @@ class recordings {
$record->timestart = $rec->datebegin ? strtotime($rec->datebegin) : 0;
$record->timeend = $rec->dateend ? strtotime($rec->dateend) : 0;
$record->timemodified = $now;
$DB->update_record('meetlet_marketplace_recordings', $record);
$DB->update_record('meetletacbfree_recordings', $record);
}
$record->playurl = config::public_url($rec->urlpath);
@@ -104,7 +104,7 @@ class recordings {
global $DB;
$rows = $DB->get_records(
'meetlet_marketplace_recordings',
'meetletacbfree_recordings',
['instanceid' => $instance->record->id],
'timestart DESC, id DESC'
);
+18 -18
View File
@@ -17,15 +17,15 @@
/**
* BBB-style participant role mapping for Adobe Connect.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
use context;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbfree\api\service;
use stdClass;
defined('MOODLE_INTERNAL') || die();
@@ -101,7 +101,7 @@ class roles {
* Site-wide default participant rules from plugin config (or built-in).
*/
public static function get_site_default_rules(): array {
$raw = get_config('meetletacbmarketplace', 'default_participants');
$raw = get_config('meetletacbfree', 'default_participants');
if (is_string($raw) && $raw !== '') {
$decoded = json_decode($raw, true);
if (is_array($decoded) && !empty($decoded)) {
@@ -251,9 +251,9 @@ class roles {
*/
public static function adobe_role_labels(): array {
return [
self::ROLE_HOST => get_string('role_host', 'meetletacbmarketplace'),
self::ROLE_PRESENTER => get_string('role_presenter', 'meetletacbmarketplace'),
self::ROLE_PARTICIPANT => get_string('role_participant', 'meetletacbmarketplace'),
self::ROLE_HOST => get_string('role_host', 'meetletacbfree'),
self::ROLE_PRESENTER => get_string('role_presenter', 'meetletacbfree'),
self::ROLE_PARTICIPANT => get_string('role_participant', 'meetletacbfree'),
];
}
@@ -270,14 +270,14 @@ class roles {
'class' => 'generaltable meetlet-access-table meetlet-rolemapping-table',
]);
$head = \html_writer::tag('th', get_string('accessrole', 'meetletacbmarketplace'));
$head .= \html_writer::tag('th', get_string('adoberole', 'meetletacbmarketplace'));
$head = \html_writer::tag('th', get_string('accessrole', 'meetletacbfree'));
$head .= \html_writer::tag('th', get_string('adoberole', 'meetletacbfree'));
$html .= \html_writer::tag('thead', \html_writer::tag('tr', $head));
$body = '';
// Everyone row first.
$body .= self::mapping_row_html(
get_string('participant_type_all', 'meetletacbmarketplace'),
get_string('participant_type_all', 'meetletacbfree'),
$inputname . '[_all]',
$matrix['_all'] ?? self::ROLE_PARTICIPANT,
$adobelabels,
@@ -387,15 +387,15 @@ class roles {
public static function get_participant_data(context $context, ?stdClass $instance = null): array {
$data = [
'all' => [
'name' => get_string('participant_type_all', 'meetletacbmarketplace'),
'name' => get_string('participant_type_all', 'meetletacbfree'),
'children' => [],
],
'role' => [
'name' => get_string('participant_type_role', 'meetletacbmarketplace'),
'name' => get_string('participant_type_role', 'meetletacbfree'),
'children' => self::get_roles_select($context),
],
'user' => [
'name' => get_string('participant_type_user', 'meetletacbmarketplace'),
'name' => get_string('participant_type_user', 'meetletacbfree'),
'children' => [],
],
];
@@ -426,9 +426,9 @@ class roles {
public static function get_participant_selection_data(): array {
return [
'type_options' => [
'all' => get_string('participant_type_all', 'meetletacbmarketplace'),
'role' => get_string('participant_type_role', 'meetletacbmarketplace'),
'user' => get_string('participant_type_user', 'meetletacbmarketplace'),
'all' => get_string('participant_type_all', 'meetletacbfree'),
'role' => get_string('participant_type_role', 'meetletacbfree'),
'user' => get_string('participant_type_user', 'meetletacbfree'),
],
'type_selected' => 'role',
'options' => ['all' => '---------------'],
@@ -442,10 +442,10 @@ class roles {
* @return string|null Adobe permission-id or null if denied
*/
public static function resolve_adobe_role(stdClass $instance, context $context, int $userid): ?string {
if (has_capability('mod/meetletacbmarketplace:host', $context, $userid)) {
if (has_capability('mod/meetletacbfree:host', $context, $userid)) {
return service::ROLE_HOST;
}
if (has_capability('mod/meetletacbmarketplace:presenter', $context, $userid)) {
if (has_capability('mod/meetletacbfree:presenter', $context, $userid)) {
return service::ROLE_PRESENTER;
}
+6 -6
View File
@@ -17,17 +17,17 @@
/**
* Track Adobe Connect room occupancy for auto MP4 after the class actually ends.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
defined('MOODLE_INTERNAL') || die();
/**
* Persist live/closed room state on meetlet_marketplace_meetings and decide when to sweep recordings.
* Persist live/closed room state on meetletacbfree_meetings and decide when to sweep recordings.
*/
class roomsession {
/** Seconds to keep looking for new recordings after the room empties. */
@@ -48,7 +48,7 @@ class roomsession {
if (!$map || empty($map->id)) {
return false;
}
$row = $DB->get_record('meetlet_marketplace_meetings', ['id' => (int)$map->id]);
$row = $DB->get_record('meetletacbfree_meetings', ['id' => (int)$map->id]);
if (!$row) {
return false;
}
@@ -59,7 +59,7 @@ class roomsession {
if ($islive) {
$row->islive = 1;
$row->liveat = $now;
$DB->update_record('meetlet_marketplace_meetings', $row);
$DB->update_record('meetletacbfree_meetings', $row);
$instance->meetingmap = $row;
return false;
}
@@ -78,7 +78,7 @@ class roomsession {
$row->sweptat = $now;
}
if ($waslive || $due) {
$DB->update_record('meetlet_marketplace_meetings', $row);
$DB->update_record('meetletacbfree_meetings', $row);
}
$instance->meetingmap = $row;
return $due;
+4 -4
View File
@@ -17,12 +17,12 @@
/**
* Admin HTML for Adobe Connect server setup guide.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
defined('MOODLE_INTERNAL') || die();
@@ -34,7 +34,7 @@ class server_guide {
* Build guide HTML (safe for admin settings heading).
*/
public static function render(): string {
$plugin = 'meetletacbmarketplace';
$plugin = 'meetletacbfree';
$match = \html_writer::tag('h4', get_string('serverguide_match_title', $plugin)) .
\html_writer::tag('p', get_string('serverguide_match_intro', $plugin)) .
@@ -97,7 +97,7 @@ class server_guide {
* Help-code table so an admin can match a student-reported ML- code.
*/
protected static function errorcodes_section(): string {
$plugin = 'meetletacbmarketplace';
$plugin = 'meetletacbfree';
$head = \html_writer::tag('tr',
\html_writer::tag('th', get_string('serverguide_errorcodes_col_code', $plugin)) .
\html_writer::tag('th', get_string('serverguide_errorcodes_col_meaning', $plugin)) .
+6 -6
View File
@@ -17,15 +17,15 @@
/**
* Adobe Connect SSO helpers for the current Moodle user.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
use mod_meetletacbmarketplace\api\client;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbfree\api\client;
use mod_meetletacbfree\api\service;
use moodle_exception;
use stdClass;
@@ -76,7 +76,7 @@ class sso {
* @param string[] $logincandidates
*/
public static function breeze_session(array $logincandidates): string {
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$cookie = '';
$lasterror = null;
@@ -138,7 +138,7 @@ class sso {
* @return array{cookie:string,adobeuser:stdClass}
*/
public static function provision_and_login(stdClass $user, int $scoid, string $permission): array {
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$service = new service();
$service->login_admin();
+20 -20
View File
@@ -17,12 +17,12 @@
/**
* Audience-aware MeetLet errors (student vs teacher/admin) with help codes.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\local;
namespace mod_meetletacbfree\local;
use moodle_exception;
@@ -55,7 +55,7 @@ class usererror extends moodle_exception {
if ($this->xml !== '') {
$debug['xml'] = $this->xml;
}
parent::__construct($errorcode, 'meetletacbmarketplace', '', null, json_encode($debug, JSON_UNESCAPED_UNICODE));
parent::__construct($errorcode, 'meetletacbfree', '', null, json_encode($debug, JSON_UNESCAPED_UNICODE));
}
/**
@@ -66,9 +66,9 @@ class usererror extends moodle_exception {
'moodle/site:config',
'moodle/course:update',
'moodle/course:manageactivities',
'mod/meetletacbmarketplace:addinstance',
'mod/meetletacbmarketplace:host',
'mod/meetletacbmarketplace:presenter',
'mod/meetletacbfree:addinstance',
'mod/meetletacbfree:host',
'mod/meetletacbfree:presenter',
], $context, $userid);
}
@@ -147,7 +147,7 @@ class usererror extends moodle_exception {
if (!$staff) {
return [
'code' => $label,
'message' => get_string('error_user_unavailable', 'meetletacbmarketplace', $label),
'message' => get_string('error_user_unavailable', 'meetletacbfree', $label),
'detailhtml' => '',
'staff' => false,
];
@@ -312,13 +312,13 @@ class usererror extends moodle_exception {
protected static function staff_title(string $helpid, \Throwable $e): string {
$cat = self::catalog();
$key = $cat[$helpid]['titlekey'] ?? '';
if ($key !== '' && get_string_manager()->string_exists($key, 'meetletacbmarketplace')) {
return get_string($key, 'meetletacbmarketplace');
if ($key !== '' && get_string_manager()->string_exists($key, 'meetletacbfree')) {
return get_string($key, 'meetletacbfree');
}
if ($e instanceof moodle_exception) {
return $e->getMessage();
}
return get_string('error', 'meetletacbmarketplace');
return get_string('error', 'meetletacbfree');
}
/**
@@ -330,12 +330,12 @@ class usererror extends moodle_exception {
$cat = self::catalog();
$titlekey = $cat[$helpid]['titlekey'] ?? '';
$fixkey = $cat[$helpid]['fixkey'] ?? '';
$title = ($titlekey !== '' && get_string_manager()->string_exists($titlekey, 'meetletacbmarketplace'))
? get_string($titlekey, 'meetletacbmarketplace')
: get_string('error', 'meetletacbmarketplace');
$title = ($titlekey !== '' && get_string_manager()->string_exists($titlekey, 'meetletacbfree'))
? get_string($titlekey, 'meetletacbfree')
: get_string('error', 'meetletacbfree');
$codebox = \html_writer::div(
\html_writer::span(get_string('error_helpcode_label', 'meetletacbmarketplace'), 'meetlet-err__codelabel') .
\html_writer::span(get_string('error_helpcode_label', 'meetletacbfree'), 'meetlet-err__codelabel') .
\html_writer::tag('code', s($label), ['data-copy-code' => $label]),
'meetlet-err__codebox'
);
@@ -348,8 +348,8 @@ class usererror extends moodle_exception {
continue;
}
$dtkey = 'errorfact_' . $key;
$dt = get_string_manager()->string_exists($dtkey, 'meetletacbmarketplace')
? get_string($dtkey, 'meetletacbmarketplace')
$dt = get_string_manager()->string_exists($dtkey, 'meetletacbfree')
? get_string($dtkey, 'meetletacbfree')
: $key;
$rows .= \html_writer::tag(
'div',
@@ -372,17 +372,17 @@ class usererror extends moodle_exception {
$factshtml = $rows !== '' ? \html_writer::tag('dl', $rows, ['class' => 'meetlet-err__facts']) : '';
$fix = '';
if ($fixkey !== '' && get_string_manager()->string_exists($fixkey, 'meetletacbmarketplace')) {
$fix = \html_writer::div(get_string($fixkey, 'meetletacbmarketplace'), 'meetlet-err__fix');
if ($fixkey !== '' && get_string_manager()->string_exists($fixkey, 'meetletacbfree')) {
$fix = \html_writer::div(get_string($fixkey, 'meetletacbfree'), 'meetlet-err__fix');
}
$xmlhtml = '';
if ($parsed['xml'] !== '') {
$xmlhtml = \html_writer::tag('p', get_string('error_adobe_response', 'meetletacbmarketplace'), ['class' => 'meetlet-err__prelabel']) .
$xmlhtml = \html_writer::tag('p', get_string('error_adobe_response', 'meetletacbfree'), ['class' => 'meetlet-err__prelabel']) .
\html_writer::tag('pre', s($parsed['xml']), ['class' => 'meetlet-err__xml']);
}
$guide = \html_writer::tag('p', get_string('error_see_serverguide', 'meetletacbmarketplace'), ['class' => 'meetlet-err__guide']);
$guide = \html_writer::tag('p', get_string('error_see_serverguide', 'meetletacbfree'), ['class' => 'meetlet-err__guide']);
return \html_writer::div(
\html_writer::tag('p', s($title), ['class' => 'meetlet-err__lead']) .
+3 -3
View File
@@ -17,12 +17,12 @@
/**
* Plugin renderer.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\output;
namespace mod_meetletacbfree\output;
use plugin_renderer_base;
@@ -33,6 +33,6 @@ defined('MOODLE_INTERNAL') || die();
*/
class renderer extends plugin_renderer_base {
public function render_view_page(view_page $page): string {
return $this->render_from_template('mod_meetletacbmarketplace/view_page', $page->export_for_template($this));
return $this->render_from_template('mod_meetletacbfree/view_page', $page->export_for_template($this));
}
}
+19 -19
View File
@@ -17,17 +17,17 @@
/**
* View page renderable.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\output;
namespace mod_meetletacbfree\output;
use mod_meetletacbmarketplace\local\featureaccess;
use mod_meetletacbmarketplace\local\icons;
use mod_meetletacbmarketplace\local\instance;
use mod_meetletacbmarketplace\local\meetingstatus;
use mod_meetletacbfree\local\featureaccess;
use mod_meetletacbfree\local\icons;
use mod_meetletacbfree\local\instance;
use mod_meetletacbfree\local\meetingstatus;
use renderable;
use renderer_base;
use templatable;
@@ -69,11 +69,11 @@ class view_page implements renderable, templatable {
$startts = (int)$lifecycle['starttime'];
$endts = (int)$lifecycle['endtime'];
$intro = format_module_intro('meetletacbmarketplace', $rec, $this->instance->cm->id);
$intro = format_module_intro('meetletacbfree', $rec, $this->instance->cm->id);
$tabs = [
[
'id' => 'details',
'label' => get_string('tabdetails', 'meetletacbmarketplace'),
'label' => get_string('tabdetails', 'meetletacbfree'),
'icon' => icons::svg('details'),
'active' => true,
],
@@ -81,7 +81,7 @@ class view_page implements renderable, templatable {
if (featureaccess::allowed(featureaccess::RECORDINGS, $this->instance->context, $rec)) {
$tabs[] = [
'id' => 'recordings',
'label' => get_string('tabrecordings', 'meetletacbmarketplace'),
'label' => get_string('tabrecordings', 'meetletacbfree'),
'icon' => icons::svg('recordings'),
'active' => false,
];
@@ -89,7 +89,7 @@ class view_page implements renderable, templatable {
if (featureaccess::allowed(featureaccess::CONTENT, $this->instance->context, $rec)) {
$tabs[] = [
'id' => 'content',
'label' => get_string('tabcontent', 'meetletacbmarketplace'),
'label' => get_string('tabcontent', 'meetletacbfree'),
'icon' => icons::svg('content'),
'active' => false,
];
@@ -104,12 +104,12 @@ class view_page implements renderable, templatable {
'name' => format_string($rec->name),
'intro' => $intro,
'hasintro' => trim(strip_tags($intro)) !== '',
'detailstitle' => get_string('tabdetails', 'meetletacbmarketplace'),
'emptydetails' => get_string('emptydetails', 'meetletacbmarketplace'),
'detailstitle' => get_string('tabdetails', 'meetletacbfree'),
'emptydetails' => get_string('emptydetails', 'meetletacbfree'),
'configured' => $this->configured,
'notconfiguredmsg' => get_string('notconfigured', 'meetletacbmarketplace'),
'subtitle' => get_string('subtitle', 'meetletacbmarketplace'),
'logourl' => $output->image_url('adobeconnect', 'meetletacbmarketplace')->out(false),
'notconfiguredmsg' => get_string('notconfigured', 'meetletacbfree'),
'subtitle' => get_string('subtitle', 'meetletacbfree'),
'logourl' => $output->image_url('adobeconnect', 'meetletacbfree')->out(false),
'status' => $status,
'statuslabel' => $statuslabel,
'statusmessage' => (string)$lifecycle['message'],
@@ -117,10 +117,10 @@ class view_page implements renderable, templatable {
'endtime' => $endts ? userdate($endts) : '',
'hasend' => !empty($endts),
'tabs' => $tabs,
'loading' => get_string('loading', 'meetletacbmarketplace'),
'joining' => get_string('joining', 'meetletacbmarketplace'),
'joiningtitle' => get_string('joiningtitle', 'meetletacbmarketplace'),
'joinlabel' => get_string('joinmeeting', 'meetletacbmarketplace'),
'loading' => get_string('loading', 'meetletacbfree'),
'joining' => get_string('joining', 'meetletacbfree'),
'joiningtitle' => get_string('joiningtitle', 'meetletacbfree'),
'joinlabel' => get_string('joinmeeting', 'meetletacbfree'),
'canjoin' => $featurejoin,
'joinable' => $joinable,
'statuspollseconds' => $this->registrationusable ? 15 : 0,
+45 -45
View File
@@ -15,14 +15,14 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy API for mod_meetletacbmarketplace.
* Privacy API for mod_meetletacbfree.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\privacy;
namespace mod_meetletacbfree\privacy;
defined('MOODLE_INTERNAL') || die();
@@ -54,26 +54,26 @@ class provider implements
* @return collection
*/
public static function get_metadata(collection $collection): collection {
$collection->add_database_table('meetletacbmarketplace', [
'userid' => 'privacy:metadata:meetletacbmarketplace:userid',
'name' => 'privacy:metadata:meetletacbmarketplace:name',
'intro' => 'privacy:metadata:meetletacbmarketplace:intro',
'participants' => 'privacy:metadata:meetletacbmarketplace:participants',
'timecreated' => 'privacy:metadata:meetletacbmarketplace:timecreated',
'timemodified' => 'privacy:metadata:meetletacbmarketplace:timemodified',
], 'privacy:metadata:meetletacbmarketplace');
$collection->add_database_table('meetletacbfree', [
'userid' => 'privacy:metadata:meetletacbfree:userid',
'name' => 'privacy:metadata:meetletacbfree:name',
'intro' => 'privacy:metadata:meetletacbfree:intro',
'participants' => 'privacy:metadata:meetletacbfree:participants',
'timecreated' => 'privacy:metadata:meetletacbfree:timecreated',
'timemodified' => 'privacy:metadata:meetletacbfree:timemodified',
], 'privacy:metadata:meetletacbfree');
$collection->add_database_table('meetlet_marketplace_meetings', [
'groupid' => 'privacy:metadata:meetlet_marketplace_meetings:groupid',
'meetingscoid' => 'privacy:metadata:meetlet_marketplace_meetings:meetingscoid',
'urlpath' => 'privacy:metadata:meetlet_marketplace_meetings:urlpath',
], 'privacy:metadata:meetlet_marketplace_meetings');
$collection->add_database_table('meetletacbfree_meetings', [
'groupid' => 'privacy:metadata:meetletacbfree_meetings:groupid',
'meetingscoid' => 'privacy:metadata:meetletacbfree_meetings:meetingscoid',
'urlpath' => 'privacy:metadata:meetletacbfree_meetings:urlpath',
], 'privacy:metadata:meetletacbfree_meetings');
$collection->add_database_table('meetlet_marketplace_recordings', [
'name' => 'privacy:metadata:meetlet_marketplace_recordings:name',
'urlpath' => 'privacy:metadata:meetlet_marketplace_recordings:urlpath',
'jobstatus' => 'privacy:metadata:meetlet_marketplace_recordings:jobstatus',
], 'privacy:metadata:meetlet_marketplace_recordings');
$collection->add_database_table('meetletacbfree_recordings', [
'name' => 'privacy:metadata:meetletacbfree_recordings:name',
'urlpath' => 'privacy:metadata:meetletacbfree_recordings:urlpath',
'jobstatus' => 'privacy:metadata:meetletacbfree_recordings:jobstatus',
], 'privacy:metadata:meetletacbfree_recordings');
$collection->add_external_location_link('adobeconnect', [
'firstname' => 'privacy:metadata:adobeconnect:firstname',
@@ -82,11 +82,11 @@ class provider implements
'username' => 'privacy:metadata:adobeconnect:username',
], 'privacy:metadata:adobeconnect');
$collection->add_database_table('meetlet_marketplace_license', [
'installation_id' => 'privacy:metadata:meetlet_marketplace_license:installation_id',
'status' => 'privacy:metadata:meetlet_marketplace_license:status',
'last_validated' => 'privacy:metadata:meetlet_marketplace_license:last_validated',
], 'privacy:metadata:meetlet_marketplace_license');
$collection->add_database_table('meetletacbfree_license', [
'installation_id' => 'privacy:metadata:meetletacbfree_license:installation_id',
'status' => 'privacy:metadata:meetletacbfree_license:status',
'last_validated' => 'privacy:metadata:meetletacbfree_license:last_validated',
], 'privacy:metadata:meetletacbfree_license');
$collection->add_external_location_link('meetlet_registration', [
'domain' => 'privacy:metadata:meetlet_registration:domain',
@@ -115,11 +115,11 @@ class provider implements
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {meetletacbmarketplace} a ON a.id = cm.instance
JOIN {meetletacbfree} a ON a.id = cm.instance
WHERE a.userid = :userid";
$contextlist->add_from_sql($sql, [
'contextlevel' => CONTEXT_MODULE,
'modname' => 'meetletacbmarketplace',
'modname' => 'meetletacbfree',
'userid' => $userid,
]);
@@ -131,12 +131,12 @@ class provider implements
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {meetletacbmarketplace} a ON a.id = cm.instance
JOIN {meetletacbfree} a ON a.id = cm.instance
WHERE " . $DB->sql_like('a.participants', ':pat1') . "
OR " . $DB->sql_like('a.participants', ':pat2');
$contextlist->add_from_sql($sql, [
'contextlevel' => CONTEXT_MODULE,
'modname' => 'meetletacbmarketplace',
'modname' => 'meetletacbfree',
'pat1' => $pat1,
'pat2' => $pat2,
]);
@@ -157,12 +157,12 @@ class provider implements
$params = [
'instanceid' => $context->instanceid,
'modulename' => 'meetletacbmarketplace',
'modulename' => 'meetletacbfree',
];
$sql = "SELECT a.userid
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {meetletacbmarketplace} a ON a.id = cm.instance
JOIN {meetletacbfree} a ON a.id = cm.instance
WHERE cm.id = :instanceid AND a.userid <> 0";
$userlist->add_from_sql('userid', $sql, $params);
@@ -171,7 +171,7 @@ class provider implements
"SELECT a.participants
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {meetletacbmarketplace} a ON a.id = cm.instance
JOIN {meetletacbfree} a ON a.id = cm.instance
WHERE cm.id = :instanceid",
$params
);
@@ -209,11 +209,11 @@ class provider implements
if ($context->contextlevel !== CONTEXT_MODULE) {
continue;
}
$cm = get_coursemodule_from_id('meetletacbmarketplace', $context->instanceid);
$cm = get_coursemodule_from_id('meetletacbfree', $context->instanceid);
if (!$cm) {
continue;
}
$activity = $DB->get_record('meetletacbmarketplace', ['id' => $cm->instance]);
$activity = $DB->get_record('meetletacbfree', ['id' => $cm->instance]);
if (!$activity) {
continue;
}
@@ -226,7 +226,7 @@ class provider implements
'is_creator' => ((int)$activity->userid === $userid),
'timecreated' => empty($activity->timecreated) ? null : transform::datetime($activity->timecreated),
'timemodified' => empty($activity->timemodified) ? null : transform::datetime($activity->timemodified),
'adobeconnect_note' => get_string('privacy:export:adobeconnect', 'meetletacbmarketplace'),
'adobeconnect_note' => get_string('privacy:export:adobeconnect', 'meetletacbfree'),
];
$userrules = [];
@@ -263,18 +263,18 @@ class provider implements
if (!$context instanceof \context_module) {
return;
}
$cm = get_coursemodule_from_id('meetletacbmarketplace', $context->instanceid);
$cm = get_coursemodule_from_id('meetletacbfree', $context->instanceid);
if (!$cm) {
return;
}
$activity = $DB->get_record('meetletacbmarketplace', ['id' => $cm->instance]);
$activity = $DB->get_record('meetletacbfree', ['id' => $cm->instance]);
if (!$activity) {
return;
}
$activity->userid = 0;
$activity->participants = self::strip_user_rules((string)($activity->participants ?? ''), null);
$activity->timemodified = time();
$DB->update_record('meetletacbmarketplace', $activity);
$DB->update_record('meetletacbfree', $activity);
}
/**
@@ -290,11 +290,11 @@ class provider implements
if ($context->contextlevel !== CONTEXT_MODULE) {
continue;
}
$cm = get_coursemodule_from_id('meetletacbmarketplace', $context->instanceid);
$cm = get_coursemodule_from_id('meetletacbfree', $context->instanceid);
if (!$cm) {
continue;
}
$activity = $DB->get_record('meetletacbmarketplace', ['id' => $cm->instance]);
$activity = $DB->get_record('meetletacbfree', ['id' => $cm->instance]);
if (!$activity) {
continue;
}
@@ -303,7 +303,7 @@ class provider implements
}
$activity->participants = self::strip_user_rules((string)($activity->participants ?? ''), $userid);
$activity->timemodified = time();
$DB->update_record('meetletacbmarketplace', $activity);
$DB->update_record('meetletacbfree', $activity);
}
}
@@ -323,11 +323,11 @@ class provider implements
if (!$userids) {
return;
}
$cm = get_coursemodule_from_id('meetletacbmarketplace', $context->instanceid);
$cm = get_coursemodule_from_id('meetletacbfree', $context->instanceid);
if (!$cm) {
return;
}
$activity = $DB->get_record('meetletacbmarketplace', ['id' => $cm->instance]);
$activity = $DB->get_record('meetletacbfree', ['id' => $cm->instance]);
if (!$activity) {
return;
}
@@ -338,7 +338,7 @@ class provider implements
$activity->participants = self::strip_user_rules((string)($activity->participants ?? ''), (int)$userid);
}
$activity->timemodified = time();
$DB->update_record('meetletacbmarketplace', $activity);
$DB->update_record('meetletacbfree', $activity);
}
/**
+2 -2
View File
@@ -4,12 +4,12 @@
/**
* HTTP client for MeetLet registration API.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\registration;
namespace mod_meetletacbfree\registration;
defined('MOODLE_INTERNAL') || die();
+6 -6
View File
@@ -4,12 +4,12 @@
/**
* Ed25519 + canonical JSON helpers (compatible with @meetlet/crypto).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\registration;
namespace mod_meetletacbfree\registration;
defined('MOODLE_INTERNAL') || die();
@@ -85,7 +85,7 @@ PEM;
}
$raw = base64_decode(strtr($b64, '-_', '+/'), true);
if ($raw === false) {
throw new \moodle_exception('registration_crypto_error', 'meetletacbmarketplace');
throw new \moodle_exception('registration_crypto_error', 'meetletacbfree');
}
return $raw;
}
@@ -95,7 +95,7 @@ PEM;
*/
public static function generate_installation_keypair(): array {
if (!function_exists('sodium_crypto_sign_keypair')) {
throw new \moodle_exception('registration_sodium_required', 'meetletacbmarketplace');
throw new \moodle_exception('registration_sodium_required', 'meetletacbfree');
}
$kp = sodium_crypto_sign_keypair();
$secret = sodium_crypto_sign_secretkey($kp);
@@ -129,7 +129,7 @@ PEM;
$b64 = preg_replace('/\s+/', '', $b64);
$der = base64_decode($b64, true);
if ($der === false || strlen($der) < 32) {
throw new \moodle_exception('registration_crypto_error', 'meetletacbmarketplace');
throw new \moodle_exception('registration_crypto_error', 'meetletacbfree');
}
return substr($der, -32);
}
@@ -140,7 +140,7 @@ PEM;
$b64 = preg_replace('/\s+/', '', $b64);
$der = base64_decode($b64, true);
if ($der === false || strlen($der) < 48) {
throw new \moodle_exception('registration_crypto_error', 'meetletacbmarketplace');
throw new \moodle_exception('registration_crypto_error', 'meetletacbfree');
}
$seed = substr($der, -32);
$kp = sodium_crypto_sign_seed_keypair($seed);
+4 -4
View File
@@ -4,12 +4,12 @@
/**
* Map registration API / local error codes → product status and UX behaviour.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\registration;
namespace mod_meetletacbfree\registration;
defined('MOODLE_INTERNAL') || die();
@@ -107,8 +107,8 @@ class error_mapper {
}
public static function user_message(string $messagekey, string $fallback = ''): string {
if ($messagekey !== '' && get_string_manager()->string_exists($messagekey, 'meetletacbmarketplace')) {
return get_string($messagekey, 'meetletacbmarketplace');
if ($messagekey !== '' && get_string_manager()->string_exists($messagekey, 'meetletacbfree')) {
return get_string($messagekey, 'meetletacbfree');
}
return $fallback !== '' ? $fallback : $messagekey;
}
+19 -19
View File
@@ -7,12 +7,12 @@
* Hard-locks all plugin features until the administrator completes voluntary
* online activation. After activation, every Marketplace feature unlocks.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\registration;
namespace mod_meetletacbfree\registration;
defined('MOODLE_INTERNAL') || die();
@@ -28,7 +28,7 @@ class manager {
public const DEFAULT_API_URL = 'https://license.webatsign.com';
public static function api_base_url(): string {
$url = trim((string)get_config('meetletacbmarketplace', self::CONFIG_API_URL));
$url = trim((string)get_config('meetletacbfree', self::CONFIG_API_URL));
$url = rtrim($url, '/');
return $url !== '' ? $url : self::DEFAULT_API_URL;
}
@@ -53,16 +53,16 @@ class manager {
*/
public static function settings_tab_url(string $tab): \moodle_url {
return new \moodle_url('/admin/settings.php', [
'section' => 'modsettingmeetletacbmarketplace',
'section' => 'modsettingmeetletacbfree',
], $tab);
}
public static function settings_url(): \moodle_url {
return self::settings_tab_url('meetletacbmarketplace_registration');
return self::settings_tab_url('meetletacbfree_registration');
}
public static function privacy_tab_url(): \moodle_url {
return self::settings_tab_url('meetletacbmarketplace_privacy');
return self::settings_tab_url('meetletacbfree_privacy');
}
/**
@@ -82,7 +82,7 @@ class manager {
if (self::is_registered()) {
return;
}
throw new \moodle_exception('registration_required', 'meetletacbmarketplace', self::settings_url());
throw new \moodle_exception('registration_required', 'meetletacbfree', self::settings_url());
}
/** @deprecated Use require_registered() */
@@ -96,9 +96,9 @@ class manager {
}
$url = self::settings_url();
return \html_writer::div(
\html_writer::tag('strong', get_string('registration_gate_title', 'meetletacbmarketplace')) .
' ' . get_string('registration_gate_body', 'meetletacbmarketplace') . ' ' .
\html_writer::link($url, get_string('registration_gate_link', 'meetletacbmarketplace')),
\html_writer::tag('strong', get_string('registration_gate_title', 'meetletacbfree')) .
' ' . get_string('registration_gate_body', 'meetletacbfree') . ' ' .
\html_writer::link($url, get_string('registration_gate_link', 'meetletacbfree')),
'alert alert-warning meetlet-registration-gate mb-3'
);
}
@@ -113,7 +113,7 @@ class manager {
public static function activate(): array {
if (self::is_registered()) {
throw new \moodle_exception('registration_already_active', 'meetletacbmarketplace');
throw new \moodle_exception('registration_already_active', 'meetletacbfree');
}
$row = store::get_record();
$stale = $row && in_array($row->status ?? '', [
@@ -194,7 +194,7 @@ class manager {
'status' => $status,
'status_label' => self::status_label($active ? error_mapper::STATUS_ACTIVE : $status),
'product' => $active ? self::PRODUCT_SLUG : '',
'product_label' => $active ? get_string('registration_product_free', 'meetletacbmarketplace') : '',
'product_label' => $active ? get_string('registration_product_free', 'meetletacbfree') : '',
'can_deactivate' => self::can_deactivate($row),
'auth_expires_at' => self::parse_unix_timestamp($payload['expires_at'] ?? null),
'features' => is_array($payload['features'] ?? null) ? $payload['features'] : [],
@@ -263,8 +263,8 @@ class manager {
public static function status_label(string $status): string {
$key = 'registration_status_' . $status;
if (get_string_manager()->string_exists($key, 'meetletacbmarketplace')) {
return get_string($key, 'meetletacbmarketplace');
if (get_string_manager()->string_exists($key, 'meetletacbfree')) {
return get_string($key, 'meetletacbfree');
}
return $status;
}
@@ -301,7 +301,7 @@ class manager {
if ($expires !== null && time() >= $expires) {
self::invalidate_local([
'code' => 'LICENSE_EXPIRED',
'message' => get_string('registration_err_expired', 'meetletacbmarketplace'),
'message' => get_string('registration_err_expired', 'meetletacbfree'),
'at' => time(),
], error_mapper::STATUS_EXPIRED);
return true;
@@ -424,7 +424,7 @@ class manager {
'runtime' => 'php',
'runtime_version' => PHP_VERSION,
'metadata' => [
'plugin' => 'mod_meetletacbmarketplace',
'plugin' => 'mod_meetletacbfree',
'plugin_release' => self::plugin_release(),
],
];
@@ -555,7 +555,7 @@ class manager {
*/
protected static function status_error_message(string $status, ?array $lasterror): ?string {
if ($status === error_mapper::STATUS_EXPIRED) {
return get_string('registration_err_expired', 'meetletacbmarketplace');
return get_string('registration_err_expired', 'meetletacbfree');
}
return $lasterror['message'] ?? null;
}
@@ -603,14 +603,14 @@ class manager {
public static function plugin_release(): string {
global $CFG;
$plugin = new \stdClass();
$versionfile = $CFG->dirroot . '/mod/meetletacbmarketplace/version.php';
$versionfile = $CFG->dirroot . '/mod/meetletacbfree/version.php';
if (is_readable($versionfile)) {
include($versionfile);
}
if (!empty($plugin->release)) {
return (string)$plugin->release;
}
$ver = get_config('meetletacbmarketplace', 'version');
$ver = get_config('meetletacbfree', 'version');
return $ver !== false ? (string)$ver : '0';
}
}
@@ -4,12 +4,12 @@
/**
* Structured registration API / local client exception.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\registration;
namespace mod_meetletacbfree\registration;
defined('MOODLE_INTERNAL') || die();
@@ -40,7 +40,7 @@ class registration_exception extends \moodle_exception {
$this->requestid = $requestid !== null && $requestid !== '' ? $requestid : null;
parent::__construct(
'registration_api_error',
'meetletacbmarketplace',
'meetletacbfree',
'',
$this->apicode . ': ' . $this->apimessage
);
+4 -4
View File
@@ -4,20 +4,20 @@
/**
* Persist MeetLet installation identity + cached runtime authorization.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\registration;
namespace mod_meetletacbfree\registration;
defined('MOODLE_INTERNAL') || die();
/**
* Single-row registration store in meetlet_marketplace_license.
* Single-row registration store in meetletacbfree_license.
*/
class store {
public const TABLE = 'meetlet_marketplace_license';
public const TABLE = 'meetletacbfree_license';
/**
* @return \stdClass|null
+4 -4
View File
@@ -17,14 +17,14 @@
/**
* Scheduled task: optional MeetLet site registration heartbeat.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\task;
namespace mod_meetletacbfree\task;
use mod_meetletacbmarketplace\registration\manager;
use mod_meetletacbfree\registration\manager;
defined('MOODLE_INTERNAL') || die();
@@ -33,7 +33,7 @@ defined('MOODLE_INTERNAL') || die();
*/
class registration_heartbeat extends \core\task\scheduled_task {
public function get_name() {
return get_string('task_registration_heartbeat', 'meetletacbmarketplace');
return get_string('task_registration_heartbeat', 'meetletacbfree');
}
public function execute() {
+9 -9
View File
@@ -17,16 +17,16 @@
/**
* Scheduled task: sync Adobe Connect recordings into Moodle.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_meetletacbmarketplace\task;
namespace mod_meetletacbfree\task;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\instance;
use mod_meetletacbmarketplace\local\recordings;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\instance;
use mod_meetletacbfree\local\recordings;
defined('MOODLE_INTERNAL') || die();
@@ -35,17 +35,17 @@ defined('MOODLE_INTERNAL') || die();
*/
class sync_recordings extends \core\task\scheduled_task {
public function get_name() {
return get_string('tasksync', 'meetletacbmarketplace');
return get_string('tasksync', 'meetletacbfree');
}
public function execute() {
if (!\mod_meetletacbmarketplace\registration\manager::is_registered()) {
if (!\mod_meetletacbfree\registration\manager::is_registered()) {
mtrace('MeetLet registration: inactive — skip recording sync.');
return;
}
global $DB;
foreach ($DB->get_records('meetletacbmarketplace') as $activity) {
foreach ($DB->get_records('meetlet_marketplace_meetings', ['instanceid' => $activity->id]) as $map) {
foreach ($DB->get_records('meetletacbfree') as $activity) {
foreach ($DB->get_records('meetletacbfree_meetings', ['instanceid' => $activity->id]) as $map) {
try {
$inst = instance::get_from_instanceid((int)$activity->id, (int)$map->groupid);
$service = new service();
+23 -23
View File
@@ -3,48 +3,48 @@
require_once('../../config.php');
use mod_meetletacbmarketplace\api\client;
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbfree\api\client;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\config;
require_login();
require_capability('moodle/site:config', context_system::instance());
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
global $OUTPUT, $PAGE;
$PAGE->set_context(context_system::instance());
$PAGE->set_url(new moodle_url('/mod/meetletacbmarketplace/conntest.php'));
$PAGE->set_title(get_string('conntesttitle', 'meetletacbmarketplace'));
$PAGE->set_url(new moodle_url('/mod/meetletacbfree/conntest.php'));
$PAGE->set_title(get_string('conntesttitle', 'meetletacbfree'));
$PAGE->set_pagelayout('admin');
$PAGE->requires->css(new moodle_url('/mod/meetletacbmarketplace/styles.css', ['v' => '2026081415']));
$PAGE->requires->css(new moodle_url('/mod/meetletacbfree/styles.css', ['v' => '2026081415']));
$results = [];
$push = static function(string $label, bool $ok, string $detail = '') use (&$results): void {
$results[] = ['label' => $label, 'ok' => $ok, 'detail' => $detail];
};
$logo = $OUTPUT->image_url('adobeconnect', 'meetletacbmarketplace');
$logo = $OUTPUT->image_url('adobeconnect', 'meetletacbfree');
echo $OUTPUT->header();
echo html_writer::start_div('meetlet-conntest');
echo html_writer::start_div('meetlet-conntest__hero');
echo html_writer::img($logo, 'Adobe Connect', ['class' => 'meetlet-conntest__logo']);
echo html_writer::tag('h2', get_string('conntesttitle', 'meetletacbmarketplace'), ['class' => 'meetlet-conntest__title']);
echo html_writer::tag('p', get_string('conntestintro', 'meetletacbmarketplace'), ['class' => 'meetlet-conntest__intro']);
echo html_writer::tag('h2', get_string('conntesttitle', 'meetletacbfree'), ['class' => 'meetlet-conntest__title']);
echo html_writer::tag('p', get_string('conntestintro', 'meetletacbfree'), ['class' => 'meetlet-conntest__intro']);
echo html_writer::end_div();
if (!config::is_configured()) {
echo html_writer::div(get_string('notconfigured', 'meetletacbmarketplace'), 'meetlet-alert');
echo html_writer::div(get_string('notconfigured', 'meetletacbfree'), 'meetlet-alert');
} else {
try {
$service = new service();
$client = $service->get_client();
$service->login_admin();
$push(get_string('testlogin', 'meetletacbmarketplace'), true);
$push(get_string('testlogin', 'meetletacbfree'), true);
$content = $service->get_folder_scoid('content');
$archives = $service->get_folder_scoid('forced-archives');
$meetings = $service->get_folder_scoid('meetings');
$push(get_string('testfolders', 'meetletacbmarketplace'), ($content && $archives && $meetings),
$push(get_string('testfolders', 'meetletacbfree'), ($content && $archives && $meetings),
"content={$content} · archives={$archives} · meetings={$meetings}");
$meeting = (object)[
@@ -65,7 +65,7 @@ if (!config::is_configured()) {
$principal = $service->ensure_user($user);
$assigned = $service->assign_permission($principal->principalid, $scoid, service::ROLE_PRESENTER);
$push(get_string('testuser', 'meetletacbmarketplace'), $assigned);
$push(get_string('testuser', 'meetletacbfree'), $assigned);
// SSO: prefer admin (known good), then disposable created login/ext-login.
$ssook = false;
@@ -74,7 +74,7 @@ if (!config::is_configured()) {
$sso = new client();
$cookie = $sso->login_external(config::get_admin_login());
$ssook = ($cookie !== '');
$ssodetail = get_string('testsso_adminok', 'meetletacbmarketplace');
$ssodetail = get_string('testsso_adminok', 'meetletacbfree');
} catch (Throwable $e) {
$ssodetail = $e->getMessage();
}
@@ -82,28 +82,28 @@ if (!config::is_configured()) {
try {
$sso2 = new client();
$cookie2 = $sso2->login_external($principal->login);
$ssodetail .= ' · ' . get_string('testsso_userok', 'meetletacbmarketplace');
$ssodetail .= ' · ' . get_string('testsso_userok', 'meetletacbfree');
} catch (Throwable $e) {
// Admin SSO is enough for infrastructure health.
$ssodetail .= ' · ' . get_string('testsso_userwarn', 'meetletacbmarketplace');
$ssodetail .= ' · ' . get_string('testsso_userwarn', 'meetletacbfree');
}
}
$push(get_string('testsso', 'meetletacbmarketplace'), $ssook, $ssodetail);
$push(get_string('testsso', 'meetletacbfree'), $ssook, $ssodetail);
$service->delete_sco($scoid);
$client->request(['action' => 'principals-delete', 'principal-id' => $principal->principalid]);
$push(get_string('testmeeting', 'meetletacbmarketplace'), true);
$push(get_string('testmeeting', 'meetletacbfree'), true);
$service->logout();
} catch (Throwable $e) {
$push(get_string('error', 'meetletacbmarketplace'), false, $e->getMessage());
$push(get_string('error', 'meetletacbfree'), false, $e->getMessage());
}
echo html_writer::start_div('meetlet-conntest__grid');
foreach ($results as $row) {
$state = $row['ok'] ? 'ok' : 'fail';
$badge = html_writer::span(
$row['ok'] ? get_string('testok', 'meetletacbmarketplace') : get_string('testfail', 'meetletacbmarketplace'),
$row['ok'] ? get_string('testok', 'meetletacbfree') : get_string('testfail', 'meetletacbfree'),
'meetlet-pill meetlet-pill--' . $state
);
echo html_writer::div(
@@ -122,8 +122,8 @@ if (!config::is_configured()) {
echo html_writer::div(
html_writer::link(
new moodle_url('/admin/settings.php', ['section' => 'modsettingmeetletacbmarketplace']),
get_string('pluginadministration', 'meetletacbmarketplace'),
new moodle_url('/admin/settings.php', ['section' => 'modsettingmeetletacbfree']),
get_string('pluginadministration', 'meetletacbfree'),
['class' => 'meetlet-admin-testbtn meetlet-admin-testbtn--ghost']
),
'meetlet-conntest__footer'
+8 -8
View File
@@ -17,7 +17,7 @@
/**
* Capability definitions for MeetLet.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'mod/meetletacbmarketplace:addinstance' => [
'mod/meetletacbfree:addinstance' => [
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
@@ -35,7 +35,7 @@ $capabilities = [
],
'clonepermissionsfrom' => 'moodle/course:manageactivities',
],
'mod/meetletacbmarketplace:view' => [
'mod/meetletacbfree:view' => [
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
@@ -47,7 +47,7 @@ $capabilities = [
'manager' => CAP_ALLOW,
],
],
'mod/meetletacbmarketplace:join' => [
'mod/meetletacbfree:join' => [
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
@@ -57,7 +57,7 @@ $capabilities = [
'manager' => CAP_ALLOW,
],
],
'mod/meetletacbmarketplace:host' => [
'mod/meetletacbfree:host' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
@@ -65,7 +65,7 @@ $capabilities = [
'manager' => CAP_ALLOW,
],
],
'mod/meetletacbmarketplace:presenter' => [
'mod/meetletacbfree:presenter' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
@@ -74,7 +74,7 @@ $capabilities = [
'manager' => CAP_ALLOW,
],
],
'mod/meetletacbmarketplace:viewrecordings' => [
'mod/meetletacbfree:viewrecordings' => [
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
@@ -84,7 +84,7 @@ $capabilities = [
'manager' => CAP_ALLOW,
],
],
'mod/meetletacbmarketplace:grade' => [
'mod/meetletacbfree:grade' => [
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
+1 -1
View File
@@ -17,7 +17,7 @@
/**
* Cache definitions for faster Adobe Connect lookups.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+6 -3
View File
@@ -17,7 +17,7 @@
/**
* Post-install: migrate legacy mod_meetletacbmdlrules data when present.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -27,8 +27,11 @@ defined('MOODLE_INTERNAL') || die();
/**
* Runs after install.xml on first install of this component.
*/
function xmldb_meetletacbmarketplace_install() {
function xmldb_meetletacbfree_install() {
global $DB;
require_once(__DIR__ . '/upgrade.php');
xmldb_meetletacbmarketplace_migrate_from_mdlrules($DB->get_manager());
$dbman = $DB->get_manager();
xmldb_meetletacbfree_rename_legacy_main_table($dbman);
xmldb_meetletacbfree_migrate_from_mdlrules($dbman);
xmldb_meetletacbfree_migrate_from_market($dbman);
}
+7 -7
View File
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/meetletacbmarketplace/db" VERSION="2026081912" COMMENT="XMLDB for mod_meetletacbmarketplace"
<XMLDB PATH="mod/meetletacbfree/db" VERSION="2026081912" COMMENT="XMLDB for mod_meetletacbfree"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="meetletacbmarketplace" COMMENT="MeetLet Adobe Connect Bridge activities">
<TABLE NAME="meetletacbfree" COMMENT="MeetLet Adobe Connect Bridge activities">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
@@ -43,7 +43,7 @@
<INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
</INDEXES>
</TABLE>
<TABLE NAME="meetlet_marketplace_meetings" COMMENT="Adobe meeting sco mapping per group">
<TABLE NAME="meetletacbfree_meetings" COMMENT="Adobe meeting sco mapping per group">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="instanceid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
@@ -58,14 +58,14 @@
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_instance" TYPE="foreign" FIELDS="instanceid" REFTABLE="meetletacbmarketplace" REFFIELDS="id"/>
<KEY NAME="fk_instance" TYPE="foreign" FIELDS="instanceid" REFTABLE="meetletacbfree" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="instanceid_idx" UNIQUE="false" FIELDS="instanceid"/>
<INDEX NAME="groupid_idx" UNIQUE="false" FIELDS="groupid"/>
</INDEXES>
</TABLE>
<TABLE NAME="meetlet_marketplace_recordings" COMMENT="Cached recording / offline status">
<TABLE NAME="meetletacbfree_recordings" COMMENT="Cached recording / offline status">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="instanceid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
@@ -86,14 +86,14 @@
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_instance" TYPE="foreign" FIELDS="instanceid" REFTABLE="meetletacbmarketplace" REFFIELDS="id"/>
<KEY NAME="fk_instance" TYPE="foreign" FIELDS="instanceid" REFTABLE="meetletacbfree" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="instance_rec" UNIQUE="true" FIELDS="instanceid, recordingscoid"/>
<INDEX NAME="meeting_idx" UNIQUE="false" FIELDS="meetingscoid"/>
</INDEXES>
</TABLE>
<TABLE NAME="meetlet_marketplace_license" COMMENT="Optional MeetLet site registration identity and auth cache">
<TABLE NAME="meetletacbfree_license" COMMENT="Optional MeetLet site registration identity and auth cache">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="installation_id" TYPE="char" LENGTH="128" NOTNULL="true" SEQUENCE="false"/>
+22 -22
View File
@@ -17,7 +17,7 @@
/**
* External services for MeetLet Ajax tabs.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -25,60 +25,60 @@
defined('MOODLE_INTERNAL') || die();
$functions = [
'mod_meetletacbmarketplace_get_tab' => [
'classname' => 'mod_meetletacbmarketplace\external\get_tab',
'mod_meetletacbfree_get_tab' => [
'classname' => 'mod_meetletacbfree\external\get_tab',
'methodname' => 'execute',
'description' => 'Load MeetLet activity tab content (info, recordings, content)',
'type' => 'read',
'ajax' => true,
'capabilities' => 'mod/meetletacbmarketplace:view',
'capabilities' => 'mod/meetletacbfree:view',
],
'mod_meetletacbmarketplace_get_meeting_status' => [
'classname' => 'mod_meetletacbmarketplace\external\get_meeting_status',
'mod_meetletacbfree_get_meeting_status' => [
'classname' => 'mod_meetletacbfree\external\get_meeting_status',
'methodname' => 'execute',
'description' => 'Poll MeetLet meeting join status for the activity hero',
'type' => 'read',
'ajax' => true,
'capabilities' => 'mod/meetletacbmarketplace:view',
'capabilities' => 'mod/meetletacbfree:view',
],
'mod_meetletacbmarketplace_get_join_url' => [
'classname' => 'mod_meetletacbmarketplace\external\get_join_url',
'mod_meetletacbfree_get_join_url' => [
'classname' => 'mod_meetletacbfree\external\get_join_url',
'methodname' => 'execute',
'description' => 'Prepare Adobe Connect SSO join URL for the current user',
'type' => 'write',
'ajax' => true,
'capabilities' => 'mod/meetletacbmarketplace:join',
'capabilities' => 'mod/meetletacbfree:join',
],
'mod_meetletacbmarketplace_get_recording_launch_url' => [
'classname' => 'mod_meetletacbmarketplace\external\get_recording_launch_url',
'mod_meetletacbfree_get_recording_launch_url' => [
'classname' => 'mod_meetletacbfree\external\get_recording_launch_url',
'methodname' => 'execute',
'description' => 'Prepare Adobe Connect SSO URL to play or edit a recording',
'type' => 'write',
'ajax' => true,
'capabilities' => 'mod/meetletacbmarketplace:view',
'capabilities' => 'mod/meetletacbfree:view',
],
'mod_meetletacbmarketplace_get_content_launch_url' => [
'classname' => 'mod_meetletacbmarketplace\external\get_content_launch_url',
'mod_meetletacbfree_get_content_launch_url' => [
'classname' => 'mod_meetletacbfree\external\get_content_launch_url',
'methodname' => 'execute',
'description' => 'Prepare Adobe Connect SSO URL to view uploaded meeting content',
'type' => 'write',
'ajax' => true,
'capabilities' => 'mod/meetletacbmarketplace:view',
'capabilities' => 'mod/meetletacbfree:view',
],
'mod_meetletacbmarketplace_search_server_meetings' => [
'classname' => 'mod_meetletacbmarketplace\external\search_server_meetings',
'mod_meetletacbfree_search_server_meetings' => [
'classname' => 'mod_meetletacbfree\external\search_server_meetings',
'methodname' => 'execute',
'description' => 'Search or list recent Adobe Connect meetings for the activity form',
'type' => 'read',
'ajax' => true,
'capabilities' => 'moodle/course:manageactivities,mod/meetletacbmarketplace:addinstance',
'capabilities' => 'moodle/course:manageactivities,mod/meetletacbfree:addinstance',
],
'mod_meetletacbmarketplace_rename_recording' => [
'classname' => 'mod_meetletacbmarketplace\external\rename_recording',
'mod_meetletacbfree_rename_recording' => [
'classname' => 'mod_meetletacbfree\external\rename_recording',
'methodname' => 'execute',
'description' => 'Rename an Adobe Connect recording',
'type' => 'write',
'ajax' => true,
'capabilities' => 'mod/meetletacbmarketplace:host',
'capabilities' => 'mod/meetletacbfree:host',
],
];
+4 -4
View File
@@ -15,9 +15,9 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Scheduled tasks for mod_meetletacbmarketplace.
* Scheduled tasks for mod_meetletacbfree.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -26,7 +26,7 @@ defined('MOODLE_INTERNAL') || die();
$tasks = [
[
'classname' => 'mod_meetletacbmarketplace\\task\\sync_recordings',
'classname' => 'mod_meetletacbfree\\task\\sync_recordings',
'blocking' => 0,
'minute' => '*/15',
'hour' => '*',
@@ -35,7 +35,7 @@ $tasks = [
'dayofweek' => '*',
],
[
'classname' => 'mod_meetletacbmarketplace\\task\\registration_heartbeat',
'classname' => 'mod_meetletacbfree\\task\\registration_heartbeat',
'blocking' => 0,
'minute' => '15',
'hour' => '3',
+342 -170
View File
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -19,7 +19,7 @@
*
* Authenticated, current-user bound. The URL carries an opaque HMAC token.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -27,25 +27,25 @@
require(__DIR__ . '/../../config.php');
$k = required_param('k', PARAM_RAW_TRIMMED);
$claims = \mod_meetletacbmarketplace\local\content::unpack_download_token($k);
$claims = \mod_meetletacbfree\local\content::unpack_download_token($k);
$cm = get_coursemodule_from_id('meetletacbmarketplace', $claims['cmid'], 0, false, MUST_EXIST);
$cm = get_coursemodule_from_id('meetletacbfree', $claims['cmid'], 0, false, MUST_EXIST);
$course = $DB->get_record('course', ['id' => $cm->course], '*', MUST_EXIST);
$instance = $DB->get_record('meetletacbmarketplace', ['id' => $cm->instance], '*', MUST_EXIST);
$instance = $DB->get_record('meetletacbfree', ['id' => $cm->instance], '*', MUST_EXIST);
require_login($course, false, $cm);
if ((int)$USER->id !== (int)$claims['userid'] || isguestuser()) {
throw new moodle_exception('errorbadcontenttoken', 'meetletacbmarketplace');
throw new moodle_exception('errorbadcontenttoken', 'meetletacbfree');
}
$context = context_module::instance($cm->id);
require_capability('mod/meetletacbmarketplace:view', $context);
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbmarketplace\local\featureaccess::require_feature(
\mod_meetletacbmarketplace\local\featureaccess::CONTENT,
require_capability('mod/meetletacbfree:view', $context);
\mod_meetletacbfree\registration\manager::require_registered();
\mod_meetletacbfree\local\featureaccess::require_feature(
\mod_meetletacbfree\local\featureaccess::CONTENT,
$context,
$instance
);
$inst = \mod_meetletacbmarketplace\local\instance::get_from_cmid((int)$cm->id);
\mod_meetletacbmarketplace\local\content::serve_download($inst, (int)$claims['cid']);
$inst = \mod_meetletacbfree\local\instance::get_from_cmid((int)$cm->id);
\mod_meetletacbfree\local\content::serve_download($inst, (int)$claims['cid']);
+9 -9
View File
@@ -17,7 +17,7 @@
/**
* List all MeetLet instances in a course.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -27,25 +27,25 @@ require_once('../../config.php');
$id = required_param('id', PARAM_INT);
$course = $DB->get_record('course', ['id' => $id], '*', MUST_EXIST);
require_course_login($course);
\mod_meetletacbmarketplace\registration\manager::require_registered();
$PAGE->set_url('/mod/meetletacbmarketplace/index.php', ['id' => $id]);
$PAGE->set_title(get_string('modulenameplural', 'meetletacbmarketplace'));
\mod_meetletacbfree\registration\manager::require_registered();
$PAGE->set_url('/mod/meetletacbfree/index.php', ['id' => $id]);
$PAGE->set_title(get_string('modulenameplural', 'meetletacbfree'));
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('modulenameplural', 'meetletacbmarketplace'));
echo $OUTPUT->heading(get_string('modulenameplural', 'meetletacbfree'));
if (!$instances = get_all_instances_in_course('meetletacbmarketplace', $course)) {
notice(get_string('thereareno', 'moodle', get_string('modulenameplural', 'meetletacbmarketplace')),
if (!$instances = get_all_instances_in_course('meetletacbfree', $course)) {
notice(get_string('thereareno', 'moodle', get_string('modulenameplural', 'meetletacbfree')),
new moodle_url('/course/view.php', ['id' => $course->id]));
echo $OUTPUT->footer();
die();
}
$table = new html_table();
$table->head = [get_string('meetingname', 'meetletacbmarketplace'), get_string('starttime', 'meetletacbmarketplace')];
$table->head = [get_string('meetingname', 'meetletacbfree'), get_string('starttime', 'meetletacbfree')];
foreach ($instances as $instance) {
$url = new moodle_url('/mod/meetletacbmarketplace/view.php', ['id' => $instance->coursemodule]);
$url = new moodle_url('/mod/meetletacbfree/view.php', ['id' => $instance->coursemodule]);
$table->data[] = [
html_writer::link($url, format_string($instance->name)),
$instance->starttime ? userdate($instance->starttime) : '-',
+1 -1
View File
@@ -2,7 +2,7 @@
* Shared scroll lock for MeetLet modals.
* Uses body overflow + scroll guards — no position:fixed on body (avoids white-page flash).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+5 -5
View File
@@ -54,9 +54,9 @@ require(['core/str', 'core/notification', 'core/templates', 'core/ajax'], functi
const participantAddToForm = async(selectionTypeValue, selectionValue, selectedRole, canRemove) => {
const participantData = JSON.parse(ELEMENT_SELECTOR.participantData().dataset.participantData);
const [shost, spresenter, sparticipant] = await Promise.all([
Str.get_string('role_host', 'meetletacbmarketplace'),
Str.get_string('role_presenter', 'meetletacbmarketplace'),
Str.get_string('role_participant', 'meetletacbmarketplace'),
Str.get_string('role_host', 'meetletacbfree'),
Str.get_string('role_presenter', 'meetletacbfree'),
Str.get_string('role_participant', 'meetletacbfree'),
]);
const roles = {
host: {id: 'host', label: shost},
@@ -80,7 +80,7 @@ require(['core/str', 'core/notification', 'core/templates', 'core/ajax'], functi
roles: Object.values(roles),
canRemove: canRemove,
};
const {html, js} = await Templates.renderForPromise('mod_meetletacbmarketplace/participant_form_add', templateContext);
const {html, js} = await Templates.renderForPromise('mod_meetletacbfree/participant_form_add', templateContext);
const newNode = Templates.appendNodeContents(listTable, html, js)[0];
newNode.querySelector('.participant-select').addEventListener('change', () => {
participantListRoleUpdate(selectionTypeValue, selectionValue);
@@ -337,7 +337,7 @@ require(['core/str', 'core/notification', 'core/templates', 'core/ajax'], functi
hint.textContent = strLoading;
}
return Ajax.call([{
methodname: 'mod_meetletacbmarketplace_search_server_meetings',
methodname: 'mod_meetletacbfree_search_server_meetings',
args: {
query: query || '',
limit: 10,
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* Reset-to-default for site role mapping and feature-access matrix (admin settings).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* Inline Ajax site registration on plugin settings tab (Marketplace free edition).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+4 -4
View File
@@ -90,8 +90,8 @@
}
function syncHoursEnabled() {
var sel = document.querySelector('select[name="s_meetletacbmarketplace_agent_dispatch"]')
|| document.getElementById('id_s_meetletacbmarketplace_agent_dispatch');
var sel = document.querySelector('select[name="s_meetletacbfree_agent_dispatch"]')
|| document.getElementById('id_s_meetletacbfree_agent_dispatch');
var wrap = document.querySelector('[data-meetlet-hours-wrap]');
if (!wrap) {
return;
@@ -127,8 +127,8 @@
applyHours(wrap, list);
}
});
var sel = document.querySelector('select[name="s_meetletacbmarketplace_agent_dispatch"]')
|| document.getElementById('id_s_meetletacbmarketplace_agent_dispatch');
var sel = document.querySelector('select[name="s_meetletacbfree_agent_dispatch"]')
|| document.getElementById('id_s_meetletacbfree_agent_dispatch');
if (sel) {
sel.addEventListener('change', syncHoursEnabled);
if (document.documentElement.getAttribute('dir') === 'rtl') {
+14 -14
View File
@@ -1,6 +1,6 @@
/**
* MeetLet activity view — page-local only (not AMD).
* Loaded only on mod/meetletacbmarketplace/view.php via $PAGE->requires->js().
* Loaded only on mod/meetletacbfree/view.php via $PAGE->requires->js().
*/
require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notification, Str) {
const SELECTORS = {
@@ -332,7 +332,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
const notifyDownloadError = (err) => {
const isAbort = err && err.name === 'AbortError';
const key = isAbort ? 'downloadcontenttimeout' : 'downloadcontentfailed';
return Str.get_string(key, 'meetletacbmarketplace').then((message) => {
return Str.get_string(key, 'meetletacbfree').then((message) => {
Notification.addNotification({message: message, type: 'error'});
return null;
}).catch(() => {
@@ -418,7 +418,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
}
input.disabled = true;
Ajax.call([{
methodname: 'mod_meetletacbmarketplace_rename_recording',
methodname: 'mod_meetletacbfree_rename_recording',
args: {
cmid: state.cmid,
recordingscoid: parseInt(wrap.getAttribute('data-recording'), 10),
@@ -497,7 +497,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
btn.addEventListener('click', () => {
setButtonBusy(btn, true);
Ajax.call([{
methodname: 'mod_meetletacbmarketplace_make_offline',
methodname: 'mod_meetletacbfree_make_offline',
args: {
cmid: state.cmid,
recordingscoid: parseInt(btn.dataset.recording, 10),
@@ -534,7 +534,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
setButtonBusy(btn, true);
setOverlay(true, 'recording');
Ajax.call([{
methodname: 'mod_meetletacbmarketplace_get_recording_launch_url',
methodname: 'mod_meetletacbfree_get_recording_launch_url',
args: {
cmid: state.cmid,
recordingscoid: scoid,
@@ -564,7 +564,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
setButtonBusy(btn, true);
setOverlay(true, 'content');
Ajax.call([{
methodname: 'mod_meetletacbmarketplace_get_content_launch_url',
methodname: 'mod_meetletacbfree_get_content_launch_url',
args: {
cmid: state.cmid,
contentscoid: scoid,
@@ -648,10 +648,10 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
return Promise.resolve();
}
return Str.get_string('loading', 'meetletacbmarketplace').then((loading) => {
return Str.get_string('loading', 'meetletacbfree').then((loading) => {
setLoading(panel, loading);
return Ajax.call([{
methodname: 'mod_meetletacbmarketplace_get_tab',
methodname: 'mod_meetletacbfree_get_tab',
args: {cmid: state.cmid, tab: tab, groupid: state.groupid},
}])[0];
}).then((response) => {
@@ -670,7 +670,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
return;
}
Ajax.call([{
methodname: 'mod_meetletacbmarketplace_get_tab',
methodname: 'mod_meetletacbfree_get_tab',
args: {cmid: state.cmid, tab: 'recordings', groupid: state.groupid},
}])[0].then((response) => {
state.cache.recordings = response.html;
@@ -796,7 +796,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
return;
}
if (response && (response.message || response.detailhtml || response.helpcode)) {
Str.get_string('joindeniedtitle', 'meetletacbmarketplace').then((title) => {
Str.get_string('joindeniedtitle', 'meetletacbfree').then((title) => {
showHelpError(response, title);
return null;
}).catch(() => showHelpError(response, ''));
@@ -805,7 +805,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
if (fallbackErr) {
const msg = (fallbackErr.message || fallbackErr.error) ? (fallbackErr.message || fallbackErr.error) : '';
if (msg) {
Str.get_string('joindeniedtitle', 'meetletacbmarketplace').then((title) => {
Str.get_string('joindeniedtitle', 'meetletacbfree').then((title) => {
showHelpError({message: msg}, title);
return null;
}).catch(() => Notification.exception(fallbackErr));
@@ -872,7 +872,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
const pollMeetingStatus = () => {
return Ajax.call([{
methodname: 'mod_meetletacbmarketplace_get_meeting_status',
methodname: 'mod_meetletacbfree_get_meeting_status',
args: {cmid: state.cmid, groupid: state.groupid},
}])[0].then((info) => {
applyMeetingStatus(info);
@@ -918,7 +918,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
const joinMeeting = () => {
if (!state.joinable) {
Str.get_strings([
{key: 'joindeniedtitle', component: 'meetletacbmarketplace'},
{key: 'joindeniedtitle', component: 'meetletacbfree'},
]).then((strings) => {
const msg = (state.status === 'waitinghost' || state.status === 'checking')
? (state.strJoinWaiting || state.statusMessage || '')
@@ -936,7 +936,7 @@ require(['core/ajax', 'core/notification', 'core/str'], function(Ajax, Notificat
}
setOverlay(true, 'meeting');
Ajax.call([{
methodname: 'mod_meetletacbmarketplace_get_join_url',
methodname: 'mod_meetletacbfree_get_join_url',
args: {cmid: state.cmid, groupid: state.groupid},
}])[0].then((response) => {
setOverlay(false);
@@ -15,9 +15,9 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* English language strings for mod_meetletacbmarketplace.
* English language strings for mod_meetletacbfree.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -33,13 +33,13 @@ $string['settingsintro'] = 'Connect Moodle to Adobe Connect for meeting creation
$string['marketplace_commercial_note'] = 'Attendance reports, offline MP4 video, Windows Agent integration and premium support are available in the commercial MeetLet Adobe Connect Bridge.';
$string['about_visit_website'] = 'Visit the MeetLet website';
$string['marketplace_commercial_visit'] = 'meetlet.net';
$string['meetletacbmarketplace:addinstance'] = 'Add a new MeetLet meeting';
$string['meetletacbmarketplace:view'] = 'View MeetLet meeting';
$string['meetletacbmarketplace:join'] = 'Join MeetLet meeting';
$string['meetletacbmarketplace:host'] = 'Act as Adobe Connect host';
$string['meetletacbmarketplace:presenter'] = 'Act as Adobe Connect presenter';
$string['meetletacbmarketplace:viewrecordings'] = 'View recordings';
$string['meetletacbmarketplace:grade'] = 'Grade MeetLet activity';
$string['meetletacbfree:addinstance'] = 'Add a new MeetLet meeting';
$string['meetletacbfree:view'] = 'View MeetLet meeting';
$string['meetletacbfree:join'] = 'Join MeetLet meeting';
$string['meetletacbfree:host'] = 'Act as Adobe Connect host';
$string['meetletacbfree:presenter'] = 'Act as Adobe Connect presenter';
$string['meetletacbfree:viewrecordings'] = 'View recordings';
$string['meetletacbfree:grade'] = 'Grade MeetLet activity';
$string['meetingname'] = 'Meeting name';
$string['meetingintro'] = 'Meeting summary';
@@ -306,21 +306,21 @@ $string['contenticon_content'] = 'Content';
$string['errornofolder'] = 'Could not find the Adobe Connect meetings folder';
$string['notconfigured'] = 'MeetLet is not configured yet. Ask an administrator to complete Adobe Connect settings.';
$string['privacy:metadata'] = 'MeetLet stores meeting mappings and recording metadata locally, and exchanges user profile fields with Adobe Connect to enable SSO.';
$string['privacy:metadata:meetletacbmarketplace'] = 'MeetLet activity instances stored in Moodle.';
$string['privacy:metadata:meetletacbmarketplace:userid'] = 'The user who created the activity instance.';
$string['privacy:metadata:meetletacbmarketplace:name'] = 'The activity name.';
$string['privacy:metadata:meetletacbmarketplace:intro'] = 'The activity description.';
$string['privacy:metadata:meetletacbmarketplace:participants'] = 'Role mapping rules, which may include specific Moodle user ids.';
$string['privacy:metadata:meetletacbmarketplace:timecreated'] = 'When the activity was created.';
$string['privacy:metadata:meetletacbmarketplace:timemodified'] = 'When the activity was last modified.';
$string['privacy:metadata:meetlet_marketplace_meetings'] = 'Adobe Connect meeting SCO mapping per Moodle group.';
$string['privacy:metadata:meetlet_marketplace_meetings:groupid'] = 'Moodle group linked to the Adobe Connect meeting.';
$string['privacy:metadata:meetlet_marketplace_meetings:meetingscoid'] = 'Adobe Connect meeting SCO id.';
$string['privacy:metadata:meetlet_marketplace_meetings:urlpath'] = 'Adobe Connect meeting URL path.';
$string['privacy:metadata:meetlet_marketplace_recordings'] = 'Cached recording and offline video metadata.';
$string['privacy:metadata:meetlet_marketplace_recordings:name'] = 'Recording title cached from Adobe Connect.';
$string['privacy:metadata:meetlet_marketplace_recordings:urlpath'] = 'Recording URL path.';
$string['privacy:metadata:meetlet_marketplace_recordings:jobstatus'] = 'Offline video job status.';
$string['privacy:metadata:meetletacbfree'] = 'MeetLet activity instances stored in Moodle.';
$string['privacy:metadata:meetletacbfree:userid'] = 'The user who created the activity instance.';
$string['privacy:metadata:meetletacbfree:name'] = 'The activity name.';
$string['privacy:metadata:meetletacbfree:intro'] = 'The activity description.';
$string['privacy:metadata:meetletacbfree:participants'] = 'Role mapping rules, which may include specific Moodle user ids.';
$string['privacy:metadata:meetletacbfree:timecreated'] = 'When the activity was created.';
$string['privacy:metadata:meetletacbfree:timemodified'] = 'When the activity was last modified.';
$string['privacy:metadata:meetletacbfree_meetings'] = 'Adobe Connect meeting SCO mapping per Moodle group.';
$string['privacy:metadata:meetletacbfree_meetings:groupid'] = 'Moodle group linked to the Adobe Connect meeting.';
$string['privacy:metadata:meetletacbfree_meetings:meetingscoid'] = 'Adobe Connect meeting SCO id.';
$string['privacy:metadata:meetletacbfree_meetings:urlpath'] = 'Adobe Connect meeting URL path.';
$string['privacy:metadata:meetletacbfree_recordings'] = 'Cached recording and offline video metadata.';
$string['privacy:metadata:meetletacbfree_recordings:name'] = 'Recording title cached from Adobe Connect.';
$string['privacy:metadata:meetletacbfree_recordings:urlpath'] = 'Recording URL path.';
$string['privacy:metadata:meetletacbfree_recordings:jobstatus'] = 'Offline video job status.';
$string['privacy:metadata:adobeconnect'] = 'User name, email and login are sent to Adobe Connect for account provisioning and meeting access.';
$string['privacy:metadata:adobeconnect:firstname'] = 'User first name sent to Adobe Connect.';
$string['privacy:metadata:adobeconnect:lastname'] = 'User last name sent to Adobe Connect.';
@@ -470,7 +470,7 @@ $string['privacy_tab_heading'] = 'Privacy policy — Marketplace edition';
$string['privacy_tab_intro'] = 'This policy describes how the MeetLet Adobe Connect Bridge plugin (Marketplace / free edition) handles personal and technical data when installed in Moodle. It applies to site administrators who configure the plugin and to end users who join Adobe Connect meetings through Moodle activities.';
$string['privacy_tab_effective'] = 'Effective date: September 2026. MeetLet may update this in-plugin policy when the plugin changes; the version installed on your site is the authoritative copy.';
$string['privacy_tab_scope_title'] = '1. Scope';
$string['privacy_tab_scope_body'] = '<p>This policy covers data processed by the <strong>mod_meetletacbmarketplace</strong> activity module and its site-wide administration settings. It does not replace your organisation\'s own privacy notices to learners, your Adobe Connect server operator\'s terms, or Moodle core privacy documentation.</p><p>MeetLet develops and maintains this plugin. For questions about this policy, contact <a href="mailto:info@meetlet.net">info@meetlet.net</a>.</p>';
$string['privacy_tab_scope_body'] = '<p>This policy covers data processed by the <strong>mod_meetletacbfree</strong> activity module and its site-wide administration settings. It does not replace your organisation\'s own privacy notices to learners, your Adobe Connect server operator\'s terms, or Moodle core privacy documentation.</p><p>MeetLet develops and maintains this plugin. For questions about this policy, contact <a href="mailto:info@meetlet.net">info@meetlet.net</a>.</p>';
$string['privacy_tab_registration_title'] = '2. Optional plugin activation';
$string['privacy_tab_registration_body'] = '<p>Plugin activation is <strong>voluntary</strong>. No data is sent to MeetLet until a site administrator explicitly clicks <em>Activate plugin</em> on the Plugin activation tab. Until then, the plugin does not contact the MeetLet activation service.</p><p>When an administrator activates the plugin, the following metadata may be transmitted to the MeetLet activation service:</p><ul><li>Public site URL / domain</li><li>A unique installation identifier generated by the plugin</li><li>Moodle platform name and release version</li><li>Plugin component name and release version</li><li>Site or organisation name (from Moodle site settings), if available</li><li>Site administrator or support contact email, if available in Moodle</li></ul><p>No learner personal data, course content, meeting recordings, or Adobe Connect credentials are included in activation requests.</p>';
$string['privacy_tab_purpose_title'] = '3. Purpose of activation data';
@@ -520,7 +520,7 @@ $string['registration_last_validated_never'] = 'Never';
$string['registration_activate_help'] = 'Send site metadata to MeetLet and activate this installation on the free Marketplace product.';
$string['registration_activate_confirm_title'] = 'Activate this plugin?';
$string['registration_activate_confirm_item_domain'] = 'Public site domain and a unique installation ID';
$string['registration_activate_confirm_item_plugin'] = 'Plugin component (mod_meetletacbmarketplace) and release version';
$string['registration_activate_confirm_item_plugin'] = 'Plugin component (mod_meetletacbfree) and release version';
$string['registration_activate_confirm_item_contact'] = 'Site name and administrator contact email (for support statistics only)';
$string['registration_activate_confirm_optional'] = 'You can deactivate at any time. A daily scheduled task re-validates activation only while activated.';
$string['registration_recheck'] = 'Re-check activation';
@@ -554,10 +554,10 @@ $string['registration_err_unknown'] = 'An unknown activation error occurred.';
$string['registration_crypto_error'] = 'Activation cryptography error.';
$string['registration_sodium_required'] = 'PHP sodium extension is required for plugin activation.';
$string['task_registration_heartbeat'] = 'MeetLet plugin activation heartbeat';
$string['privacy:metadata:meetlet_marketplace_license'] = 'Optional MeetLet plugin activation identity stored locally when an administrator activates the plugin.';
$string['privacy:metadata:meetlet_marketplace_license:installation_id'] = 'Unique installation identifier generated by the plugin.';
$string['privacy:metadata:meetlet_marketplace_license:status'] = 'Last known activation status.';
$string['privacy:metadata:meetlet_marketplace_license:last_validated'] = 'When activation was last validated with MeetLet.';
$string['privacy:metadata:meetletacbfree_license'] = 'Optional MeetLet plugin activation identity stored locally when an administrator activates the plugin.';
$string['privacy:metadata:meetletacbfree_license:installation_id'] = 'Unique installation identifier generated by the plugin.';
$string['privacy:metadata:meetletacbfree_license:status'] = 'Last known activation status.';
$string['privacy:metadata:meetletacbfree_license:last_validated'] = 'When activation was last validated with MeetLet.';
$string['privacy:metadata:meetlet_registration'] = 'When an administrator opts in, site metadata is sent to the MeetLet activation service for update notices and support statistics.';
$string['privacy:metadata:meetlet_registration:domain'] = 'Public Moodle site domain.';
$string['privacy:metadata:meetlet_registration:installation_id'] = 'Unique installation identifier.';
@@ -15,9 +15,9 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Persian language strings for mod_meetletacbmarketplace.
* Persian language strings for mod_meetletacbfree.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -33,13 +33,13 @@ $string['settingsintro'] = 'اتصال مودل به Adobe Connect برای ای
$string['marketplace_commercial_note'] = 'گزارش حضور و غیاب، ویدیوی MP4 آفلاین، Agent ویندوز و پشتیبانی حرفه‌ای در نسخه تجاری MeetLet Adobe Connect Bridge موجود است.';
$string['about_visit_website'] = 'ورود به وب‌سایت MeetLet';
$string['marketplace_commercial_visit'] = 'meetlet.net';
$string['meetletacbmarketplace:addinstance'] = 'افزودن جلسه MeetLet';
$string['meetletacbmarketplace:view'] = 'مشاهده جلسه MeetLet';
$string['meetletacbmarketplace:join'] = 'پیوستن به جلسه MeetLet';
$string['meetletacbmarketplace:host'] = 'میزبان Adobe Connect';
$string['meetletacbmarketplace:presenter'] = 'ارائه‌دهنده Adobe Connect';
$string['meetletacbmarketplace:viewrecordings'] = 'مشاهده ضبط‌ها';
$string['meetletacbmarketplace:grade'] = 'نمره‌دهی فعالیت MeetLet';
$string['meetletacbfree:addinstance'] = 'افزودن جلسه MeetLet';
$string['meetletacbfree:view'] = 'مشاهده جلسه MeetLet';
$string['meetletacbfree:join'] = 'پیوستن به جلسه MeetLet';
$string['meetletacbfree:host'] = 'میزبان Adobe Connect';
$string['meetletacbfree:presenter'] = 'ارائه‌دهنده Adobe Connect';
$string['meetletacbfree:viewrecordings'] = 'مشاهده ضبط‌ها';
$string['meetletacbfree:grade'] = 'نمره‌دهی فعالیت MeetLet';
$string['meetingname'] = 'نام جلسه';
$string['meetingintro'] = 'خلاصه جلسه';
@@ -308,21 +308,21 @@ $string['contenticon_content'] = 'محتوا';
$string['errornofolder'] = 'پوشه جلسات Adobe Connect پیدا نشد';
$string['notconfigured'] = 'اتصال Adobe Connect هنوز پیکربندی نشده است. از مدیر سایت بخواهید تنظیمات را کامل کند.';
$string['privacy:metadata'] = 'MeetLet نگاشت جلسات و متادیتای ضبط را محلی نگه می‌دارد و برای SSO فیلدهای پروفایل را با Adobe Connect مبادله می‌کند.';
$string['privacy:metadata:meetletacbmarketplace'] = 'نمونه‌های فعالیت MeetLet که در مودل ذخیره می‌شوند.';
$string['privacy:metadata:meetletacbmarketplace:userid'] = 'کاربری که نمونه فعالیت را ساخته است.';
$string['privacy:metadata:meetletacbmarketplace:name'] = 'نام فعالیت.';
$string['privacy:metadata:meetletacbmarketplace:intro'] = 'توضیح فعالیت.';
$string['privacy:metadata:meetletacbmarketplace:participants'] = 'قواعد نگاشت نقش که ممکن است شامل شناسه کاربران مودل باشد.';
$string['privacy:metadata:meetletacbmarketplace:timecreated'] = 'زمان ایجاد فعالیت.';
$string['privacy:metadata:meetletacbmarketplace:timemodified'] = 'زمان آخرین ویرایش فعالیت.';
$string['privacy:metadata:meetlet_marketplace_meetings'] = 'نگاشت SCO جلسه Adobe Connect به ازای هر گروه مودل.';
$string['privacy:metadata:meetlet_marketplace_meetings:groupid'] = 'گروه مودل متصل به جلسه Adobe Connect.';
$string['privacy:metadata:meetlet_marketplace_meetings:meetingscoid'] = 'شناسه SCO جلسه در Adobe Connect.';
$string['privacy:metadata:meetlet_marketplace_meetings:urlpath'] = 'مسیر URL جلسه Adobe Connect.';
$string['privacy:metadata:meetlet_marketplace_recordings'] = 'متادیتای کش‌شده ضبط و ساخت ویدیوی آفلاین.';
$string['privacy:metadata:meetlet_marketplace_recordings:name'] = 'عنوان ضبط کش‌شده از Adobe Connect.';
$string['privacy:metadata:meetlet_marketplace_recordings:urlpath'] = 'مسیر URL ضبط.';
$string['privacy:metadata:meetlet_marketplace_recordings:jobstatus'] = 'وضعیت جاب ساخت ویدیوی آفلاین.';
$string['privacy:metadata:meetletacbfree'] = 'نمونه‌های فعالیت MeetLet که در مودل ذخیره می‌شوند.';
$string['privacy:metadata:meetletacbfree:userid'] = 'کاربری که نمونه فعالیت را ساخته است.';
$string['privacy:metadata:meetletacbfree:name'] = 'نام فعالیت.';
$string['privacy:metadata:meetletacbfree:intro'] = 'توضیح فعالیت.';
$string['privacy:metadata:meetletacbfree:participants'] = 'قواعد نگاشت نقش که ممکن است شامل شناسه کاربران مودل باشد.';
$string['privacy:metadata:meetletacbfree:timecreated'] = 'زمان ایجاد فعالیت.';
$string['privacy:metadata:meetletacbfree:timemodified'] = 'زمان آخرین ویرایش فعالیت.';
$string['privacy:metadata:meetletacbfree_meetings'] = 'نگاشت SCO جلسه Adobe Connect به ازای هر گروه مودل.';
$string['privacy:metadata:meetletacbfree_meetings:groupid'] = 'گروه مودل متصل به جلسه Adobe Connect.';
$string['privacy:metadata:meetletacbfree_meetings:meetingscoid'] = 'شناسه SCO جلسه در Adobe Connect.';
$string['privacy:metadata:meetletacbfree_meetings:urlpath'] = 'مسیر URL جلسه Adobe Connect.';
$string['privacy:metadata:meetletacbfree_recordings'] = 'متادیتای کش‌شده ضبط و ساخت ویدیوی آفلاین.';
$string['privacy:metadata:meetletacbfree_recordings:name'] = 'عنوان ضبط کش‌شده از Adobe Connect.';
$string['privacy:metadata:meetletacbfree_recordings:urlpath'] = 'مسیر URL ضبط.';
$string['privacy:metadata:meetletacbfree_recordings:jobstatus'] = 'وضعیت جاب ساخت ویدیوی آفلاین.';
$string['privacy:metadata:adobeconnect'] = 'نام، ایمیل و لاگین کاربر برای ساخت حساب و دسترسی جلسه به Adobe Connect ارسال می‌شود.';
$string['privacy:metadata:adobeconnect:firstname'] = 'نام کاربر که به Adobe Connect ارسال می‌شود.';
$string['privacy:metadata:adobeconnect:lastname'] = 'نام خانوادگی کاربر که به Adobe Connect ارسال می‌شود.';
@@ -472,7 +472,7 @@ $string['privacy_tab_heading'] = 'سیاست حریم خصوصی — نسخه Ma
$string['privacy_tab_intro'] = 'این سیاست نحوه پردازش داده‌های فنی و شخصی توسط افزونه پل Adobe Connect میت‌لت (نسخه Marketplace / رایگان) در مودل را توضیح می‌دهد. شامل مدیرانی است که افزونه را پیکربندی می‌کنند و کاربرانی که از طریق فعالیت‌های مودل به جلسات Adobe Connect می‌پیوندند.';
$string['privacy_tab_effective'] = 'تاریخ اجرا: شهریور ۱۴۰۵ (سپتامبر ۲۰۲۶). میت‌لت ممکن است این سیاست درون‌افزونه‌ای را هنگام به‌روزرسانی افزونه اصلاح کند؛ نسخه نصب‌شده روی سایت شما مرجع است.';
$string['privacy_tab_scope_title'] = '۱. حوزه شمول';
$string['privacy_tab_scope_body'] = '<p>این سیاست داده‌های پردازش‌شده توسط ماژول فعالیت <strong>mod_meetletacbmarketplace</strong> و تنظیمات سراسری آن را پوشش می‌دهد. جایگزین اعلامیه حریم خصوصی سازمان شما نسبت به فراگیران، شرایط اپراتور سرور Adobe Connect، یا مستندات حریم خصوصی هسته مودل نیست.</p><p>میت‌لت (MeetLet) این افزونه را توسعه و نگهداری می‌کند. برای پرسش درباره این سیاست با <a href="mailto:info@meetlet.net">info@meetlet.net</a> تماس بگیرید.</p>';
$string['privacy_tab_scope_body'] = '<p>این سیاست داده‌های پردازش‌شده توسط ماژول فعالیت <strong>mod_meetletacbfree</strong> و تنظیمات سراسری آن را پوشش می‌دهد. جایگزین اعلامیه حریم خصوصی سازمان شما نسبت به فراگیران، شرایط اپراتور سرور Adobe Connect، یا مستندات حریم خصوصی هسته مودل نیست.</p><p>میت‌لت (MeetLet) این افزونه را توسعه و نگهداری می‌کند. برای پرسش درباره این سیاست با <a href="mailto:info@meetlet.net">info@meetlet.net</a> تماس بگیرید.</p>';
$string['privacy_tab_registration_title'] = '۲. فعال‌سازی اختیاری پلاگین';
$string['privacy_tab_registration_body'] = '<p>فعال‌سازی پلاگین <strong>اختیاری</strong> است. تا زمانی که مدیر سایت صریحاً روی <em>فعال‌سازی پلاگین</em> در تب فعال‌سازی پلاگین کلیک نکند، هیچ داده‌ای به میت‌لت ارسال نمی‌شود و افزونه با سرویس فعال‌سازی میت‌لت تماس نمی‌گیرد.</p><p>هنگام فعال‌سازی، متادیتای زیر ممکن است به <strong>سرویس فعال‌سازی میت‌لت</strong> ارسال شود:</p><ul><li>آدرس/دامنه عمومی سایت</li><li>شناسه یکتای نصب تولیدشده توسط افزونه</li><li>نام و نسخه انتشار مودل</li><li>نام کامپوننت و نسخه انتشار افزونه</li><li>نام سایت یا سازمان (از تنظیمات مودل)، در صورت موجود بودن</li><li>ایمیل مدیر یا پشتیبانی سایت، در صورت موجود بودن در مودل</li></ul><p>داده شخصی فراگیران، محتوای درس، ضبط جلسات یا اعتبارنامه Adobe Connect در درخواست‌های فعال‌سازی گنجانده نمی‌شود.</p>';
$string['privacy_tab_purpose_title'] = '۳. هدف از داده‌های فعال‌سازی';
@@ -522,7 +522,7 @@ $string['registration_last_validated_never'] = 'هرگز';
$string['registration_activate_help'] = 'ارسال متادیتای سایت به MeetLet و فعال‌سازی این نصب روی محصول رایگان Marketplace.';
$string['registration_activate_confirm_title'] = 'این افزونه فعال شود؟';
$string['registration_activate_confirm_item_domain'] = 'دامنه عمومی سایت و شناسه یکتای نصب';
$string['registration_activate_confirm_item_plugin'] = 'کامپوننت افزونه (mod_meetletacbmarketplace) و نسخه انتشار';
$string['registration_activate_confirm_item_plugin'] = 'کامپوننت افزونه (mod_meetletacbfree) و نسخه انتشار';
$string['registration_activate_confirm_item_contact'] = 'نام سایت و ایمیل تماس مدیر (فقط برای آمار پشتیبانی)';
$string['registration_activate_confirm_optional'] = 'هر زمان می‌توانید غیرفعال کنید. وظیفه زمان‌بندی‌شده روزانه فقط در صورت فعال‌سازی، وضعیت را تازه می‌کند.';
$string['registration_recheck'] = 'بررسی مجدد فعال‌سازی';
@@ -556,10 +556,10 @@ $string['registration_err_unknown'] = 'خطای ناشناخته در فعال
$string['registration_crypto_error'] = 'خطای رمزنگاری فعال‌سازی.';
$string['registration_sodium_required'] = 'افزونه sodium در PHP برای فعال‌سازی پلاگین لازم است.';
$string['task_registration_heartbeat'] = 'بررسی روزانه فعال‌سازی پلاگین MeetLet';
$string['privacy:metadata:meetlet_marketplace_license'] = 'هویت فعال‌سازی اختیاری MeetLet که فقط پس از فعال‌سازی توسط مدیر ذخیره می‌شود.';
$string['privacy:metadata:meetlet_marketplace_license:installation_id'] = 'شناسه یکتای نصب تولیدشده توسط افزونه.';
$string['privacy:metadata:meetlet_marketplace_license:status'] = 'آخرین وضعیت فعال‌سازی شناخته‌شده.';
$string['privacy:metadata:meetlet_marketplace_license:last_validated'] = 'زمان آخرین اعتبارسنجی فعال‌سازی با MeetLet.';
$string['privacy:metadata:meetletacbfree_license'] = 'هویت فعال‌سازی اختیاری MeetLet که فقط پس از فعال‌سازی توسط مدیر ذخیره می‌شود.';
$string['privacy:metadata:meetletacbfree_license:installation_id'] = 'شناسه یکتای نصب تولیدشده توسط افزونه.';
$string['privacy:metadata:meetletacbfree_license:status'] = 'آخرین وضعیت فعال‌سازی شناخته‌شده.';
$string['privacy:metadata:meetletacbfree_license:last_validated'] = 'زمان آخرین اعتبارسنجی فعال‌سازی با MeetLet.';
$string['privacy:metadata:meetlet_registration'] = 'در صورت فعال‌سازی اختیاری توسط مدیر، متادیتای سایت به سرویس فعال‌سازی MeetLet برای اعلان به‌روزرسانی و آمار پشتیبانی ارسال می‌شود.';
$string['privacy:metadata:meetlet_registration:domain'] = 'دامنه عمومی سایت مودل.';
$string['privacy:metadata:meetlet_registration:installation_id'] = 'شناسه یکتای نصب.';
+95 -95
View File
@@ -17,16 +17,16 @@
/**
* Library functions for MeetLet Adobe Connect Bridge.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbmarketplace\local\roles;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\config;
use mod_meetletacbfree\local\roles;
/**
* Feature support.
@@ -34,7 +34,7 @@ use mod_meetletacbmarketplace\local\roles;
* @param string $feature
* @return mixed
*/
function meetletacbmarketplace_supports($feature) {
function meetletacbfree_supports($feature) {
switch ($feature) {
case FEATURE_GROUPS:
return true;
@@ -64,7 +64,7 @@ function meetletacbmarketplace_supports($feature) {
*
* @return bool
*/
function meetletacbmarketplace_is_branded(): bool {
function meetletacbfree_is_branded(): bool {
return true;
}
@@ -76,12 +76,12 @@ function meetletacbmarketplace_is_branded(): bool {
* @param \stdClass $course
* @return array
*/
function mod_meetletacbmarketplace_get_course_content_items(
function mod_meetletacbfree_get_course_content_items(
\core_course\local\entity\content_item $contentitem,
\stdClass $user,
\stdClass $course
): array {
if (!\mod_meetletacbmarketplace\registration\manager::is_registered()) {
if (!\mod_meetletacbfree\registration\manager::is_registered()) {
return [];
}
return [$contentitem];
@@ -91,13 +91,13 @@ function mod_meetletacbmarketplace_get_course_content_items(
* Add instance.
*
* @param stdClass $data
* @param mod_meetletacbmarketplace_mod_form|null $mform
* @param mod_meetletacbfree_mod_form|null $mform
* @return int
*/
function meetletacbmarketplace_add_instance($data, $mform = null) {
function meetletacbfree_add_instance($data, $mform = null) {
global $DB, $USER;
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$data->timecreated = time();
$data->timemodified = $data->timecreated;
@@ -112,40 +112,40 @@ function meetletacbmarketplace_add_instance($data, $mform = null) {
} else if (empty($data->participants)) {
$data->participants = json_encode(roles::get_participant_list_default($coursecontext, $USER->id));
}
$togglefields = meetletacbmarketplace_activity_override_fields();
$data->settingoverrides = config::setting_overrides_json(meetletacbmarketplace_collect_setting_override_states($data, $togglefields));
$data->autooffline = meetletacbmarketplace_legacy_setting_value($data, 'autooffline');
$togglefields = meetletacbfree_activity_override_fields();
$data->settingoverrides = config::setting_overrides_json(meetletacbfree_collect_setting_override_states($data, $togglefields));
$data->autooffline = meetletacbfree_legacy_setting_value($data, 'autooffline');
$data->meetingpublic = empty($data->meetingpublic) ? 0 : 1;
$data->showzip = meetletacbmarketplace_legacy_setting_value($data, 'showzip');
$data->showzip = meetletacbfree_legacy_setting_value($data, 'showzip');
$data->showofflineplayer = empty($data->showofflineplayer) ? 0 : 1;
$data->showrecordingstab = meetletacbmarketplace_legacy_setting_value($data, 'showrecordingstab');
$data->showcontenttab = meetletacbmarketplace_legacy_setting_value($data, 'showcontenttab');
$data->showmp4 = meetletacbmarketplace_legacy_setting_value($data, 'showmp4');
$data->showmakeoffline = meetletacbmarketplace_legacy_setting_value($data, 'showmakeoffline');
$data->showrecordingstab = meetletacbfree_legacy_setting_value($data, 'showrecordingstab');
$data->showcontenttab = meetletacbfree_legacy_setting_value($data, 'showcontenttab');
$data->showmp4 = meetletacbfree_legacy_setting_value($data, 'showmp4');
$data->showmakeoffline = meetletacbfree_legacy_setting_value($data, 'showmakeoffline');
$data->linkmode = empty($data->linkmode) ? 0 : 1;
$data->existingscoid = (int)($data->existingscoid ?? 0);
$data->waitforhost = meetletacbmarketplace_legacy_setting_value($data, 'waitforhost');
$data->waitforhost = meetletacbfree_legacy_setting_value($data, 'waitforhost');
$data->meetinglang = clean_param($data->meetinglang ?? '', PARAM_ALPHANUMEXT);
if ($data->linkmode) {
$data->templatescoid = 0;
$data->meeturl = '';
}
$data->meeturl = meetletacbmarketplace_clean_meet_url($data->meeturl ?? '');
$data->meeturl = meetletacbfree_clean_meet_url($data->meeturl ?? '');
if (empty($data->featureaccess_override)) {
$data->featureaccess = '';
} else {
$matrix = optional_param_array('featureaccess_matrix', [], PARAM_RAW);
$data->featureaccess = \mod_meetletacbmarketplace\local\featureaccess::matrix_from_post($matrix);
$data->featureaccess = \mod_meetletacbfree\local\featureaccess::matrix_from_post($matrix);
}
unset($data->featureaccess_override, $data->featureaccess_matrix);
meetletacbmarketplace_clear_override_form_fields($data, $togglefields);
meetletacbfree_clear_override_form_fields($data, $togglefields);
$id = $DB->insert_record('meetletacbmarketplace', $data);
$id = $DB->insert_record('meetletacbfree', $data);
$data->id = $id;
meetletacbmarketplace_create_remote_meetings($data);
meetletacbmarketplace_grade_item_update($data);
meetletacbmarketplace_update_calendar($data);
meetletacbfree_create_remote_meetings($data);
meetletacbfree_grade_item_update($data);
meetletacbfree_update_calendar($data);
return $id;
}
@@ -154,13 +154,13 @@ function meetletacbmarketplace_add_instance($data, $mform = null) {
* Update instance.
*
* @param stdClass $data
* @param mod_meetletacbmarketplace_mod_form|null $mform
* @param mod_meetletacbfree_mod_form|null $mform
* @return bool
*/
function meetletacbmarketplace_update_instance($data, $mform = null) {
function meetletacbfree_update_instance($data, $mform = null) {
global $DB, $USER;
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
$data->timemodified = time();
$data->id = $data->instance;
@@ -174,17 +174,17 @@ function meetletacbmarketplace_update_instance($data, $mform = null) {
} else if (empty($data->participants)) {
$data->participants = json_encode(roles::get_participant_list_default($coursecontext, $USER->id ?? 0));
}
$togglefields = meetletacbmarketplace_activity_override_fields();
$data->settingoverrides = config::setting_overrides_json(meetletacbmarketplace_collect_setting_override_states($data, $togglefields));
$data->autooffline = meetletacbmarketplace_legacy_setting_value($data, 'autooffline');
$togglefields = meetletacbfree_activity_override_fields();
$data->settingoverrides = config::setting_overrides_json(meetletacbfree_collect_setting_override_states($data, $togglefields));
$data->autooffline = meetletacbfree_legacy_setting_value($data, 'autooffline');
$data->meetingpublic = empty($data->meetingpublic) ? 0 : 1;
$data->showzip = meetletacbmarketplace_legacy_setting_value($data, 'showzip');
$data->showzip = meetletacbfree_legacy_setting_value($data, 'showzip');
$data->showofflineplayer = empty($data->showofflineplayer) ? 0 : 1;
$data->showrecordingstab = meetletacbmarketplace_legacy_setting_value($data, 'showrecordingstab');
$data->showcontenttab = meetletacbmarketplace_legacy_setting_value($data, 'showcontenttab');
$data->showmp4 = meetletacbmarketplace_legacy_setting_value($data, 'showmp4');
$data->showmakeoffline = meetletacbmarketplace_legacy_setting_value($data, 'showmakeoffline');
$data->waitforhost = meetletacbmarketplace_legacy_setting_value($data, 'waitforhost');
$data->showrecordingstab = meetletacbfree_legacy_setting_value($data, 'showrecordingstab');
$data->showcontenttab = meetletacbfree_legacy_setting_value($data, 'showcontenttab');
$data->showmp4 = meetletacbfree_legacy_setting_value($data, 'showmp4');
$data->showmakeoffline = meetletacbfree_legacy_setting_value($data, 'showmakeoffline');
$data->waitforhost = meetletacbfree_legacy_setting_value($data, 'waitforhost');
$data->meetinglang = clean_param($data->meetinglang ?? '', PARAM_ALPHANUMEXT);
// linkmode / existingscoid are immutable after create.
unset($data->linkmode, $data->existingscoid);
@@ -192,17 +192,17 @@ function meetletacbmarketplace_update_instance($data, $mform = null) {
$data->featureaccess = '';
} else {
$matrix = optional_param_array('featureaccess_matrix', [], PARAM_RAW);
$data->featureaccess = \mod_meetletacbmarketplace\local\featureaccess::matrix_from_post($matrix);
$data->featureaccess = \mod_meetletacbfree\local\featureaccess::matrix_from_post($matrix);
}
unset($data->featureaccess_override, $data->featureaccess_matrix);
meetletacbmarketplace_clear_override_form_fields($data, $togglefields);
meetletacbfree_clear_override_form_fields($data, $togglefields);
$DB->update_record('meetletacbmarketplace', $data);
$DB->update_record('meetletacbfree', $data);
if (config::is_configured()) {
$service = new service();
$service->login_admin();
$maps = $DB->get_records('meetlet_marketplace_meetings', ['instanceid' => $data->id]);
$maps = $DB->get_records('meetletacbfree_meetings', ['instanceid' => $data->id]);
foreach ($maps as $map) {
$payload = clone $data;
if (!empty($map->groupid)) {
@@ -218,8 +218,8 @@ function meetletacbmarketplace_update_instance($data, $mform = null) {
$service->logout();
}
meetletacbmarketplace_grade_item_update($data);
meetletacbmarketplace_update_calendar($data);
meetletacbfree_grade_item_update($data);
meetletacbfree_update_calendar($data);
return true;
}
@@ -229,12 +229,12 @@ function meetletacbmarketplace_update_instance($data, $mform = null) {
* @param int $id
* @return bool
*/
function meetletacbmarketplace_delete_instance($id) {
function meetletacbfree_delete_instance($id) {
global $DB;
\mod_meetletacbmarketplace\registration\manager::require_registered();
\mod_meetletacbfree\registration\manager::require_registered();
if (!$record = $DB->get_record('meetletacbmarketplace', ['id' => $id])) {
if (!$record = $DB->get_record('meetletacbfree', ['id' => $id])) {
return false;
}
@@ -242,7 +242,7 @@ function meetletacbmarketplace_delete_instance($id) {
try {
$service = new service();
$service->login_admin();
$maps = $DB->get_records('meetlet_marketplace_meetings', ['instanceid' => $id]);
$maps = $DB->get_records('meetletacbfree_meetings', ['instanceid' => $id]);
$deleteremote = empty($record->linkmode);
foreach ($maps as $map) {
if ($deleteremote) {
@@ -255,11 +255,11 @@ function meetletacbmarketplace_delete_instance($id) {
}
}
$DB->delete_records('meetlet_marketplace_recordings', ['instanceid' => $id]);
$DB->delete_records('meetlet_marketplace_meetings', ['instanceid' => $id]);
$DB->delete_records('meetletacbmarketplace', ['id' => $id]);
$DB->delete_records('meetletacbfree_recordings', ['instanceid' => $id]);
$DB->delete_records('meetletacbfree_meetings', ['instanceid' => $id]);
$DB->delete_records('meetletacbfree', ['id' => $id]);
meetletacbmarketplace_grade_item_delete($record);
meetletacbfree_grade_item_delete($record);
return true;
}
@@ -268,7 +268,7 @@ function meetletacbmarketplace_delete_instance($id) {
*
* @param stdClass $data
*/
function meetletacbmarketplace_create_remote_meetings(stdClass $data): void {
function meetletacbfree_create_remote_meetings(stdClass $data): void {
global $DB, $COURSE, $USER;
if (!config::is_configured()) {
@@ -290,7 +290,7 @@ function meetletacbmarketplace_create_remote_meetings(stdClass $data): void {
$info = $service->meeting_info($scoid);
if (!$info) {
$service->logout();
throw new moodle_exception('errorexistingsco', 'meetletacbmarketplace');
throw new moodle_exception('errorexistingsco', 'meetletacbfree');
}
$service->set_meeting_public($scoid, !empty($data->meetingpublic));
// Push Moodle form values (name/times/options) onto the existing Adobe meeting.
@@ -301,12 +301,12 @@ function meetletacbmarketplace_create_remote_meetings(stdClass $data): void {
'groupid' => 0,
'urlpath' => $info->url ?? '',
];
$DB->insert_record('meetlet_marketplace_meetings', $map);
$DB->insert_record('meetletacbfree_meetings', $map);
$provisionscoids[] = $scoid;
if (!empty($info->url)) {
$DB->set_field('meetletacbmarketplace', 'meeturl', trim($info->url, '/'), ['id' => $data->id]);
$DB->set_field('meetletacbfree', 'meeturl', trim($info->url, '/'), ['id' => $data->id]);
}
meetletacbmarketplace_provision_creator_on_meetings($service, $data, $provisionscoids, $creatorrole);
meetletacbfree_provision_creator_on_meetings($service, $data, $provisionscoids, $creatorrole);
$service->logout();
return;
}
@@ -314,7 +314,7 @@ function meetletacbmarketplace_create_remote_meetings(stdClass $data): void {
$folder = $service->get_folder_scoid('meetings');
if (!$folder) {
$service->logout();
throw new moodle_exception('errornofolder', 'meetletacbmarketplace');
throw new moodle_exception('errornofolder', 'meetletacbfree');
}
// During add_instance, course_modules.instance is not linked yet — use form data.
@@ -326,7 +326,7 @@ function meetletacbmarketplace_create_remote_meetings(stdClass $data): void {
$payload = clone $data;
$payload->name = $data->name . '_' . $group->name;
if (!empty($data->meeturl)) {
$payload->meeturl = meetletacbmarketplace_clean_meet_url($data->meeturl . '_' . $group->name);
$payload->meeturl = meetletacbfree_clean_meet_url($data->meeturl . '_' . $group->name);
}
$scoid = $service->create_meeting($payload, $folder);
$service->set_meeting_public($scoid, !empty($data->meetingpublic));
@@ -337,7 +337,7 @@ function meetletacbmarketplace_create_remote_meetings(stdClass $data): void {
'groupid' => $group->id,
'urlpath' => $info->url ?? '',
];
$DB->insert_record('meetlet_marketplace_meetings', $map);
$DB->insert_record('meetletacbfree_meetings', $map);
$provisionscoids[] = $scoid;
}
} else {
@@ -350,14 +350,14 @@ function meetletacbmarketplace_create_remote_meetings(stdClass $data): void {
'groupid' => 0,
'urlpath' => $info->url ?? '',
];
$DB->insert_record('meetlet_marketplace_meetings', $map);
$DB->insert_record('meetletacbfree_meetings', $map);
$provisionscoids[] = $scoid;
if (empty($data->meeturl) && !empty($info->url)) {
$DB->set_field('meetletacbmarketplace', 'meeturl', trim($info->url, '/'), ['id' => $data->id]);
$DB->set_field('meetletacbfree', 'meeturl', trim($info->url, '/'), ['id' => $data->id]);
}
}
meetletacbmarketplace_provision_creator_on_meetings($service, $data, $provisionscoids, $creatorrole);
meetletacbfree_provision_creator_on_meetings($service, $data, $provisionscoids, $creatorrole);
$service->logout();
}
@@ -366,7 +366,7 @@ function meetletacbmarketplace_create_remote_meetings(stdClass $data): void {
*
* @param int[] $scoids
*/
function meetletacbmarketplace_provision_creator_on_meetings(service $service, stdClass $data, array $scoids, string $permission): void {
function meetletacbfree_provision_creator_on_meetings(service $service, stdClass $data, array $scoids, string $permission): void {
global $USER;
if (empty($scoids) || empty($USER->id)) {
return;
@@ -385,7 +385,7 @@ function meetletacbmarketplace_provision_creator_on_meetings(service $service, s
/**
* Clean custom meeting URL path.
*/
function meetletacbmarketplace_clean_meet_url(string $url): string {
function meetletacbfree_clean_meet_url(string $url): string {
$url = trim($url);
$url = trim($url, '/');
$url = preg_replace('/[^a-zA-Z0-9\-]/', '', $url);
@@ -395,7 +395,7 @@ function meetletacbmarketplace_clean_meet_url(string $url): string {
/**
* Grade item update.
*/
function meetletacbmarketplace_grade_item_update($meetlet, $grades = null) {
function meetletacbfree_grade_item_update($meetlet, $grades = null) {
global $CFG;
require_once($CFG->libdir . '/gradelib.php');
@@ -420,27 +420,27 @@ function meetletacbmarketplace_grade_item_update($meetlet, $grades = null) {
$grades = null;
}
return grade_update('mod/meetletacbmarketplace', $meetlet->course, 'mod', 'meetletacbmarketplace', $meetlet->id, 0, $grades, $params);
return grade_update('mod/meetletacbfree', $meetlet->course, 'mod', 'meetletacbfree', $meetlet->id, 0, $grades, $params);
}
/**
* Delete grade item.
*/
function meetletacbmarketplace_grade_item_delete($meetlet) {
function meetletacbfree_grade_item_delete($meetlet) {
global $CFG;
require_once($CFG->libdir . '/gradelib.php');
return grade_update('mod/meetletacbmarketplace', $meetlet->course, 'mod', 'meetletacbmarketplace', $meetlet->id, 0, null, ['deleted' => 1]);
return grade_update('mod/meetletacbfree', $meetlet->course, 'mod', 'meetletacbfree', $meetlet->id, 0, null, ['deleted' => 1]);
}
/**
* Update calendar event.
*/
function meetletacbmarketplace_update_calendar($meetlet): void {
function meetletacbfree_update_calendar($meetlet): void {
global $DB, $CFG;
require_once($CFG->dirroot . '/calendar/lib.php');
$event = $DB->get_record('event', [
'modulename' => 'meetletacbmarketplace',
'modulename' => 'meetletacbfree',
'instance' => $meetlet->id,
]);
if (!$event) {
@@ -461,12 +461,12 @@ function meetletacbmarketplace_update_calendar($meetlet): void {
$eventdata = new stdClass();
$eventdata->name = $meetlet->name;
$eventdata->description = format_module_intro('meetletacbmarketplace', $meetlet, $meetlet->coursemodule ?? 0, false);
$eventdata->description = format_module_intro('meetletacbfree', $meetlet, $meetlet->coursemodule ?? 0, false);
$eventdata->format = FORMAT_HTML;
$eventdata->courseid = $meetlet->course;
$eventdata->groupid = 0;
$eventdata->userid = 0;
$eventdata->modulename = 'meetletacbmarketplace';
$eventdata->modulename = 'meetletacbfree';
$eventdata->instance = $meetlet->id;
$eventdata->eventtype = 'course';
$eventdata->timestart = $meetlet->starttime;
@@ -484,22 +484,22 @@ function meetletacbmarketplace_update_calendar($meetlet): void {
/**
* Extend settings navigation (optional).
*/
function meetletacbmarketplace_extend_settings_navigation(settings_navigation $settingsnav, navigation_node $meetletnode) {
function meetletacbfree_extend_settings_navigation(settings_navigation $settingsnav, navigation_node $meetletnode) {
// Intentionally minimal ? roles are configured in activity settings.
}
/**
* Course module info for course page.
*/
function meetletacbmarketplace_get_coursemodule_info($coursemodule) {
function meetletacbfree_get_coursemodule_info($coursemodule) {
global $DB;
if (!$record = $DB->get_record('meetletacbmarketplace', ['id' => $coursemodule->instance], 'id, name, intro, introformat, starttime, endtime')) {
if (!$record = $DB->get_record('meetletacbfree', ['id' => $coursemodule->instance], 'id, name, intro, introformat, starttime, endtime')) {
return false;
}
$info = new cached_cm_info();
$info->name = $record->name;
if ($coursemodule->showdescription) {
$info->content = format_module_intro('meetletacbmarketplace', $record, $coursemodule->id, false);
$info->content = format_module_intro('meetletacbfree', $record, $coursemodule->id, false);
}
// Branded monologo: skip Moodle purpose colour filter (orange on course page).
$info->customdata['filtericon'] = false;
@@ -509,8 +509,8 @@ function meetletacbmarketplace_get_coursemodule_info($coursemodule) {
/**
* Apply plugin cron interval to the Moodle scheduled task row.
*/
function meetletacbmarketplace_update_cron_interval() {
\mod_meetletacbmarketplace\local\config::apply_cron_interval();
function meetletacbfree_update_cron_interval() {
\mod_meetletacbfree\local\config::apply_cron_interval();
}
/**
@@ -518,7 +518,7 @@ function meetletacbmarketplace_update_cron_interval() {
*
* @return string[]
*/
function meetletacbmarketplace_activity_override_fields(): array {
function meetletacbfree_activity_override_fields(): array {
return ['waitforhost', 'autooffline', 'showzip', 'showrecordingstab', 'showcontenttab', 'showmp4', 'showmakeoffline'];
}
@@ -529,11 +529,11 @@ function meetletacbmarketplace_activity_override_fields(): array {
* @param string[] $fields
* @return array<string,int>
*/
function meetletacbmarketplace_collect_setting_override_states(stdClass $data, array $fields): array {
function meetletacbfree_collect_setting_override_states(stdClass $data, array $fields): array {
$states = [];
foreach ($fields as $field) {
$statefield = $field . '_state';
$states[$field] = $data->{$statefield} ?? \mod_meetletacbmarketplace\local\config::OVERRIDE_INHERIT;
$states[$field] = $data->{$statefield} ?? \mod_meetletacbfree\local\config::OVERRIDE_INHERIT;
}
return $states;
}
@@ -541,30 +541,30 @@ function meetletacbmarketplace_collect_setting_override_states(stdClass $data, a
/**
* Keep legacy columns in sync for older code, reports and backups.
*/
function meetletacbmarketplace_legacy_setting_value(stdClass $data, string $field): int {
function meetletacbfree_legacy_setting_value(stdClass $data, string $field): int {
$statefield = $field . '_state';
$state = \mod_meetletacbmarketplace\local\config::normalize_override_state($data->{$statefield} ?? null);
if ($state === \mod_meetletacbmarketplace\local\config::OVERRIDE_ON) {
$state = \mod_meetletacbfree\local\config::normalize_override_state($data->{$statefield} ?? null);
if ($state === \mod_meetletacbfree\local\config::OVERRIDE_ON) {
return 1;
}
if ($state === \mod_meetletacbmarketplace\local\config::OVERRIDE_OFF) {
if ($state === \mod_meetletacbfree\local\config::OVERRIDE_OFF) {
return 0;
}
switch ($field) {
case 'waitforhost':
return \mod_meetletacbmarketplace\local\config::default_wait_for_host() ? 1 : 0;
return \mod_meetletacbfree\local\config::default_wait_for_host() ? 1 : 0;
case 'autooffline':
return \mod_meetletacbmarketplace\local\config::auto_offline_default() ? 1 : 0;
return \mod_meetletacbfree\local\config::auto_offline_default() ? 1 : 0;
case 'showzip':
return \mod_meetletacbmarketplace\local\config::feature_enabled('zip') ? 1 : 0;
return \mod_meetletacbfree\local\config::feature_enabled('zip') ? 1 : 0;
case 'showrecordingstab':
return \mod_meetletacbmarketplace\local\config::feature_enabled('recordingstab') ? 1 : 0;
return \mod_meetletacbfree\local\config::feature_enabled('recordingstab') ? 1 : 0;
case 'showcontenttab':
return \mod_meetletacbmarketplace\local\config::feature_enabled('contenttab') ? 1 : 0;
return \mod_meetletacbfree\local\config::feature_enabled('contenttab') ? 1 : 0;
case 'showmp4':
return \mod_meetletacbmarketplace\local\config::feature_enabled('mp4') ? 1 : 0;
return \mod_meetletacbfree\local\config::feature_enabled('mp4') ? 1 : 0;
case 'showmakeoffline':
return \mod_meetletacbmarketplace\local\config::feature_enabled('makeoffline') ? 1 : 0;
return \mod_meetletacbfree\local\config::feature_enabled('makeoffline') ? 1 : 0;
default:
return empty($data->{$field}) ? 0 : 1;
}
@@ -576,7 +576,7 @@ function meetletacbmarketplace_legacy_setting_value(stdClass $data, string $fiel
* @param stdClass $data
* @param string[] $fields
*/
function meetletacbmarketplace_clear_override_form_fields(stdClass $data, array $fields): void {
function meetletacbfree_clear_override_form_fields(stdClass $data, array $fields): void {
foreach ($fields as $field) {
$statefield = $field . '_state';
unset($data->{$statefield});
+67 -67
View File
@@ -4,20 +4,20 @@ defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/course/moodleform_mod.php');
use mod_meetletacbmarketplace\api\service;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbmarketplace\local\featureaccess;
use mod_meetletacbmarketplace\local\roles;
use mod_meetletacbmarketplace\registration\manager as registration_manager;
use mod_meetletacbfree\api\service;
use mod_meetletacbfree\local\config;
use mod_meetletacbfree\local\featureaccess;
use mod_meetletacbfree\local\roles;
use mod_meetletacbfree\registration\manager as registration_manager;
/**
* MeetLet mod form.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
class mod_meetletacbfree_mod_form extends moodleform_mod {
public function definition() {
global $OUTPUT, $PAGE, $USER;
@@ -34,35 +34,35 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
return;
}
$PAGE->requires->js(new moodle_url('/mod/meetletacbmarketplace/javascript/modform.js'));
$PAGE->requires->js(new moodle_url('/mod/meetletacbmarketplace/javascript/featureaccess_matrix.js'));
$PAGE->requires->js(new moodle_url('/mod/meetletacbmarketplace/javascript/settings_toggles.js'));
$PAGE->requires->css(new moodle_url('/mod/meetletacbmarketplace/styles.css', ['v' => '2026081913']));
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/modform.js'));
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/featureaccess_matrix.js'));
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/settings_toggles.js'));
$PAGE->requires->css(new moodle_url('/mod/meetletacbfree/styles.css', ['v' => '2026081913']));
$mform->addElement('header', 'general', get_string('general', 'form'));
$mform->addElement('text', 'name', get_string('meetingname', 'meetletacbmarketplace'), ['size' => '64']);
$mform->addElement('text', 'name', get_string('meetingname', 'meetletacbfree'), ['size' => '64']);
$mform->setType('name', PARAM_TEXT);
$mform->addRule('name', null, 'required', null, 'client');
$mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
$this->standard_intro_elements(get_string('meetingintro', 'meetletacbmarketplace'));
$this->standard_intro_elements(get_string('meetingintro', 'meetletacbfree'));
$mform->addElement('header', 'meetletroom', get_string('roomsettings', 'meetletacbmarketplace'));
$mform->addElement('header', 'meetletroom', get_string('roomsettings', 'meetletacbfree'));
// Create-new is default; existing meetings are loaded lazily via Ajax.
$linkmodes = [
0 => get_string('linkmode_create', 'meetletacbmarketplace'),
1 => get_string('linkmode_existing', 'meetletacbmarketplace'),
0 => get_string('linkmode_create', 'meetletacbfree'),
1 => get_string('linkmode_existing', 'meetletacbfree'),
];
$mform->addElement('select', 'linkmode', get_string('linkmode', 'meetletacbmarketplace'), $linkmodes);
$mform->addElement('select', 'linkmode', get_string('linkmode', 'meetletacbfree'), $linkmodes);
$mform->setDefault('linkmode', 0);
$mform->addHelpButton('linkmode', 'linkmode', 'meetletacbmarketplace');
$mform->addHelpButton('linkmode', 'linkmode', 'meetletacbfree');
if (!$isnew) {
$mform->hardFreeze('linkmode');
}
$meetingsmeta = [];
$selectedsco = (int)($current->existingscoid ?? 0);
$selectedlabel = get_string('chooseservermeeting', 'meetletacbmarketplace');
$selectedlabel = get_string('chooseservermeeting', 'meetletacbfree');
$readonly = !$isnew;
// On edit of a linked activity, keep the selected meeting visible without listing all.
if (!$isnew && !empty($current->linkmode) && $selectedsco && config::is_configured()) {
@@ -128,7 +128,7 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
'type' => 'search',
'class' => 'meetlet-combobox__search',
'data-meeting-search' => '1',
'placeholder' => get_string('searchservermeetings', 'meetletacbmarketplace'),
'placeholder' => get_string('searchservermeetings', 'meetletacbfree'),
'autocomplete' => 'off',
]) .
html_writer::tag('ul', $listhtml, [
@@ -144,45 +144,45 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
'data-meeting-picker' => '1',
'data-courseid' => (int)$this->_course->id,
'data-readonly' => $readonly ? '1' : '0',
'data-str-loading' => get_string('loadingmeetings', 'meetletacbmarketplace'),
'data-str-empty' => get_string('nomeetingsfound', 'meetletacbmarketplace'),
'data-str-choose' => get_string('chooseservermeeting', 'meetletacbmarketplace'),
'data-str-loading' => get_string('loadingmeetings', 'meetletacbfree'),
'data-str-empty' => get_string('nomeetingsfound', 'meetletacbfree'),
'data-str-choose' => get_string('chooseservermeeting', 'meetletacbfree'),
]
);
$mform->addElement('static', 'existingscoid_ui', get_string('existingscoid', 'meetletacbmarketplace'), $picker);
$mform->addElement('static', 'existingscoid_ui', get_string('existingscoid', 'meetletacbfree'), $picker);
$mform->hideIf('existingscoid_ui', 'linkmode', 'neq', 1);
$mform->addElement('html', html_writer::div('', 'd-none', [
'data-meetings-meta' => json_encode($meetingsmeta, JSON_UNESCAPED_UNICODE),
]));
$mform->addElement('text', 'meeturl', get_string('meeturl', 'meetletacbmarketplace'), ['size' => 40]);
$mform->addElement('text', 'meeturl', get_string('meeturl', 'meetletacbfree'), ['size' => 40]);
$mform->setType('meeturl', PARAM_PATH);
$mform->addHelpButton('meeturl', 'meeturl', 'meetletacbmarketplace');
$mform->addHelpButton('meeturl', 'meeturl', 'meetletacbfree');
$mform->hideIf('meeturl', 'linkmode', 'eq', 1);
$mform->addElement('select', 'meetingpublic', get_string('meetingtype', 'meetletacbmarketplace'), [
0 => get_string('private', 'meetletacbmarketplace'),
1 => get_string('public', 'meetletacbmarketplace'),
$mform->addElement('select', 'meetingpublic', get_string('meetingtype', 'meetletacbfree'), [
0 => get_string('private', 'meetletacbfree'),
1 => get_string('public', 'meetletacbfree'),
]);
$mform->setDefault('meetingpublic', 0);
$langs = config::meeting_lang_options();
$mform->addElement('select', 'meetinglang', get_string('meetinglang', 'meetletacbmarketplace'), $langs);
$mform->addElement('select', 'meetinglang', get_string('meetinglang', 'meetletacbfree'), $langs);
$mform->setType('meetinglang', PARAM_ALPHANUMEXT);
$mform->addHelpButton('meetinglang', 'meetinglang', 'meetletacbmarketplace');
$mform->addHelpButton('meetinglang', 'meetinglang', 'meetletacbfree');
$mform->setDefault('meetinglang', config::default_meeting_lang());
$waitstate = $this->resolve_toggle_state($current, 'waitforhost', $isnew);
$mform->addElement('static', 'waitforhost_state_ui', get_string('waitforhost', 'meetletacbmarketplace'),
$mform->addElement('static', 'waitforhost_state_ui', get_string('waitforhost', 'meetletacbfree'),
$this->render_override_chip_group(
'waitforhost_state',
$waitstate,
get_string('waitforhost_help', 'meetletacbmarketplace'),
get_string('waitforhost_help', 'meetletacbfree'),
[
config::OVERRIDE_INHERIT => get_string(
config::default_wait_for_host() ? 'settingstate_inherit_on' : 'settingstate_inherit_off',
'meetletacbmarketplace'
'meetletacbfree'
),
]
)
@@ -190,7 +190,7 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
$mform->addElement('hidden', 'waitforhost', $waitstate === config::OVERRIDE_ON ? 1 : 0);
$mform->setType('waitforhost', PARAM_INT);
$templates = [0 => get_string('defaulttemplate', 'meetletacbmarketplace')];
$templates = [0 => get_string('defaulttemplate', 'meetletacbfree')];
if (config::is_configured()) {
try {
$service = new service();
@@ -201,33 +201,33 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
// Ignore.
}
}
$mform->addElement('select', 'templatescoid', get_string('meettemplates', 'meetletacbmarketplace'), $templates);
$mform->addElement('select', 'templatescoid', get_string('meettemplates', 'meetletacbfree'), $templates);
$mform->setType('templatescoid', PARAM_INT);
$mform->hideIf('templatescoid', 'linkmode', 'eq', 1);
$mform->addElement('date_time_selector', 'starttime', get_string('starttime', 'meetletacbmarketplace'));
$mform->addElement('date_time_selector', 'starttime', get_string('starttime', 'meetletacbfree'));
$mform->addRule('starttime', null, 'required', null, 'client');
$mform->addElement('advcheckbox', 'endtimeenable', get_string('endtimeenable', 'meetletacbmarketplace'));
$mform->addElement('date_time_selector', 'endtime', get_string('endtime', 'meetletacbmarketplace'));
$mform->addElement('advcheckbox', 'endtimeenable', get_string('endtimeenable', 'meetletacbfree'));
$mform->addElement('date_time_selector', 'endtime', get_string('endtime', 'meetletacbfree'));
$mform->disabledIf('endtime', 'endtimeenable');
$mform->setDefault('endtime', time() + 2 * HOURSECS);
// BBB-style participant mapping.
$participantlist = roles::get_participant_list($current, $context);
$participantselection = roles::get_participant_selection_data();
$mform->addElement('header', 'permissions', get_string('rolemapping', 'meetletacbmarketplace'));
$mform->addElement('header', 'permissions', get_string('rolemapping', 'meetletacbfree'));
$mform->setExpanded('permissions');
$mform->addElement('static', 'rolemappingdesc', '', get_string('rolemapping_desc', 'meetletacbmarketplace'));
$mform->addElement('static', 'rolemappingdesc', '', get_string('rolemapping_desc', 'meetletacbfree'));
$participantsmode = $this->resolve_participants_mode($current, $isnew);
$mform->addElement('static', 'participantsmode_ui', get_string('rolemapping_mode', 'meetletacbmarketplace'),
$mform->addElement('static', 'participantsmode_ui', get_string('rolemapping_mode', 'meetletacbfree'),
$this->render_override_chip_group(
'participantsmode_state',
$participantsmode,
get_string('rolemapping_mode_help', 'meetletacbmarketplace'),
get_string('rolemapping_mode_help', 'meetletacbfree'),
[],
[
roles::MODE_INHERIT => get_string('settingstate_inherit', 'meetletacbmarketplace'),
roles::MODE_OVERRIDE => get_string('rolemapping_mode_override_short', 'meetletacbmarketplace'),
roles::MODE_INHERIT => get_string('settingstate_inherit', 'meetletacbfree'),
roles::MODE_OVERRIDE => get_string('rolemapping_mode_override_short', 'meetletacbfree'),
]
)
);
@@ -245,26 +245,26 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
$participantselection['options'],
$participantselection['selected']);
$action = new single_button(new moodle_url(qualified_me()),
get_string('participant_add', 'meetletacbmarketplace'),
get_string('participant_add', 'meetletacbfree'),
'post',
single_button::BUTTON_SECONDARY,
['name' => 'meetlet_participant_selection_add']
);
$html = $OUTPUT->render_from_template('mod_meetletacbmarketplace/participant_form', [
$html = $OUTPUT->render_from_template('mod_meetletacbfree/participant_form', [
'selectionType' => $selectiontype->export_for_template($OUTPUT),
'selectionParticipant' => $selectionparticipants->export_for_template($OUTPUT),
'action' => $action->export_for_template($OUTPUT),
]);
$mform->addElement('static', 'static_participant_list', get_string('participant_list', 'meetletacbmarketplace'), $html);
$mform->addElement('static', 'static_participant_list', get_string('participant_list', 'meetletacbfree'), $html);
$mform->addElement('html', html_writer::div('', 'd-none', [
'data-participant-data' => json_encode(roles::get_participant_data($context, $current ?: (object)['id' => 0])),
]));
if (featureaccess::activity_override_enabled()) {
$mform->addElement('header', 'meetletaccess', get_string('featureaccess_activity', 'meetletacbmarketplace'));
$mform->addElement('advcheckbox', 'featureaccess_override', get_string('featureaccess_override', 'meetletacbmarketplace'),
get_string('featureaccess_override_help', 'meetletacbmarketplace'));
$mform->addElement('header', 'meetletaccess', get_string('featureaccess_activity', 'meetletacbfree'));
$mform->addElement('advcheckbox', 'featureaccess_override', get_string('featureaccess_override', 'meetletacbfree'),
get_string('featureaccess_override_help', 'meetletacbfree'));
$hascustom = $current && !empty($current->featureaccess);
$mform->setDefault('featureaccess_override', $hascustom ? 1 : 0);
$matrix = featureaccess::matrix_for_activity($current);
@@ -274,17 +274,17 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
}
if (config::offline_render_active()) {
$mform->addElement('header', 'meetletoffline', get_string('offlinesettings', 'meetletacbmarketplace'));
$mform->addElement('header', 'meetletoffline', get_string('offlinesettings', 'meetletacbfree'));
$autostate = $this->resolve_toggle_state($current, 'autooffline', $isnew);
$mform->addElement('static', 'autooffline_state_ui', get_string('autooffline', 'meetletacbmarketplace'),
$mform->addElement('static', 'autooffline_state_ui', get_string('autooffline', 'meetletacbfree'),
$this->render_override_chip_group(
'autooffline_state',
$autostate,
get_string('autooffline_help', 'meetletacbmarketplace'),
get_string('autooffline_help', 'meetletacbfree'),
[
config::OVERRIDE_INHERIT => get_string(
config::auto_offline_default() ? 'settingstate_inherit_on' : 'settingstate_inherit_off',
'meetletacbmarketplace'
'meetletacbfree'
),
]
)
@@ -293,7 +293,7 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
$mform->setType('autooffline', PARAM_INT);
}
$mform->addElement('header', 'meetletfeatures', get_string('activityfeatures', 'meetletacbmarketplace'));
$mform->addElement('header', 'meetletfeatures', get_string('activityfeatures', 'meetletacbfree'));
$featurefields = [
'zip' => 'showzip',
'recordingstab' => 'showrecordingstab',
@@ -310,25 +310,25 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
}
$state = $this->resolve_toggle_state($current, $field, $isnew);
$inheritkey = config::feature_enabled($feature) ? 'settingstate_inherit_on' : 'settingstate_inherit_off';
$help = ($field === 'showzip') ? get_string('showzip_help', 'meetletacbmarketplace') : '';
$mform->addElement('static', $field . '_state_ui', get_string($field, 'meetletacbmarketplace'),
$help = ($field === 'showzip') ? get_string('showzip_help', 'meetletacbfree') : '';
$mform->addElement('static', $field . '_state_ui', get_string($field, 'meetletacbfree'),
$this->render_override_chip_group(
$field . '_state',
$state,
$help,
[config::OVERRIDE_INHERIT => get_string($inheritkey, 'meetletacbmarketplace')]
[config::OVERRIDE_INHERIT => get_string($inheritkey, 'meetletacbfree')]
)
);
$mform->addElement('hidden', $field, $state === config::OVERRIDE_ON ? 1 : 0);
$mform->setType($field, PARAM_INT);
if ($field === 'showzip') {
$mform->removeElement($field . '_state_ui');
$mform->addElement('static', $field . '_state_ui', get_string($field, 'meetletacbmarketplace'),
$mform->addElement('static', $field . '_state_ui', get_string($field, 'meetletacbfree'),
$this->render_override_chip_group(
$field . '_state',
$state,
get_string('showzip_help', 'meetletacbmarketplace'),
[config::OVERRIDE_INHERIT => get_string($inheritkey, 'meetletacbmarketplace')]
get_string('showzip_help', 'meetletacbfree'),
[config::OVERRIDE_INHERIT => get_string($inheritkey, 'meetletacbfree')]
)
);
}
@@ -349,7 +349,7 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
public function data_preprocessing(&$defaultvalues) {
parent::data_preprocessing($defaultvalues);
$defaultvalues['endtimeenable'] = !empty($defaultvalues['endtime']) ? 1 : 0;
foreach (\meetletacbmarketplace_activity_override_fields() as $field) {
foreach (\meetletacbfree_activity_override_fields() as $field) {
$defaultvalues[$field . '_state'] = $this->resolve_toggle_state((object)$defaultvalues, $field, false);
}
$defaultvalues['participantsmode'] = $this->resolve_participants_mode((object)$defaultvalues, false);
@@ -367,18 +367,18 @@ class mod_meetletacbmarketplace_mod_form extends moodleform_mod {
public function validation($data, $files) {
$errors = parent::validation($data, $files);
if (!registration_manager::is_registered()) {
$errors['registrationlock'] = get_string('registration_required', 'meetletacbmarketplace');
$errors['registrationlock'] = get_string('registration_required', 'meetletacbfree');
return $errors;
}
if (!empty($data['endtimeenable']) && (int)$data['endtime'] <= (int)$data['starttime']) {
$errors['endtime'] = get_string('greaterstarttime', 'meetletacbmarketplace');
$errors['endtime'] = get_string('greaterstarttime', 'meetletacbfree');
}
if (!empty($data['meeturl']) && empty($data['linkmode'])
&& !preg_match('/^[a-zA-Z][a-zA-Z0-9\-]*$/', $data['meeturl'])) {
$errors['meeturl'] = get_string('invalidurl', 'meetletacbmarketplace');
$errors['meeturl'] = get_string('invalidurl', 'meetletacbfree');
}
if (!empty($data['linkmode']) && empty($data['existingscoid'])) {
$errors['existingscoid_ui'] = get_string('errorexistingsco', 'meetletacbmarketplace');
$errors['existingscoid_ui'] = get_string('errorexistingsco', 'meetletacbfree');
}
return $errors;
}
+114 -114
View File
@@ -17,19 +17,19 @@
/**
* Admin settings for MeetLet Adobe Connect Bridge (tabbed).
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
use mod_meetletacbmarketplace\admin\settingspage_tabs;
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbmarketplace\local\conntest_runner;
use mod_meetletacbmarketplace\local\privacy_policy;
use mod_meetletacbmarketplace\local\server_guide;
use mod_meetletacbmarketplace\registration\manager as registration_manager;
use mod_meetletacbfree\admin\settingspage_tabs;
use mod_meetletacbfree\local\config;
use mod_meetletacbfree\local\conntest_runner;
use mod_meetletacbfree\local\privacy_policy;
use mod_meetletacbfree\local\server_guide;
use mod_meetletacbfree\registration\manager as registration_manager;
// Ensure class is available even if Moodle classmap cache is stale after adding this file.
require_once(__DIR__ . '/classes/local/server_guide.php');
@@ -45,17 +45,17 @@ if ($ADMIN->fulltree) {
$settings->hidden
);
$logo = $OUTPUT->image_url('adobeconnect', 'meetletacbmarketplace');
$stylesurl = new moodle_url('/mod/meetletacbmarketplace/styles.css', ['v' => '2026090146']);
$jsurl = new moodle_url('/mod/meetletacbmarketplace/javascript/settings_conntest.js', ['v' => '2026082135']);
$togglejsurl = new moodle_url('/mod/meetletacbmarketplace/javascript/settings_toggles.js', ['v' => '2026081907']);
$matrixjsurl = new moodle_url('/mod/meetletacbmarketplace/javascript/featureaccess_matrix.js');
$accessresetjsurl = new moodle_url('/mod/meetletacbmarketplace/javascript/settings_access_reset.js', ['v' => '2026090115']);
$resetajaxurl = new moodle_url('/mod/meetletacbmarketplace/ajax/settings_reset.php');
$modalscrolljsurl = new moodle_url('/mod/meetletacbmarketplace/javascript/meetlet_modal_scroll.js', ['v' => '2026082239']);
$registrationjsurl = new moodle_url('/mod/meetletacbmarketplace/javascript/settings_registration.js', ['v' => '2026090144']);
$logo = $OUTPUT->image_url('adobeconnect', 'meetletacbfree');
$stylesurl = new moodle_url('/mod/meetletacbfree/styles.css', ['v' => '2026090146']);
$jsurl = new moodle_url('/mod/meetletacbfree/javascript/settings_conntest.js', ['v' => '2026082135']);
$togglejsurl = new moodle_url('/mod/meetletacbfree/javascript/settings_toggles.js', ['v' => '2026081907']);
$matrixjsurl = new moodle_url('/mod/meetletacbfree/javascript/featureaccess_matrix.js');
$accessresetjsurl = new moodle_url('/mod/meetletacbfree/javascript/settings_access_reset.js', ['v' => '2026090115']);
$resetajaxurl = new moodle_url('/mod/meetletacbfree/ajax/settings_reset.php');
$modalscrolljsurl = new moodle_url('/mod/meetletacbfree/javascript/meetlet_modal_scroll.js', ['v' => '2026082239']);
$registrationjsurl = new moodle_url('/mod/meetletacbfree/javascript/settings_registration.js', ['v' => '2026090144']);
$cronjsurl = null;
$ajaxurl = new moodle_url('/mod/meetletacbmarketplace/ajax/conntest.php');
$ajaxurl = new moodle_url('/mod/meetletacbfree/ajax/conntest.php');
// Load styles.css explicitly on admin tabs (theme concatenate alone is not enough for switch CSS).
$styles = '
@@ -671,13 +671,13 @@ html[dir="rtl"] .path-admin #adminsettings .form-buttons {
]);
}
$versionbadge = $release !== ''
? html_writer::span(get_string('settingsversion', 'meetletacbmarketplace', $release), 'meetlet-settings-version')
? html_writer::span(get_string('settingsversion', 'meetletacbfree', $release), 'meetlet-settings-version')
: '';
$hero = $styles . html_writer::div(
html_writer::img($logo, 'Adobe Connect', ['alt' => 'Adobe Connect']) .
html_writer::div(
html_writer::tag('h3', get_string('pluginname', 'meetletacbmarketplace')) .
html_writer::tag('p', get_string('settingsintro', 'meetletacbmarketplace')),
html_writer::tag('h3', get_string('pluginname', 'meetletacbfree')) .
html_writer::tag('p', get_string('settingsintro', 'meetletacbfree')),
'meetlet-settings-copy'
) .
$versionbadge,
@@ -686,26 +686,26 @@ html[dir="rtl"] .path-admin #adminsettings .form-buttons {
$settings->set_hero($hero);
// Tab: Online activation (required before other features work).
$page = new admin_settingpage('meetletacbmarketplace_registration', get_string('tab_registration', 'meetletacbmarketplace'));
$page = new admin_settingpage('meetletacbfree_registration', get_string('tab_registration', 'meetletacbfree'));
$page->add(new admin_setting_heading(
'meetletacbmarketplace/registrationheading',
get_string('registration_heading', 'meetletacbmarketplace'),
get_string('registration_heading_desc', 'meetletacbmarketplace')
'meetletacbfree/registrationheading',
get_string('registration_heading', 'meetletacbfree'),
get_string('registration_heading_desc', 'meetletacbfree')
));
$page->add(new admin_setting_configtext(
'meetletacbmarketplace/registration_api_url',
get_string('registration_api_url', 'meetletacbmarketplace'),
get_string('registration_api_url_desc', 'meetletacbmarketplace'),
'meetletacbfree/registration_api_url',
get_string('registration_api_url', 'meetletacbfree'),
get_string('registration_api_url_desc', 'meetletacbfree'),
registration_manager::DEFAULT_API_URL,
PARAM_URL
));
$page->add(new \mod_meetletacbmarketplace\admin\setting_registration());
$page->add(new \mod_meetletacbfree\admin\setting_registration());
$settings->add($page);
// Tab: Privacy (always visible — read policy before activating).
$page = new admin_settingpage('meetletacbmarketplace_privacy', get_string('tab_privacy', 'meetletacbmarketplace'));
$page = new admin_settingpage('meetletacbfree_privacy', get_string('tab_privacy', 'meetletacbfree'));
$page->add(new admin_setting_heading(
'meetletacbmarketplace/privacycard',
'meetletacbfree/privacycard',
'',
privacy_policy::render()
));
@@ -716,93 +716,93 @@ html[dir="rtl"] .path-admin #adminsettings .form-buttons {
if ($registered) {
// Tab: Server setup guide.
$page = new admin_settingpage('meetletacbmarketplace_serverguide', get_string('tab_serverguide', 'meetletacbmarketplace'));
$page = new admin_settingpage('meetletacbfree_serverguide', get_string('tab_serverguide', 'meetletacbfree'));
$page->add(new admin_setting_heading(
'meetletacbmarketplace/serverguidecard',
'meetletacbfree/serverguidecard',
'',
server_guide::render()
));
$settings->add($page);
// Tab 2: Server settings (API / admin / offline listener).
$page = new admin_settingpage('meetletacbmarketplace_connection', get_string('settings_connection', 'meetletacbmarketplace'));
$page = new admin_settingpage('meetletacbfree_connection', get_string('settings_connection', 'meetletacbfree'));
$page->add(new admin_setting_heading(
'meetletacbmarketplace/connectionheading',
get_string('settings_connection', 'meetletacbmarketplace'),
get_string('settings_connection_desc', 'meetletacbmarketplace')
'meetletacbfree/connectionheading',
get_string('settings_connection', 'meetletacbfree'),
get_string('settings_connection_desc', 'meetletacbfree')
));
$page->add(new admin_setting_heading(
'meetletacbmarketplace/server_api_group',
'meetletacbfree/server_api_group',
'',
html_writer::div(
html_writer::tag('h4', get_string('server_group_api', 'meetletacbmarketplace')) .
html_writer::tag('p', get_string('server_group_api_desc', 'meetletacbmarketplace')),
html_writer::tag('h4', get_string('server_group_api', 'meetletacbfree')) .
html_writer::tag('p', get_string('server_group_api_desc', 'meetletacbfree')),
'meetlet-server-group'
)
));
$page->add(new admin_setting_configtext(
'meetletacbmarketplace/host', get_string('host', 'meetletacbmarketplace'), get_string('host_desc', 'meetletacbmarketplace'),
'meetletacbfree/host', get_string('host', 'meetletacbfree'), get_string('host_desc', 'meetletacbfree'),
'https://connect.example.edu/api/xml', PARAM_URL
));
$page->add(new admin_setting_configtext(
'meetletacbmarketplace/meethost', get_string('meethost', 'meetletacbmarketplace'), get_string('meethost_desc', 'meetletacbmarketplace'),
'meetletacbfree/meethost', get_string('meethost', 'meetletacbfree'), get_string('meethost_desc', 'meetletacbfree'),
'connect.example.edu', PARAM_HOST
));
$page->add(new admin_setting_configtext(
'meetletacbmarketplace/port', get_string('port', 'meetletacbmarketplace'), get_string('port_desc', 'meetletacbmarketplace'),
'meetletacbfree/port', get_string('port', 'meetletacbfree'), get_string('port_desc', 'meetletacbfree'),
'443', PARAM_INT
));
$page->add(new admin_setting_configcheckbox(
'meetletacbmarketplace/https', get_string('https', 'meetletacbmarketplace'), get_string('https_desc', 'meetletacbmarketplace'), 1
'meetletacbfree/https', get_string('https', 'meetletacbfree'), get_string('https_desc', 'meetletacbfree'), 1
));
$page->add(new admin_setting_heading(
'meetletacbmarketplace/server_admin_group',
'meetletacbfree/server_admin_group',
'',
html_writer::div(
html_writer::tag('h4', get_string('server_group_admin', 'meetletacbmarketplace')) .
html_writer::tag('p', get_string('server_group_admin_desc', 'meetletacbmarketplace')),
html_writer::tag('h4', get_string('server_group_admin', 'meetletacbfree')) .
html_writer::tag('p', get_string('server_group_admin_desc', 'meetletacbfree')),
'meetlet-server-group'
)
));
$page->add(new admin_setting_configtext(
'meetletacbmarketplace/admin_login', get_string('admin_login', 'meetletacbmarketplace'), get_string('admin_login_desc', 'meetletacbmarketplace'),
'meetletacbfree/admin_login', get_string('admin_login', 'meetletacbfree'), get_string('admin_login_desc', 'meetletacbfree'),
'', PARAM_RAW_TRIMMED
));
$page->add(new admin_setting_configpasswordunmask(
'meetletacbmarketplace/admin_password', get_string('admin_password', 'meetletacbmarketplace'), get_string('admin_password_desc', 'meetletacbmarketplace'), ''
'meetletacbfree/admin_password', get_string('admin_password', 'meetletacbfree'), get_string('admin_password_desc', 'meetletacbfree'), ''
));
$page->add(new admin_setting_configtext(
'meetletacbmarketplace/admin_httpauth', get_string('admin_httpauth', 'meetletacbmarketplace'), get_string('admin_httpauth_desc', 'meetletacbmarketplace'),
'meetletacbfree/admin_httpauth', get_string('admin_httpauth', 'meetletacbfree'), get_string('admin_httpauth_desc', 'meetletacbfree'),
'Generate-Safe-Random-Token', PARAM_TEXT
));
$page->add(new admin_setting_configcheckbox(
'meetletacbmarketplace/email_login', get_string('email_login', 'meetletacbmarketplace'), get_string('email_login_desc', 'meetletacbmarketplace'), 1
'meetletacbfree/email_login', get_string('email_login', 'meetletacbfree'), get_string('email_login_desc', 'meetletacbfree'), 1
));
$settings->add($page);
// Tab 4: Connection test (Ajax).
$page = new admin_settingpage('meetletacbmarketplace_test', get_string('tab_connectiontest', 'meetletacbmarketplace'));
$page = new admin_settingpage('meetletacbfree_test', get_string('tab_connectiontest', 'meetletacbfree'));
$steplabels = [
'login' => get_string('testlogin', 'meetletacbmarketplace'),
'folders' => get_string('testfolders', 'meetletacbmarketplace'),
'user' => get_string('testuser', 'meetletacbmarketplace'),
'sso' => get_string('testsso', 'meetletacbmarketplace'),
'cleanup' => get_string('testcleanup', 'meetletacbmarketplace'),
'login' => get_string('testlogin', 'meetletacbfree'),
'folders' => get_string('testfolders', 'meetletacbfree'),
'user' => get_string('testuser', 'meetletacbfree'),
'sso' => get_string('testsso', 'meetletacbfree'),
'cleanup' => get_string('testcleanup', 'meetletacbfree'),
];
$testui = html_writer::div(
html_writer::start_div('meetlet-conntest__hero') .
html_writer::img($logo, 'Adobe Connect', ['class' => 'meetlet-conntest__logo']) .
html_writer::tag('h2', get_string('conntesttitle', 'meetletacbmarketplace'), ['class' => 'meetlet-conntest__title']) .
html_writer::tag('p', get_string('conntestintro', 'meetletacbmarketplace'), ['class' => 'meetlet-conntest__intro']) .
html_writer::tag('h2', get_string('conntesttitle', 'meetletacbfree'), ['class' => 'meetlet-conntest__title']) .
html_writer::tag('p', get_string('conntestintro', 'meetletacbfree'), ['class' => 'meetlet-conntest__intro']) .
html_writer::end_div() .
html_writer::div(
html_writer::tag('button',
'<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">'
. '<path fill="currentColor" d="M8 5v14l11-7z"/></svg>'
. html_writer::span(get_string('runtest', 'meetletacbmarketplace'), 'meetlet-btn-with-icon__label'),
. html_writer::span(get_string('runtest', 'meetletacbfree'), 'meetlet-btn-with-icon__label'),
[
'type' => 'button',
'class' => 'meetlet-settings-btn meetlet-btn-with-icon',
@@ -832,110 +832,110 @@ html[dir="rtl"] .path-admin #adminsettings .form-buttons {
'data-sesskey' => sesskey(),
'data-steps' => implode(',', conntest_runner::STEPS),
'data-step-labels' => json_encode($steplabels, JSON_UNESCAPED_UNICODE),
'data-str-ok' => get_string('testok', 'meetletacbmarketplace'),
'data-str-fail' => get_string('testfail', 'meetletacbmarketplace'),
'data-str-running' => get_string('testrunning', 'meetletacbmarketplace'),
'data-str-ok' => get_string('testok', 'meetletacbfree'),
'data-str-fail' => get_string('testfail', 'meetletacbfree'),
'data-str-running' => get_string('testrunning', 'meetletacbfree'),
'data-str-idle' => '',
'data-str-waiting' => get_string('testwaiting', 'meetletacbmarketplace'),
'data-str-runningstep' => get_string('testrunningstep', 'meetletacbmarketplace'),
'data-str-skipped' => get_string('testskipped', 'meetletacbmarketplace'),
'data-str-progress' => get_string('testprogress', 'meetletacbmarketplace'),
'data-str-waiting' => get_string('testwaiting', 'meetletacbfree'),
'data-str-runningstep' => get_string('testrunningstep', 'meetletacbfree'),
'data-str-skipped' => get_string('testskipped', 'meetletacbfree'),
'data-str-progress' => get_string('testprogress', 'meetletacbfree'),
]
);
$page->add(new admin_setting_heading('meetletacbmarketplace/testui', '', $testui));
$page->add(new admin_setting_heading('meetletacbfree/testui', '', $testui));
$settings->add($page);
// Tab 4: Meeting settings (defaults + feature visibility).
$page = new admin_settingpage('meetletacbmarketplace_meetings', get_string('tab_meetingsettings', 'meetletacbmarketplace'));
$page = new admin_settingpage('meetletacbfree_meetings', get_string('tab_meetingsettings', 'meetletacbfree'));
$page->add(new admin_setting_heading(
'meetletacbmarketplace/roomdefaultsheading',
get_string('roomdefaults', 'meetletacbmarketplace'),
get_string('roomdefaults_desc', 'meetletacbmarketplace')
'meetletacbfree/roomdefaultsheading',
get_string('roomdefaults', 'meetletacbfree'),
get_string('roomdefaults_desc', 'meetletacbfree')
));
$page->add(new admin_setting_configselect(
'meetletacbmarketplace/default_meetinglang',
get_string('default_meetinglang', 'meetletacbmarketplace'),
get_string('default_meetinglang_desc', 'meetletacbmarketplace'),
'meetletacbfree/default_meetinglang',
get_string('default_meetinglang', 'meetletacbfree'),
get_string('default_meetinglang_desc', 'meetletacbfree'),
'',
config::meeting_lang_options()
));
$page->add(new admin_setting_configcheckbox(
'meetletacbmarketplace/default_waitforhost',
get_string('default_waitforhost', 'meetletacbmarketplace'),
get_string('default_waitforhost_desc', 'meetletacbmarketplace'),
'meetletacbfree/default_waitforhost',
get_string('default_waitforhost', 'meetletacbfree'),
get_string('default_waitforhost_desc', 'meetletacbfree'),
0
));
$page->add(new admin_setting_heading(
'meetletacbmarketplace/featuresheading',
get_string('featuresheading', 'meetletacbmarketplace'),
get_string('featuresheading_desc', 'meetletacbmarketplace')
'meetletacbfree/featuresheading',
get_string('featuresheading', 'meetletacbfree'),
get_string('featuresheading_desc', 'meetletacbfree')
));
$featuregroups = ['recordingstab', 'contenttab'];
foreach ($featuregroups as $feature) {
$grouphtml = html_writer::div(
html_writer::tag('h4', get_string('featuregroup_' . $feature, 'meetletacbmarketplace')) .
html_writer::tag('p', get_string('featuregroup_' . $feature . '_desc', 'meetletacbmarketplace')),
html_writer::tag('h4', get_string('featuregroup_' . $feature, 'meetletacbfree')) .
html_writer::tag('p', get_string('featuregroup_' . $feature . '_desc', 'meetletacbfree')),
'meetlet-feature-group'
);
$page->add(new admin_setting_heading(
'meetletacbmarketplace/featuregroup_' . $feature,
'meetletacbfree/featuregroup_' . $feature,
'',
$grouphtml
));
// ZIP download is off by default; other features stay on.
$enabledefault = ($feature === 'zip') ? 0 : 1;
$page->add(new admin_setting_configcheckbox(
'meetletacbmarketplace/enable_' . $feature,
get_string('enable_' . $feature, 'meetletacbmarketplace'),
get_string('enable_' . $feature . '_desc', 'meetletacbmarketplace'),
'meetletacbfree/enable_' . $feature,
get_string('enable_' . $feature, 'meetletacbfree'),
get_string('enable_' . $feature . '_desc', 'meetletacbfree'),
$enabledefault
));
$page->add(new admin_setting_configcheckbox(
'meetletacbmarketplace/allow_override_' . $feature,
get_string('allow_override_' . $feature, 'meetletacbmarketplace'),
get_string('allow_override_' . $feature . '_desc', 'meetletacbmarketplace'),
'meetletacbfree/allow_override_' . $feature,
get_string('allow_override_' . $feature, 'meetletacbfree'),
get_string('allow_override_' . $feature . '_desc', 'meetletacbfree'),
1
));
}
$settings->add($page);
// Tab 5: Role feature access + Adobe room role mapping.
$page = new admin_settingpage('meetletacbmarketplace_access', get_string('tab_accesssettings', 'meetletacbmarketplace'));
$page = new admin_settingpage('meetletacbfree_access', get_string('tab_accesssettings', 'meetletacbfree'));
$page->add(new admin_setting_heading(
'meetletacbmarketplace/rolemappingheading',
get_string('siterolemapping', 'meetletacbmarketplace'),
get_string('siterolemapping_desc', 'meetletacbmarketplace')
'meetletacbfree/rolemappingheading',
get_string('siterolemapping', 'meetletacbfree'),
get_string('siterolemapping_desc', 'meetletacbfree')
));
$page->add(new \mod_meetletacbmarketplace\admin\setting_rolemapping());
$page->add(new \mod_meetletacbfree\admin\setting_rolemapping());
$page->add(new admin_setting_heading(
'meetletacbmarketplace/accessheading',
get_string('featureaccess', 'meetletacbmarketplace'),
get_string('featureaccess_desc', 'meetletacbmarketplace')
'meetletacbfree/accessheading',
get_string('featureaccess', 'meetletacbfree'),
get_string('featureaccess_desc', 'meetletacbfree')
));
$page->add(new admin_setting_configcheckbox(
'meetletacbmarketplace/activity_featureaccess',
get_string('activity_featureaccess', 'meetletacbmarketplace'),
get_string('activity_featureaccess_desc', 'meetletacbmarketplace'),
'meetletacbfree/activity_featureaccess',
get_string('activity_featureaccess', 'meetletacbfree'),
get_string('activity_featureaccess_desc', 'meetletacbfree'),
1
));
$page->add(new \mod_meetletacbmarketplace\admin\setting_featureaccess());
$page->add(new \mod_meetletacbfree\admin\setting_featureaccess());
$page->add(new admin_setting_heading(
'meetletacbmarketplace/accessresetassets',
'meetletacbfree/accessresetassets',
'',
\mod_meetletacbmarketplace\admin\access_reset_ui::page_assets($resetajaxurl)
\mod_meetletacbfree\admin\access_reset_ui::page_assets($resetajaxurl)
));
$settings->add($page);
} // End tabs unlocked after online activation.
// Tab: About developer / MeetLet (read-only; always visible).
$page = new admin_settingpage('meetletacbmarketplace_about', get_string('tab_aboutdev', 'meetletacbmarketplace'));
$meetletlogo = $OUTPUT->image_url('meetlet_logo', 'meetletacbmarketplace');
$page = new admin_settingpage('meetletacbfree_about', get_string('tab_aboutdev', 'meetletacbfree'));
$meetletlogo = $OUTPUT->image_url('meetlet_logo', 'meetletacbfree');
$abouturl = new moodle_url('https://meetlet.net/', [
'utm_source' => 'moodle',
'utm_medium' => 'plugin',
'utm_campaign' => 'meetletacbmarketplace',
'utm_campaign' => 'meetletacbfree',
'utm_content' => 'about_developer_tab',
]);
$about = html_writer::div(
@@ -943,16 +943,16 @@ html[dir="rtl"] .path-admin #adminsettings .form-buttons {
html_writer::img($meetletlogo, 'MeetLet', ['alt' => 'MeetLet']),
'meetlet-about__brand'
) .
html_writer::tag('h4', get_string('about_heading', 'meetletacbmarketplace')) .
html_writer::tag('p', get_string('about_body_p1', 'meetletacbmarketplace')) .
html_writer::tag('p', get_string('about_body_p2', 'meetletacbmarketplace')) .
html_writer::tag('p', get_string('about_body_p3', 'meetletacbmarketplace')) .
html_writer::tag('p', get_string('about_body_p4', 'meetletacbmarketplace')) .
html_writer::tag('p', get_string('marketplace_commercial_note', 'meetletacbmarketplace'), [
html_writer::tag('h4', get_string('about_heading', 'meetletacbfree')) .
html_writer::tag('p', get_string('about_body_p1', 'meetletacbfree')) .
html_writer::tag('p', get_string('about_body_p2', 'meetletacbfree')) .
html_writer::tag('p', get_string('about_body_p3', 'meetletacbfree')) .
html_writer::tag('p', get_string('about_body_p4', 'meetletacbfree')) .
html_writer::tag('p', get_string('marketplace_commercial_note', 'meetletacbfree'), [
'class' => 'meetlet-about__commercial',
]) .
html_writer::div(
html_writer::link($abouturl, get_string('about_visit_website', 'meetletacbmarketplace'), [
html_writer::link($abouturl, get_string('about_visit_website', 'meetletacbfree'), [
'class' => 'meetlet-about__cta',
'target' => '_blank',
'rel' => 'noopener',
@@ -961,7 +961,7 @@ html[dir="rtl"] .path-admin #adminsettings .form-buttons {
),
'meetlet-about meetlet-settings-card'
);
$page->add(new admin_setting_heading('meetletacbmarketplace/aboutcard', '', $about));
$page->add(new admin_setting_heading('meetletacbfree/aboutcard', '', $about));
$settings->add($page);
}
+5 -5
View File
@@ -2049,13 +2049,13 @@ html[dir="rtl"] .path-admin #adminsettings .form-item:has(.meetlet-switch) .form
}
}
html[dir="rtl"] .path-admin #adminsettings #id_s_meetletacbmarketplace_agent_dispatch,
html[dir="rtl"] .path-admin #adminsettings select[name="s_meetletacbmarketplace_agent_dispatch"] {
html[dir="rtl"] .path-admin #adminsettings #id_s_meetletacbfree_agent_dispatch,
html[dir="rtl"] .path-admin #adminsettings select[name="s_meetletacbfree_agent_dispatch"] {
direction: rtl;
text-align: right;
}
html[dir="rtl"] .path-admin #adminsettings #id_s_meetletacbmarketplace_agent_dispatch option,
html[dir="rtl"] .path-admin #adminsettings select[name="s_meetletacbmarketplace_agent_dispatch"] option {
html[dir="rtl"] .path-admin #adminsettings #id_s_meetletacbfree_agent_dispatch option,
html[dir="rtl"] .path-admin #adminsettings select[name="s_meetletacbfree_agent_dispatch"] option {
direction: rtl;
text-align: right;
}
@@ -2197,6 +2197,6 @@ html[dir="rtl"] .path-admin .meetlet-hourpresets {
/* Course page: keep branded monologo colours (Moove / filtericon fallback). */
.activityiconcontainer.communication.isbranded .activityicon,
.activityiconcontainer.communication .activityicon.nofilter,
.activityiconcontainer .activityicon[src*="mod/meetletacbmarketplace"] {
.activityiconcontainer .activityicon[src*="mod/meetletacbfree"] {
filter: none !important;
}
+2 -2
View File
@@ -1,9 +1,9 @@
<div class="participant-form meetlet-participant-form">
{{#selectionType}}
{{> mod_meetletacbmarketplace/participant_single_select}}
{{> mod_meetletacbfree/participant_single_select}}
{{/selectionType}}
{{#selectionParticipant}}
{{> mod_meetletacbmarketplace/participant_single_select}}
{{> mod_meetletacbfree/participant_single_select}}
{{/selectionParticipant}}
{{#action}}
<button type="button" class="btn btn-secondary"
+2 -2
View File
@@ -1,7 +1,7 @@
<tr id="participant_list_tr_{{selectiontypevalue}}-{{selectionvalue}}">
<td class="participant_list_c0"><b><i>{{participanttype}}</i></b></td>
<td class="participant_list_c1">{{participantvalue}}</td>
<td class="participant_list_c2"><i>{{#str}}participant_as, meetletacbmarketplace{{/str}}</i></td>
<td class="participant_list_c2"><i>{{#str}}participant_as, meetletacbfree{{/str}}</i></td>
<td class="participant_list_c3">
<select class="participant-select form-select" name="select-for-{{selectiontypevalue}}-{{selectionvalue}}">
{{#roles}}
@@ -11,7 +11,7 @@
</td>
<td class="participant_list_c4">
{{#canRemove}}
<a href="#" class="btn btn-secondary btn-sm remove-button">{{#str}}participant_remove, meetletacbmarketplace{{/str}}</a>
<a href="#" class="btn btn-secondary btn-sm remove-button">{{#str}}participant_remove, meetletacbfree{{/str}}</a>
{{/canRemove}}
</td>
</tr>
+3 -3
View File
@@ -11,7 +11,7 @@
<div class="meetlet-statuswrap" data-meetlet-status-wrap data-status="{{status}}">
{{#licenseusable}}
<span class="meetlet-statusring-wrap"
data-tip="{{#str}} statuscountdown_help, meetletacbmarketplace {{/str}}"
data-tip="{{#str}} statuscountdown_help, meetletacbfree {{/str}}"
tabindex="0">
<svg class="meetlet-statusring" viewBox="0 0 40 40" aria-hidden="true">
<circle class="meetlet-statusring__track" cx="20" cy="20" r="16"></circle>
@@ -23,8 +23,8 @@
<span class="meetlet-status meetlet-status--{{status}}" data-meetlet-status
{{^joinable}}{{#statusmessage}}data-tip="{{statusmessage}}" tabindex="0"{{/statusmessage}}{{/joinable}}>{{statuslabel}}</span>
</div>
{{#starttime}}<div class="meetlet-meta-line">{{#str}} starttime, meetletacbmarketplace {{/str}}: {{starttime}}</div>{{/starttime}}
{{#hasend}}<div class="meetlet-meta-line">{{#str}} endtime, meetletacbmarketplace {{/str}}: {{endtime}}</div>{{/hasend}}
{{#starttime}}<div class="meetlet-meta-line">{{#str}} starttime, meetletacbfree {{/str}}: {{starttime}}</div>{{/starttime}}
{{#hasend}}<div class="meetlet-meta-line">{{#str}} endtime, meetletacbfree {{/str}}: {{endtime}}</div>{{/hasend}}
</div>
{{#canjoin}}
<div class="meetlet-hero__actions">
+4 -4
View File
@@ -17,16 +17,16 @@
/**
* Plugin version metadata.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet <info@meetlet.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'mod_meetletacbmarketplace';
$plugin->version = 2026090148;
$plugin->component = 'mod_meetletacbfree';
$plugin->version = 2026090150;
$plugin->requires = 2024100700; // Moodle 4.5+.
$plugin->supported = [405, 502]; // 4.5 LTS through 5.2.
$plugin->maturity = MATURITY_STABLE;
$plugin->release = '1.0.7-marketplace';
$plugin->release = '1.0.9-marketplace';
+23 -23
View File
@@ -17,40 +17,40 @@
/**
* Activity view page.
*
* @package mod_meetletacbmarketplace
* @package mod_meetletacbfree
* @copyright 2026 MeetLet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../../config.php');
use mod_meetletacbmarketplace\local\config;
use mod_meetletacbmarketplace\local\featureaccess;
use mod_meetletacbmarketplace\local\instance;
use mod_meetletacbmarketplace\local\meetingstatus;
use mod_meetletacbmarketplace\output\view_page;
use mod_meetletacbmarketplace\registration\manager as registration_manager;
use mod_meetletacbfree\local\config;
use mod_meetletacbfree\local\featureaccess;
use mod_meetletacbfree\local\instance;
use mod_meetletacbfree\local\meetingstatus;
use mod_meetletacbfree\output\view_page;
use mod_meetletacbfree\registration\manager as registration_manager;
$id = required_param('id', PARAM_INT);
$groupid = optional_param('group', 0, PARAM_INT);
$cm = get_coursemodule_from_id('meetletacbmarketplace', $id, 0, false, MUST_EXIST);
$cm = get_coursemodule_from_id('meetletacbfree', $id, 0, false, MUST_EXIST);
$course = $DB->get_record('course', ['id' => $cm->course], '*', MUST_EXIST);
$meetlet = $DB->get_record('meetletacbmarketplace', ['id' => $cm->instance], '*', MUST_EXIST);
$meetlet = $DB->get_record('meetletacbfree', ['id' => $cm->instance], '*', MUST_EXIST);
require_login($course, true, $cm);
$context = context_module::instance($cm->id);
require_capability('mod/meetletacbmarketplace:view', $context);
\mod_meetletacbmarketplace\registration\manager::require_registered();
require_capability('mod/meetletacbfree:view', $context);
\mod_meetletacbfree\registration\manager::require_registered();
$PAGE->set_url('/mod/meetletacbmarketplace/view.php', ['id' => $cm->id]);
$PAGE->set_url('/mod/meetletacbfree/view.php', ['id' => $cm->id]);
$PAGE->set_title(format_string($meetlet->name));
$PAGE->set_heading(format_string($course->fullname));
$PAGE->set_context($context);
$PAGE->activityheader->disable();
$PAGE->requires->css(new moodle_url('/mod/meetletacbmarketplace/styles.css', ['v' => '2026082250']));
$PAGE->requires->js(new moodle_url('/mod/meetletacbmarketplace/javascript/meetlet_modal_scroll.js', ['v' => '2026082250']));
$PAGE->requires->js(new moodle_url('/mod/meetletacbmarketplace/javascript/view.js', ['v' => '2026082250']));
$PAGE->requires->css(new moodle_url('/mod/meetletacbfree/styles.css', ['v' => '2026082250']));
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/meetlet_modal_scroll.js', ['v' => '2026082250']));
$PAGE->requires->js(new moodle_url('/mod/meetletacbfree/javascript/view.js', ['v' => '2026082250']));
if ($cm->groupmode) {
$groupid = groups_get_activity_group($cm, true) ?: $groupid;
@@ -61,15 +61,15 @@ $inst = instance::get_from_cmid($cm->id, (int)$groupid);
$lifecycle = meetingstatus::resolve_local($inst, (int)$USER->id);
$featurejoin = featureaccess::allowed(featureaccess::JOIN, $context, $meetlet);
$event = \mod_meetletacbmarketplace\event\course_module_viewed::create([
$event = \mod_meetletacbfree\event\course_module_viewed::create([
'objectid' => $meetlet->id,
'context' => $context,
]);
$event->add_record_snapshot('course', $course);
$event->add_record_snapshot('meetletacbmarketplace', $meetlet);
$event->add_record_snapshot('meetletacbfree', $meetlet);
$event->trigger();
$renderer = $PAGE->get_renderer('mod_meetletacbmarketplace');
$renderer = $PAGE->get_renderer('mod_meetletacbfree');
$page = new view_page($inst, config::is_configured(), $lifecycle, true);
echo $OUTPUT->header();
@@ -86,11 +86,11 @@ echo html_writer::div('', '', [
'status' => (string)$lifecycle['status'],
'statusMessage' => (string)$lifecycle['message'],
'statusPollSeconds' => 15,
'strJoinWaiting' => get_string('joinblocked_waitinghost', 'meetletacbmarketplace'),
'strJoiningTitle' => get_string('joiningtitle', 'meetletacbmarketplace'),
'strJoiningText' => get_string('joining', 'meetletacbmarketplace'),
'strRecordingTitle' => get_string('preparingrecordingtitle', 'meetletacbmarketplace'),
'strRecordingText' => get_string('preparingrecording', 'meetletacbmarketplace'),
'strJoinWaiting' => get_string('joinblocked_waitinghost', 'meetletacbfree'),
'strJoiningTitle' => get_string('joiningtitle', 'meetletacbfree'),
'strJoiningText' => get_string('joining', 'meetletacbfree'),
'strRecordingTitle' => get_string('preparingrecordingtitle', 'meetletacbfree'),
'strRecordingText' => get_string('preparingrecording', 'meetletacbfree'),
'canrecordings' => featureaccess::allowed(featureaccess::RECORDINGS, $context, $meetlet),
], JSON_UNESCAPED_UNICODE),
'hidden' => 'hidden',