diff --git a/www/addons/grades/services/grades.js b/www/addons/grades/services/grades.js index 462c2ce4c37..007b0e18a0e 100644 --- a/www/addons/grades/services/grades.js +++ b/www/addons/grades/services/grades.js @@ -21,7 +21,7 @@ angular.module('mm.addons.grades') * @ngdoc service * @name $mmaGrades */ -.factory('$mmaGrades', function($q, $log, $mmSite, $mmText, $ionicPlatform, $translate, $mmCourse, $mmCourses) { +.factory('$mmaGrades', function($q, $log, $mmSite, $mmText, $ionicPlatform, $translate, $mmCourse, $mmCourses, $mmSitesManager) { $log = $log.getInstance('$mmaGrades'); @@ -185,15 +185,20 @@ angular.module('mm.addons.grades') }; /** - * Returns whether or not the plugin is enabled for the current site. + * Returns whether or not the plugin is enabled for a certain site. * * @module mm.addons.grades * @ngdoc method * @name $mmaGrades#isPluginEnabled - * @return {Boolean} True if plugin is enabled, false otherwise. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Boolean} True if plugin is enabled, false otherwise. */ - self.isPluginEnabled = function() { - return $mmSite.wsAvailable('gradereport_user_get_grades_table'); + self.isPluginEnabled = function(siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + return site.wsAvailable('gradereport_user_get_grades_table'); + }); }; /** @@ -202,15 +207,16 @@ angular.module('mm.addons.grades') * @module mm.addons.grades * @ngdoc method * @name $mmaGrades#isPluginEnabledForCourse - * @param {Number} courseId Course ID. - * @return {Promise} Promise resolved with true if plugin is enabled, rejected or resolved with false otherwise. + * @param {Number} courseId Course ID. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if plugin is enabled, rejected or resolved with false otherwise. */ - self.isPluginEnabledForCourse = function(courseId) { + self.isPluginEnabledForCourse = function(courseId, siteId) { if (!courseId) { return $q.reject(); } - return $mmCourses.getUserCourse(courseId, true).then(function(course) { + return $mmCourses.getUserCourse(courseId, true, siteId).then(function(course) { if (course && typeof course.showgrades != 'undefined' && !course.showgrades) { return false; } diff --git a/www/addons/grades/services/handlers.js b/www/addons/grades/services/handlers.js index 6e3ee8d0035..47597bc97e6 100644 --- a/www/addons/grades/services/handlers.js +++ b/www/addons/grades/services/handlers.js @@ -39,7 +39,7 @@ angular.module('mm.addons.grades') /** * Check if handler is enabled. * - * @return {Boolean} True if handler is enabled, false otherwise. + * @return {Promise} Promise resolved with true if handler is enabled, false otherwise. */ self.isEnabled = function() { return $mmaGrades.isPluginEnabled(); @@ -104,7 +104,7 @@ angular.module('mm.addons.grades') /** * Check if handler is enabled. * - * @return {Boolean} True if handler is enabled, false otherwise. + * @return {Promise} Promise resolved with true if handler is enabled, false otherwise. */ self.isEnabled = function() { return $mmaGrades.isPluginEnabled(); @@ -167,37 +167,54 @@ angular.module('mm.addons.grades') var self = {}; /** - * Whether or not the handler is enabled for the site. + * Whether or not the handler is enabled for a certain site and course. * - * @return {Boolean} + * @param {String} siteId Site ID. + * @param {Number} courseId Course ID. + * @return {Promise} Promise resolved with true if enabled. */ - self.isEnabled = function() { - return $mmaGrades.isPluginEnabled(); - }; + function isEnabled(siteId, courseId) { + return $mmaGrades.isPluginEnabled(siteId).then(function(enabled) { + if (enabled) { + return $mmaGrades.isPluginEnabledForCourse(courseId, siteId); + } + }); + } /** * Get actions to perform with the link. * - * @param {String} url URL to treat. - * @return {Object[]} List of actions. See {@link $mmContentLinksDelegate#registerLinkHandler}. + * @param {String[]} siteIds Site IDs the URL belongs to. + * @param {String} url URL to treat. + * @return {Object[]} Promise resolved with the list of actions. + * See {@link $mmContentLinksDelegate#registerLinkHandler}. */ - self.getActions = function(url) { + self.getActions = function(siteIds, url) { // Check it's a grade URL. if (url.indexOf('/grade/report/user/index.php') > -1) { var params = $mmUtil.extractUrlParams(url); if (typeof params.id != 'undefined') { - // Return actions. - return [{ - message: 'mm.core.view', - icon: 'ion-eye', - action: function(siteId) { - var stateParams = { - course: {id: parseInt(params.id, 10)}, - userid: parseInt(params.userid, 10) - }; - $mmContentLinksHelper.goInSite('site.grades', stateParams, siteId); + var courseId = parseInt(params.id, 10); + // Pass false because all sites should have the same siteurl. + return $mmContentLinksHelper.filterSupportedSites(siteIds, isEnabled, false, courseId).then(function(ids) { + if (!ids.length) { + return []; + } else { + // Return actions. + return [{ + message: 'mm.core.view', + icon: 'ion-eye', + sites: ids, + action: function(siteId) { + var stateParams = { + course: {id: courseId}, + userid: parseInt(params.userid, 10) + }; + $mmContentLinksHelper.goInSite('site.grades', stateParams, siteId); + } + }]; } - }]; + }); } } return []; diff --git a/www/addons/messages/services/handlers.js b/www/addons/messages/services/handlers.js index 6faeb1fb02f..de96d529b89 100644 --- a/www/addons/messages/services/handlers.js +++ b/www/addons/messages/services/handlers.js @@ -293,62 +293,73 @@ angular.module('mm.addons.messages') var self = {}; /** - * Whether or not the handler is enabled for the site. + * Whether or not the handler is enabled for a certain site. * - * @return {Boolean} + * @param {String} siteId Site ID. + * @return {Promise} Promise resolved with true if enabled. */ - self.isEnabled = function() { - return $mmaMessages.isPluginEnabled(); - }; + function isEnabledForSite(siteId) { + return $mmaMessages.isPluginEnabled(siteId); + } /** * Get actions to perform with the link. * - * @param {String} url URL to treat. - * @return {Object[]} List of actions. See {@link $mmContentLinksDelegate#registerLinkHandler}. + * @param {String[]} siteIds Site IDs the URL belongs to. + * @param {String} url URL to treat. + * @return {Object[]} Promise resolved with the list of actions. + * See {@link $mmContentLinksDelegate#registerLinkHandler}. */ - self.getActions = function(url) { + self.getActions = function(siteIds, url) { // Check it's a messages URL. if (url.indexOf('/message/index.php') > -1) { - var params = $mmUtil.extractUrlParams(url); - // Return actions. - return [{ - message: 'mm.core.view', - icon: 'ion-eye', - action: function(siteId) { - var stateName, - stateParams; - - if (typeof params.user1 != 'undefined' && typeof params.user2 != 'undefined') { - // Check if the current user is in the conversation. - if ($mmSite.getUserId() == params.user1) { - stateName = 'site.messages-discussion'; - stateParams = {userId: parseInt(params.user2, 10)}; - } else if ($mmSite.getUserId() == params.user2) { - stateName = 'site.messages-discussion'; - stateParams = {userId: parseInt(params.user1, 10)}; - } else { - // He isn't, open in browser. - $mmUtil.openInBrowser(url); - return; + // Pass false because all sites should have the same siteurl. + return $mmContentLinksHelper.filterSupportedSites(siteIds, isEnabledForSite, false).then(function(ids) { + if (!ids.length) { + return []; + } else { + // Return actions. + var params = $mmUtil.extractUrlParams(url); + return [{ + message: 'mm.core.view', + icon: 'ion-eye', + sites: ids, + action: function(siteId) { + var stateName, + stateParams; + + if (typeof params.user1 != 'undefined' && typeof params.user2 != 'undefined') { + // Check if the current user is in the conversation. + if ($mmSite.getUserId() == params.user1) { + stateName = 'site.messages-discussion'; + stateParams = {userId: parseInt(params.user2, 10)}; + } else if ($mmSite.getUserId() == params.user2) { + stateName = 'site.messages-discussion'; + stateParams = {userId: parseInt(params.user1, 10)}; + } else { + // He isn't, open in browser. + $mmUtil.openInBrowser(url); + return; + } + } else if (typeof params.id != 'undefined') { + stateName = 'site.messages-discussion'; + stateParams = {userId: parseInt(params.id, 10)}; + } + + if (!stateName) { + // Go to messaging index page. We use redirect state to view the side menu. + $state.go('redirect', { + siteid: siteId, + state: 'site.messages', + params: {} + }); + } else { + $mmContentLinksHelper.goInSite(stateName, stateParams, siteId); + } } - } else if (typeof params.id != 'undefined') { - stateName = 'site.messages-discussion'; - stateParams = {userId: parseInt(params.id, 10)}; - } - - if (!stateName) { - // Go to messaging index page. We use redirect state to view the side menu. - $state.go('redirect', { - siteid: siteId, - state: 'site.messages', - params: {} - }); - } else { - $mmContentLinksHelper.goInSite(stateName, stateParams, siteId); - } + }]; } - }]; + }); } return []; }; diff --git a/www/addons/messages/services/messages.js b/www/addons/messages/services/messages.js index 0c0fe8cbad5..581aa2b896c 100644 --- a/www/addons/messages/services/messages.js +++ b/www/addons/messages/services/messages.js @@ -595,26 +595,30 @@ angular.module('mm.addons.messages') * @return {Promise} Resolved when enabled, otherwise rejected. * @protected */ - self._isMessagingEnabled = function() { - var enabled = $mmSite.canUseAdvancedFeature('messaging', 'unknown'); - - if (enabled === 'unknown') { - // On older version we cannot check other than calling a WS. If the request - // fails there is a very high chance that messaging is disabled. - $log.debug('Using WS call to check if messaging is enabled.'); - return $mmSite.read('core_message_search_contacts', { - searchtext: 'CheckingIfMessagingIsEnabled', - onlymycourses: 0 - }, { - emergencyCache: false, - cacheKey: self._getCacheKeyForEnabled() - }); - } + self._isMessagingEnabled = function(siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + var enabled = site.canUseAdvancedFeature('messaging', 'unknown'); + + if (enabled === 'unknown') { + // On older version we cannot check other than calling a WS. If the request + // fails there is a very high chance that messaging is disabled. + $log.debug('Using WS call to check if messaging is enabled.'); + return site.read('core_message_search_contacts', { + searchtext: 'CheckingIfMessagingIsEnabled', + onlymycourses: 0 + }, { + emergencyCache: false, + cacheKey: self._getCacheKeyForEnabled() + }); + } - if (enabled) { - return $q.when(true); - } - return $q.reject(); + if (enabled) { + return true; + } + return $q.reject(); + }); }; /** @@ -648,30 +652,30 @@ angular.module('mm.addons.messages') }; /** - * Returns whether or not the plugin is enabled for the current site. + * Returns whether or not the plugin is enabled in a certain site. * * Do not abuse this method. * * @module mm.addons.messages * @ngdoc method * @name $mmaMessages#isPluginEnabled - * @return {Promise} Rejected when not enabled. - */ - self.isPluginEnabled = function() { - var infos, - enabled = $q.when(true); - - if (!$mmSite.isLoggedIn()) { - enabled = $q.reject(); - } else if (!$mmSite.canUseAdvancedFeature('messaging')) { - enabled = $q.reject(); - } else if (!$mmSite.wsAvailable('core_message_get_messages')) { - enabled = $q.reject(); - } else { - enabled = self._isMessagingEnabled(); - } + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if enabled, rejected or resolved with false otherwise. + */ + self.isPluginEnabled = function(siteId) { + siteId = siteId || $mmSite.getId(); - return enabled; + return $mmSitesManager.getSite(siteId).then(function(site) { + if (!site.canUseAdvancedFeature('messaging')) { + return false; + } else if (!site.wsAvailable('core_message_get_messages')) { + return false; + } else { + return self._isMessagingEnabled(siteId).then(function() { + return true; + }); + } + }); }; /** diff --git a/www/addons/mod_assign/services/assign.js b/www/addons/mod_assign/services/assign.js index 5317ef7e1ac..71e1970e8a9 100644 --- a/www/addons/mod_assign/services/assign.js +++ b/www/addons/mod_assign/services/assign.js @@ -21,7 +21,7 @@ angular.module('mm.addons.mod_assign') * @ngdoc controller * @name $mmaModAssign */ -.factory('$mmaModAssign', function($mmSite, $q, $mmUser) { +.factory('$mmaModAssign', function($mmSite, $q, $mmUser, $mmSitesManager) { var self = {}; /** @@ -179,15 +179,20 @@ angular.module('mm.addons.mod_assign') }; /** - * Check if assignments plugin is enabled. + * Check if assignments plugin is enabled in a certain site. * * @module mm.addons.mod_assign * @ngdoc method * @name $mmaModAssign#isPluginEnabled - * @return {Boolean} True if plugin is enabled, false otherwise. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if plugin is enabled, rejected or resolved with false otherwise. */ - self.isPluginEnabled = function() { - return $mmSite.wsAvailable('mod_assign_get_assignments') && $mmSite.wsAvailable('mod_assign_get_submissions'); + self.isPluginEnabled = function(siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + return site.wsAvailable('mod_assign_get_assignments') && site.wsAvailable('mod_assign_get_submissions'); + }); }; return self; diff --git a/www/addons/mod_assign/services/handlers.js b/www/addons/mod_assign/services/handlers.js index 15a378d04a0..860cc5da45f 100644 --- a/www/addons/mod_assign/services/handlers.js +++ b/www/addons/mod_assign/services/handlers.js @@ -21,7 +21,7 @@ angular.module('mm.addons.mod_assign') * @ngdoc service * @name $mmaModAssignHandlers */ -.factory('$mmaModAssignHandlers', function($mmCourse, $mmaModAssign, $state, $mmSite) { +.factory('$mmaModAssignHandlers', function($mmCourse, $mmaModAssign, $state, $q, $mmContentLinksHelper) { var self = {}; /** @@ -38,7 +38,7 @@ angular.module('mm.addons.mod_assign') /** * Whether or not the handler is enabled for the site. * - * @return {Boolean} + * @return {Promise} */ self.isEnabled = function() { return $mmaModAssign.isPluginEnabled(); @@ -56,8 +56,10 @@ angular.module('mm.addons.mod_assign') $scope.title = module.name; $scope.icon = $mmCourse.getModuleIconSrc('assign'); $scope.action = function(e) { - e.preventDefault(); - e.stopPropagation(); + if (e) { + e.preventDefault(); + e.stopPropagation(); + } $state.go('site.mod_assign', {module: module, courseid: courseid}); }; }; @@ -78,40 +80,36 @@ angular.module('mm.addons.mod_assign') var self = {}; /** - * Whether or not the handler is enabled for the site. + * Whether or not the handler is enabled for a certain site. * - * @return {Boolean} + * @param {String} siteId Site ID. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with true if enabled. */ - self.isEnabled = function() { - return $mmaModAssign.isPluginEnabled(); - }; + function isEnabled(siteId, courseId) { + return $mmaModAssign.isPluginEnabled(siteId).then(function(enabled) { + if (!enabled) { + return false; + } + return courseId || $mmCourse.canGetModuleWithoutCourseId(siteId); + }); + } /** * Get actions to perform with the link. * + * @param {String[]} siteIds Site IDs the URL belongs to. * @param {String} url URL to treat. - * @param {Number} [courseid] Course ID related to the URL. - * @return {Object[]} List of actions. See {@link $mmContentLinksDelegate#registerLinkHandler}. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with the list of actions. + * See {@link $mmContentLinksDelegate#registerLinkHandler}. */ - self.getActions = function(url, courseid) { - // Check it's an assign URL from the current site. - if (courseid && $mmSite.containsUrl(url) && url.indexOf('/mod/assign/') > -1) { - var matches = url.match(/view\.php\?id=(\d*)/); // Get assignment ID. - if (matches && typeof matches[1] != 'undefined') { - // Return actions. - return [{ - message: 'mm.core.view', - icon: 'ion-eye', - action: function() { - $state.go('site.mod_assign', { - courseid: courseid, - module: {id: matches[1]} - }); - } - }]; - } + self.getActions = function(siteIds, url, courseId) { + // Check it's an assign URL. + if (url.indexOf('/mod/assign/view.php') > -1) { + return $mmContentLinksHelper.treatModuleIndexUrl(siteIds, url, isEnabled, courseId); } - return []; + return $q.when([]); }; return self; diff --git a/www/addons/mod_book/main.js b/www/addons/mod_book/main.js index 009d2a61178..b4f9029a35e 100644 --- a/www/addons/mod_book/main.js +++ b/www/addons/mod_book/main.js @@ -36,7 +36,10 @@ angular.module('mm.addons.mod_book', ['mm.core']) }) -.config(function($mmCourseDelegateProvider, $mmCoursePrefetchDelegateProvider) { - $mmCourseDelegateProvider.registerContentHandler('mmaModBook', 'book', '$mmaModBookCourseContentHandler'); +.config(function($mmCourseDelegateProvider, $mmCoursePrefetchDelegateProvider, $mmContentLinksDelegateProvider) { + $mmCourseDelegateProvider.registerContentHandler('mmaModBook', 'book', '$mmaModBookHandlers.courseContentHandler'); $mmCoursePrefetchDelegateProvider.registerPrefetchHandler('mmaModBook', 'book', '$mmaModBookPrefetchHandler'); + + // Register content links handler. + $mmContentLinksDelegateProvider.registerLinkHandler('mmaModBook', '$mmaModBookHandlers.linksHandler'); }); diff --git a/www/addons/mod_book/services/book.js b/www/addons/mod_book/services/book.js index eb486e6592b..ea467b9dcd9 100644 --- a/www/addons/mod_book/services/book.js +++ b/www/addons/mod_book/services/book.js @@ -21,7 +21,7 @@ angular.module('mm.addons.mod_book') * @ngdoc service * @name $mmaModBook */ -.factory('$mmaModBook', function($mmFilepool, $mmSite, $mmFS, $http, $log, $q, mmaModBookComponent) { +.factory('$mmaModBook', function($mmFilepool, $mmSite, $mmFS, $http, $log, $q, $mmSitesManager, mmaModBookComponent) { $log = $log.getInstance('$mmaModBook'); var self = {}; @@ -339,12 +339,17 @@ angular.module('mm.addons.mod_book') * @module mm.addons.mod_book * @ngdoc method * @name $mmaModBook#isPluginEnabled - * @return {Boolean} True if plugin is enabled, false otherwise. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if plugin is enabled, rejected or resolved with false otherwise. */ - self.isPluginEnabled = function() { - var version = $mmSite.getInfo().version; - // Require Moodle 2.9. - return version && (parseInt(version) >= 2015051100) && $mmSite.canDownloadFiles(); + self.isPluginEnabled = function(siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + var version = site.getInfo().version; + // Require Moodle 2.9. + return version && (parseInt(version) >= 2015051100) && site.canDownloadFiles(); + }); }; /** diff --git a/www/addons/mod_book/services/course_content_handler.js b/www/addons/mod_book/services/course_content_handler.js deleted file mode 100644 index 9407802ffb9..00000000000 --- a/www/addons/mod_book/services/course_content_handler.js +++ /dev/null @@ -1,130 +0,0 @@ -// (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.addons.mod_book') - -/** - * Mod book course content handler. - * - * @module mm.addons.mod_book - * @ngdoc service - * @name $mmaModBookCourseContentHandler - */ -.factory('$mmaModBookCourseContentHandler', function($mmCourse, $mmaModBook, $mmEvents, $state, $mmSite, $mmUtil, $mmFilepool, - $mmCoursePrefetchDelegate, mmCoreDownloading, mmCoreNotDownloaded, mmCoreOutdated, mmCoreDownloaded, - mmCoreEventPackageStatusChanged, mmaModBookComponent) { - - var self = {}; - - /** - * Whether or not the module is enabled for the site. - * - * @module mm.addons.mod_book - * @ngdoc method - * @name $mmaModBookCourseContentHandler#isEnabled - * @return {Boolean} - */ - self.isEnabled = function() { - return $mmaModBook.isPluginEnabled(); - }; - - /** - * Get the controller. - * - * @module mm.addons.mod_book - * @ngdoc method - * @name $mmaModBookCourseContentHandler#getController - * @param {Object} module The module info. - * @param {Number} courseid The course ID. - * @return {Function} - */ - self.getController = function(module, courseid) { - return function($scope) { - var downloadBtn, - refreshBtn, - revision = $mmFilepool.getRevisionFromFileList(module.contents), - timemodified = $mmFilepool.getTimemodifiedFromFileList(module.contents); - - downloadBtn = { - hidden: true, - icon: 'ion-ios-cloud-download-outline', - label: 'mm.core.download', - action: function(e) { - e.preventDefault(); - e.stopPropagation(); - $mmaModBook.prefetchContent(module).catch(function() { - if (!$scope.$$destroyed) { - $mmUtil.showErrorModal('mm.core.errordownloading', true); - } - }); - } - }; - - refreshBtn = { - icon: 'ion-android-refresh', - label: 'mm.core.refresh', - hidden: true, - action: function(e) { - e.preventDefault(); - e.stopPropagation(); - - $mmaModBook.invalidateContent(module.id).finally(function() { - $mmaModBook.prefetchContent(module).catch(function() { - if (!$scope.$$destroyed) { - $mmUtil.showErrorModal('mm.core.errordownloading', true); - } - }); - }); - } - }; - - $scope.title = module.name; - $scope.icon = $mmCourse.getModuleIconSrc('book'); - $scope.buttons = [downloadBtn, refreshBtn]; - $scope.spinner = false; - - $scope.action = function(e) { - e.preventDefault(); - e.stopPropagation(); - $state.go('site.mod_book', {module: module, courseid: courseid}); - }; - - // Show buttons according to module status. - function showStatus(status) { - if (status) { - $scope.spinner = status === mmCoreDownloading; - downloadBtn.hidden = status !== mmCoreNotDownloaded; - // Always show refresh button if a book is downloaded because revision and timemodified aren't reliable. - refreshBtn.hidden = status !== mmCoreOutdated && status !== mmCoreDownloaded; - } - } - - // Listen for changes on this module status. - var statusObserver = $mmEvents.on(mmCoreEventPackageStatusChanged, function(data) { - if (data.siteid === $mmSite.getId() && data.componentId === module.id && data.component === mmaModBookComponent) { - showStatus(data.status); - } - }); - - // Get current status to decide which icon should be shown. - $mmCoursePrefetchDelegate.getModuleStatus(module, courseid, revision, timemodified).then(showStatus); - - $scope.$on('$destroy', function() { - statusObserver && statusObserver.off && statusObserver.off(); - }); - }; - }; - - return self; -}); diff --git a/www/addons/mod_book/services/handlers.js b/www/addons/mod_book/services/handlers.js new file mode 100644 index 00000000000..79c6208c974 --- /dev/null +++ b/www/addons/mod_book/services/handlers.js @@ -0,0 +1,186 @@ +// (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.addons.mod_book') + +/** + * Mod book handlers. + * + * @module mm.addons.mod_book + * @ngdoc service + * @name $mmaModBookHandlers + */ +.factory('$mmaModBookHandlers', function($mmCourse, $mmaModBook, $mmEvents, $state, $mmSite, $mmUtil, $mmFilepool, + $mmCoursePrefetchDelegate, mmCoreDownloading, mmCoreNotDownloaded, mmCoreOutdated, mmCoreDownloaded, + mmCoreEventPackageStatusChanged, mmaModBookComponent, $mmContentLinksHelper, $q) { + + var self = {}; + + /** + * Course content handler. + * + * @module mm.addons.mod_book + * @ngdoc method + * @name $mmaModBookHandlers#courseContentHandler + */ + self.courseContentHandler = function() { + var self = {}; + + /** + * Whether or not the module is enabled for the site. + * + * @return {Boolean} + */ + self.isEnabled = function() { + return $mmaModBook.isPluginEnabled(); + }; + + /** + * Get the controller. + * + * @param {Object} module The module info. + * @param {Number} courseid The course ID. + * @return {Function} + */ + self.getController = function(module, courseid) { + return function($scope) { + var downloadBtn, + refreshBtn, + revision = $mmFilepool.getRevisionFromFileList(module.contents), + timemodified = $mmFilepool.getTimemodifiedFromFileList(module.contents); + + downloadBtn = { + hidden: true, + icon: 'ion-ios-cloud-download-outline', + label: 'mm.core.download', + action: function(e) { + e.preventDefault(); + e.stopPropagation(); + $mmaModBook.prefetchContent(module).catch(function() { + if (!$scope.$$destroyed) { + $mmUtil.showErrorModal('mm.core.errordownloading', true); + } + }); + } + }; + + refreshBtn = { + icon: 'ion-android-refresh', + label: 'mm.core.refresh', + hidden: true, + action: function(e) { + e.preventDefault(); + e.stopPropagation(); + + $mmaModBook.invalidateContent(module.id).finally(function() { + $mmaModBook.prefetchContent(module).catch(function() { + if (!$scope.$$destroyed) { + $mmUtil.showErrorModal('mm.core.errordownloading', true); + } + }); + }); + } + }; + + $scope.title = module.name; + $scope.icon = $mmCourse.getModuleIconSrc('book'); + $scope.buttons = [downloadBtn, refreshBtn]; + $scope.spinner = false; + + $scope.action = function(e) { + if (e) { + e.preventDefault(); + e.stopPropagation(); + } + $state.go('site.mod_book', {module: module, courseid: courseid}); + }; + + // Show buttons according to module status. + function showStatus(status) { + if (status) { + $scope.spinner = status === mmCoreDownloading; + downloadBtn.hidden = status !== mmCoreNotDownloaded; + // Always show refresh button if a book is downloaded because revision and timemodified aren't reliable. + refreshBtn.hidden = status !== mmCoreOutdated && status !== mmCoreDownloaded; + } + } + + // Listen for changes on this module status. + var statusObserver = $mmEvents.on(mmCoreEventPackageStatusChanged, function(data) { + if (data.siteid === $mmSite.getId() && data.componentId === module.id && data.component === mmaModBookComponent) { + showStatus(data.status); + } + }); + + // Get current status to decide which icon should be shown. + $mmCoursePrefetchDelegate.getModuleStatus(module, courseid, revision, timemodified).then(showStatus); + + $scope.$on('$destroy', function() { + statusObserver && statusObserver.off && statusObserver.off(); + }); + }; + }; + + return self; + }; + + /** + * Content links handler. + * + * @module mm.addons.mod_book + * @ngdoc method + * @name $mmaModBookHandlers#linksHandler + */ + self.linksHandler = function() { + + var self = {}; + + /** + * Whether or not the handler is enabled for a certain site. + * + * @param {String} siteId Site ID. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with true if enabled. + */ + function isEnabled(siteId, courseId) { + return $mmaModBook.isPluginEnabled(siteId).then(function(enabled) { + if (!enabled) { + return false; + } + return courseId || $mmCourse.canGetModuleWithoutCourseId(siteId); + }); + } + + /** + * Get actions to perform with the link. + * + * @param {String[]} siteIds Site IDs the URL belongs to. + * @param {String} url URL to treat. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with the list of actions. + * See {@link $mmContentLinksDelegate#registerLinkHandler}. + */ + self.getActions = function(siteIds, url, courseId) { + // Check it's a book URL. + if (url.indexOf('/mod/book/view.php') > -1) { + return $mmContentLinksHelper.treatModuleIndexUrl(siteIds, url, isEnabled, courseId); + } + return $q.when([]); + }; + + return self; + }; + + return self; +}); diff --git a/www/addons/mod_chat/main.js b/www/addons/mod_chat/main.js index d8a28a69dbb..b0c0eb041cd 100644 --- a/www/addons/mod_chat/main.js +++ b/www/addons/mod_chat/main.js @@ -51,6 +51,7 @@ angular.module('mm.addons.mod_chat', []) }) -.config(function($mmCourseDelegateProvider) { - $mmCourseDelegateProvider.registerContentHandler('mmaModChat', 'chat', '$mmaModChatCourseContentHandler'); +.config(function($mmCourseDelegateProvider, $mmContentLinksDelegateProvider) { + $mmCourseDelegateProvider.registerContentHandler('mmaModChat', 'chat', '$mmaModChatHandlers.courseContent'); + $mmContentLinksDelegateProvider.registerLinkHandler('mmaModChat', '$mmaModChatHandlers.linksHandler'); }); \ No newline at end of file diff --git a/www/addons/mod_chat/services/chat.js b/www/addons/mod_chat/services/chat.js index ad4d2490cde..330974b295b 100644 --- a/www/addons/mod_chat/services/chat.js +++ b/www/addons/mod_chat/services/chat.js @@ -21,24 +21,29 @@ angular.module('mm.addons.mod_chat') * @ngdoc service * @name $mmaModChat */ -.factory('$mmaModChat', function($q, $mmSite, $mmUser) { +.factory('$mmaModChat', function($q, $mmSite, $mmUser, $mmSitesManager) { var self = {}; /** - * Return whether or not the plugin is enabled. Plugin is enabled if the chat WS are available. + * Return whether or not the plugin is enabled in a certain site. Plugin is enabled if the chat WS are available. * * @module mm.addons.mod_chat * @ngdoc method * @name $mmaModChat#isPluginEnabled - * @return {Boolean} True if plugin is enabled, false otherwise. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if plugin is enabled, rejected or resolved with false otherwise. */ - self.isPluginEnabled = function() { - return $mmSite.wsAvailable('mod_chat_get_chats_by_courses') && - $mmSite.wsAvailable('mod_chat_login_user') && - $mmSite.wsAvailable('mod_chat_get_chat_users') && - $mmSite.wsAvailable('mod_chat_send_chat_message') && - $mmSite.wsAvailable('mod_chat_get_chat_latest_messages'); + self.isPluginEnabled = function(siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + return site.wsAvailable('mod_chat_get_chats_by_courses') && + site.wsAvailable('mod_chat_login_user') && + site.wsAvailable('mod_chat_get_chat_users') && + site.wsAvailable('mod_chat_send_chat_message') && + site.wsAvailable('mod_chat_get_chat_latest_messages'); + }); }; /** diff --git a/www/addons/mod_chat/services/course_content_handler.js b/www/addons/mod_chat/services/course_content_handler.js deleted file mode 100644 index eebde75f2f8..00000000000 --- a/www/addons/mod_chat/services/course_content_handler.js +++ /dev/null @@ -1,60 +0,0 @@ -// (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.addons.mod_chat') - -/** - * Mod chat course content handler. - * - * @module mm.addons.mod_chat - * @ngdoc service - * @name $mmaModChatCourseContentHandler - */ -.factory('$mmaModChatCourseContentHandler', function($mmCourse, $mmaModChat, $state) { - var self = {}; - - /** - * Whether or not the module is enabled for the site. - * - * @module mm.addons.mod_chat - * @ngdoc method - * @name $mmaModChatCourseContentHandler#isEnabled - * @return {Boolean} - */ - self.isEnabled = function() { - return $mmaModChat.isPluginEnabled(); - }; - - /** - * Get the controller. - * - * @module mm.addons.mod_chat - * @ngdoc method - * @name $mmaModChatCourseContentHandler#isEnabled - * @param {Object} module The module info. - * @param {Number} courseid The course ID. - * @return {Function} - */ - self.getController = function(module, courseid) { - return function($scope) { - $scope.title = module.name; - $scope.icon = $mmCourse.getModuleIconSrc('chat'); - $scope.action = function(e) { - $state.go('site.mod_chat', {module: module, courseid: courseid}); - }; - }; - }; - - return self; -}); \ No newline at end of file diff --git a/www/addons/mod_chat/services/handlers.js b/www/addons/mod_chat/services/handlers.js new file mode 100644 index 00000000000..426feb0baa8 --- /dev/null +++ b/www/addons/mod_chat/services/handlers.js @@ -0,0 +1,114 @@ +// (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.addons.mod_chat') + +/** + * Mod chat handlers. + * + * @module mm.addons.mod_chat + * @ngdoc service + * @name $mmaModChatHandlers + */ +.factory('$mmaModChatHandlers', function($mmCourse, $mmaModChat, $state, $mmContentLinksHelper, $q) { + var self = {}; + + /** + * Course content handler. + * + * @module mm.addons.mod_chat + * @ngdoc method + * @name $mmaModChatHandlers#courseContent + */ + self.courseContent = function() { + var self = {}; + + /** + * Whether or not the module is enabled for the site. + * + * @return {Boolean} + */ + self.isEnabled = function() { + return $mmaModChat.isPluginEnabled(); + }; + + /** + * Get the controller. + * + * @param {Object} module The module info. + * @param {Number} courseid The course ID. + * @return {Function} + */ + self.getController = function(module, courseid) { + return function($scope) { + $scope.title = module.name; + $scope.icon = $mmCourse.getModuleIconSrc('chat'); + $scope.action = function(e) { + $state.go('site.mod_chat', {module: module, courseid: courseid}); + }; + }; + }; + + return self; + }; + + /** + * Content links handler. + * + * @module mm.addons.mod_chat + * @ngdoc method + * @name $mmaModChatHandlers#linksHandler + */ + self.linksHandler = function() { + + var self = {}; + + /** + * Whether or not the handler is enabled for a certain site. + * + * @param {String} siteId Site ID. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with true if enabled. + */ + function isEnabled(siteId, courseId) { + return $mmaModChat.isPluginEnabled(siteId).then(function(enabled) { + if (!enabled) { + return false; + } + return courseId || $mmCourse.canGetModuleWithoutCourseId(siteId); + }); + } + + /** + * Get actions to perform with the link. + * + * @param {String[]} siteIds Site IDs the URL belongs to. + * @param {String} url URL to treat. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with the list of actions. + * See {@link $mmContentLinksDelegate#registerLinkHandler}. + */ + self.getActions = function(siteIds, url, courseId) { + // Check it's a chat URL. + if (url.indexOf('/mod/chat/view.php') > -1) { + return $mmContentLinksHelper.treatModuleIndexUrl(siteIds, url, isEnabled, courseId); + } + return $q.when([]); + }; + + return self; + }; + + return self; +}); \ No newline at end of file diff --git a/www/addons/mod_choice/main.js b/www/addons/mod_choice/main.js index 282280a1b8c..b09e001bed3 100644 --- a/www/addons/mod_choice/main.js +++ b/www/addons/mod_choice/main.js @@ -39,6 +39,7 @@ angular.module('mm.addons.mod_choice', []) }) -.config(function($mmCourseDelegateProvider) { - $mmCourseDelegateProvider.registerContentHandler('mmaModChoice', 'choice', '$mmaModChoiceCourseContentHandler'); +.config(function($mmCourseDelegateProvider, $mmContentLinksDelegateProvider) { + $mmCourseDelegateProvider.registerContentHandler('mmaModChoice', 'choice', '$mmaModChoiceHandlers.courseContent'); + $mmContentLinksDelegateProvider.registerLinkHandler('mmaModChoice', '$mmaModChoiceHandlers.linksHandler'); }); diff --git a/www/addons/mod_choice/services/choice.js b/www/addons/mod_choice/services/choice.js index 7bf766336bd..f136dd1b356 100644 --- a/www/addons/mod_choice/services/choice.js +++ b/www/addons/mod_choice/services/choice.js @@ -21,7 +21,7 @@ angular.module('mm.addons.mod_choice') * @ngdoc service * @name $mmaModChoice */ -.factory('$mmaModChoice', function($q, $mmSite, mmaModChoiceResultsAfterAnswer, mmaModChoiceResultsAfterClose, +.factory('$mmaModChoice', function($q, $mmSite, $mmSitesManager, mmaModChoiceResultsAfterAnswer, mmaModChoiceResultsAfterClose, mmaModChoiceResultsAlways) { var self = {}; @@ -108,18 +108,23 @@ angular.module('mm.addons.mod_choice') }; /** - * Return whether or not the plugin is enabled. Plugin is enabled if the choice WS are available. + * Return whether or not the plugin is enabled in a certain site. Plugin is enabled if the choice WS are available. * * @module mm.addons.mod_choice * @ngdoc method * @name $mmaModChoice#isPluginEnabled - * @return {Boolean} True if plugin is enabled, false otherwise. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if plugin is enabled, rejected or resolved with false otherwise. */ - self.isPluginEnabled = function() { - return $mmSite.wsAvailable('mod_choice_get_choice_options') && - $mmSite.wsAvailable('mod_choice_get_choice_results') && - $mmSite.wsAvailable('mod_choice_get_choices_by_courses') && - $mmSite.wsAvailable('mod_choice_submit_choice_response'); + self.isPluginEnabled = function(siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + return site.wsAvailable('mod_choice_get_choice_options') && + site.wsAvailable('mod_choice_get_choice_results') && + site.wsAvailable('mod_choice_get_choices_by_courses') && + site.wsAvailable('mod_choice_submit_choice_response'); + }); }; /** diff --git a/www/addons/mod_choice/services/course_content_handler.js b/www/addons/mod_choice/services/course_content_handler.js deleted file mode 100644 index b4796d57262..00000000000 --- a/www/addons/mod_choice/services/course_content_handler.js +++ /dev/null @@ -1,60 +0,0 @@ -// (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.addons.mod_choice') - -/** - * Mod forum course content handler. - * - * @module mm.addons.mod_forum - * @ngdoc service - * @name $mmaModForumCourseContentHandler - */ -.factory('$mmaModChoiceCourseContentHandler', function($mmCourse, $mmaModChoice, $state) { - var self = {}; - - /** - * Whether or not the module is enabled for the site. - * - * @module mm.addons.mod_forum - * @ngdoc method - * @name $mmaModForumCourseContentHandler#isEnabled - * @return {Boolean} - */ - self.isEnabled = function() { - return $mmaModChoice.isPluginEnabled(); - }; - - /** - * Get the controller. - * - * @module mm.addons.mod_forum - * @ngdoc method - * @name $mmaModForumCourseContentHandler#isEnabled - * @param {Object} module The module info. - * @param {Number} courseid The course ID. - * @return {Function} - */ - self.getController = function(module, courseid) { - return function($scope) { - $scope.title = module.name; - $scope.icon = $mmCourse.getModuleIconSrc('choice'); - $scope.action = function(e) { - $state.go('site.mod_choice', {module: module, courseid: courseid}); - }; - }; - }; - - return self; -}); diff --git a/www/addons/mod_choice/services/handlers.js b/www/addons/mod_choice/services/handlers.js new file mode 100644 index 00000000000..e0baf57e4a1 --- /dev/null +++ b/www/addons/mod_choice/services/handlers.js @@ -0,0 +1,115 @@ +// (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.addons.mod_choice') + +/** + * Mod choice handlers. + * + * @module mm.addons.mod_choice + * @ngdoc service + * @name $mmaModChoiceHandlers + */ +.factory('$mmaModChoiceHandlers', function($mmCourse, $mmaModChoice, $state, $mmContentLinksHelper, $q) { + var self = {}; + + /** + * Course content handler. + * + * @module mm.addons.mod_choice + * @ngdoc method + * @name $mmaModChoiceHandlers#courseContent + */ + self.courseContent = function() { + + var self = {}; + + /** + * Whether or not the module is enabled for the site. + * + * @return {Boolean} + */ + self.isEnabled = function() { + return $mmaModChoice.isPluginEnabled(); + }; + + /** + * Get the controller. + * + * @param {Object} module The module info. + * @param {Number} courseid The course ID. + * @return {Function} + */ + self.getController = function(module, courseid) { + return function($scope) { + $scope.title = module.name; + $scope.icon = $mmCourse.getModuleIconSrc('choice'); + $scope.action = function(e) { + $state.go('site.mod_choice', {module: module, courseid: courseid}); + }; + }; + }; + + return self; + }; + + /** + * Content links handler. + * + * @module mm.addons.mod_choice + * @ngdoc method + * @name $mmaModChoiceHandlers#linksHandler + */ + self.linksHandler = function() { + + var self = {}; + + /** + * Whether or not the handler is enabled for a certain site. + * + * @param {String} siteId Site ID. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with true if enabled. + */ + function isEnabled(siteId, courseId) { + return $mmaModChoice.isPluginEnabled(siteId).then(function(enabled) { + if (!enabled) { + return false; + } + return courseId || $mmCourse.canGetModuleWithoutCourseId(siteId); + }); + } + + /** + * Get actions to perform with the link. + * + * @param {String[]} siteIds Site IDs the URL belongs to. + * @param {String} url URL to treat. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with the list of actions. + * See {@link $mmContentLinksDelegate#registerLinkHandler}. + */ + self.getActions = function(siteIds, url, courseId) { + // Check it's a choice URL. + if (url.indexOf('/mod/choice/view.php') > -1) { + return $mmContentLinksHelper.treatModuleIndexUrl(siteIds, url, isEnabled, courseId); + } + return $q.when([]); + }; + + return self; + }; + + return self; +}); diff --git a/www/addons/mod_folder/controllers/index.js b/www/addons/mod_folder/controllers/index.js index 1b50c04af51..cfe3771e76e 100644 --- a/www/addons/mod_folder/controllers/index.js +++ b/www/addons/mod_folder/controllers/index.js @@ -42,7 +42,7 @@ angular.module('mm.addons.mod_folder') // Convenience function to fetch folder data from Moodle. function fetchFolder() { - return $mmCourse.getModule(courseid, module.id, sectionid).then(function(module) { + return $mmCourse.getModule(module.id, courseid, sectionid).then(function(module) { showModuleData(module); }, function(error) { if (error) { diff --git a/www/addons/mod_folder/main.js b/www/addons/mod_folder/main.js index 364f7e05678..ba4369de32b 100644 --- a/www/addons/mod_folder/main.js +++ b/www/addons/mod_folder/main.js @@ -38,7 +38,8 @@ angular.module('mm.addons.mod_folder', ['mm.core']) }) -.config(function($mmCourseDelegateProvider, $mmCoursePrefetchDelegateProvider) { - $mmCourseDelegateProvider.registerContentHandler('mmaModFolder', 'folder', '$mmaModFolderCourseContentHandler'); +.config(function($mmCourseDelegateProvider, $mmCoursePrefetchDelegateProvider, $mmContentLinksDelegateProvider) { + $mmCourseDelegateProvider.registerContentHandler('mmaModFolder', 'folder', '$mmaModFolderHandlers.courseContent'); $mmCoursePrefetchDelegateProvider.registerPrefetchHandler('mmaModFolder', 'folder', '$mmaModFolderPrefetchHandler'); + $mmContentLinksDelegateProvider.registerLinkHandler('mmaModFolder', '$mmaModFolderHandlers.linksHandler'); }); diff --git a/www/addons/mod_folder/services/course_content_handler.js b/www/addons/mod_folder/services/course_content_handler.js deleted file mode 100644 index 9589ce44f56..00000000000 --- a/www/addons/mod_folder/services/course_content_handler.js +++ /dev/null @@ -1,121 +0,0 @@ -// (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.addons.mod_folder') - -/** - * Mod Folder course content handler. - * - * @module mm.addons.mod_folder - * @ngdoc service - * @name $mmaModFolderCourseContentHandler - */ -.factory('$mmaModFolderCourseContentHandler', function($mmCourse, $mmaModFolder, $mmEvents, $state, $mmSite, $mmUtil, $mmFilepool, - $mmCoursePrefetchDelegate, mmCoreDownloading, mmCoreNotDownloaded, mmCoreOutdated, mmCoreEventPackageStatusChanged, - mmaModFolderComponent) { - var self = {}; - - /** - * Whether or not the module is enabled for the site. - * - * @module mm.addons.mod_folder - * @ngdoc method - * @name $mmaModFolderCourseContentHandler#isEnabled - * @return {Boolean} - */ - self.isEnabled = function() { - return true; - }; - - /** - * Get the controller. - * - * @module mm.addons.mod_folder - * @ngdoc method - * @name $mmaModFolderCourseContentHandler#getController - * @param {Object} module The module info. - * @param {Number} courseid Course ID. - * @param {Number} sectionid Section ID. - * @return {Function} - */ - self.getController = function(module, courseid, sectionid) { - return function($scope) { - var downloadBtn, - refreshBtn, - revision = $mmFilepool.getRevisionFromFileList(module.contents), - timemodified = $mmFilepool.getTimemodifiedFromFileList(module.contents); - - // Prefetch folder contents. - function prefetchFolder(e) { - e.preventDefault(); - e.stopPropagation(); - $mmaModFolder.prefetchContent(module).catch(function() { - if (!$scope.$$destroyed) { - $mmUtil.showErrorModal('mm.core.errordownloading', true); - } - }); - } - - downloadBtn = { - hidden: true, - icon: 'ion-ios-cloud-download-outline', - label: 'mm.core.download', - action: prefetchFolder - }; - - refreshBtn = { - hidden: true, - icon: 'ion-android-refresh', - label: 'mm.core.refresh', - action: prefetchFolder - }; - - $scope.icon = $mmCourse.getModuleIconSrc('folder'); - $scope.title = module.name; - $scope.buttons = [downloadBtn, refreshBtn]; - $scope.spinner = false; - - $scope.action = function(e) { - e.preventDefault(); - e.stopPropagation(); - $state.go('site.mod_folder', {module: module, courseid: courseid, sectionid: sectionid}); - }; - - // Show buttons according to module status. - function showStatus(status) { - if (status) { - $scope.spinner = status === mmCoreDownloading; - downloadBtn.hidden = status !== mmCoreNotDownloaded; - refreshBtn.hidden = status !== mmCoreOutdated; - } - } - - // Listen for changes on this module status. - var statusObserver = $mmEvents.on(mmCoreEventPackageStatusChanged, function(data) { - if (data.siteid === $mmSite.getId() && data.componentId === module.id && data.component === mmaModFolderComponent) { - showStatus(data.status); - } - }); - - // Get current status to decide which icon should be shown. - $mmCoursePrefetchDelegate.getModuleStatus(module, courseid, revision, timemodified).then(showStatus); - - $scope.$on('$destroy', function() { - statusObserver && statusObserver.off && statusObserver.off(); - }); - }; - }; - - return self; -}); diff --git a/www/addons/mod_folder/services/handlers.js b/www/addons/mod_folder/services/handlers.js new file mode 100644 index 00000000000..472f74d7790 --- /dev/null +++ b/www/addons/mod_folder/services/handlers.js @@ -0,0 +1,181 @@ +// (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.addons.mod_folder') + +/** + * Mod Folder handlers. + * + * @module mm.addons.mod_folder + * @ngdoc service + * @name $mmaModFolderHandlers + */ +.factory('$mmaModFolderHandlers', function($mmCourse, $mmaModFolder, $mmEvents, $state, $mmSite, $mmUtil, $mmFilepool, + $mmCoursePrefetchDelegate, mmCoreDownloading, mmCoreNotDownloaded, mmCoreOutdated, mmCoreEventPackageStatusChanged, + mmaModFolderComponent, $mmContentLinksHelper, $q) { + var self = {}; + + /** + * Course content handler. + * + * @module mm.addons.mod_folder + * @ngdoc method + * @name $mmaModFolderHandlers#courseContent + */ + self.courseContent = function() { + var self = {}; + + /** + * Whether or not the module is enabled for the site. + * + * @module mm.addons.mod_folder + * @ngdoc method + * @name $mmaModFolderCourseContentHandler#isEnabled + * @return {Boolean} + */ + self.isEnabled = function() { + return true; + }; + + /** + * Get the controller. + * + * @module mm.addons.mod_folder + * @ngdoc method + * @name $mmaModFolderCourseContentHandler#getController + * @param {Object} module The module info. + * @param {Number} courseid Course ID. + * @param {Number} sectionid Section ID. + * @return {Function} + */ + self.getController = function(module, courseid, sectionid) { + return function($scope) { + var downloadBtn, + refreshBtn, + revision = $mmFilepool.getRevisionFromFileList(module.contents), + timemodified = $mmFilepool.getTimemodifiedFromFileList(module.contents); + + // Prefetch folder contents. + function prefetchFolder(e) { + e.preventDefault(); + e.stopPropagation(); + $mmaModFolder.prefetchContent(module).catch(function() { + if (!$scope.$$destroyed) { + $mmUtil.showErrorModal('mm.core.errordownloading', true); + } + }); + } + + downloadBtn = { + hidden: true, + icon: 'ion-ios-cloud-download-outline', + label: 'mm.core.download', + action: prefetchFolder + }; + + refreshBtn = { + hidden: true, + icon: 'ion-android-refresh', + label: 'mm.core.refresh', + action: prefetchFolder + }; + + $scope.icon = $mmCourse.getModuleIconSrc('folder'); + $scope.title = module.name; + $scope.buttons = [downloadBtn, refreshBtn]; + $scope.spinner = false; + + $scope.action = function(e) { + if (e) { + e.preventDefault(); + e.stopPropagation(); + } + $state.go('site.mod_folder', {module: module, courseid: courseid, sectionid: sectionid}); + }; + + // Show buttons according to module status. + function showStatus(status) { + if (status) { + $scope.spinner = status === mmCoreDownloading; + downloadBtn.hidden = status !== mmCoreNotDownloaded; + refreshBtn.hidden = status !== mmCoreOutdated; + } + } + + // Listen for changes on this module status. + var statusObserver = $mmEvents.on(mmCoreEventPackageStatusChanged, function(data) { + if (data.siteid === $mmSite.getId() && data.componentId === module.id && data.component === mmaModFolderComponent) { + showStatus(data.status); + } + }); + + // Get current status to decide which icon should be shown. + $mmCoursePrefetchDelegate.getModuleStatus(module, courseid, revision, timemodified).then(showStatus); + + $scope.$on('$destroy', function() { + statusObserver && statusObserver.off && statusObserver.off(); + }); + }; + }; + + return self; + }; + + /** + * Content links handler. + * + * @module mm.addons.mod_folder + * @ngdoc method + * @name $mmaModFolderHandlers#linksHandler + */ + self.linksHandler = function() { + + var self = {}; + + /** + * Whether or not the handler is enabled for a certain site. + * + * @param {String} siteId Site ID. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with true if enabled. + */ + function isEnabled(siteId, courseId) { + if (courseId) { + return $q.when(true); + } + return $mmCourse.canGetModuleWithoutCourseId(siteId); + } + + /** + * Get actions to perform with the link. + * + * @param {String[]} siteIds Site IDs the URL belongs to. + * @param {String} url URL to treat. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with the list of actions. + * See {@link $mmContentLinksDelegate#registerLinkHandler}. + */ + self.getActions = function(siteIds, url, courseId) { + // Check it's a folder URL. + if (url.indexOf('/mod/folder/view.php') > -1) { + return $mmContentLinksHelper.treatModuleIndexUrl(siteIds, url, isEnabled, courseId); + } + return $q.when([]); + }; + + return self; + }; + + return self; +}); diff --git a/www/addons/mod_forum/controllers/discussion.js b/www/addons/mod_forum/controllers/discussion.js index 81ae46aef59..637ee87e085 100644 --- a/www/addons/mod_forum/controllers/discussion.js +++ b/www/addons/mod_forum/controllers/discussion.js @@ -25,7 +25,7 @@ angular.module('mm.addons.mod_forum') $ionicScrollDelegate, mmaModForumComponent) { var discussionid = $stateParams.discussionid, - courseid = $stateParams.courseid, + courseid = $stateParams.cid, scrollView; $scope.component = mmaModForumComponent; diff --git a/www/addons/mod_forum/controllers/newdiscussion.js b/www/addons/mod_forum/controllers/newdiscussion.js index 4f1b78d6379..2402fe1c845 100644 --- a/www/addons/mod_forum/controllers/newdiscussion.js +++ b/www/addons/mod_forum/controllers/newdiscussion.js @@ -24,7 +24,7 @@ angular.module('mm.addons.mod_forum') .controller('mmaModForumNewDiscussionCtrl', function($scope, $stateParams, $mmGroups, $q, $mmaModForum, $mmEvents, $ionicPlatform, $mmUtil, $ionicHistory, $translate, mmaModForumNewDiscussionEvent) { - var courseid = $stateParams.courseid, + var courseid = $stateParams.cid, forumid = $stateParams.forumid, cmid = $stateParams.cmid; diff --git a/www/addons/mod_forum/main.js b/www/addons/mod_forum/main.js index e77578960d6..c75054f1f74 100644 --- a/www/addons/mod_forum/main.js +++ b/www/addons/mod_forum/main.js @@ -40,7 +40,7 @@ angular.module('mm.addons.mod_forum', []) url: '/mod_forum-discussion', params: { discussionid: null, - courseid: null + cid: null // Not naming it courseid because it collides with 'site.mod_forum' param in split-view. }, views: { 'site': { @@ -53,7 +53,7 @@ angular.module('mm.addons.mod_forum', []) .state('site.mod_forum-newdiscussion', { url: '/mod_forum-newdiscussion', params: { - courseid: null, + cid: null, // Not naming it courseid because it collides with 'site.mod_forum' param in split-view. forumid: null, cmid: null }, diff --git a/www/addons/mod_forum/services/forum.js b/www/addons/mod_forum/services/forum.js index d4eb9886d76..7791f39cc3c 100644 --- a/www/addons/mod_forum/services/forum.js +++ b/www/addons/mod_forum/services/forum.js @@ -21,7 +21,7 @@ angular.module('mm.addons.mod_forum') * @ngdoc controller * @name $mmaModForum */ -.factory('$mmaModForum', function($q, $mmSite, $mmUser, $mmGroups, $translate, mmaModForumDiscPerPage) { +.factory('$mmaModForum', function($q, $mmSite, $mmUser, $mmGroups, $translate, $mmSitesManager, mmaModForumDiscPerPage) { var self = {}; /** @@ -194,17 +194,22 @@ angular.module('mm.addons.mod_forum') }; /** - * Return whether or not the plugin is enabled. Plugin is enabled if the forum WS are available. + * Return whether or not the plugin is enabled in a certain site. Plugin is enabled if the forum WS are available. * * @module mm.addons.mod_forum * @ngdoc method * @name $mmaModForum#isPluginEnabled - * @return {Boolean} True if plugin is enabled, false otherwise. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if plugin is enabled, rejected or resolved with false otherwise. */ - self.isPluginEnabled = function() { - return $mmSite.wsAvailable('mod_forum_get_forums_by_courses') && - $mmSite.wsAvailable('mod_forum_get_forum_discussions_paginated') && - $mmSite.wsAvailable('mod_forum_get_forum_discussion_posts'); + self.isPluginEnabled = function(siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + return site.wsAvailable('mod_forum_get_forums_by_courses') && + site.wsAvailable('mod_forum_get_forum_discussions_paginated') && + site.wsAvailable('mod_forum_get_forum_discussion_posts'); + }); }; /** diff --git a/www/addons/mod_forum/services/handlers.js b/www/addons/mod_forum/services/handlers.js index 91c737a2e80..58391e98dde 100644 --- a/www/addons/mod_forum/services/handlers.js +++ b/www/addons/mod_forum/services/handlers.js @@ -21,7 +21,7 @@ angular.module('mm.addons.mod_forum') * @ngdoc service * @name $mmaModForumHandlers */ -.factory('$mmaModForumHandlers', function($mmCourse, $mmaModForum, $state, $mmSite) { +.factory('$mmaModForumHandlers', function($mmCourse, $mmaModForum, $state, $mmUtil, $mmContentLinksHelper, $q) { var self = {}; /** @@ -61,8 +61,10 @@ angular.module('mm.addons.mod_forum') $scope.title = module.name; $scope.icon = $mmCourse.getModuleIconSrc('forum'); $scope.action = function(e) { - e.preventDefault(); - e.stopPropagation(); + if (e) { + e.preventDefault(); + e.stopPropagation(); + } $state.go('site.mod_forum', {module: module, courseid: courseid}); }; }; @@ -83,40 +85,73 @@ angular.module('mm.addons.mod_forum') var self = {}; /** - * Whether or not the handler is enabled for the site. + * Whether or not the handler is enabled for a certain site. * - * @return {Boolean} + * @param {String} siteId Site ID. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with true if enabled. */ - self.isEnabled = function() { - return $mmaModForum.isPluginEnabled(); - }; + function isIndexEnabled(siteId, courseId) { + return $mmaModForum.isPluginEnabled(siteId).then(function(enabled) { + if (!enabled) { + return false; + } + return courseId || $mmCourse.canGetModuleWithoutCourseId(siteId); + }); + } + + /** + * Whether or not the handler is enabled for a certain site. + * + * @param {String} siteId Site ID. + * @return {Promise} Promise resolved with true if enabled. + */ + function isDiscEnabled(siteId) { + // We don't check courseId because it's only needed for user profile links, we can afford not passing it. + return $mmaModForum.isPluginEnabled(siteId); + } /** * Get actions to perform with the link. * + * @param {String[]} siteIds Site IDs the URL belongs to. * @param {String} url URL to treat. - * @param {Number} [courseid] Course ID related to the URL. - * @return {Object[]} List of actions. See {@link $mmContentLinksDelegate#registerLinkHandler}. + * @param {Number} [courseId] Course ID related to the URL. + * @return {Promise} Promise resolved with the list of actions. + * See {@link $mmContentLinksDelegate#registerLinkHandler}. */ - self.getActions = function(url, courseid) { - // Check it's a forum URL from the current site. - if (courseid && $mmSite.containsUrl(url) && url.indexOf('/mod/forum/') > -1) { - var matches = url.match(/discuss\.php\?d=([^#]*)/); // Get discussion ID. - if (matches && typeof matches[1] != 'undefined') { - // Return actions. - return [{ - message: 'mm.core.view', - icon: 'ion-eye', - action: function() { - $state.go('site.mod_forum-discussion', { - courseid: courseid, - discussionid: matches[1] - }); + self.getActions = function(siteIds, url, courseId) { + // Check it's a forum URL. + if (url.indexOf('/mod/forum/view.php') > -1) { + // Forum index. + return $mmContentLinksHelper.treatModuleIndexUrl(siteIds, url, isIndexEnabled, courseId); + } else if (url.indexOf('/mod/forum/discuss.php') > -1) { + // Forum discussion. + var params = $mmUtil.extractUrlParams(url); + if (params.d != 'undefined') { + // Pass false because all sites should have the same siteurl. + return $mmContentLinksHelper.filterSupportedSites(siteIds, isDiscEnabled, false, courseId).then(function(ids) { + if (!ids.length) { + return []; + } else { + // Return actions. + return [{ + message: 'mm.core.view', + icon: 'ion-eye', + sites: ids, + action: function(siteId) { + var stateParams = { + discussionid: parseInt(params.d, 10), + cid: courseId + }; + $mmContentLinksHelper.goInSite('site.mod_forum-discussion', stateParams, siteId); + } + }]; } - }]; + }); } } - return []; + return $q.when([]); }; return self; diff --git a/www/addons/mod_forum/templates/discussions.html b/www/addons/mod_forum/templates/discussions.html index 2d8d4ca5bfe..42636254b2a 100644 --- a/www/addons/mod_forum/templates/discussions.html +++ b/www/addons/mod_forum/templates/discussions.html @@ -11,12 +11,12 @@