2020-08-07 12:23:59 +02:00
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
const striptags = require("striptags");
|
|
|
|
|
|
|
|
|
|
const slugify = require("slugify");
|
|
|
|
|
const tool = require("../tools/main");
|
|
|
|
|
|
|
|
|
|
const config = require("../config/main.js");
|
|
|
|
|
const txt = require("../lang/"+config.adminLang+"/questionnaire");
|
|
|
|
|
const txtGeneral = require("../lang/"+config.adminLang+"/general");
|
|
|
|
|
|
|
|
|
|
module.exports = (sequelize, DataTypes) =>
|
|
|
|
|
{
|
|
|
|
|
const Questionnaire = sequelize.define("Questionnaire",
|
|
|
|
|
{
|
|
|
|
|
title:
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.STRING(255), allowNull: false,
|
|
|
|
|
set(value)
|
|
|
|
|
{
|
|
|
|
|
this.setDataValue("title", tool.trimIfNotNull(striptags(value)));
|
|
|
|
|
},
|
|
|
|
|
validate:
|
|
|
|
|
{
|
|
|
|
|
notNull: { msg: txt.needTitle },
|
|
|
|
|
len:
|
|
|
|
|
{
|
|
|
|
|
args: [1, 255],
|
|
|
|
|
msg: txt.needNotTooLongTitle
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
slug:
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.STRING(150), allowNull: false,
|
|
|
|
|
unique:
|
|
|
|
|
{
|
|
|
|
|
args: true,
|
|
|
|
|
msg: txt.needUniqueUrl
|
|
|
|
|
},
|
|
|
|
|
set(value)
|
|
|
|
|
{
|
|
|
|
|
value=tool.trimIfNotNull(striptags(value));
|
|
|
|
|
if(value!==null)
|
|
|
|
|
this.setDataValue("slug", slugify(value.substring(0,150), { lower:true, strict:true }));
|
|
|
|
|
else if(this.title!==null)
|
|
|
|
|
this.setDataValue("slug", slugify(this.title.substring(0,150), { lower:true, strict:true }));
|
|
|
|
|
},
|
|
|
|
|
validate:
|
|
|
|
|
{
|
|
|
|
|
notNull: { msg: txt.needUrl }
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
introduction:
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.TEXT, allowNull: false,
|
2020-11-06 10:24:58 +01:00
|
|
|
|
set(value) { this.setDataValue("introduction", tool.trimIfNotNull(striptags(value,"<h3><h4><h5><p><b><i><em><strong><ul><li><div><a><br>"))); },
|
2020-08-07 12:23:59 +02:00
|
|
|
|
validate:
|
|
|
|
|
{
|
|
|
|
|
notNull: { msg: txt.needIntroduction }
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
keywords:
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.TEXT, allowNull: true,
|
|
|
|
|
set(value) { this.setDataValue("keywords", tool.trimIfNotNull(striptags(value))); },
|
|
|
|
|
comment : "Not published but only used for research."
|
|
|
|
|
},
|
|
|
|
|
publishingAt:
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.DATE, comment: "If null, the questionnaire is not published (=draft).",
|
|
|
|
|
set(value) { this.setDataValue("publishingAt", tool.trimIfNotNull(value)); },
|
|
|
|
|
validate:
|
|
|
|
|
{
|
|
|
|
|
isDate: { msg: txt.needCorrectPublishingDate }
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
isPublished:// valeur non saisie et validée par le code
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.BOOLEAN, allowNull: false, defaultValue:false,
|
|
|
|
|
comment: "May depend on factors other than the date of publication.",
|
|
|
|
|
validate:
|
|
|
|
|
{
|
|
|
|
|
notNull: { msg: txt.needKnowIfIsPublished },
|
|
|
|
|
isIn:
|
|
|
|
|
{
|
|
|
|
|
args: [[true, false]],
|
|
|
|
|
msg: txt.needKnowIfIsPublished+" "+txtGeneral.notValidFormat
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
language: // liste des langues dispo dans un fichier de configuration fourni par l'API au client
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.STRING(4), allowNull: false, defaultValue: "fr",
|
|
|
|
|
validate:
|
|
|
|
|
{
|
|
|
|
|
notNull: { msg: txt.needLanguage },
|
|
|
|
|
len:
|
|
|
|
|
{
|
|
|
|
|
args: [2, 4],
|
|
|
|
|
msg: txt.needLanguage+" "+txtGeneral.notValidFormat
|
|
|
|
|
} // en fait, il faudra vérifier l'existence du fichier de la langue choisie.
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
estimatedTime:
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.ENUM("short", "medium", "long"), allowNull: false, defaultValue: "medium",
|
|
|
|
|
comment: "Provides an estimate of the time required to complete this questionnaire.",
|
|
|
|
|
validate:
|
|
|
|
|
{
|
|
|
|
|
notNull: { msg: txt.needEstimatedTime },
|
|
|
|
|
isIn:
|
|
|
|
|
{
|
|
|
|
|
args: [["short", "medium", "long"]],
|
|
|
|
|
msg: txt.needEstimatedTime+" "+txtGeneral.notValidFormat
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-07 18:43:45 +02:00
|
|
|
|
},
|
|
|
|
|
rankInGroup:
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.INTEGER(2).UNSIGNED, allowNull: true,
|
|
|
|
|
comment: "Allows you to classify the questionnaire if it belongs to a group.",
|
2020-10-20 11:01:52 +02:00
|
|
|
|
set(value) { this.setDataValue("rankInGroup", tool.trimIfNotNull((value))); },
|
2020-10-07 18:43:45 +02:00
|
|
|
|
validate:
|
|
|
|
|
{
|
|
|
|
|
isInt: { msg: txt.needNumberForRank },
|
|
|
|
|
min:
|
|
|
|
|
{
|
|
|
|
|
args: [1],
|
|
|
|
|
msg: txt.needNumberForRank
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-20 11:01:52 +02:00
|
|
|
|
},
|
|
|
|
|
GroupId:
|
|
|
|
|
{
|
|
|
|
|
type: DataTypes.INTEGER(11).UNSIGNED, allowNull: true,
|
|
|
|
|
set(value) { this.setDataValue("GroupId", tool.trimIfNotNull((value))); }
|
2020-08-07 12:23:59 +02:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
charset: "utf8mb4",
|
|
|
|
|
collate: "utf8mb4_unicode_ci"
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
Questionnaire.associate = function(models)
|
|
|
|
|
{
|
|
|
|
|
Questionnaire.hasMany(models.Question);
|
|
|
|
|
Questionnaire.hasMany(models.Illustration);
|
|
|
|
|
Questionnaire.hasMany(models.Link);
|
|
|
|
|
Questionnaire.hasMany(models.Answer);
|
|
|
|
|
Questionnaire.belongsTo(models.User, { as: "Creator", foreignKey: { name: "CreatorId", allowNull: false } });
|
2020-10-07 18:43:45 +02:00
|
|
|
|
Questionnaire.belongsTo(models.Group, { foreignKey: { name: "GroupId", allowNull: true }, onDelete: 'RESTRICT', onUpdate: 'RESTRICT' });
|
2020-08-07 12:23:59 +02:00
|
|
|
|
Questionnaire.belongsToMany(models.Tag, { through: models.QuestionnaireClassification });
|
|
|
|
|
Questionnaire.belongsToMany(models.User, { through: models.QuestionnaireAccess });
|
|
|
|
|
};
|
|
|
|
|
return Questionnaire;
|
|
|
|
|
};
|