From cc5974edd3c6c1b451c449254d28b9fbe79ba993 Mon Sep 17 00:00:00 2001 From: Brian Quinn Date: Wed, 2 Sep 2015 15:13:46 +0100 Subject: [PATCH 1/7] Fixes #792, adds support for HTML table editing This is enabled via a CKEditor config on initialisation. --- frontend/src/core/scaffold/scaffoldOverrides.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/core/scaffold/scaffoldOverrides.js b/frontend/src/core/scaffold/scaffoldOverrides.js index 4409db93a2..6f4228ce0b 100644 --- a/frontend/src/core/scaffold/scaffoldOverrides.js +++ b/frontend/src/core/scaffold/scaffoldOverrides.js @@ -122,7 +122,7 @@ define(function(require) { { name: 'styles', items: ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock']}, { name: 'links', items: [ 'Link', 'Unlink' ] }, { name: 'colors', items: [ 'TextColor', 'BGColor' ] }, - { name: 'insert', items: [ 'SpecialChar' ] }, + { name: 'insert', items: [ 'SpecialChar', 'Table' ] }, { name: 'tools', items: [ ] }, { name: 'others', items: [ '-' ] } ], From 351dbf7b10f213c45f1fae89de834a293d400881 Mon Sep 17 00:00:00 2001 From: Brian Quinn Date: Wed, 2 Sep 2015 16:08:55 +0100 Subject: [PATCH 2/7] Added support for upgrading core plugins via script This features the addition of the lib/bowermanager.js helper, and moving the bower management to core. Further re-work is required to remove old, redundant code. --- lib/application.js | 46 +++-- lib/bowermanager.js | 338 ++++++++++++++++++++++++++++++++++ plugins/output/adapt/index.js | 2 +- routes/poll/index.js | 2 +- upgrade.js | 75 ++++++-- 5 files changed, 429 insertions(+), 34 deletions(-) create mode 100644 lib/bowermanager.js diff --git a/lib/application.js b/lib/application.js index 2e78caaa7f..e06c1fed92 100644 --- a/lib/application.js +++ b/lib/application.js @@ -362,7 +362,7 @@ Origin.prototype.createServer = function (options, cb) { }, configuration.getConfig('dbName')); }; -Origin.prototype.startServer = function () { +Origin.prototype.startServer = function (options) { // configure server var serverOptions = {}; if (!this.configuration || !this.configuration.getConfig('dbName')) { @@ -388,10 +388,10 @@ Origin.prototype.startServer = function () { callback(); }, function(callback) { - if (true === configuration.getConfig('isTestEnvironment')) { + if (true === configuration.getConfig('isTestEnvironment') || options.skipVersionCheck) { return callback(); } - + // Check the latest version of the project request({ headers: { @@ -400,9 +400,11 @@ Origin.prototype.startServer = function () { uri: 'https://api.github.com/repos/adaptlearning/adapt_authoring/tags', method: 'GET' }, function (error, response, body) { - if (!error && response.statusCode == 200) { + if (error) { + logger.log('error', error); + } else if (response.statusCode == 200) { var tagInfo = JSON.parse(body); - + if (tagInfo) { latestBuilderTag = tagInfo[0].name; } @@ -412,7 +414,7 @@ Origin.prototype.startServer = function () { }); }, function(callback) { - if (true === configuration.getConfig('isTestEnvironment')) { + if (true === configuration.getConfig('isTestEnvironment') || options.skipVersionCheck) { return callback(); } @@ -424,19 +426,21 @@ Origin.prototype.startServer = function () { uri: 'https://api.github.com/repos/adaptlearning/adapt_framework/tags', method: 'GET' }, function (error, response, body) { - if (!error && response.statusCode == 200) { + if (error) { + logger.log('error', error); + } else if (response.statusCode == 200) { var tagInfo = JSON.parse(body); if (tagInfo) { latestFrameworkTag = tagInfo[0].name; } - } + } callback(); }); }, function(callback) { - if (true === configuration.getConfig('isTestEnvironment')) { + if (true === configuration.getConfig('isTestEnvironment') || options.skipVersionCheck) { return callback(); } @@ -449,13 +453,12 @@ Origin.prototype.startServer = function () { isUpdateAvailable = true; } - // @TODO #771 - remove this check until the builder supports v2 of the framework - // if (installedFrameworkVersion == latestFrameworkTag) { - // console.log(chalk.green('Adapt Framework %s'), installedFrameworkVersion); - // } else { - // console.log(chalk.yellow('The Adapt Framework being used is %s - %s is now available'), installedFrameworkVersion, latestFrameworkTag); - // isUpdateAvailable = true; - // } + if (installedFrameworkVersion == latestFrameworkTag) { + console.log(chalk.green('Adapt Framework %s'), installedFrameworkVersion); + } else { + console.log(chalk.yellow('The Adapt Framework being used is %s - %s is now available'), installedFrameworkVersion, latestFrameworkTag); + isUpdateAvailable = true; + } if (isUpdateAvailable) { console.log("Run " + chalk.bgRed('"node upgrade.js"') + " to update to the latest version"); @@ -571,7 +574,13 @@ Origin.prototype.restartServer = function () { * @api public */ -Origin.prototype.run = function () { +Origin.prototype.run = function (options) { + if (!options) { + options = { + skipVersionCheck: false + }; + } + // some modules are loaded async, so wait for them before actually starting the server this.once('modulesReady', function (app) { try { @@ -584,7 +593,7 @@ Origin.prototype.run = function () { } app.mailer = new Mailer(); - app.startServer(); + app.startServer(options); }); @@ -602,6 +611,7 @@ Origin.prototype.run = function () { this.preloadModule('usermanager', require('./usermanager')); this.preloadModule('tenantmanager', require('./tenantmanager')); this.preloadModule('rolemanager', require('./rolemanager')); + this.preloadModule('bowermanager', require('./bowermanager')); this.preload(); }; diff --git a/lib/bowermanager.js b/lib/bowermanager.js new file mode 100644 index 0000000000..6c204e284b --- /dev/null +++ b/lib/bowermanager.js @@ -0,0 +1,338 @@ +var bower = require('bower'); +var async = require('async'); +var rimraf = require('rimraf'); +var semver = require('semver'); +var logger = require('./logger'); +var database = require('./database'); +var configuration = require('./configuration'); +var ncp = require('ncp').ncp; +var mkdirp = require('mkdirp'); +var fs = require('fs'); +var path = require('path'); +var _ = require('underscore'); +var bowerOptions = require('../plugins/content/bower/defaults.json'); + +/* + * CONSTANTS + */ +var MODNAME = 'bowermanager', + WAITFOR = 'contentmanager'; + +var BowerManager = function() { + +} + +BowerManager.prototype.extractPackageInfo = function(plugin, pkgMeta, schema) { + // Build package info. + var info = { + name: pkgMeta.name, + displayName: pkgMeta.displayName, + description: pkgMeta.description, + version: pkgMeta.version, + framework: pkgMeta.framework ? pkgMeta.framework : null, + isLocalPackage: pkgMeta.isLocalPackage ? pkgMeta.isLocalPackage : false, + properties: schema.properties, + globals: schema.globals ? schema.globals : null + }; + + if (pkgMeta.assetFields) { + info.assetFields = pkgMeta.assetFields; + } + + // Set the type and package id for the package. + info[plugin.getModelName()] = pkgMeta[plugin.getModelName()]; + + // Set extra properties. + plugin.extra && plugin.extra.forEach(function (key) { + if (pkgMeta[key]) { + info[key] = pkgMeta[key]; + } + }); + + return info; +} + +/** + * Installs a specified Adapt plugin. + * @param {string} pluginName - The name of the Adapt plugin + * @param {string} pluginVersion - The semantic version or branch name to install, for latest use '*' + * @param {function} callback - Callback function + */ +BowerManager.prototype.installPlugin = function(pluginName, pluginVersion, callback) { + var self = this; + + // Formulate the package name. + var packageName = (pluginVersion == '*') + ? pluginName + : pluginName + '#' + pluginVersion; + + // Interrogate the version.json file on installation as we cannot rely on including it via a 'require' call. + fs.readFile(path.join(configuration.getConfig('root'), 'version.json'), 'utf8', function(err, version) { + // Ensure the JSON is parsed. + version = JSON.parse(version); + + if (err) { + logger.log('error', err); + return callback(err); + } + + // Clear the bower cache for this plugin. + rimraf(path.join(bowerOptions.directory, pluginName), function (err) { + if (err) { + logger.log('error', err); + return callback(err); + } + + // Query bower to verify that the specified plugin exists. + bower.commands.search(packageName, bowerOptions) + .on('error', callback) + .on('end', function (results) { + if (!results) { + logger.log('warn', 'Plugin ' + packageName + ' not found!'); + return callback('Plugin ' + packageName + ' not found!'); + } + + // The plugin exists -- remove any fuzzy matches, e.g. adapt-contrib-assessment would + // also bring in adapt-contrib-assessmentResults, etc. + var bowerPackage = _.findWhere(results, {name: packageName}); + + // Install the plugin from bower. + bower.commands.install([bowerPackage.name], { save: true }, bowerOptions) + .on('error', function(err) { + logger.log('error', err); + return callback(err); + }) + .on('end', function (packageInfo) { + // Unfortunately this is required as the only way to identify the type + // of a plugin is to check for the presence of the property which + // actually indicates its type. :-/ + var pluginType = packageInfo[pluginName].pkgMeta.hasOwnProperty('component') + ? 'component' + : packageInfo[pluginName].pkgMeta.hasOwnProperty('extension') + ? 'extension' + : packageInfo[pluginName].pkgMeta.hasOwnProperty('menu') + ? 'menu' + : packageInfo[pluginName].pkgMeta.hasOwnProperty('theme') + ? 'theme' : '' + + if (pluginType == '') { + logger.log('error', 'Unable to identify pluginType for ' + packageName); + return callback('Unable to identify pluginType for ' + packageName); + } + + app.contentmanager.getContentPlugin(pluginType, function(err, plugin) { + if (err) { + return callback(err); + } + + if (packageInfo[pluginName].pkgMeta.framework) { + // If the plugin defines a framework, ensure that it is compatible + if (semver.satisfies(semver.clean(version.adapt_framework), packageInfo[pluginName].pkgMeta.framework)) { + self.importPackage(plugin, packageInfo[pluginName], bowerOptions, callback); + } else { + logger.log('error', 'Unable to install ' + packageInfo[pluginName].pkgMeta.name + '(' + packageInfo[pluginName].framework + ') as it is not supported in the current version of of the Adapt framework (' + version.adapt_framework + ')'); + return callback('Unable to install ' + packageInfo[pluginName].pkgMeta.name + ' as it is not supported in the current version of of the Adapt framework'); + } + } else { + self.importPackage(plugin, packageInfo[pluginName], bowerOptions, callback); + } + }); + }); + }); + }); + }); +} + +/** + * adds a new package to the system - fired after bower + * has installed to the cache + * + * @param {object} plugin - bowerConfig object for a bower plugin type + * @param {object} packageInfo - the bower package info retrieved during install + * @param {object} options + * @param {callback} callback + */ +BowerManager.prototype.importPackage = function (plugin, packageInfo, options, callback) { + // Shuffle params. + if ('function' === typeof options) { + callback = options; + options = { + strict: false + }; + } + + var self = this; + var pkgMeta = packageInfo.pkgMeta; + var schemaPath = path.join(packageInfo.canonicalDir, options._adaptSchemaFile); + + fs.exists(schemaPath, function (exists) { + if (!exists) { + if (options.strict) { + return callback('Package does not contain a schema'); + } + + logger.log('warn', 'ignoring package with no schema: ' + pkgMeta.name); + return callback(null); + } + + fs.readFile(schemaPath, function (err, data) { + var schema = false; + if (err) { + if (options.strict) { + return callback('Failed to parse schema for package ' + pkgMeta.name); + } + + logger.log('error', 'failed to parse schema for ' + pkgMeta.name, err); + return callback(null); + } + + try { + schema = JSON.parse(data); + } catch (e) { + if (options.strict) { + return callback('Failed to parse schema for package ' + pkgMeta.name); + } + + logger.log('error', 'failed to parse schema for ' + pkgMeta.name, e); + return callback(null); + } + + // Build a path to the destination working folder. + var destination = path.join(configuration.tempDir, configuration.getConfig('masterTenantID'), 'adapt_framework', 'src', plugin.bowerConfig.srcLocation, pkgMeta.name); + + // Remove whatever version of the plugin is there already. + rimraf(destination, function(err) { + if (err) { + return logger.log('error', err); + } + + // Re-create the plugin folder. + mkdirp(destination, function (err) { + if (err) { + return logger.log('error', err); + } + + // Move from the bower cache to the working directory. + ncp(packageInfo.canonicalDir, destination, function (err) { + if (err) { + // Don't double call callback. + return logger.log('error', err); + } + + // Copy the plugin into place. + ncp(packageInfo.canonicalDir, destination, function (err) { + if (err) { + return logger.log('error', err); + } + + logger.log('info', 'Successfully copied ' + pkgMeta.name + ' to ' + destination); + + // Build the package information. + var package = self.extractPackageInfo(plugin, pkgMeta, schema); + var db = app.db; + var pluginString = package.name + ' (v' + package.version + ')'; + + // Add the package to the collection. + // Check if a plugin with this name and version already exists. + db.retrieve(plugin.getPluginType(), { name: package.name, version: package.version }, function (err, results) { + if (err) { + logger.log('error', err); + return callback(err); + } + + if (results && results.length !== 0) { + // Don't add a duplicate. + if (options.strict) { + return callback("Can't add " + pluginString + ": verion already exists"); + } + + return callback(null); + } + + // Add the new plugin. + db.create(plugin.getPluginType(), package, function (err, newPlugin) { + if (err) { + logger.log('error', err); + + if (options.strict) { + return callback(err); + } + + logger.log('error', 'Failed to add package: ' + pluginString, err); + return callback(null); + } + + logger.log('info', 'Added package: ' + pluginString); + + // Retrieve any older versions of the plugin. + db.retrieve(plugin.getPluginType(), { name: package.name, version: { $ne: newPlugin.version } }, function (err, results) { + if (err) { + // strictness doesn't matter at this point + logger.log('error', 'Failed to retrieve previous packages: ' + err.message, err); + } + + // Remove older versions of this plugin. + db.destroy(plugin.getPluginType(), { name: package.name, version: { $ne: newPlugin.version } }, function (err) { + if (err) { + logger.log('error', err); + return callback(err); + } + + logger.log('info', 'Successfully removed versions of ' + package.name + ' (' + plugin.getPluginType() + ') older than ' + newPlugin.version); + + return callback(null, newPlugin); + }); // Remove older versions of the plugin. + }); // Retrieve older versions of the plugin. + }); // Add the new plugin. + }); // Check if a plugin with this name and version already exists. + }); + }); + }); + }); + }); + }); +} + +exports = module.exports = { + + // expose the bower manager constructor + BowerManager : BowerManager, + + /** + * preload function + * + * @param {object} app - AdaptBuilder instance + * @return {object} preloader - an AdaptBuilder ModulePreloader + */ + preload : function (app) { + var preloader = new app.ModulePreloader(app, MODNAME, { events: this.preloadHandle(app, new BowerManager()) }); + return preloader; + }, + + /** + * Event handler for preload events + * + * @param {object} app - Server instance + * @param {object} instance - Instance of this module + * @return {object} hash map of events and handlers + */ + preloadHandle : function (app, instance){ + + return { + preload : function(){ + var preloader = this; + preloader.emit('preloadChange', MODNAME, app.preloadConstants.WAITING); + }, + + moduleLoaded : function(modloaded){ + var preloader = this; + + //is the module that loaded this modules requirement + if (modloaded === WAITFOR) { + app.bowermanager = instance; + preloader.emit('preloadChange', MODNAME, app.preloadConstants.COMPLETE); + } + } + }; + } +}; diff --git a/plugins/output/adapt/index.js b/plugins/output/adapt/index.js index 20575f1b2c..7a677534d4 100644 --- a/plugins/output/adapt/index.js +++ b/plugins/output/adapt/index.js @@ -147,7 +147,7 @@ AdaptOutput.prototype.publish = function (courseId, isPreview, request, response var args = []; - args.push('--outputdir=' + path.join(Constants.Folders.AllCourses, tenantId, courseId)); + args.push('--outputdir=' + path.join(Constants.Folders.AllCourses, tenantId, courseId, Constants.Folders.Build)); args.push('--theme=' + themeName); args.push('--menu=' + menuName); diff --git a/routes/poll/index.js b/routes/poll/index.js index c643d9e488..5f2afcb98f 100644 --- a/routes/poll/index.js +++ b/routes/poll/index.js @@ -13,7 +13,7 @@ server.get('/poll/:id', function (request, response, next) { var pollUrl = configuration.getConfig('buildServerStatusUrl'); - if (pollUrl && id != 0) { + if (pollUrl && id !== 0) { var req = http.get(pollUrl + id, function(res) { // Buffer the body entirely for processing as a whole. diff --git a/upgrade.js b/upgrade.js index a4d1aa3e59..e9e491aa3b 100644 --- a/upgrade.js +++ b/upgrade.js @@ -1,14 +1,17 @@ +var builder = require('./lib/application'); var prompt = require('prompt'); var fs = require('fs'); var request = require('request'); var async = require('async'); var exec = require('child_process').exec; var rimraf = require('rimraf'); +var path = require('path'); // Constants var DEFAULT_USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'; // GLOBALS +var app = builder(); var installedBuilderVersion = ''; var latestBuilderTag = ''; var installedFrameworkVersion = ''; @@ -19,6 +22,14 @@ var versionFile = JSON.parse(fs.readFileSync('version.json'), {encoding: 'utf8'} var configFile = JSON.parse(fs.readFileSync('conf/config.json'), {encoding: 'utf8'}); var steps = [ + function(callback) { + app.run({skipVersionCheck: true}); + + app.on('serverStarted', function () { + console.log('Server has started'); + callback(); + }); + }, function(callback) { console.log('Checking versions'); @@ -72,21 +83,10 @@ var steps = [ var tagInfo = JSON.parse(body); if (tagInfo) { - // For now - we should only worry about v1 tags of the framework - async.detectSeries(tagInfo, function(tag, callback) { - if (tag.name.split('.')[0] == 'v1') { - callback(tag); - } else { - callback(false); - } - }, function(latestVersion) { - - latestFrameworkTag = latestVersion.name; - callback(); - - }); + latestFrameworkTag = tagInfo[0].name; } + callback(); } }); @@ -97,7 +97,7 @@ var steps = [ shouldUpdateBuilder = true; console.log('Update for Adapt Builder is available: ' + latestBuilderTag); } - + if (latestFrameworkTag != installedFrameworkVersion) { shouldUpdateFramework = true; console.log('Update for Adapt Framework is available: ' + latestFrameworkTag); @@ -161,6 +161,41 @@ var steps = [ }); }, function(callback) { + if (shouldUpdateFramework) { + // If the framework has been updated, interrogate the adapt.json file from the adapt_framework + // folder and install the latest versions of the core plugins + fs.readFile(path.join(configFile.root, 'temp', configFile.masterTenantID, 'adapt_framework', 'adapt.json'), function (err, data) { + if (err) { + return callback(err); + } + + var json = JSON.parse(data); + // 'dependencies' contains a key-value pair representing the plugin name and the semver + var plugins = Object.keys(json.dependencies); + + async.eachSeries(plugins, function(plugin, pluginCallback) { + app.bowermanager.installPlugin(plugin, json.dependencies[plugin], function(err) { + if (err) { + return pluginCallback(err); + } + + pluginCallback(); + }); + + }, function(err) { + if (err) { + console.log(err); + return callback(err); + } + + callback(); + }); + }); + } else { + callback(); + } + }, + function(callback) { // Left empty for any upgrade scripts - just remember to call the callback when done. callback(); } @@ -183,6 +218,18 @@ prompt.get({ name: 'Y/n', type: 'string', default: 'Y' }, function (err, result) return exitUpgrade(1, 'Upgrade was unsuccessful. Please check the console output.'); } + console.log(' '); + + if (shouldUpdateFramework) { + console.log('Run \`npm install\` from the /temp/' + configFile.masterTenantID + '/adapt_framework folder'); + } + + if (shouldUpdateBuilder) { + console.log('Run \'npm install\` followed by \'grunt build:prod\''); + } + + console.log(' '); + exitUpgrade(0, 'Great work! Your Adapt Builder is now updated.'); }); }); From f275862cc7bff75c11038b8252c5b1c707664242 Mon Sep 17 00:00:00 2001 From: Brian Quinn Date: Wed, 2 Sep 2015 16:50:23 +0100 Subject: [PATCH 3/7] Added conditional check for outputdir argument The 'build' folder was automatically added in v1.x of the Adapt framework but is not in v2.x. This change should allow backwards compatibility. --- plugins/output/adapt/index.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/output/adapt/index.js b/plugins/output/adapt/index.js index 7a677534d4..f847dbc317 100644 --- a/plugins/output/adapt/index.js +++ b/plugins/output/adapt/index.js @@ -20,6 +20,8 @@ var OutputPlugin = require('../../../lib/outputmanager').OutputPlugin, usermanager = require('../../../lib/usermanager'), assetmanager = require('../../../lib/assetmanager'), exec = require('child_process').exec, + semver = require('semver'), + version = require('../../../version'), logger = require('../../../lib/logger'); function AdaptOutput () { @@ -146,8 +148,14 @@ AdaptOutput.prototype.publish = function (courseId, isPreview, request, response logger.log('info', '3.1. Ensuring framework build exists'); var args = []; - - args.push('--outputdir=' + path.join(Constants.Folders.AllCourses, tenantId, courseId, Constants.Folders.Build)); + var outputFolder = path.join(Constants.Folders.AllCourses, tenantId, courseId); + + // Append the 'build' folder to later versions of the framework + if (semver.gt(semver.clean(version.adapt_framework), '2.0.0')) { + outputFolder = path.join(outputFolder, Constants.Folders.Build); + } + + args.push('--outputdir=' + outputFolder); args.push('--theme=' + themeName); args.push('--menu=' + menuName); From 17c8ad27778921b5523d581912f2d307af6d14ec Mon Sep 17 00:00:00 2001 From: Brian Quinn Date: Wed, 2 Sep 2015 16:51:43 +0100 Subject: [PATCH 4/7] Added 'framework' to bower plugin schema. --- plugins/content/bower/bowerplugin.schema | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/content/bower/bowerplugin.schema b/plugins/content/bower/bowerplugin.schema index f115e5a189..2e316875a3 100644 --- a/plugins/content/bower/bowerplugin.schema +++ b/plugins/content/bower/bowerplugin.schema @@ -20,6 +20,10 @@ "type": "string", "required": true }, + "framework":{ + "type": "string", + "required": true + }, "_isAvailableInEditor": { "type":"boolean", "default": true, From e0372bbdc4b539456884465a1accee4eb6e9335e Mon Sep 17 00:00:00 2001 From: Brian Quinn Date: Thu, 3 Sep 2015 09:42:52 +0100 Subject: [PATCH 5/7] Tidy up of lib/application.js - Swapped console.log() calls for logger.log() - Moved defaulting the 'options' object to startServer() --- lib/application.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/application.js b/lib/application.js index e06c1fed92..9c40cd0f88 100644 --- a/lib/application.js +++ b/lib/application.js @@ -363,6 +363,12 @@ Origin.prototype.createServer = function (options, cb) { }; Origin.prototype.startServer = function (options) { + + // Ensure that the options object is set. + options = typeof options === 'undefined' + ? { skipVersionCheck: false } + : options; + // configure server var serverOptions = {}; if (!this.configuration || !this.configuration.getConfig('dbName')) { @@ -447,22 +453,21 @@ Origin.prototype.startServer = function (options) { var isUpdateAvailable = false; if (installedBuilderVersion == latestBuilderTag) { - console.log(chalk.green('Adapt Builder %s'), installedBuilderVersion); + logger.log('info', chalk.green('Adapt Builder %s'), installedBuilderVersion); } else { - console.log(chalk.yellow('You are currently running Adapt Builder %s - %s is now available'), installedBuilderVersion, latestBuilderTag); + logger.log('info', chalk.yellow('You are currently running Adapt Builder %s - %s is now available'), installedBuilderVersion, latestBuilderTag); isUpdateAvailable = true; } if (installedFrameworkVersion == latestFrameworkTag) { - console.log(chalk.green('Adapt Framework %s'), installedFrameworkVersion); + logger.log('info', chalk.green('Adapt Framework %s'), installedFrameworkVersion); } else { - console.log(chalk.yellow('The Adapt Framework being used is %s - %s is now available'), installedFrameworkVersion, latestFrameworkTag); + logger.log('info', chalk.yellow('The Adapt Framework being used is %s - %s is now available'), installedFrameworkVersion, latestFrameworkTag); isUpdateAvailable = true; } if (isUpdateAvailable) { - console.log("Run " + chalk.bgRed('"node upgrade.js"') + " to update to the latest version"); - console.log(); + logger.log('info', "Run " + chalk.bgRed('"node upgrade.js"') + " to update to the latest version"); } callback(); @@ -564,7 +569,7 @@ Origin.prototype.restartServer = function () { app.startServer(); }); } catch (error) { - console.log(error); + logger.log('error', error); } } }; @@ -575,12 +580,6 @@ Origin.prototype.restartServer = function () { */ Origin.prototype.run = function (options) { - if (!options) { - options = { - skipVersionCheck: false - }; - } - // some modules are loaded async, so wait for them before actually starting the server this.once('modulesReady', function (app) { try { From d5814d719cb6f789efa5850c54efeada195f4dbf Mon Sep 17 00:00:00 2001 From: Brian Quinn Date: Thu, 3 Sep 2015 15:07:56 +0100 Subject: [PATCH 6/7] Resolves #737, removes editor attributes from published JSON In course.json: - customStyle - tags - heroImage In components.json: - _componentType While looking into this it was noticed that the editorOnly property did not work with arrays/array items -- that is now fixed. --- lib/dml/mongoose/index.js | 6 ++++-- plugins/content/component/model.schema | 3 ++- plugins/content/course/model.schema | 7 +++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/dml/mongoose/index.js b/lib/dml/mongoose/index.js index d49734be5c..c47c0858fc 100644 --- a/lib/dml/mongoose/index.js +++ b/lib/dml/mongoose/index.js @@ -445,8 +445,10 @@ MongooseDB.prototype.addSchema = function (modelName, schema) { schema.options.toJSON = { transform: function (doc, json, options) { Object.keys(rawSchema).forEach(function (key) { - if (options && options.forExport && rawSchema[key].editorOnly && json.hasOwnProperty(key)) { - delete json[key]; + if (options && options.forExport && (rawSchema[key].editorOnly + || (Array.isArray(rawSchema[key]) && rawSchema[key].length == 1 && rawSchema[key][0].editorOnly) + && json.hasOwnProperty(key))) { + delete json[key]; } if (rawSchema[key].protect && json.hasOwnProperty(key)) { diff --git a/plugins/content/component/model.schema b/plugins/content/component/model.schema index ddc2beb4c7..1a184079d1 100644 --- a/plugins/content/component/model.schema +++ b/plugins/content/component/model.schema @@ -12,7 +12,8 @@ }, "_type": { "type":"string", - "id": "http://jsonschema.net/_type" + "id": "http://jsonschema.net/_type", + "editorOnly": true }, "_component": { "type": "string", diff --git a/plugins/content/course/model.schema b/plugins/content/course/model.schema index cce85ea67c..d75688cbcb 100644 --- a/plugins/content/course/model.schema +++ b/plugins/content/course/model.schema @@ -8,7 +8,8 @@ "type": "string", "default": "", "inputType": "Asset:image", - "validators": [] + "validators": [], + "editorOnly": true }, "title": { "type": "string", @@ -445,6 +446,7 @@ "type": "objectid", "inputType": "Text", "required": false, + "editorOnly": true, "ref": "tag" }, "help": "Add tags to your course by entering one or more words, separated with a comma (,)", @@ -495,7 +497,8 @@ "inputType": "TextArea:blank", "validators": [], "title": "Custom CSS/LESS code", - "help": "Add any custom CSS or valid LESS code here" + "help": "Add any custom CSS or valid LESS code here", + "editorOnly": true } } } From 9b48032369a1d05079e85a6d8c7bbd53d7a19ad4 Mon Sep 17 00:00:00 2001 From: Brian Quinn Date: Thu, 3 Sep 2015 15:30:36 +0100 Subject: [PATCH 7/7] Correction - setting editorOnly: true to the correct attribute --- plugins/content/component/model.schema | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/content/component/model.schema b/plugins/content/component/model.schema index 1a184079d1..43ffac15f5 100644 --- a/plugins/content/component/model.schema +++ b/plugins/content/component/model.schema @@ -8,12 +8,11 @@ "type": "objectid", "required": true, "ref": "componenttype", - "editorOnly": false + "editorOnly": true }, "_type": { "type":"string", - "id": "http://jsonschema.net/_type", - "editorOnly": true + "id": "http://jsonschema.net/_type" }, "_component": { "type": "string",