Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@kohanajs/mod-cms

Package Overview
Dependencies
Maintainers
1
Versions
56
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kohanajs/mod-cms - npm Package Compare versions

Comparing version 4.0.0 to 4.2.0

classes/model/PageBlockItem.js

16

CHANGELOG.md

@@ -5,2 +5,18 @@ # Changelog

## [4.2.0](https://gitlab.com/kohana-js/proposals/level0/mod-cms/compare/v4.1.0...v4.2.0) (2021-11-30)
### Features
* page blocks ([f29de7f](https://gitlab.com/kohana-js/proposals/level0/mod-cms/commit/f29de7fee2b073c837801156c3367bc40be5b95b))
## [4.1.0](https://gitlab.com/kohana-js/proposals/level0/mod-cms/compare/v4.0.1...v4.1.0) (2021-11-08)
### Features
* unpublish on delete ([2ad52eb](https://gitlab.com/kohana-js/proposals/level0/mod-cms/commit/2ad52eb2a8cc57a53e3de3351e6e492ca0dccc92))
### [4.0.1](https://gitlab.com/kohana-js/proposals/level0/mod-cms/compare/v4.0.0...v4.0.1) (2021-11-08)
## [4.0.0](https://gitlab.com/kohana-js/proposals/level0/mod-cms/compare/v3.2.0...v4.0.0) (2021-11-08)

@@ -7,0 +23,0 @@

69

classes/controller/admin/Content.js

@@ -1,8 +0,8 @@

const {SQL} = require("@kohanajs/constants");
const path = require('path');
const {readFile} = require('fs').promises;
const {ControllerMixinMultipartForm, HelperForm} = require("@kohanajs/mod-form");
const {ControllerMixinDatabase, ControllerMixinView, ORMAdapter, KohanaJS, ORM} = require("kohanajs");
const {ControllerAdmin} = require("@kohanajs/mod-admin");
const Page = ORM.require('Page');
const PageItem = ORM.require('PageItem');
const PageItemValue = ORM.require('PageItemValue');
const pluralize = require('pluralize');

@@ -67,6 +67,6 @@

async action_create_by_type(){
const { draftDB, page_type } = await this.assignDatabase();
const { draftDB: database, page_type } = await this.assignDatabase();
const insertID = ORMAdapter.defaultID();
const page = ORM.create(Page, {database: draftDB, insertID});
const page = ORM.create(Page, {database, insertID});
page.name = `Untitled ${pluralize.singular(page_type)}`;

@@ -80,54 +80,19 @@ page.page_type = page_type;

async action_page_add_item(){
const pageId = this.request.params['page_id'];
const itemName= this.request.params['item_name'];
async action_import_post(){
const $_POST = this.state.get(ControllerMixinMultipartForm.POST_DATA);
const uploadRoot = `${KohanaJS.EXE_PATH}/../public`;
const file = await HelperForm.moveToUpload($_POST['import_file'], '/media/import', uploadRoot);
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
const page = await ORM.factory(Page, pageId, {database});
if(!page) throw new Error(`Page ${pageId} not found`);
const buffer = await readFile(path.normalize(uploadRoot + file));
const text = buffer.toString('ucs2');
const pageItems = await ORM.readWith(PageItem, [
['', 'page_id', SQL.EQUAL, page.id],
[SQL.AND, 'name', SQL.EQUAL, itemName]
], {database, asArray:true});
const data = text
.replace(/^\uFEFF/, '')
.replaceAll('\r\n', '\n')
.split('\n');
const headers = data.shift().split('\t').map(it => it.toLowerCase());
const masterItem = pageItems.filter(it => it.weight === 1)[0] || pageItems[0];
await masterItem.eagerLoad({with: ['PageItemValue']});
const template = masterItem.page_item_values;
if(!template.length)throw new Error(`PageItem ${masterItem} is empty and cannot be copy`);
const newPageItem = ORM.create(PageItem, {database});
newPageItem.page_id = page.id;
newPageItem.page_version_id = masterItem.page_version_id;
newPageItem.name = masterItem.name;
newPageItem.weight = pageItems.length + 1;
await newPageItem.write();
await Promise.all(
template.map(async itemValue => {
const newValue = ORM.create(PageItemValue, {database});
newValue.page_item_id = newPageItem.id;
newValue.language_id = itemValue.language_id;
newValue.name = itemValue.name;
newValue.attribute_name = itemValue.attribute_name;
newValue.value = '';
await newValue.write();
})
);
await this.redirect(`/admin/pages/${page.id}${this.language ? ("?language="+this.language) : ""}`);
}
async action_page_delete_item(){
const item_id = this.request.params['item_id'];
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
const item = await ORM.factory(PageItem, item_id, {database});
const page_id = item.page_id;
await item.delete();
await this.redirect(`/admin/pages/${page_id}${this.language ? ("?language="+this.language) : ""}`);
}
}
module.exports = ControllerAdminContent;

@@ -0,7 +1,8 @@

const {SQL} = require("@kohanajs/constants");
const path = require('path');
const {stat, mkdir, copyFile, unlink} = require('fs').promises;
const { ControllerAdmin } = require('@kohanajs/mod-admin');
const { ControllerMixinDatabase, ControllerMixinView, KohanaJS, ORM } = require('kohanajs');
const { ControllerMixinMultipartForm } = require('@kohanajs/mod-form');
const { ControllerMixinORMDelete } = require("@kohanajs/mixin-orm");
const { ControllerMixinMultipartForm, HelperForm } = require('@kohanajs/mod-form');
const HelperPage = require('../../helper/Page');

@@ -11,2 +12,9 @@

const Language = ORM.require('Language');
const PageItem = ORM.require('PageItem');
const PageItemValue = ORM.require('PageItemValue');
const PageBlock = ORM.require('PageBlock');
const PageBlockAttribute = ORM.require('PageBlockAttribute');
const PageBlockValue = ORM.require('PageBlockValue');
const PageBlockItem = ORM.require('PageBlockItem');
const PageBlockItemValue = ORM.require('PageBlockItemValue');

@@ -34,26 +42,2 @@ class ControllerAdminPage extends ControllerAdmin {

async moveToUpload(fileField){
const today = new Date();
const uploadFolder = `${KohanaJS.EXE_PATH}/../public`;
const dateFolder = `/media/cms/${today.getFullYear()}/${today.getMonth()+1}/${today.getDate()}`;
const uploadDateFolder = path.normalize(uploadFolder+dateFolder);
//create folder
try{
await stat(uploadDateFolder)
}catch(err){
if(err.code === 'ENOENT'){
await mkdir(uploadDateFolder, {recursive: true});
}else{
throw err;
}
}
const uploadPath = `${dateFolder}/${fileField.tmpName}-${fileField.filename}`;
//move file to media/upload
await copyFile(fileField.tmp, path.normalize(uploadFolder + uploadPath));
await unlink(fileField.tmp);
return uploadPath;
}
async action_update() {

@@ -66,5 +50,2 @@ //if no param id, create page proxy

//find page type name
await HelperPage.defaultValue(instance, instance.page_type, database, this.languageId);
const $_POST = this.state.get(ControllerMixinMultipartForm.POST_DATA);

@@ -76,4 +57,4 @@ //handle files upload

//move tmp file to public/media/upload
const id = key.match(/\((\d+)\)/)[1];
const Model = key.match(/>([^(]+)/)[1];
const id = key.match(/\((\d+)\):value/)[1];
const Model = key.match(/>([^(]+)\(\d+\):value/)[1];

@@ -88,3 +69,3 @@ const instance = await ORM.factory(ORM.require(Model), id, {database});

}
instance.value = await this.moveToUpload($_POST[key]);
instance.value = await HelperForm.moveToUpload($_POST[key], '/media/cms', `${KohanaJS.EXE_PATH}/../public`);
await instance.write();

@@ -95,2 +76,3 @@ }

this.request.session.autosave = $_POST['autosave'];

@@ -131,3 +113,3 @@ switch ($_POST['action']) {

//check page exist, remove it.
const exist = await ORM.readBy(Page, 'id', [page.id],{database, limit:1, asArray:false});
const exist = await ORM.factory(Page, page.id, {database});
if(exist)await exist.delete();

@@ -170,9 +152,16 @@

async action_unpublish(){
async unpublish(){
const id = this.request.params['id'];
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('live');
const exist = await ORM.factory(Page, id,{database});
if(!exist)throw new Error(`Page not published`);
await exist.delete();
try{
const exist = await ORM.factory(Page, id,{database});
await exist.delete();
} catch (e){
}
}
async action_unpublish(){
await this.unpublish();
const draftDB = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');

@@ -186,17 +175,13 @@ const page = await ORM.factory(Page, id, {database: draftDB});

async setEditTemplate(){
setEditTemplate(page, placeholders = {}){
const templateData = this.state.get(ControllerMixinView.TEMPLATE).data;
const page = this.state.get('instance');
await page.eagerLoad({
with:["PageValue", "PageAttribute", "PageItem", "PageBlock"],
page_items: {with: ['PageItemValue']},
page_blocks: {with: ['PageBlockAttribute', 'PageBlockValue']},
});
templateData.values = HelperPage.arrayToObject(page.page_values, this.languageId);
templateData.attributes = HelperPage.arrayToObject(page.page_attributes, this.languageId);
templateData.items = HelperPage.itemsToObject(page.page_items, this.languageId);
templateData.blocks = HelperPage.blocksToObject(page.blocks, this.languageId);
templateData.blocks = HelperPage.blocksToObject(page.page_blocks, this.languageId);
templateData.block_names= Object.keys(KohanaJS.config.cms.blocks) || [];
templateData.language = this.language;
templateData.placeholders = placeholders;
templateData.autosave = this.request.session.autosave;

@@ -207,17 +192,6 @@ const editTemplateFolder = page.page_type ?? 'default';

async syncMasterValues(){
const page = this.state.get('instance');
async syncMasterValues(page){
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
if(this.language === KohanaJS.config.cms.defaultLanguage){
await HelperPage.defaultValue(page, page.page_type, database, this.languageId);
return;
}
const masterLanguage = await ORM.readBy(Language, 'name', [KohanaJS.config.cms.defaultLanguage], {database, limit:1 });
await page.eagerLoad({
with: ['PageValue', 'PageItem', 'PageBlock'],
page_items: {with: ['PageItemValue']},
page_blocks: {with: ['PageBlockValue']},
})

@@ -227,3 +201,3 @@ const masterPageObject = {

items: HelperPage.itemsToObject(page.page_items, masterLanguage.id),
blocks: HelperPage.blocksToObject(page.blocks, masterLanguage.id),
blocks: HelperPage.blocksToObject(page.page_blocks, masterLanguage.id),
}

@@ -237,3 +211,3 @@

items: HelperPage.itemsToObject(page.page_items, this.languageId),
blocks: HelperPage.blocksToObject(page.blocks, this.languageId),
blocks: HelperPage.blocksToObject(page.page_blocks, this.languageId),
}

@@ -283,16 +257,191 @@

async pageEagerLoad(){
const page = this.state.get('instance');
await page.eagerLoad({
with:["PageAttribute", "PageValue", "PageItem", "PageBlock"],
page_items: {with: ['PageItemValue']},
page_blocks: {with: ['PageBlockAttribute', 'PageBlockValue', 'PageBlockItem'],
page_block_items: {with: ['PageBlockItemValue']}
},
});
return page;
}
async action_create(){
await this.setEditTemplate();
this.setEditTemplate(await this.pageEagerLoad());
}
async action_read() {
await this.syncMasterValues();
await this.setEditTemplate();
const page = this.state.get('instance');
const placeholders = {};
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
const masterLanguage = await ORM.readBy(Language, 'name', [KohanaJS.config.cms.defaultLanguage], {database, limit:1 });
const masterLanguageId = masterLanguage.id;
await HelperPage.defaultMasterValue(page, database);
if(this.language !== KohanaJS.config.cms.defaultLanguage){
placeholders.values = HelperPage.arrayToObject(page.page_values, masterLanguageId);
placeholders.attributes = HelperPage.arrayToObject(page.page_attributes, masterLanguageId);
placeholders.items = HelperPage.itemsToObject(page.page_items, masterLanguageId, "page_item_values");
placeholders.blocks = HelperPage.blocksToObject(page.page_blocks, masterLanguageId);
await HelperPage.defaultLanguageValue(page, this.languageId, database);
}
this.setEditTemplate(page, placeholders);
}
async action_edit(){
await this.syncMasterValues();
await this.setEditTemplate();
await this.action_read();
}
async action_delete(){
if(this.state.get(ControllerMixinORMDelete.DELETED)){
await this.unpublish();
//redirect to page type index
const page = this.state.get(ControllerMixinORMDelete.INSTANCE);
await this.redirect(`/admin/contents/list/${page.page_type}`);
}
}
async action_add_item(){
const pageId = this.request.params['page_id'];
const itemName= this.request.params['item_name'];
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
const page = await ORM.factory(Page, pageId, {database});
if(!page) throw new Error(`Page ${pageId} not found`);
const pageItems = await ORM.readWith(PageItem, [
['', 'page_id', SQL.EQUAL, page.id],
[SQL.AND, 'name', SQL.EQUAL, itemName]
], {database, asArray:true});
const masterItem = pageItems.filter(it => it.weight === 1)[0] || pageItems[0];
await masterItem.eagerLoad({with: ['PageItemValue']});
const template = masterItem.page_item_values;
if(!template.length)throw new Error(`PageItem ${masterItem} is empty and cannot be copy`);
const newPageItem = ORM.create(PageItem, {database});
newPageItem.page_id = page.id;
newPageItem.name = masterItem.name;
newPageItem.weight = pageItems.length;
await newPageItem.write();
await Promise.all(
template.map(async itemValue => {
const newValue = ORM.create(PageItemValue, {database});
newValue.page_item_id = newPageItem.id;
newValue.language_id = itemValue.language_id;
newValue.name = itemValue.name;
newValue.attribute_name = itemValue.attribute_name;
newValue.value = '';
await newValue.write();
})
);
await this.redirect(`/admin/pages/${page.id}${this.language ? ("?language="+this.language) : ""}`);
}
async action_delete_item(){
const item_id = this.request.params['item_id'];
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
const item = await ORM.factory(PageItem, item_id, {database});
const page_id = item.page_id;
await item.delete();
await this.redirect(`/admin/pages/${page_id}${this.language ? ("?language="+this.language) : ""}`);
}
async action_add_block_item(){
const blockId = this.request.params['block_id'];
const itemName= this.request.params['item_name'];
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
const block = await ORM.factory(PageBlock, blockId, {database});
if(!block) throw new Error(`Block ${blockId} not found`);
const pageBlockItems = await ORM.readWith(PageBlockItem, [
['', 'page_block_id', SQL.EQUAL, block.id],
[SQL.AND, 'name', SQL.EQUAL, itemName]
], {database, asArray:true});
const masterItem = pageBlockItems.filter(it => it.weight === 1)[0] || pageBlockItems[0];
await masterItem.eagerLoad({with: ['PageBlockItemValue']});
const template = masterItem.page_block_item_values;
if(!template.length)throw new Error(`PageItem ${masterItem} is empty and cannot be copy`);
const newPageBlockItem = ORM.create(PageBlockItem, {database});
newPageBlockItem.page_block_id = block.id;
newPageBlockItem.name = masterItem.name;
newPageBlockItem.weight = pageBlockItems.length;
await newPageBlockItem.write();
await Promise.all(
template.map(async itemValue => {
const newValue = ORM.create(PageBlockItemValue, {database});
newValue.page_block_item_id = newPageBlockItem.id;
newValue.language_id = itemValue.language_id;
newValue.name = itemValue.name;
newValue.attribute_name = itemValue.attribute_name;
newValue.value = '';
await newValue.write();
})
);
await this.redirect(`/admin/pages/${block.page_id}${this.language ? ("?language="+this.language) : ""}`);
}
async action_delete_block_item(){
const item_id = this.request.params['item_id'];
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
const item = await ORM.factory(PageBlockItem, item_id, {database});
const block_id = item.page_block_id;
await item.delete();
const block = await ORM.factory(PageBlock, block_id, {database});
await this.redirect(`/admin/pages/${block.page_id}${this.language ? ("?language="+this.language) : ""}`);
}
async action_add_block(){
const page_id = this.request.params['page_id'];
const blockName= this.request.params['block_name'];
const blueprint = KohanaJS.config.cms.blocks[blockName];
if(!blueprint) throw new Error(`Block ${blockName} not defined in config`);
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
const page = await ORM.factory(Page, page_id, {database});
if(!page) throw new Error(`Page ${page_id} not found`);
const blocks = await ORM.readBy(PageBlock, 'page_id', [page.id], {database, limit: 99999})
const masterLanguage = await ORM.readBy(Language, 'name', [KohanaJS.config.cms.defaultLanguage], {database, limit:1 });
const blockId = ORM.defaultAdapter.defaultID();
const block = ORM.create(PageBlock, {database, insertID: blockId});
block.page_id = page.id;
block.name = blockName;
block.weight = blocks.length;
await block.write();
await HelperPage.initBlock(blueprint, masterLanguage.id, PageBlockAttribute, PageBlockValue, PageBlockItem, PageBlockItemValue, 'page_block_id', blockId, 'page_block_item_id', database);
await this.redirect(`/admin/pages/${page_id}${this.language ? ("?language="+this.language) : ""}`);
}
async action_delete_block(){
const block_id = this.request.params['block_id'];
const database = this.state.get(ControllerMixinDatabase.DATABASES).get('draft');
const item = await ORM.factory(PageBlock, block_id, {database});
const page_id = item.page_id;
await item.delete();
await this.redirect(`/admin/pages/${page_id}${this.language ? ("?language="+this.language) : ""}`);
}
}
module.exports = ControllerAdminPage;

@@ -0,1 +1,2 @@

const { SQL } = require("@kohanajs/constants")
const { ORM, KohanaJS } = require("kohanajs");

@@ -6,5 +7,6 @@ const PageValue = ORM.require('PageValue');

const PageItemValue = ORM.require('PageItemValue');
const Language = ORM.require('Language');
class HelperPage{
static arrayToObject(values, languageId= 1){
static arrayToObject(values=[], languageId= 1){
const result = {};

@@ -25,20 +27,21 @@ values.forEach(it => {

static itemsToObject(items, languageId=1){
static itemsToObject(items=[], languageId=1, children= "page_item_values"){
const result = {}
items.forEach(x => {
result[x.name] = result[x.name] || [];
const obj = { _ : x };
items.forEach(item => {
result[item.name] = result[item.name] || [];
const obj = { _ : item, values : {} };
item.values = obj.values;
x.page_item_values.forEach(y => {
(item[children] || []).forEach(y => {
if(y.language_id && y.language_id !== languageId)return;
if(y.attribute_name){
obj[y.name] = obj[y.name] || {};
obj[y.name][y.attribute_name] = y;
obj.values[y.name] = obj.values[y.name] || {};
obj.values[y.name][y.attribute_name] = y;
return;
}
obj[y.name] = y;
obj.values[y.name] = y;
})
result[x.name].push(obj);
result[item.name].push(obj);
});

@@ -54,8 +57,17 @@

static blocksToObject(blocks){
//TODO, block
return {};
static blocksToObject(blocks=[], languageId = 1){
const result = blocks.map(block =>({
_ : block,
values: this.arrayToObject(block.page_block_values, languageId),
attributes: this.arrayToObject(block.page_block_attributes, languageId),
items: this.itemsToObject(block.page_block_items, languageId, "page_block_item_values"),
}));
//sort items by weight;
result.sort((a, b) => (a._.weight || 0) - (b._.weight || 0));
return result;
}
static async create(mapName, model, name, attribute_name, instance, languageId, database){
static async create(model, name, attribute_name, parentId, languageId, fk, database){
const item = ORM.create(model, {database});

@@ -65,3 +77,3 @@ item.name = name;

if(languageId)item.language_id = languageId;
item.page_id = instance.id;
item[fk] = parentId;
item.value = "";

@@ -72,131 +84,165 @@ await item.write();

static async createEmptyValue(name, attribute_name, instance, languageId, database){
await this.create('pageValueMap', PageValue, name, attribute_name, instance, languageId, database);
static async initBlock(blueprint, languageId, ModelAttribute, ModelValue, ModelItem, ModelItemValue, fk, parent_id, item_fk, database){
if(!blueprint) throw new Error(`Blueprint not defined in config`);
//loop the blueprint
const creators = [];
blueprint.attributes.forEach(it => {
creators.push(this.createField(it, {id: parent_id, attributes:{}}, [], 'attributes', ModelAttribute, fk, database, null));
});
blueprint.values.forEach(it => {
creators.push(this.createField(it, {id: parent_id, values:{}}, [], 'values', ModelValue, fk, database, languageId));
});
//loop items
Object.keys(blueprint.items).forEach(item_name => {
const itemValues = blueprint.items[item_name];
const item = ORM.create(ModelItem, {database});
item.name = item_name;
item[fk] = parent_id;
item.values = {};
creators.push(item.write());
itemValues.forEach(it => {
creators.push(this.createField(it, item, [], "values", ModelItemValue, item_fk, database, languageId));
});
});
await Promise.all(creators);
}
static async createEmptyAttribute(name, attribute_name, instance, database){
await this.create('pageAttributeMap', PageAttribute, name, attribute_name, instance, null, database);
static async createField(blueprint, entity, entityChildren, fieldType, fieldModel, fk, database, languageId){
const creators = [];
//attribute is array of (string | {name: string[] } )
//it is from config file
if(typeof blueprint === "string") {
if(entity[fieldType][blueprint])return;
creators.push(this.create(fieldModel, blueprint, null, entity.id, languageId, fk, database).then(x => entityChildren.push(x)));
}else{
const name = Object.keys(blueprint)[0];
blueprint[name].forEach(attr => {
entity[fieldType][name] = entity[fieldType][name] || {};
if(entity[fieldType][name][attr])return;
creators.push(this.create(fieldModel, name, attr, entity.id, languageId, fk, database).then(x => entityChildren.push(x)))
});
}
await Promise.all(creators)
}
static async createEmptyItemValue(item_name, value_name, subvalue, instance, languageId, database, index=0){
const item = ORM.create(PageItemValue, {database});
item.name = value_name;
if(subvalue)item.attribute_name = subvalue;
if(languageId)item.language_id = languageId;
item.page_item_id = instance.items[item_name][index]._.id;
item.value = "";
await item.write();
return item;
static async updatePageObject(page, language_id){
await page.eagerLoad({
with:["PageAttribute", "PageValue", "PageItem", "PageBlock"],
page_items: {with: ['PageItemValue']},
page_blocks: {with: ['PageBlockAttribute', 'PageBlockValue', 'PageBlockItem'],
page_block_items: {with: ['PageBlockItemValue']}
},
});
page.values = this.arrayToObject(page.page_values, language_id);
page.attributes = this.arrayToObject(page.page_attributes, language_id);
page.items = this.itemsToObject(page.page_items, language_id, "page_item_values");
}
/**
*
* @param {Page} instance
* @param {string} pageType
* @param database
* @param {number} languageId
* @returns {Promise<void>}
*/
static async defaultMasterValue(page, database){
const masterLanguage = await ORM.readBy(Language, 'name', [KohanaJS.config.cms.defaultLanguage], {database, limit:1 });
const masterLanguageId = masterLanguage.id;
static async defaultValue(instance, pageType, database, languageId = 1){
const blueprint = KohanaJS.config.cms.blueprint || {};
const content = blueprint[pageType.toLowerCase()];
if(!content)throw new Error(`Creating undefined content by page type : ${pageType}`);
const pageType = page.page_type;
const blueprints = KohanaJS.config.cms.blueprint || {};
const blueprint = blueprints[pageType];
if(!blueprint)return;
//prepare instance to check default value exists
if(!instance.page_values || !instance.page_attributes || !instance.page_items ){
await instance.eagerLoad({
with: ['PageValue', 'PageAttribute', 'PageItem'],
page_items: {
with: ['PageItemValue']
}
});
}
await this.updatePageObject(page, masterLanguageId);
if(!instance.values || !instance.attributes || !instance.items ){
instance.values = this.arrayToObject(instance.page_values, languageId);
instance.attributes = this.arrayToObject(instance.page_attributes, languageId);
instance.items = this.itemsToObject(instance.page_items, languageId);
}
//loop the blueprint
const creators = [];
await Promise.all(
content.attributes.map(async it => {
//it is from config file
if(typeof it === "string") {
if(instance.attributes[it])return;
return await this.createEmptyAttribute(it, null, instance, database);
}
blueprint.attributes.forEach(it => {
creators.push(this.createField(it, page, page.page_attributes, "attributes", PageAttribute, "page_id", database));
});
const name = Object.keys(it)[0];
const subvalues = it[name];
blueprint.values.forEach(it => {
creators.push(this.createField(it, page, page.page_values, "values", PageValue, "page_id", database, masterLanguageId));
});
await Promise.all(
subvalues.map(async attr => {
if(instance.attributes[name] && instance.attributes[name][attr])return;
await this.createEmptyAttribute(name, attr, instance, database)
})
);
})
)
Object.keys(blueprint.items).forEach(item_name => {
const blueprintItem = blueprint.items[item_name];
await Promise.all(
content.values.map(async it => {
if(typeof it === "string") {
if(instance.values[it]) return;
return await this.createEmptyValue(it, null, instance, languageId, database);
}
if(!page.items[item_name]){
//no item, create one
const item = ORM.create(PageItem, {database});
item.name = item_name;
item.page_id = page.id;
item.page_item_values = [];
const obj = { _ :item, values:{} };
item.values = obj.values;
const name = Object.keys(it)[0];
const subvalues = it[name];
creators.push(item.write());
page.page_items.push(item);
page.items[item_name] = [obj];
}
await Promise.all(
subvalues.map(async attr => {
if(instance.values[name] && instance.values[name][attr])return;
await this.createEmptyValue(name, attr, instance, languageId, database)
})
);
page.items[item_name].forEach(item =>{
//create item value by blueprint
blueprintItem.forEach(it => {
creators.push(this.createField(it, item._, item._.page_item_values, "values", PageItemValue, "page_item_id", database, masterLanguageId));
});
})
);
});
await Promise.all(creators);
}
static getFieldMap(fields, prefix, language_id){
const result = new Map();
fields.forEach(it =>{
if(it.language_id === language_id){
result.set(`${prefix}::${it.name}::${it.attribute_name || ''}`, it);
}
});
return result;
}
static async fieldFactory(fields, prefix, master_language_id, language_id, mapCompare, database){
await Promise.all(
Object.keys(content.items).map(async item_name => {
if(!instance.items[item_name]){
instance.items[item_name] = [];
const item = instance.items[item_name];
const firstItem = await ORM.readWith(PageItem, [['', 'page_id', SQL.EQUAL, instance.id], [SQL.AND, 'name', SQL.EQUAL, item_name], [SQL.AND, 'weight', SQL.EQUAL, 1]], {database});
fields.map(it => {
if(it.language_id !== master_language_id)return;
//check difference
if(mapCompare.get(`${prefix}::${it.name}::${it.attribute_name || ""}`))return;
//create languge fields
if(!firstItem){
const firstItem = ORM.create(PageItem, {database});
firstItem.page_id = instance.id;
firstItem.name = item_name;
firstItem.weight = 1;
await firstItem.write();
item[0] = {_: firstItem};
}
}
const field = ORM.create(it.constructor, {database});
Object.assign(field, it);
field.id = null;
field.language_id = language_id;
field.value = "";
return field.write();
})
)
}
await Promise.all(
content.items[item_name].map(async value => {
if(typeof value === "string") {
if(instance.items[item_name] && instance.items[item_name][0][value])return;
return await this.createEmptyItemValue(item_name, value, null, instance, languageId, database);
}
static async defaultLanguageValue(page, language_id, database){
const masterLanguage = await ORM.readBy(Language, 'name', [KohanaJS.config.cms.defaultLanguage], {database, limit:1 });
const masterLanguageId = masterLanguage.id;
//queue all fields
//map languge fields
const valueMap = this.getFieldMap(page.page_values, '', language_id);
const itemValueMap = new Map(page.page_items.map(item => [...this.getFieldMap(item.page_item_values, item.id, language_id)]).flat());
const blockValueMap = new Map(page.page_blocks.map(block => [...this.getFieldMap(block.page_block_values, block.id, language_id)]).flat());
const blockItemValueMap = new Map(page.page_blocks.map(block => block.page_block_items.map(item => [...this.getFieldMap(item.page_block_item_values, item.id, language_id)]).flat(2)));
const valueName = Object.keys(value)[0];
await Promise.all(
value[valueName].map(async subvalue => {
//guard item value with attribute exist
if(
instance.items[item_name][0] &&
instance.items[item_name][0][valueName] &&
instance.items[item_name][0][valueName][subvalue]
)return;
//loop master fields to find undefined language fields
await Promise.all([
this.fieldFactory(page.page_values, '', masterLanguageId, language_id, valueMap, database),
...page.page_items.map(item => this.fieldFactory(item.page_item_values, item.id, masterLanguageId, language_id, itemValueMap, database)),
...page.page_blocks.map(block => this.fieldFactory(block.page_block_values, block.id, masterLanguageId, language_id, blockValueMap, database)),
...page.page_blocks.map(async block => await Promise.all(block.page_block_items.map(item => this.fieldFactory(item.page_block_item_values, item.id, masterLanguageId, language_id, blockItemValueMap, database)))),
]);
await this.createEmptyItemValue(item_name, valueName, subvalue, instance, languageId, database)
})
);
})
)
})
);
await this.updatePageObject(page, language_id);
}

@@ -203,0 +249,0 @@ }

@@ -16,3 +16,4 @@ const {ORM} = require('kohanajs');

["language_id", "PageItemValue"],
["language_id", "PageBlockValue"]
["language_id", "PageBlockValue"],
["language_id", "PageBlockItemValue"]
];

@@ -19,0 +20,0 @@ }

@@ -5,2 +5,3 @@ const {ORM} = require('kohanajs');

page_id = null;
name = null;
weight = 0;

@@ -12,2 +13,3 @@

static fields = new Map([
["name", "String"],
["weight", "Int"]

@@ -20,3 +22,4 @@ ]);

["page_block_id", "PageBlockAttribute"],
["page_block_id", "PageBlockValue"]
["page_block_id", "PageBlockValue"],
["page_block_id", "PageBlockItem"]
];

@@ -23,0 +26,0 @@ }

@@ -16,2 +16,25 @@ const { KohanaJS } = require('kohanajs');

},
blocks: {
logos : {
attributes:[],
values: ['label'],
items:{
pictures: ["url"]
}
},
timelines:{
attributes:["start-year", "end-year"],
values:["subject"],
items: {
events: ["subject", "body"]
}
},
paragraphs:{
attributes: [],
values: ["subject", "body", "picture", "caption", "description"],
items: {}
}
}
};

@@ -9,2 +9,10 @@ const {KohanaJS} = require('kohanajs')

RouteList.add('/admin/pages/add-block/:page_id/:block_name', 'controller/admin/Page', 'add_block');
RouteList.add('/admin/pages/delete-block/:block_id', 'controller/admin/Page', 'delete_block');
RouteList.add('/admin/pages/add-block-item/:block_id/:item_name', 'controller/admin/Page', 'add_block_item');
RouteList.add('/admin/pages/delete-block-item/:item_id', 'controller/admin/Page', 'delete_block_item');
RouteList.add('/admin/pages/add-item/:page_id/:item_name', 'controller/admin/Page', 'add_item');
RouteList.add('/admin/pages/delete-item/:item_id', 'controller/admin/Page', 'delete_item');
RouteList.add('/admin/pages/un-publish/:id', 'controller/admin/Page', 'unpublish');

@@ -15,4 +23,2 @@ RouteCRUD.add('pages', 'controller/admin/Page');

RouteList.add('/admin/contents/create/:page_type', 'controller/admin/Content', 'create_by_type');
RouteList.add('/admin/contents/page-add-item/:page_id/:item_name', 'controller/admin/Content', 'page_add_item');
RouteList.add('/admin/contents/page-delete-item/:item_id', 'controller/admin/Content', 'page_delete_item');
{
"name": "@kohanajs/mod-cms",
"version": "4.0.0",
"version": "4.2.0",
"description": "The CMS module for KohanaJS",

@@ -5,0 +5,0 @@ "main": "index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc