diff --git a/public/admin/tool/mobile/classes/api.php b/public/admin/tool/mobile/classes/api.php index 5cd949c34b9..daac6a9f04c 100644 --- a/public/admin/tool/mobile/classes/api.php +++ b/public/admin/tool/mobile/classes/api.php @@ -816,6 +816,8 @@ class api { public static function get_subscription_information($forcecache = false, $ignorecache = false, $timeout = 10): ?array { global $CFG; + require_once($CFG->libdir . '/filelib.php'); + $timeout = min(30, $timeout); // Manage cache of the subscription information to avoid requesting it too often to the Moodle Apps Portal. $cache = \cache::make('tool_mobile', 'subscriptioninfo'); @@ -869,7 +871,7 @@ class api { ]; // Ask the Moodle Apps Portal for the subscription information. - $curl = new curl(); + $curl = new \curl(); $curl->setopt([ 'CURLOPT_TIMEOUT' => $timeout, 'CURLOPT_CONNECTTIMEOUT' => $timeout, diff --git a/public/admin/tool/mobile/lang/en/tool_mobile.php b/public/admin/tool/mobile/lang/en/tool_mobile.php index db03570e0cd..3e8b1f3244d 100644 --- a/public/admin/tool/mobile/lang/en/tool_mobile.php +++ b/public/admin/tool/mobile/lang/en/tool_mobile.php @@ -39,11 +39,13 @@ $string['autologoutcustom'] = 'Custom time after users leave or close the app'; $string['autologoutinmediate'] = 'Immediately after users leave or close the app'; $string['autologouttime'] = 'Auto logout timer'; $string['billedannually'] = 'Billed annually'; +$string['branding'] = 'Branding'; $string['cachedef_plugininfo'] = 'This stores the list of plugins with mobile addons'; $string['cachedef_subscriptioninfo'] = 'This stores the Moodle app subscription information.'; $string['clickheretolaunchtheapp'] = 'Click here if the app does not open automatically.'; $string['configmobilecssurl'] = 'A CSS file to customise your mobile app interface.'; $string['currentusage'] = 'Current usage'; +$string['customisation'] = 'Customisation'; $string['customlangstrings'] = 'Custom language strings'; $string['customlangstrings_desc'] = 'Words and phrases displayed in the app can be customised here. Enter each custom language string on a new line with format: string identifier, custom language string and language code, separated by pipe characters. For example:
@@ -88,6 +90,7 @@ $string['downloadcourse'] = 'Download course';
$string['downloadcourses'] = 'Download courses';
$string['enablesmartappbanners'] = 'Enable App Banners';
$string['enablesmartappbanners_desc'] = 'If enabled, a banner promoting the mobile app will be displayed when accessing the site using a mobile browser.';
+$string['enhanced'] = 'Premium';
$string['feature'] = 'Feature';
$string['featurecomparison'] = 'Feature comparison';
$string['features'] = 'features';
@@ -111,11 +114,17 @@ $string['invaliduserquotawarning'] = 'The user quota (userquota) is set to an in
$string['iosappid'] = 'iOS app\'s unique identifier';
$string['iosappid_desc'] = 'This setting may be left as default unless you have a custom iOS app.';
$string['launchviasiteinbrowser'] = 'Launch via site in system browser';
+$string['learnmore'] = 'Learn more';
+$string['limiteddisabledfeature'] = 'You are limited to {$a->limit} {$a->feature} on your {$a->plan} plan. {$a->related}Learn more';
+$string['limiteddisabledfeature_related'] = 'This limit is shared with {$a}. ';
$string['limitedfeatures'] = 'Limited features';
$string['loginintheapp'] = 'Via the app';
$string['logininthebrowser'] = 'Via a browser window (for SSO plugins)';
$string['loginintheembeddedbrowser'] = 'Via an embedded browser (for SSO plugins)';
$string['logoutconfirmation'] = 'Are you sure you want to log out from the mobile app on your mobile devices? By logging out, you will then need to re-enter your username and password in the mobile app on all devices where you have the app installed.';
+$string['lookingforcsscustomisation'] = 'Looking for CSS customisation?';
+$string['lookingforcustomisationfeatures'] = 'Looking for customisation features?';
+$string['lookingforqrcodelogin'] = 'Looking for QR code Login?';
$string['mainmenu'] = 'Main menu';
$string['manage'] = 'Manage';
$string['managefiletypes'] = 'Manage file types';
@@ -131,6 +140,10 @@ $string['mobilefeatures'] = 'Mobile features';
$string['mobilenotificationsdisabledwarning'] = 'Mobile notifications are not enabled. They should be enabled in Notification settings.';
$string['mobilesettings'] = 'Mobile settings';
$string['moodleappsportalfeatureswarning'] = 'Please note that some features may be restricted depending on your Moodle app subscription. For details, visit the Moodle Apps Portal.';
+$string['movedcsstopremiumfeatures'] = 'CSS for mobile app customisation has been moved to the {$a->urlname} section.';
+$string['moveddisabledtopremiumfeatures'] = 'Features like disabled features, custom menu items, and language customisation have been moved to the {$a->urlname} section.';
+$string['movedqrtopremiumfeatures'] = 'QR code authentication has been moved to the {$a->urlname} section. This includes both basic QR code (Free) and automatic QR login ({$a->upgradename}).';
+$string['new'] = 'New';
$string['nosubsblocked'] = 'Your Moodle server may be blocking outbound connections to the Moodle Apps Portal.';
$string['nosubscouldntretrieve'] = "We couldn't retrieve your plan details";
$string['nosubsoerror'] = "Unable to connect to Moodle Apps Portal. Your plan, feature limits, and usage data are temporarily unavailable. This doesnβt affect your active subscription.";
@@ -152,9 +165,12 @@ $string['planbenefits'] = 'Your {$a} plan benefits';
$string['plancontinues'] = 'Your {$a} plan continues without changes';
$string['plandetails'] = 'Your Moodle app subscription';
$string['planexpireson'] = 'Expires on ';
+$string['planlastchecked'] = 'Plan status last checked on {$a}.';
$string['planneverchecked'] = 'Plan status has never been checked.';
$string['pluginname'] = 'Moodle app tools';
$string['pluginnotenabledorconfigured'] = 'Plugin not enabled or configured.';
+$string['premiumfeatureonly'] = 'Premium feature only';
+$string['premiumfeatures'] = 'Premium features';
$string['privacy:metadata:core_userkey'] = 'User\'s keys used to create auto-login key for the current user.';
$string['privacy:metadata:preference:tool_mobile_autologin_request_last'] = 'The date of the last auto-login key request. Between each request 6 minutes are required.';
$string['qrcodedisabled'] = 'Access via QR code disabled';
@@ -164,14 +180,15 @@ $string['qrcodeformobileappurlabout'] = 'Scan the QR code with your mobile app t
$string['qrcodetype'] = 'QR code access';
$string['qrcodetype_desc'] = 'A QR code can be provided for mobile app users to scan. This can be used to fill in the site URL, or where the site is secured using HTTPS, to automatically log the user in without having to enter their username and password.';
$string['qrcodetypelogin'] = 'QR code with automatic login';
-$string['qrcodetypeurl'] = 'QR code with site URL';
+$string['qrcodetypeurl'] = 'QR code with site URL (Free)';
$string['qrkeyttl'] = 'QR authentication key duration';
$string['qrkeyttl_desc'] = 'The length of time for which a QR code for automatic login is valid.';
+$string['qronlypremium'] = '{$a->feature} is only available in Premium. Upgrade to use QR code with automatic login. Learn more';
$string['qrsameipcheck'] = 'QR authentication same IP check';
$string['qrsameipcheck_desc'] = 'Whether users must use the same network for both generating and scanning a QR code for login. Only disable it if users report issues with the QR login.';
$string['qrsiteadminsnotallowed'] = 'For security reasons login via QR code is not allowed for site administrators or if you are logged in as another user.';
$string['readingthisemailgettheapp'] = 'Are you reading this in an email? Download the mobile app and receive notifications on your mobile device.';
-$string['siteplugins'] = 'Site plugins';
+$string['refreshplanstatus'] = 'Refresh plan status';
$string['register'] = 'Register';
$string['responsivemainmenuitems'] = 'Responsive menu items';
$string['scanqrcode'] = 'Scan QR code';
@@ -180,6 +197,7 @@ $string['setuplink'] = 'App download page';
$string['setuplink_desc'] = 'URL of page with options to download the mobile app from the App Store and Google Play. The app download page link is displayed in the page footer and in a user\'s profile. Leave blank to not display a link.';
$string['showingcacheddata'] = 'Last synced: {$a->since} days ago ({$a->date}).';
$string['showinglivedata'] = 'View live data in the Moodle Apps Portal.';
+$string['siteplugins'] = 'Site plugins';
$string['smartappbanners'] = 'App Banners';
$string['subscription'] = 'Subscription';
$string['subscriptioncreated'] = 'Start date';
@@ -195,6 +213,8 @@ $string['taskrefreshsubscriptioncache'] = 'Refresh Moodle app subscription infor
$string['typeoflogin'] = 'Type of login';
$string['typeoflogin_desc'] = 'If the site uses a SSO authentication method, then select via a browser window or via an embedded browser. An embedded browser provides a better user experience, though it doesn\'t work with all SSO plugins.';
$string['upgradeforunlimit'] = 'Upgrade to {$a} for unlimited access.';
+$string['upgradeplanlimits'] = 'Some features are available with limits on the {$a} plan.';
+$string['upgraderemovelimits'] = 'Upgrade to {$a} and remove all limits';
$string['upgradetosubscription'] = 'Upgrade to {$a}';
$string['upgradeyourplan'] = 'Upgrade your plan';
$string['viewqrcode'] = 'View QR code';
diff --git a/public/admin/tool/mobile/settings.php b/public/admin/tool/mobile/settings.php
index e798c633235..91be2dcd38d 100644
--- a/public/admin/tool/mobile/settings.php
+++ b/public/admin/tool/mobile/settings.php
@@ -38,38 +38,54 @@ if ($hassiteconfig || has_capability('moodle/site:configview', context_system::i
$enablemobiledoclink = html_writer::link($enablemobiledocurl, new lang_string('documentation'));
$default = is_https() ? 1 : 0;
$optionalsubsystems = $ADMIN->locate('optionalsubsystems');
- $optionalsubsystems->add(new admin_setting_enablemobileservice('enablemobilewebservice',
- new lang_string('enablemobilewebservice', 'admin'),
- new lang_string('configenablemobilewebservice', 'admin', $enablemobiledoclink), $default));
+ $optionalsubsystems->add(new admin_setting_enablemobileservice(
+ 'enablemobilewebservice',
+ new lang_string('enablemobilewebservice', 'admin'),
+ new lang_string('configenablemobilewebservice', 'admin', $enablemobiledoclink),
+ $default
+ ));
}
- $ismobilewsdisabled = empty($CFG->enablemobilewebservice);
- $ADMIN->add('root',
- new admin_category('mobileapp', new lang_string('mobileapp', 'tool_mobile'), $ismobilewsdisabled),
- 'development'
- );
- // General notification about limited features due to app restrictions.
- $subscriptionurl = (new moodle_url("/$CFG->admin/tool/mobile/subscription.php"))->out(false);
- $notify = new \core\output\notification(
- get_string('moodleappsportalfeatureswarning', 'tool_mobile', $subscriptionurl),
- \core\output\notification::NOTIFY_WARNING
- );
- $featuresnotice = $OUTPUT->render($notify);
-
- $visiblename = get_string('mobileappsubscription', 'tool_mobile');
-
+ // Getting information to prepare settings pages.
$ispremiumplan = false;
$subscriptiondata = api::get_subscription_information(true);
if (is_array($subscriptiondata) && !empty($subscriptiondata['subscription']['plan'])) {
$plan = \core_text::strtolower(trim($subscriptiondata['subscription']['plan']));
$ispremiumplan = ($plan === 'premium' || $plan === 'bma');
}
+ if (!$ispremiumplan) {
+ $upgradeplanname = new lang_string('enhanced', 'tool_mobile');
+ if (is_array($subscriptiondata) && !empty($subscriptiondata['availableplans'])) {
+ foreach ($subscriptiondata['availableplans'] as $plan) {
+ if ($plan['plan'] != 'premium') {
+ continue;
+ }
+ $upgradeplanname = $plan['name'];
+ }
+ }
+ $planname = new lang_string('currentusage', 'tool_mobile');
+ if (is_array($subscriptiondata) && !empty($subscriptiondata['subscription']['name'])) {
+ $planname = $subscriptiondata['subscription']['name'];
+ }
+ $appsportalurl = (new \moodle_url(\tool_mobile\api::MOODLE_APPS_PORTAL_URL))->out(true);
+ $premiumfeaturesurl = (new moodle_url("/admin/settings.php", ['section' => 'premiumfeatures']))->out(true);
+ }
+ // Setting pages group.
+ $ismobilewsdisabled = empty($CFG->enablemobilewebservice);
+ $ADMIN->add(
+ 'root',
+ new admin_category('mobileapp', new lang_string('mobileapp', 'tool_mobile'), $ismobilewsdisabled),
+ 'development'
+ );
+
+ // Subscription information page.
+ $mobileappsubscriptionstr = get_string('mobileappsubscription', 'tool_mobile');
if (!$ispremiumplan) {
$upgradetext = strtoupper(get_string('upgradeyourplan', 'tool_mobile'));
if (right_to_left()) {
- $visiblename .= ' ' . $upgradetext . ' π';
+ $mobileappsubscriptionstr .= ' ' . $upgradetext . ' π';
} else {
- $visiblename .= ' π ' . $upgradetext;
+ $mobileappsubscriptionstr .= ' π ' . $upgradetext;
}
}
@@ -77,111 +93,272 @@ if ($hassiteconfig || has_capability('moodle/site:configview', context_system::i
'mobileapp',
new admin_externalpage(
'mobileappsubscription',
- $visiblename,
+ $mobileappsubscriptionstr,
"$CFG->wwwroot/$CFG->admin/tool/mobile/subscription.php",
'moodle/site:configview',
$ismobilewsdisabled
)
);
-
+ // Premium features settings page.
+ $premiumfeaturestitle = get_string('premiumfeatures', 'tool_mobile');
+ $shownewsettingsuntil = null;
+ if (!$ismobilewsdisabled) {
+ $shownewsettingsuntil = get_config('tool_mobile', 'shownewsettings');
+ if (empty($shownewsettingsuntil)) {
+ $shownewsettingsuntil = time() + (180 * DAYSECS);
+ set_config('shownewsettings', $shownewsettingsuntil, 'tool_mobile');
+ }
+ if (!empty($shownewsettingsuntil) && time() < $shownewsettingsuntil) {
+ $new = strtoupper(get_string('new', 'tool_mobile'));
+ if (right_to_left()) {
+ $premiumfeaturestitle .= ' ' . $new . ' βοΈ';
+ } else {
+ $premiumfeaturestitle .= ' βοΈ ' . $new;
+ }
+ }
+ }
$temp = new admin_settingpage(
- 'mobilesettings',
- new lang_string('mobilesettings', 'tool_mobile'),
- 'moodle/site:config',
- $ismobilewsdisabled,
- );
-
- $temp->add(new admin_setting_configtext(
- 'tool_mobile/apppolicy',
- new lang_string('apppolicy', 'tool_mobile'),
- new lang_string('apppolicy_help', 'tool_mobile'),
- '',
- PARAM_URL,
- ));
-
- $ADMIN->add('mobileapp', $temp);
-
- // Type of login.
- $temp = new admin_settingpage(
- 'mobileauthentication',
- new lang_string('mobileauthentication', 'tool_mobile'),
+ 'premiumfeatures',
+ $premiumfeaturestitle,
'moodle/site:config',
$ismobilewsdisabled
);
- $temp->add(new admin_setting_heading('tool_mobile/moodleappsportalfeaturesauth', '', $featuresnotice));
+ if (!$ispremiumplan) {
+ // Show notice about features limited in the current plan.
+ $templateheadersettings = [
+ 'title' => new lang_string('upgraderemovelimits', 'tool_mobile', $upgradeplanname),
+ 'icon' => 'π',
+ 'message' => clean_text(get_string('upgradeplanlimits', 'tool_mobile', $planname)),
+ 'buttonstr' => new lang_string('learnmore', 'tool_mobile'),
+ 'buttonurl' => (new \moodle_url("/admin/tool/mobile/subscription.php"))->out(true),
+ ];
+ $lastupdated = get_config('tool_mobile', 'subscriptioninfoupdated');
+ if (!$lastupdated || time() - $lastupdated > 10 * DAYSECS) {
+ // Add cache reload option if the information is older than 10 days.
+ $reloadcachetext = new lang_string('planneverchecked', 'tool_mobile');
+ if ($lastupdated) {
+ $lastupdatedstr = userdate($lastupdated, get_string('strftimedatemonthabbr', 'langconfig'));
+ $reloadcachetext = new lang_string('planlastchecked', 'tool_mobile', $lastupdatedstr);
+ }
+ $templateheadersettings['reloadcache'] = [
+ 'url' => (new \moodle_url("/admin/tool/mobile/subscription.php", ['returnto' => $premiumfeaturesurl]))->out(true),
+ 'text' => $reloadcachetext,
+ ];
+ }
- $options = array(
- tool_mobile\api::LOGIN_VIA_APP => new lang_string('loginintheapp', 'tool_mobile'),
- tool_mobile\api::LOGIN_VIA_BROWSER => new lang_string('logininthebrowser', 'tool_mobile'),
- tool_mobile\api::LOGIN_VIA_EMBEDDED_BROWSER => new lang_string('loginintheembeddedbrowser', 'tool_mobile'),
- );
- $temp->add(new admin_setting_configselect('tool_mobile/typeoflogin',
- new lang_string('typeoflogin', 'tool_mobile'),
- new lang_string('typeoflogin_desc', 'tool_mobile'), 1, $options));
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/moodleappsportalfeatures',
+ '',
+ $OUTPUT->render_from_template('tool_mobile/settings_alert', $templateheadersettings)
+ ));
+ }
- $options = [
- tool_mobile\api::AUTOLOGOUT_DISABLED => new lang_string('never'),
- tool_mobile\api::AUTOLOGOUT_INMEDIATE => new lang_string('autologoutinmediate', 'tool_mobile'),
- tool_mobile\api::AUTOLOGOUT_CUSTOM => new lang_string('autologoutcustom', 'tool_mobile'),
- ];
- $temp->add(new admin_setting_configselect('tool_mobile/autologout',
- new lang_string('autologout', 'tool_mobile'),
- new lang_string('autologout_desc', 'tool_mobile'), 0, $options));
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/authentication',
+ new lang_string('authentication'),
+ ''
+ ));
- $temp->add(new admin_setting_configduration('tool_mobile/autologouttime',
- new lang_string('autologouttime', 'tool_mobile'), '', DAYSECS));
- $temp->hide_if('tool_mobile/autologouttime', 'tool_mobile/autologout', 'neq', tool_mobile\api::AUTOLOGOUT_CUSTOM);
+ if (!$ispremiumplan) {
+ $featureslimited = [];
+ if (is_array($subscriptiondata) && !empty($subscriptiondata['subscription']['features'])) {
+ foreach ($subscriptiondata['subscription']['features'] as $feature) {
+ if (isset($feature['limit']) && $feature['limit']) {
+ switch ($feature['name']) {
+ case 'customlanguagestrings':
+ $featureslimited['customlangstrings'] = $feature['limit'];
+ break;
+ default:
+ $featureslimited[$feature['name']] = $feature['limit'];
+ break;
+ }
+ }
+ }
+ }
+ $featureparams = [
+ 'url' => $appsportalurl,
+ 'plan' => $planname,
+ 'related' => '',
+ ];
+
+ $templatesubscribe = [
+ 'insettings' => true,
+ 'icon' => [
+ 'icon' => 'i/warning',
+ 'component' => 'core',
+ ],
+ ];
+ }
$options = [
tool_mobile\api::QR_CODE_DISABLED => new lang_string('qrcodedisabled', 'tool_mobile'),
tool_mobile\api::QR_CODE_URL => new lang_string('qrcodetypeurl', 'tool_mobile'),
];
- $qrcodetypedefault = tool_mobile\api::QR_CODE_URL;
if (is_https()) { // Allow QR login for https sites.
- $options[tool_mobile\api::QR_CODE_LOGIN] = new lang_string('qrcodetypelogin', 'tool_mobile');
- $qrcodetypedefault = tool_mobile\api::QR_CODE_LOGIN;
+ $options[tool_mobile\api::QR_CODE_LOGIN] = 'β‘ ' . get_string('qrcodetypelogin', 'tool_mobile')
+ . ' (' . get_string('premiumfeatureonly', 'tool_mobile') . ')';
}
- $temp->add(new admin_setting_configselect('tool_mobile/qrcodetype',
- new lang_string('qrcodetype', 'tool_mobile'),
- new lang_string('qrcodetype_desc', 'tool_mobile'), $qrcodetypedefault, $options));
+ $temp->add(new admin_setting_configselect(
+ 'tool_mobile/qrcodetype',
+ new lang_string('qrcodetype', 'tool_mobile'),
+ new lang_string('qrcodetype_desc', 'tool_mobile'),
+ tool_mobile\api::QR_CODE_URL,
+ $options
+ ));
- $temp->add(new admin_setting_configduration('tool_mobile/qrkeyttl',
+ $temp->add(new admin_setting_configduration(
+ 'tool_mobile/qrkeyttl',
new lang_string('qrkeyttl', 'tool_mobile'),
- new lang_string('qrkeyttl_desc', 'tool_mobile'), tool_mobile\api::LOGIN_QR_KEY_TTL, MINSECS));
+ new lang_string('qrkeyttl_desc', 'tool_mobile'),
+ tool_mobile\api::LOGIN_QR_KEY_TTL,
+ MINSECS
+ ));
$temp->hide_if('tool_mobile/qrkeyttl', 'tool_mobile/qrcodetype', 'neq', tool_mobile\api::QR_CODE_LOGIN);
- $temp->add(new admin_setting_configcheckbox('tool_mobile/qrsameipcheck',
- new lang_string('qrsameipcheck', 'tool_mobile'),
- new lang_string('qrsameipcheck_desc', 'tool_mobile'), 1));
+ $temp->add(new admin_setting_configcheckbox(
+ 'tool_mobile/qrsameipcheck',
+ new lang_string('qrsameipcheck', 'tool_mobile'),
+ new lang_string('qrsameipcheck_desc', 'tool_mobile'),
+ 1
+ ));
$temp->hide_if('tool_mobile/qrsameipcheck', 'tool_mobile/qrcodetype', 'neq', tool_mobile\api::QR_CODE_LOGIN);
- $temp->add(new admin_setting_configtext('tool_mobile/forcedurlscheme',
- new lang_string('forcedurlscheme_key', 'tool_mobile'),
- new lang_string('forcedurlscheme', 'tool_mobile'), 'moodlemobile', PARAM_NOTAGS));
+ if (!$ispremiumplan && get_config('tool_mobile', 'qrcodetype') == tool_mobile\api::QR_CODE_LOGIN) {
+ $featureparams['feature'] = get_string('qrcodetypelogin', 'tool_mobile');
+ $templatesubscribe['message'] = clean_text(get_string('qronlypremium', 'tool_mobile', $featureparams));
- $temp->add(new admin_setting_configtext('tool_mobile/minimumversion',
- new lang_string('minimumversion_key', 'tool_mobile'),
- new lang_string('minimumversion', 'tool_mobile'), '', PARAM_NOTAGS));
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/qronlypremium',
+ '',
+ $OUTPUT->render_from_template('tool_mobile/subscribe_alert', $templatesubscribe)
+ ));
+ }
- $options = [
- 60 => new lang_string('numminutes', '', 1),
- 180 => new lang_string('numminutes', '', 3),
- 360 => new lang_string('numminutes', '', 6),
- 900 => new lang_string('numminutes', '', 15),
- 1800 => new lang_string('numminutes', '', 30),
- 3600 => new lang_string('numminutes', '', 60)
- ];
- $temp->add(new admin_setting_configselect('tool_mobile/autologinmintimebetweenreq',
- new lang_string('autologinmintimebetweenreq', 'tool_mobile'),
- new lang_string('autologinmintimebetweenreq_desc', 'tool_mobile'), 360, $options));
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/branding',
+ new lang_string('branding', 'tool_mobile'),
+ ''
+ ));
+
+ $temp->add(new admin_setting_configtext(
+ 'mobilecssurl',
+ new lang_string('mobilecssurl', 'tool_mobile'),
+ new lang_string('configmobilecssurl', 'tool_mobile'),
+ '',
+ PARAM_URL
+ ));
+
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/customisation',
+ new lang_string('customisation', 'tool_mobile'),
+ ''
+ ));
+
+ $options = tool_mobile\api::get_features_list();
+ $featurename = new lang_string('disabledfeatures', 'tool_mobile');
+ $temp->add(new admin_setting_configmultiselect(
+ 'tool_mobile/disabledfeatures',
+ $featurename,
+ new lang_string('disabledfeatures_desc', 'tool_mobile'),
+ [],
+ $options
+ ));
+ if (!$ispremiumplan && isset($featureslimited['disabledfeatures'])) {
+ $featureparams['limit'] = $featureslimited['disabledfeatures'];
+ $featureparams['feature'] = strtolower($featurename);
+ $templatesubscribe['message'] = clean_text(get_string('limiteddisabledfeature', 'tool_mobile', $featureparams));
+
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/disabledfeaturessubscribe',
+ '',
+ $OUTPUT->render_from_template('tool_mobile/subscribe_alert', $templatesubscribe)
+ ));
+ }
+
+ // Manage disabledfeatures with custommenuitems and customusermenuitems.
+ $custommenuitemsstr = new lang_string('disabledfeatures', 'tool_mobile');
+ $customusermenuitemsstr = new lang_string('customusermenuitems', 'tool_mobile');
+ $temp->add(new admin_setting_configtextarea(
+ 'tool_mobile/custommenuitems',
+ $custommenuitemsstr,
+ new lang_string('custommenuitems_desc', 'tool_mobile'),
+ '',
+ PARAM_RAW,
+ '50',
+ '10',
+ ));
+ if (!$ispremiumplan && isset($featureslimited['custommenuitems'])) {
+ $featureparams['limit'] = $featureslimited['custommenuitems'];
+ $featureparams['feature'] = strtolower($custommenuitemsstr);
+ $featureparams['related'] = new lang_string(
+ 'limiteddisabledfeature_related',
+ 'tool_mobile',
+ strtolower($customusermenuitemsstr)
+ );
+ $templatesubscribe['message'] = clean_text(get_string('limiteddisabledfeature', 'tool_mobile', $featureparams));
+
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/custommenuitemssubscribe',
+ '',
+ $OUTPUT->render_from_template('tool_mobile/subscribe_alert', $templatesubscribe)
+ ));
+ }
+
+ $temp->add(new admin_setting_configtextarea(
+ 'tool_mobile/customusermenuitems',
+ $customusermenuitemsstr,
+ new lang_string('customusermenuitems_desc', 'tool_mobile'),
+ '',
+ PARAM_RAW,
+ '50',
+ '10',
+ ));
+ if (!$ispremiumplan && isset($featureslimited['customusermenuitems'])) {
+ $featureparams['feature'] = strtolower($customusermenuitemsstr);
+ $featureparams['related'] = new lang_string(
+ 'limiteddisabledfeature_related',
+ 'tool_mobile',
+ strtolower($custommenuitemsstr)
+ );
+ $templatesubscribe['message'] = clean_text(get_string('limiteddisabledfeature', 'tool_mobile', $featureparams));
+
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/customusermenuitemssubscribe',
+ '',
+ $OUTPUT->render_from_template('tool_mobile/subscribe_alert', $templatesubscribe)
+ ));
+ }
+
+ $featurename = new lang_string('customlangstrings', 'tool_mobile');
+ $temp->add(new admin_setting_configtextarea(
+ 'tool_mobile/customlangstrings',
+ $featurename,
+ new lang_string('customlangstrings_desc', 'tool_mobile'),
+ '',
+ PARAM_RAW,
+ '50',
+ '10'
+ ));
+ if (!$ispremiumplan && isset($featureslimited['customlangstrings'])) {
+ $featureparams['limit'] = $featureslimited['customlangstrings'];
+ $featureparams['feature'] = strtolower($featurename);
+ $featureparams['related'] = '';
+ $templatesubscribe['message'] = clean_text(get_string('limiteddisabledfeature', 'tool_mobile', $featureparams));
+
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/customlangstringssubscribe',
+ '',
+ $OUTPUT->render_from_template('tool_mobile/subscribe_alert', $templatesubscribe)
+ ));
+ }
$ADMIN->add('mobileapp', $temp);
- // Appearance related settings.
+ // Appearance features settings page.
$temp = new admin_settingpage(
'mobileappearance',
new lang_string('mobileappearance', 'tool_mobile'),
@@ -189,38 +366,177 @@ if ($hassiteconfig || has_capability('moodle/site:configview', context_system::i
$ismobilewsdisabled
);
- $temp->add(new admin_setting_heading('tool_mobile/moodleappsportalfeaturesappearance', '', $featuresnotice));
+ if (!$ispremiumplan) {
+ $strmovedparams = [
+ 'url' => $premiumfeaturesurl,
+ 'urlname' => get_string('premiumfeatures', 'tool_mobile'),
+ 'name' => $planname,
+ 'upgradename' => $upgradeplanname,
+ ];
+ $templateheadersettings = [
+ 'title' => new lang_string('lookingforcsscustomisation', 'tool_mobile'),
+ 'icon' => 'π‘',
+ 'message' => clean_text(get_string('movedcsstopremiumfeatures', 'tool_mobile', $strmovedparams)),
+ 'extraclasses' => 'alert-info',
+ ];
- $temp->add(new admin_setting_configtext('mobilecssurl', new lang_string('mobilecssurl', 'tool_mobile'),
- new lang_string('configmobilecssurl', 'tool_mobile'), '', PARAM_URL));
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/moodleappsportalfeaturesappearance',
+ '',
+ $OUTPUT->render_from_template('tool_mobile/settings_alert', $templateheadersettings)
+ ));
+ }
// Reference to Branded Mobile App.
if (empty($CFG->disableserviceads_branded)) {
- $temp->add(new admin_setting_description('moodlebrandedappreference',
+ $temp->add(new admin_setting_description(
+ 'moodlebrandedappreference',
new lang_string('moodlebrandedapp', 'admin'),
new lang_string('moodlebrandedappreference', 'admin')
));
}
- $temp->add(new admin_setting_heading('tool_mobile/smartappbanners',
- new lang_string('smartappbanners', 'tool_mobile'), ''));
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/smartappbanners',
+ new lang_string('smartappbanners', 'tool_mobile'),
+ ''
+ ));
- $temp->add(new admin_setting_configcheckbox('tool_mobile/enablesmartappbanners',
- new lang_string('enablesmartappbanners', 'tool_mobile'),
- new lang_string('enablesmartappbanners_desc', 'tool_mobile'), 0));
+ $temp->add(
+ new admin_setting_configcheckbox(
+ 'tool_mobile/enablesmartappbanners',
+ new lang_string('enablesmartappbanners', 'tool_mobile'),
+ new lang_string('enablesmartappbanners_desc', 'tool_mobile'),
+ 0
+ )
+ );
- $temp->add(new admin_setting_configtext('tool_mobile/iosappid', new lang_string('iosappid', 'tool_mobile'),
- new lang_string('iosappid_desc', 'tool_mobile'), tool_mobile\api::DEFAULT_IOS_APP_ID, PARAM_ALPHANUM));
+ $temp->add(new admin_setting_configtext(
+ 'tool_mobile/iosappid',
+ new lang_string('iosappid', 'tool_mobile'),
+ new lang_string('iosappid_desc', 'tool_mobile'),
+ tool_mobile\api::DEFAULT_IOS_APP_ID,
+ PARAM_ALPHANUM
+ ));
- $temp->add(new admin_setting_configtext('tool_mobile/androidappid', new lang_string('androidappid', 'tool_mobile'),
- new lang_string('androidappid_desc', 'tool_mobile'), tool_mobile\api::DEFAULT_ANDROID_APP_ID, PARAM_NOTAGS));
+ $temp->add(new admin_setting_configtext(
+ 'tool_mobile/androidappid',
+ new lang_string('androidappid', 'tool_mobile'),
+ new lang_string('androidappid_desc', 'tool_mobile'),
+ tool_mobile\api::DEFAULT_ANDROID_APP_ID,
+ PARAM_NOTAGS
+ ));
- $temp->add(new admin_setting_configtext('tool_mobile/setuplink', new lang_string('setuplink', 'tool_mobile'),
- new lang_string('setuplink_desc', 'tool_mobile'), 'https://download.moodle.org/mobile', PARAM_URL));
+ $temp->add(new admin_setting_configtext(
+ 'tool_mobile/setuplink',
+ new lang_string('setuplink', 'tool_mobile'),
+ new lang_string('setuplink_desc', 'tool_mobile'),
+ 'https://download.moodle.org/mobile',
+ PARAM_URL
+ ));
$ADMIN->add('mobileapp', $temp);
- // Features related settings.
+ // Authentication features settings page.
+ $temp = new admin_settingpage(
+ 'mobileauthentication',
+ new lang_string('mobileauthentication', 'tool_mobile'),
+ 'moodle/site:config',
+ $ismobilewsdisabled
+ );
+
+ if (!$ispremiumplan) {
+ $templateheadersettings = [
+ 'title' => new lang_string('lookingforqrcodelogin', 'tool_mobile'),
+ 'icon' => 'π―',
+ 'message' => clean_text(get_string('movedqrtopremiumfeatures', 'tool_mobile', $strmovedparams)),
+ 'extraclasses' => 'alert-info',
+ ];
+ $featuresnotice = $OUTPUT->render_from_template('tool_mobile/settings_alert', $templateheadersettings);
+
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/moodleappsportalfeaturesauthentication',
+ '',
+ $featuresnotice
+ ));
+ }
+
+ $options = [
+ tool_mobile\api::LOGIN_VIA_APP => new lang_string('loginintheapp', 'tool_mobile'),
+ tool_mobile\api::LOGIN_VIA_BROWSER => new lang_string('logininthebrowser', 'tool_mobile'),
+ tool_mobile\api::LOGIN_VIA_EMBEDDED_BROWSER => new lang_string('loginintheembeddedbrowser', 'tool_mobile'),
+ ];
+ $temp->add(new admin_setting_configselect(
+ 'tool_mobile/typeoflogin',
+ new lang_string('typeoflogin', 'tool_mobile'),
+ new lang_string('typeoflogin_desc', 'tool_mobile'),
+ 1,
+ $options
+ ));
+
+ $temp->add(new admin_setting_configtext(
+ 'tool_mobile/forcedurlscheme',
+ new lang_string('forcedurlscheme_key', 'tool_mobile'),
+ new lang_string('forcedurlscheme', 'tool_mobile'),
+ 'moodlemobile',
+ PARAM_NOTAGS
+ ));
+
+ $temp->add(new admin_setting_configcheckbox(
+ 'tool_mobile/forcelogout',
+ new lang_string('forcelogout', 'tool_mobile'),
+ new lang_string('forcelogout_desc', 'tool_mobile'),
+ 0
+ ));
+
+ $options = [
+ tool_mobile\api::AUTOLOGOUT_DISABLED => new lang_string('never'),
+ tool_mobile\api::AUTOLOGOUT_INMEDIATE => new lang_string('autologoutinmediate', 'tool_mobile'),
+ tool_mobile\api::AUTOLOGOUT_CUSTOM => new lang_string('autologoutcustom', 'tool_mobile'),
+ ];
+ $temp->add(new admin_setting_configselect(
+ 'tool_mobile/autologout',
+ new lang_string('autologout', 'tool_mobile'),
+ new lang_string('autologout_desc', 'tool_mobile'),
+ 0,
+ $options
+ ));
+
+ $temp->add(new admin_setting_configduration(
+ 'tool_mobile/autologouttime',
+ new lang_string('autologouttime', 'tool_mobile'),
+ '',
+ DAYSECS
+ ));
+ $temp->hide_if('tool_mobile/autologouttime', 'tool_mobile/autologout', 'neq', tool_mobile\api::AUTOLOGOUT_CUSTOM);
+
+ $temp->add(new admin_setting_configtext(
+ 'tool_mobile/minimumversion',
+ new lang_string('minimumversion_key', 'tool_mobile'),
+ new lang_string('minimumversion', 'tool_mobile'),
+ '',
+ PARAM_NOTAGS
+ ));
+
+ $options = [
+ 60 => new lang_string('numminutes', '', 1),
+ 180 => new lang_string('numminutes', '', 3),
+ 360 => new lang_string('numminutes', '', 6),
+ 900 => new lang_string('numminutes', '', 15),
+ 1800 => new lang_string('numminutes', '', 30),
+ 3600 => new lang_string('numminutes', '', 60),
+ ];
+ $temp->add(new admin_setting_configselect(
+ 'tool_mobile/autologinmintimebetweenreq',
+ new lang_string('autologinmintimebetweenreq', 'tool_mobile'),
+ new lang_string('autologinmintimebetweenreq_desc', 'tool_mobile'),
+ 360,
+ $options
+ ));
+
+ $ADMIN->add('mobileapp', $temp);
+
+ // Features settings page.
$temp = new admin_settingpage(
'mobilefeatures',
new lang_string('mobilefeatures', 'tool_mobile'),
@@ -228,41 +544,28 @@ if ($hassiteconfig || has_capability('moodle/site:configview', context_system::i
$ismobilewsdisabled
);
- $temp->add(new admin_setting_heading('tool_mobile/moodleappsportalfeatures', '', $featuresnotice));
+ if (!$ispremiumplan) {
+ $templateheadersettings = [
+ 'title' => new lang_string('lookingforcustomisationfeatures', 'tool_mobile'),
+ 'icon' => 'π―',
+ 'message' => clean_text(get_string('moveddisabledtopremiumfeatures', 'tool_mobile', $strmovedparams)),
+ 'extraclasses' => 'alert-info',
+ ];
+ $featuresnotice = $OUTPUT->render_from_template('tool_mobile/settings_alert', $templateheadersettings);
- $temp->add(new admin_setting_heading('tool_mobile/logout',
- new lang_string('logout'), ''));
+ $temp->add(new admin_setting_heading(
+ 'tool_mobile/moodleappsportalfeaturesfeatures',
+ '',
+ $featuresnotice
+ ));
+ }
- $temp->add(new admin_setting_configcheckbox('tool_mobile/forcelogout',
- new lang_string('forcelogout', 'tool_mobile'),
- new lang_string('forcelogout_desc', 'tool_mobile'), 0));
-
- $temp->add(new admin_setting_heading('tool_mobile/features',
- new lang_string('mobilefeatures', 'tool_mobile'), ''));
-
- $options = tool_mobile\api::get_features_list();
- $temp->add(new admin_setting_configmultiselect('tool_mobile/disabledfeatures',
- new lang_string('disabledfeatures', 'tool_mobile'),
- new lang_string('disabledfeatures_desc', 'tool_mobile'), array(), $options));
-
- $temp->add(new admin_setting_configtextarea(
- 'tool_mobile/custommenuitems',
- new lang_string('custommenuitems', 'tool_mobile'),
- new lang_string('custommenuitems_desc', 'tool_mobile'),
+ $temp->add(new admin_setting_configtext(
+ 'tool_mobile/apppolicy',
+ new lang_string('apppolicy', 'tool_mobile'),
+ new lang_string('apppolicy_help', 'tool_mobile'),
'',
- PARAM_RAW,
- '50',
- '10',
- ));
-
- $temp->add(new admin_setting_configtextarea(
- 'tool_mobile/customusermenuitems',
- new lang_string('customusermenuitems', 'tool_mobile'),
- new lang_string('customusermenuitems_desc', 'tool_mobile'),
- '',
- PARAM_RAW,
- '50',
- '10',
+ PARAM_URL
));
// File type exclusionlist.
@@ -277,21 +580,19 @@ if ($hassiteconfig || has_capability('moodle/site:configview', context_system::i
$attributes = [
'manageurl' => new \moodle_url('/admin/tool/filetypes/index.php'),
- 'managetext' => get_string('managefiletypes', 'tool_mobile'),
+ 'managetext' => new lang_string('managefiletypes', 'tool_mobile'),
'multiple' => true,
'delimiter' => ',',
- 'placeholder' => get_string('filetypeexclusionlistplaceholder', 'tool_mobile')
+ 'placeholder' => new lang_string('filetypeexclusionlistplaceholder', 'tool_mobile'),
];
- $temp->add(new autocomplete('tool_mobile/filetypeexclusionlist',
+ $temp->add(new autocomplete(
+ 'tool_mobile/filetypeexclusionlist',
new lang_string('filetypeexclusionlist', 'tool_mobile'),
- new lang_string('filetypeexclusionlist_desc', 'tool_mobile'), array(), $choices, $attributes));
-
- $temp->add(new admin_setting_heading('tool_mobile/language',
- new lang_string('language'), ''));
-
- $temp->add(new admin_setting_configtextarea('tool_mobile/customlangstrings',
- new lang_string('customlangstrings', 'tool_mobile'),
- new lang_string('customlangstrings_desc', 'tool_mobile'), '', PARAM_RAW, '50', '10'));
+ new lang_string('filetypeexclusionlist_desc', 'tool_mobile'),
+ [],
+ $choices,
+ $attributes
+ ));
$ADMIN->add('mobileapp', $temp);
}
diff --git a/public/admin/tool/mobile/styles.css b/public/admin/tool/mobile/styles.css
index f51e5c77657..94948a88353 100644
--- a/public/admin/tool/mobile/styles.css
+++ b/public/admin/tool/mobile/styles.css
@@ -29,4 +29,19 @@
#page-admin-tool-mobile-subscription progress {
width: 100%;
-}
\ No newline at end of file
+}
+
+.tool_mobile-settings-alert a:not(.btn) {
+ font-weight: 700;
+ text-decoration: underline;
+}
+
+.tool_mobile-settings-alert a:not(.btn):hover {
+ text-decoration: underline;
+}
+
+.tool_mobile-settings-alert img.icon {
+ width: 20px;
+ height: 20px;
+ margin-bottom: .5rem;
+}
diff --git a/public/admin/tool/mobile/subscription.php b/public/admin/tool/mobile/subscription.php
index 8a9d20165d2..e8dcaef2591 100644
--- a/public/admin/tool/mobile/subscription.php
+++ b/public/admin/tool/mobile/subscription.php
@@ -35,6 +35,12 @@ if (!$CFG->enablemobilewebservice) {
$subscriptiondata = \tool_mobile\api::get_subscription_information(false, true, 5);
+$returnto = optional_param('returnto', '', PARAM_LOCALURL);
+if (!empty($returnto)) {
+ $returnurl = (new \moodle_url($returnto))->out(true);
+ redirect($returnurl);
+}
+
echo $OUTPUT->header();
if (empty($subscriptiondata)) {
diff --git a/public/admin/tool/mobile/templates/settings_alert.mustache b/public/admin/tool/mobile/templates/settings_alert.mustache
new file mode 100644
index 00000000000..734896c4186
--- /dev/null
+++ b/public/admin/tool/mobile/templates/settings_alert.mustache
@@ -0,0 +1,90 @@
+{{!
+ 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 .
+}}
+{{!
+ @template tool_mobile/settings_alert
+
+ Subscription-related alert notification for the Mobile tool.
+
+ The purpose of this template is to render an alert with an
+ optional action button (for example, to register the site or
+ complete subscription details).
+
+ Classes required for JS:
+ * none
+
+ Data attributes required for JS:
+ * none
+
+ Context variables required for this template:
+ * title Optional heading text (lang_string or string).
+ * icon Optional short label for the icon (for example "rocket", "lightbulb", "bullseye").
+ * message A cleaned string (use clean_text()) to display under the title.
+ * buttonstr Text for the optional primary action button.
+ * buttonurl URL for the optional primary action button.
+ * extrabuttonclasses Additional classes for the button element.
+ * reloadcache Optional object with:
+ * text Helper text displayed in the footer.
+ * url Link used to refresh or reload the subscription/cache information.
+
+ Example context (json):
+ {
+ "title": "Upgrade to Premium to remove all limits",
+ "icon": "rocket",
+ "message": "Some features are available with limits on the Free plan.",
+ "buttonstr": "Learn more",
+ "buttonurl": "https://apps.moodle.com",
+ "extrabuttonclasses": "",
+ "reloadcache": {
+ "text": "Plan last checked 10 days ago.",
+ "url": "https://example.com/admin/tool/mobile/subscription.php?returnto=..."
+ }
+ }
+}}
+
+
+
+
+ {{#title}}
+
+ {{#icon}}
+ {{icon}}
+ {{/icon}}
+
+ {{.}}
+
+
+ {{/title}}
+
+ {{{ message }}}
+
+
+ {{#buttonurl}}
+
+ {{buttonstr}}
+
+ {{/buttonurl}}
+
+
+{{#reloadcache}}
+
+{{/reloadcache}}
+
+
diff --git a/public/admin/tool/mobile/templates/subscribe_alert.mustache b/public/admin/tool/mobile/templates/subscribe_alert.mustache
index 76aac149cc0..6ee972439ff 100644
--- a/public/admin/tool/mobile/templates/subscribe_alert.mustache
+++ b/public/admin/tool/mobile/templates/subscribe_alert.mustache
@@ -31,27 +31,31 @@
Context variables required for this template:
* message A cleaned string (use clean_text()) to display.
- * extraclasses Additional classes to apply to the notification.
+ * extraclasses Additional classes to apply to the notification (for example "mt-4").
* buttonstr Text for the optional action button.
* buttonurl URL for the optional action button.
* extrabuttonclasses Additional classes for the button element.
- * icon Optional icon definition (with "icon" and "component").
+ * icon Optional boolean/section to indicate if the leading info icon should be displayed.
+ * insettings Optional boolean. When true, the alert is wrapped in form-item markup for use in admin settings pages.
Example context (json):
{
"message": "Your site is not registered in Moodle Apps Portal.",
- "extraclasses": "alert-danger",
- "buttonstr": "Register",
- "buttonurl": "https://apps.moodle.com/register",
- "extrabuttonclasses": "bg-danger",
- "icon": {
- "icon": "i/circleinfo",
- "component": "core"
- }
+ "extraclasses": "mt-4",
+ "buttonstr": "View plans",
+ "buttonurl": "https://apps.moodle.com",
+ "extrabuttonclasses": "",
+ "icon": true,
+ "insettings": true
}
}}
-
-
+{{#insettings}}
+
+
+
+
+{{/insettings}}
+
{{#icon}}
@@ -69,3 +73,7 @@
{{/buttonurl}}
+{{#insettings}}
+
+
+{{/insettings}}
\ No newline at end of file