diff --git a/www/addons/files/services/files.js b/www/addons/files/services/files.js index b1f3c702abf..058c3a9b62e 100644 --- a/www/addons/files/services/files.js +++ b/www/addons/files/services/files.js @@ -26,8 +26,7 @@ angular.module('mm.addons.files') "itemid": 0, "filepath": "", "filename": "" - }, - moodle310version = 2016052300; + }; /** * Check if core_files_get_files WS call is available. @@ -429,8 +428,7 @@ angular.module('mm.addons.files') siteId = siteId || $mmSite.getId(); return $mmSitesManager.getSite(siteId).then(function(site) { - var version = parseInt(site.getInfo().version, 10); - return version && version >= moodle310version; + return site.isVersionGreaterEqualThan('3.1.0'); }); }; @@ -447,16 +445,12 @@ angular.module('mm.addons.files') siteId = siteId || $mmSite.getId(); return $mmSitesManager.getSite(siteId).then(function(site) { - var version = parseInt(site.getInfo().version, 10); - if (!version) { - // Cannot determine version, return false. - return false; - } else if (version == moodle310version) { - // Uploading is not working right now for Moodle 3.1.0 (2016052300). - return false; - } else if (version > moodle310version) { + if (site.isVersionGreaterEqualThan('3.1.1')) { // In Moodle 3.1.1 or higher we need a WS to move to private files. return self.canMoveFromDraftToPrivate(siteId); + } else if (site.isVersionGreaterEqualThan('3.1.0')) { + // Upload private files doesn't work for Moodle 3.1.0 due to a bug. + return false; } return true; diff --git a/www/addons/mod/assign/controllers/index.js b/www/addons/mod/assign/controllers/index.js index b8324bd8d12..2006a438cb1 100644 --- a/www/addons/mod/assign/controllers/index.js +++ b/www/addons/mod/assign/controllers/index.js @@ -111,7 +111,7 @@ angular.module('mm.addons.mod_assign') $scope.summary = response.gradingsummary; $scope.needsGradingAvalaible = response.gradingsummary.submissionsneedgradingcount > 0 && - parseInt($mmSite.getInfo().version, 10) >= 2016110200; + $mmSite.isVersionGreaterEqualThan('3.2'); }).catch(function() { // Fail silently (WS is not available, fallback). return $q.when(); diff --git a/www/addons/mod/assign/submission/onlinetext/handlers.js b/www/addons/mod/assign/submission/onlinetext/handlers.js index 0b104f86546..879d0a22f4d 100644 --- a/www/addons/mod/assign/submission/onlinetext/handlers.js +++ b/www/addons/mod/assign/submission/onlinetext/handlers.js @@ -137,11 +137,8 @@ angular.module('mm.addons.mod_assign') */ self.isEnabledForEdit = function() { // There's a bug in Moodle 3.1.0 that doesn't allow submitting HTML, so we'll disable this plugin in that case. - // Bug was fixed in 3.1.1 minor release (2016052301) and in master version 2016070700. - var version = parseInt($mmSite.getInfo().version, 10), - localMobileEnabled = $mmSite.checkIfAppUsesLocalMobile(); - - return (version >= 2016052301 && version < 2016052400) || version >= 2016070700 || localMobileEnabled; + // Bug was fixed in 3.1.1 minor release and in 3.2. + return $mmSite.isVersionGreaterEqualThan('3.1.1') || $mmSite.checkIfAppUsesLocalMobile(); }; /** diff --git a/www/addons/mod/book/services/book.js b/www/addons/mod/book/services/book.js index 15067896fc5..a237b482bf3 100644 --- a/www/addons/mod/book/services/book.js +++ b/www/addons/mod/book/services/book.js @@ -353,9 +353,7 @@ angular.module('mm.addons.mod_book') 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(); + return site.isVersionGreaterEqualThan('2.9') && site.canDownloadFiles(); }); }; diff --git a/www/addons/mod/forum/controllers/newdiscussion.js b/www/addons/mod/forum/controllers/newdiscussion.js index 678de7e4262..a44d244b354 100644 --- a/www/addons/mod/forum/controllers/newdiscussion.js +++ b/www/addons/mod/forum/controllers/newdiscussion.js @@ -59,8 +59,8 @@ angular.module('mm.addons.mod_forum') // We need to check which of the returned groups the user can post to. promise = validateVisibleGroups(forumgroups, refresh); } else { - // WS already filters groups, no need to do it ourselves. - promise = $q.when(forumgroups); + // WS already filters groups, no need to do it ourselves. Add "All participants" if needed. + promise = addAllParticipantsOption(forumgroups, true); } return promise.then(function(forumgroups) { @@ -135,8 +135,8 @@ angular.module('mm.addons.mod_forum') return false; }).then(function(canAdd) { if (canAdd) { - // The user can post to all groups, return them all. - return forumgroups; + // The user can post to all groups, add the "All participants" option and return them all. + return addAllParticipantsOption(forumgroups); } else { // The user can't post to all groups, let's check which groups he can post to. var promises = [], @@ -189,6 +189,37 @@ angular.module('mm.addons.mod_forum') return filtered; } + // Add the "All participants" option to a list of groups if the user can add a discussion to all participants. + function addAllParticipantsOption(groups, check) { + var promise; + + if (!$mmaModForum.isAllParticipantsFixed()) { + // All participants has a bug, don't add it. + return $q.when(groups); + } else if (check) { + // We need to check if the user can add a discussion to all participants. + promise = $mmaModForum.canAddDiscussionToAll(forumId).catch(function() { + // The call failed, let's assume he can't. + return false; + }); + } else { + // No need to check, assume the user can. + promise = $q.when(true); + } + + return promise.then(function(canAdd) { + if (canAdd) { + groups.unshift({ + courseid: courseId, + id: -1, + name: $translate.instant('mm.core.allparticipants') + }); + } + + return groups; + }); + } + fetchDiscussionData().finally(function() { $scope.groupsLoaded = true; }); diff --git a/www/addons/mod/forum/services/forum.js b/www/addons/mod/forum/services/forum.js index ecd775ae540..2210bfb3950 100644 --- a/www/addons/mod/forum/services/forum.js +++ b/www/addons/mod/forum/services/forum.js @@ -203,8 +203,7 @@ angular.module('mm.addons.mod_forum') self.canAddAttachments = function(siteId) { return $mmSitesManager.getSite(siteId).then(function(site) { // Attachments allowed from Moodle 3.1. - var version = parseInt(site.getInfo().version, 10); - return version && version >= 2016052300; + return site.isVersionGreaterEqualThan('3.1'); }); }; @@ -268,6 +267,18 @@ angular.module('mm.addons.mod_forum') return undefined; }; + /** + * There was a bug adding new discussions to All Participants (see MDL-57962). Check if it's fixed. + * + * @module mm.addons.mod_forum + * @ngdoc method + * @name $mmaModForum#isAllParticipantsFixed + * @return {Boolean} True if fixed, false otherwise. + */ + self.isAllParticipantsFixed = function() { + return $mmSite.isVersionGreaterEqualThan(['3.1.5', '3.2.2']); + }; + /** * Check if canAddDiscussion is available. * diff --git a/www/addons/mod/imscp/services/imscp.js b/www/addons/mod/imscp/services/imscp.js index c2acb71b9e1..4cdaed955b0 100644 --- a/www/addons/mod/imscp/services/imscp.js +++ b/www/addons/mod/imscp/services/imscp.js @@ -358,9 +358,7 @@ angular.module('mm.addons.mod_imscp') 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(); + return site.isVersionGreaterEqualThan('2.9') && site.canDownloadFiles(); }); }; diff --git a/www/addons/mod/wiki/services/wiki.js b/www/addons/mod/wiki/services/wiki.js index 52ed0a3fc97..5aaeffc061a 100644 --- a/www/addons/mod/wiki/services/wiki.js +++ b/www/addons/mod/wiki/services/wiki.js @@ -448,10 +448,8 @@ angular.module('mm.addons.mod_wiki') } if (lockonly) { - var version = $mmSite.getInfo().version; - // This parameter requires Moodle 3.2. It saves network usage. - if (version && parseInt(version, 10) >= 2016100700) { + if ($mmSite.isVersionGreaterEqualThan('3.2')) { params.lockonly = 1; } } diff --git a/www/core/components/course/services/course.js b/www/core/components/course/services/course.js index 8a22efce8b0..47924d8cda6 100644 --- a/www/core/components/course/services/course.js +++ b/www/core/components/course/services/course.js @@ -597,9 +597,7 @@ angular.module('mm.core.course') } return $mmSitesManager.getSite(siteId).then(function(site) { - var version = parseInt(site.getInfo().version, 10); - - if (version >= 2015051100) { + if (site.isVersionGreaterEqualThan('2.9')) { // From Moodle 2.9 the course contents can be filtered, so maybe the module doesn't have contents // because they were filtered. Try to get its contents. return self.getModule(module.id, courseId, sectionId, preferCache, ignoreCache, siteId).then(function(mod) { diff --git a/www/core/lib/site.js b/www/core/lib/site.js index 062a709ed77..cda8236e0f6 100644 --- a/www/core/lib/site.js +++ b/www/core/lib/site.js @@ -498,6 +498,32 @@ angular.module('mm.core') * Check if a certain feature is disabled in the site. */ + /** + * @module mm.core + * @ngdoc method + * @name $mmSite#isVersionGreaterEqualThan + * @param {Mixed} versions Version or list of versions to check. + * @return {Boolean} True if greater or equal, false otherwise. + * @description + * + * Check if the site version is greater than one or some versions. + * This function accepts a string or an array of strings. If array, the last version must be the highest. + * + * If a string is supplied (e.g. '3.2.1'), it will check if the site version is greater or equal than this version. + * + * If an array of versions is supplied, it will check if the site version is greater or equal than the last version, + * or if it's higher or equal than any of the other releases supplied but lower than the next major release. The last + * version of the array must be the highest version. + * For example, if the values supplied are ['3.0.5', '3.2.3', '3.3.1'] the function will return true if the site version + * is either: + * - Greater or equal than 3.3.1. + * - Greater or equal than 3.2.3 but lower than 3.3. + * - Greater or equal than 3.0.5 but lower than 3.1. + * + * This function only accepts versions from 2.4.0 and above. If any of the versions supplied isn't found, it will assume + * it's the last released major version. + */ + /** * @module mm.core * @ngdoc method diff --git a/www/core/lib/sitesfactory.js b/www/core/lib/sitesfactory.js index c8109eac0f1..c6336392318 100644 --- a/www/core/lib/sitesfactory.js +++ b/www/core/lib/sitesfactory.js @@ -236,7 +236,18 @@ angular.module('mm.core') "moodle_webservice_get_siteinfo": "core_webservice_get_site_info", }; - var self = {}; + var self = {}, + moodleReleases = { + '2.4': 2012120300, + '2.5': 2013051400, + '2.6': 2013111800, + '2.7': 2014051200, + '2.8': 2014111000, + '2.9': 2015051100, + '3.0': 2015111600, + '3.1': 2016052300, + '3.2': 2016120500 + }; /** * Site object to store site data. @@ -752,7 +763,7 @@ angular.module('mm.core') */ Site.prototype.uploadFile = function(uri, options) { if (!options.fileArea) { - if (parseInt(this.infos.version, 10) >= 2016052300) { + if (this.isVersionGreaterEqualThan('3.1')) { // From Moodle 3.1 only draft is allowed. options.fileArea = 'draft'; } else { @@ -1290,6 +1301,123 @@ angular.module('mm.core') return method; }; + /** + * Check if the site version is greater than one or some versions. + * This function accepts a string or an array of strings. If array, the last version must be the highest. + * + * @param {Mixed} versions Version or list of versions to check. + * @return {Boolean} True if greater or equal, false otherwise. + * @description + * If a string is supplied (e.g. '3.2.1'), it will check if the site version is greater or equal than this version. + * + * If an array of versions is supplied, it will check if the site version is greater or equal than the last version, + * or if it's higher or equal than any of the other releases supplied but lower than the next major release. The last + * version of the array must be the highest version. + * For example, if the values supplied are ['3.0.5', '3.2.3', '3.3.1'] the function will return true if the site version + * is either: + * - Greater or equal than 3.3.1. + * - Greater or equal than 3.2.3 but lower than 3.3. + * - Greater or equal than 3.0.5 but lower than 3.1. + * + * This function only accepts versions from 2.4.0 and above. If any of the versions supplied isn't found, it will assume + * it's the last released major version. + */ + Site.prototype.isVersionGreaterEqualThan = function(versions) { + var siteVersion = parseInt(this.getInfo().version, 10); + + if (angular.isArray(versions)) { + if (!versions.length) { + return false; + } + + for (var i = 0; i < versions.length; i++) { + var versionNumber = getVersionNumber(versions[i]); + if (i == versions.length - 1) { + // It's the last version, check only if site version is greater than this one. + return siteVersion >= versionNumber; + } else { + // Check if site version if bigger than this number but lesser than next major. + if (siteVersion >= versionNumber && siteVersion < getNextMajorVersionNumber(versions[i])) { + return true; + } + } + } + } else if (typeof versions == 'string') { + // Compare with this version. + return siteVersion >= getVersionNumber(versions); + } + + return false; + }; + + /** + * Get a version number from a release version. + * If release version is valid but not found in the list of Moodle releases, it will use the last released major version. + * + * @param {String} version Release version to convert to version number. + * @return {Number} Version number, 0 if invalid. + */ + function getVersionNumber(version) { + var data = getMajorAndMinor(version); + + if (!data) { + // Invalid version. + return 0; + } + + if (typeof moodleReleases[data.major] == 'undefined') { + // Major version not found. Use the last one. + data.major = Object.keys(moodleReleases).slice(-1); + } + + return moodleReleases[data.major] + data.minor; + } + + /** + * Given a release version, return the major and minor versions. + * + * @param {String} version Release version (e.g. '3.1.0'). + * @return {Object} Object with major and minor. Returns false if invalid version. + */ + function getMajorAndMinor(version) { + var match = version.match(/(\d)+(?:\.(\d)+)?(?:\.(\d)+)?/); + if (!match || !match[1]) { + // Invalid version. + return false; + } + + return { + major: match[1] + '.' + (match[2] || '0'), + minor: parseInt(match[3] || 0, 10) + }; + } + + /** + * Given a release version, return the next major version number. + * + * @param {String} version Release version (e.g. '3.1.0'). + * @return {Number} Next major version number. + */ + function getNextMajorVersionNumber(version) { + var data = getMajorAndMinor(version), + position, + releases = Object.keys(moodleReleases); + + if (!data) { + // Invalid version. + return 0; + } + + position = releases.indexOf(data.major); + + if (position == -1 || position == releases.length -1) { + // Major version not found or it's the last one. Use the last one. + return moodleReleases[releases[position]]; + } + + return moodleReleases[releases[position + 1]]; + } + /** * Get cache ID. * diff --git a/www/core/lib/webworkers.js b/www/core/lib/webworkers.js index 19c7c4f114a..1ab707642d0 100644 --- a/www/core/lib/webworkers.js +++ b/www/core/lib/webworkers.js @@ -36,7 +36,7 @@ angular.module('mm.core') * * Example usage: * - * if ($mmWebWorkers.isSupportedByDevice() && $mmWebWorkers.isSupportedInSite(site.getInfo().version)) { + * if ($mmWebWorkers.isSupportedByDevice() && $mmWebWorkers.isSupportedInSite(site)) { * $mmWebWorkers.startWorker(name, path, params).then(function() { * // Final message will be received in here. * }, function() { @@ -103,21 +103,20 @@ angular.module('mm.core') * @module mm.core * @ngdoc method * @name $mmWebWorkers#isSupportedInSite - * @param {Number} [version] The site version. If not defined, current site will be used. - * @return {Boolean} True if supported, false otherwise. + * @param {Object} [site] Site to check. If not defined, current site. + * @return {Boolean} True if supported, false otherwise. */ - self.isSupportedInSite = function(version) { - if (!version) { + self.isSupportedInSite = function(site) { + if (!site) { // We use injector to keep this service as independent as possible. - var site = $injector.get('$mmSite'); + site = $injector.get('$mmSite'); if (!site || !site.isLoggedIn()) { return false; } - version = site.getInfo().version; } // WebWorkers needs CORS enabled at the Moodle site, it is supported from 2.8. - return version >= 2014111000; + return site.isVersionGreaterEqualThan('2.8'); }; /**