Name
sn_cd.cd_ContentDelivery
Description
API for getting content to display on a portal.
Script
var cd_ContentDelivery = Class.create();
cd_ContentDelivery.prototype = {
type: 'cd_ContentDelivery',
useCache: true // attempt to find audience evaluation result in cache
};
/* Get content for the specified sp_instance
* @param instanceId String The ID of the sp_instance for which we want content
* @return Array A sorted array of objects containing information about the content specified by @function _addContentToResult
*/
cd_ContentDelivery.getContentForWidgetInstance = function (instanceId, topicId) {
var results = {
contentMap: {},
contentArray: []
};
cd_ContentDelivery._getStandardPortalContentForWidgetInstance(instanceId, topicId, results);
cd_ContentDelivery._getCampaignPortalContentForWidgetInstance(instanceId, topicId, results);
return results.contentArray.sort(function (a, b) {
var i = Number(a.order);
var j = Number(b.order);
var k = new GlideDateTime(a.availability_start_date.length > 0 ? a.availability_start_date : a.sys_created_on);
var l = new GlideDateTime(b.availability_start_date.length > 0 ? b.availability_start_date : b.sys_created_on);
if (i < j)
return -1;
if (i > j)
return 1;
if (k.after(l))
return -1;
if (k.before(l))
return 1;
return 0;
});
};
/* Get standard content for the specified sp_instance
* @param instanceId String The ID of the sp_instance for which we want content
* @param results Array Objects containing information about the content and to which we will append more objects
*/
cd_ContentDelivery._getStandardPortalContentForWidgetInstance = function (instanceId, topicId, results) {
var cd_Audience = new sn_cd.cd_Audience();
var gdtNow = new GlideDateTime();
var user = gs.getUserID();
// get all active content associated with this sp_instance
var grContentVisibility = new GlideRecord('sn_cd_content_visibility');
grContentVisibility.addActiveQuery();
grContentVisibility.addNullQuery('content_location').addOrCondition('content_location', 'service_portal');
grContentVisibility.addQuery('sp_instance', instanceId);
grContentVisibility.addQuery('content.active', true);
grContentVisibility.addQuery('content.sys_class_name', 'INSTANCEOF', 'sn_cd_content_portal');
grContentVisibility.addNullQuery('approvers').addOrCondition('state', 'published');
grContentVisibility.addNullQuery('availability_start_date').addOrCondition('availability_start_date', '<=', gdtNow);
grContentVisibility.addNullQuery('availability_end_date').addOrCondition('availability_end_date', '>=', gdtNow);
// NOTE: we rely on event end being null if the content type is not event (BR enforces this)
grContentVisibility.addNullQuery('content.event_end').addOrCondition('content.event_end', '>=', gdtNow);
// query topic if it's a query param
if (topicId != null)
grContentVisibility.addQuery('topic', 'CONTAINS', topicId);
grContentVisibility.query();
while (grContentVisibility.next()) {
var useAdhocUsers = !!grContentVisibility.use_adhoc_users;
if (((useAdhocUsers && grContentVisibility.getValue('users').indexOf(user) !== -1) || (!useAdhocUsers && cd_Audience.isUserInAudience(grContentVisibility.getValue("audience"), user, null, null, this.useCache))) && !cd_ContentDelivery._hasUnprocessedTodoScheduledContent(grContentVisibility))
cd_ContentDelivery._addContentToResult(grContentVisibility.content.getRefRecord(), results, grContentVisibility);
}
};
/* Get campaign content for the specified sp_instance
* @param instanceId String The ID of the sp_instance for which we want content
* @param results Array Objects containing information about the content and to which we will append more objects
*/
cd_ContentDelivery._getCampaignPortalContentForWidgetInstance = function (instanceId, topicId, results) {
if (!instanceId || !(new GlidePluginManager().isActive('com.sn_content_automation')))
return;
var campaignContent = new sn_ca.ca_CampaignContent();
var contentIds = [];
if (!topicId)
contentIds = campaignContent.getCampaignContentForUserAndWidgetInstance(gs.getUserID(), instanceId);
else if (typeof campaignContent.getCampaignContentForUserWidgetInstanceAndTopic !== "undefined")
contentIds = campaignContent.getCampaignContentForUserWidgetInstanceAndTopic(gs.getUserID(), instanceId, topicId);
if (contentIds && contentIds.length > 0) {
var grContentPortal = new GlideRecord('sn_cd_content_portal');
var grCampaignContent = new GlideRecord('sn_ca_campaign_item');
for (var i = 0; i < contentIds.length; i+=1)
if (grContentPortal.get(contentIds[i].id) && grCampaignContent.get(contentIds[i].campaignItemId) && !cd_ContentDelivery._hasUnprocessedTodoCampaignContent(grCampaignContent)) {
var idx = cd_ContentDelivery._addContentToResult(grContentPortal, results, null, grCampaignContent);
var contentJson = results.contentArray[idx];
// the keys of campaignSet will be the ids
// of the campaigns that are publishing the content
if (!contentJson.hasOwnProperty('campaignSet'))
contentJson.campaignSet = {};
var campaignId = contentIds[i].campaignId;
contentJson.campaignSet[campaignId] = null;
}
}
};
/* Get content for the specified sys_ux_custom_content_root_elem
* @param contentIdentifier String The identifier tag for which we want content
* @return Array A sorted array of objects containing information about the content
*/
cd_ContentDelivery.getContentForWorkspaceInstance = function (contentIdentifier, isUIB) {
var results = {
contentMap: {},
contentArray: []
};
cd_ContentDelivery._getStandardPortalContentForWorkspaceInstance(contentIdentifier, results, isUIB);
return results.contentArray.sort(function (a, b) {
var i = Number(a.order);
var j = Number(b.order);
if (i < j)
return -1;
if (i > j)
return 1;
return 0;
});
};
/* Get standard content for the specified sys_ux_custom_content_root_elem
* @param contentIdentifier String The identifier tag for which we want content
* @param results Array Objects containing information about the content and to which we will append more objects
*/
cd_ContentDelivery._getStandardPortalContentForWorkspaceInstance = function (contentIdentifier, results, isUIB) {
var cd_Audience = new sn_cd.cd_Audience();
var gdtNow = new GlideDateTime();
var user = gs.getUserID();
// get all active content associated with this sp_instance
var grContentVisibility = new GlideRecord('sn_cd_content_visibility');
if (!grContentVisibility.isValidField("content_identifier") && !isUIB)
return;
grContentVisibility.addActiveQuery();
if (isUIB) {
grContentVisibility.addQuery('content_location', 'uib_workspace');
grContentVisibility.addQuery('content_group', contentIdentifier);
} else {
grContentVisibility.addQuery('content_location', 'workspace');
grContentVisibility.addQuery('content_identifier', contentIdentifier);
}
grContentVisibility.addQuery('content.active', true);
grContentVisibility.addQuery('content.sys_class_name', 'INSTANCEOF', 'sn_cd_content_portal');
grContentVisibility.addNullQuery('approvers').addOrCondition('state', 'published');
grContentVisibility.addNullQuery('availability_start_date').addOrCondition('availability_start_date', '<=', gdtNow);
grContentVisibility.addNullQuery('availability_end_date').addOrCondition('availability_end_date', '>=', gdtNow);
grContentVisibility.addNotNullQuery('audience');
// NOTE: we rely on event end being null if the content type is not event (BR enforces this)
grContentVisibility.addNullQuery('content.event_end').addOrCondition('content.event_end', '>=', gdtNow);
grContentVisibility.orderBy('title');
grContentVisibility.query();
while (grContentVisibility.next())
if (cd_Audience.isUserInAudience(grContentVisibility.getValue("audience"), user))
if (isUIB)
cd_ContentDelivery._addContentToResultForUIB(grContentVisibility.content.getRefRecord(), results, grContentVisibility.getValue('component_type'));
else
cd_ContentDelivery._addContentToResult(grContentVisibility.content.getRefRecord(), results);
};
cd_ContentDelivery._getLinkObj = function (grContent, label, type, opensWindow, download) {
return {
label: label,
type: type,
value: {
href: grContent.url_asset.url.toString()
},
opensWindow: opensWindow,
configAria: {},
download: download
};
};
cd_ContentDelivery._getAnnouncementObj = function (grContent, linkType) {
return {
customHTML: grContent.getDisplayValue("use_custom_html") || false,
richText: grContent.getDisplayValue("rich_text") || "",
headingText: grContent.getDisplayValue("heading_text") || "",
bodyText: grContent.getDisplayValue("body_text") || "",
showButton: grContent.getDisplayValue("show_button") || false,
buttonText: grContent.getDisplayValue("button_text") || "",
buttonLink: cd_ContentDelivery._getLinkObj(grContent, '', linkType, true, false),
};
};
cd_ContentDelivery._addContentToResultForUIB = function (grContent, accumulatedContent, componentType) {
var id = grContent.getUniqueValue();
var content = {};
var linkType = "external";
switch (componentType) {
case "announcements": // Banner (Announcement section)
content = cd_ContentDelivery._getAnnouncementObj(grContent, linkType);
break;
case "frequently_used_apps": // Image-based Link (Frequently used apps section)
content = {
heading: {
type: "link",
hasIcon: false,
icon: {},
label: "",
link: cd_ContentDelivery._getLinkObj(grContent, '', linkType, true, false),
hasTile: true,
tile: {
type: "image",
content: {
image: {
url: grContent.getDisplayValue('image'),
altText: grContent.getDisplayValue('title'),
alignment: "center",
headerOverImage: false,
fit: "contain",
}
}
}
}
};
break;
case "quick_links": // URL (Quick links section)
content = cd_ContentDelivery._getLinkObj(grContent, grContent.getDisplayValue('title'), linkType, false, false);
break;
default:
}
accumulatedContent.contentArray.push(content);
return accumulatedContent.contentMap[id];
};
/**
* Get an object describing the specified content
* @param string contentId The sys id of the portal content record we want
* @return Array An array (max length one in this case) of content object information
*/
cd_ContentDelivery.getPortalContentById = function (contentId) {
if (!contentId)
return [];
var results = {
contentMap: {},
contentArray: []
};
var grContentPortal = new GlideRecord('sn_cd_content_portal');
if (grContentPortal.get(contentId))
cd_ContentDelivery._addContentToResult(grContentPortal, results);
return results.contentArray;
};
/** Get portal content referencing the specified schedule
* @param scheduleId string cmn_schedule sys_id to get portal content by
* @return Array Objects representing a portal content record specified by @function _addContentToResult
*/
cd_ContentDelivery.getPortalContentByScheduleId = function (scheduleId) {
if (!scheduleId)
return [];
var results = {
contentMap: {},
contentArray: []
};
var grContentPortal = new GlideRecord('sn_cd_content_portal');
grContentPortal.addQuery('schedule', scheduleId);
grContentPortal.query();
while (grContentPortal.next())
cd_ContentDelivery._addContentToResult(grContentPortal, results);
return results.contentArray;
};
/**
* This gets content using the availability dates and end dates, but ignores the audience.
* It is expected to be called by the Holiday Calendar widget to get other calendars
* that can be displayed via the dropdown,
* @param instanceId String The ID of the sp_instance for which we want content
* @return Array A sorted array of objects containing information about the content specified by @function _addContentToResult
*/
cd_ContentDelivery.getContentForWidgetInstanceIgnoreAudience = function (instanceId) {
var gdtNow = new GlideDateTime();
var results = {
contentMap: {},
contentArray: []
};
var grContentVisibility = new GlideRecord('sn_cd_content_visibility');
grContentVisibility.addActiveQuery();
grContentVisibility.addQuery('sp_instance', instanceId);
grContentVisibility.addQuery('content.active', true);
grContentVisibility.addNullQuery('availability_start_date').addOrCondition('availability_start_date', '<=', gdtNow);
grContentVisibility.addNullQuery('availability_end_date').addOrCondition('availability_end_date', '>=', gdtNow);
// NOTE: we rely on event end being null if the content type is not event (BR enforces this)
grContentVisibility.addNullQuery('content.event_end').addOrCondition('content.event_end', '>=', gdtNow);
grContentVisibility.query();
while (grContentVisibility.next()) {
var grContentPortal = new GlideRecord('sn_cd_content_portal');
if (grContentPortal.get(grContentVisibility.content))
cd_ContentDelivery._addContentToResult(grContentPortal, results);
}
return results.contentArray.sort(function (a, b) {
var i = Number(a.order);
var j = Number(b.order);
if (i < j)
return -1;
if (i > j)
return 1;
return 0;
});
};
/**
* Add information about a portal content record to an array
* @param grContent GlideRecord [sn_cd_content_portal] Content record from which we will get information
* @param accumulatedContent Array An array of objects to which we will add information about the portal content
* @param grContentVisibility GlideRecord [sn_cd_content_visibility] Optional, used to generate link to user todo if applicable
* @param grCampaignContent GlideRecord [sn_ca_campaign_item] Optional, used to generate link to user todo if applicable
* @return the index of the content
*/
cd_ContentDelivery._addContentToResult = function (grContent, accumulatedContent, grContentVisibility, grCampaignContent) {
var id = grContent.getUniqueValue();
var hasCV = grContentVisibility != null;
var supportedContentTypes = ['a673597a0b4303008cd6e7ae37673a6f', '41040dd7237e2300fb0c949e27bf652a', 'a342197a0b4303008cd6e7ae37673a19', '3893597a0b4303008cd6e7ae37673a4c', 'ae935d7a0b4303008cd6e7ae37673a9a', '97a35d7a0b4303008cd6e7ae37673a47', 'afb39d7a0b4303008cd6e7ae37673a16', 'f8c39d7a0b4303008cd6e7ae37673a55'];
var isValidContentType = supportedContentTypes.indexOf(grContent.content_type.toString()) > -1;
var isValid = hasCV && isValidContentType;
if (!accumulatedContent.contentMap.hasOwnProperty(id)) {
accumulatedContent.contentArray.push({
title: grContent.getDisplayValue('title'),
url: cd_ContentDelivery._getUrlFromContent(grContent, grContentVisibility, grCampaignContent),
open_in: grContent.url_asset.open_in.toString(),
order: grContent.order.toString(),
user_ref_table: grContent.user_reference_table.toString(),
schedule: grContent.schedule.toString(),
rich_text: cd_ContentDelivery.getRichTextForContent(grContent, 'rich_text'),
rich_content_html: cd_ContentDelivery.getRichTextForContent(grContent, 'rich_content_html'),
rich_content_css: grContent.rich_content_css.toString(),
event_start: grContent.event_start.toString(),
event_end: grContent.event_end.toString(),
sys_id: id,
add_icon: grContent.add_icon.toString() === 'true',
icon: grContent.icon.toString(),
icon_size: grContent.icon_size.toString(),
add_background_image: grContent.add_background_image.toString() === 'true',
background_image: grContent.getDisplayValue('image'),
background_color: grContent.background_color.toString(),
background_size: grContent.background_size.toString(),
background_position: grContent.background_position.toString(),
add_gradient: grContent.add_gradient.toString() === 'true',
text_over_background: grContent.text_over_background.toString() === 'true',
text_color: grContent.text_color.toString(),
text_alignment: grContent.text_alignment.toString(),
headline_text: cd_ContentDelivery.getRichTextForContent(grContent, 'headline'),
heading_text: cd_ContentDelivery.getRichTextForContent(grContent, 'heading_text'),
body_text: cd_ContentDelivery.getRichTextForContent(grContent, 'body_text'),
action: grContent.call_to_action.toString(),
show_button: grContent.show_button.toString(),
link_text: grContent.link_text.toString(),
button_text: grContent.button_text.toString(),
use_custom_html: grContent.use_custom_html.toString() === 'true',
use_block: grContent.use_block.toString() === 'true',
image_src: grContent.getDisplayValue('image'),
is_clickable: cd_ContentDelivery.isClickable(grContent),
is_todo_link: grContent.url_asset.type.toString() === 'todo',
type: grContent.type.toString(),
video_link_id: grContent.video_link.toString(),
video_url: cd_ContentDelivery._getVideoUrlFromContent(grContent),
content_type: grContent.content_type.toString(),
sys_created_on: isValid && grContentVisibility.sys_created_on != null ? grContentVisibility.sys_created_on.toString() : 0,
availability_start_date: isValid && grContentVisibility.availability_start_date != null ? grContentVisibility.availability_start_date.toString() : 0
});
accumulatedContent.contentMap[id] = accumulatedContent.contentArray.length - 1;
}
return accumulatedContent.contentMap[id];
};
/* Get the rich text from a content record
* @param grContent GlideRecord [sn_cd_content_portal] Content record to get rich text from
* @param field string The field on grContent to get rich text for
* @return String Parsed rich text from @param grContent
*/
cd_ContentDelivery.getRichTextForContent = function (grContent, field) {
if (gs.nil(grContent[field]) && gs.nil(grContent.block))
return null;
var userTable;
var userRefField;
// TODO: Add condition to test if the content type is valid and has Use block content allowed
if (grContent.use_block) {
userTable = grContent.block.user_reference_table.toString();
userRefField = grContent.block.user_column.toString();
} else {
userTable = grContent.user_reference_table.toString();
userRefField = grContent.user_column.toString();
}
var glideRec;
if (userTable && new GlideRecord(userTable).isValid()) {
var grsUserTable = new GlideRecordSecure(userTable);
if (new GlideTableHierarchy('sys_user').getAllExtensions().indexOf(userTable) !== -1) {
if (grsUserTable.get(gs.getUserID()))
glideRec = grsUserTable;
} else if (userRefField && grsUserTable.isValidField(userRefField)) {
if (grsUserTable.isValidField("active"))
grsUserTable.addActiveQuery();
grsUserTable.addQuery(userRefField, gs.getUserID());
grsUserTable.query();
if (grsUserTable.next())
glideRec = grsUserTable;
}
}
var contentBody;
if (grContent.use_block && !gs.nil(grContent.block))
if (grContent.block.user_specific)
contentBody = grContent.block.rich_text_user_specific.toString();
else
contentBody = grContent.block.rich_text.toString();
else if (grContent[field])
contentBody = grContent[field].toString();
return new sn_cd.cd_ContentParser().parseRichTextHtmlBody(contentBody, glideRec) + cd_ContentDelivery._processRCScript(grContent);
};
/* Process the rich component script
* @param grContent GlideRecord [sn_cd_content_portal] Content record
* @return element of the script
*/
cd_ContentDelivery._processRCScript = function(grContent) {
var rcScripts = [];
if (grContent.getValue("content_type") === cd_CommonConstants.CONTENT_TYPE_RICH_CONTENT)
try {
var rcComponents = JSON.parse(grContent.rich_content_components);
rcComponents.forEach(function(idx) {
var script = cd_ContentDelivery._getRichContentComponentScript(idx);
if (script) {
var elm = "var elements = document.querySelectorAll('." + idx + "'); elements.forEach(function(element) {(" + script + ".bind(element)())});" ;
rcScripts.push("<script> " + elm + "</script>");
}
});
} catch (error) {
gs.error(error);
}
return rcScripts.toString();
};
/* Get the rich component script from a wb_component record
* @param grContent GlideRecord [wb_component] Content record to get script from
* @param field string The field on wbCompGR to get script
* @return String of the script from wbCompGR
*/
cd_ContentDelivery._getRichContentComponentScript = function(component) {
// Keeping for when component table is reimplemented
// var scriptContent;
// var wbCompGR = new GlideRecord("wb_component");
// wbCompGR.addQuery("name", component);
// wbCompGR.query();
// if (wbCompGR.next())
// scriptContent = wbCompGR.getValue("script");
// return scriptContent;
if (component === 'wb-tab-container')
return "function wbTabContainer() {" +
"const el = this;" +
"el.addEventListener('keydown', onKeydown);" +
"el.addEventListener('click', onClick);" +
"const activeTab = el.firstElementChild.querySelector('.active[role=tab]');" +
"if (activeTab) selectTab(activeTab);" +
"else selectTab(el.firstElementChild.querySelector('[role=tab]'));" +
"function onClick(event) {" +
" var target = event.target;" +
" if (target.role !== 'tab') target = getTargetedTab(target);" +
" if (target) {" +
" event.preventDefault();" +
" selectTab(target);" +
" }" +
"}" +
"function onKeydown(event) {" +
" var target = event.target;" +
" var flag = false;" +
" if (target.role !== 'tab') target = getTargetedTab(target);" +
" if (target) {" +
" switch (event.key) {" +
" case 'ArrowLeft':" +
" setSelectedToPreviousTab(target);" +
" flag = true;" +
" break;" +
" case 'ArrowRight':" +
" setSelectedToNextTab(target);" +
" flag = true;" +
" break;" +
" case 'Home':" +
" selectTab(target.parentNode.firstChild, true);" +
" flag = true;" +
" break;" +
" case 'End':" +
" selectTab(target.parentNode.lastChild, true);" +
" flag = true;" +
" break;" +
" default:" +
" break;" +
" }" +
" if (flag) {" +
" event.stopPropagation();" +
" event.preventDefault();" +
" }" +
" }" +
"}" +
"function selectTab(target, setFocus) {" +
" const tabs = el.firstElementChild.querySelectorAll('[role=tab]');" +
" tabs.forEach(function (tab) {" +
" tab.tabIndex = -1;" +
" tab.className = tab.className.replace('active', '').trim();" +
" tab.ariaSelected = false;" +
" const panel = el.querySelector('#' + tab.getAttribute('aria-controls'));" +
" if (panel) {" +
" panel.hidden = true;" +
" panel.tabIndex = -1;" +
" }" +
" });" +
" target.tabIndex = 0;" +
" target.className += ' active';" +
" target.ariaSelected = true;" +
" const panel = el.querySelector('#' + target.getAttribute('aria-controls'));" +
" panel.hidden = false;" +
" panel.tabIndex = 0;" +
" if (setFocus) target.focus();" +
"}" +
"function setSelectedToPreviousTab(currentTab) {" +
" var previousTab = currentTab.previousElementSibling;" +
" if (previousTab) selectTab(previousTab, true);" +
" else selectTab(currentTab.parentNode.lastChild, true);" +
"}" +
"function setSelectedToNextTab(currentTab) {" +
" var nextTab = currentTab.nextElementSibling;" +
" if (nextTab) selectTab(nextTab, true);" +
" else selectTab(currentTab.parentNode.firstChild, true);" +
"}" +
"function getTargetedTab(target) {" +
" var tabTarget;" +
" el.firstElementChild.querySelectorAll('[role=tab]').forEach(function (tab) {" +
" if (tab.contains(target)) tabTarget = tab;" +
" });" +
" return tabTarget;" +
"}" +
"}";
return '';
};
/* Get the URL to from the portal content record
* @param grContent GlideRecord [sn_cd_content_portal] Content record to get the linked content from
* @param grContentVisibility GlideRecord [sn_cd_content_visibility] Optional, if provided check for linked todo content
* @param grCampaignContent GlideRecord [sn_ca_campaign_item] Optional, if provided check for linked todo content
* @return String The correct URL to pass to widget
*/
cd_ContentDelivery._getUrlFromContent = function (grContent, grContentVisibility, grCampaignContent) {
var todoTaskGr;
var portalGr;
var portalSuffix;
var taskSysId;
// Check linked todo
if (grContentVisibility && !grContentVisibility.todo_scheduled_content.nil()) {
const todoScheduledContentSysId = grContentVisibility.todo_scheduled_content.toString();
todoTaskGr = new GlideRecord("sn_cd_task");
todoTaskGr.addQuery("assigned_to", gs.getUserID());
todoTaskGr.addQuery("created_from_scheduled_content", todoScheduledContentSysId);
todoTaskGr.query();
portalGr = $sp.getPortalRecord();
portalSuffix = portalGr.getDisplayValue("url_suffix");
if (todoTaskGr.next()) {
taskSysId = todoTaskGr.getUniqueValue();
return "/" + portalSuffix + "?id=hrm_todos_page&todo=" + taskSysId;
}
} else if (grCampaignContent && !grCampaignContent.todo_campaign_content.nil()) {
const todoCampaignItemSysId = grCampaignContent.todo_campaign_content.toString();
todoTaskGr = new GlideRecord("sn_cd_task");
todoTaskGr.addQuery("assigned_to", gs.getUserID());
todoTaskGr.addQuery("created_from_campaign_content", todoCampaignItemSysId);
todoTaskGr.query();
portalGr = $sp.getPortalRecord();
portalSuffix = portalGr.getDisplayValue("url_suffix");
if (todoTaskGr.next()) {
taskSysId = todoTaskGr.getUniqueValue();
return "/" + portalSuffix + "?id=hrm_todos_page&todo=" + taskSysId;
}
}
// Else check kb article
var Kb = new cd_KnowledgeBase();
return Kb.getUrlAsset(grContent.url_asset);
};
/* Get the video URL to from the portal content record
* @param grContent GlideRecord [sn_cd_content_portal] Content record to get the linked content from
* @return String The correct video URL to pass to widget
*/
cd_ContentDelivery._getVideoUrlFromContent = function (grContent) {
if (grContent && grContent.video_link) {
var videoId = grContent.video_link;
var urlAssetGr = new GlideRecord("sn_cd_url_asset");
if (urlAssetGr.get(videoId) && (urlAssetGr.getValue('type') === 'video'))
return urlAssetGr.getValue('url');
}
return '';
};
/*
* Checks if content is associated to scheduled to-do content and if that content has been processed
* and posted to user inboxes yet.
* @param grContentVisibility GlideRecord [sn_cd_content_visibility] A scheduled content record
* @return boolean true if the content has associated to-do content that has not yet been processed, false otherwise
*/
cd_ContentDelivery._hasUnprocessedTodoScheduledContent = function (grContentVisibility) {
if (grContentVisibility.todo_scheduled_content.nil())
return false;
var todoScheduledContentId = grContentVisibility.todo_scheduled_content.toString();
var todoScheduledContentStatus = grContentVisibility.todo_scheduled_content.notification_status.toString();
// If all are unprocessed or an error occured, don't bother querying tasks
if (["pending", "error"].indexOf(todoScheduledContentStatus) > -1)
return true;
// Check if individual user todo has been processed
var grTask = new GlideRecord("sn_cd_task");
grTask.addQuery("created_from_scheduled_content", todoScheduledContentId);
grTask.addQuery("assigned_to", gs.getUserID());
grTask.query();
return !grTask.hasNext();
};
cd_ContentDelivery._hasUnprocessedTodoCampaignContent = function (grCampaignItem) {
if (grCampaignItem.todo_campaign_content.nil())
return false;
var todoCampaignContentId = grCampaignItem.todo_campaign_content.toString();
// Check if individual user todo has been processed
var grTask = new GlideRecord("sn_cd_task");
grTask.addQuery("created_from_campaign_content", todoCampaignContentId);
grTask.addQuery("assigned_to", gs.getUserID());
grTask.query();
return !grTask.hasNext();
};
/*
* @param grContent GlideRecord a content record
* @return boolean true if the content is clickable (i.e. it has a button)
* or a link in it. false otherwise
*/
cd_ContentDelivery.isClickable = function (grContent) {
if (grContent.sys_class_name === 'sn_cd_content_todo')
return true;
var isClickableHTML = function (text) {
return text.indexOf('</a>') >= 0;
};
var isBanner = grContent.content_type === 'a673597a0b4303008cd6e7ae37673a6f';
var isRichText = grContent.content_type === '97a35d7a0b4303008cd6e7ae37673a47';
var isEmail = grContent.content_type === '02dccfc33b630300d901655593efc4df';
if (isBanner) {
if (grContent.use_custom_html)
return isClickableHTML(grContent.rich_text + '');
return grContent.show_button.toString() === "true";
}
if (isRichText) {
if (grContent.use_block)
return isClickableHTML(grContent.block.rich_text + '');
return isClickableHTML(grContent.rich_text + '');
}
if (isEmail) {
if (grContent.use_block)
return isClickableHTML(grContent.block.rich_text + '');
return isClickableHTML(grContent.rich_text_plain_html + '');
}
if (grContent.content_type.category === 'portal_content')
return true;
return false;
};
/* Given a service portal context, returns true if the content widget is in preview mode
* @param Object widget $sp context object
* @return true if the content is being previewed, false otherwise
*/
cd_ContentDelivery.isContentPreview = function ($sp) {
if (!$sp || typeof $sp.getParameter !== 'function')
return false;
return $sp.getParameter('is_preview') === 'true';
};
/* Get the widget that should rendered for this preview called by CD Preview Widget
* @param Object widget $sp context object
* @return Object the widget object to render
*/
cd_ContentDelivery.getWidgetForPreview = function ($sp) {
// TODO: allow preview of standard portal content from Content Publishing, STRY51126195
var contentItemId = $sp.getParameter('sca_content_id');
if (contentItemId)
return cd_ContentDelivery.getWidgetForSCAPreview($sp);
if (new GlidePluginManager().isActive('com.sn_content_automation'))
return sn_ca.ca_CampaignPortalPreview.getWidgetForPreview($sp);
return null;
};
cd_ContentDelivery.getWidgetForSCAPreview = function ($sp) {
var contentId = $sp.getParameter('sca_content_id');
var previewObj = {};
var grContentItem = new GlideRecord('sn_cd_content_portal');
if (grContentItem.get(contentId)) {
var grContentType = grContentItem.getValue('content_type');
if (grContentType === 'a673597a0b4303008cd6e7ae37673a6f')
previewObj.widget = $sp.getWidget('cd-banner', {
content_id: grContentItem.getUniqueValue()
});
else if (grContentType === '41040dd7237e2300fb0c949e27bf652a')
previewObj.widget = $sp.getWidget('cd-styled-content', {
content_id: grContentItem.getUniqueValue()
});
else if (grContentType === 'f8c39d7a0b4303008cd6e7ae37673a55')
previewObj.widget = $sp.getWidget('cd-video-carousel', {
content_id: grContentItem.getUniqueValue()
});
else if (grContentType === 'afb39d7a0b4303008cd6e7ae37673a16')
previewObj.widget = $sp.getWidget('cd-information-links', {
content_id: grContentItem.getUniqueValue()
});
else if (grContentType === 'ae935d7a0b4303008cd6e7ae37673a9a')
previewObj.widget = $sp.getWidget('cd-quick-links', {
content_id : grContentItem.getUniqueValue()
});
else if (grContentType === '3893597a0b4303008cd6e7ae37673a4c')
previewObj.widget = $sp.getWidget('cd-upcoming-events', {
content_id : grContentItem.getUniqueValue()
});
else if (grContentType === '97a35d7a0b4303008cd6e7ae37673a47')
previewObj.widget = $sp.getWidget('cd-announcements', {
content_id : grContentItem.getUniqueValue()
});
else if (grContentType === '181d586d77741110a10440483f5a9933')
previewObj.widget = $sp.getWidget('cd-richcontent', {
content_id : grContentItem.getUniqueValue()
});
} else
gs.addErrorMessage(gs.getMessage("Could not find sn_cd_content_portal {0}", contentId));
return previewObj;
};
cd_ContentDelivery.getScaPreviewContent = function ($sp, portalPreview) {
var content_id = $sp.getParameter('sca_content_id');
var result = [];
var user = gs.getUser();
if (user.hasRole('sn_cd.content_approver'))
result = cd_ContentDelivery._buildScaPreviewContent($sp, portalPreview);
else
if (new GlidePluginManager().isActive('com.sn_content_governance')) {
var contentGovernance = new sn_cg.cg_PermissionUtils();
if (contentGovernance.isRequestor(content_id, gs.getUserID()) ||
contentGovernance.isApprover(content_id, gs.getUserID()))
result = cd_ContentDelivery._buildScaPreviewContent($sp, portalPreview);
else {
gs.addErrorMessage(gs.getMessage("You do not have permission to preview this content."));
return result;
}
}
return result;
};
cd_ContentDelivery._buildScaPreviewContent = function ($sp, portalPreview) {
var grContent = new GlideRecord('sn_cd_content_portal');
var content_id = $sp.getParameter('sca_content_id');
var result = [];
if (grContent.get(content_id)) {
var accumulatedContent = {
contentMap: {},
contentArray: []
};
cd_ContentDelivery._addContentToResult(grContent, accumulatedContent);
if (portalPreview) {
if ($sp.getParameter('attachment_id'))
accumulatedContent.contentArray[0].background_image = $sp.getParameter('attachment_id') + '.iix';
accumulatedContent.contentArray[0].is_preview = true;
accumulatedContent.contentArray[0].is_content_active = grContent.getValue('active');
if (grContent.getValue('active') === '1')
accumulatedContent.contentArray[0].content_title = grContent.getDisplayValue('title');
else
accumulatedContent.contentArray[0].content_title = gs.getMessage('(Inactive) {0}', grContent.getDisplayValue('title'));
}
result = accumulatedContent.contentArray;
}
if (portalPreview) {
var grInstanceRecord = $sp.getInstanceRecord();
var spInstanceId = grInstanceRecord.getUniqueValue();
var topicId = $sp.getParameter('topic_id');
var contentList = cd_ContentDelivery.getContentForWidgetInstance(spInstanceId, topicId);
result = result.concat(cd_ContentDelivery.getContentForWidgetInstance(spInstanceId, topicId).filter(function (content) {
return content.sys_id !== content_id;
}));
var publishedContent = contentList.filter(function (content) {
return content.sys_id === content_id;
});
if (publishedContent.length === 1)
gs.addInfoMessage(gs.getMessage("Previewed content is highlighted below, but please note it is currently published and visible to applicable employees"));
else {
var sysIds = result.map(function(item) {
return item.sys_id
});
result = result.concat(contentList.filter(function (content) {
return content.sys_id !== content_id && sysIds.indexOf(content.sys_id) === -1;
}));
}
}
return result;
};
/* Determine if the widget is for portal or preview and return the appropriate content
* @param Object widget $sp context object
* @return Array the content item(s) for data.items
*/
cd_ContentDelivery.getContent = function ($sp, instanceId) {
var grInstanceRecord = $sp.getInstanceRecord();
var spInstanceId = grInstanceRecord.getUniqueValue();
var topicId = $sp.getParameter("topic_id");
if ($sp.getParameter('sca_content_id') && $sp.getParameter('sca_instance_id') && $sp.getParameter('sca_instance_id') === instanceId)
return cd_ContentDelivery.getScaPreviewContent($sp, true);
if ($sp.getParameter('sca_content_id') && !$sp.getParameter('sca_instance_id'))
return cd_ContentDelivery.getScaPreviewContent($sp);
if (cd_ContentDelivery.isContentPreview($sp) && !$sp.getParameter('sca_instance_id'))
return sn_ca.ca_CampaignPortalPreview.getContentForPreview($sp);
return cd_ContentDelivery.getContentForWidgetInstance(spInstanceId, topicId);
};
/* Creates the info object that holds the display info for the content popover in portal preview
* @param data Object the data object that has the items info
* @param additionalDetails Array objects with keys label and value
* @return Object the object with items with the info objects
*/
cd_ContentDelivery.setInfoObjectOnContentItem = function (item, additionalDetails) {
item.infoObject = {
title: gs.getMessage('Content Details'),
sections: [{
sectionTitle: '',
details: [{
label: gs.getMessage('Title'),
value: item.content_title
},
{
label: gs.getMessage('Order'),
value: item.order
},
].concat(additionalDetails),
}],
};
return item;
};
Sys ID
0f3c54bb537132003585c3c606dc341f