Skip to content

Commit 9824ead

Browse files
Move course validation to back-end for efficiency
1 parent 859227b commit 9824ead

8 files changed

Lines changed: 59 additions & 60 deletions

File tree

frontend/src/core/helpers.js

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -228,37 +228,6 @@ define(function(require){
228228
return success;
229229
},
230230

231-
// checks for at least one child object
232-
validateCourseContent: function(currentCourse, callback) {
233-
var containsAtLeastOneChild = true;
234-
var alerts = [];
235-
var iterateOverChildren = function(model, index, doneIterator) {
236-
if(!model._childTypes) {
237-
return doneIterator();
238-
}
239-
model.fetchChildren(function(currentChildren) {
240-
if (currentChildren.length > 0) {
241-
return helpers.forParallelAsync(currentChildren, iterateOverChildren, doneIterator);
242-
}
243-
containsAtLeastOneChild = false;
244-
var children = _.isArray(model._childTypes) ? model._childTypes.join('/') : model._childTypes;
245-
alerts.push(model.get('_type') + " '" + model.get('title') + "' missing " + children);
246-
doneIterator();
247-
});
248-
};
249-
// start recursion
250-
iterateOverChildren(currentCourse, null, function() {
251-
var errorMessage = "";
252-
if(alerts.length > 0) {
253-
for(var i = 0, len = alerts.length; i < len; i++) {
254-
errorMessage += "<li>" + alerts[i] + "</li>";
255-
}
256-
return callback(new Error(errorMessage));
257-
}
258-
callback(null, true);
259-
});
260-
},
261-
262231
isValidEmail: function(value) {
263232
var regEx = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
264233
return value.length > 0 && regEx.test(value);

frontend/src/modules/editor/global/views/editorView.js

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,12 @@ define(function(require) {
4444
'editorView:copy': this.addToClipboard,
4545
'editorView:copyID': this.copyIdToClipboard,
4646
'editorView:paste': this.pasteFromClipboard,
47-
'editorCommon:download': function() {
48-
this.validateProject(function(error) {
49-
this.downloadProject();
50-
});
51-
},
47+
'editorCommon:download': this.downloadProject,
5248
'editorCommon:preview': function(isForceRebuild) {
5349
var previewWindow = window.open('loading', 'preview');
54-
this.validateProject(function(error) {
55-
if(error) {
56-
return previewWindow.close();
57-
}
58-
this.previewProject(previewWindow, isForceRebuild);
59-
});
50+
this.previewProject(previewWindow, isForceRebuild);
6051
},
61-
'editorCommon:export': function() {
62-
this.validateProject(function(error) {
63-
this.exportProject(error);
64-
});
65-
}
52+
'editorCommon:export': this.exportProject
6653
});
6754
this.render();
6855
this.setupEditor();
@@ -76,15 +63,6 @@ define(function(require) {
7663
this.renderCurrentEditorView();
7764
},
7865

79-
validateProject: function(next) {
80-
helpers.validateCourseContent(this.currentCourse, _.bind(function(error) {
81-
if(error) {
82-
Origin.Notify.alert({ type: 'error', text: "There's something wrong with your course:<br/><br/>" + error });
83-
}
84-
next.call(this, error);
85-
}, this));
86-
},
87-
8866
previewProject: function(previewWindow, forceRebuild) {
8967
if(Origin.editor.isPreviewPending) {
9068
return;

plugins/output/adapt/importsource.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const database = require("../../../lib/database");
77
const filestorage = require('../../../lib/filestorage');
88
const fs = require("fs-extra");
99
const glob = require('glob');
10-
const helpers = require('./helpers');
10+
const helpers = require('./outputHelpers');
1111
const logger = require("../../../lib/logger");
1212
const mime = require('mime');
1313
const path = require("path");

plugins/output/adapt/importsourcecheck.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const configuration = require('../../../lib/configuration');
66
const Constants = require('../../../lib/outputmanager').Constants;
77
const database = require("../../../lib/database");
88
const fs = require("fs-extra");
9-
const helpers = require('./helpers');
9+
const helpers = require('./outputHelpers');
1010
const IncomingForm = require('formidable').IncomingForm;
1111
const logger = require("../../../lib/logger");
1212
const path = require("path");
Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,43 @@ function getPluginFrameworkVersionCategory(serverFrameworkVersion, pluginMetaDat
277277
});
278278
};
279279

280+
function validateCourse(data, cb) {
281+
let errors = '';
282+
let contentObjects = data.contentobject;
283+
let articles = data.article;
284+
let blocks = data.block;
285+
let components = data.component;
286+
287+
if (typeof contentObjects === 'undefined') {
288+
let courseString = app.polyglot.t('app.course').charAt(0).toUpperCase() + app.polyglot.t('app.course').slice(1);
289+
errors += courseString + ' "' + data.course[0].title + '" ' + app.polyglot.t('app.doesnotcontain') + ' ' + app.polyglot.t('app.page') + 's\n';
290+
return cb(errors, false);
291+
}
292+
293+
errors += iterateThroughChildren(contentObjects, articles);
294+
errors += iterateThroughChildren(articles, blocks);
295+
errors += iterateThroughChildren(blocks, components);
296+
297+
if (errors.length !== 0) return cb(errors, false);
298+
299+
return cb(null, true);
300+
}
301+
302+
function iterateThroughChildren(parents, children) {
303+
let errors = '';
304+
parents.forEach(parent => {
305+
let parentType = app.polyglot.t('app.' + parent._type).charAt(0).toUpperCase() + app.polyglot.t('app.' + parent._type).slice(1);
306+
let childType = app.polyglot.t('app.children');
307+
if (children[0] && children[0]._type) childType = app.polyglot.t('app.' + children[0]._type) + 's';
308+
let found = children.find(child => JSON.stringify(child._parentId) === JSON.stringify(parent._id));
309+
310+
if (typeof found === 'undefined') {
311+
errors += parentType + ' "' + parent.title + '" ' + app.polyglot.t('app.doesnotcontain') + ' ' + childType + '\n';
312+
}
313+
});
314+
return errors;
315+
}
316+
280317
function ImportError(message, httpStatus) {
281318
this.message = message || "Course import failed";
282319
this.httpStatus = httpStatus || 500;
@@ -322,5 +359,6 @@ exports = module.exports = {
322359
ImportError: ImportError,
323360
PartialImportError: PartialImportError,
324361
sortContentObjects: sortContentObjects,
325-
cleanUpImport: cleanUpImport
362+
cleanUpImport: cleanUpImport,
363+
validateCourse: validateCourse
326364
};

plugins/output/adapt/publish.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const helpers = require('../../../lib/helpers');
1212
const installHelpers = require('../../../lib/installHelpers');
1313
const logger = require('../../../lib/logger');
1414
const origin = require('../../../');
15+
const outputHelpers = require('./outputHelpers');
1516
const usermanager = require('../../../lib/usermanager');
1617

1718
function publishCourse(courseId, mode, request, response, next) {
@@ -58,6 +59,16 @@ function publishCourse(courseId, mode, request, response, next) {
5859
callback(null);
5960
});
6061
},
62+
// validate the course data
63+
function(callback) {
64+
outputHelpers.validateCourse(outputJson, function(error, isValid) {
65+
if (error || !isValid) {
66+
return callback({ message: error });
67+
}
68+
69+
callback(null);
70+
});
71+
},
6172
//
6273
function(callback) {
6374
var temporaryThemeFolder = path.join(SRC_FOLDER, Constants.Folders.Theme, customPluginName);

routes/import/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ var permissions = require('../../lib/permissions');
33
var server = module.exports = require('express')();
44
var usermanager = require('../../lib/usermanager');
55
var util = require('util');
6-
var helpers = require('../../plugins/output/adapt/helpers');
6+
var helpers = require('../../plugins/output/adapt/outputHelpers');
77

88
// stop any auto permissions checks
99
permissions.ignoreRoute(/^\/import\/?.*$/);

routes/lang/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@
171171
"app.preview": "Preview course",
172172
"app.previewing": "Previewing...",
173173
"app.forcerebuild": "Force rebuild",
174+
"app.doesnotcontain": "does not contain any",
175+
"app.children": "children",
174176
"app.editprofiletitle": "User profile",
175177
"app.editprofileinformation": "You can view and modify your user information below.",
176178
"app.firstname": "First name",
@@ -392,6 +394,7 @@
392394
"app.editormenusettings": "Menu picker",
393395
"app.editorextensions": "Manage extensions",
394396
"app.editing": "Editing %{type}: %{text}",
397+
"app.course": "course",
395398
"app.menu": "menu",
396399
"app.page": "page",
397400
"app.article": "article",

0 commit comments

Comments
 (0)