@ -7,7 +7,7 @@
const striptags = require ( 'striptags' ) ;
const slug = require ( 'slug' ) ;
const { SiteService , SiteError } = require ( '../../lib/site-lib' ) ;
const { SiteService , SiteError , SiteAsync } = require ( '../../lib/site-lib' ) ;
const mongoose = require ( 'mongoose' ) ;
const ObjectId = mongoose . Types . ObjectId ;
@ -22,26 +22,14 @@ class PageService extends SiteService {
async menuMiddleware ( req , res , next ) {
try {
const pages = await Page
. 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 ;
} ) ;
let mainMenu = await this . getMainMenuPages ( ) ;
if ( ! mainMenu ) {
await this . cacheMainMenuPages ( ) ;
mainMenu = await this . getMainMenuPages ( ) ;
}
res . locals . mainMenu = mainMenu ;
return next ( ) ;
} catch ( error ) {
this . log . error ( 'failed to build page menu' , { error } ) ;
@ -71,6 +59,8 @@ class PageService extends SiteService {
}
await page . save ( ) ;
await this . cacheMainMenuPages ( ) ;
return page . toObject ( ) ;
}
@ -121,14 +111,16 @@ class PageService extends SiteService {
if ( ! user . permissions . canPublishPages ) {
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 (
{ _ id : page . _ id } ,
updateOp ,
{ upsert : true } ,
) ;
await this . cacheMainMenuPages ( ) ;
}
async getPages ( pagination , status = [ 'published' ] ) {
@ -144,12 +136,21 @@ class PageService extends SiteService {
return pages ;
}
async getById ( pageId ) {
const page = await Page
async getById ( pageId , populateParent ) {
if ( populateParent ) {
const page = await Page
. findById ( pageId )
. select ( '+content +menu' )
. populate ( 'menu.parent' )
. lean ( ) ;
return page ;
} else {
const page = await Page
. findById ( pageId )
. select ( '+content' )
. lean ( ) ;
return page ;
return page ;
}
}
async getBySlug ( pageSlug ) {
@ -158,12 +159,27 @@ class PageService extends SiteService {
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 ) {
const search = { } ;
let search = { } ;
if ( 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 ;
}
@ -179,7 +195,101 @@ class PageService extends SiteService {
const pageSlug = slug ( pageTitle . trim ( ) . toLowerCase ( ) ) . split ( '-' ) . slice ( 0 , 4 ) . join ( '-' ) ;
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 = {
slug : 'page' ,