UNPKG

jsharmony-cms

Version:
744 lines (661 loc) 43.1 kB
/* Copyright 2019 apHarmony This file is part of jsHarmony. jsHarmony is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. jsHarmony is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this package. If not, see <http://www.gnu.org/licenses/>. */ var Helper = require('jsharmony/Helper'); var _ = require('lodash'); var async = require('async'); module.exports = exports = function(module, funcs){ var exports = {}; var _t = module._t; //Add old and new pages to branch_data.page_keys exports.conflicts_getPages = function(branch_data, callback){ var jsh = module.jsh; var appsrv = jsh.AppSrv; var dbtypes = appsrv.DB.types; branch_data.page_keys = {}; var sql_ptypes = [dbtypes.BigInt, dbtypes.BigInt]; var sql_params = { src_branch_id: branch_data.src_branch_id, dst_branch_id: branch_data.dst_branch_id }; var sql = "\ select 'DST_NEW' branch_diff_type,page_id,page_key,page_file_id,page_title,page_path,page_tags,page_author,page_template_id,page_template_path,page_seo_title,page_seo_canonical_url,page_seo_metadesc,page_seo_keywords,page_review_sts,page_lang \ from "+(module.schema?module.schema+'.':'')+'page page where page_is_folder = 0 and page.page_id in (select page_id from '+(module.schema?module.schema+'.':'')+"branch_page where branch_id=@dst_branch_id) \ union all \ select 'DST_PREV' branch_diff_type,page_id,page_key,page_file_id,page_title,page_path,page_tags,page_author,page_template_id,page_template_path,page_seo_title,page_seo_canonical_url,page_seo_metadesc,page_seo_keywords,page_review_sts,page_lang \ from "+(module.schema?module.schema+'.':'')+'page page where page_is_folder = 0 and page.page_id in (select page_orig_id from '+(module.schema?module.schema+'.':'')+"branch_page where branch_id=@dst_branch_id) \ union all \ select 'SRC_NEW' branch_diff_type,page_id,page_key,page_file_id,page_title,page_path,page_tags,page_author,page_template_id,page_template_path,page_seo_title,page_seo_canonical_url,page_seo_metadesc,page_seo_keywords,page_review_sts,page_lang \ from "+(module.schema?module.schema+'.':'')+'page page where page_is_folder = 0 and page.page_id in (select page_id from '+(module.schema?module.schema+'.':'')+"branch_page where branch_id=@src_branch_id) \ union all \ select 'SRC_PREV' branch_diff_type,page_id,page_key,page_file_id,page_title,page_path,page_tags,page_author,page_template_id,page_template_path,page_seo_title,page_seo_canonical_url,page_seo_metadesc,page_seo_keywords,page_review_sts,page_lang \ from "+(module.schema?module.schema+'.':'')+'page page where page_is_folder = 0 and page.page_id in (select page_orig_id from '+(module.schema?module.schema+'.':'')+'branch_page where branch_id=@src_branch_id) \ '; appsrv.ExecRecordset(branch_data._DBContext, sql, sql_ptypes, sql_params, function (err, rslt) { if (err != null) { err.sql = sql; return callback(err); } if(rslt && rslt[0]){ _.each(rslt[0], function(page){ branch_data.page_keys[page.page_key] = page; if( (page.branch_diff_type=='DST_NEW') || (page.branch_diff_type=='DST_PREV' && !(page.page_key in branch_data.page_keys)) || (page.branch_diff_type=='SRC_NEW' && !(page.page_key in branch_data.page_keys)) || (page.branch_diff_type=='SRC_PREV' && !(page.page_key in branch_data.page_keys)) ) branch_data.page_keys[page.page_key] = page; }); } return callback(); }); }; //Add old and new media to branch_data.media_keys exports.conflicts_getMedia = function(branch_data, callback){ var jsh = module.jsh; var appsrv = jsh.AppSrv; var dbtypes = appsrv.DB.types; branch_data.media_keys = {}; var sql_ptypes = [dbtypes.BigInt, dbtypes.BigInt]; var sql_params = { src_branch_id: branch_data.src_branch_id, dst_branch_id: branch_data.dst_branch_id }; var sql = "\ select 'DST_NEW' branch_diff_type,media_id,media_key,media_file_id,media_desc,media_path \ from "+(module.schema?module.schema+'.':'')+'media media where media_is_folder=0 and media.media_id in (select media_id from '+(module.schema?module.schema+'.':'')+"branch_media where branch_id=@dst_branch_id)\ union all \ select 'DST_PREV' branch_diff_type,media_id,media_key,media_file_id,media_desc,media_path \ from "+(module.schema?module.schema+'.':'')+'media media where media_is_folder=0 and media.media_id in (select media_orig_id from '+(module.schema?module.schema+'.':'')+"branch_media where branch_id=@dst_branch_id)\ union all \ select 'SRC_NEW' branch_diff_type,media_id,media_key,media_file_id,media_desc,media_path \ from "+(module.schema?module.schema+'.':'')+'media media where media_is_folder=0 and media.media_id in (select media_id from '+(module.schema?module.schema+'.':'')+"branch_media where branch_id=@src_branch_id)\ union all \ select 'SRC_PREV' branch_diff_type,media_id,media_key,media_file_id,media_desc,media_path \ from "+(module.schema?module.schema+'.':'')+'media media where media_is_folder=0 and media.media_id in (select media_orig_id from '+(module.schema?module.schema+'.':'')+'branch_media where branch_id=@src_branch_id)\ '; appsrv.ExecRecordset(branch_data._DBContext, sql, sql_ptypes, sql_params, function (err, rslt) { if (err) return callback(err); if(rslt && rslt[0]){ _.each(rslt[0], function(media){ if( (media.branch_diff_type=='DST_NEW') || (media.branch_diff_type=='DST_PREV' && !(media.media_key in branch_data.media_keys)) || (media.branch_diff_type=='SRC_NEW' && !(media.media_key in branch_data.media_keys)) || (media.branch_diff_type=='DST_PRV' && !(media.media_key in branch_data.media_keys)) ) branch_data.media_keys[media.media_key] = media; }); } return callback(); }); }; exports.conflicts_page = function(branch_pages, branch_data, callback){ var jsh = module.jsh; var appsrv = jsh.AppSrv; var dbtypes = appsrv.DB.types; var updated_pages = {}; async.waterfall([ //Get updated pages function(cb){ var sql_ptypes = [dbtypes.BigInt, dbtypes.BigInt]; var sql_params = { src_branch_id: branch_data.src_branch_id, dst_branch_id: branch_data.dst_branch_id }; var sql = 'select page_id,page_key,page_file_id,page_title,page_path,page_tags,page_author,page_template_id,page_template_path,page_seo_title,page_seo_canonical_url,page_seo_metadesc,page_seo_keywords,page_review_sts,page_lang \ from '+(module.schema?module.schema+'.':'')+'page page \ where page_is_folder = 0 and (\ page.page_id in (select page_id from '+(module.schema?module.schema+'.':'')+'branch_page where branch_id=@src_branch_id and branch_page_action is not null) or \ page.page_id in (select page_orig_id from '+(module.schema?module.schema+'.':'')+"branch_page where branch_id=@src_branch_id and branch_page_action = 'UPDATE') or \ page.page_id in (select page_id from "+(module.schema?module.schema+'.':'')+'branch_page src_branch_page where src_branch_page.branch_id=@src_branch_id and src_branch_page.page_key in (select page_key from '+(module.schema?module.schema+'.':'')+'branch_page dst_branch_page where dst_branch_page.branch_id=@dst_branch_id and branch_page_action is not null)) or \ page.page_id in (select page_id from '+(module.schema?module.schema+'.':'')+'branch_page where branch_id=@dst_branch_id and branch_page_action is not null) or \ page.page_id in (select page_orig_id from '+(module.schema?module.schema+'.':'')+"branch_page where branch_id=@dst_branch_id and branch_page_action = 'UPDATE') or \ page.page_id in (select page_id from "+(module.schema?module.schema+'.':'')+'branch_page dst_branch_page where dst_branch_page.branch_id=@dst_branch_id and dst_branch_page.page_key in (select page_key from '+(module.schema?module.schema+'.':'')+'branch_page src_branch_page where src_branch_page.branch_id=@src_branch_id and branch_page_action is not null)) \ )'; appsrv.ExecRecordset(branch_data._DBContext, sql, sql_ptypes, sql_params, function (err, rslt) { if (err != null) { err.sql = sql;return cb(err); } if(rslt && rslt[0]){ _.each(rslt[0], function(page){ updated_pages[page.page_id] = page; }); } return cb(); }); }, //Get page file content function(cb){ async.eachOfSeries(updated_pages, function(page, page_id, page_cb){ funcs.getClientPage(branch_data._DBContext, page, null, branch_data.site_id, { includeExtraRemoteContent: true, pageTemplates: branch_data.page_templates, ignoreInvalidPageTemplate: true }, function(err, clientPage){ if(err) return page_cb(err); if(!clientPage) return page_cb(null); funcs.localizePageURLs(clientPage.page, branch_data.baseurl, !!clientPage.template.raw); page.compiled = clientPage.page; page.template = clientPage.template; if(page.compiled.content){ var pretty_params = { unformatted: ['code', 'pre'], indent_inner_html: true, indent_char: ' ', indent_size: 2, sep: '\n' }; for(var key in page.compiled.content){ page.compiled.content[key] = funcs.prettyhtml(page.compiled.content[key], pretty_params); } } page.template_title = clientPage.template.title; return page_cb(null); }); }, cb); }, //Perform page diff function(cb){ _.each(branch_pages, function(branch_page){ if(branch_page.src_branch_page_action && branch_page.src_branch_page_action.toUpperCase()=='UPDATE' && branch_page.dst_branch_page_action && branch_page.dst_branch_page_action.toUpperCase()=='UPDATE'){ branch_page.src_diff = funcs.diff_pageContent(updated_pages[branch_page.src_orig_page.id], updated_pages[branch_page.src_page.id]); branch_page.dst_diff = funcs.diff_pageContent(updated_pages[branch_page.dst_orig_page.id], updated_pages[branch_page.dst_page.id]); } else if(branch_page.src_branch_page_action && branch_page.src_branch_page_action.toUpperCase()=='UPDATE'){ branch_page.src_diff = funcs.diff_pageContent(updated_pages[branch_page.src_orig_page.id], updated_pages[branch_page.src_page.id]); branch_page.dst_diff = funcs.diff_pageContent(updated_pages[branch_page.src_orig_page.id], updated_pages[branch_page.dst_page.id]); if (branch_page.dst_diff) branch_page.dst_diff.diff_with_cmp_branch = true; } else if(branch_page.dst_branch_page_action && branch_page.dst_branch_page_action.toUpperCase()=='UPDATE'){ branch_page.src_diff = funcs.diff_pageContent(updated_pages[branch_page.dst_orig_page.id], updated_pages[branch_page.src_page.id]); branch_page.dst_diff = funcs.diff_pageContent(updated_pages[branch_page.dst_orig_page.id], updated_pages[branch_page.dst_page.id]); if (branch_page.src_diff) branch_page.src_diff.diff_with_cmp_branch = true; } }); return cb(); }, ], callback); }; exports.conflicts_media = function(branch_media, branch_data, callback){ var jsh = module.jsh; var appsrv = jsh.AppSrv; var dbtypes = appsrv.DB.types; var media = {}; async.waterfall([ //Get all media function(cb){ var sql_ptypes = [dbtypes.BigInt, dbtypes.BigInt]; var sql_params = { src_branch_id: branch_data.src_branch_id, dst_branch_id: branch_data.dst_branch_id }; var sql = 'select media_id,media_key,media_file_id,media_desc,media_tags,media_type,media_path \ from '+(module.schema?module.schema+'.':'')+'media media \ where\ media.media_id in (select media_id from '+(module.schema?module.schema+'.':'')+'branch_media where branch_id=@src_branch_id and branch_media_action is not null) or \ media.media_id in (select media_orig_id from '+(module.schema?module.schema+'.':'')+"branch_media where branch_id=@src_branch_id and branch_media_action = 'UPDATE') or\ media.media_id in (select media_id from "+(module.schema?module.schema+'.':'')+'branch_media src_branch_media where src_branch_media.branch_id=@src_branch_id and src_branch_media.media_key in (select media_key from '+(module.schema?module.schema+'.':'')+'branch_media dst_branch_media where dst_branch_media.branch_id=@dst_branch_id and branch_media_action is not null)) or \ media.media_id in (select media_id from '+(module.schema?module.schema+'.':'')+'branch_media where branch_id=@dst_branch_id and branch_media_action is not null) or \ media.media_id in (select media_orig_id from '+(module.schema?module.schema+'.':'')+"branch_media where branch_id=@dst_branch_id and branch_media_action = 'UPDATE') or\ media.media_id in (select media_id from "+(module.schema?module.schema+'.':'')+'branch_media dst_branch_media where dst_branch_media.branch_id=@dst_branch_id and dst_branch_media.media_key in (select media_key from '+(module.schema?module.schema+'.':'')+'branch_media src_branch_media where src_branch_media.branch_id=@src_branch_id and branch_media_action is not null))'; appsrv.ExecRecordset(branch_data._DBContext, sql, sql_ptypes, sql_params, function (err, rslt) { if (err != null) { err.sql = sql;return cb(err); } if(rslt && rslt[0]){ _.each(rslt[0], function(media_item){ media[media_item.media_id] = media_item; }); } return cb(); }); }, //Perform media diff function(cb){ _.each(branch_media, function(branch_media_item){ if(branch_media_item.src_branch_media_action && branch_media_item.src_branch_media_action.toUpperCase()=='UPDATE' && branch_media_item.dst_branch_media_action && branch_media_item.dst_branch_media_action.toUpperCase()=='UPDATE'){ branch_media_item.src_diff = funcs.mediaDiff(media[branch_media_item.src_orig_media.id], media[branch_media_item.src_media.id]); branch_media_item.dst_diff = funcs.mediaDiff(media[branch_media_item.dst_orig_media.id], media[branch_media_item.dst_media.id]); } else if(branch_media_item.src_branch_media_action && branch_media_item.src_branch_media_action.toUpperCase()=='UPDATE'){ branch_media_item.src_diff = funcs.mediaDiff(media[branch_media_item.src_orig_media.id], media[branch_media_item.src_media.id]); branch_media_item.dst_diff = funcs.mediaDiff(media[branch_media_item.src_orig_media.id], media[branch_media_item.dst_media.id]); if (branch_media_item.dst_diff) branch_media_item.dst_diff.diff_with_cmp_branch = true; } else if(branch_media_item.dst_branch_media_action && branch_media_item.dst_branch_media_action.toUpperCase()=='UPDATE'){ branch_media_item.src_diff = funcs.mediaDiff(media[branch_media_item.dst_orig_media.id], media[branch_media_item.src_media.id]); branch_media_item.dst_diff = funcs.mediaDiff(media[branch_media_item.dst_orig_media.id], media[branch_media_item.dst_media.id]); if (branch_media_item.src_diff) branch_media_item.src_diff.diff_with_cmp_branch = true; } }); return cb(); }, ], callback); }; exports.conflicts_menu = function(branch_menus, branch_data, callback){ var jsh = module.jsh; var appsrv = jsh.AppSrv; var dbtypes = appsrv.DB.types; var menus = {}; async.waterfall([ //Get all menus function(cb){ var sql_ptypes = [dbtypes.BigInt, dbtypes.BigInt]; var sql_params = { src_branch_id: branch_data.src_branch_id, dst_branch_id: branch_data.dst_branch_id }; var sql = 'select menu_id,menu_key,menu_file_id,menu_name,menu_tag \ from '+(module.schema?module.schema+'.':'')+'menu menu \ where\ menu.menu_id in (select menu_id from '+(module.schema?module.schema+'.':'')+'branch_menu where branch_id=@src_branch_id and branch_menu_action is not null) or \ menu.menu_id in (select menu_orig_id from '+(module.schema?module.schema+'.':'')+"branch_menu where branch_id=@src_branch_id and branch_menu_action = 'UPDATE') or\ menu.menu_id in (select menu_id from "+(module.schema?module.schema+'.':'')+'branch_menu src_branch_menu where src_branch_menu.branch_id=@src_branch_id and src_branch_menu.menu_key in (select menu_key from '+(module.schema?module.schema+'.':'')+'branch_menu dst_branch_menu where dst_branch_menu.branch_id=@dst_branch_id and branch_menu_action is not null)) or \ menu.menu_id in (select menu_id from '+(module.schema?module.schema+'.':'')+'branch_menu where branch_id=@dst_branch_id and branch_menu_action is not null) or \ menu.menu_id in (select menu_orig_id from '+(module.schema?module.schema+'.':'')+"branch_menu where branch_id=@dst_branch_id and branch_menu_action = 'UPDATE') or\ menu.menu_id in (select menu_id from "+(module.schema?module.schema+'.':'')+'branch_menu dst_branch_menu where dst_branch_menu.branch_id=@dst_branch_id and dst_branch_menu.menu_key in (select menu_key from '+(module.schema?module.schema+'.':'')+'branch_menu src_branch_menu where src_branch_menu.branch_id=@src_branch_id and branch_menu_action is not null))'; appsrv.ExecRecordset(branch_data._DBContext, sql, sql_ptypes, sql_params, function (err, rslt) { if (err != null) { err.sql = sql;return cb(err); } if(rslt && rslt[0]){ _.each(rslt[0], function(menu){ menus[menu.menu_id] = menu; }); } return cb(); }); }, //Get menu file content function(cb){ async.eachOfSeries(menus, function(menu, menu_id, menu_cb){ funcs.getClientMenu(menu, function(err, menu_content){ if(err) return menu_cb(err); if(!menu_content) return menu_cb(null); menu.menu_items_text = funcs.prettyMenu(menu_content.menu_items, branch_data.page_keys, branch_data.media_keys); return menu_cb(); }); }, cb); }, //Perform menu diff function(cb){ _.each(branch_menus, function(branch_menu){ if(branch_menu.src_branch_menu_action && branch_menu.src_branch_menu_action.toUpperCase()=='UPDATE' && branch_menu.dst_branch_menu_action && branch_menu.dst_branch_menu_action.toUpperCase()=='UPDATE'){ branch_menu.src_diff = funcs.menuDiff(menus[branch_menu.src_orig_menu.id], menus[branch_menu.src_menu.id]); branch_menu.dst_diff = funcs.menuDiff(menus[branch_menu.dst_orig_menu.id], menus[branch_menu.dst_menu.id]); } else if(branch_menu.src_branch_menu_action && branch_menu.src_branch_menu_action.toUpperCase()=='UPDATE'){ branch_menu.src_diff = funcs.menuDiff(menus[branch_menu.src_orig_menu.id], menus[branch_menu.src_menu.id]); branch_menu.dst_diff = funcs.menuDiff(menus[branch_menu.src_orig_menu.id], menus[branch_menu.dst_menu.id]); if (branch_menu.dst_diff) branch_menu.dst_diff.diff_with_cmp_branch = true; } else if(branch_menu.dst_branch_menu_action && branch_menu.dst_branch_menu_action.toUpperCase()=='UPDATE'){ branch_menu.src_diff = funcs.menuDiff(menus[branch_menu.dst_orig_menu.id], menus[branch_menu.src_menu.id]); branch_menu.dst_diff = funcs.menuDiff(menus[branch_menu.dst_orig_menu.id], menus[branch_menu.dst_menu.id]); if (branch_menu.src_diff) branch_menu.src_diff.diff_with_cmp_branch = true; } }); return cb(); }, ], callback); }; exports.conflicts_sitemap = function(branch_sitemaps, branch_data, callback){ var jsh = module.jsh; var appsrv = jsh.AppSrv; var dbtypes = appsrv.DB.types; var sitemaps = {}; async.waterfall([ //Get all sitemaps function(cb){ var sql_ptypes = [dbtypes.BigInt, dbtypes.BigInt]; var sql_params = { src_branch_id: branch_data.src_branch_id, dst_branch_id: branch_data.dst_branch_id }; var sql = 'select sitemap_id,sitemap_key,sitemap_file_id,sitemap_name,sitemap_type \ from '+(module.schema?module.schema+'.':'')+'sitemap sitemap \ where\ sitemap.sitemap_id in (select sitemap_id from '+(module.schema?module.schema+'.':'')+'branch_sitemap where branch_id=@src_branch_id and branch_sitemap_action is not null) or \ sitemap.sitemap_id in (select sitemap_orig_id from '+(module.schema?module.schema+'.':'')+"branch_sitemap where branch_id=@src_branch_id and branch_sitemap_action = 'UPDATE') or\ sitemap.sitemap_id in (select sitemap_id from "+(module.schema?module.schema+'.':'')+'branch_sitemap src_branch_sitemap where src_branch_sitemap.branch_id=@src_branch_id and src_branch_sitemap.sitemap_key in (select sitemap_key from '+(module.schema?module.schema+'.':'')+'branch_sitemap dst_branch_sitemap where dst_branch_sitemap.branch_id=@dst_branch_id and branch_sitemap_action is not null)) or \ sitemap.sitemap_id in (select sitemap_id from '+(module.schema?module.schema+'.':'')+'branch_sitemap where branch_id=@dst_branch_id and branch_sitemap_action is not null) or \ sitemap.sitemap_id in (select sitemap_orig_id from '+(module.schema?module.schema+'.':'')+"branch_sitemap where branch_id=@dst_branch_id and branch_sitemap_action = 'UPDATE') or\ sitemap.sitemap_id in (select sitemap_id from "+(module.schema?module.schema+'.':'')+'branch_sitemap dst_branch_sitemap where dst_branch_sitemap.branch_id=@dst_branch_id and dst_branch_sitemap.sitemap_key in (select sitemap_key from '+(module.schema?module.schema+'.':'')+'branch_sitemap src_branch_sitemap where src_branch_sitemap.branch_id=@src_branch_id and branch_sitemap_action is not null))'; appsrv.ExecRecordset(branch_data._DBContext, sql, sql_ptypes, sql_params, function (err, rslt) { if (err != null) { err.sql = sql;return cb(err); } if(rslt && rslt[0]){ _.each(rslt[0], function(sitemap){ sitemaps[sitemap.sitemap_id] = sitemap; }); } return cb(); }); }, //Get sitemap file content function(cb){ async.eachOfSeries(sitemaps, function(sitemap, sitemap_id, sitemap_cb){ funcs.getClientSitemap(sitemap, function(err, sitemap_content){ if(err) return sitemap_cb(err); if(!sitemap_content) return sitemap_cb(null); sitemap.sitemap_items_text = funcs.prettySitemap(sitemap_content.sitemap_items, branch_data.page_keys, branch_data.media_keys); return sitemap_cb(); }); }, cb); }, //Perform sitemap diff function(cb){ _.each(branch_sitemaps, function(branch_sitemap){ if(branch_sitemap.src_branch_sitemap_action && branch_sitemap.src_branch_sitemap_action.toUpperCase()=='UPDATE' && branch_sitemap.dst_branch_sitemap_action && branch_sitemap.dst_branch_sitemap_action.toUpperCase()=='UPDATE'){ branch_sitemap.src_diff = funcs.sitemapDiff(sitemaps[branch_sitemap.src_orig_sitemap.id], sitemaps[branch_sitemap.src_sitemap.id]); branch_sitemap.dst_diff = funcs.sitemapDiff(sitemaps[branch_sitemap.dst_orig_sitemap.id], sitemaps[branch_sitemap.dst_sitemap.id]); } else if(branch_sitemap.src_branch_sitemap_action && branch_sitemap.src_branch_sitemap_action.toUpperCase()=='UPDATE'){ branch_sitemap.src_diff = funcs.sitemapDiff(sitemaps[branch_sitemap.src_orig_sitemap.id], sitemaps[branch_sitemap.src_sitemap.id]); branch_sitemap.dst_diff = funcs.sitemapDiff(sitemaps[branch_sitemap.src_orig_sitemap.id], sitemaps[branch_sitemap.dst_sitemap.id]); if (branch_sitemap.dst_diff) branch_sitemap.dst_diff.diff_with_cmp_branch = true; } else if(branch_sitemap.dst_branch_sitemap_action && branch_sitemap.dst_branch_sitemap_action.toUpperCase()=='UPDATE'){ branch_sitemap.src_diff = funcs.sitemapDiff(sitemaps[branch_sitemap.dst_orig_sitemap.id], sitemaps[branch_sitemap.src_sitemap.id]); branch_sitemap.dst_diff = funcs.sitemapDiff(sitemaps[branch_sitemap.dst_orig_sitemap.id], sitemaps[branch_sitemap.dst_sitemap.id]); if (branch_sitemap.src_diff) branch_sitemap.src_diff.diff_with_cmp_branch = true; } }); return cb(); }, ], callback); }; var CONFLICT_DETAIL_TABLES = [ ['src_orig_'], ['dst_orig_'], ['src_'], ['dst_'], ['merge_'], ]; function selectConflictDetailFields(detailFields) { return _.flatMap(CONFLICT_DETAIL_TABLES, function(det) { var prefix = det[0]; var table = prefix + '{item}'; return (['{item}_id','{item}_key']).concat(detailFields).map(function(field) { return table + '.' + field + ' ' + prefix + field; }); }).join(','); } function propertyPrefixToSubObject(obj, sub) { var prefix = sub + '_'; obj[sub] = {}; var toDelete = []; _.forOwn(obj, function(value, key) { if (_.startsWith(key, prefix)) { obj[sub][key.replace(prefix, '')] = value; toDelete.push(key); } }); toDelete.forEach(function(key) { delete obj[key]; }); } function formatBranchObject(collection, objectType) { _.each(collection, function(branch_object){ branch_object['src_branch_'+objectType+'_action'] = (branch_object['src_branch_'+objectType+'_action']||'').toString().toUpperCase(); branch_object['dst_branch_'+objectType+'_action'] = (branch_object['dst_branch_'+objectType+'_action']||'').toString().toUpperCase(); propertyPrefixToSubObject(branch_object, 'src_'+objectType); propertyPrefixToSubObject(branch_object, 'dst_'+objectType); propertyPrefixToSubObject(branch_object, 'src_orig_'+objectType); propertyPrefixToSubObject(branch_object, 'dst_orig_'+objectType); propertyPrefixToSubObject(branch_object, 'merge_'+objectType); }); } function rejectDirectAncestorConflicts(collection, objectType, lineage) { var parent = {}; _.each(lineage, function(link) { parent[link.id] = link.orig_id; }); return _.filter(collection, function(branch_object){ var src = branch_object['src_'+objectType]; var dst = branch_object['dst_'+objectType]; if (!src || !dst || !src.id || !dst.id) return true; var newer = src.id; var older = dst.id; var cur_depth = 0; while (newer && (parseInt(newer) > parseInt(older)) && (cur_depth++ < 200)) { newer = parent[newer]; } return newer != older; }); } exports.conflicts = function(context, baseurl, src_branch_id, dst_branch_id, callback) { var cms = module; var jsh = module.jsh; var appsrv = jsh.AppSrv; var dbtypes = appsrv.DB.types; var branch_conflicts = {}; var src_branch_desc = 'Source'; var dst_branch_desc = 'Destination'; var branch_data = { src_branch_id: src_branch_id, dst_branch_id: dst_branch_id, page_templates: null, site_id: null, _DBContext: context, baseurl: baseurl, }; var sql_ptypes = [dbtypes.BigInt, dbtypes.BigInt]; var sql_params = { src_branch_id: src_branch_id, dst_branch_id: dst_branch_id }; async.waterfall([ function(cb){ funcs.merge_check_permissions(context, sql_params, cb); }, //Get template variables function(cb){ var sql = 'select site_editor deployment_target_id,v_my_branch_desc.site_id from '+(module.schema?module.schema+'.':'')+'v_my_branch_desc left outer join '+(module.schema?module.schema+'.':'')+'v_my_site on v_my_site.site_id = v_my_branch_desc.site_id where v_my_branch_desc.branch_id=@dst_branch_id'; appsrv.ExecRow(context, sql, sql_ptypes, sql_params, function (err, rslt) { if (err != null) { err.sql = sql;return cb(err); } if(rslt && rslt[0]){ try{ branch_data.deployment_target_id = rslt[0].deployment_target_id; branch_data.site_id = rslt[0].site_id; } catch(ex){ /* Do nothing */ } } return cb(); }); }, //Get branch names function(cb){ var sql = 'select branch_id, branch_desc from '+(module.schema?module.schema+'.':'')+'v_my_branch_desc where branch_id=@dst_branch_id or branch_id=@src_branch_id'; appsrv.ExecRecordset(context, sql, sql_ptypes, sql_params, function (err, rslt) { if (err != null) { err.sql = sql;return cb(err); } if(rslt && rslt[0]){ _.forEach(rslt[0], function(branch) { if(branch.branch_id == src_branch_id) src_branch_desc = branch.branch_desc; if(branch.branch_id == dst_branch_id) dst_branch_desc = branch.branch_desc; }); } return cb(); }); }, //Run onBeforeConflicts functions function(cb){ async.eachOfSeries(cms.BranchItems, function(branch_item, branch_item_type, branch_item_cb){ if(!branch_item.conflicts) return branch_item_cb(); Helper.execif(branch_item.conflicts.onBeforeConflicts, function(f){ branch_item.conflicts.onBeforeConflicts(branch_data, f); }, branch_item_cb ); }, cb); }, //Get all conflicts per branch item type function(cb){ async.eachOfSeries(cms.BranchItems, function(branch_item, branch_item_type, branch_item_cb){ if(!branch_item.conflicts) return branch_item_cb(); var sql = "select 'same_key' conflict_type, src_branch_{item}.{item}_key,\ src_branch_{item}.branch_{item}_action as src_branch_{item}_action,\ dst_branch_{item}.branch_{item}_action as dst_branch_{item}_action,\ dst_branch_{item}.{item}_merge_id, dst_branch_{item}.branch_{item}_merge_action, "; sql += selectConflictDetailFields(branch_item.conflicts.columns || []); sql += ' from {tbl_branch_item} src_branch_{item} \ inner join {tbl_branch_item} dst_branch_{item} on dst_branch_{item}.{item}_key=src_branch_{item}.{item}_key and dst_branch_{item}.branch_id=@dst_branch_id '; sql += '\ left outer join {tbl_item} src_{item} on src_{item}.{item}_id=src_branch_{item}.{item}_id \ left outer join {tbl_item} dst_{item} on dst_{item}.{item}_id=dst_branch_{item}.{item}_id \ left outer join {tbl_item} src_orig_{item} on src_orig_{item}.{item}_id=src_branch_{item}.{item}_orig_id \ left outer join {tbl_item} dst_orig_{item} on dst_orig_{item}.{item}_id=dst_branch_{item}.{item}_orig_id \ left outer join {tbl_item} merge_{item} on merge_{item}.{item}_id=dst_branch_{item}.{item}_merge_id '; sql += ' where src_branch_{item}.branch_id=@src_branch_id\ and jsharmony.nequal(dst_branch_{item}.{item}_id,src_branch_{item}.{item}_id)\ and ((src_branch_{item}.branch_{item}_action is not null and jsharmony.nequal(src_branch_{item}.{item}_orig_id,dst_branch_{item}.{item}_id))\ or (dst_branch_{item}.branch_{item}_action is not null and jsharmony.nequal(dst_branch_{item}.{item}_orig_id,src_branch_{item}.{item}_id))) '; if(branch_item.conflicts.sqlwhere) sql += ' and (' + branch_item.conflicts.sqlwhere + ')'; if(branch_item.conflicts.unique){ sql += ' union all '; sql += sql = "select 'diff_key' conflict_type, src_branch_{item}.{item}_key,\ src_branch_{item}.branch_{item}_action as src_branch_{item}_action,\ dst_branch_{item}.branch_{item}_action as dst_branch_{item}_action,\ dst_branch_{item}.{item}_merge_id, dst_branch_{item}.branch_{item}_merge_action, "; sql += selectConflictDetailFields(branch_item.conflicts.columns || []); sql += ' from {tbl_branch_item} src_branch_{item} \ inner join {tbl_branch_item} dst_branch_{item} on dst_branch_{item}.{item}_key<>src_branch_{item}.{item}_key and dst_branch_{item}.branch_id=@dst_branch_id \ inner join {tbl_item} src_{item} on src_{item}.{item}_id=src_branch_{item}.{item}_id \ inner join {tbl_item} dst_{item} on dst_{item}.{item}_id=dst_branch_{item}.{item}_id and (' + branch_item.conflicts.unique + ')'; sql += '\ left outer join {tbl_item} src_orig_{item} on src_orig_{item}.{item}_id=src_branch_{item}.{item}_orig_id \ left outer join {tbl_item} dst_orig_{item} on dst_orig_{item}.{item}_id=dst_branch_{item}.{item}_orig_id \ left outer join {tbl_item} merge_{item} on merge_{item}.{item}_id=dst_branch_{item}.{item}_merge_id '; sql += ' where src_branch_{item}.branch_id=@src_branch_id\ and jsharmony.nequal(dst_branch_{item}.{item}_id,src_branch_{item}.{item}_id)\ and ((src_branch_{item}.branch_{item}_action is not null and jsharmony.nequal(src_branch_{item}.{item}_orig_id,dst_branch_{item}.{item}_id))\ or (dst_branch_{item}.branch_{item}_action is not null and jsharmony.nequal(dst_branch_{item}.{item}_orig_id,src_branch_{item}.{item}_id))) '; if(branch_item.conflicts.sqlwhere) sql += ' and (' + branch_item.conflicts.sqlwhere + ')'; } appsrv.ExecRecordset(context, cms.applyBranchItemSQL(branch_item_type, sql), sql_ptypes, sql_params, function (err, rslt) { if (err != null) { err.sql = sql; return cb(err); } if(rslt && rslt[0]){ branch_conflicts[branch_item_type] = rslt[0]; formatBranchObject(branch_conflicts[branch_item_type], branch_item_type); } branch_item_cb(); }); }, cb); }, //Reject conflicts where one item is a direct descendant of the other function(cb){ async.eachOfSeries(cms.BranchItems, function(branch_item, branch_item_type, branch_item_cb){ if(!branch_item.conflicts) return branch_item_cb(); var sql = 'select {item}_key as "key", {item}_id id, {item}_orig_id orig_id\ from {tbl_item}\ where {item}.{item}_key in \ (select {item}_key \ from {tbl_branch_item} \ where (branch_id = @src_branch_id and branch_{item}_action is not null) or (branch_id = @dst_branch_id and branch_{item}_action is not null) \ ) \ and {item}_id between \ (select min({item}_id) \ from {tbl_branch_item} \ where {item}_id is not null and {item}_key = {tbl_item}.{item}_key and (branch_id = @src_branch_id or branch_id = @dst_branch_id) \ ) \ and \ (select max({item}_id) \ from {tbl_branch_item} \ where {item}_id is not null and {item}_key = {tbl_item}.{item}_key and (branch_id = @src_branch_id or branch_id = @dst_branch_id) \ ) \ ;'; appsrv.ExecRecordset(context, cms.applyBranchItemSQL(branch_item_type, sql), sql_ptypes, sql_params, function (err, rslt) { if (err != null) { err.sql = sql; return cb(err); } if(rslt && rslt[0]){ branch_conflicts[branch_item_type] = rejectDirectAncestorConflicts(branch_conflicts[branch_item_type], branch_item_type, rslt[0]); } branch_item_cb(); }); }, cb); }, //Run onConflicts functions function(cb){ async.eachOfSeries(cms.BranchItems, function(branch_item, branch_item_type, branch_item_cb){ if(!branch_item.conflicts) return branch_item_cb(); Helper.execif(branch_item.conflicts.onConflicts, function(f){ branch_item.conflicts.onConflicts(branch_conflicts[branch_item_type], branch_data, f); }, branch_item_cb ); }, cb); }, ], function(err){ callback(err, { _success: 1, src_branch_desc: src_branch_desc, dst_branch_desc: dst_branch_desc, branch_conflicts: branch_conflicts, }); }); return; }; exports.req_conflicts = function (req, res, next) { var verb = req.method.toLowerCase(); if (!req.body) req.body = {}; var Q = req.query; var P = req.body; var appsrv = this; var jsh = module.jsh; var XValidate = jsh.XValidate; var model = jsh.getModel(req, module.namespace + 'Branch_Conflicts'); if (!Helper.hasModelAction(req, model, 'B')) { Helper.GenError(req, res, -11, _t('Invalid Model Access')); return; } if (verb == 'get') { //Validate parameters if (!appsrv.ParamCheck('P', P, [])) { Helper.GenError(req, res, -4, 'Invalid Parameters'); return; } if (!appsrv.ParamCheck('Q', Q, ['&dst_branch_id','&src_branch_id'])) { Helper.GenError(req, res, -4, 'Invalid Parameters'); return; } var dst_branch_id = req.query.dst_branch_id; var src_branch_id = req.query.src_branch_id; //Check if item is defined var sql_params = { dst_branch_id: dst_branch_id, src_branch_id: src_branch_id }; var validate = new XValidate(); var verrors = {}; validate.AddValidator('_obj.dst_branch_id', 'Destination Branch ID', 'B', [XValidate._v_IsNumeric(), XValidate._v_Required()]); validate.AddValidator('_obj.src_branch_id', 'Source Branch ID', 'B', [XValidate._v_IsNumeric(), XValidate._v_Required()]); verrors = _.merge(verrors, validate.Validate('B', sql_params)); if (!_.isEmpty(verrors)) { Helper.GenError(req, res, -2, verrors[''].join('\n')); return; } var baseurl = req.baseurl; if(baseurl.indexOf('//')<0) baseurl = req.protocol + '://' + req.get('host') + baseurl; funcs.conflicts(req._DBContext, baseurl, src_branch_id, dst_branch_id, function(err, result) { if (err != null && err.sql) { appsrv.AppDBError(req, res, err); return; } if(err) return Helper.GenError(req, res, -99999, err.toString()); res.end(JSON.stringify(result)); }); } else { return next(); } }; exports.req_conflicts_resolve = function (req, res, next) { var verb = req.method.toLowerCase(); if (!req.body) req.body = {}; var Q = req.query; var P = req.body; var appsrv = this; var cms = module; var jsh = module.jsh; var XValidate = jsh.XValidate; var dbtypes = appsrv.DB.types; var model = jsh.getModel(req, module.namespace + 'Branch_Conflicts'); if (!Helper.hasModelAction(req, model, 'U')) { Helper.GenError(req, res, -11, _t('Invalid Model Access')); return; } if (verb == 'post') { //Validate parameters if (!appsrv.ParamCheck('Q', Q, [])) { Helper.GenError(req, res, -4, 'Invalid Parameters'); return; } if (!appsrv.ParamCheck('P', P, ['&branch_item_type','&branch_id','&key','&merge_id','&branch_merge_action'])) { Helper.GenError(req, res, -4, 'Invalid Parameters'); return; } var branch_item_type = req.body.branch_item_type; var branch_id = req.body.branch_id; var key = req.body.key; var merge_id = req.body.merge_id; var branch_merge_action = req.body.branch_merge_action; if(!(branch_item_type in cms.BranchItems)) { Helper.GenError(req, res, -4, 'Invalid Parameters'); return; } //Check if item is defined var sql_ptypes = [dbtypes.BigInt, dbtypes.BigInt, dbtypes.BigInt, dbtypes.VarChar(32)]; var sql_params = { branch_id: branch_id, key: key, merge_id: merge_id, branch_merge_action: branch_merge_action }; var validate = new XValidate(); var verrors = {}; validate.AddValidator('_obj.branch_id', 'Branch ID', 'U', [XValidate._v_IsNumeric(), XValidate._v_Required()]); validate.AddValidator('_obj.key', 'Item Key', 'U', [XValidate._v_IsNumeric(), XValidate._v_Required()]); validate.AddValidator('_obj.merge_id', 'Merge ID', 'U', [XValidate._v_IsNumeric()]); validate.AddValidator('_obj.branch_merge_action', 'Action', 'U', [XValidate._v_MaxLength(32)]); verrors = _.merge(verrors, validate.Validate('U', sql_params)); if (!_.isEmpty(verrors)) { Helper.GenError(req, res, -2, verrors[''].join('\n')); return; } //Validate user has access to branch var sql = "update {tbl_branch_item} set {item}_merge_id=@merge_id, branch_{item}_merge_action=@branch_merge_action where branch_id=@branch_id and {item}_key=@key and ('RW' = (select branch_access from "+(module.schema?module.schema+'.':'')+'v_my_branch_access access where access.branch_id=@branch_id));'; appsrv.ExecCommand(req._DBContext, cms.applyBranchItemSQL(branch_item_type, sql), sql_ptypes, sql_params, function (err, rslt) { if (err && err.sql) { appsrv.AppDBError(req, res, err); return; } if(err) return Helper.GenError(req, res, -99999, err.toString()); res.end(JSON.stringify({ '_success': 1 })); }); } else { return next(); } }; return exports; };