From 23b0c4cd29799bc2530cdc851501f813963ae0ac Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 31 Mar 2016 15:16:02 +0200 Subject: [PATCH] MOBILE-1497 book: Fix files in folders and bug with same filename --- upgrade.txt | 4 + www/addons/mod_book/controllers/index.js | 5 +- www/addons/mod_book/services/book.js | 101 +++++++++++++++-------- 3 files changed, 72 insertions(+), 38 deletions(-) diff --git a/upgrade.txt b/upgrade.txt index 90e428ea849..b7b8ea3058b 100644 --- a/upgrade.txt +++ b/upgrade.txt @@ -1,6 +1,10 @@ This files describes API changes in the Moodle Mobile app, information provided here is intended especially for developers. +=== 2.10 === + + * The function $mmaModBook#getChapterContent now requires to receive the result of $mmaModBook#getContentsMap instead of module.contents. + === 2.9 === * Most of the functions from $mmaModScormOnline, $mmaModScormOffline, $mmaModScorm, $mmaModScormSync and $mmaModScormHelper now have a new param siteId to determine the site to affect. If you use any of these services please make sure you still pass the right parameters. diff --git a/www/addons/mod_book/controllers/index.js b/www/addons/mod_book/controllers/index.js index 467d804181a..bfcd7fe464b 100644 --- a/www/addons/mod_book/controllers/index.js +++ b/www/addons/mod_book/controllers/index.js @@ -27,7 +27,8 @@ angular.module('mm.addons.mod_book') var module = $stateParams.module || {}, courseid = $stateParams.courseid, - currentChapter; + currentChapter, + contentsMap = $mmaModBook.getContentsMap(module.contents); $scope.title = module.name; $scope.description = module.description; @@ -43,7 +44,7 @@ angular.module('mm.addons.mod_book') function loadChapter(chapterId) { currentChapter = chapterId; $ionicScrollDelegate.scrollTop(); - return $mmaModBook.getChapterContent(module.contents, chapterId, module.id).then(function(content) { + return $mmaModBook.getChapterContent(contentsMap, chapterId, module.id).then(function(content) { $scope.content = content; $scope.previousChapter = $mmaModBook.getPreviousChapter(chapters, chapterId); $scope.nextChapter = $mmaModBook.getNextChapter(chapters, chapterId); diff --git a/www/addons/mod_book/services/book.js b/www/addons/mod_book/services/book.js index 825c904b289..a6324cbaec3 100644 --- a/www/addons/mod_book/services/book.js +++ b/www/addons/mod_book/services/book.js @@ -232,48 +232,27 @@ angular.module('mm.addons.mod_book') * @module mm.addons.mod_book * @ngdoc method * @name $mmaModBook#getChapterContent - * @param {Object} contents The module contents. + * @param {Object} contentsMap Contents map returned by $mmaModBook#getContentsMap. * @param {String} chapterId Chapter to retrieve. * @param {Integer} moduleId The module ID. * @return {Promise} */ - self.getChapterContent = function(contents, chapterId, moduleId) { - var indexUrl, - paths = {}, + self.getChapterContent = function(contentsMap, chapterId, moduleId) { + var indexUrl = contentsMap[chapterId] ? contentsMap[chapterId].indexUrl : undefined, promise; - // Extract the information about paths from the module contents. - angular.forEach(contents, function(content) { - if (self.isFileDownloadable(content)) { - var key, - url = content.fileurl; - - if (!indexUrl && content.filename == 'index.html') { - // First chapter, we don't have a chapter id. - if (content.filepath == "/" + chapterId + "/") { - indexUrl = url; - } - } else { - key = content.filename; - paths[key] = url; - } - } - }); + if (!indexUrl) { + // If ever that happens. + $log.debug('Could not locate the index chapter'); + return $q.reject(); + } - // Promise handling when we are in a browser. - promise = (function() { - if (!indexUrl) { - // If ever that happens. - $log.debug('Could not locate the index chapter'); - return $q.reject(); - } else if ($mmFS.isAvailable()) { - // The file system is available. - return $mmFilepool.downloadUrl($mmSite.getId(), indexUrl, false, mmaModBookComponent, moduleId); - } else { - // We return the live URL. - return $q.when($mmSite.fixPluginfileURL(indexUrl)); - } - })(); + if ($mmFS.isAvailable()) { + promise = $mmFilepool.downloadUrl($mmSite.getId(), indexUrl, false, mmaModBookComponent, moduleId); + } else { + // We return the live URL. + return $q.when($mmSite.fixPluginfileURL(indexUrl)); + } return promise.then(function(url) { // Fetch the URL content. @@ -283,12 +262,62 @@ angular.module('mm.addons.mod_book') } else { // Now that we have the content, we update the SRC to point back to // the external resource. That will be caught by mm-format-text. - return $mmUtil.restoreSourcesInHtml(response.data, paths); + return $mmUtil.restoreSourcesInHtml(response.data, contentsMap[chapterId].paths); } }); }); }; + /** + * Convert an array of book contents into an object where contents are organized in chapters. + * Each chapter has an indexUrl and the list of contents in that chapter. + * + * @module mm.addons.mod_book + * @ngdoc method + * @name $mmaModBook#getContentsMap + * @param {Object} contents The module contents. + * @return {Object} Contents map. + */ + self.getContentsMap = function(contents) { + var map = {}; + + angular.forEach(contents, function(content) { + if (self.isFileDownloadable(content)) { + var chapter, + matches, + split, + filepathIsChapter; + + // Search the chapter number in the filepath. + matches = content.filepath.match(/\/(\d+)\//); + if (matches && matches[1]) { + chapter = matches[1]; + filepathIsChapter = content.filepath == '/' + chapter + '/'; + + // Init the chapter if it's not defined yet. + map[chapter] = map[chapter] || { paths: {} }; + + if (content.filename == 'index.html' && filepathIsChapter) { + map[chapter].indexUrl = content.fileurl; + } else { + if (filepathIsChapter) { + // It's a file in the root folder OR the WS isn't returning the filepath as it should (MDL-53671). + // Try to get the path to the file from the URL. + split = content.fileurl.split('mod_book/chapter' + content.filepath); + key = split[1] || content.filename; // Use filename if we couldn't find the path. + } else { + // Remove the chapter folder from the path and add the filename. + key = content.filepath.replace('/' + chapter + '/', '') + content.filename; + } + map[chapter].paths[key] = content.fileurl; + } + } + } + }); + + return map; + }; + /** * Invalidate the prefetched content. *