190 lines
4.8 KiB
JavaScript
Raw Normal View History

'use strict';
/**
* Upload.js controller
*
*/
2018-02-21 14:06:57 +01:00
const _ = require('lodash');
const validateSettings = require('./validation/settings');
const { yup, formatYupErrors } = require('strapi-utils');
const apiUploadController = require('./api-upload');
const apiAdminUploadController = require('./api-admin-upload');
const fileInfoSchema = yup.object({
name: yup.string().nullable(),
alternativeText: yup.string().nullable(),
caption: yup.string().nullable(),
});
const uploadSchema = yup.object({
fileInfo: fileInfoSchema,
});
const multiUploadSchema = yup.object({
fileInfo: yup.array().of(fileInfoSchema),
});
const validateUploadBody = (schema, data = {}) => {
return schema.validate(data, { abortEarly: false }).catch(err => {
throw strapi.errors.badRequest('ValidationError', { errors: formatYupErrors(err) });
});
};
2018-02-21 14:06:57 +01:00
const isUploadDisabled = () => _.get(strapi.plugins, 'upload.config.enabled', true) === false;
const disabledPluginError = () =>
strapi.errors.badRequest(null, {
errors: [{ id: 'Upload.status.disabled', message: 'File upload is disabled' }],
});
2019-08-01 07:48:52 +02:00
const emptyFileError = () =>
strapi.errors.badRequest(null, {
errors: [{ id: 'Upload.status.empty', message: 'Files are empty' }],
});
2018-02-20 17:10:25 +01:00
// Assign created_by and updated_by on medias
const setCreatorInfo = (ctx, files, { edition = false } = {}) => {
if (!Array.isArray(files)) files = [files];
return Promise.all(
files.map(file => {
if (ctx.state.isAuthenticatedAdmin) {
if (edition) {
return strapi.query('file', 'upload').update(
{ id: file.id },
{
updated_by: ctx.state.user.id,
}
);
}
return strapi.query('file', 'upload').update(
{ id: file.id },
{
created_by: ctx.state.user.id,
updated_by: ctx.state.user.id,
}
);
}
})
);
};
const resolveControllerFor = method => ctx => {
const {
state: { isAuthenticatedAdmin },
} = ctx;
const controller = isAuthenticatedAdmin ? apiAdminUploadController : apiUploadController;
const callbackFn = controller[method];
if (!_.isFunction(callbackFn)) {
return ctx.notFound();
}
return callbackFn(ctx);
};
module.exports = {
async upload(ctx) {
if (isUploadDisabled()) {
throw disabledPluginError();
2018-02-20 17:10:25 +01:00
}
const { id } = ctx.query;
const files = _.get(ctx.request.files, 'files');
// update only fileInfo if not file content sent
if (id && (_.isEmpty(files) || files.size === 0)) {
const data = await validateUploadBody(uploadSchema, ctx.request.body);
const file = await strapi.plugins.upload.services.upload.updateFileInfo(id, data.fileInfo);
await setCreatorInfo(ctx, file, { edition: true });
return (ctx.body = file);
}
if (_.isEmpty(files) || files.size === 0) {
throw emptyFileError();
2018-02-21 14:46:10 +01:00
}
const uploadService = strapi.plugins.upload.services.upload;
const validationSchema = Array.isArray(files) ? multiUploadSchema : uploadSchema;
const data = await validateUploadBody(validationSchema, ctx.request.body);
if (id) {
// cannot replace with more than one file
if (Array.isArray(files)) {
throw strapi.errors.badRequest(null, {
errors: [
{ id: 'Upload.replace.single', message: 'Cannot replace a file with multiple ones' },
],
});
}
const file = await uploadService.replace(id, { data, file: files });
await setCreatorInfo(ctx, file, { edition: true });
ctx.body = file;
} else {
const file = await uploadService.upload({ data, files });
await setCreatorInfo(ctx, file);
ctx.body = file;
}
},
async getSettings(ctx) {
const data = await strapi.plugins.upload.services.upload.getSettings();
ctx.body = { data };
2018-02-20 17:10:25 +01:00
},
async updateSettings(ctx) {
const data = await validateSettings(ctx.request.body);
2018-02-20 17:10:25 +01:00
await strapi.plugins.upload.services.upload.setSettings(data);
ctx.body = { data };
2018-02-20 17:10:25 +01:00
},
find: resolveControllerFor('find'),
findOne: resolveControllerFor('findOne'),
count: resolveControllerFor('count'),
destroy: resolveControllerFor('destroy'),
2018-02-22 17:12:03 +01:00
async search(ctx) {
const { id } = ctx.params;
ctx.body = await strapi.query('file', 'upload').custom(searchQueries)({
id,
});
2018-02-22 17:12:03 +01:00
},
};
const searchQueries = {
bookshelf({ model }) {
return ({ id }) => {
return model
.query(qb => {
qb.whereRaw('LOWER(hash) LIKE ?', [`%${id}%`]).orWhereRaw('LOWER(name) LIKE ?', [
`%${id}%`,
]);
})
.fetchAll()
.then(results => results.toJSON());
};
},
mongoose({ model }) {
return ({ id }) => {
const re = new RegExp(id, 'i');
2019-12-24 17:49:17 +01:00
return model
.find({
$or: [{ hash: re }, { name: re }],
})
.lean();
};
},
};