diff --git a/public/admin/tool/mobile/classes/api.php b/public/admin/tool/mobile/classes/api.php index 11ef7715246..26f431211b6 100644 --- a/public/admin/tool/mobile/classes/api.php +++ b/public/admin/tool/mobile/classes/api.php @@ -324,13 +324,16 @@ class api { $settings->tool_mobile_disabledfeatures = get_config('tool_mobile', 'disabledfeatures'); $settings->tool_mobile_filetypeexclusionlist = get_config('tool_mobile', 'filetypeexclusionlist'); $custommenuitems = get_config('tool_mobile', 'custommenuitems'); + $customusermenuitems = get_config('tool_mobile', 'customusermenuitems'); // If filtering of the primary custom menu is enabled, apply only the string filters. if (!empty($CFG->navfilter && !empty($CFG->stringfilters))) { // Apply filters that are enabled for Content and Headings. $filtermanager = \filter_manager::instance(); $custommenuitems = $filtermanager->filter_string($custommenuitems, \context_system::instance()); + $customusermenuitems = $filtermanager->filter_string($customusermenuitems, \context_system::instance()); } $settings->tool_mobile_custommenuitems = $custommenuitems; + $settings->tool_mobile_customusermenuitems = $customusermenuitems; $settings->tool_mobile_apppolicy = get_config('tool_mobile', 'apppolicy'); // This setting could be not set in some edge cases such as bad upgrade. $mintimereq = get_config('tool_mobile', 'autologinmintimebetweenreq'); diff --git a/public/admin/tool/mobile/classes/output/subscription.php b/public/admin/tool/mobile/classes/output/subscription.php index 572a91ac400..cf31dc3c2e5 100644 --- a/public/admin/tool/mobile/classes/output/subscription.php +++ b/public/admin/tool/mobile/classes/output/subscription.php @@ -121,12 +121,25 @@ class subscription implements \renderable, \templatable { $custommenuitems = explode("\n", $els); // Get unique custom menu urls. $custommenuitems = array_flip( - array_map(function($val) { + array_map(function ($val) { return explode('|', $val)[1]; }, $custommenuitems) ); } - $feature['status'] = count($custommenuitems); + + $customusermenuitems = []; + $els = rtrim($ms->customusermenuitems, "\n"); + if (!empty($els)) { + $customusermenuitems = explode("\n", $els); + // Get unique custom menu urls. + $customusermenuitems = array_flip( + array_map(function ($val) { + return explode('|', $val)[1]; + }, $customusermenuitems) + ); + } + + $feature['status'] = count($custommenuitems) + count($customusermenuitems); break; // Check language strings. case 'customlanguagestrings': diff --git a/public/admin/tool/mobile/lang/en/tool_mobile.php b/public/admin/tool/mobile/lang/en/tool_mobile.php index 06ca328f080..19dd8c6f9f8 100644 --- a/public/admin/tool/mobile/lang/en/tool_mobile.php +++ b/public/admin/tool/mobile/lang/en/tool_mobile.php @@ -45,8 +45,8 @@ $string['configmobilecssurl'] = 'A CSS file to customise your mobile app interfa $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:
-mm.user.student|Learner|en -mm.user.student|Aprendiz|es +core.user.student|Learner|en +core.user.student|Aprendiz|esFor a complete list of string identifiers, see the documentation.'; $string['custommenuitems'] = 'Custom menu items'; @@ -56,6 +56,20 @@ Link-opening methods are: app (for linking to an activity supported by the app), When items are missing a translation for a given language, they will use other languages as fallback unless "_only" is appended to the language code. +For example: +
+App help|https://someurl.xyz/help|inappbrowser +My grades|https://someurl.xyz/local/mygrades/index.php|embedded|en +Mis calificaciones|https://someurl.xyz/local/mygrades/index.php|embedded|es +You will only see this in English|https://someurl.xyz/english|browser|en_only +'; +$string['customusermenuitems'] = 'Custom user menu items'; +$string['customusermenuitems_desc'] = 'Additional items can be added to the app\'s user menu by specifying them here. Enter each custom user menu item on a new line with format: item text, link URL, link-opening method and language code (optional, for displaying the item to users of the specified language only), separated by pipe characters. + +Link-opening methods are: app (for linking to an activity supported by the app), inappbrowser (for opening a link in a browser without leaving the app), browser (for opening the link in the device default browser outside the app) and embedded (for displaying the link in an iframe in a new page in the app). + +When items are missing a translation for a given language, they will use other languages as fallback unless "_only" is appended to the language code. + For example:
App help|https://someurl.xyz/help|inappbrowser
diff --git a/public/admin/tool/mobile/settings.php b/public/admin/tool/mobile/settings.php
index 8055b2f3c18..e0ce32ede18 100644
--- a/public/admin/tool/mobile/settings.php
+++ b/public/admin/tool/mobile/settings.php
@@ -230,9 +230,25 @@ if ($hassiteconfig) {
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'), '', PARAM_RAW, '50', '10'));
+ $temp->add(new admin_setting_configtextarea(
+ 'tool_mobile/custommenuitems',
+ new lang_string('custommenuitems', 'tool_mobile'),
+ new lang_string('custommenuitems_desc', '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',
+ ));
// File type exclusionlist.
$choices = [];
diff --git a/public/admin/tool/mobile/tests/externallib_test.php b/public/admin/tool/mobile/tests/externallib_test.php
index e260a4af8e6..483aeb23671 100644
--- a/public/admin/tool/mobile/tests/externallib_test.php
+++ b/public/admin/tool/mobile/tests/externallib_test.php
@@ -194,38 +194,39 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
// Test default values.
$context = \context_system::instance();
- $expected = array(
- array('name' => 'fullname', 'value' => $SITE->fullname),
- array('name' => 'shortname', 'value' => $SITE->shortname),
- array('name' => 'summary', 'value' => $sitesummary),
- array('name' => 'summaryformat', 'value' => $summaryformat),
- array('name' => 'frontpage', 'value' => $CFG->frontpage),
- array('name' => 'frontpageloggedin', 'value' => $CFG->frontpageloggedin),
- array('name' => 'maxcategorydepth', 'value' => $CFG->maxcategorydepth),
- array('name' => 'frontpagecourselimit', 'value' => $CFG->frontpagecourselimit),
- array('name' => 'numsections', 'value' => course_get_format($SITE)->get_last_section_number()),
- array('name' => 'newsitems', 'value' => $SITE->newsitems),
- array('name' => 'commentsperpage', 'value' => $CFG->commentsperpage),
- array('name' => 'sitepolicy', 'value' => $mysitepolicy),
- array('name' => 'sitepolicyhandler', 'value' => ''),
- array('name' => 'disableuserimages', 'value' => $CFG->disableuserimages),
- array('name' => 'mygradesurl', 'value' => user_mygrades_url()->out(false)),
- array('name' => 'tool_mobile_forcelogout', 'value' => 0),
- array('name' => 'tool_mobile_customlangstrings', 'value' => ''),
- array('name' => 'tool_mobile_disabledfeatures', 'value' => ''),
- array('name' => 'tool_mobile_filetypeexclusionlist', 'value' => ''),
- array('name' => 'tool_mobile_custommenuitems', 'value' => ''),
- array('name' => 'tool_mobile_apppolicy', 'value' => ''),
- array('name' => 'tool_mobile_autologinmintimebetweenreq', 'value' => 6 * MINSECS),
- array('name' => 'tool_mobile_autologout', 'value' => get_config('tool_mobile', 'autologout')),
- array('name' => 'tool_mobile_autologouttime', 'value' => get_config('tool_mobile', 'autologouttime')),
- array('name' => 'calendartype', 'value' => $CFG->calendartype),
- array('name' => 'calendar_site_timeformat', 'value' => $CFG->calendar_site_timeformat),
- array('name' => 'calendar_startwday', 'value' => $CFG->calendar_startwday),
- array('name' => 'calendar_adminseesall', 'value' => $CFG->calendar_adminseesall),
- array('name' => 'calendar_lookahead', 'value' => $CFG->calendar_lookahead),
- array('name' => 'calendar_maxevents', 'value' => $CFG->calendar_maxevents),
- );
+ $expected = [
+ [ 'name' => 'fullname', 'value' => $SITE->fullname ],
+ [ 'name' => 'shortname', 'value' => $SITE->shortname ],
+ [ 'name' => 'summary', 'value' => $sitesummary ],
+ [ 'name' => 'summaryformat', 'value' => $summaryformat ],
+ [ 'name' => 'frontpage', 'value' => $CFG->frontpage ],
+ [ 'name' => 'frontpageloggedin', 'value' => $CFG->frontpageloggedin ],
+ [ 'name' => 'maxcategorydepth', 'value' => $CFG->maxcategorydepth ],
+ [ 'name' => 'frontpagecourselimit', 'value' => $CFG->frontpagecourselimit ],
+ [ 'name' => 'numsections', 'value' => course_get_format($SITE)->get_last_section_number() ],
+ [ 'name' => 'newsitems', 'value' => $SITE->newsitems ],
+ [ 'name' => 'commentsperpage', 'value' => $CFG->commentsperpage ],
+ [ 'name' => 'sitepolicy', 'value' => $mysitepolicy ],
+ [ 'name' => 'sitepolicyhandler', 'value' => '' ],
+ [ 'name' => 'disableuserimages', 'value' => $CFG->disableuserimages ],
+ [ 'name' => 'mygradesurl', 'value' => user_mygrades_url()->out(false) ],
+ [ 'name' => 'tool_mobile_forcelogout', 'value' => 0 ],
+ [ 'name' => 'tool_mobile_customlangstrings', 'value' => '' ],
+ [ 'name' => 'tool_mobile_disabledfeatures', 'value' => '' ],
+ [ 'name' => 'tool_mobile_filetypeexclusionlist', 'value' => '' ],
+ [ 'name' => 'tool_mobile_custommenuitems', 'value' => '' ],
+ [ 'name' => 'tool_mobile_customusermenuitems', 'value' => '' ],
+ [ 'name' => 'tool_mobile_apppolicy', 'value' => '' ],
+ [ 'name' => 'tool_mobile_autologinmintimebetweenreq', 'value' => 6 * MINSECS ],
+ [ 'name' => 'tool_mobile_autologout', 'value' => get_config('tool_mobile', 'autologout') ],
+ [ 'name' => 'tool_mobile_autologouttime', 'value' => get_config('tool_mobile', 'autologouttime') ],
+ [ 'name' => 'calendartype', 'value' => $CFG->calendartype ],
+ [ 'name' => 'calendar_site_timeformat', 'value' => $CFG->calendar_site_timeformat ],
+ [ 'name' => 'calendar_startwday', 'value' => $CFG->calendar_startwday ],
+ [ 'name' => 'calendar_adminseesall', 'value' => $CFG->calendar_adminseesall ],
+ [ 'name' => 'calendar_lookahead', 'value' => $CFG->calendar_lookahead ],
+ [ 'name' => 'calendar_maxevents', 'value' => $CFG->calendar_maxevents ],
+ ];
$colornumbers = range(1, 10);
foreach ($colornumbers as $number) {
$expected[] = [
diff --git a/public/admin/tool/mobile/version.php b/public/admin/tool/mobile/version.php
index b8330efa391..aa53d539583 100644
--- a/public/admin/tool/mobile/version.php
+++ b/public/admin/tool/mobile/version.php
@@ -23,7 +23,7 @@
*/
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2025100600; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2025102200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025092600; // Requires this Moodle version.
$plugin->component = 'tool_mobile'; // Full name of the plugin (used for diagnostics).
$plugin->dependencies = [