nfp_sites/old/article/model.mjs

160 lines
4.4 KiB
JavaScript

import { createPrototype, safeColumns } from '../knex.mjs'
import Media from '../media/model.mjs'
import File from '../file/model.mjs'
import Staff from '../staff/model.mjs'
import Page from '../page/model.mjs'
/*
Article model:
{
name,
path,
description,
media_id,
staff_id,
parent_id,
is_deleted,
created_at,
updated_at,
}
*/
function ArticleItem(data) {
Object.assign(this, data)
}
function Article() {
this.tableName = 'articles'
this.Model = ArticleItem
this.includes = {
staff: Staff.includeHasOne('articles.staff_id', 'id'),
media: Media.includeHasOne('articles.media_id', 'id'),
banner: Media.includeHasOne('articles.banner_id', 'id'),
parent: Page.includeHasOne('articles.parent_id', 'id'),
files: File.includeHasMany('article_id', 'articles.id'),
}
this.publicFields = this.privateFields = safeColumns([
'staff_id',
'parent_id',
'name',
'path',
'description',
'banner_id',
'media_id',
'published_at',
'is_featured',
])
this.init()
}
Article.prototype = createPrototype({
getAll(ctx, where = null, includes = [], orderBy = 'id', limitToday = false) {
return this._getAll(ctx, (qb) => {
if (where) qb.where(where)
if (limitToday) {
qb.where(this.tableName + '.published_at', '<=', (new Date()).toISOString())
}
}, includes, orderBy, [])
},
getAllFromPage(ctx, pageId, includes = [], orderBy = 'id', limitToday = false) {
return this._getAll(ctx, (qb) => {
qb = qb.innerJoin('pages', 'articles.parent_id', 'pages.id')
qb.where(subq => {
subq.where('pages.id', pageId)
.orWhere('pages.parent_id', pageId)
})
if (limitToday) {
qb.where(this.tableName + '.published_at', '<=', (new Date()).toISOString())
}
return qb
}, includes, orderBy, [])
},
getSingle(id, includes = [], require = true, ctx = null, limitToday = false) {
return this._getSingle(qb => {
qb.where(subq => {
subq.where(this.tableName + '.id', '=', Number(id) || 0)
.orWhere(this.tableName + '.path', '=', id)
})
if (limitToday && (!ctx || !ctx.state.user || ctx.state.user.level < 10)) {
qb.where(this.tableName + '.published_at', '<=', (new Date()).toISOString())
}
}, includes, require, ctx)
},
getFeaturedArticle(includes = [], ctx = null) {
return this._getSingle(qb => {
qb.where({ is_featured: true })
.where(this.tableName + '.published_at', '<=', (new Date()).toISOString())
.orderBy(this.tableName + '.published_at', 'DESC')
.select(this.knex.raw('1 as __group'))
.limit(1)
}, includes, false, ctx)
},
async getFrontpageArticles(orgPage = 1) {
let page = Math.max(orgPage, 1)
let out = {
featured: null,
items: [],
total: 0,
}
let qFeatured = this.query(qb => {
return qb.where({ is_featured: true })
.where(this.tableName + '.published_at', '<=', (new Date()).toISOString())
.orderBy(this.tableName + '.published_at', 'DESC')
.select(this.knex.raw('1 as __group'))
.limit(1)
}, ['staff', 'media', 'banner'])
let qArticles = this.query(qb => {
return qb
.where(this.tableName + '.published_at', '<=', (new Date()).toISOString())
.select(this.knex.raw('2 as __group'))
.orderBy(this.tableName + '.published_at', 'DESC')
.limit(10)
.offset((page - 1) * 10)
}, ['staff', 'media', 'banner'], null, qFeatured)
let [articles, total] = await Promise.all([
this.getAllQuery(
this.knex
.unionAll(qFeatured, true)
.unionAll(qArticles, true),
qFeatured
),
this.knex('articles')
.where(this.tableName + '.published_at', '<=', (new Date()).toISOString())
.where({ is_deleted: false })
.count('* as count'),
])
out.total = total[0].count
if (articles.length > 0 && articles[0].is_featured) {
out.featured = articles[0]
out.items = articles.slice(1)
} else {
out.items = articles
}
return out
},
setAllUnfeatured() {
return knex('articles')
.where({ is_featured: true })
.update({
is_featured: false,
})
},
})
const articleInstance = new Article()
// Hook into includes for Page
// Page.addInclude('news', articleInstance.includeHasMany('parent_id', 'pages.id'))
export default articleInstance