diff --git a/www/core/components/sidemenu/controllers/iframe.js b/www/core/components/sidemenu/controllers/iframe.js
new file mode 100644
index 00000000000..5f575fb9f90
--- /dev/null
+++ b/www/core/components/sidemenu/controllers/iframe.js
@@ -0,0 +1,27 @@
+// (C) Copyright 2015 Martin Dougiamas
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+angular.module('mm.core.sidemenu')
+
+/**
+ * Controller of the iframe viewer.
+ *
+ * @module mm.core.sidemenu
+ * @ngdoc controller
+ * @name mmSideMenuIframeViewCtrl
+ */
+.controller('mmSideMenuIframeViewCtrl', function($scope, $stateParams, $sce) {
+ $scope.title = $stateParams.title;
+ $scope.url = $sce.trustAsResourceUrl($stateParams.url);
+});
diff --git a/www/core/components/sidemenu/controllers/menu.js b/www/core/components/sidemenu/controllers/menu.js
index 5aef487ba79..d5795bb84f6 100644
--- a/www/core/components/sidemenu/controllers/menu.js
+++ b/www/core/components/sidemenu/controllers/menu.js
@@ -27,8 +27,7 @@ angular.module('mm.core.sidemenu')
$mmSideMenu.setScope($scope);
$scope.handlers = $mmSideMenuDelegate.getNavHandlers();
$scope.areNavHandlersLoaded = $mmSideMenuDelegate.areNavHandlersLoaded;
- $scope.siteinfo = $mmSite.getInfo();
- loadLogoutLabel();
+ loadSiteInfo();
$scope.logout = function() {
$mmSitesManager.logout().finally(function() {
@@ -40,25 +39,29 @@ angular.module('mm.core.sidemenu')
$scope.docsurl = docsurl;
});
+ function loadSiteInfo() {
+ var config = $mmSite.getStoredConfig();
+
+ $scope.siteinfo = $mmSite.getInfo();
+ $scope.logoutLabel = 'mm.sidemenu.' + (config && config.tool_mobile_forcelogout == "1" ? 'logout': 'changesite');
+
+ $mmSite.getDocsUrl().then(function(docsurl) {
+ $scope.docsurl = docsurl;
+ });
+
+ $mmSideMenu.getCustomMenuItems().then(function(items) {
+ $scope.customItems = items;
+ });
+ }
+
function updateSiteInfo() {
// We need to use $timeout to force a $digest and make $watch notice the variable change.
$scope.siteinfo = undefined;
$timeout(function() {
- $scope.siteinfo = $mmSite.getInfo();
- loadLogoutLabel();
-
- // Update docs URL, maybe the Moodle release has changed.
- $mmSite.getDocsUrl().then(function(docsurl) {
- $scope.docsurl = docsurl;
- });
+ loadSiteInfo();
});
}
- function loadLogoutLabel() {
- var config = $mmSite.getStoredConfig();
- $scope.logoutLabel = 'mm.sidemenu.' + (config && config.tool_mobile_forcelogout == "1" ? 'logout': 'changesite');
- }
-
var langObserver = $mmEvents.on(mmCoreEventLanguageChanged, updateSiteInfo);
var updateSiteObserver = $mmEvents.on(mmCoreEventSiteUpdated, function(siteid) {
if ($mmSite.getId() === siteid) {
diff --git a/www/core/components/sidemenu/main.js b/www/core/components/sidemenu/main.js
index 33e8a2a2e18..7391da33eaa 100644
--- a/www/core/components/sidemenu/main.js
+++ b/www/core/components/sidemenu/main.js
@@ -33,6 +33,20 @@ angular.module('mm.core.sidemenu', [])
$state.go('mm_login.init');
}
}
+ })
+
+ .state('site.iframe-view', {
+ url: '/iframe-view',
+ params: {
+ title: null,
+ url: null
+ },
+ views: {
+ 'site': {
+ templateUrl: 'core/components/sidemenu/templates/iframe.html',
+ controller: 'mmSideMenuIframeViewCtrl'
+ }
+ }
});
})
diff --git a/www/core/components/sidemenu/services/sidemenu.js b/www/core/components/sidemenu/services/sidemenu.js
index bf9f3cf3b21..871410137a9 100644
--- a/www/core/components/sidemenu/services/sidemenu.js
+++ b/www/core/components/sidemenu/services/sidemenu.js
@@ -21,12 +21,102 @@ angular.module('mm.core.sidemenu')
* @ngdoc service
* @name $mmSideMenu
*/
-.factory('$mmSideMenu', function($log) {
+.factory('$mmSideMenu', function($log, $mmLang, $mmSitesManager, mmCoreConfigConstants) {
$log = $log.getInstance('$mmSideMenu');
var self = {},
scope;
+ /**
+ * Get a list of custom menu items for a certain site.
+ *
+ * @module mm.core.sidemenu
+ * @ngdoc method
+ * @name $mmSideMenu#getCustomMenuItems
+ * @param {String} [siteId] Site ID. If not defined, current site.
+ * @return {Object[]} List of custom menu items.
+ */
+ self.getCustomMenuItems = function(siteId) {
+ return $mmSitesManager.getSite(siteId).then(function(site) {
+ var itemsString = site.getStoredConfig('tool_mobile_custommenuitems'),
+ items,
+ position = 0, // Position of each item, to keep the same order as it's configured.
+ map = {},
+ result = [];
+
+ if (!itemsString || typeof itemsString != 'string') {
+ // Setting not valid.
+ return result;
+ }
+
+ // Add items to the map.
+ items = itemsString.split(/(?:\r\n|\r|\n)/);
+ angular.forEach(items, function(item) {
+ var values = item.split('|'),
+ id,
+ label = values[0] ? values[0].trim() : values[0],
+ url = values[1] ? values[1].trim() : values[1],
+ type = values[2] ? values[2].trim() : values[2],
+ lang = (values[3] ? values[3].trim() : values[3]) || 'none',
+ icon = values[4] ? values[4].trim() : values[4];
+
+ if (!label || !url || !type) {
+ // Invalid item, ignore it.
+ return;
+ }
+
+ id = url + '#' + type;
+ if (!icon) {
+ // Icon not defined, use default one.
+ icon = type == 'embedded' ? 'ion-qr-scanner' : 'ion-link';
+ }
+
+ if (!map[id]) {
+ // New entry, add it to the map.
+ map[id] = {
+ url: url,
+ type: type,
+ position: position,
+ labels: {}
+ };
+ position++;
+ }
+
+ map[id].labels[lang.toLowerCase()] = {
+ label: label,
+ icon: icon
+ };
+ });
+
+ if (!position) {
+ // No valid items found, stop.
+ return result;
+ }
+
+ return $mmLang.getCurrentLanguage().then(function(currentLang) {
+ var fallbackLang = mmCoreConfigConstants.default_lang || 'en';
+
+ // Get the right label for each entry and add it to the result.
+ angular.forEach(map, function(entry) {
+ var data = entry.labels[currentLang] || entry.labels.none || entry.labels[fallbackLang];
+ if (!data) {
+ // No valid label found, get the first one.
+ data = entry.labels[Object.keys(entry.labels)[0]];
+ }
+
+ result[entry.position] = {
+ url: entry.url,
+ type: entry.type,
+ label: data.label,
+ icon: data.icon
+ };
+ });
+
+ return result;
+ });
+ });
+ };
+
/**
* Hide the right side menu.
*
diff --git a/www/core/components/sidemenu/templates/iframe.html b/www/core/components/sidemenu/templates/iframe.html
new file mode 100644
index 00000000000..dc6516e41f9
--- /dev/null
+++ b/www/core/components/sidemenu/templates/iframe.html
@@ -0,0 +1,6 @@
+