UNPKG

keystone

Version:

Web Application Framework and Admin GUI / Content Management System built on Express.js and Mongoose

370 lines (306 loc) 9.54 kB
/** Deprecated. Using this field will now throw an error, and this code will be removed soon. See https://github.com/keystonejs/keystone/wiki/File-Fields-Upgrade-Guide */ /* eslint-disable */ /** * localfiles FieldType Constructor * @extends Field * @api public */ function localfiles (list, path, options) { throw new Error('The LocalFiles field type has been removed. Please use File instead.' + '\n\nSee https://github.com/keystonejs/keystone/wiki/File-Fields-Upgrade-Guide\n'); /* grappling.mixin(this).allowHooks('move'); this._underscoreMethods = ['format', 'uploadFiles']; this._fixedSize = 'full'; // TODO: implement filtering, usage disabled for now options.nofilter = true; // TODO: implement initial form, usage disabled for now if (options.initial) { throw new Error('Invalid Configuration\n\n' + 'localfiles fields (' + list.key + '.' + path + ') do not currently support being used as initial fields.\n'); } if (options.overwrite !== false) { options.overwrite = true; } localfiles.super_.call(this, list, path, options); // validate destination dir if (!options.dest) { throw new Error('Invalid Configuration\n\n' + 'localfiles fields (' + list.key + '.' + path + ') require the "dest" option to be set.'); } // Allow hook into before and after if (options.pre && options.pre.move) { this.pre('move', options.pre.move); } if (options.post && options.post.move) { this.post('move', options.post.move); } */ } localfiles.properName = 'LocalFiles'; // util.inherits(localfiles, FieldType); /** * Registers the field on the List's Mongoose Schema. */ localfiles.prototype.addToSchema = function (schema) { var field = this; var mongoose = keystone.mongoose; var paths = this.paths = { // fields filename: this.path + '.filename', path: this.path + '.path', originalname: this.path + '.originalname', size: this.path + '.size', filetype: this.path + '.filetype', // virtuals exists: this.path + '.exists', upload: this.path + '_upload', action: this.path + '_action', order: this.path + '_order', }; var schemaPaths = new mongoose.Schema({ filename: String, originalname: String, path: String, size: Number, filetype: String, }); // The .href virtual returns the public path of the file schemaPaths.virtual('href').get(function () { return field.href(this); }); schema.add(this._path.addTo({}, [schemaPaths])); var exists = function (item, element_id) { var values = item.get(field.path); var value; if (typeof values === 'undefined' || values.length === 0) { return false; } // if current Field contains any file, it means it exists if (typeof element_id === 'undefined') { value = values[0]; } else { // allow implicit type coercion to compare string IDs with MongoID objects value = values.find(function (val) { return val._id == element_id; }); // eslint-disable-line eqeqeq } if (typeof value === 'undefined') { return false; } var filepaths = value.path; var filename = value.filename; if (!filepaths || !filename) { return false; } return fs.existsSync(path.join(filepaths, filename)); }; // The .exists virtual indicates whether a file is stored schema.virtual(paths.exists).get(function () { return schemaMethods.exists.apply(this); }); var reset = function (item, element_id) { if (typeof element_id === 'undefined') { item.set(field.path, []); } else { var values = item.get(field.path); // allow implicit type coercion to compare string IDs with MongoID objects var value = values.find(function (val) { return val._id == element_id; }); // eslint-disable-line eqeqeq if (typeof value !== 'undefined') { values.splice(values.indexOf(value), 1); item.set(field.path, values); } } }; var schemaMethods = { exists: function () { return exists(this); }, /** * Resets the value of the field */ reset: function () { reset(this); }, /** * Deletes the file from localfiles and resets the field */ delete: function (element_id) { if (exists(this, element_id)) { var values = this.get(field.path); // allow implicit type coercion to compare string IDs with MongoID objects var value = values.find(function (val) { return val._id == element_id; }); // eslint-disable-line eqeqeq if (typeof value !== 'undefined') { fs.unlinkSync(path.join(value.path, value.filename)); } } reset(this, element_id); }, }; _.forEach(schemaMethods, function (fn, key) { field.underscoreMethod(key, fn); }); // expose a method on the field to call schema methods this.apply = function (item, method) { return schemaMethods[method].apply(item, Array.prototype.slice.call(arguments, 2)); }; this.bindUnderscoreMethods(); }; /** * Formats the field value */ localfiles.prototype.format = function (item, i) { var files = item.get(this.path); if (typeof i === 'undefined') { return utils.plural(files.length, '* File'); } var file = files[i]; if (!file) return ''; if (this.hasFormatter()) { file.href = this.href(file); return this.options.format.call(this, item, file); } return file.filename; }; /** * Detects whether the field has a formatter function */ localfiles.prototype.hasFormatter = function () { return typeof this.options.format === 'function'; }; /** * Return the public href for a single stored file */ localfiles.prototype.href = function (file) { if (!file.filename) return ''; var prefix = this.options.prefix ? this.options.prefix : file.path; return prefix + '/' + file.filename; }; /** * Detects whether the field has been modified */ localfiles.prototype.isModified = function (item) { return item.isModified(this.paths.path); }; /** * Validates that a value for this field has been provided in a data object * * Deprecated */ localfiles.prototype.inputIsValid = function (data) { // eslint-disable-line no-unused-vars // TODO - how should file field input be validated? return true; }; /** * Updates the value for this field in the item from a data object */ localfiles.prototype.updateItem = function (item, data, callback) { // eslint-disable-line no-unused-vars // TODO - direct updating of data (not via upload) process.nextTick(callback); }; /** * Uploads the file for this field */ localfiles.prototype.uploadFiles = function (item, files, update, callback) { var field = this; if (typeof update === 'function') { callback = update; update = false; } async.map(files, function (file, processedFile) { var prefix = field.options.datePrefix ? moment().format(field.options.datePrefix) + '-' : ''; var filename = prefix + file.name; var filetype = file.mimetype || file.type; if (field.options.allowedTypes && !_.includes(field.options.allowedTypes, filetype)) { return processedFile(new Error('Unsupported File Type: ' + filetype)); } var doMove = function (doneMove) { if (typeof field.options.filename === 'function') { filename = field.options.filename(item, file); } fs.move(file.path, path.join(field.options.dest, filename), { clobber: field.options.overwrite }, function (err) { if (err) return doneMove(err); var fileData = { filename: filename, originalname: file.originalname, path: field.options.dest, size: file.size, filetype: filetype, }; if (update) { item.get(field.path).push(fileData); } doneMove(null, fileData); }); }; field.callHook('pre:move', item, file, function (err) { if (err) return processedFile(err); doMove(function (err, fileData) { if (err) return processedFile(err); field.callHook('post:move', item, file, fileData, function (err) { return processedFile(err, fileData); }); }); }); }, callback); }; /** * Returns a callback that handles a standard form submission for the field * * Expected form parts are * - `field.paths.action` in `req.body` (`clear` or `delete`) * - `field.paths.upload` in `req.files` (uploads the file to localfiles) */ localfiles.prototype.getRequestHandler = function (item, req, paths, callback) { var field = this; if (utils.isFunction(paths)) { callback = paths; paths = field.paths; } else if (!paths) { paths = field.paths; } callback = callback || function () {}; return function () { // Order if (req.body[paths.order]) { var files = item.get(field.path); var newOrder = req.body[paths.order].split(','); files.sort(function (a, b) { return (newOrder.indexOf(a._id.toString()) > newOrder.indexOf(b._id.toString())) ? 1 : -1; }); } // Removals if (req.body && req.body[paths.action]) { var actions = req.body[paths.action].split('|'); actions.forEach(function (action) { action = action.split(':'); var method = action[0]; var ids = action[1]; if (!(/^(delete|reset)$/.test(method)) || !ids) return; ids.split(',').forEach(function (id) { field.apply(item, method, id); }); }); } // Upload new files if (req.files) { var upFiles = req.files[paths.upload]; if (upFiles) { if (!Array.isArray(upFiles)) { upFiles = [upFiles]; } if (upFiles.length > 0) { upFiles = _.filter(upFiles, function (f) { return typeof f.name !== 'undefined' && f.name.length > 0; }); if (upFiles.length > 0) { return field.uploadFiles(item, upFiles, true, callback); } } } } return callback(); }; }; /* Export Field Type */ module.exports = localfiles;