File: D:/HostingSpaces/RImmers2/portal.photomenu.nl/wwwroot/controllers/restaurants.js
exports.install = function () {
F.route('/restaurants', restraurantsIndex, ['get', 'authorize']);
F.route('/restaurants/edit/{id}', restraurantsEdit, ['get', 'authorize']);
F.route('/restaurants/edit/{id}', restraurantsPost, ['+xhr', 'upload', 'post']);
F.route('/restaurants/edit/{id}/delete-image/{index}', deleteImage, ['get']);
F.route('/restaurants/delete/{id}', restraurantsDelete, ['get', 'authorize']);
};
const path = require('path');
const Promise = require("bluebird");
const uuidV4 = require('uuid/v4');
const phoneFormatter = require('phone');
const validator = require('validator');
const gm = require('gm').subClass({
imageMagick: false
});
function sendEmail(fromaddress,toaddress,txtsubject,txthtml,bodytext,filePath) {
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
var transporter = nodemailer.createTransport(smtpTransport({
host: 'localhost',
port: 25
}));
transporter.sendMail({
from: fromaddress,
to: toaddress,
subject: txtsubject,
html: txthtml,
text: bodytext,
// attachments: [
// { // utf-8 string as an attachment
// path: filePath
// }]
}).catch(err => {
console.log(err);
});
}
function deleteImage(id, index) {
const params = {};
const self = this;
F.model('restaurant').load(id).then(function (restaurant) {
params.id = id;
params.restaurant = restaurant;
if (params.restaurant.images.length === 1) {
params.error = true;
params.errorMessage = "At least one image is required."
self.layout('/layouts/protected');
self.view('/restaurants/edit', params);
} else {
const result = [];
params.restaurant.images.forEach((url, i) => {
if (i !== +index) {
result.push(url);
}
})
params.restaurant.images = result;
return F.model('restaurant').edit(params).then(function () {
self.res.redirect(`/restaurants/edit/${id}`);
})
}
}).catch(err => console.log(err));
}
function restraurantsIndex() {
var self = this;
var params = {};
F.model('restaurant').list().then(function (snapshot) {
params.list = {};
if (self.repository.type === 'restaurant') {
let item = snapshot.val()[self.repository.currentRestaurant];
item.key = self.repository.currentRestaurant;
params.list = [item];
} else {
let sorted = [];
snapshot.forEach(r => {
let item = r.val();
item.key = r.key;
sorted.push(item);
})
// params.list = sorted.sort((i1, i2) => {
// if (i1.Name.toLowerCase() < i2.Name.toLowerCase()) return -1;
// if (i1.Name.toLowerCase() === i2.Name.toLowerCase()) return 0;
// if (i1.Name.toLowerCase() > i2.Name.toLowerCase()) return 1;
// });
// params.list = sorted.sort((i1, i2) => {
// if (i1.Inactive == 0) return -1;
// if (i1.Inactive == 1) return 1;
// });
//
params.list = sorted.sort((i1, i2) => i1.Inactive - i2.Inactive || i1.Name.toLowerCase().localeCompare(i2.Name.toLowerCase()));
}
self.layout('/layouts/protected');
self.view('/restaurants/index', params);
});
};
function restraurantsEdit(id) {
var self = this;
var params = {};
console.log('self.repository.currentRestaurant', self.repository.currentRestaurant)
// Check if allowed access.
if (self.repository.currentRestaurant && self.repository.currentRestaurant !== id && self.repository.type !== 'admin') {
self.res.redirect('/');
}
self.layout('/layouts/protected');
params.id = id;
params.restaurant = false;
if (id === 'new') {
self.view('/restaurants/edit', params);
} else {
F.model('restaurant').load(id).then(function (restaurant) {
params.restaurant = restaurant;
self.view('/restaurants/edit', params);
}).catch(err => console.log(err));
}
};
function restraurantsPost(id) {
var self = this;
var params = {};
params.restaurant = self.body;
params.id = id;
// Format phone number.
const [formattedPhoneNumber] = phoneFormatter(self.body['Phone']);
self.body['Phone'] = formattedPhoneNumber || self.body['Phone'];
self.body['Phone'] = (self.body['Phone'].startsWith('+')) ? self.body['Phone'] : '+' + self.body['Phone'];
// Format data.
self.body['Credits'] = parseInt(self.body['Credits']) || null;
self.body['Inactive'] = self.body['Inactive'] == 'on' ? false : true;
self.body['Subscription'] = self.body['Subscription'] == 'none-selected' ? null : self.body['Subscription'];
self.body['SubscriptionDate'] = self.body['SubscriptionDate'] || '';
self.body['hasActiveDishes'] = self.body['hasActiveDishes'] == 'on' ? true : false;
self.body['Disable share emails'] = self.body['Disable share emails'] == 'on' ? true : false;
self.body['Number of times shown android'] = parseInt(self.body['Number of times shown android']) || null;
self.body['Number of times shown iOS'] = parseInt(self.body['Number of times shown iOS']) || null;
// Format url.
self.body['Website'] = self.body['Website'] || '';
self.body['Website'] = 'http://' + self.body['Website'].replace('http://', '').replace('https://', '');
params.restaurant['Opening hours per day'] = [];
params.restaurant['Opening hours per day'][0] = self.body['MON'] || '';
params.restaurant['Opening hours per day'][1] = self.body['TUE'] || '';
params.restaurant['Opening hours per day'][2] = self.body['WED'] || '';
params.restaurant['Opening hours per day'][3] = self.body['THU'] || '';
params.restaurant['Opening hours per day'][4] = self.body['FRI'] || '';
params.restaurant['Opening hours per day'][5] = self.body['SAT'] || '';
params.restaurant['Opening hours per day'][6] = self.body['SUN'] || '';
params.restaurant['Opening hours per day ENG'] = [];
params.restaurant['Opening hours per day ENG'][0] = self.body['MON-ENG'] || '';
params.restaurant['Opening hours per day ENG'][1] = self.body['TUE-ENG'] || '';
params.restaurant['Opening hours per day ENG'][2] = self.body['WED-ENG'] || '';
params.restaurant['Opening hours per day ENG'][3] = self.body['THU-ENG'] || '';
params.restaurant['Opening hours per day ENG'][4] = self.body['FRI-ENG'] || '';
params.restaurant['Opening hours per day ENG'][5] = self.body['SAT-ENG'] || '';
params.restaurant['Opening hours per day ENG'][6] = self.body['SUN-ENG'] || '';
delete params.restaurant['MON'];
delete params.restaurant['TUE'];
delete params.restaurant['WED'];
delete params.restaurant['THU'];
delete params.restaurant['FRI'];
delete params.restaurant['SAT'];
delete params.restaurant['SUN'];
delete params.restaurant['MON-ENG'];
delete params.restaurant['TUE-ENG'];
delete params.restaurant['WED-ENG'];
delete params.restaurant['THU-ENG'];
delete params.restaurant['FRI-ENG'];
delete params.restaurant['SAT-ENG'];
delete params.restaurant['SUN-ENG'];
// Check if both tumb and at least one image are added.
let hasThumb = false;
let hasImage = false;
let photoToLarge = false;
self.files.forEach(file => {
if (id === 'new') {
if (file.name === 'thumbnail') {
hasThumb = true;
} else {
hasImage = true;
}
}
// Validate photo size and resolution.
if (file.length > 10000000) {
params.error = true;
params.errorMessage = `"${file.filename}" is to large.`
}
const exp = new RegExp(/\.(gif|jpg|jpeg|png|GIF|JPG|JPEG|PNG)$/);
if (!exp.test(file.filename)) {
params.error = true;
params.errorMessage = `"${file.filename}" is invalid type.`
}
});
if (id === 'new') {
if (!hasThumb) {
params.error = true;
params.errorMessage = "Thumbnail image is required."
}
if (!hasImage) {
params.error = true;
params.errorMessage = "At least one image is required."
}
}
// Input validations.
if (self.repository.type === 'admin') {
// Format coords.
self.body['longitude'] = parseFloat(self.body['longitude']);
self.body['latitude'] = parseFloat(self.body['latitude']);
if (!self.body['longitude'] && self.body['longitude'] !== undefined) {
params.error = true;
params.errorMessage = 'Invalid "longitude" value.'
}
if (!self.body['latitude'] && self.body['latitude'] !== undefined) {
params.error = true;
params.errorMessage = 'Invalid "latitude" value.'
}
if (!self.body['Number of times shown android']) {
params.error = true;
params.errorMessage = 'Invalid "Number of times shown android" value.'
}
if (!self.body['Number of times shown iOS']) {
params.error = true;
params.errorMessage = 'Invalid "Number of times shown iOS" value.'
}
}
if (!self.body['Lunch start'] && self.body['Lunch finish']) {
params.error = true;
params.errorMessage = '"Lunch start" value is required.'
}
if (self.body['Lunch start'] && !self.body['Lunch finish']) {
params.error = true;
params.errorMessage = '"Lunch finish" value is required.'
}
//if (!validator.isEmail(self.body['E-mail']) || !validator.isLength(self.body['E-mail'], {
if (!validator.isLength(self.body['E-mail'], {
min: 1,
max: 40
})) {
params.error = true;
params.errorMessage = 'Invalid "E-mail" value.'
}
if (!validator.isLength(self.body['Address'] || '', {
min: 1,
max: 35
})) {
params.error = true;
params.errorMessage = '"Address" value can have max 35 characters.';
self.body['Address'] = self.body['Address'] || '';
if (self.body['Address'].length < 1) {
params.errorMessage = '"Address" value is required.'
}
}
if (!validator.isLength(self.body['Country'] || '', {
min: 1,
max: 25
})) {
params.error = true;
params.errorMessage = '"Country" value can have max 25 characters.';
self.body['Country'] = self.body['Country'] || '';
if (self.body['Country'].length < 1) {
params.errorMessage = '"Country" value is required.'
}
}
if (!validator.isLength(self.body['City'] || '', {
min: 1,
max: 28
})) {
params.error = true;
params.errorMessage = '"City" value can have max 28 characters.';
self.body['City'] = self.body['City'] || '';
if (self.body['City'].length < 1) {
params.errorMessage = '"City" value is required.'
}
}
if (!validator.isLength(self.body['Type of restaurant'] || '', {
min: 1,
max: 40
})) {
params.error = true;
params.errorMessage = '"Type of restaurant" value can have max 40 characters.';
self.body['Type of restaurant'] = self.body['Type of restaurant'] || '';
if (self.body['Type of restaurant'].length < 1) {
params.errorMessage = '"Type of restaurant" value is required.'
}
}
if (!validator.isLength(self.body['Description'] || '', {
min: 1,
max: 400
})) {
params.error = true;
params.errorMessage = '"Description" value can have max 400 characters.';
self.body['Description'] = self.body['Description'] || '';
if (self.body['Description'].length < 1) {
params.errorMessage = '"Description" value is required.'
}
}
if (!validator.isLength(self.body['Description ENG'] || '', {
min: 0,
max: 400
})) {
params.error = true;
params.errorMessage = '"Description ENG" value can have max 400 characters.'
}
if (!validator.isLength(self.body['Opening hours'] || '', {
min: 1,
max: 70
})) {
params.error = true;
params.errorMessage = '"Opening hours" value can have max 70 characters.';
self.body['Opening hours'] = self.body['Opening hours'] || '';
if (self.body['Opening hours'].length < 1) {
params.errorMessage = '"Opening hours" value is required.'
}
}
if (!validator.isLength(self.body['Opening hours ENG'] || '', {
min: 0,
max: 70
})) {
params.error = true;
params.errorMessage = '"Opening hours ENG" value can have max 70 characters.'
}
if (self.repository.type === 'admin') {
if (!self.body['Credits']) {
params.error = true;
params.errorMessage = '"Credits" value is required.'
}
}
if (!validator.isLength(self.body['Name'] || '', {
min: 1,
max: 25
})) {
params.error = true;
params.errorMessage = '"Name" value can have max 25 characters.';
self.body['Name'] = self.body['Name'] || '';
if (self.body['Name'].length < 1) {
params.errorMessage = '"Name" value is required.'
}
}
if (!validator.isLength(self.body['Phone'] || '', {
min: 1,
max: 15
})) {
params.error = true;
params.errorMessage = '"Phone" value can have max 15 characters.'
}
const phoneReg = /^\+[0-9]*$/;
if (!phoneReg.test(self.body['Phone'])) {
params.error = true;
params.errorMessage = '"Phone" value is invalid';
}
if (!validator.isLength(self.body['Postcode'] || '', {
min: 1,
max: 10
})) {
params.error = true;
params.errorMessage = '"Postcode" value can have max 10 characters.';
self.body['Postcode'] = self.body['Postcode'] || '';
if (self.body['Postcode'].length < 1) {
params.errorMessage = '"Postcode" value is required.'
}
}
const isValidURL = validator.isURL(self.body['Website'] || '');
if (!isValidURL || !validator.isLength(self.body['Website'], {
min: 0,
max: 40
})) {
params.error = true;
params.errorMessage = isValidURL ? '"Website" value can have max 40 characters.' : '"Website" value is invalid';
}
if (params.error) {
self.layout('/layouts/protected');
F.model('restaurant').load(id).then(function (old) {
params.restaurant.images = old.images;
params.restaurant.thumbnail = old.thumbnail;
if (self.repository.type === 'restaurant') {
params.restaurant.Credits = old.Credits;
params.restaurant.longitude = old.longitude;
params.restaurant.latitude = old.latitude;
}
self.view('/restaurants/edit', params);
}).catch(err => self.view('/restaurants/edit', params));
} else {
// email edit restaurant
var strMailBody = 'Restaurant: ' + self.body['Name'] + '\nInActive: ' + self.body['Inactive'] + '\nDescription: ' + self.body['Description'];
var strHTMLMailBody = 'Restaurant: ' + self.body['Name'] + '<br/>InActive: ' + self.body['Inactive'] + '<br/>Description:' + self.body['Description'];
if (self.repository.type !== 'admin') {
sendEmail('info@photomenu.nl','photomenushares@gmail.com','Edit Restaurant', strHTMLMailBody, strMailBody, null);
}
// email edit restaurant
if (id === 'new') {
params.id = uuidV4();
}
params.restaurant.images = [];
if (self.files.length > 0) {
let allUploads = [];
self.files.forEach(file => {
const options = {
destination: `${params.id}/${uuidV4()}-${file.filename}`
}
let upload = {};
// console.log('408 file.name:' + file.name);
if (file.name === 'thumbnail') {
if (file.length > 1000000 || file.width > 1500 || file.height > 1500) {
upload = new Promise(function (resolve, reject) {
const resizedPath = path.normalize(`${__dirname}/../tmp/${file.filename}`);
gm(file.path).resize(1500, 1500).write(resizedPath, err => {
if (err) {
reject(err);
}
gm(file.path).thumb(1500, 0, resizedPath, 0, err => {
F.storage.upload(resizedPath, options, function (err, uploaded, apiResponse) {
if (err) {
return reject(err);
}
uploaded.makePublic(err => reject(err));
params.restaurant.thumbnail = uploaded.metadata.mediaLink;
resolve(uploaded.metadata.mediaLink);
})
})
});
});
} else {
upload = new Promise(function (resolve, reject) {
F.storage.upload(file.path, options, function (err, file, apiResponse) {
if (err) {
return reject(err);
}
file.makePublic(err => reject(err));
params.restaurant.thumbnail = file.metadata.mediaLink;
resolve(file.metadata.mediaLink);
})
});
}
} else {
//multiple image upload
console.log('file.length:' + file.length);
if (file.length > 1000000 || file.width > 1500 || file.height > 1500) {
upload = new Promise(function (resolve, reject) {
const resizedPath = path.normalize(`${__dirname}/../tmp/${file.filename}`);
console.log('resizedPath:' + resizedPath);
gm(file.path).resize(1500, 1500).write(resizedPath, err => {
if (err) {
reject(err);
}
gm(file.path).thumb(1500, 0, resizedPath, 0, err => {
F.storage.upload(resizedPath, options, function (err, uploaded, apiResponse) {
if (err) {
return reject(err);
}
uploaded.makePublic(err => reject(err));
params.restaurant.images.push(uploaded.metadata.mediaLink);
resolve(uploaded.metadata.mediaLink);
})
})
});
});
} else {
upload = new Promise(function (resolve, reject) {
console.log('file.path:' + file.path);
F.storage.upload(file.path, options, function (err, file, apiResponse) {
if (err) {
return reject(err);
}
file.makePublic(err => reject(err));
params.restaurant.images.push(file.metadata.mediaLink);
resolve(file.metadata.mediaLink);
})
});
}
}
allUploads.push(upload);
});
Promise.all(allUploads).then(() => {
if (id === 'new') {
F.model('restaurant').create(params).then(function () {
self.res.redirect('/restaurants');
}).catch(err => {
console.log(err);
params.error = true;
params.errorMessage = err;
params.id = id;
self.layout('/layouts/protected');
self.view('/restaurants/edit', params);
});
} else {
F.firebase('/Restaurant/' + params.id).once('value').then(function (old) {
const oldData = old.val() || {};
oldData.images = oldData.images || [];
// Don't replace existing images.
params.restaurant.images = params.restaurant.images.concat(oldData.images);
params.restaurant.thumbnail = params.restaurant.thumbnail === '' ? oldData.thumbnail : params.restaurant.thumbnail || oldData.thumbnail;
// Credits check.
if (self.repository.type === 'admin') {
self.body['Credits'] = parseInt(self.body['Credits']);
} else {
self.body['Credits'] = oldData.Credits;
}
F.model('restaurant').edit(params).then(function () {
self.res.redirect('/restaurants');
}).catch(err => {
console.log(err);
params.error = true;
params.errorMessage = err;
self.layout('/layouts/protected');
self.view('/restaurants/edit', params);
});
});
}
}).catch(err => {
console.log('Error uploading photos:', err);
params.error = true;
params.errorMessage = err;
self.layout('/layouts/protected');
self.view('/restaurants/edit', params);
})
} else {
F.firebase('/Restaurant/' + params.id).once('value').then(function (old) {
const oldData = old.val();
params.restaurant.images = oldData.images;
params.restaurant.thumbnail = oldData.thumbnail;
// Credits check.
if (self.repository.type === 'admin') {
self.body['Credits'] = parseInt(self.body['Credits']);
} else {
self.body['Credits'] = oldData.Credits;
}
F.model('restaurant').edit(params).then(function () {
self.res.redirect('/restaurants');
}).catch(err => {
console.log(err);
params.error = true;
params.errorMessage = err;
self.layout('/layouts/protected');
self.view('/restaurants/edit', params);
});
});
}
}
};
function restraurantsDelete(id) {
var self = this;
F.model('restaurant').delete(id).then(() => {
F.storage.deleteFiles({
prefix: `${id}/`
}, function (err) {
if (!err) {
self.res.redirect('/restaurants');
} else {
console.log("Error when deleting restaurant:", err);
self.res.redirect('/restaurants');
}
});
}).catch((err) => {
console.log("Error when deleting restaurant::", err);
self.res.redirect('/restaurants');
})
};