@@ -33,7 +33,7 @@ angular.module('mm.core.course')
3333 * @ngdoc service
3434 * @name $mmCourse
3535 */
36- . factory ( '$mmCourse' , function ( $mmSite , $translate , $q , $log , $mmEvents , mmCoreEventCompletionModuleViewed ) {
36+ . factory ( '$mmCourse' , function ( $mmSite , $translate , $q , $log , $mmEvents , $mmSitesManager , mmCoreEventCompletionModuleViewed ) {
3737
3838 $log = $log . getInstance ( '$mmCourse' ) ;
3939
@@ -58,6 +58,40 @@ angular.module('mm.core.course')
5858 return module ;
5959 }
6060
61+ /**
62+ * Check if the site is prepared to return a module without having its course ID.
63+ *
64+ * @module mm.core.course
65+ * @ngdoc method
66+ * @name $mmCourse#canGetModuleWithoutCourseId
67+ * @param {String } [siteId] Site ID. If not defined, current site.
68+ * @return {Promise } Promise resolved with true if can return it, rejected or resolved with false otherwise.
69+ */
70+ self . canGetModuleWithoutCourseId = function ( siteId ) {
71+ siteId = siteId || $mmSite . getId ( ) ;
72+
73+ return $mmSitesManager . getSite ( siteId ) . then ( function ( site ) {
74+ return site . wsAvailable ( 'core_course_get_course_module' ) ;
75+ } ) ;
76+ } ;
77+
78+ /**
79+ * Check if the site is prepared to return a module by instance ID.
80+ *
81+ * @module mm.core.course
82+ * @ngdoc method
83+ * @name $mmCourse#canGetModuleByInstance
84+ * @param {String } [siteId] Site ID. If not defined, current site.
85+ * @return {Promise } Promise resolved with true if can return it, rejected or resolved with false otherwise.
86+ */
87+ self . canGetModuleByInstance = function ( siteId ) {
88+ siteId = siteId || $mmSite . getId ( ) ;
89+
90+ return $mmSitesManager . getSite ( siteId ) . then ( function ( site ) {
91+ return site . wsAvailable ( 'core_course_get_course_module_by_instance' ) ;
92+ } ) ;
93+ } ;
94+
6195 /**
6296 * Check if module completion could have changed. If it could have, trigger event. This function must be used,
6397 * for example, after calling a "module_view" WS since it can change the module completion.
@@ -122,63 +156,155 @@ angular.module('mm.core.course')
122156 return 'mmCourse:activitiescompletion:' + courseid + ':' + userid ;
123157 }
124158
159+ /**
160+ * Gets a module basic info by module ID.
161+ *
162+ * @module mm.core.course
163+ * @ngdoc method
164+ * @name $mmCourse#getModuleBasicInfo
165+ * @param {Number } moduleId Module ID.
166+ * @param {String } [siteId] Site ID. If not defined, current site.
167+ * @return {Promise } Promise resolved with the module's info.
168+ */
169+ self . getModuleBasicInfo = function ( moduleId , siteId ) {
170+ siteId = siteId || $mmSite . getId ( ) ;
171+
172+ return $mmSitesManager . getSite ( siteId ) . then ( function ( site ) {
173+ var params = {
174+ cmid : moduleId
175+ } ,
176+ preSets = {
177+ cacheKey : getModuleCacheKey ( moduleId )
178+ } ;
179+
180+ return site . read ( 'core_course_get_course_module' , params , preSets ) . then ( function ( response ) {
181+ if ( response . cm && ( ! response . warnings || ! response . warnings . length ) ) {
182+ return response . cm ;
183+ }
184+ return $q . reject ( ) ;
185+ } ) ;
186+ } ) ;
187+ } ;
188+
189+ /**
190+ * Gets a module basic info by instance.
191+ *
192+ * @module mm.core.course
193+ * @ngdoc method
194+ * @name $mmCourse#getModuleBasicInfoByInstance
195+ * @param {Number } id Instance ID.
196+ * @param {String } module Name of the module. E.g. 'glossary'.
197+ * @param {String } [siteId] Site ID. If not defined, current site.
198+ * @return {Promise } Promise resolved with the module's info.
199+ */
200+ self . getModuleBasicInfoByInstance = function ( id , module , siteId ) {
201+ siteId = siteId || $mmSite . getId ( ) ;
202+
203+ return $mmSitesManager . getSite ( siteId ) . then ( function ( site ) {
204+ var params = {
205+ instance : id ,
206+ module : module
207+ } ,
208+ preSets = {
209+ cacheKey : getModuleByInstanceCacheKey ( id , module )
210+ } ;
211+
212+ return site . read ( 'core_course_get_course_module_by_instance' , params , preSets ) . then ( function ( response ) {
213+ if ( response . cm && ( ! response . warnings || ! response . warnings . length ) ) {
214+ return response . cm ;
215+ }
216+ return $q . reject ( ) ;
217+ } ) ;
218+ } ) ;
219+ } ;
220+
125221 /**
126222 * Get a module from Moodle.
127223 *
128224 * @module mm.core.course
129225 * @ngdoc method
130226 * @name $mmCourse#getModule
131- * @param {Number } courseid The course ID.
132- * @param {Number } moduleid The module ID.
133- * @param {Number } [sectionid ] The section ID.
227+ * @param {Number } moduleId The module ID.
228+ * @param {Number } [courseId] The course ID. Recommended to speed up the process and minimize data usage .
229+ * @param {Number } [sectionId ] The section ID.
134230 * @return {Promise }
135231 */
136- self . getModule = function ( courseid , moduleid , sectionid ) {
232+ self . getModule = function ( moduleId , courseId , sectionId ) {
137233
138- if ( ! moduleid ) {
234+ if ( ! moduleId ) {
139235 return $q . reject ( ) ;
140236 }
141237
142- $log . debug ( 'Getting module ' + moduleid + ' in course ' + courseid + ' and section ' + sectionid ) ;
238+ var promise ;
143239
144- var params = {
145- courseid : courseid ,
240+ if ( ! courseId ) {
241+ // No courseId passed, try to retrieve it.
242+ promise = self . getModuleBasicInfo ( moduleId ) . then ( function ( module ) {
243+ return module . course ;
244+ } ) ;
245+ } else {
246+ promise = $q . when ( courseId ) ;
247+ }
248+
249+ return promise . then ( function ( courseId ) {
250+ // We have courseId, we can use core_course_get_contents for compatibility.
251+ $log . debug ( 'Getting module ' + moduleId + ' in course ' + courseId ) ;
252+
253+ params = {
254+ courseid : courseId ,
146255 options : [
147256 {
148257 name : 'cmid' ,
149- value : moduleid
258+ value : moduleId
150259 }
151260 ]
152- } ,
261+ } ;
153262 preSets = {
154- cacheKey : getModuleCacheKey ( moduleid )
263+ cacheKey : getModuleCacheKey ( moduleId )
155264 } ;
156265
157- if ( sectionid ) {
158- params . options . push ( {
159- name : 'sectionid' ,
160- value : sectionid
161- } ) ;
162- }
163-
164- return $mmSite . read ( 'core_course_get_contents' , params , preSets ) . then ( function ( sections ) {
165- var section ,
166- module ;
266+ if ( sectionId ) {
267+ params . options . push ( {
268+ name : 'sectionid' ,
269+ value : sectionId
270+ } ) ;
271+ }
167272
168- for ( var i = 0 ; i < sections . length ; i ++ ) {
169- section = sections [ i ] ;
170- for ( var j = 0 ; j < section . modules . length ; j ++ ) {
171- module = section . modules [ j ] ;
172- if ( module . id === moduleid ) {
173- return addContentsIfNeeded ( module ) ;
273+ return $mmSite . read ( 'core_course_get_contents' , params , preSets ) . catch ( function ( ) {
274+ // Error getting the module. Try to get all contents (without filtering).
275+ params . options = [ ] ;
276+ preSets . cacheKey = getSectionsCacheKey ( courseId ) ;
277+ return $mmSite . read ( 'core_course_get_contents' , params , preSets ) ;
278+ } ) . then ( function ( sections ) {
279+ var section ,
280+ module ;
281+
282+ for ( var i = 0 ; i < sections . length ; i ++ ) {
283+ section = sections [ i ] ;
284+ for ( var j = 0 ; j < section . modules . length ; j ++ ) {
285+ module = section . modules [ j ] ;
286+ if ( module . id == moduleId ) {
287+ module . course = courseId ;
288+ return addContentsIfNeeded ( module ) ;
289+ }
174290 }
175291 }
176- }
177-
178- return $q . reject ( ) ;
292+ return $q . reject ( ) ;
293+ } ) ;
179294 } ) ;
180295 } ;
181296
297+ /**
298+ * Get cache key for module WS calls.
299+ *
300+ * @param {Number } id Instance ID.
301+ * @param {String } module Name of the module. E.g. 'glossary'.
302+ * @return {String } Cache key.
303+ */
304+ function getModuleByInstanceCacheKey ( id , module ) {
305+ return 'mmCourse:moduleByInstance:' + module + ':' + id ;
306+ }
307+
182308 /**
183309 * Get cache key for module WS calls.
184310 *
@@ -289,6 +415,20 @@ angular.module('mm.core.course')
289415 return $mmSite . invalidateWsCacheForKey ( getModuleCacheKey ( moduleid ) ) ;
290416 } ;
291417
418+ /**
419+ * Invalidates module WS call.
420+ *
421+ * @module mm.core.course
422+ * @ngdoc method
423+ * @name $mmCourse#invalidateModuleByInstance
424+ * @param {Number } id Instance ID.
425+ * @param {String } module Name of the module. E.g. 'glossary'.
426+ * @return {Promise } Promise resolved when the data is invalidated.
427+ */
428+ self . invalidateModuleByInstance = function ( id , module ) {
429+ return $mmSite . invalidateWsCacheForKey ( getModuleByInstanceCacheKey ( id , module ) ) ;
430+ } ;
431+
292432 /**
293433 * Invalidates sections WS call.
294434 *
0 commit comments