Skip to content

Commit

Permalink
Merge pull request #630 from scottnath/feature/file-get
Browse files Browse the repository at this point in the history
Feature/file get
  • Loading branch information
Snugug authored Dec 22, 2016
2 parents 25b64a0 + 7ade084 commit ba69a77
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 26 deletions.
5 changes: 4 additions & 1 deletion config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ module.exports = {
dest: 'public/files',
settings: {},
public: '/files', // Can include {{dest}} for the dest path
temp: 'public/tmp/',
temp: {
dest: 'public/tmp/',
public: '/tmp',
},
},
};
28 changes: 28 additions & 0 deletions content-types/bar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,34 @@ attributes:
inputs:
text:
placeholder: add svc name
- type: email
id: service-email
name: Service Email
inputs:
text:
placeholder: add svc email
- type: file
id: image-file
name: Image Filer
inputs:
file:
settings:
types:
- .png
- .jpg
- .gif
- type: file
id: text-file
name: Text Filer
- type: file
id: bar-file-repeat
name: Bar File Repeater
repeatable: true
- type: text
id: bar-repeat-test
name: Bar Repeat Test
description: Checkin the repeatin
repeatable: true
- type: reference
id: bar-reference
name: Bar reference
Expand Down
162 changes: 152 additions & 10 deletions lib/content/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
'use strict';

const config = require('config');
const _ = require('lodash');

const storage = require('../storage');

/**
Expand Down Expand Up @@ -28,12 +31,25 @@ const fileinputs = attributes => {
return Object.keys(inputs).filter(input => {
return inputs[input].type === 'file'; // only want file inputs
}).map(input => {
const parts = inputs[input].name.split('--');
const parts = _.split(inputs[input].name, '--', 2);
const checkbox = Object.keys(inputs).filter(ipt => {
return inputs[ipt].type === 'checkbox'; // only want file input's checkbox
});
const repeatable = (attr.hasOwnProperty('repeatable') && typeof attr.repeatable === 'object');

return {
'attr': attr.id,
'input': parts[parts.length - 1],
'type': inputs[input].type,
attr: attr.id,
input: parts[parts.length - 1],
type: inputs[input].type,
repeatable,
file: {
name: `${attr.id}--${input}`,
input,
},
checkbox: {
name: `${attr.id}--${checkbox}`,
input: checkbox,
},
};
});
}).filter(filer => {
Expand Down Expand Up @@ -65,21 +81,21 @@ const filepaths = (files, data) => {
if (Array.isArray(files) && files.length > 0) {
files.forEach(filer => {
// if repeatable
if (Array.isArray(content[filer.attr][filer.input])) {
content[filer.attr][filer.input] = content[filer.attr][filer.input].map(inpt => {
if (Array.isArray(content[filer.attr])) {
content[filer.attr] = content[filer.attr].map(inpt => {
const input = inpt;

if (input.value.hasOwnProperty('original') && input.value.original !== '') {
input.value = storage.get(input.value);
if (input[filer.file.input] && input[filer.file.input].hasOwnProperty('value') && input[filer.file.input].value.hasOwnProperty('original') && input[filer.file.input].value.original !== '') {
input[filer.file.input].value = storage.get(input[filer.file.input].value);
}

return input;
});
}
else {
// non-repeatables
if (content[filer.attr] && content[filer.attr][filer.input].value.hasOwnProperty('original') && content[filer.attr][filer.input].value.original !== '') {
content[filer.attr][filer.input].value = storage.get(content[filer.attr][filer.input].value);
if (content[filer.attr] && content[filer.attr][filer.file.input] && content[filer.attr][filer.file.input].value.hasOwnProperty('original') && content[filer.attr][filer.file.input].value.original !== '') {
content[filer.attr][filer.file.input].value = storage.get(content[filer.attr][filer.file.input].value);
}
}
});
Expand All @@ -88,7 +104,133 @@ const filepaths = (files, data) => {
return content;
};

/**
* Captue files after validation error and add to value
*
* @param {array} files - An array of file objects as received from a multi-part form
* @param {object} val - captured non-file form data
* @param {object} attributes - content type attributes
*
* @returns {object} content values with files added in
*/
const filehold = (files, val, attributes) => {
const values = val;

if (!files || !Array.isArray(files) || !values || typeof values !== 'object' || !attributes || typeof attributes !== 'object') {
return values;
}

// get all file inputs from the content type attributes
const inputs = fileinputs(attributes);

// Add file paths to data
if (Array.isArray(inputs) && inputs.length > 0 && Array.isArray(files) && files.length > 0) {
inputs.forEach(filer => {
const filedata = files.find(file => {
return (file.originalname !== '' && file.fieldname === `${filer.attr}--${filer.input}`);
});

if (filedata) {
values[filer.attr] = {
[filer.input]: {
value: {
type: filedata.mimetype,
original: filedata.originalname,
path: `${config.storage.temp.public}/${filedata.originalname}`,
},
},
};
}
else {
const repeaters = files.filter(file => {
return (file.originalname !== '' && file.fieldname.startsWith(`${filer.attr}--${filer.input}--`));
});

if (Array.isArray(repeaters) && repeaters.length > 0) {
if (!values[filer.attr]) {
values[filer.attr] = [];
}

repeaters.forEach(repeater => {
values[filer.attr].push({
[filer.input]: {
value: {
type: repeater.mimetype,
original: repeater.originalname,
path: `${config.storage.temp.public}/${repeater.originalname}`,
},
},
});
});
}
}
});
}

return values;
};


