From cd0c52a22fc364a2cac8be9543c453aa9621a6bb Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 29 Jan 2016 11:35:03 +0100 Subject: [PATCH 1/5] MOBILE-1158 course: Allow retrieving a module without courseid --- www/core/components/course/lang/en.json | 1 + www/core/components/course/services/course.js | 202 +++++++++++++++--- www/core/components/course/services/helper.js | 24 +++ 3 files changed, 196 insertions(+), 31 deletions(-) diff --git a/www/core/components/course/lang/en.json b/www/core/components/course/lang/en.json index cbe906345d2..78449400ca6 100644 --- a/www/core/components/course/lang/en.json +++ b/www/core/components/course/lang/en.json @@ -8,6 +8,7 @@ "couldnotloadsections": "Could not load the sections, please try again later.", "couldnotloadsectioncontent": "Could not load the section content, please try again later.", "errordownloadingsection": "Error downloading section.", + "errorgetmodule": "Error getting module data.", "gotothesite": "Go to the site", "nocontentavailable": "No content available at the moment.", "showall": "Show all", diff --git a/www/core/components/course/services/course.js b/www/core/components/course/services/course.js index d8028c3eb9e..d451b15fd81 100644 --- a/www/core/components/course/services/course.js +++ b/www/core/components/course/services/course.js @@ -33,7 +33,7 @@ angular.module('mm.core.course') * @ngdoc service * @name $mmCourse */ -.factory('$mmCourse', function($mmSite, $translate, $q, $log, $mmEvents, mmCoreEventCompletionModuleViewed) { +.factory('$mmCourse', function($mmSite, $translate, $q, $log, $mmEvents, $mmSitesManager, mmCoreEventCompletionModuleViewed) { $log = $log.getInstance('$mmCourse'); @@ -58,6 +58,40 @@ angular.module('mm.core.course') return module; } + /** + * Check if the site is prepared to return a module without having its course ID. + * + * @module mm.core.course + * @ngdoc method + * @name $mmCourse#canGetModuleWithoutCourseId + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if can return it, rejected or resolved with false otherwise. + */ + self.canGetModuleWithoutCourseId = function(siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + return site.wsAvailable('core_course_get_course_module'); + }); + }; + + /** + * Check if the site is prepared to return a module by instance ID. + * + * @module mm.core.course + * @ngdoc method + * @name $mmCourse#canGetModuleByInstance + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if can return it, rejected or resolved with false otherwise. + */ + self.canGetModuleByInstance = function(siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + return site.wsAvailable('core_course_get_course_module_by_instance'); + }); + }; + /** * Check if module completion could have changed. If it could have, trigger event. This function must be used, * for example, after calling a "module_view" WS since it can change the module completion. @@ -122,63 +156,155 @@ angular.module('mm.core.course') return 'mmCourse:activitiescompletion:' + courseid + ':' + userid; } + /** + * Gets a module basic info by module ID. + * + * @module mm.core.course + * @ngdoc method + * @name $mmCourse#getModuleBasicInfo + * @param {Number} moduleId Module ID. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with the module's info. + */ + self.getModuleBasicInfo = function(moduleId, siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + var params = { + cmid: moduleId + }, + preSets = { + cacheKey: getModuleCacheKey(moduleId) + }; + + return site.read('core_course_get_course_module', params, preSets).then(function(response) { + if (response.cm && (!response.warnings || !response.warnings.length)) { + return response.cm; + } + return $q.reject(); + }); + }); + }; + + /** + * Gets a module basic info by instance. + * + * @module mm.core.course + * @ngdoc method + * @name $mmCourse#getModuleBasicInfoByInstance + * @param {Number} id Instance ID. + * @param {String} module Name of the module. E.g. 'glossary'. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with the module's info. + */ + self.getModuleBasicInfoByInstance = function(id, module, siteId) { + siteId = siteId || $mmSite.getId(); + + return $mmSitesManager.getSite(siteId).then(function(site) { + var params = { + instance: id, + module: module + }, + preSets = { + cacheKey: getModuleByInstanceCacheKey(id, module) + }; + + return site.read('core_course_get_course_module_by_instance', params, preSets).then(function(response) { + if (response.cm && (!response.warnings || !response.warnings.length)) { + return response.cm; + } + return $q.reject(); + }); + }); + }; + /** * Get a module from Moodle. * * @module mm.core.course * @ngdoc method * @name $mmCourse#getModule - * @param {Number} courseid The course ID. - * @param {Number} moduleid The module ID. - * @param {Number} [sectionid] The section ID. + * @param {Number} moduleId The module ID. + * @param {Number} [courseId] The course ID. Recommended to speed up the process and minimize data usage. + * @param {Number} [sectionId] The section ID. * @return {Promise} */ - self.getModule = function(courseid, moduleid, sectionid) { + self.getModule = function(moduleId, courseId, sectionId) { - if (!moduleid) { + if (!moduleId) { return $q.reject(); } - $log.debug('Getting module ' + moduleid + ' in course ' + courseid + ' and section ' +sectionid); + var promise; - var params = { - courseid: courseid, + if (!courseId) { + // No courseId passed, try to retrieve it. + promise = self.getModuleBasicInfo(moduleId).then(function(module) { + return module.course; + }); + } else { + promise = $q.when(courseId); + } + + return promise.then(function(courseId) { + // We have courseId, we can use core_course_get_contents for compatibility. + $log.debug('Getting module ' + moduleId + ' in course ' + courseId); + + params = { + courseid: courseId, options: [ { name: 'cmid', - value: moduleid + value: moduleId } ] - }, + }; preSets = { - cacheKey: getModuleCacheKey(moduleid) + cacheKey: getModuleCacheKey(moduleId) }; - if (sectionid) { - params.options.push({ - name: 'sectionid', - value: sectionid - }); - } - - return $mmSite.read('core_course_get_contents', params, preSets).then(function(sections) { - var section, - module; + if (sectionId) { + params.options.push({ + name: 'sectionid', + value: sectionId + }); + } - for (var i = 0; i < sections.length; i++) { - section = sections[i]; - for (var j = 0; j < section.modules.length; j++) { - module = section.modules[j]; - if (module.id === moduleid) { - return addContentsIfNeeded(module); + return $mmSite.read('core_course_get_contents', params, preSets).catch(function() { + // Error getting the module. Try to get all contents (without filtering). + params.options = []; + preSets.cacheKey = getSectionsCacheKey(courseId); + return $mmSite.read('core_course_get_contents', params, preSets); + }).then(function(sections) { + var section, + module; + + for (var i = 0; i < sections.length; i++) { + section = sections[i]; + for (var j = 0; j < section.modules.length; j++) { + module = section.modules[j]; + if (module.id == moduleId) { + module.course = courseId; + return addContentsIfNeeded(module); + } } } - } - - return $q.reject(); + return $q.reject(); + }); }); }; + /** + * Get cache key for module WS calls. + * + * @param {Number} id Instance ID. + * @param {String} module Name of the module. E.g. 'glossary'. + * @return {String} Cache key. + */ + function getModuleByInstanceCacheKey(id, module) { + return 'mmCourse:moduleByInstance:' + module + ':' + id; + } + /** * Get cache key for module WS calls. * @@ -289,6 +415,20 @@ angular.module('mm.core.course') return $mmSite.invalidateWsCacheForKey(getModuleCacheKey(moduleid)); }; + /** + * Invalidates module WS call. + * + * @module mm.core.course + * @ngdoc method + * @name $mmCourse#invalidateModuleByInstance + * @param {Number} id Instance ID. + * @param {String} module Name of the module. E.g. 'glossary'. + * @return {Promise} Promise resolved when the data is invalidated. + */ + self.invalidateModuleByInstance = function(id, module) { + return $mmSite.invalidateWsCacheForKey(getModuleByInstanceCacheKey(id, module)); + }; + /** * Invalidates sections WS call. * diff --git a/www/core/components/course/services/helper.js b/www/core/components/course/services/helper.js index ecd035b84cc..be06f499469 100644 --- a/www/core/components/course/services/helper.js +++ b/www/core/components/course/services/helper.js @@ -167,6 +167,30 @@ angular.module('mm.core.course') }); }; + /** + * Get the course ID from a module, showing an error message if it can't be retrieved. + * + * @module mm.core.course + * @ngdoc method + * @name $mmCourseHelper#getModuleCourseId + * @param {Number} id Instance ID. + * @param {String} module Name of the module. E.g. 'glossary'. + * @param {String} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with the module's course ID. + */ + self.getModuleCourseIdByInstance = function(id, module, siteId) { + return $mmCourse.getModuleBasicInfoByInstance(id, module, siteId).then(function(cm) { + return cm.course; + }).catch(function(error) { + if (error) { + $mmUtil.showErrorModal(error); + } else { + $mmUtil.showErrorModal('mm.course.errorgetmodule', true); + } + return $q.reject(); + }); + }; + /** * Get the download ID of a section. It's used to interact with $mmCoursePrefetchDelegate. * From d9d43b7ca3f3c6374731631d7a4ac0c0c68e1724 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 29 Jan 2016 12:07:21 +0100 Subject: [PATCH 2/5] MOBILE-1158 splitview: Avoid params collision in split view --- www/addons/mod_forum/controllers/discussion.js | 2 +- www/addons/mod_forum/controllers/newdiscussion.js | 2 +- www/addons/mod_forum/main.js | 4 ++-- www/addons/mod_forum/templates/discussions.html | 4 ++-- www/addons/mod_glossary/controllers/entry.js | 2 +- www/addons/mod_glossary/main.js | 2 +- www/addons/mod_glossary/templates/index.html | 2 +- www/core/components/course/controllers/section.js | 2 +- www/core/components/course/main.js | 2 +- www/core/components/course/templates/sections.html | 2 +- www/core/directives/splitview.js | 12 ++++++++++++ www/core/directives/splitviewlink.js | 6 ++++++ 12 files changed, 30 insertions(+), 12 deletions(-) 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/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 @@