91334a46b5
Co-authored-by: Cursor <cursoragent@cursor.com>
968 lines
38 KiB
PHP
968 lines
38 KiB
PHP
<?php
|
||
// This file is part of Moodle - http://moodle.org/
|
||
//
|
||
// Moodle is free software: you can redistribute it and/or modify
|
||
// it under the terms of the GNU General Public License as published by
|
||
// the Free Software Foundation, either version 3 of the License, or
|
||
// (at your option) any later version.
|
||
//
|
||
// Moodle is distributed in the hope that it will be useful,
|
||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
// GNU General Public License for more details.
|
||
//
|
||
// You should have received a copy of the GNU General Public License
|
||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||
|
||
/**
|
||
* Admin settings for MeetLet Adobe Connect Bridge (tabbed).
|
||
*
|
||
* @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_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');
|
||
require_once(__DIR__ . '/classes/local/privacy_policy.php');
|
||
|
||
if ($ADMIN->fulltree) {
|
||
global $OUTPUT;
|
||
|
||
$settings = new settingspage_tabs(
|
||
$settings->name,
|
||
$settings->visiblename,
|
||
$settings->req_capability,
|
||
$settings->hidden
|
||
);
|
||
|
||
$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/meetletacbfree/ajax/conntest.php');
|
||
|
||
// Load styles.css explicitly on admin tabs (theme concatenate alone is not enough for switch CSS).
|
||
$styles = '
|
||
<link rel="stylesheet" href="' . s($stylesurl->out(false)) . '">
|
||
<style>
|
||
.path-admin #adminsettings .settingsform > h2 {
|
||
display: none;
|
||
}
|
||
.path-admin .meetlet-settings-hero {
|
||
display:flex; gap:1rem; align-items:center;
|
||
padding:1.15rem 1.25rem; margin:0 0 1rem;
|
||
border-radius:16px;
|
||
background:
|
||
radial-gradient(700px 180px at 100% 0%, rgba(82,204,163,.22), transparent 55%),
|
||
linear-gradient(135deg, #00261a 0%, #0a3d2e 60%, #145c45 100%);
|
||
color:#fff;
|
||
border:1px solid rgba(82,204,163,.25);
|
||
}
|
||
.path-admin .meetlet-settings-hero img {
|
||
width:56px; height:56px; object-fit:contain;
|
||
background:rgba(255,255,255,.95); border-radius:12px; padding:6px;
|
||
}
|
||
.path-admin .meetlet-settings-hero h3 {
|
||
margin:0 0 .2rem; font-size:1.2rem; font-weight:700; color:#fff;
|
||
display:flex; flex-wrap:wrap; align-items:center; gap:.45rem .55rem;
|
||
}
|
||
.path-admin .meetlet-settings-hero .meetlet-settings-version {
|
||
display:inline-block;
|
||
flex:0 0 auto;
|
||
align-self:center;
|
||
margin-inline-start:auto;
|
||
padding:.12rem .55rem;
|
||
font-size:.72rem; font-weight:650; line-height:1.35;
|
||
letter-spacing:.02em;
|
||
border-radius:999px;
|
||
background:rgba(82,204,163,.18);
|
||
border:1px solid rgba(82,204,163,.35);
|
||
color:#b8f5df;
|
||
white-space:nowrap;
|
||
direction:ltr;
|
||
unicode-bidi:isolate;
|
||
}
|
||
.path-admin .meetlet-settings-hero p {
|
||
margin:0; opacity:.85; color:#e6faf3;
|
||
white-space:nowrap;
|
||
max-width:none;
|
||
}
|
||
.path-admin .meetlet-settings-copy {
|
||
min-width:0; flex:1 1 auto;
|
||
}
|
||
@media (max-width: 900px) {
|
||
.path-admin .meetlet-settings-hero p {
|
||
white-space:normal;
|
||
}
|
||
}
|
||
.path-admin #adminsettings .nav-tabs {
|
||
border-bottom:2px solid #cfe8de;
|
||
gap:.2rem;
|
||
}
|
||
.path-admin #adminsettings .nav-tabs .nav-link {
|
||
border:0 !important;
|
||
border-radius:6px !important;
|
||
padding:.45rem .9rem;
|
||
color:#00261a;
|
||
font-weight:650;
|
||
box-shadow:none !important;
|
||
outline:none !important;
|
||
}
|
||
.path-admin #adminsettings .nav-tabs .nav-link:hover {
|
||
background:#e6faf3; color:#00261a;
|
||
}
|
||
.path-admin #adminsettings .nav-tabs .nav-link.active {
|
||
background:#52cca3; color:#00261a;
|
||
}
|
||
.path-admin #adminsettings .nav-tabs .nav-link:focus,
|
||
.path-admin #adminsettings .nav-tabs .nav-link:focus-visible,
|
||
.path-admin #adminsettings .nav-tabs .nav-link:active {
|
||
outline:none !important;
|
||
box-shadow:none !important;
|
||
border:0 !important;
|
||
}
|
||
.path-admin .meetlet-feature-group {
|
||
margin:1rem 0 .35rem;
|
||
padding:1rem 1.1rem .35rem;
|
||
border:1px solid #cfe8de;
|
||
border-radius:12px;
|
||
background:linear-gradient(180deg, #f3fbf8 0%, #ffffff 55%);
|
||
}
|
||
.path-admin .meetlet-feature-group h4 {
|
||
margin:0 0 .25rem; color:#00261a; font-size:1.02rem; font-weight:700;
|
||
}
|
||
.path-admin .meetlet-feature-group p {
|
||
margin:0 0 .5rem; color:#4a6b5f; font-size:.9rem;
|
||
}
|
||
.path-admin .meetlet-settings-card {
|
||
background:#fff; border:1px solid #cfe8de; border-radius:14px;
|
||
padding:1rem 1.15rem; margin:.35rem 0 1rem;
|
||
}
|
||
.meetlet-license-badge {
|
||
font-weight: 700;
|
||
border-radius: 999px;
|
||
padding: .35rem .65rem;
|
||
}
|
||
.meetlet-license-badge--active {
|
||
background: var(--ml-green, #52cca3);
|
||
color: var(--ml-green-deep, #00261a);
|
||
}
|
||
.meetlet-license-badge--inactive {
|
||
background: #fff4d6;
|
||
color: #5a4700;
|
||
}
|
||
.path-admin #meetlet-license-modal.meetlet-modal,
|
||
.path-admin #meetlet-registration-modal.meetlet-modal,
|
||
.path-admin #meetlet-cronmon-modal.meetlet-modal,
|
||
.path-admin #meetlet-access-reset-modal.meetlet-modal {
|
||
z-index: 20000 !important;
|
||
}
|
||
.path-admin .meetlet-access-reset-toolbar {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
margin: 0 0 .65rem;
|
||
}
|
||
html[dir="rtl"] .path-admin .meetlet-access-reset-toolbar {
|
||
justify-content: flex-start;
|
||
}
|
||
/* Cron videos ops cell: no extra cell/wrapper border (icon buttons keep theirs). */
|
||
.path-admin .meetlet-cronmon__table td.meetlet-cronmon__dl {
|
||
border-left: 0 !important;
|
||
border-right: 0 !important;
|
||
border-top: 0 !important;
|
||
background: transparent !important;
|
||
box-shadow: none !important;
|
||
}
|
||
.path-admin .meetlet-cronmon__dl .meetlet-iconactions {
|
||
border: 0 !important;
|
||
background: transparent !important;
|
||
box-shadow: none !important;
|
||
padding: 0 !important;
|
||
margin: 0 !important;
|
||
}
|
||
.path-admin .meetlet-modal--confirm .meetlet-modal__dialog {
|
||
width: min(480px, 100%);
|
||
max-height: min(86vh, 640px);
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.path-admin .meetlet-modal--confirm .meetlet-modal__head {
|
||
padding: 1.2rem 1.15rem 1rem;
|
||
border-radius: 18px 18px 0 0;
|
||
}
|
||
.path-admin .meetlet-modal__lead {
|
||
margin: 0 0 .85rem;
|
||
font-size: 1rem;
|
||
font-weight: 650;
|
||
line-height: 1.65;
|
||
color: #00261a;
|
||
}
|
||
.path-admin .meetlet-modal__callout {
|
||
margin: 0 0 .9rem;
|
||
padding: .85rem 1rem .7rem;
|
||
border-radius: 12px;
|
||
border: 1px solid #e6c56a;
|
||
background: #fff8e6;
|
||
color: #5a4700;
|
||
}
|
||
.path-admin .meetlet-modal__callout-title {
|
||
margin: 0 0 .4rem;
|
||
font-weight: 700;
|
||
}
|
||
.path-admin .meetlet-modal__limits {
|
||
margin: 0 0 .55rem;
|
||
padding-inline-start: 1.2rem;
|
||
}
|
||
.path-admin .meetlet-modal__keep {
|
||
margin: 0;
|
||
color: #334942;
|
||
line-height: 1.65;
|
||
}
|
||
.path-admin .meetlet-modal__foot {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
gap: .6rem;
|
||
flex-wrap: wrap;
|
||
padding: .9rem 1.15rem 1.05rem;
|
||
border-top: 1px solid #cfe8de;
|
||
background: linear-gradient(180deg, #f7fcfa 0%, #ffffff 70%);
|
||
}
|
||
.path-admin .meetlet-modal__foot .btn {
|
||
border-radius: 10px;
|
||
font-weight: 700;
|
||
padding: .5rem 1.15rem;
|
||
}
|
||
.path-admin .meetlet-modal__foot .btn-success {
|
||
background: #52cca3 !important;
|
||
border-color: #3db892 !important;
|
||
color: #00261a !important;
|
||
}
|
||
.path-admin .meetlet-modal__foot .btn-outline-danger {
|
||
color: #a33b3b !important;
|
||
border-color: #d9a0a0 !important;
|
||
background: #fff !important;
|
||
}
|
||
.path-admin .meetlet-modal__foot .btn-outline-danger:hover,
|
||
.path-admin .meetlet-modal__foot .btn-outline-danger:focus {
|
||
color: #fff !important;
|
||
background: #c0392b !important;
|
||
border-color: #c0392b !important;
|
||
}
|
||
.path-admin .meetlet-about {
|
||
display:grid; gap:1.1rem;
|
||
}
|
||
.path-admin .meetlet-about__brand {
|
||
display:flex; justify-content:center; align-items:center;
|
||
padding:1.35rem 1.2rem;
|
||
border-radius:14px;
|
||
background:#f0f2f4;
|
||
border:1px solid #e2e6ea;
|
||
}
|
||
.path-admin .meetlet-about__brand img {
|
||
max-width:240px; width:100%; height:auto; display:block; margin:0 auto;
|
||
}
|
||
.path-admin .meetlet-about h4 { margin:0 0 .55rem; color:#00261a; }
|
||
.path-admin .meetlet-about p {
|
||
margin:0 0 .85rem; color:#334942; line-height:1.75; text-align:justify;
|
||
}
|
||
.path-admin .meetlet-guide { display:grid; gap:1rem; }
|
||
.path-admin .meetlet-guide__heading { margin:0; color:#00261a; font-size:1.15rem; }
|
||
.path-admin .meetlet-guide__intro {
|
||
margin:0; color:#334942; line-height:1.7;
|
||
}
|
||
.path-admin .meetlet-guide__callout {
|
||
padding:.85rem 1rem; border-radius:10px; line-height:1.65;
|
||
border:1px solid #e6c56a; background:#fff8e6; color:#5a4700;
|
||
}
|
||
.path-admin .meetlet-guide__section {
|
||
padding:1rem 1.05rem; border-radius:12px;
|
||
border:1px solid #cfe8de; background:#f7fcfa;
|
||
}
|
||
.path-admin .meetlet-guide__section--current { background:#fff; }
|
||
.path-admin .meetlet-guide__section h4 {
|
||
margin:0 0 .55rem; color:#00261a; font-size:1.02rem; font-weight:700;
|
||
}
|
||
.path-admin .meetlet-guide__section h5 {
|
||
margin:.85rem 0 .35rem; color:#0a3d2e; font-size:.95rem; font-weight:700;
|
||
}
|
||
.path-admin .meetlet-guide__body,
|
||
.path-admin .meetlet-guide__body p,
|
||
.path-admin .meetlet-guide__body li {
|
||
color:#334942; line-height:1.7;
|
||
}
|
||
.path-admin .meetlet-guide__body p { margin:0 0 .55rem; }
|
||
.path-admin .meetlet-guide__body ol,
|
||
.path-admin .meetlet-guide__body ul { margin:0 0 .35rem; padding-inline-start:1.25rem; }
|
||
.path-admin .meetlet-guide__body li { margin:0 0 .35rem; }
|
||
.path-admin .meetlet-guide__body code,
|
||
.path-admin .meetlet-guide__table code {
|
||
font-size:.88em; padding:.05rem .3rem; border-radius:4px;
|
||
background:#e6faf3; color:#00261a;
|
||
}
|
||
.path-admin .meetlet-guide__table {
|
||
width:100%; margin:.35rem 0 0; border-collapse:collapse;
|
||
}
|
||
.path-admin .meetlet-guide__table th,
|
||
.path-admin .meetlet-guide__table td {
|
||
padding:.45rem .55rem; border:1px solid #cfe8de; vertical-align:top;
|
||
text-align:start;
|
||
}
|
||
.path-admin .meetlet-guide__table thead th,
|
||
.path-admin .meetlet-guide__table tbody th {
|
||
background:#e6faf3; color:#00261a; font-weight:650;
|
||
}
|
||
.path-admin .meetlet-guide__code {
|
||
margin:.35rem 0 0; padding:.75rem .9rem; overflow-x:auto;
|
||
border-radius:10px; border:1px solid #cfe8de;
|
||
background:#0a3d2e; color:#e6faf3;
|
||
font-size:.82rem; line-height:1.45; direction:ltr; text-align:left;
|
||
white-space:pre;
|
||
}
|
||
.path-admin .meetlet-guide__code-cell code {
|
||
font-weight:800; letter-spacing:.02em; direction:ltr; unicode-bidi:isolate;
|
||
}
|
||
.path-admin .meetlet-guide__table td ol,
|
||
.path-admin .meetlet-guide__table td ul {
|
||
margin:.15rem 0 0; padding-inline-start:1.15rem;
|
||
}
|
||
.path-admin .meetlet-guide__table td li { margin:0 0 .25rem; }
|
||
.path-admin .meetlet-hourpicker { max-width: 42rem; }
|
||
.path-admin .meetlet-hourpicker.is-dimmed,
|
||
.path-admin #adminsettings .form-item.is-dimmed {
|
||
opacity: .45;
|
||
pointer-events: none;
|
||
}
|
||
.path-admin .meetlet-hourpicker__tz {
|
||
margin: 0 0 .55rem; color:#4a6b5f; font-size:.88rem;
|
||
}
|
||
.path-admin .meetlet-hourpresets {
|
||
display:flex; flex-wrap:wrap; gap:.4rem; margin:0 0 .65rem;
|
||
}
|
||
.path-admin .meetlet-hourpreset {
|
||
border:1px solid #9fdcc4; background:#fff; color:#00261a;
|
||
border-radius:999px; padding:.28rem .7rem; font-size:.8rem; font-weight:650;
|
||
cursor:pointer;
|
||
}
|
||
.path-admin .meetlet-hourpreset:hover { background:#e6faf3; }
|
||
.path-admin .meetlet-hourpreset--ghost { border-color:#cfe8de; color:#4a6b5f; }
|
||
.path-admin .meetlet-hourgrid {
|
||
display:grid; grid-template-columns:repeat(8, minmax(0,1fr)); gap:.35rem;
|
||
}
|
||
.path-admin .meetlet-hourchip {
|
||
border:1px solid #cfe8de; background:#f7fcfa; color:#00261a;
|
||
border-radius:10px; padding:.45rem 0; font-size:.82rem; font-weight:750;
|
||
cursor:pointer;
|
||
}
|
||
.path-admin .meetlet-hourchip.is-on {
|
||
background:#52cca3; border-color:#0d9f6e; color:#00261a;
|
||
}
|
||
.path-admin .meetlet-hourchip.is-now { box-shadow:0 0 0 2px rgba(13,159,110,.35); }
|
||
@media (max-width: 720px) {
|
||
.path-admin .meetlet-hourgrid { grid-template-columns:repeat(6, minmax(0,1fr)); }
|
||
}
|
||
.path-admin .meetlet-about__cta-wrap {
|
||
display:flex; justify-content:center; margin-top:.35rem; padding-top:.35rem;
|
||
}
|
||
.path-admin .meetlet-about__cta {
|
||
display:inline-flex; align-items:center; justify-content:center;
|
||
min-width:220px; padding:.7rem 1.35rem; border-radius:10px;
|
||
background:#52cca3; color:#00261a !important;
|
||
text-decoration:none !important; font-weight:700;
|
||
border:1px solid #3db892;
|
||
box-shadow:0 6px 16px rgba(0,38,26,.08);
|
||
}
|
||
.path-admin .meetlet-about__cta:hover {
|
||
background:#6fd9b5; color:#00261a !important;
|
||
}
|
||
.path-admin .meetlet-settings-btn {
|
||
display:inline-flex; align-items:center; justify-content:center; gap:.45rem;
|
||
padding:.6rem 1.15rem; border-radius:10px; border:0; cursor:pointer;
|
||
background:#52cca3; color:#00261a !important;
|
||
text-decoration:none !important; font-weight:700;
|
||
}
|
||
.path-admin .meetlet-settings-btn:hover { background:#6fd9b5; color:#00261a !important; }
|
||
.path-admin .meetlet-settings-btn:disabled { opacity:.65; cursor:wait; }
|
||
.path-admin .meetlet-settings-btn svg {
|
||
width:1.1rem; height:1.1rem; flex:0 0 auto; display:block;
|
||
}
|
||
.path-admin .meetlet-license-actions {
|
||
display:flex; flex-wrap:wrap; gap:.55rem; align-items:center;
|
||
}
|
||
.path-admin .meetlet-license-actions .btn {
|
||
display:inline-flex; align-items:center; justify-content:center; gap:.45rem;
|
||
}
|
||
.path-admin .meetlet-license-actions .btn svg {
|
||
width:1.05rem; height:1.05rem; flex:0 0 auto; display:block;
|
||
}
|
||
.path-admin .meetlet-license-btn--free {
|
||
background: linear-gradient(180deg, #e6faf3 0%, #d4f5ea 100%) !important;
|
||
border: 2px solid #52cca3 !important;
|
||
color: #00261a !important;
|
||
border-radius: 10px !important;
|
||
font-weight: 700 !important;
|
||
padding: .6rem 1.15rem !important;
|
||
box-shadow: 0 4px 12px rgba(82, 204, 163, 0.18) !important;
|
||
}
|
||
.path-admin .meetlet-license-btn--free:hover,
|
||
.path-admin .meetlet-license-btn--free:focus {
|
||
background: linear-gradient(180deg, #6fd9b5 0%, #52cca3 100%) !important;
|
||
border-color: #3db892 !important;
|
||
color: #00261a !important;
|
||
box-shadow: 0 6px 16px rgba(82, 204, 163, 0.28) !important;
|
||
}
|
||
.path-admin .meetlet-conntest { max-width:none; margin:0; }
|
||
.path-admin .meetlet-conntest__actions {
|
||
display:flex; flex-wrap:wrap; gap:.75rem; align-items:center;
|
||
margin:.85rem 0 1rem;
|
||
}
|
||
.path-admin .meetlet-conntest__status { color:#4a6b5f; font-size:.9rem; }
|
||
.path-admin .meetlet-conntest__progress {
|
||
margin:0 0 1rem; padding:.85rem 1rem;
|
||
border:1px solid #cfe8de; border-radius:12px; background:#f7fcfa;
|
||
}
|
||
.path-admin .meetlet-conntest__progress-label {
|
||
display:flex; justify-content:space-between; gap:.75rem;
|
||
margin:0 0 .45rem; color:#00261a; font-weight:650; font-size:.92rem;
|
||
}
|
||
.path-admin .meetlet-conntest__progress-track {
|
||
height:10px; border-radius:999px; background:#d9eee5; overflow:hidden;
|
||
}
|
||
.path-admin .meetlet-conntest__progress-fill {
|
||
height:100%; width:0; border-radius:999px;
|
||
background:linear-gradient(90deg, #2f9f7a, #52cca3);
|
||
transition:width .28s ease;
|
||
}
|
||
.path-admin .meetlet-conntest__num {
|
||
min-width:1.7rem; height:1.7rem; border-radius:8px;
|
||
display:inline-flex; align-items:center; justify-content:center;
|
||
background:#e6faf3; color:#00261a; font-weight:750; font-size:.85rem;
|
||
}
|
||
.path-admin .meetlet-conntest__card--pending { opacity:.78; background:#fbfefe; }
|
||
.path-admin .meetlet-conntest__card--running {
|
||
border-color:#e6b422;
|
||
box-shadow:0 0 0 2px rgba(230,180,34,.22);
|
||
background:#fff8e6;
|
||
}
|
||
.path-admin .meetlet-conntest__card--running .meetlet-conntest__num {
|
||
background:#ffe08a; color:#5c4700;
|
||
}
|
||
.path-admin .meetlet-conntest__card--ok {
|
||
border-color:#9fdcc4; background:#f3fbf8;
|
||
}
|
||
.path-admin .meetlet-conntest__card--fail {
|
||
border-color:#ead3d0; background:#fff8f7;
|
||
}
|
||
.path-admin .meetlet-conntest__card--skipped { opacity:.55; }
|
||
.path-admin .meetlet-dot--pending { background:#9bb7ac; box-shadow:0 0 0 4px rgba(155,183,172,.18); }
|
||
.path-admin .meetlet-dot--running {
|
||
background:#e6b422; box-shadow:0 0 0 4px rgba(230,180,34,.28);
|
||
animation:meetletPulse 1s ease-in-out infinite;
|
||
}
|
||
.path-admin .meetlet-dot--skipped { background:#b7c4be; box-shadow:none; }
|
||
.path-admin .meetlet-pill--pending { background:#e8efec; color:#456257; }
|
||
.path-admin .meetlet-pill--running { background:#ffe08a; color:#5c4700; }
|
||
.path-admin .meetlet-pill--skipped { background:#eef1f0; color:#667a72; }
|
||
@keyframes meetletPulse {
|
||
0%, 100% { transform:scale(1); opacity:1; }
|
||
50% { transform:scale(1.15); opacity:.75; }
|
||
}
|
||
.path-admin #adminsettings form.settingsform {
|
||
padding-bottom:1rem;
|
||
}
|
||
/* Single save row: spacing only — no stacked border/gradient bands. */
|
||
.path-admin #adminsettings .settingsform > .row:has(.btn-primary),
|
||
.path-admin #adminsettings .form-buttons,
|
||
.path-admin #adminsettings .btns-group {
|
||
margin-top:1.25rem !important;
|
||
padding:0;
|
||
border:0;
|
||
background:transparent;
|
||
border-radius:0;
|
||
}
|
||
.path-admin #adminsettings .meetlet-savebar {
|
||
margin-top: 1.25rem !important;
|
||
margin-right: 0 !important;
|
||
margin-left: 0 !important;
|
||
margin-inline: 0 !important;
|
||
flex: 0 0 100% !important;
|
||
max-width: 100% !important;
|
||
width: 100% !important;
|
||
padding: .35rem 0 !important;
|
||
border: 0 !important;
|
||
background: transparent !important;
|
||
border-radius: 0 !important;
|
||
}
|
||
@media (min-width: 576px) {
|
||
.path-admin #adminsettings .meetlet-savebar.offset-sm-3,
|
||
.path-admin #adminsettings .meetlet-savebar {
|
||
margin-right: 0 !important;
|
||
margin-left: 0 !important;
|
||
}
|
||
}
|
||
.path-admin #adminsettings .btn-primary,
|
||
.path-admin #adminsettings input[type="submit"].btn-primary,
|
||
.path-admin #adminsettings button[type="submit"].btn-primary,
|
||
.path-admin #adminsettings .meetlet-btn-with-icon.btn-primary {
|
||
background:#52cca3 !important;
|
||
border-color:#3db892 !important;
|
||
color:#00261a !important;
|
||
font-weight:700 !important;
|
||
border-radius:10px !important;
|
||
padding:.55rem 1.35rem !important;
|
||
box-shadow:none !important;
|
||
}
|
||
.path-admin #adminsettings .btn-primary:hover,
|
||
.path-admin #adminsettings input[type="submit"].btn-primary:hover,
|
||
.path-admin #adminsettings button[type="submit"].btn-primary:hover {
|
||
background:#6fd9b5 !important;
|
||
border-color:#52cca3 !important;
|
||
color:#00261a !important;
|
||
}
|
||
.path-admin .meetlet-btn-with-icon {
|
||
display:inline-flex !important;
|
||
align-items:center;
|
||
justify-content:center;
|
||
gap:.45rem;
|
||
}
|
||
.path-admin .meetlet-btn-with-icon svg {
|
||
width:1.1rem;
|
||
height:1.1rem;
|
||
flex:0 0 auto;
|
||
display:block;
|
||
}
|
||
.path-admin .meetlet-btn-with-icon__label {
|
||
line-height:1.2;
|
||
}
|
||
|
||
.path-admin .meetlet-server-group {
|
||
margin:1.1rem 0 .4rem; padding:1rem 1.1rem .2rem;
|
||
border:1px solid #cfe8de; border-radius:12px;
|
||
background:linear-gradient(180deg, #f3fbf8 0%, #ffffff 60%);
|
||
}
|
||
.path-admin .meetlet-server-group h4 {
|
||
margin:0 0 .25rem; color:#00261a; font-size:1.02rem; font-weight:700;
|
||
}
|
||
.path-admin .meetlet-server-group p {
|
||
margin:0 0 .55rem; color:#4a6b5f; font-size:.9rem; line-height:1.55;
|
||
}
|
||
|
||
/* RTL alignment for Persian/Arabic admin settings */
|
||
html[dir="rtl"] .path-admin #adminsettings,
|
||
html[dir="rtl"] .path-admin #adminsettings .settingsform,
|
||
html[dir="rtl"] .path-admin #adminsettings .tab-content,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-item {
|
||
direction: rtl;
|
||
}
|
||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label.label,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label > label,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label .form-shortname,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-description,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-defaultinfo,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting .form-check,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting .checkbox,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting label,
|
||
html[dir="rtl"] .path-admin #adminsettings h3.main,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label.text-sm-end,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label.text-end {
|
||
text-align: right !important;
|
||
direction: rtl;
|
||
}
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-feature-group,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-feature-group h4,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-feature-group p,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-settings-card,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-about,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-about p,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-about h4,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-privacy,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-privacy p,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-privacy h3,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-privacy h4,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest__intro,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest__title,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest__status,
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-conntest__progress-label,
|
||
html[dir="rtl"] .path-admin .meetlet-settings-hero,
|
||
html[dir="rtl"] .path-admin .meetlet-settings-hero h3,
|
||
html[dir="rtl"] .path-admin .meetlet-settings-hero .meetlet-settings-version,
|
||
html[dir="rtl"] .path-admin .meetlet-settings-hero p,
|
||
html[dir="rtl"] .path-admin .meetlet-settings-copy {
|
||
direction: rtl;
|
||
text-align: right;
|
||
}
|
||
html[dir="rtl"] .path-admin .meetlet-settings-hero {
|
||
flex-direction: row;
|
||
}
|
||
html[dir="rtl"] .path-admin #adminsettings .nav-tabs {
|
||
direction: rtl;
|
||
}
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting input[type="text"],
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting input[type="password"],
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting input[type="url"],
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting input[type="number"],
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting select,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting textarea {
|
||
direction: ltr;
|
||
text-align: left;
|
||
unicode-bidi: isolate;
|
||
}
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting .form-check,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting .checkbox,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting .form-checkbox {
|
||
display: flex;
|
||
flex-direction: row-reverse;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
gap: .5rem;
|
||
text-align: right;
|
||
}
|
||
html[dir="rtl"] .path-admin #adminsettings .form-item .form-label .form-shortname {
|
||
direction: ltr;
|
||
unicode-bidi: isolate;
|
||
text-align: right !important;
|
||
display: block;
|
||
}
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting .form-checkbox {
|
||
direction: rtl;
|
||
text-align: right;
|
||
}
|
||
html[dir="rtl"] .path-admin #adminsettings .form-setting .defaultsnext {
|
||
text-align: right;
|
||
}
|
||
html[dir="rtl"] .path-admin #adminsettings .meetlet-savebar,
|
||
html[dir="rtl"] .path-admin #adminsettings .form-buttons {
|
||
text-align: right;
|
||
}
|
||
</style>
|
||
<script src="' . s($modalscrolljsurl->out(false)) . '" defer></script>
|
||
<script src="' . s($registrationjsurl->out(false)) . '" defer></script>
|
||
<script src="' . s($jsurl->out(false)) . '" defer></script>
|
||
<script src="' . s($togglejsurl->out(false)) . '" defer></script>
|
||
<script src="' . s($matrixjsurl->out(false)) . '" defer></script>
|
||
<script src="' . s($accessresetjsurl->out(false)) . '" defer></script>';
|
||
|
||
$plugin = new stdClass();
|
||
include(__DIR__ . '/version.php');
|
||
$release = $plugin->release ?? '';
|
||
if ($release !== '' && strpos(current_language(), 'fa') === 0) {
|
||
$release = strtr($release, [
|
||
'0' => '۰', '1' => '۱', '2' => '۲', '3' => '۳', '4' => '۴',
|
||
'5' => '۵', '6' => '۶', '7' => '۷', '8' => '۸', '9' => '۹',
|
||
]);
|
||
}
|
||
$versionbadge = $release !== ''
|
||
? 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', 'meetletacbfree')) .
|
||
html_writer::tag('p', get_string('settingsintro', 'meetletacbfree')),
|
||
'meetlet-settings-copy'
|
||
) .
|
||
$versionbadge,
|
||
'meetlet-settings-hero'
|
||
);
|
||
$settings->set_hero($hero);
|
||
|
||
// Tab: Online activation (required before other features work).
|
||
$page = new admin_settingpage('meetletacbfree_registration', get_string('tab_registration', 'meetletacbfree'));
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/registrationheading',
|
||
get_string('registration_heading', 'meetletacbfree'),
|
||
get_string('registration_heading_desc', 'meetletacbfree')
|
||
));
|
||
$page->add(new admin_setting_configtext(
|
||
'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_meetletacbfree\admin\setting_registration());
|
||
$settings->add($page);
|
||
|
||
// Tab: Privacy (always visible — read policy before activating).
|
||
$page = new admin_settingpage('meetletacbfree_privacy', get_string('tab_privacy', 'meetletacbfree'));
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/privacycard',
|
||
'',
|
||
privacy_policy::render()
|
||
));
|
||
$settings->add($page);
|
||
|
||
$registered = registration_manager::is_registered();
|
||
|
||
if ($registered) {
|
||
|
||
// Tab: Server setup guide.
|
||
$page = new admin_settingpage('meetletacbfree_serverguide', get_string('tab_serverguide', 'meetletacbfree'));
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/serverguidecard',
|
||
'',
|
||
server_guide::render()
|
||
));
|
||
$settings->add($page);
|
||
|
||
// Tab 2: Server settings (API / admin / offline listener).
|
||
$page = new admin_settingpage('meetletacbfree_connection', get_string('settings_connection', 'meetletacbfree'));
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/connectionheading',
|
||
get_string('settings_connection', 'meetletacbfree'),
|
||
get_string('settings_connection_desc', 'meetletacbfree')
|
||
));
|
||
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/server_api_group',
|
||
'',
|
||
html_writer::div(
|
||
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(
|
||
'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(
|
||
'meetletacbfree/meethost', get_string('meethost', 'meetletacbfree'), get_string('meethost_desc', 'meetletacbfree'),
|
||
'connect.example.edu', PARAM_HOST
|
||
));
|
||
$page->add(new admin_setting_configtext(
|
||
'meetletacbfree/port', get_string('port', 'meetletacbfree'), get_string('port_desc', 'meetletacbfree'),
|
||
'443', PARAM_INT
|
||
));
|
||
$page->add(new admin_setting_configcheckbox(
|
||
'meetletacbfree/https', get_string('https', 'meetletacbfree'), get_string('https_desc', 'meetletacbfree'), 1
|
||
));
|
||
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/server_admin_group',
|
||
'',
|
||
html_writer::div(
|
||
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(
|
||
'meetletacbfree/admin_login', get_string('admin_login', 'meetletacbfree'), get_string('admin_login_desc', 'meetletacbfree'),
|
||
'', PARAM_RAW_TRIMMED
|
||
));
|
||
$page->add(new admin_setting_configpasswordunmask(
|
||
'meetletacbfree/admin_password', get_string('admin_password', 'meetletacbfree'), get_string('admin_password_desc', 'meetletacbfree'), ''
|
||
));
|
||
$page->add(new admin_setting_configtext(
|
||
'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(
|
||
'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('meetletacbfree_test', get_string('tab_connectiontest', 'meetletacbfree'));
|
||
$steplabels = [
|
||
'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', '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', 'meetletacbfree'), 'meetlet-btn-with-icon__label'),
|
||
[
|
||
'type' => 'button',
|
||
'class' => 'meetlet-settings-btn meetlet-btn-with-icon',
|
||
'data-meetlet-run-test' => '1',
|
||
]
|
||
) .
|
||
html_writer::span('', 'meetlet-conntest__status', ['data-meetlet-test-status' => '1']),
|
||
'meetlet-conntest__actions'
|
||
) .
|
||
html_writer::div(
|
||
html_writer::div(
|
||
html_writer::span('', 'meetlet-conntest__progress-text', ['data-meetlet-progress-label' => '1']),
|
||
'meetlet-conntest__progress-label'
|
||
) .
|
||
html_writer::div(
|
||
html_writer::div('', 'meetlet-conntest__progress-fill', ['data-meetlet-progress-fill' => '1']),
|
||
'meetlet-conntest__progress-track'
|
||
),
|
||
'meetlet-conntest__progress',
|
||
['data-meetlet-progress' => '1', 'hidden' => 'hidden']
|
||
) .
|
||
html_writer::div('', 'meetlet-conntest__grid', ['data-meetlet-test-grid' => '1']),
|
||
'meetlet-conntest',
|
||
[
|
||
'id' => 'meetlet-acb-conntest',
|
||
'data-endpoint' => $ajaxurl->out(false),
|
||
'data-sesskey' => sesskey(),
|
||
'data-steps' => implode(',', conntest_runner::STEPS),
|
||
'data-step-labels' => json_encode($steplabels, JSON_UNESCAPED_UNICODE),
|
||
'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', '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('meetletacbfree/testui', '', $testui));
|
||
$settings->add($page);
|
||
|
||
// Tab 4: Meeting settings (defaults + feature visibility).
|
||
$page = new admin_settingpage('meetletacbfree_meetings', get_string('tab_meetingsettings', 'meetletacbfree'));
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/roomdefaultsheading',
|
||
get_string('roomdefaults', 'meetletacbfree'),
|
||
get_string('roomdefaults_desc', 'meetletacbfree')
|
||
));
|
||
$page->add(new admin_setting_configselect(
|
||
'meetletacbfree/default_meetinglang',
|
||
get_string('default_meetinglang', 'meetletacbfree'),
|
||
get_string('default_meetinglang_desc', 'meetletacbfree'),
|
||
'',
|
||
config::meeting_lang_options()
|
||
));
|
||
$page->add(new admin_setting_configcheckbox(
|
||
'meetletacbfree/default_waitforhost',
|
||
get_string('default_waitforhost', 'meetletacbfree'),
|
||
get_string('default_waitforhost_desc', 'meetletacbfree'),
|
||
0
|
||
));
|
||
$page->add(new admin_setting_heading(
|
||
'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, 'meetletacbfree')) .
|
||
html_writer::tag('p', get_string('featuregroup_' . $feature . '_desc', 'meetletacbfree')),
|
||
'meetlet-feature-group'
|
||
);
|
||
$page->add(new admin_setting_heading(
|
||
'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(
|
||
'meetletacbfree/enable_' . $feature,
|
||
get_string('enable_' . $feature, 'meetletacbfree'),
|
||
get_string('enable_' . $feature . '_desc', 'meetletacbfree'),
|
||
$enabledefault
|
||
));
|
||
$page->add(new admin_setting_configcheckbox(
|
||
'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('meetletacbfree_access', get_string('tab_accesssettings', 'meetletacbfree'));
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/rolemappingheading',
|
||
get_string('siterolemapping', 'meetletacbfree'),
|
||
get_string('siterolemapping_desc', 'meetletacbfree')
|
||
));
|
||
$page->add(new \mod_meetletacbfree\admin\setting_rolemapping());
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/accessheading',
|
||
get_string('featureaccess', 'meetletacbfree'),
|
||
get_string('featureaccess_desc', 'meetletacbfree')
|
||
));
|
||
$page->add(new admin_setting_configcheckbox(
|
||
'meetletacbfree/activity_featureaccess',
|
||
get_string('activity_featureaccess', 'meetletacbfree'),
|
||
get_string('activity_featureaccess_desc', 'meetletacbfree'),
|
||
1
|
||
));
|
||
$page->add(new \mod_meetletacbfree\admin\setting_featureaccess());
|
||
$page->add(new admin_setting_heading(
|
||
'meetletacbfree/accessresetassets',
|
||
'',
|
||
\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('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' => 'meetletacbfree',
|
||
'utm_content' => 'about_developer_tab',
|
||
]);
|
||
$about = html_writer::div(
|
||
html_writer::div(
|
||
html_writer::img($meetletlogo, 'MeetLet', ['alt' => 'MeetLet']),
|
||
'meetlet-about__brand'
|
||
) .
|
||
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', 'meetletacbfree'), [
|
||
'class' => 'meetlet-about__cta',
|
||
'target' => '_blank',
|
||
'rel' => 'noopener',
|
||
]),
|
||
'meetlet-about__cta-wrap'
|
||
),
|
||
'meetlet-about meetlet-settings-card'
|
||
);
|
||
$page->add(new admin_setting_heading('meetletacbfree/aboutcard', '', $about));
|
||
$settings->add($page);
|
||
|
||
}
|