/**
* Compare files from form against existing data
*
* @param {array} files - An array of file objects as received from a multi-part form
* @param {object} inserted - formatted data object with files, ready for storage
* @param {object} val - existing data
* @param {object} attributes - content type attributes
*
* @returns {object} content values with files added in
*/
const filecompare = (files, inserted, val, attributes) => {
const values = val;
const data = inserted;

if (!files || !Array.isArray(files) || !data || typeof data !== 'object' || !values || typeof values !== 'object' || !attributes || typeof attributes !== 'object') {
return values;
}

// get all file inputs from the content type attributes
const finputs = fileinputs(attributes);

// Add file paths to data
if (Array.isArray(finputs) && finputs.length > 0) {
finputs.forEach(finput => {
const filedata = files.find(file => {
return (file.originalname !== '' && file.fieldname === `${finput.attr}--${finput.input}`);
});

const checkbox = finput.checkbox;
const input = finput.file;

if (finput.repeatable) {
// do repeatable thingies
}
else {
// nothing new/deleted - grab file content from previous if it exists
if (!_.get(data, `${finput.attr}.${checkbox.input}`, false) && !filedata && _.get(val, `value.${finput.attr}.${input.input}`, false)) {
_.set(data, `${finput.attr}.${input.input}`, _.get(val, `value.${finput.attr}.${input.input}`));
}

// delete checkbox checked, clear file/delete
if (_.get(data, `${finput.attr}.${checkbox.input}`, false)) {
// clear checkbox data
delete data[finput.attr][checkbox.input];

// clear file data if there is any
if (_.get(data, `${finput.attr}.${input.input}`, false)) {
delete data[finput.attr][input.input];
}
}
}
});
}

return data;
};

module.exports = {
fileinputs,
filepaths,
filehold,
filecompare,
};
2 changes: 1 addition & 1 deletion lib/init/authenticated.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const config = require('config');
*
*/
const authenticated = (req, res, next) => {
if ((!req.isAuthenticated || !req.isAuthenticated()) && !req.url.startsWith('/create-admin') && req.url !== config.authentication.login.path && !req.url.startsWith('/css') && !req.url.startsWith('/js') && !req.url.startsWith('/images') && !req.url.startsWith('/favicon') && !req.url.startsWith('/api') && req.url !== '/robots.txt') {
if ((!req.isAuthenticated || !req.isAuthenticated()) && !req.url.startsWith('/create-admin') && req.url !== config.authentication.login.path && !req.url.startsWith('/css') && !req.url.startsWith('/js') && !req.url.startsWith('/images') && !req.url.startsWith('/favicon') && !req.url.startsWith('/api') && !req.url.startsWith('/tmp') && req.url !== '/robots.txt') {
res.redirect('/login');
}
else {
Expand Down
Loading

0 comments on commit ba69a77

Please sign in to comment.