159 lines
4.4 KiB
JavaScript
159 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
|