Handle association on upload route

This commit is contained in:
Aurelsicoko 2018-02-27 16:53:06 +01:00
parent ab108a6f93
commit dac8931676
9 changed files with 103 additions and 43 deletions

View File

@ -1,6 +1,6 @@
const _ = require('lodash');
module.exports = {
module.exports = {
find: async function (params) {
return this.query(function(qb) {
_.forEach(params.where, (where, key) => {

View File

@ -19,13 +19,14 @@ module.exports = {
.findOne({
[this.primaryKey]: params[this.primaryKey] || params.id
})
.populate(this.associations.map(x => x.alias).join(' '));
.populate(this.associations.map(x => x.alias).join(' '))
.lean();
},
create: async function (params) {
// Exclude relationships.
const values = Object.keys(params.values).reduce((acc, current) => {
if (this._attributes[current].type) {
if (this._attributes[current] && this._attributes[current].type) {
acc[current] = params.values[current];
}
@ -39,10 +40,10 @@ module.exports = {
.map(obj => {
const globalId = obj.source && obj.source !== 'content-manager' ?
strapi.plugins[obj.source].models[obj.model].globalId:
strapi.models[obj.model].globalId;
strapi.models[obj.ref.toLowerCase()].globalId;
return {
ref: obj.ref,
ref: obj.refId,
kind: globalId,
[association.filter]: obj.field
}
@ -202,9 +203,9 @@ module.exports = {
}));
// Update virtuals fields.
const process = await Promise.all(virtualFields);
await Promise.all(virtualFields);
return process[process.length - 1];
return await module.exports.findOne.call(this, params);
},
delete: async function (params) {

View File

@ -40,9 +40,12 @@ module.exports = {
edit: async (params, values, source) => {
// Multipart/form-data.
if (values.hasOwnProperty('fields') && values.hasOwnProperty('files')) {
// Parse stringify JSON data.
const parsedFields = JSON.parse(values.fields);
// Update JSON fields (files are exlucded).
const fields = await strapi.query(params.model, source).update({
id: params.id,
values
values: parsedFields
});
// Request plugin upload.
@ -53,7 +56,15 @@ module.exports = {
name: 'upload'
}).get({ key: 'provider' });
const arrayOfPromise = await Promise.all(
// Retrieve primary key.
const primaryKey = strapi.query(params.model, source).primaryKey;
// Delete removed files.
const entry = await strapi.query(params.model, source).findOne({
id: params.id
});
await Promise.all(
Object.keys(values.files)
.map(async attribute => {
// Bufferize files per attribute.
@ -71,8 +82,34 @@ module.exports = {
return file;
});
const arrayOfPromises = [strapi.plugins.upload.services.upload.upload(files, config)];
// Remove deleted files.
if (parsedFields[attribute]) {
const transformToArrayID = (array) => {
return _.isArray(array) ? array.map(value => {
if (_.isPlainObject(value)) {
return value[primaryKey];
}
return value;
}) : array;
};
// Compare array of ID to find deleted files.
const currentValue = transformToArrayID(parsedFields[attribute]);
const storedValue = transformToArrayID(entry[attribute]);
const removeRelations = _.difference(storedValue, currentValue);
console.log("removeRelation", removeRelation);
// TODO:
// - Remove relationships in files.
}
// Make upload async.
return await strapi.plugins.upload.services.upload.upload(files, config);
return await Promise.all(arrayOfPromises);
})
);
}

View File

@ -17,41 +17,60 @@ module.exports = {
*/
index: async (ctx) => {
// Retrieve provider configuration.
const config = await strapi.store({
environment: strapi.config.environment,
type: 'plugin',
name: 'upload'
}).get({key: 'provider'});
if (!config.enabled) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.disabled' }] }] : 'Upload is disabled!');
// Verify if the file upload is enable.
if (config.enabled === false) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.disabled' }] }] : 'The file upload is disabled!');
}
const Service = strapi.plugins['upload'].services.upload;
// Extract optional relational data.
const { refId, ref, source, field } = ctx.request.body.fields;
// transform stream files to buffer
const files = await Service.bufferize(ctx.request.body.files.files);
// Transform stream files to buffer
const buffers = await strapi.plugins.upload.services.upload.bufferize(ctx.request.body.files.files);
const files = buffers.map(file => {
if (file.size > config.sizeLimit) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.sizeLimit', values: {file: file.name} }] }] : `${file.name} file is bigger than limit size!`);
}
for (var i = 0; i < files.length; i++) {
if (files[i].size > config.sizeLimit) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.sizeLimit', values: {file: files[i].name} }] }] : `${files[i].name} file is bigger than limit size!`);
}
// Add details to the file to be able to create the relationships.
if (refId && ref && field) {
Object.assign(file, {
related: [{
refId,
ref,
source,
field
}]
});
}
return file;
});
// Something is wrong (size limit)...
if (ctx.status === 400) {
return;
}
await Service.upload(files, config);
const uploadedFiles = await strapi.plugins.upload.services.upload.upload(files, config);
// Send 200 `ok`
ctx.send(files.map((file) => {
delete file.buffer;
// if is local server upload, add backend host as prefix
if (_.startsWith(file.url, '/')) {
ctx.send(uploadedFiles.map((file) => {
// If is local server upload, add backend host as prefix
if (file.url && file.url[0] === '/') {
file.url = strapi.config.url + file.url;
}
// Static data waiting relations
file.updatedAt = new Date();
file.relatedTo = 'John Doe';
if (_.isArray(file.related)) {
file.related = file.related.map(obj => obj.ref || obj);
}
return file;
}));
@ -86,7 +105,7 @@ module.exports = {
// Send 200 `ok`
ctx.send(data.map((file) => {
// if is local server upload, add backend host as prefix
if (_.startsWith(file.url, '/')) {
if (file.url[0] === '/') {
file.url = strapi.config.url + file.url;
}

View File

@ -42,20 +42,19 @@ module.exports = {
},
upload: async (files, config) => {
// get upload provider settings to configure the provider to use
const provider = _.cloneDeep(_.find(strapi.plugins.upload.config.providers, {provider: config.provider}));
_.assign(provider, config);
const actions = provider.init(strapi, config);
// Get upload provider settings to configure the provider to use.
const provider = _.find(strapi.plugins.upload.config.providers, { provider: config.provider });
const actions = provider.init(config);
// execute upload function of the provider for all files
// Execute upload function of the provider for all files.
return Promise.all(
files.map(async file => {
await actions.upload(file);
// remove buffer to don't save it
// Remove buffer to don't save it.
delete file.buffer;
await strapi.plugins['upload'].services.upload.add(file);
return await strapi.plugins['upload'].services.upload.add(file);
})
);
},

View File

@ -49,7 +49,7 @@ module.exports = {
type: 'text'
}
},
init: (strapi, config) => {
init: (config) => {
// configure AWS S3 bucket connection
AWS.config.update({
accessKeyId: config.auth.public,

View File

@ -11,7 +11,7 @@ const path = require('path');
module.exports = {
provider: 'local',
name: 'Local server',
init: (strapi, config) => {
init: (config) => {
return {
upload: (file) => {
return new Promise((resolve, reject) => {

View File

@ -315,10 +315,10 @@ class Strapi extends EventEmitter {
// Bind queries with the current model to allow the use of `this`.
const bindQueries = Object.keys(queries).reduce((acc, current) => {
return acc[current] = queries[current].bind(Model), acc;
}, {});
// Send ORM to the called function.
bindQueries.orm = connector;
}, {
orm: connector,
primaryKey: Model.primaryKey
});
return bindQueries;
}

View File

@ -11,7 +11,11 @@ module.exports = strapi => {
*/
initialize: function(cb) {
strapi.app.use(strapi.koaMiddlewares.body(strapi.config.middleware.settings.parser));
strapi.app.use(strapi.koaMiddlewares.body(Object.assign({
patchKoa: true,
},
strapi.config.middleware.settings.parser
)));
cb();
}