2020-08-07 12:23:59 +02:00
const sharp = require ( "sharp" ) ;
const config = require ( "../config/main.js" ) ;
const configIllustrations = require ( "../config/illustrations.js" ) ;
const tool = require ( "../tools/main" ) ;
const toolError = require ( "../tools/error" ) ;
const toolFile = require ( "../tools/file" ) ;
const questionnaireCtrl = require ( "./questionnaire" ) ;
const txt = require ( "../lang/" + config . adminLang + "/illustration" ) ;
const txtGeneral = require ( "../lang/" + config . adminLang + "/general" ) ;
exports . create = async ( req , res , next ) =>
{
try
{
const db = require ( "../models/index" ) ;
const illustrationDatas = await checkHasFile ( req ) ;
// Le fichier peut avoir été bloqué par multer :
if ( ! illustrationDatas . url )
res . status ( 400 ) . json ( { errors : [ txt . needGoodFile ] } ) ;
else
{
const questionnaire = await questionnaireCtrl . searchQuestionnaireById ( illustrationDatas . QuestionnaireId ) ;
if ( ! questionnaire )
{
toolFile . deleteFile ( configIllustrations . dirIllustrations , illustrationDatas . url ) ;
throw { message : txt . needQuestionnaireForIllustration } ;
}
2020-08-20 12:29:18 +02:00
else if ( config . nbIllustrationsMax !== 0 && questionnaire . Illustrations . length >= config . nbIllustrationsMax )
2020-08-07 12:23:59 +02:00
{
toolFile . deleteFile ( configIllustrations . dirIllustrations , illustrationDatas . url ) ;
res . status ( 400 ) . json ( { errors : [ txt . needMaxIllustrationsForQuestionnaire ] } ) ;
}
else
{
const illustration = await db [ "Illustration" ] . create ( { ... illustrationDatas } , { fields : [ "url" , "alt" , "title" , "caption" , "QuestionnaireId" ] } ) ;
const questionnaireDatas = await questionnaireCtrl . creaQuestionnaireJson ( illustrationDatas . QuestionnaireId ) ; // me permet de retourner en réponse les infos actualisées pour les afficher
res . status ( 201 ) . json ( { message : txt . addedOkMessage , questionnaire : questionnaireDatas } ) ;
}
}
next ( ) ;
}
catch ( e )
{
const returnAPI = toolError . returnSequelize ( e ) ;
if ( returnAPI . messages )
{
res . status ( returnAPI . status ) . json ( { errors : returnAPI . messages } ) ;
next ( ) ;
}
else
next ( e ) ;
}
}
exports . modify = async ( req , res , next ) =>
{
try
{
const db = require ( "../models/index" ) ;
const illustration = await searchIllustrationById ( req . params . id ) ;
if ( ! illustration )
res . status ( 404 ) . json ( { errors : txt . notFound } ) ;
else
{
const questionnaire = await questionnaireCtrl . searchQuestionnaireById ( illustration . QuestionnaireId ) ;
if ( ! questionnaire )
{
if ( illustrationDatas . url )
toolFile . deleteFile ( configIllustrations . dirIllustrations , illustrationDatas . url ) ;
throw { message : txt . needQuestionnaireForIllustration } ;
}
else if ( req . connectedUser . User . status === "creator" && req . connectedUser . User . id !== questionnaire . Questionnaire . CreatorId )
{
if ( illustrationDatas . url )
toolFile . deleteFile ( configIllustrations . dirIllustrations , illustrationDatas . url ) ;
res . status ( 401 ) . json ( { errors : txtGeneral . notAllowed } ) ;
}
else
{
if ( ! tool . isEmpty ( req . body . fileError ) )
res . status ( 400 ) . json ( { errors : [ req . body . fileError ] } ) ;
else
{
const illustrationDatas = await checkHasFile ( req ) ;
// Lors d'une mise à jour, un nouveau fichier n'a pas forcément été envoyé ou peut avoir été bloqué par multer
// Mais si c'est le cas, on supprime l'ancien fichier :
if ( illustrationDatas . url )
{
2020-08-20 12:29:18 +02:00
toolFile . deleteFile ( configIllustrations . dirIllustrations , illustration . url ) ;
2020-08-07 12:23:59 +02:00
toolFile . deleteFile ( configIllustrations . dirIllustrations + "/min" , illustration . url ) ;
}
await db [ "Illustration" ] . update ( { ... illustrationDatas } , { where : { id : req . params . id } , fields : [ "url" , "alt" , "title" , "caption" ] , limit : 1 } ) ;
const questionnaireDatas = await questionnaireCtrl . creaQuestionnaireJson ( illustrationDatas . QuestionnaireId ) ; // me permet de retourner en réponse les infos actualisées pour les afficher
res . status ( 200 ) . json ( { message : txt . updatedOkMessage , questionnaire : questionnaireDatas } ) ;
}
}
}
next ( ) ;
}
catch ( e )
{
const returnAPI = toolError . returnSequelize ( e ) ;
if ( returnAPI . messages )
{
res . status ( returnAPI . status ) . json ( { errors : returnAPI . messages } ) ;
next ( ) ;
}
else
next ( e ) ;
}
}
exports . delete = async ( req , res , next ) =>
{
try
{
const db = require ( "../models/index" ) ;
const illustration = await searchIllustrationById ( req . params . id ) ;
if ( ! illustration )
throw { message : txt . notFound + req . params . id } ;
else
{
const questionnaire = await questionnaireCtrl . searchQuestionnaireById ( illustration . QuestionnaireId ) ;
if ( ! questionnaire )
throw { message : txt . needQuestionnaireForIllustration } ;
else if ( req . connectedUser . User . status === "creator" && req . connectedUser . User . id !== questionnaire . Questionnaire . CreatorId )
res . status ( 401 ) . json ( { errors : txtGeneral . notAllowed } ) ;
else
{
const delIllus = await deleteIllustrationById ( req . params . id ) ;
if ( delIllus )
{
const questionnaireDatas = await questionnaireCtrl . creaQuestionnaireJson ( illustration . QuestionnaireId ) ; // me permet de retourner en réponse les infos actualisées pour les afficher
res . status ( 200 ) . json ( { message : txt . deletedOkMessage , questionnaire : questionnaireDatas } ) ;
}
else
res . status ( 400 ) . json ( { errors : [ txtGeneral . serverError ] } ) ;
}
}
next ( ) ;
}
catch ( e )
{
next ( e ) ;
}
}
exports . getOneIllustrationById = async ( req , res , next ) =>
{
try
{
const illustration = await searchIllustrationById ( req . params . id ) ;
if ( illustration )
res . status ( 200 ) . json ( illustration ) ;
else
res . status ( 404 ) . json ( null ) ;
}
catch ( e )
{
next ( e ) ;
}
}
// cron de nettoyage des fichiers illustrations n'existant plus dans la bd
exports . deleteOldFiles = async ( req , res , next ) =>
{
try
{
const db = require ( "../models/index" ) ;
const illustrations = await db [ "Illustration" ] . findAll ( { attributes : [ "url" ] } ) ;
let saveFiles = [ ] ;
for ( let i in illustrations )
saveFiles . push ( illustrations [ i ] . url ) ;
await toolFile . deleteFilesInDirectory ( configIllustrations . dirIllustrations , saveFiles ) ;
await toolFile . deleteFilesInDirectory ( configIllustrations . dirIllustrations + "/min" , saveFiles ) ;
// + le répertoire temporaire où rien ne devrait traîner :
const fileExpiration = new Date ( ) . getTime ( ) - 1000 ;
await toolFile . deleteOldFilesInDirectory ( configIllustrations . dirIllustrationsTmp , fileExpiration ) ;
res . status ( 200 ) . json ( deleteFiles ) ;
next ( ) ;
}
catch ( e )
{
next ( e ) ;
}
}
// FONCTIONS UTILITAIRES
// Gère le redimensionnement de l'image si un fichier est envoyé.
// c'est multer qui vérifie dans le middleware précédent que l'image a le bon format, puis lui donne un nom (filename) si c'est ok
const checkHasFile = async ( req ) =>
{
if ( req . file )
{ // à revoir ? : là l'image est aggrandie si + petite que demandé
2020-08-20 12:29:18 +02:00
await sharp ( req . file . path ) . resize ( config . illustrationsWidthMaxInPx ) . toFile ( configIllustrations . dirIllustrations + "/" + req . file . filename ) ;
await sharp ( req . file . path ) . resize ( config . illustrationsMiniaturesWidthMaxInPx ) . toFile ( configIllustrations . dirIllustrations + "/min/" + req . file . filename ) ;
2020-08-07 12:23:59 +02:00
await toolFile . deleteFile ( configIllustrations . dirIllustrationsTmp , req . file . filename ) ;
}
// La gestion du téléchargement du fichier de l'illustration fait que les données sont envoyées sous forme de chaîne de caractères (form-data), qu'il faut transformer en json
const datas = req . file ? { ... req . body , url : req . file . filename } : { ... req . body } ;
return datas ;
}
const searchIllustrationById = async ( id ) =>
{
const db = require ( "../models/index" ) ;
const illustration = await db [ "Illustration" ] . findByPk ( id ) ;
if ( illustration )
return illustration ;
else
return false ;
}
const deleteIllustrationById = async ( id ) =>
{
const db = require ( "../models/index" ) ;
const illustration = await searchIllustrationById ( id ) ;
if ( ! illustration )
throw { message : txt . notFound + id } ;
else
{
const nb = await db [ "Illustration" ] . destroy ( { where : { id : id } , limit : 1 } ) ;
if ( nb === 1 )
{
toolFile . deleteFile ( configIllustrations . dirIllustrations , illustration . url ) ;
toolFile . deleteFile ( configIllustrations . dirIllustrations + "/min" , illustration . url ) ;
questionnaireCtrl . creaQuestionnaireJson ( illustration . QuestionnaireId ) ;
}
return true ;
}
}
exports . deleteIllustrationById = deleteIllustrationById ;