Skip to content

Commit

Permalink
Merge pull request #18 from SpongeUK/feature/serialiser
Browse files Browse the repository at this point in the history
Feature/serialiser
  • Loading branch information
cajones committed Mar 13, 2014
2 parents bc23ccb + 57f311d commit 7e0649b
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 226 deletions.
293 changes: 67 additions & 226 deletions js/adapt-contrib-spoor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
*/
define(function(require) {

var Adapt = require('coreJS/adapt');
var scormAPI = require('extensions/adapt-contrib-spoor/js/SCORM_API_wrapper');
var scormWrapper = require('extensions/adapt-contrib-spoor/js/scormWrapper').getInstance();
var scormLog = require('extensions/adapt-contrib-spoor/js/logger');

var Adapt = require('coreJS/adapt'),
_ = require('underscore'),
scormAPI = require('extensions/adapt-contrib-spoor/js/SCORM_API_wrapper'),
scormWrapper = require('extensions/adapt-contrib-spoor/js/scormWrapper').getInstance(),
scormLog = require('extensions/adapt-contrib-spoor/js/logger'),
serialiser = require('./serialisers/default');

var Spoor = Backbone.Model.extend({

defaults: {
Expand All @@ -19,206 +21,109 @@ define(function(require) {
},

initialize: function() {
//_.bindAll(this);
this.data = Adapt.config.get('_spoor');
console.log(scormWrapper);
this.SCOStart()
$(window).unload(_.bind(this.SCOFinish, this));
this.onDataReady();
this.data = Adapt.config.get('_spoor');
this.SCOStart() ;
$(window).unload(_.bind(this.SCOFinish, this));
this.onDataReady();
},

checkCompletionCriteria: function() {
var requirementArray = [this.data._tracking._requireCourseCompleted, this.data._tracking._requireAssessmentPassed];
var actualArray = [Adapt.course.get('_isComplete'), Adapt.course.get('_isAssessmentPassed')];

var criteriaMet = true;

_.each(requirementArray, function(requirement, index) {
if(requirement) {
if(!actualArray[index]) {
criteriaMet = false;
}
}
}, this);

if(criteriaMet) {
this.setLessonStatus(this.data._reporting._onTrackingCriteriaMet);
}
},
SCOStart: function() {
var sw = scormWrapper;
if (sw.initialize()) {
sw.setVersion("1.2");
this.set('initialised', true);
var lessonStatus = sw.getStatus().toLowerCase();

convertCompletionStringToArray: function(string) {
var completionArray = string.split("");
for (var i = 0; i < completionArray.length; i++) {
if (completionArray[i] === "-") {
completionArray[i] = -1;
} else {
completionArray[i] = parseInt(completionArray[i], 10);
if (lessonStatus === "not attempted" || lessonStatus === "unknown" || lessonStatus === undefined) {
sw.setIncomplete();
}
}
return completionArray;
},

convertCompletionArrayToString: function(array) {
var completionString = array.join("");
return completionString.replace(/-1/g, "-");
},

createCompletionString: function() {
if(Adapt.course.get('_isComplete')) {
return 'courseComplete';
}
var _blockCompletionArray = this.get('_blockCompletionArray');

_.each(Adapt.blocks.models, function(blockModel) {
if (blockModel.get('_isComplete')) {
_blockCompletionArray[blockModel.get('_trackingId')] = 1;
}
}, this);

this.set('_blockCompletionArray', _blockCompletionArray);
return this.convertCompletionArrayToString(_blockCompletionArray);
},

createCompletionObject: function() {
var completionObject = {spoor:{}};
completionObject.spoor.completion = this.createCompletionString();
completionObject.spoor._isAssessmentPassed = Adapt.course.get('_isAssessmentPassed') || false;
this.set('completionObject', completionObject);
return completionObject;
},

getDataIsAlreadyReported: function(completionObject) {
return JSON.stringify(this.get('_suspendData')) === JSON.stringify(completionObject);
},

markBlockAsComplete: function(parameters) {
var block = parameters.block;

if (block.get('_isComplete')) {
return;
}

block.getChildren().each(function(child) {
child.set('_isComplete', true);
}, this);
},

onCriterionMet: function(criterion) {
if (!Adapt.course.get(criterion)) {
Adapt.course.set(criterion, true);
SCOFinish:function() {
if (!this.get('_SCOFinishCalled')) {
this.set('SCOFinishCalled', true);
scormWrapper.finish();
}
this.sendCompletionString();
this.checkCompletionCriteria();
},

onDataReady: function() {
this.setSessionData();
this.setupBlockCompletionData();
this.repopulateCompletionData();
this.loadSuspendData();
this.assignSessionId();
this.setupListeners();
// may no longer be needed - DH
// Adapt.trigger("spoorReady");
},

setupListeners: function() {
Adapt.blocks.on('change:_isComplete', this.onBlockComplete, this);
Adapt.course.on('change:_isComplete', this.onCourseComplete, this);
Adapt.on('assessment:complete', this.onAssessmentComplete, this);
Adapt.on('questionView:complete', this.onQuestionComplete, this);
Adapt.on('questionView:reset', this.onQuestionReset, this);
},

onCourseComplete: function() {
this.onCriterionMet("_isComplete");

loadSuspendData: function() {
var suspendData = scormWrapper.getSuspendData();

if (suspendData === "" || suspendData === " " || suspendData === undefined) {
this.set('_suspendData', serialiser.serialise());
} else {
this.set('_suspendData', serialiser.deserialise(suspendData));
}
},


assignSessionId: function () {
this.set({
_sessionID: Math.random().toString(36).slice(-8)
});
},

onBlockComplete: function(block) {
this.set('lastCompletedBlock', block);
this.sendCompletionString();
this.persistSuspendData();
},


onCourseComplete: function() {
if(Adapt.course.get('_isComplete') === true) {
this.set('_attempts', this.get('_attempts')+1);
}
_.defer(function waitForBlockComplete() {
this.persistSuspendData();
});
},

onAssessmentComplete: function(event) {
if(this.data._tracking._shouldSubmitScore) {
scormWrapper.setScore(event.scoreAsPercent, 0, 100);
}
if (event.isPass) {
this.onCriterionMet("_isAssessmentPassed");
Adapt.course.set('_isAssessmentPassed', event.isPass);
this.persistSuspendData();
} else {
var onAssessmentFailure = this.data._reporting._onAssessmentFailure;
if (onAssessmentFailure !== "" && onAssessmentFailure !== "incomplete") {
this.setLessonStatus(onAssessmentFailure);
}
}
if(this.data._tracking._shouldSubmitScore) {
scormWrapper.setScore(event.scoreAsPercent, 0, 100);
}
},

onQuestionComplete: function(questionView) {
questionView.model.set('_sessionID', this.get('_sessionID'));
},

onQuestionReset: function(questionView) {
var sameSession = this.get('_sessionID') === questionView.model.get('_sessionID');
if(!sameSession) {
if(this.get('_sessionID') !== questionView.model.get('_sessionID')) {
questionView.model.set('_isEnabledOnRevisit', true);
}
},

repopulateCompletionData: function() {
var suspendData = this.get('_suspendData');

if (suspendData.spoor.completion !== "") {
this.restoreProgress(suspendData);
}
},

restoreProgress: function(suspendData) {
if (suspendData.spoor.completion === "courseComplete") {
Adapt.course.set('_isComplete', true);
Adapt.course.setOnChildren('_isComplete', true);
} else {
_.each(this.get('_blockCompletionArray'), function(blockCompletion, blockTrackingId) {
if (blockCompletion === 1) {
this.markBlockAsComplete({block: Adapt.blocks.findWhere({_trackingId: blockTrackingId}), includeChildren: true});
}
}, this);
}
Adapt.course.set('_isAssessmentPassed', suspendData.spoor._isAssessmentPassed);
this.set('_suspendData', suspendData);
this.sendCompletionString();
},

SCOFinish:function() {
if (!this.get('_SCOFinishCalled')) {
this.set('SCOFinishCalled', true);
scormWrapper.finish();
}
},

SCOStart: function() {
// this.set('scormWrapper', this.data._testingMode') ? this.get('testingLMS : ScormWrapper.getInstance());
var sw = scormWrapper;
if (sw.initialize()) {
sw.setVersion("1.2");
this.set('initialised', true);
var lessonStatus = sw.getStatus().toLowerCase();

if (lessonStatus == "not attempted" || lessonStatus == "unknown") {
sw.setIncomplete();
}
}
},
persistSuspendData: function(){
var courseCriteriaMet = this.data._tracking._requireCourseCompleted ? Adapt.course.get('_isComplete') : true,
assessmentCriteriaMet = this.data._tracking._requireAssessmentPassed ? Adapt.course.get('_isAssessmentPassed') : true;

sendCompletionString: function(){
var suspendData = this.createCompletionObject();
if (!this.getDataIsAlreadyReported(suspendData)) {
if (this.get('_lastCompletedBlock') !== undefined) {
console.info("Spoor: block " + this.get('_lastCompletedBlock').get('id') + " is complete.");
}
this.set({
_suspendData: suspendData,
_blockCompletionArray: this.convertCompletionStringToArray(suspendData.spoor.completion)
});
scormWrapper.setSuspendData(JSON.stringify(suspendData));
if(courseCriteriaMet && assessmentCriteriaMet) {
this.setLessonStatus(this.data._reporting._onTrackingCriteriaMet);
}
scormWrapper.setSuspendData(JSON.stringify(serialiser.serialise()));
},

setLessonStatus:function(status){
Expand All @@ -239,74 +144,10 @@ define(function(require) {
console.warn("cmi.core.lesson_status of " + status + " is not supported.");
break;
}
},

setScore: function(score){
scormWrapper.setScore(score,0,100);
},

setSessionData: function() {
var suspendData = scormWrapper.getSuspendData();

if (suspendData === "" || suspendData === " " || suspendData === undefined) {
this.set('_suspendData', {
spoor: {
completion: "",
_isAssessmentPassed: false
}
});
} else {
this.set('_suspendData', JSON.parse(suspendData));
}

this.set({
_sessionID: this.generateRandomID(8)
});
},

setTestingMode: function(value) {
this.set('testingLMS', value ? new TestingLMS() : null);
this.set('testingMode', value);
},

setupBlockCompletionData: function() {
if (Adapt.course.get('_latestTrackingId') === undefined) {
var message = "This course is missing a latestTrackingID.\n\nPlease run the grunt process prior to deploying this module on LMS.\n\nScorm tracking will not work correctly until this is done.";
alert(message);
console.error(message);
}
var _blockCompletionArray = new Array(Adapt.course.get('_latestTrackingId') + 1);
for (var i = 0; i < _blockCompletionArray.length; i++) {
_blockCompletionArray[i] = -1;
}

_.each(Adapt.blocks.models, function(model, index) {
var _trackingId = model.get('_trackingId');
var recordedCompletion = parseInt(this.get('_suspendData').spoor.completion[_trackingId], 10) || 0;
if (_trackingId === undefined) {
var message = "Block '" + model.get('id') + "' doesn't have a tracking ID assigned.\n\nPlease run the grunt process prior to deploying this module on LMS.\n\nScorm tracking will not work correctly until this is done.";
alert(message);
console.error(message);
}
_blockCompletionArray[_trackingId] = recordedCompletion;
}, this);
this.set('_blockCompletionArray', _blockCompletionArray);
},

parseBool: function(str) {
if(_.isString(str)) {
if (typeof str === 'string' && str.toLowerCase() == 'true')
return true;
return (parseInt(str) > 0);
} else if (_.isBoolean(str)) return str;
},

generateRandomID: function(numberOfCharacters) {
return Math.random().toString(36).slice(-numberOfCharacters);
}

});
Adapt.on('app:dataReady', function() {
new Spoor();
})
});
});
Loading

0 comments on commit 7e0649b

Please sign in to comment.