|
|
@ -7,7 +7,7 @@
|
|
|
|
const striptags = require('striptags');
|
|
|
|
const striptags = require('striptags');
|
|
|
|
const slug = require('slug');
|
|
|
|
const slug = require('slug');
|
|
|
|
|
|
|
|
|
|
|
|
const { SiteService, SiteError } = require('../../lib/site-lib');
|
|
|
|
const { SiteService, SiteError, SiteAsync } = require('../../lib/site-lib');
|
|
|
|
|
|
|
|
|
|
|
|
const mongoose = require('mongoose');
|
|
|
|
const mongoose = require('mongoose');
|
|
|
|
const ObjectId = mongoose.Types.ObjectId;
|
|
|
|
const ObjectId = mongoose.Types.ObjectId;
|
|
|
@ -22,26 +22,14 @@ class PageService extends SiteService {
|
|
|
|
|
|
|
|
|
|
|
|
async menuMiddleware (req, res, next) {
|
|
|
|
async menuMiddleware (req, res, next) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const pages = await Page
|
|
|
|
let mainMenu = await this.getMainMenuPages();
|
|
|
|
.find({ status: 'published', parent: { $exists: false } })
|
|
|
|
|
|
|
|
.select('slug menu')
|
|
|
|
|
|
|
|
.lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
res.locals.mainMenu = pages
|
|
|
|
|
|
|
|
.filter((page) => !page.parent)
|
|
|
|
|
|
|
|
.map((page) => {
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
url: `/page/${page.slug}`,
|
|
|
|
|
|
|
|
slug: page.slug,
|
|
|
|
|
|
|
|
icon: page.menu.icon,
|
|
|
|
|
|
|
|
label: page.menu.label,
|
|
|
|
|
|
|
|
order: page.menu.order,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.sort((a, b) => {
|
|
|
|
|
|
|
|
return a.order < b.order;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!mainMenu) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await this.cacheMainMenuPages();
|
|
|
|
|
|
|
|
mainMenu = await this.getMainMenuPages();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
res.locals.mainMenu = mainMenu;
|
|
|
|
return next();
|
|
|
|
return next();
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to build page menu', { error });
|
|
|
|
this.log.error('failed to build page menu', { error });
|
|
|
@ -71,6 +59,8 @@ class PageService extends SiteService {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
await page.save();
|
|
|
|
await page.save();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await this.cacheMainMenuPages();
|
|
|
|
|
|
|
|
|
|
|
|
return page.toObject();
|
|
|
|
return page.toObject();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -121,14 +111,16 @@ class PageService extends SiteService {
|
|
|
|
if (!user.permissions.canPublishPages) {
|
|
|
|
if (!user.permissions.canPublishPages) {
|
|
|
|
throw new SiteError(403, 'You are not permitted to publish pages');
|
|
|
|
throw new SiteError(403, 'You are not permitted to publish pages');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
updateOp.$set.status = striptags(pageDefinition.status.trim());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
updateOp.$set.status = striptags(pageDefinition.status.trim());
|
|
|
|
|
|
|
|
|
|
|
|
await Page.updateOne(
|
|
|
|
await Page.updateOne(
|
|
|
|
{ _id: page._id },
|
|
|
|
{ _id: page._id },
|
|
|
|
updateOp,
|
|
|
|
updateOp,
|
|
|
|
{ upsert: true },
|
|
|
|
{ upsert: true },
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await this.cacheMainMenuPages();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getPages (pagination, status = ['published']) {
|
|
|
|
async getPages (pagination, status = ['published']) {
|
|
|
@ -144,12 +136,21 @@ class PageService extends SiteService {
|
|
|
|
return pages;
|
|
|
|
return pages;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getById (pageId) {
|
|
|
|
async getById (pageId, populateParent) {
|
|
|
|
const page = await Page
|
|
|
|
if (populateParent) {
|
|
|
|
|
|
|
|
const page = await Page
|
|
|
|
|
|
|
|
.findById(pageId)
|
|
|
|
|
|
|
|
.select('+content +menu')
|
|
|
|
|
|
|
|
.populate('menu.parent')
|
|
|
|
|
|
|
|
.lean();
|
|
|
|
|
|
|
|
return page;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
const page = await Page
|
|
|
|
.findById(pageId)
|
|
|
|
.findById(pageId)
|
|
|
|
.select('+content')
|
|
|
|
.select('+content')
|
|
|
|
.lean();
|
|
|
|
.lean();
|
|
|
|
return page;
|
|
|
|
return page;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getBySlug (pageSlug) {
|
|
|
|
async getBySlug (pageSlug) {
|
|
|
@ -158,12 +159,27 @@ class PageService extends SiteService {
|
|
|
|
return this.getById(pageId);
|
|
|
|
return this.getById(pageId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async isParentPage (page) {
|
|
|
|
|
|
|
|
if (page) {
|
|
|
|
|
|
|
|
page = [page];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const parentPage = await Page.distinct( 'menu.parent', { "menu.parent" : { $in : page } } );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return parentPage.length > 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getAvailablePages (excludedPageIds) {
|
|
|
|
async getAvailablePages (excludedPageIds) {
|
|
|
|
const search = { };
|
|
|
|
let search = { };
|
|
|
|
|
|
|
|
|
|
|
|
if (excludedPageIds) {
|
|
|
|
if (excludedPageIds) {
|
|
|
|
search._id = { $nin: excludedPageIds };
|
|
|
|
search._id = { $nin: excludedPageIds };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const pages = await Page.find(search).lean();
|
|
|
|
const pages = (await Page.find(search).lean()).filter((page) => {
|
|
|
|
|
|
|
|
if (page.menu && !page.menu.parent ) {
|
|
|
|
|
|
|
|
return page;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
return pages;
|
|
|
|
return pages;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -179,8 +195,102 @@ class PageService extends SiteService {
|
|
|
|
const pageSlug = slug(pageTitle.trim().toLowerCase()).split('-').slice(0, 4).join('-');
|
|
|
|
const pageSlug = slug(pageTitle.trim().toLowerCase()).split('-').slice(0, 4).join('-');
|
|
|
|
return `${pageSlug}-${pageId}`;
|
|
|
|
return `${pageSlug}-${pageId}`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async cacheMainMenuPages () {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const pages = await Page
|
|
|
|
|
|
|
|
.find({ status: 'published' })
|
|
|
|
|
|
|
|
.select('slug menu')
|
|
|
|
|
|
|
|
.populate({path: 'menu.parent'})
|
|
|
|
|
|
|
|
.lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mainMenu = [];
|
|
|
|
|
|
|
|
await SiteAsync.each(pages, async (page) => {
|
|
|
|
|
|
|
|
if (page.menu.parent) {
|
|
|
|
|
|
|
|
let parent = page.menu.parent;
|
|
|
|
|
|
|
|
if (parent.status === 'published') {
|
|
|
|
|
|
|
|
let parentPage = mainMenu.find(item => item.slug === parent.slug);
|
|
|
|
|
|
|
|
if (parentPage) {
|
|
|
|
|
|
|
|
let childPage = {
|
|
|
|
|
|
|
|
url: `/page/${page.slug}`,
|
|
|
|
|
|
|
|
slug: page.slug,
|
|
|
|
|
|
|
|
icon: page.menu.icon,
|
|
|
|
|
|
|
|
label: page.menu.label,
|
|
|
|
|
|
|
|
order: page.menu.order,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
parentPage.children.splice(childPage.order, 0, childPage);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
let parentPage = {
|
|
|
|
|
|
|
|
url: `/page/${parent.slug}`,
|
|
|
|
|
|
|
|
slug: parent.slug,
|
|
|
|
|
|
|
|
icon: parent.menu.icon,
|
|
|
|
|
|
|
|
label: parent.menu.label,
|
|
|
|
|
|
|
|
order: parent.menu.order,
|
|
|
|
|
|
|
|
children: [],
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
let childPage = {
|
|
|
|
|
|
|
|
url: `/page/${page.slug}`,
|
|
|
|
|
|
|
|
slug: page.slug,
|
|
|
|
|
|
|
|
icon: page.menu.icon,
|
|
|
|
|
|
|
|
label: page.menu.label,
|
|
|
|
|
|
|
|
order: page.menu.order,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
parentPage.children.splice(childPage.order, 0, childPage);
|
|
|
|
|
|
|
|
mainMenu.splice(parentPage.order, 0, parentPage);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
let menuPage = {
|
|
|
|
|
|
|
|
url: `/page/${page.slug}`,
|
|
|
|
|
|
|
|
slug: page.slug,
|
|
|
|
|
|
|
|
icon: page.menu.icon,
|
|
|
|
|
|
|
|
label: page.menu.label,
|
|
|
|
|
|
|
|
order: page.menu.order,
|
|
|
|
|
|
|
|
children: [],
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
mainMenu.splice(menuPage.order, 0, menuPage);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
let isPageInMenu = mainMenu.find(item => item.slug === page.slug);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!isPageInMenu) {
|
|
|
|
|
|
|
|
let menuPage = {
|
|
|
|
|
|
|
|
url: `/page/${page.slug}`,
|
|
|
|
|
|
|
|
slug: page.slug,
|
|
|
|
|
|
|
|
icon: page.menu.icon,
|
|
|
|
|
|
|
|
label: page.menu.label,
|
|
|
|
|
|
|
|
order: page.menu.order,
|
|
|
|
|
|
|
|
children: [],
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
mainMenu.push(menuPage);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mainMenu.sort((a, b) => a.order - b.order);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await SiteAsync.each(mainMenu, async (menu) => {
|
|
|
|
|
|
|
|
if (menu.children) {
|
|
|
|
|
|
|
|
menu.children.sort((a, b) => a.order - b.order);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
const deleteResponse = await this.dtp.services.cache.del("mainMenu");
|
|
|
|
|
|
|
|
this.dtp.log.info(deleteResponse);
|
|
|
|
|
|
|
|
const storeResponse = await this.dtp.services.cache.setObject("mainMenu", mainMenu);
|
|
|
|
|
|
|
|
this.dtp.log.info(storeResponse);
|
|
|
|
|
|
|
|
// const getresp = await this.dtp.services.cache.getObject("mainMenu");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
this.dtp.log.error('failed to build page menu', { error });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getMainMenuPages() {
|
|
|
|
|
|
|
|
return this.dtp.services.cache.getObject("mainMenu");
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
module.exports = {
|
|
|
|
slug: 'page',
|
|
|
|
slug: 'page',
|
|
|
|
name: 'page',
|
|
|
|
name: 'page',
|
|
|
|