Skip to content

Commit f4abe8c

Browse files
committed
MOBILE-1543 quiz: Gather preflight in sync and store password in DB
1 parent b0b4c2f commit f4abe8c

File tree

19 files changed

+506
-178
lines changed

19 files changed

+506
-178
lines changed

www/addons/mod_quiz/accessrules/delaybetweenattempts/handlers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ angular.module('mm.addons.mod_quiz')
3737
/**
3838
* Check if a preflight check is required.
3939
*
40+
* @param {Object} quiz Quiz.
4041
* @param {Object} [attempt] Attempt to continue. Not defined if starting a new attempt.
4142
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
43+
* @param {String} [siteId] Site ID. If not defined, current site.
4244
* @return {Boolean} True if preflight check required.
4345
*/
44-
self.isPreflightCheckRequired = function(attempt, prefetch) {
46+
self.isPreflightCheckRequired = function(quiz, attempt, prefetch, siteId) {
4547
return false;
4648
};
4749

www/addons/mod_quiz/accessrules/ipaddress/handlers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ angular.module('mm.addons.mod_quiz')
3737
/**
3838
* Check if a preflight check is required.
3939
*
40+
* @param {Object} quiz Quiz.
4041
* @param {Object} [attempt] Attempt to continue. Not defined if starting a new attempt.
4142
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
43+
* @param {String} [siteId] Site ID. If not defined, current site.
4244
* @return {Boolean} True if preflight check required.
4345
*/
44-
self.isPreflightCheckRequired = function(attempt, prefetch) {
46+
self.isPreflightCheckRequired = function(quiz, attempt, prefetch, siteId) {
4547
return false;
4648
};
4749

www/addons/mod_quiz/accessrules/numattempts/handlers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ angular.module('mm.addons.mod_quiz')
3737
/**
3838
* Check if a preflight check is required.
3939
*
40+
* @param {Object} quiz Quiz.
4041
* @param {Object} [attempt] Attempt to continue. Not defined if starting a new attempt.
4142
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
43+
* @param {String} [siteId] Site ID. If not defined, current site.
4244
* @return {Boolean} True if preflight check required.
4345
*/
44-
self.isPreflightCheckRequired = function(attempt, prefetch) {
46+
self.isPreflightCheckRequired = function(quiz, attempt, prefetch, siteId) {
4547
return false;
4648
};
4749

www/addons/mod_quiz/accessrules/offlineattempts/handlers.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ angular.module('mm.addons.mod_quiz')
3737
/**
3838
* Check if a preflight check is required.
3939
*
40+
* @param {Object} quiz Quiz.
4041
* @param {Object} [attempt] Attempt to continue. Not defined if starting a new attempt.
4142
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
43+
* @param {String} [siteId] Site ID. If not defined, current site.
4244
* @return {Boolean} True if preflight check required.
4345
*/
44-
self.isPreflightCheckRequired = function(attempt, prefetch) {
46+
self.isPreflightCheckRequired = function(quiz, attempt, prefetch, siteId) {
4547
if (prefetch) {
4648
return false;
4749
}
@@ -57,15 +59,14 @@ angular.module('mm.addons.mod_quiz')
5759
/**
5860
* Get fixed preflight data (data that doesn't require user interaction).
5961
*
60-
* @module mm.addons.mod_quiz
61-
* @ngdoc method
62-
* @name $mmaModQuizAccessRulesDelegate#getFixedPreflightData
62+
* @param {Object} quiz Quiz.
6363
* @param {Object} attempt Attempt.
6464
* @param {Object} preflightData Object where to store the preflight data.
6565
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
66+
* @param {String} [siteId] Site ID. If not defined, current site.
6667
* @return {Void}
6768
*/
68-
self.getFixedPreflightData = function(attempt, preflightData, prefetch) {
69+
self.getFixedPreflightData = function(quiz, attempt, preflightData, prefetch, siteId) {
6970
preflightData.confirmdatasaved = 1;
7071
};
7172

www/addons/mod_quiz/accessrules/openclosedate/handlers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ angular.module('mm.addons.mod_quiz')
3737
/**
3838
* Check if a preflight check is required.
3939
*
40+
* @param {Object} quiz Quiz.
4041
* @param {Object} [attempt] Attempt to continue. Not defined if starting a new attempt.
4142
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
43+
* @param {String} [siteId] Site ID. If not defined, current site.
4244
* @return {Boolean} True if preflight check required.
4345
*/
44-
self.isPreflightCheckRequired = function(attempt, prefetch) {
46+
self.isPreflightCheckRequired = function(quiz, attempt, prefetch, siteId) {
4547
return false;
4648
};
4749

www/addons/mod_quiz/accessrules/password/handlers.js

Lines changed: 134 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@
1313
// limitations under the License.
1414

1515
angular.module('mm.addons.mod_quiz')
16+
.constant('mmaModQuizAccessPasswordStore', 'mod_quiz_access_password')
17+
18+
.config(function($mmSitesFactoryProvider, mmaModQuizAccessPasswordStore) {
19+
var stores = [
20+
{
21+
name: mmaModQuizAccessPasswordStore,
22+
keyPath: 'id',
23+
indexes: []
24+
}
25+
];
26+
$mmSitesFactoryProvider.registerStores(stores);
27+
})
1628

1729
/**
1830
* Handler for password quiz access rule.
@@ -21,7 +33,7 @@ angular.module('mm.addons.mod_quiz')
2133
* @ngdoc service
2234
* @name $mmaQuizAccessPasswordHandler
2335
*/
24-
.factory('$mmaQuizAccessPasswordHandler', function() {
36+
.factory('$mmaQuizAccessPasswordHandler', function($mmSitesManager, $mmSite, $q, mmaModQuizAccessPasswordStore) {
2537

2638
var self = {};
2739

@@ -34,6 +46,80 @@ angular.module('mm.addons.mod_quiz')
3446
delete data.quizpassword;
3547
};
3648

49+
/**
50+
* Get a password stored in DB.
51+
*
52+
* @param {Number} quizId Quiz ID.
53+
* @param {String} [siteId] Site ID. If not defined, current site.
54+
* @return {Promise} Promise resolved with password on success, rejected otherwise.
55+
*/
56+
function getPasswordEntry(quizId, siteId) {
57+
siteId = siteId || $mmSite.getId();
58+
59+
return $mmSitesManager.getSite(siteId).then(function(site) {
60+
return site.getDb().get(mmaModQuizAccessPasswordStore, quizId);
61+
});
62+
}
63+
64+
/**
65+
* Remove a password from DB.
66+
*
67+
* @param {Number} quizId Quiz ID.
68+
* @param {String} [siteId] Site ID. If not defined, current site.
69+
* @return {Promise} Promise resolved on success, rejected otherwise.
70+
*/
71+
function removePassword(quizId, siteId) {
72+
siteId = siteId || $mmSite.getId();
73+
74+
return $mmSitesManager.getSite(siteId).then(function(site) {
75+
return site.getDb().remove(mmaModQuizAccessPasswordStore, quizId);
76+
});
77+
}
78+
79+
/**
80+
* Store a password in DB.
81+
*
82+
* @param {Number} quizId Quiz ID.
83+
* @param {String} password Password.
84+
* @param {String} [siteId] Site ID. If not defined, current site.
85+
* @return {Promise} Promise resolved on success, rejected otherwise.
86+
*/
87+
function storePassword(quizId, password, siteId) {
88+
siteId = siteId || $mmSite.getId();
89+
90+
return $mmSitesManager.getSite(siteId).then(function(site) {
91+
var entry = {
92+
id: quizId,
93+
password: password,
94+
timemodified: new Date().getTime()
95+
};
96+
97+
return site.getDb().insert(mmaModQuizAccessPasswordStore, entry);
98+
});
99+
}
100+
101+
/**
102+
* Get fixed preflight data (data that doesn't require user interaction).
103+
*
104+
* @param {Object} quiz Quiz.
105+
* @param {Object} attempt Attempt.
106+
* @param {Object} preflightData Object where to store the preflight data.
107+
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
108+
* @param {String} [siteId] Site ID. If not defined, current site.
109+
* @return {Promise} Promise resolved when preflight data has been added.
110+
*/
111+
self.getFixedPreflightData = function(quiz, attempt, preflightData, prefetch, siteId) {
112+
if (quiz && quiz.id && typeof preflightData.quizpassword == 'undefined') {
113+
return getPasswordEntry(quiz.id, siteId).then(function(entry) {
114+
preflightData.quizpassword = entry.password;
115+
}).catch(function() {
116+
// Don't reject.
117+
});
118+
}
119+
120+
return $q.when();
121+
};
122+
37123
/**
38124
* Whether or not the rule is enabled for the site.
39125
*
@@ -46,13 +132,20 @@ angular.module('mm.addons.mod_quiz')
46132
/**
47133
* Check if a preflight check is required.
48134
*
135+
* @param {Object} quiz Quiz.
49136
* @param {Object} [attempt] Attempt to continue. Not defined if starting a new attempt.
50137
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
51-
* @return {Boolean} True if preflight check required.
138+
* @param {String} [siteId] Site ID. If not defined, current site.
139+
* @return {Promise} Promise resolved with a boolean: true if preflight check required, false otherwise.
52140
*/
53-
self.isPreflightCheckRequired = function(attempt, prefetch) {
54-
// If the password rule is active in a quiz we always require to input the password.
55-
return true;
141+
self.isPreflightCheckRequired = function(quiz, attempt, prefetch, siteId) {
142+
// Check if we have a password stored.
143+
return getPasswordEntry(quiz.id, siteId).then(function() {
144+
return false;
145+
}).catch(function() {
146+
// Not stored.
147+
return true;
148+
});
56149
};
57150

58151
/**
@@ -64,6 +157,42 @@ angular.module('mm.addons.mod_quiz')
64157
return 'mma-quiz-access-password-preflight';
65158
};
66159

160+
/**
161+
* The preflight check has passed. This is a chance to record that fact in some way.
162+
*
163+
* @param {Object} quiz Quiz.
164+
* @param {Object} attempt Attempt.
165+
* @param {Object} preflightData Object where to store the preflight data.
166+
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
167+
* @param {String} [siteId] Site ID. If not defined, current site.
168+
* @return {Promise} Promise resolved when done.
169+
*/
170+
self.notifyPreflightCheckPassed = function(quiz, attempt, preflightData, prefetch, siteId) {
171+
if (quiz && quiz.id && typeof preflightData.quizpassword != 'undefined') {
172+
return storePassword(quiz.id, preflightData.quizpassword, siteId);
173+
}
174+
175+
return $q.when();
176+
};
177+
178+
/**
179+
* The preflight check has failed.
180+
*
181+
* @param {Object} quiz Quiz.
182+
* @param {Object} attempt Attempt.
183+
* @param {Object} preflightData Object where to store the preflight data.
184+
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
185+
* @param {String} [siteId] Site ID. If not defined, current site.
186+
* @return {Promise} Promise resolved when done.
187+
*/
188+
self.notifyPreflightCheckFailed = function(quiz, attempt, preflightData, prefetch, siteId) {
189+
if (quiz && quiz.id) {
190+
return removePassword(quiz.id, siteId);
191+
}
192+
193+
return $q.when();
194+
};
195+
67196
return self;
68197
})
69198

www/addons/mod_quiz/accessrules/safebrowser/handlers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ angular.module('mm.addons.mod_quiz')
3737
/**
3838
* Check if a preflight check is required.
3939
*
40+
* @param {Object} quiz Quiz.
4041
* @param {Object} [attempt] Attempt to continue. Not defined if starting a new attempt.
4142
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
43+
* @param {String} [siteId] Site ID. If not defined, current site.
4244
* @return {Boolean} True if preflight check required.
4345
*/
44-
self.isPreflightCheckRequired = function(attempt, prefetch) {
46+
self.isPreflightCheckRequired = function(quiz, attempt, prefetch, siteId) {
4547
return false;
4648
};
4749

www/addons/mod_quiz/accessrules/securewindow/handlers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ angular.module('mm.addons.mod_quiz')
3737
/**
3838
* Check if a preflight check is required.
3939
*
40+
* @param {Object} quiz Quiz.
4041
* @param {Object} [attempt] Attempt to continue. Not defined if starting a new attempt.
4142
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
43+
* @param {String} [siteId] Site ID. If not defined, current site.
4244
* @return {Boolean} True if preflight check required.
4345
*/
44-
self.isPreflightCheckRequired = function(attempt, prefetch) {
46+
self.isPreflightCheckRequired = function(quiz, attempt, prefetch, siteId) {
4547
return false;
4648
};
4749

www/addons/mod_quiz/accessrules/timelimit/handlers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ angular.module('mm.addons.mod_quiz')
3737
/**
3838
* Check if a preflight check is required.
3939
*
40+
* @param {Object} quiz Quiz.
4041
* @param {Object} [attempt] Attempt to continue. Not defined if starting a new attempt.
4142
* @param {Boolean} prefetch True if prefetching, false if attempting the quiz.
43+
* @param {String} [siteId] Site ID. If not defined, current site.
4244
* @return {Boolean} True if preflight check required.
4345
*/
44-
self.isPreflightCheckRequired = function(attempt, prefetch) {
46+
self.isPreflightCheckRequired = function(quiz, attempt, prefetch, siteId) {
4547
// Warning only required if the attempt is not already started.
4648
// prefetch should always be false since offline isn't compatible with timed quizzes.
4749
return !attempt;

www/addons/mod_quiz/controllers/index.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ angular.module('mm.addons.mod_quiz')
316316

317317
// Tries to synchronize the current quiz.
318318
function syncQuiz(checkTime, showErrors) {
319-
var promise = checkTime ? $mmaModQuizSync.syncQuizIfNeeded(quiz) : $mmaModQuizSync.syncQuiz(quiz);
319+
var promise = checkTime ? $mmaModQuizSync.syncQuizIfNeeded(quiz, true) : $mmaModQuizSync.syncQuiz(quiz, true);
320320
return promise.then(function(warnings) {
321321
var message = $mmText.buildMessage(warnings);
322322
if (message) {
@@ -372,7 +372,7 @@ angular.module('mm.addons.mod_quiz')
372372
currentStatus = status;
373373

374374
if (status == mmCoreDownloading) {
375-
$scope.downloading = true;
375+
$scope.showSpinner = true;
376376
}
377377
}
378378

@@ -394,7 +394,12 @@ angular.module('mm.addons.mod_quiz')
394394

395395
// Synchronize the quiz.
396396
$scope.sync = function() {
397-
var modal = $mmUtil.showModalLoading('mm.settings.synchronizing', true);
397+
if ($scope.showSpinner) {
398+
// Scope is being or synchronized, abort.
399+
return;
400+
}
401+
402+
$scope.showSpinner = true;
398403
syncQuiz(false, true).then(function() {
399404
// Refresh the data.
400405
$scope.quizLoaded = false;
@@ -403,29 +408,29 @@ angular.module('mm.addons.mod_quiz')
403408
$scope.quizLoaded = true;
404409
});
405410
}).finally(function() {
406-
modal.dismiss();
411+
$scope.showSpinner = false;
407412
});
408413
};
409414

410415
// Attempt the quiz.
411416
$scope.attemptQuiz = function() {
412-
if ($scope.downloading) {
413-
// Scope is being downloaded, abort.
417+
if ($scope.showSpinner) {
418+
// Scope is being or synchronized, abort.
414419
return;
415420
}
416421

417422
if ($mmaModQuiz.isQuizOffline(quiz)) {
418423
// Quiz supports offline, check if it needs to be downloaded.
419424
if (currentStatus != mmCoreDownloaded) {
420425
// Prefetch the quiz.
421-
$scope.downloading = true;
426+
$scope.showSpinner = true;
422427
return $mmaModQuiz.prefetch(module, courseId, true).then(function() {
423428
// Success downloading, open quiz.
424429
openQuiz();
425430
}).catch(function(error) {
426431
$mmaModQuizHelper.showError(error, 'mma.mod_quiz.errordownloading');
427432
}).finally(function() {
428-
$scope.downloading = false;
433+
$scope.showSpinner = false;
429434
});
430435
} else {
431436
// Already downloaded, open it.

0 commit comments

Comments
 (0)