: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
/********************************************
* Copyright (c) 2020, Code Atlantic LLC
********************************************/
* Changes the current enabled state of supplied popup
* @param {number} popupID The ID for the popup.
* @param {number} enabledState 1 for active, 0 for inactive.
* @param {string} nonce The nonce for the action.
function changeEnabledState(popupID, enabledState, nonce) {
// eslint-disable-next-line no-undef
action: "pum_save_enabled_state",
$(".pum-enabled-toggle-button").on("change", function(e) {
if (true === e.target.checked) {
$button.data("popup-id"),
/*******************************************************************************
* Copyright (c) 2019, Code Atlantic LLC
******************************************************************************/
var $alerts = $(".pum-alerts"),
$noticeCounts = $(".pum-alert-count"),
count = parseInt($noticeCounts.eq(0).text());
function dismissAlert($alert, alertAction) {
var dismissible = $alert.data("dismissible"),
dismissible === "1" || dismissible === 1 || dismissible === true
action: "pum_alerts_action",
nonce: window.pum_alerts_nonce,
code: $alert.data("code"),
pum_dismiss_alert: alertAction
function dismissReviewRequest(reason) {
action: "pum_review_action",
nonce: window.pum_review_nonce,
group: window.pum_review_trigger.group,
code: window.pum_review_trigger.code,
pri: window.pum_review_trigger.pri,
if (typeof window.pum_review_api_url !== "undefined") {
url: window.pum_review_api_url,
trigger_group: window.pum_review_trigger.group,
trigger_code: window.pum_review_trigger.code,
uuid: window.pum_review_uuid || null
function checkRemoveAlerts() {
if ($alerts.find(".pum-alert-holder").length === 0) {
$alerts.slideUp(100, function() {
$("#menu-posts-popup .wp-menu-name .update-plugins").fadeOut();
function removeAlert($alert) {
$noticeCounts.text(count);
$alert.fadeTo(100, 0, function() {
$alert.slideUp(100, function() {
.on("pumDismissAlert", checkRemoveAlerts)
.on("click", ".pum-alert-holder .pum-dismiss", function(event) {
$alert = $this.parents(".pum-alert-holder"),
reason = $this.data("reason") || "maybe_later",
alertAction = $(this).data("action") || "dismiss";
// Prevent the PHP alert handler from also processing this.
if ("review_request" !== $alert.data("code")) {
dismissAlert($alert, alertAction);
dismissReviewRequest(reason);
/*******************************************************************************
* Copyright (c) 2019, Code Atlantic LLC
******************************************************************************/
$('.pum-color-picker').filter(':not(.pum-color-picker-initialized)')
.addClass('pum-color-picker-initialized')
change: function (event, ui) {
$(event.target).trigger('colorchange', ui);
clear: function (event) {
$(event.target).prev().trigger('colorchange').wpColorPicker('close');
window.PUM_Admin = window.PUM_Admin || {};
window.PUM_Admin.colorpicker = colorpicker;
.on('click', '.iris-palette', function () {
$(this).parents('.wp-picker-active').find('input.pum-color-picker').trigger('change');
.on('colorchange', function (event, ui) {
var $input = $(event.target),
if (ui !== undefined && ui.color !== undefined) {
color = ui.color.toString();
$input.val(color).trigger('change');
if ($('form#post input#post_type').val() === 'popup_theme') {
PUM_Admin.utils.debounce(PUM_Admin.themeEditor.refresh_preview, 100);
.on('pum_init', colorpicker.init);
/*******************************************************************************
* Copyright (c) 2019, Code Atlantic LLC
******************************************************************************/
forms.checkDependencies();
* dependencies should look like this:
* field_name_1: value, // Select, radio etc.
* field_name_2: true // Checkbox
* Support for Multiple possible values of one field
* field_name_1: [ value_1, value_2 ]
checkDependencies: function ($dependent_fields) {
var _fields = $($dependent_fields);
// If no fields passed, only do those not already initialized.
$dependent_fields = _fields.length ? _fields : $("[data-pum-dependencies]:not([data-pum-processed-dependencies])");
$dependent_fields.each(function () {
var $dependent = $(this),
dependentID = $dependent.data('id'),
// The dependency object for this field.
dependencies = $dependent.data("pum-processed-dependencies") || {},
// Total number of fields this :input is dependent on.
requiredCount = Object.keys(dependencies).length,
// Current count of fields this :input matched properly.
// An array of fields this :input is dependent on.
dependentFields = $dependent.data("pum-dependent-fields"),
// Clean up & pre-process dependencies so we don't need to rebuild each time.
if (!$dependent.data("pum-processed-dependencies")) {
dependencies = $dependent.data("pum-dependencies");
if (typeof dependencies === 'string') {
dependencies = JSON.parse(dependencies);
// Convert each key to an array of acceptable values.
for (key in dependencies) {
if (dependencies.hasOwnProperty(key)) {
if (typeof dependencies[key] === "string") {
// Leave boolean values alone as they are for checkboxes or checking if an input has any value.
if (dependencies[key].indexOf(',') !== -1) {
dependencies[key] = dependencies[key].split(',');
dependencies[key] = [dependencies[key]];
} else if (typeof dependencies[key] === "number") {
dependencies[key] = [dependencies[key]];
// Update cache & counts.
requiredCount = Object.keys(dependencies).length;
$dependent.data("pum-processed-dependencies", dependencies).attr("data-pum-processed-dependencies", dependencies);
dependentFields = $.map(dependencies, function (value, index) {
var $wrapper = $('.pum-field[data-id="' + index + '"]');
return $wrapper.length ? $wrapper.eq(0) : null;
$dependent.data("pum-dependent-fields", dependentFields);
$(dependentFields).each(function () {
$field = $wrapper.find(':input:first'),
id = $wrapper.data("id"),
required = dependencies[id],
// Used for limiting the fields that get updated when this field is changed.
all_this_fields_dependents = $wrapper.data('pum-field-dependents') || [];
if (all_this_fields_dependents.indexOf(dependentID) === -1) {
all_this_fields_dependents.push(dependentID);
$wrapper.data('pum-field-dependents', all_this_fields_dependents);
// If no required values found bail early.
if (typeof required === 'undefined' || required === null) {
$dependent.removeClass('pum-dependencies-met').hide(0).trigger('pumFormDependencyUnmet');
// Effectively breaks the .each for this $dependent and hides it.
if ($wrapper.hasClass('pum-field-radio')) {
value = $wrapper.find(':input:checked').val();
if ($wrapper.hasClass('pum-field-multicheck')) {
$wrapper.find(':checkbox:checked').each(function (i) {
value[i] = $(this).val();
if (typeof value[i] === 'string' && !isNaN(parseInt(value[i]))) {
value[i] = parseInt(value[i]);
// Check if the value matches required values.
if ($wrapper.hasClass('pum-field-select') || $wrapper.hasClass('pum-field-radio')) {
matched = required && required.indexOf(value) !== -1;
} else if ($wrapper.hasClass('pum-field-checkbox')) {
matched = required === $field.is(':checked');
} else if ($wrapper.hasClass('pum-field-multicheck')) {
if (Array.isArray(required)) {
for (var i = 0; i < required.length; i++) {
if (value.indexOf(required[i]) !== -1) {
matched = value.indexOf(required) !== -1;
matched = Array.isArray(required) ? required.indexOf(value) !== -1 : required == value;
$dependent.removeClass('pum-dependencies-met').hide(0).trigger('pumFormDependencyUnmet');
// Effectively breaks the .each for this $dependent and hides it.
if (count === requiredCount) {
$dependent.addClass('pum-dependencies-met').show(0).trigger('pumFormDependencyMet');
form_check: function () {
$(document).trigger('pum_form_check');
is_field: function (data) {
if (typeof data !== 'object') {
data.type === undefined && (data.label !== undefined || data.desc !== undefined),
data.type !== undefined && typeof data.type === 'string'
return field_tests.indexOf(true) >= 0;
flattenFields: function (data) {
sections = data.sections || {},
fields = data.fields || {};
if (Object.keys(tabs).length && Object.keys(sections).length) {
_.each(fields, function (subTabs, tabID) {
// If not a valid tab or no subsections skip it.
if (typeof subTabs !== 'object' || !Object.keys(subTabs).length) {
_.each(subTabs, function (subTabFields, subTabID) {
// If not a valid subtab or no fields skip it.
if (typeof subTabFields !== 'object' || !Object.keys(subTabFields).length) {
// Move single fields into the main subtab.
if (forms.is_field(subTabFields)) {
var newSubTabFields = {};
newSubTabFields[subTabID] = subTabFields;
subTabFields = newSubTabFields;
// Loop Tab Section Fields
_.each(subTabFields, function (field) {
// Store the field by id for easy lookup later.
form_fields[field.id] = field;
else if (Object.keys(tabs).length) {
_.each(fields, function (tabFields, tabID) {
// If not a valid tab or no subsections skip it.
if (typeof tabFields !== 'object' || !Object.keys(tabFields).length) {
_.each(tabFields, function (field) {
// Store the field by id for easy lookup later.
form_fields[field.id] = field;
else if (Object.keys(sections).length) {
_.each(fields, function (sectionFields, sectionID) {
// Loop Tab Section Fields
_.each(sectionFields, function (field) {
// Store the field by id for easy lookup later.
form_fields[field.id] = field;
fields = forms.parseFields(fields, values);
// Replace the array with rendered fields.
_.each(fields, function (field) {
// Store the field by id for easy lookup later.
form_fields[field.id] = field;
parseFields: function (fields, values) {
_.each(fields, function (field, fieldID) {
fields[fieldID] = PUM_Admin.models.field(field);
if (typeof fields[fieldID].meta !== 'object') {
fields[fieldID].meta = {};
if (undefined !== values[fieldID]) {
fields[fieldID].value = values[fieldID];
if (fields[fieldID].id === '') {
fields[fieldID].id = fieldID;
renderSection: function () {
render: function (args, values, $container) {
classes: ['link-tabs', 'sub-tabs'],