Files
freeplanet_serverside/src/models/myelem.js
Surya Paolo 9a0cdec7bd - altro aggiornamento restying
- Invio RIS aggiornato
- Eventi
- Home Page restyling
2025-12-18 17:00:43 +01:00

596 lines
13 KiB
JavaScript
Executable File

const mongoose = require('mongoose').set('debug', false);
const Schema = mongoose.Schema;
const tools = require('../tools/general');
const { ObjectId } = require('mongodb');
const shared_consts = require('../tools/shared_nodejs');
const { MySchedaSchema, IDimensioni, IImg, IText, IAreaDiStampa } = require('../models/myscheda');
mongoose.Promise = global.Promise;
mongoose.level = 'F';
// Resolving error Unknown modifier: $pushAll
mongoose.plugin((schema) => {
schema.options.usePushEach = true;
});
const IElementiPagina = new Schema({
isTemplate: Boolean,
linkIdTemplate: String,
name: String,
pagina: IDimensioni,
});
const myCard = new Schema({
imagefile: String,
vers_img: Number,
alt: String,
description: String,
style: String,
size: String,
color: String,
content: String,
colorsub: String,
link: String,
});
const animation = new Schema({
name: String,
clduration: String,
cldelay: String,
timingtype: String,
});
const elemText = new Schema({
text: String,
color: String,
class: String,
size: String,
anim: animation,
});
const catalogo = new Schema({
//++AddCATALOGO_FIELDS
idCatalogSel: { type: String },
productTypes: [{ type: Number }],
excludeproductTypes: [{ type: Number }],
editore: [{ type: String }],
argomenti: [{ type: String }],
idCollane: [{ type: String }],
idTipologia: [{ type: Number }],
idTipoFormato: [{ type: Number }],
sort_field: { type: String },
sort_dir: { type: Number },
pdf: { type: Boolean },
pdf_filename: { type: String },
printable: { type: Boolean },
indebug: { type: Boolean },
maxnumlibri: { type: Number },
showListaArgomenti: { type: Boolean },
showOnlyCatalogoPDF: { type: Boolean },
showListaCollane: { type: Boolean },
first_page: IDimensioni,
last_page: IDimensioni,
areadistampa: IAreaDiStampa,
print_isTemplate: Boolean,
print_linkIdTemplate: String,
dimensioni_def: IElementiPagina,
// -------------------
arrSchede: [
{
scheda: MySchedaSchema,
order: { type: Number },
numPagineMax: { type: Number },
/*arrProdToShow: {
type: [[mongoose.Schema.Types.Mixed]], // Definizione tipo
select: false // Imposta il campo come non selezionabile
},*/
},
],
});
const MySingleElemSchema = {
idapp: {
type: String,
},
path: {
type: String,
},
/*oldpath: {
type: String,
},*/
idElemParent: {
type: String,
},
idPage: { type: String },
type: {
type: Number,
},
img: {
type: String,
},
container: {
type: String,
},
container2: {
type: String,
},
container3: {
type: String,
},
container4: {
type: String,
},
align: {
type: Number,
},
vertalign: {
type: Number,
},
speed: {
type: Number,
},
parambool: {
type: Boolean,
},
span: {
type: Boolean,
},
parambool2: {
type: Boolean,
},
parambool3: {
type: Boolean,
},
parambool4: {
type: Boolean,
},
parambool5: {
type: Boolean,
},
number: {
type: Number,
},
num2: {
type: Number,
},
imgback: {
type: String,
},
ratio: {
type: String,
},
containerHtml: {
type: String,
},
size: {
type: String,
},
order: {
type: Number,
default: 0,
},
height: {
type: Number,
},
heightimg: {
type: String,
},
heightcarousel: {
type: String,
},
widthimg: {
type: String,
},
width: {
type: Number,
},
heightcard: {
type: String,
},
widthcard: {
type: String,
},
link: {
type: String,
},
fit: {
type: String,
},
onlyif_logged: {
type: Boolean,
},
color: {
type: String,
},
elemsText: [elemText],
anim: animation,
features: [
{
name: {
type: String,
},
icon: {
type: String,
},
description: {
type: String,
},
},
],
active: {
type: Boolean,
default: false,
},
class: {
type: String,
},
class2: {
type: String,
},
class3: {
type: String,
},
class4: {
type: String,
},
stiletit_str: {
type: String,
},
stiletit_icon: {
type: String,
},
styleadd: {
type: String,
},
image: {
type: String,
},
vers_img: {
type: Number,
},
titleBanner: String,
classBanner: String,
listcards: [myCard],
catalogo: catalogo,
list: [
{
imagefile: {
type: String,
},
vers_img: {
type: Number,
},
order: {
type: Number,
},
alt: {
type: String,
},
description: {
type: String,
},
},
],
date_created: {
type: Date,
default: Date.now,
},
date_updated: {
type: Date,
},
};
const MyElemSchema = new Schema({
...MySingleElemSchema,
// Aggiungi rows e columns
rows: {
type: [
{
...MySingleElemSchema,
columns: {
type: [
{
...MySingleElemSchema,
elems: [MySingleElemSchema],
},
],
},
},
],
},
});
MyElemSchema.pre('save', async function (next) {
if (this.isNew) {
this._id = new ObjectId();
}
next();
});
MyElemSchema.statics.getFieldsForSearch = function () {
return [
{ field: 'title', type: tools.FieldType.string },
{ field: 'content', type: tools.FieldType.string },
];
};
MyElemSchema.statics.executeQueryTable = function (idapp, params, user) {
params.fieldsearch = this.getFieldsForSearch();
return tools.executeQueryTable(this, idapp, params, user);
};
MyElemSchema.statics.SetIdPageInsteadThePah = async function (idapp) {
const MyElem = this;
const { MyPage } = require('../models/mypage');
try {
const pages = await MyPage.find({ idapp });
if (pages.length === 0) {
return 'Nessuna pagina trovata per questo idapp.';
}
const bulkOps = [];
pages.forEach((page) => {
if (page.path) {
// Aggiorna documenti con 'path'
bulkOps.push({
updateMany: {
filter: { idapp: idapp, path: page.path },
update: {
$set: { idPage: page._id, oldpath: page.path },
$unset: { path: '' },
},
},
});
// Aggiorna documenti con 'oldpath' ma senza 'idPage'
bulkOps.push({
updateMany: {
filter: {
idapp: idapp,
oldpath: page.path,
idPage: { $exists: false },
},
update: { $set: { idPage: page._id } },
},
});
}
});
if (bulkOps.length > 0) {
const result = await MyElem.bulkWrite(bulkOps);
console.log(`Aggiornati ${result.modifiedCount} documenti.`);
return `Aggiornamenti effettuati: ${result.modifiedCount} documenti.`;
}
return 'Nessun documento da aggiornare.';
} catch (error) {
console.error("Errore durante l'aggiornamento:", error);
throw error;
}
};
MyElemSchema.statics.deleteAllFromThisPage = async function (id) {
const MyElem = this;
return MyElem.deleteMany({ idPage: id });
};
MyElemSchema.statics.findAllIdApp = async function (idapp) {
const MyElem = this;
const myfind = { idapp };
const aggiorna = false;
let arrrec = null;
if (aggiorna) {
arrrec = await MyElem.find(myfind).sort({ order: 1 });
for (const elem of arrrec) {
if (elem.heightimg === 'NaNpx') {
elem.heightimg = '';
await elem.save();
}
}
} else {
arrrec = await MyElem.find(myfind).lean().sort({ order: 1 });
}
return arrrec;
};
async function deleteOldMyElems(idapp) {
try {
const { MyPage } = require('../models/mypage');
// 1. Recupera tutti gli _id dalle pagine
const existingPages = await MyPage.find({ idapp }).select('_id').lean();
const existingPageIds = existingPages.map((page) => page._id.toString());
// 2. Trova gli MyElem che hanno idPage non esistenti in MyPage
const elemsToDelete = await MyElem.find({
idapp,
idPage: { $nin: existingPageIds },
});
if (elemsToDelete.length > 0) {
// 3. Esegui la cancellazione
const result = await MyElem.deleteMany({ idPage: { $nin: existingPageIds } });
console.log(`Cancellati ${result.deletedCount} documenti di MyElem.`);
} else {
console.log('Nessun documento da cancellare.');
}
} catch (error) {
console.error('Errore durante la cancellazione dei documenti:', error);
}
}
/**
* Trova tutte le schede template associate a pagine di idapp.
* Restituisce un array di ogge tti con le seguenti proprietà:
* - scheda: l'oggetto scheda, con proprietà come _id, name, isTemplate
* - idPageOrig: l'idPage originale associata alla scheda
*
* Se idapp === '18', stampa i duplicati e i titoli delle pagine
* e cancella i documenti di MyElem con idPage non esistenti in MyPage
*
* @param {string} idapp ID dell'applicazione
* @returns {Promise<IMyElemTemplate[]>} Array di oggetti scheda con idPageOrig
*/
MyElemSchema.statics.findallSchedeTemplate = async function (idapp) {
const MyElem = this;
try {
const { MyPage } = require('../models/mypage');
const ris = await MyElem.find({ idapp }).lean();
const schedeTemplate = ris.flatMap((elem) =>
elem.catalogo && elem.catalogo.arrSchede
? elem.catalogo.arrSchede
.filter((scheda) => scheda.scheda?.isTemplate)
.map((scheda) => ({
...scheda, // mantieni i dati originali della scheda
idPageOrig: elem.idPage, // aggiungi l'idPage
}))
: []
);
if (idapp === '18') {
const duplicateIds = schedeTemplate.reduce((acc, scheda) => {
const id = scheda.scheda._id; // Ottieni l'ID della scheda
if (!acc[id]) {
acc[id] = []; // Inizializza un array per tenere traccia delle pagine
}
acc[id].push(scheda.idPageOrig); // Aggiungi l'idPage all'array
return acc;
}, {});
// Filtra i duplicati
const duplicates = Object.entries(duplicateIds)
.filter(([_, pages]) => pages.length > 1) // Mantieni solo gli ID con più di un'istanza
.map(([id, pages]) => ({ id, pages })); // Ottieni ID e pagine corrispondenti
// Recupera i dettagli delle pagine
const pageIds = duplicates.flatMap((dup) => dup.pages); // Estrai tutti gli idPage
const pages = await MyPage.find({ idapp, _id: { $in: pageIds } }).lean();
// Crea una mappatura tra idPage e title
const pageMap = pages.reduce((acc, page) => {
acc[page._id] = page.title; // Mappa idPage a title
return acc;
}, {});
// Associa i titoli delle pagine agli ID duplicati
const resultWithTitles = duplicates.map((dup) => ({
id: dup.id,
pages: dup.pages.map((_id) => ({
_id,
title: pageMap[_id] || 'Titolo non trovato', // Usa la mappatura per trovare il titolo
})),
}));
if (resultWithTitles.length > 0) {
console.log('Duplicati e titoli delle pagine:', JSON.stringify(resultWithTitles, null, 2));
// await deleteOldMyElems(idapp);
}
}
return schedeTemplate;
} catch (e) {
console.error('Err', e);
}
};
/**
* Ricerca tra tutte le schede, contenute in catalogo, se esiste un nome di template uguale,
* se non lo trova allora è quello giusto per crearne uno nuovo
*
* @param {string} idapp - ID dell'app
* @param {string} idPageOrig - ID della pagina originale
* @param {string} nomeTemplate - Nome del template
*
* @returns {string} Il nome del template libero
*/
MyElemSchema.statics.getNewFreeNameTemplate = async function (idapp, idPageOrig, nomeTemplate) {
const MyElem = this;
try {
// Trova tutti gli elementi che hanno un template con lo stesso nome
const ris = await MyElem.find(
{
idapp,
'catalogo.arrSchede.scheda.isTemplate': true,
'catalogo.arrSchede.scheda.idPage': { $ne: idPageOrig },
},
{
'catalogo.arrSchede.scheda.name': 1,
'catalogo.arrSchede.scheda.isTemplate': 1,
'catalogo.arrSchede.scheda.isPagIntro': 1,
'catalogo.arrSchede.scheda.idPage': 1,
}
);
// Recupera i nomi dei template già esistenti
const existingNames = new Set(
ris.flatMap(
(elem) =>
elem.catalogo?.arrSchede
?.filter((scheda) => scheda.scheda?.isTemplate && scheda.scheda?.idPage !== idPageOrig)
.map((scheda) => scheda.scheda?.name) || []
)
);
// Crea un nuovo nome di template univoco
let ind = 2;
let newNameTemplate;
do {
newNameTemplate = `${nomeTemplate}_copia_${ind}`;
ind++;
} while (existingNames.has(newNameTemplate) && ind <= 1000);
return newNameTemplate;
} catch (e) {
console.error('Err', e);
throw e; // Propagate the error
}
};
MyElemSchema.statics.findParentElem = async function (idapp, idElemParent) {
try {
let myelemParent = null;
myelemParent = await this.findOne({
idapp,
rows: {
$elemMatch: { columns: { $elemMatch: { _id: idElemParent } } },
},
}).lean();
return myelemParent;
} catch (e) {
console.error('Err', e);
throw e; // Propagate the error
}
};
const MyElem = mongoose.model('MyElem', MyElemSchema);
MyElem.createIndexes()
.then(() => {})
.catch((err) => {
throw err;
});
module.exports = { MyElem };