: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* @copyright Copyright (c) 2023, Code Atlantic LLC
if ( ! defined( 'ABSPATH' ) ) {
* Hook the initialize method to the WP init action.
public static function init() {
// Adds ID to top of popup editor.
add_action( 'edit_form_top', [ __CLASS__, 'add_popup_id' ] );
// Change title to popup name.
add_filter( 'enter_title_here', [ __CLASS__, '_default_title' ] );
// Add popup title field.
add_action( 'edit_form_advanced', [ __CLASS__, 'title_meta_field' ] );
// Add Contextual help to post_name field.
add_action( 'edit_form_before_permalink', [ __CLASS__, 'popup_post_title_contextual_message' ] );
add_action( 'add_meta_boxes', [ __CLASS__, 'meta_box' ] );
add_action( 'save_post', [ __CLASS__, 'save' ], 10, 2 );
// Set the slug properly on save.
add_filter( 'wp_insert_post_data', [ __CLASS__, 'set_slug' ], 99, 2 );
// Dashboard columns & filters.
add_filter( 'manage_edit-popup_columns', [ __CLASS__, 'dashboard_columns' ] );
add_action( 'manage_posts_custom_column', [ __CLASS__, 'render_columns' ], 10, 2 );
add_filter( 'manage_edit-popup_sortable_columns', [ __CLASS__, 'sortable_columns' ] );
add_filter( 'default_hidden_columns', [ __CLASS__, 'hide_columns' ], 10, 2 );
add_action( 'load-edit.php', [ __CLASS__, 'load' ], 9999 );
add_action( 'restrict_manage_posts', [ __CLASS__, 'add_popup_filters' ], 100 );
add_filter( 'post_row_actions', [ __CLASS__, 'add_id_row_actions' ], 2, 100 );
add_action( 'post_submitbox_misc_actions', [ __CLASS__, 'add_enabled_toggle_editor' ], 10, 1 );
* Adds our enabled state toggle to the "Publish" meta box.
* @param WP_POST $post The current post (i.e. the popup).
public static function add_enabled_toggle_editor( $post ) {
if ( 'publish' !== $post->post_status || 'popup' !== $post->post_type ) {
$popup = pum_get_popup( $post->ID );
$enabled = $popup->is_enabled();
$nonce = wp_create_nonce( "pum_save_enabled_state_{$popup->ID}" );
<div class="misc-pub-section" style="display:flex;">
<span style="font-weight: bold; margin-right: 10px;">Popup Enabled </span>
<div class="pum-toggle-button">
<input id="pum-enabled-toggle-<?php echo esc_attr( $popup->ID ); ?>" type="checkbox" <?php checked( true, $enabled ); ?> class="pum-enabled-toggle-button" data-nonce="<?php echo esc_attr( $nonce ); ?>" data-popup-id="<?php echo esc_attr( $popup->ID ); ?>">
<label for="pum-enabled-toggle-<?php echo esc_attr( $popup->ID ); ?>" aria-label="Switch to enable popup"></label>
* Adds the Popup ID right under the "Edit Popup" heading
* @param WP_Post $post Post object.
public static function add_popup_id( $post ) {
if ( 'popup' === $post->post_type ) {
<p style="margin:0;font-size:12px;">ID: <span id="popup-id" data-popup-id="<?php echo esc_attr( $post->ID ); ?>"><?php echo esc_html( $post->ID ); ?></span></p>
* Change default "Enter title here" input
* @param string $title Default title placeholder text.
* @return string $title New placeholder text
public static function _default_title( $title ) {
$screen = get_current_screen();
if ( 'popup_theme' === $screen->post_type ) {
$label = 'popup' === $screen->post_type ? __( 'Popup', 'popup-maker' ) : __( 'Popup Theme', 'popup-maker' );
$title = sprintf( '%s Name', $label );
if ( 'popup' === $screen->post_type ) {
$title = __( 'Popup Name', 'popup-maker' );
* Renders the popup title meta field.
public static function title_meta_field() {
global $post, $pagenow, $typenow;
if ( has_blocks( $post ) || ( function_exists( 'use_block_editor_for_post' ) && use_block_editor_for_post( $post ) ) ) {
if ( 'popup' === $typenow && in_array( $pagenow, [ 'post-new.php', 'post.php' ] ) ) {
<div id="popup-titlediv" class="pum-form">
<div id="popup-titlewrap">
<label class="screen-reader-text" id="popup-title-prompt-text" for="popup-title">
<?php esc_html_e( 'Popup Title', 'popup-maker' ); ?>
<input tabindex="2" name="popup_title" size="30" value="<?php echo esc_attr( get_post_meta( $post->ID, 'popup_title', true ) ); ?>" id="popup-title" autocomplete="off" placeholder="<?php esc_html_e( 'Popup Title', 'popup-maker' ); ?>" />
<p class="pum-desc"><?php echo '(' . esc_html__( 'Optional', 'popup-maker' ) . ') ' . esc_html__( 'Shown as headline inside the popup. Can be left blank.', 'popup-maker' ); ?></p>
<div class="inside"></div>
<script>jQuery('#popup-titlediv').insertAfter('#titlediv');</script>
* Renders contextual help for title.
public static function popup_post_title_contextual_message() {
global $post, $pagenow, $typenow;
if ( has_blocks( $post ) || ( function_exists( 'use_block_editor_for_post' ) && use_block_editor_for_post( $post ) ) ) {
if ( 'popup' === $typenow && in_array( $pagenow, [ 'post-new.php', 'post.php' ] ) ) {
<p class="pum-desc"><?php echo '(' . esc_html__( 'Required', 'popup-maker' ) . ') ' . esc_html__( 'Enter a name to help you remember what this popup is about. Only you will see this.', 'popup-maker' ); ?></p>
* Registers popup metaboxes.
public static function meta_box() {
add_meta_box( 'pum_popup_settings', __( 'Popup Settings', 'popup-maker' ), [ __CLASS__, 'render_settings_meta_box' ], 'popup', 'normal', 'high' );
add_meta_box( 'pum_popup_analytics', __( 'Analytics', 'popup-maker' ), [ __CLASS__, 'render_analytics_meta_box' ], 'popup', 'side', 'high' );
* Ensures integrity of values.
* @param array $values Array of settings.
public static function parse_values( $values = [] ) {
$defaults = self::defaults();
if ( empty( $values ) ) {
$values = self::fill_missing_defaults( $values );
* Render the settings meta box wrapper and JS vars.
public static function render_settings_meta_box() {
$popup = pum_get_popup( $post->ID );
// Get the meta directly rather than from cached object.
$settings = self::parse_values( $popup->get_settings() );
wp_nonce_field( basename( __FILE__ ), 'pum_popup_settings_nonce' );
wp_enqueue_script( 'popup-maker-admin' );
<script type="text/javascript">
window.pum_popup_settings_editor =
echo PUM_Utils_Array::safe_json_encode(
'pum_popup_settings_editor_var',
'id' => 'pum-popup-settings',
'sections' => self::sections(),
'fields' => self::fields(),
'conditions' => PUM_Conditions::instance()->get_conditions(),
'conditions_selectlist' => PUM_Conditions::instance()->dropdown_list(),
'triggers' => PUM_Triggers::instance()->get_triggers(),
'cookies' => PUM_Cookies::instance()->get_cookies(),
'current_values' => self::render_form_values( $settings ),
'preview_nonce' => wp_create_nonce( 'popup-preview' ),
<div id="pum-popup-settings-container" class="pum-popup-settings-container">
<div class="pum-no-js" style="padding: 0 12px;">
<p><?php printf( esc_html__( 'If you are seeing this, the page is still loading or there are Javascript errors on this page. %1$sView troubleshooting guide%2$s', 'popup-maker' ), '<a href="https://docs.wppopupmaker.com/article/373-checking-for-javascript-errors" target="_blank">', '</a>' ); ?></p>
* Used to get deprecated fields for metabox saving of old extensions.
public static function deprecated_meta_fields() {
foreach ( self::deprecated_meta_field_groups() as $group ) {
foreach ( apply_filters( 'popmake_popup_meta_field_group_' . $group, [] ) as $field ) {
$fields[] = 'popup_' . $group . '_' . $field;
return apply_filters( 'popmake_popup_meta_fields', $fields );
* Used to get field groups from extensions.
public static function deprecated_meta_field_groups() {
return apply_filters( 'popmake_popup_meta_field_groups', [ 'display', 'close' ] );
public static function save( $post_id, $post ) {
if ( isset( $post->post_type ) && 'popup' !== $post->post_type ) {
if ( ! isset( $_POST['pum_popup_settings_nonce'] ) || ! wp_verify_nonce( $_POST['pum_popup_settings_nonce'], basename( __FILE__ ) ) ) {
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || isset( $_REQUEST['bulk_edit'] ) ) {
if ( isset( $post->post_type ) && 'revision' === $post->post_type ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
$popup = pum_get_popup( $post_id );
if ( isset( $_POST['popup_reset_counts'] ) ) {
* Reset popup open count, per user request.
$title = ! empty( $_POST['popup_title'] ) ? trim( sanitize_text_field( $_POST['popup_title'] ) ) : '';
$popup->update_meta( 'popup_title', $title );
$settings = ! empty( $_POST['popup_settings'] ) ? $_POST['popup_settings'] : [];
$settings['conditions'] = isset( $settings['conditions'] ) ? self::sanitize_meta( $settings['conditions'] ) : [];
$settings['triggers'] = isset( $settings['triggers'] ) ? self::sanitize_meta( $settings['triggers'] ) : [];
$settings['cookies'] = isset( $settings['cookies'] ) ? self::sanitize_meta( $settings['cookies'] ) : [];
$settings = apply_filters( 'pum_popup_setting_pre_save', $settings, $post->ID );
$settings = self::sanitize_settings( $settings );
$settings = self::parse_values( $settings );
$popup->update_settings( $settings, false );
// TODO Remove this and all other code here. This should be clean and all code more compartmentalized.
foreach ( self::deprecated_meta_fields() as $field ) {
if ( isset( $_POST[ $field ] ) ) {
$new = apply_filters( 'popmake_metabox_save_' . $field, $_POST[ $field ] );
update_post_meta( $post_id, $field, $new );
delete_post_meta( $post_id, $field );
do_action( 'pum_save_popup', $post_id, $post );
* Parse & prepare values for form rendering.
* Add additional data for license_key fields, split the measure fields etc.
public static function render_form_values( $settings ) {
foreach ( $settings as $key => $value ) {
$field = self::get_field( $key );
switch ( $field['type'] ) {
* List of tabs & labels for the settings panel.
public static function tabs() {
'pum_popup_settings_tabs',
'general' => __( 'General', 'popup-maker' ),
'display' => __( 'Display', 'popup-maker' ),
'close' => __( 'Close', 'popup-maker' ),
'triggers' => __( 'Triggers', 'popup-maker' ),
'targeting' => __( 'Targeting', 'popup-maker' ),
'advanced' => __( 'Advanced', 'popup-maker' ),
* List of tabs & labels for the settings panel.
public static function sections() {
'pum_popup_settings_sections',
'main' => __( 'General Settings', 'popup-maker' ),
'main' => __( 'Triggers & Cookies', 'popup-maker' ),
'main' => __( 'Conditions', 'popup-maker' ),
'preset' => __( 'Display Presets', 'popup-maker' ),
'main' => __( 'Appearance', 'popup-maker' ),
'size' => __( 'Size', 'popup-maker' ),
'animation' => __( 'Animation', 'popup-maker' ),
'sound' => __( 'Sounds', 'popup-maker' ),
'position' => __( 'Position', 'popup-maker' ),
'advanced' => __( 'Advanced', 'popup-maker' ),
'button' => __( 'Button', 'popup-maker' ),
'forms' => __( 'Form Submission', 'popup-maker' ),
'alternate_methods' => __( 'Alternate Methods', 'popup-maker' ),
'main' => __( 'Advanced', 'popup-maker' ),
* Returns array of popup settings fields.
public static function fields() {
if ( ! isset( $tabs ) ) {
'pum_popup_settings_fields',
'general' => apply_filters(
'pum_popup_general_settings_fields',
'triggers' => apply_filters(
'pum_popup_triggers_settings_fields',
'targeting' => apply_filters(
'pum_popup_targeting_settings_fields',
'label' => __( 'Disable this popup on mobile devices.', 'popup-maker' ),
'label' => __( 'Disable this popup on tablet devices.', 'popup-maker' ),
'display' => apply_filters(
'pum_popup_display_settings_fields',
'content' => '<p>Select one of the types below to get started! Once selected, you can adjust the display settings using the tabs above.</p>',
'classes' => 'popup-types',