first commit

This commit is contained in:
2026-03-05 13:07:40 +01:00
commit 64ba0721ee
25709 changed files with 4691006 additions and 0 deletions

View File

@@ -0,0 +1,279 @@
<?php
/**
* Admin-bar modules
*
* @package PUM
* @copyright Copyright (c) 2023, Code Atlantic LLC
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class PUM_Modules_Admin_Bar
*
* This class adds admin bar menu for Popup Management.
*/
class PUM_Modules_Admin_Bar {
/**
* Initializes this module.
*/
public static function init() {
add_action( 'admin_bar_menu', [ __CLASS__, 'toolbar_links' ], 999 );
add_action( 'wp_enqueue_scripts', [ __CLASS__, 'enqueue_files' ] );
add_action( 'init', [ __CLASS__, 'show_debug_bar' ] );
}
/**
* Renders the admin debug bar when PUM Debug is enabled.
*/
public static function show_debug_bar() {
if ( self::should_render() && Popup_Maker::debug_mode() ) {
show_admin_bar( true );
}
}
/**
* Returns true only if all of the following are true:
* - User is logged in.
* - Not in WP Admin.
* - The admin bar is showing.
* - PUM Admin bar is not disabled.
* - Current user can edit others posts or manage options.
*
* @return bool
*/
public static function should_render() {
$tests = [
is_user_logged_in(),
! is_admin(),
is_admin_bar_showing(),
! pum_get_option( 'disabled_admin_bar' ),
( current_user_can( 'edit_others_posts' ) || current_user_can( 'manage_options' ) ),
];
return ! in_array( false, $tests );
}
/**
* Add additional toolbar menu items to the front end.
*
* @param WP_Admin_Bar $wp_admin_bar
*/
public static function toolbar_links( $wp_admin_bar ) {
if ( ! self::should_render() ) {
return;
}
$popups = self::loaded_popups();
$count = count( $popups );
$wp_admin_bar->add_node(
[
'id' => 'popup-maker',
'title' => sprintf( '%s <span class="counter">%d</span>', __( 'Popup Maker', 'popup-maker' ), $count ),
'href' => '#popup-maker',
'meta' => [ 'class' => 'popup-maker-toolbar' ],
'parent' => false,
]
);
$wp_admin_bar->add_node(
[
'id' => 'popups',
'title' => sprintf( '%s <span class="counter">%d</span>', __( 'Popups', 'popup-maker' ), $count ),
'href' => '#',
'parent' => 'popup-maker',
]
);
if ( $count ) {
foreach ( $popups as $popup ) {
/** @var WP_Post $popup */
$node_id = 'popup-' . $popup->ID;
$can_edit = current_user_can( 'edit_post', $popup->ID );
$edit_url = $can_edit ? admin_url( 'post.php?post=' . $popup->ID . '&action=edit' ) : '#';
// Single Popup Menu Node
$wp_admin_bar->add_node(
[
'id' => $node_id,
'title' => esc_html( $popup->post_title ),
'href' => $edit_url,
'parent' => 'popups',
]
);
// Trigger Link
$wp_admin_bar->add_node(
[
'id' => $node_id . '-open',
'title' => __( 'Open Popup', 'popup-maker' ),
'meta' => [
'onclick' => 'PUM.open(' . $popup->ID . '); return false;',
],
'href' => '#popup-maker-open-popup-' . $popup->ID,
'parent' => $node_id,
]
);
$wp_admin_bar->add_node(
[
'id' => $node_id . '-close',
'title' => __( 'Close Popup', 'popup-maker' ),
'meta' => [
'onclick' => 'PUM.close(' . $popup->ID . '); return false;',
],
'href' => '#popup-maker-close-popup-' . $popup->ID,
'parent' => $node_id,
]
);
if ( pum_get_popup( $popup->ID )->has_conditions( [ 'js_only' => true ] ) ) {
$wp_admin_bar->add_node(
[
'id' => $node_id . '-conditions',
'title' => __( 'Check Conditions', 'popup-maker' ),
'meta' => [
'onclick' => 'alert(PUM.checkConditions(' . $popup->ID . ') ? "Pass" : "Fail"); return false;',
],
'href' => '#popup-maker-check-conditions-popup-' . $popup->ID,
'parent' => $node_id,
]
);
}
$wp_admin_bar->add_node(
[
'id' => $node_id . '-reset-cookies',
'title' => __( 'Reset Cookies', 'popup-maker' ),
'meta' => [
'onclick' => 'PUM.clearCookies(' . $popup->ID . '); alert("' . __( 'Success', 'popup-maker' ) . '"); return false;',
],
'href' => '#popup-maker-reset-cookies-popup-' . $popup->ID,
'parent' => $node_id,
]
);
if ( $can_edit ) {
// Edit Popup Link
$wp_admin_bar->add_node(
[
'id' => $node_id . '-edit',
'title' => __( 'Edit Popup', 'popup-maker' ),
'href' => $edit_url,
'parent' => $node_id,
]
);
}
}
} else {
$wp_admin_bar->add_node(
[
'id' => 'no-popups-loaded',
'title' => __( 'No Popups Loaded', 'popup-maker' ) . '<strong style="color:#fff; margin-left: 5px;">?</strong>',
'href' => 'https://docs.wppopupmaker.com/article/265-my-popup-wont-work-how-can-i-fix-it?utm_campaign=contextual-help&utm_medium=inline-doclink&utm_source=plugin-admin-bar&utm_content=no-popups-loaded',
'parent' => 'popups',
'meta' => [
'target' => '_blank',
],
]
);
}
if ( current_user_can( 'edit_posts' ) ) {
$wp_admin_bar->add_node(
[
'id' => 'all-popups',
'title' => __( 'All Popups', 'popup-maker' ),
'href' => admin_url( 'edit.php?post_type=popup' ),
'parent' => 'popup-maker',
]
);
$wp_admin_bar->add_node(
[
'id' => 'new-popups', // Just `new-popup` moves this to the top of the menu for some reason. Leave the `s` to keep it in the right place.
'title' => __( 'Create New Popup', 'popup-maker' ),
'href' => admin_url( 'post-new.php?post_type=popup' ),
'parent' => 'popup-maker',
]
);
}
/**
* Tools
*/
$wp_admin_bar->add_node(
[
'id' => 'pum-tools',
'title' => __( 'Tools', 'popup-maker' ),
'href' => '#popup-maker-tools',
'parent' => 'popup-maker',
]
);
$wp_admin_bar->add_node(
[
'id' => 'flush-popup-cache',
'title' => __( 'Flush Popup Cache', 'popup-maker' ),
'href' => wp_nonce_url( add_query_arg( 'flush_popup_cache', 'yes' ), 'flush_popup_cache' ),
'parent' => 'pum-tools',
]
);
/**
* Get Selector
*/
$wp_admin_bar->add_node(
[
'id' => 'pum-get-selector',
'title' => __( 'Get Selector', 'popup-maker' ),
'href' => '#popup-maker-get-selector-tool',
'parent' => 'pum-tools',
]
);
}
/**
* @return array
*/
public static function loaded_popups() {
static $popups;
if ( ! isset( $popups ) ) {
$loaded = PUM_Site_Popups::get_loaded_popups();
$popups = $loaded->posts;
}
return $popups;
}
/**
* Enqueues and prepares our styles and scripts for the admin bar
*
* @since 1.11.0
*/
public static function enqueue_files() {
if ( ! self::should_render() ) {
return;
}
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_enqueue_script( 'pum-admin-bar', Popup_Maker::$URL . 'assets/js/admin-bar' . $suffix . '.js', [ 'jquery' ], Popup_Maker::$VER, true );
wp_enqueue_style( 'pum-admin-bar-style', Popup_Maker::$URL . 'assets/css/pum-admin-bar' . $suffix . '.css', [], Popup_Maker::$VER );
$admin_bar_text = [
'instructions' => __( 'After clicking ok, click the element you want a selector for.', 'popup-maker' ),
'results' => _x( 'Selector', 'JS alert for CSS get selector tool', 'popup-maker' ),
];
wp_localize_script( 'pum-admin-bar', 'pumAdminBarText', $admin_bar_text );
}
}
PUM_Modules_Admin_Bar::init();

View File

@@ -0,0 +1,287 @@
<?php
/**
* Modules for menus
*
* @package PUM
* @copyright Copyright (c) 2023, Code Atlantic LLC
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class PUM_Modules_Menu
*
* This class handles the menu editor fields & adds popup classes to menu items.
*/
class PUM_Modules_Menu {
/**
* Initializes this module.
*/
public static function init() {
add_filter( 'popmake_settings_misc', [ __CLASS__, 'settings' ] );
if ( PUM_Utils_Options::get( 'disabled_menu_editor', false ) ) {
return;
}
// Merge Menu Item Options
add_filter( 'wp_setup_nav_menu_item', [ __CLASS__, 'merge_item_data' ] );
// Admin Menu Editor
add_filter( 'wp_edit_nav_menu_walker', [ __CLASS__, 'nav_menu_walker' ], 999999999 );
// Admin Menu Editor Fields.
add_action( 'wp_nav_menu_item_custom_fields', [ __CLASS__, 'fields' ], 10, 4 );
add_action( 'wp_update_nav_menu_item', [ __CLASS__, 'save' ], 10, 2 );
add_filter( 'manage_nav-menus_columns', [ __CLASS__, 'nav_menu_columns' ], 11 );
}
public static function settings( $settings ) {
return array_merge(
$settings,
[
'disabled_menu_editor' => [
'id' => 'disabled_menu_editor',
'name' => __( 'Disable Popups Menu Editor', 'popup-maker' ),
'desc' => sprintf(
esc_html_x( 'Use this if there is a conflict with your theme or another plugin in the nav menu editor. %1$sLearn more%2$s', '%s represent opening and closing link html', 'popup-maker' ),
'<a href="https://docs.wppopupmaker.com/article/297-popup-maker-is-overwriting-my-menu-editor-functions-how-can-i-fix-this?utm_campaign=contextual-help&utm_medium=inline-doclink&utm_source=settings-page&utm_content=disable-popup-menu-editor" target="_blank" rel="noreferrer noopener">',
'</a>'
),
'type' => 'checkbox',
],
]
);
}
public static function nav_menu_columns( $columns = [] ) {
$columns['popup_id'] = __( 'Popup', 'popup-maker' );
return $columns;
}
/**
* Override the Admin Menu Walker
*
* @param $walker
*
* @return string
*/
public static function nav_menu_walker( $walker ) {
global $wp_version;
$bail_early = [
// WP 5.4 adds support for custom fields, no need to do this hack at all.
version_compare( $wp_version, '5.4', '>=' ),
// not sure about this one, was part of the original solution.
doing_filter( 'plugins_loaded' ),
// No need if its already loaded by another plugin.
'Walker_Nav_Menu_Edit_Custom_Fields' === $walker,
];
if ( in_array( true, $bail_early ) ) {
return $walker;
}
// Load custom nav menu walker class for custom field compatibility.
if ( ! class_exists( 'Walker_Nav_Menu_Edit_Custom_Fields' ) ) {
if ( version_compare( $wp_version, '3.6', '>=' ) ) {
require_once POPMAKE_DIR . '/includes/modules/menus/class-nav-menu-edit-custom-fields.php';
} else {
require_once POPMAKE_DIR . '/includes/modules/menus/class-nav-menu-edit-custom-fields-deprecated.php';
}
}
return 'Walker_Nav_Menu_Edit_Custom_Fields';
}
/**
* Merge Item data into the $item object.
*
* @param $item
*
* @return mixed
*/
public static function merge_item_data( $item ) {
if ( ! is_object( $item ) || ! isset( $item->ID ) || $item->ID <= 0 ) {
return $item;
}
// Merge Rules.
foreach ( self::get_item_options( $item->ID ) as $key => $value ) {
$item->$key = $value;
}
if ( is_admin() ) {
return $item;
}
if ( isset( $item->popup_id ) ) {
$item->classes[] = 'popmake-' . $item->popup_id;
}
/**
* Check menu item's classes for popmake-###. Do this after the above conditional to catch the class we add too.
* Tested both using strpos followed by preg_match as well as just doing preg_match on all and this solution
* was just a tiny bit faster. But, if a site has 100 menu items, that tiny difference will add up.
*/
foreach ( $item->classes as $class ) {
if ( strpos( $class, 'popmake-' ) !== false ) {
if ( 0 !== preg_match( '/popmake-(\d+)/', $class, $matches ) ) {
PUM_Site_Popups::preload_popup_by_id_if_enabled( $matches[1] );
}
}
}
return $item;
}
/**
* @param int $item_id
*
* @return array
*/
public static function get_item_options( $item_id = 0 ) {
// Fetch all rules for this menu item.
$item_options = get_post_meta( $item_id, '_pum_nav_item_options', true );
return self::parse_item_options( $item_options );
}
/**
* @param array $options
*
* @return array
*/
public static function parse_item_options( $options = [] ) {
if ( ! is_array( $options ) ) {
$options = [];
}
return wp_parse_args(
$options,
[
'popup_id' => null,
]
);
}
/**
* Adds custom fields to the menu item editor.
*
* @param $item_id
* @param $item
* @param $depth
* @param $args
*/
public static function fields( $item_id, $item, $depth, $args ) {
wp_nonce_field( 'pum-menu-editor-nonce', 'pum-menu-editor-nonce' ); ?>
<p class="field-popup_id description description-wide">
<label for="edit-menu-item-popup_id-<?php echo $item->ID; ?>">
<?php _e( 'Trigger a Popup', 'popup-maker' ); ?><br />
<select name="menu-item-pum[<?php echo $item->ID; ?>][popup_id]" id="edit-menu-item-popup_id-<?php echo $item->ID; ?>" class="widefat edit-menu-item-popup_id">
<option value=""></option>
<?php foreach ( self::popup_list() as $option => $label ) : ?>
<option value="<?php echo $option; ?>" <?php selected( $option, $item->popup_id ); ?>>
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
</select>
<span class="description"><?php _e( 'Choose a popup to trigger when this item is clicked.', 'popup-maker' ); ?></span>
</label>
</p>
<?php
}
/**
* Returns a list of popups for a dropdown.
*
* @return array
*/
public static function popup_list() {
static $popup_list;
if ( ! isset( $popup_list ) ) {
$popup_list = [];
$popups = pum_get_all_popups();
if ( ! empty( $popups ) ) {
foreach ( $popups as $popup ) {
$popup_list[ $popup->ID ] = $popup->post_title;
}
}
}
return $popup_list;
}
/**
* Processes the saving of menu items.
*
* @param $menu_id
* @param $item_id
*/
public static function save( $menu_id, $item_id ) {
$popups = self::popup_list();
$allowed_popups = wp_parse_id_list( array_keys( $popups ) );
if ( ! isset( $_POST['pum-menu-editor-nonce'] ) || ! wp_verify_nonce( $_POST['pum-menu-editor-nonce'], 'pum-menu-editor-nonce' ) ) {
return;
}
/**
* Return early if there are no settings.
*/
if ( empty( $_POST['menu-item-pum'][ $item_id ] ) ) {
delete_post_meta( $item_id, '_pum_nav_item_options' );
return;
}
/**
* Parse options array for valid keys.
*/
$item_options = self::parse_item_options( $_POST['menu-item-pum'][ $item_id ] );
/**
* Check for invalid values.
*/
if ( ! in_array( $item_options['popup_id'], $allowed_popups ) || $item_options['popup_id'] <= 0 ) {
unset( $item_options['popup_id'] );
}
/**
* Remove empty options to save space.
*/
$item_options = array_filter( $item_options );
/**
* Save options or delete if empty.
*/
if ( ! empty( $item_options ) ) {
update_post_meta( $item_id, '_pum_nav_item_options', $item_options );
} else {
delete_post_meta( $item_id, '_pum_nav_item_options' );
}
}
}
PUM_Modules_Menu::init();

View File

@@ -0,0 +1,68 @@
<?php
if ( ! class_exists( 'Walker_Nav_Menu_Edit' ) ) {
/** Walker_Nav_Menu_Edit class */
require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
}
/**
* Custom Walker for Nav Menu Editor
*
* Add wp_nav_menu_item_custom_fields hook to the nav menu editor.
*
* Credits:
*
* @helgatheviking - Initial concept which has made adding settings in the menu editor in a compatible way.
* @kucrut - preg_replace() method so that we no longer have to translate core strings
* @danieliser - refactor for less complexity between WP versions & updating versioned classes for proper backward compatibility with the new methods.
*
* @since WordPress 3.0.0
* @uses Walker_Nav_Menu_Edit
*/
class Walker_Nav_Menu_Edit_Custom_Fields extends Walker_Nav_Menu_Edit {
/**
* Start the element output.
*
* @see Walker_Nav_Menu_Edit::start_el()
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $item Menu item data object.
* @param int $depth Depth of menu item.
* @param array $args
*/
public function start_el( &$output, $item, $depth = 0, $args = [] ) {
$item_output = '';
parent::start_el( $item_output, $item, $depth, $args );
$output .= preg_replace( '/(<p[^>]+class="[^"]*field-description(?:.|\n)*?<\/p>)/', "$1 \r\n " . $this->get_custom_fields( $item, $depth, $args ), $item_output, 1 );
}
/**
* Get custom fields
*
* @uses do_action() Calls 'menu_item_custom_fields' hook
*
* @param object $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param array $args Menu item args.
*
* @return string Additional fields or html for the nav menu editor.
*/
protected function get_custom_fields( $item, $depth, $args = [] ) {
ob_start();
$item_id = intval( $item->ID );
/**
* Get menu item custom fields from plugins/themes
*
* @param int $item_id post ID of menu
* @param object $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param array $args Menu item args.
*
* @return string Custom fields
*/
do_action( 'wp_nav_menu_item_custom_fields', $item_id, $item, $depth, $args );
return ob_get_clean();
}
}

View File

@@ -0,0 +1,76 @@
<?php
/** Walker_Nav_Menu_Edit class */
if ( ! class_exists( 'Walker_Nav_Menu_Edit' ) ) {
global $wp_version;
if ( version_compare( $wp_version, '4.4', '>=' ) ) {
require_once ABSPATH . 'wp-admin/includes/class-walker-nav-menu-edit.php';
} else {
require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
}
}
/**
* Custom Walker for Nav Menu Editor
*
* Add wp_nav_menu_item_custom_fields hook to the nav menu editor.
*
* Credits:
*
* @helgatheviking - Initial concept which has made adding settings in the menu editor in a compatible way.
* @kucrut - preg_replace() method so that we no longer have to translate core strings
* @danieliser - refactor for less complexity between WP versions & updating versioned classes for proper backward compatibility with the new methods.
*
* @since WordPress 3.6.0
* @uses Walker_Nav_Menu_Edit
*/
class Walker_Nav_Menu_Edit_Custom_Fields extends Walker_Nav_Menu_Edit {
/**
* Start the element output.
*
* @see Walker_Nav_Menu_Edit::start_el()
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $item Menu item data object.
* @param int $depth Depth of menu item.
* @param array $args
* @param int $id
*/
public function start_el( &$output, $item, $depth = 0, $args = [], $id = 0 ) {
$item_output = '';
$output .= parent::start_el( $item_output, $item, $depth, $args, $id );
// NOTE: Check this regex on major WP version updates!
$output .= preg_replace( '/(?=<fieldset[^>]+class="[^"]*field-move)/', $this->get_custom_fields( $item, $depth, $args ), $item_output );
}
/**
* Get custom fields
*
* @uses do_action() Calls 'menu_item_custom_fields' hook
*
* @param object $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param array $args Menu item args.
*
* @return string Additional fields or html for the nav menu editor.
*/
protected function get_custom_fields( $item, $depth, $args = [] ) {
ob_start();
$item_id = intval( $item->ID );
/**
* Get menu item custom fields from plugins/themes
*
* @param int $item_id post ID of menu
* @param object $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param array $args Menu item args.
*
* @return string Custom fields
*/
do_action( 'wp_nav_menu_item_custom_fields', $item_id, $item, $depth, $args );
return ob_get_clean();
}
}

View File

@@ -0,0 +1,569 @@
<?php
/**
* Modules for reviews
*
* @package PUM
* @copyright Copyright (c) 2023, Code Atlantic LLC
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class PUM_Modules_Reviews
*
* This class adds a review request system for your plugin or theme to the WP dashboard.
*/
class PUM_Modules_Reviews {
/**
* Tracking API Endpoint.
*
* @var string
*/
public static $api_url = 'https://api.wppopupmaker.com/wp-json/pmapi/v1/review_action';
/**
*
*/
public static function init() {
// add_action( 'init', array( __CLASS__, 'hooks' ) );
add_filter( 'pum_alert_list', [ __CLASS__, 'review_alert' ] );
add_action( 'wp_ajax_pum_review_action', [ __CLASS__, 'ajax_handler' ] );
}
/**
* Hook into relevant WP actions.
*/
public static function hooks() {
if ( is_admin() && current_user_can( 'edit_posts' ) ) {
self::installed_on();
add_action( 'admin_notices', [ __CLASS__, 'admin_notices' ] );
add_action( 'network_admin_notices', [ __CLASS__, 'admin_notices' ] );
add_action( 'user_admin_notices', [ __CLASS__, 'admin_notices' ] );
}
}
/**
* Get the install date for comparisons. Sets the date to now if none is found.
*
* @return false|string
*/
public static function installed_on() {
$installed_on = get_option( 'pum_reviews_installed_on', false );
if ( ! $installed_on ) {
$installed_on = current_time( 'mysql' );
update_option( 'pum_reviews_installed_on', $installed_on );
}
return $installed_on;
}
/**
*
*/
public static function ajax_handler() {
$args = wp_parse_args(
$_REQUEST,
[
'group' => self::get_trigger_group(),
'code' => self::get_trigger_code(),
'pri' => self::get_current_trigger( 'pri' ),
'reason' => 'maybe_later',
]
);
if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'pum_review_action' ) ) {
wp_send_json_error();
}
try {
$user_id = get_current_user_id();
$dismissed_triggers = self::dismissed_triggers();
$dismissed_triggers[ $args['group'] ] = $args['pri'];
update_user_meta( $user_id, '_pum_reviews_dismissed_triggers', $dismissed_triggers );
update_user_meta( $user_id, '_pum_reviews_last_dismissed', current_time( 'mysql' ) );
switch ( $args['reason'] ) {
case 'maybe_later':
update_user_meta( $user_id, '_pum_reviews_last_dismissed', current_time( 'mysql' ) );
break;
case 'am_now':
case 'already_did':
self::already_did( true );
break;
}
wp_send_json_success();
} catch ( Exception $e ) {
wp_send_json_error( $e );
}
}
/**
* @return int|string
*/
public static function get_trigger_group() {
static $selected;
if ( ! isset( $selected ) ) {
$dismissed_triggers = self::dismissed_triggers();
$triggers = self::triggers();
foreach ( $triggers as $g => $group ) {
foreach ( $group['triggers'] as $t => $trigger ) {
if ( ! in_array( false, $trigger['conditions'] ) && ( empty( $dismissed_triggers[ $g ] ) || $dismissed_triggers[ $g ] < $trigger['pri'] ) ) {
$selected = $g;
break;
}
}
if ( isset( $selected ) ) {
break;
}
}
}
return $selected;
}
/**
* @return int|string
*/
public static function get_trigger_code() {
static $selected;
if ( ! isset( $selected ) ) {
$dismissed_triggers = self::dismissed_triggers();
foreach ( self::triggers() as $g => $group ) {
foreach ( $group['triggers'] as $t => $trigger ) {
if ( ! in_array( false, $trigger['conditions'] ) && ( empty( $dismissed_triggers[ $g ] ) || $dismissed_triggers[ $g ] < $trigger['pri'] ) ) {
$selected = $t;
break;
}
}
if ( isset( $selected ) ) {
break;
}
}
}
return $selected;
}
/**
* @param null $key
*
* @return bool|mixed|void
*/
public static function get_current_trigger( $key = null ) {
$group = self::get_trigger_group();
$code = self::get_trigger_code();
if ( ! $group || ! $code ) {
return false;
}
$trigger = self::triggers( $group, $code );
return empty( $key ) ? $trigger : ( isset( $trigger[ $key ] ) ? $trigger[ $key ] : false );
}
/**
* Returns an array of dismissed trigger groups.
*
* Array contains the group key and highest priority trigger that has been shown previously for each group.
*
* $return = array(
* 'group1' => 20
* );
*
* @return array|mixed
*/
public static function dismissed_triggers() {
$user_id = get_current_user_id();
$dismissed_triggers = get_user_meta( $user_id, '_pum_reviews_dismissed_triggers', true );
if ( ! $dismissed_triggers ) {
$dismissed_triggers = [];
}
return $dismissed_triggers;
}
/**
* Returns true if the user has opted to never see this again. Or sets the option.
*
* @param bool $set If set this will mark the user as having opted to never see this again.
*
* @return bool
*/
public static function already_did( $set = false ) {
$user_id = get_current_user_id();
if ( $set ) {
update_user_meta( $user_id, '_pum_reviews_already_did', true );
return true;
}
return (bool) get_user_meta( $user_id, '_pum_reviews_already_did', true );
}
/**
* Gets a list of triggers.
*
* @param null $group
* @param null $code
*
* @return bool|mixed
*/
public static function triggers( $group = null, $code = null ) {
static $triggers;
if ( ! isset( $triggers ) ) {
$time_message = __( 'Hi there! You\'ve been using Popup Maker on your site for %s - I hope it\'s been helpful. If you\'re enjoying my plugin, would you mind rating it 5-stars to help spread the word?', 'popup-maker' );
$triggers = [
'time_installed' => [
'triggers' => [
'one_week' => [
'message' => sprintf( $time_message, __( '1 week', 'popup-maker' ) ),
'conditions' => [
strtotime( self::installed_on() . ' +1 week' ) < time(),
],
'link' => 'https://wordpress.org/support/plugin/popup-maker/reviews/?rate=5#rate-response',
'pri' => 10,
],
'one_month' => [
'message' => sprintf( $time_message, __( '1 month', 'popup-maker' ) ),
'conditions' => [
strtotime( self::installed_on() . ' +1 month' ) < time(),
],
'link' => 'https://wordpress.org/support/plugin/popup-maker/reviews/?rate=5#rate-response',
'pri' => 20,
],
'three_months' => [
'message' => sprintf( $time_message, __( '3 months', 'popup-maker' ) ),
'conditions' => [
strtotime( self::installed_on() . ' +3 months' ) < time(),
],
'link' => 'https://wordpress.org/support/plugin/popup-maker/reviews/?rate=5#rate-response',
'pri' => 30,
],
],
'pri' => 10,
],
'open_count' => [
'triggers' => [],
'pri' => 50,
],
];
$pri = 10;
$open_message = __( 'Hi there! You\'ve recently hit %s popup views on your site thats awesome!! If you\'d like to celebrate this milestone, rate Popup Maker 5-stars to help spread the word!', 'popup-maker' );
foreach ( [ 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000 ] as $num ) {
$triggers['open_count']['triggers'][ $num . '_opens' ] = [
'message' => sprintf( $open_message, number_format( $num ) ),
'conditions' => [
get_option( 'pum_total_open_count', 0 ) > $num,
],
'link' => 'https://wordpress.org/support/plugin/popup-maker/reviews/?rate=5#rate-response',
'pri' => $pri,
];
$pri += 10;
}
$triggers = apply_filters( 'pum_reviews_triggers', $triggers );
// Sort Groups
uasort( $triggers, [ __CLASS__, 'rsort_by_priority' ] );
// Sort each groups triggers.
foreach ( $triggers as $k => $v ) {
uasort( $triggers[ $k ]['triggers'], [ __CLASS__, 'rsort_by_priority' ] );
}
}
if ( isset( $group ) ) {
if ( ! isset( $triggers[ $group ] ) ) {
return false;
}
if ( ! isset( $code ) ) {
return $triggers[ $group ];
} else {
return isset( $triggers[ $group ]['triggers'][ $code ] ) ? $triggers[ $group ]['triggers'][ $code ] : false;
}
}
return $triggers;
}
/**
* Register alert when review request is available.
*
* @param array $alerts
*
* @return array
*/
public static function review_alert( $alerts = [] ) {
if ( self::hide_notices() ) {
return $alerts;
}
$trigger = self::get_current_trigger();
// Used to anonymously distinguish unique site+user combinations in terms of effectiveness of each trigger.
$uuid = wp_hash( home_url() . '-' . get_current_user_id() );
ob_start();
?>
<script type="text/javascript">
window.pum_review_nonce = '<?php echo wp_create_nonce( 'pum_review_action' ); ?>';
window.pum_review_api_url = '<?php echo esc_attr( self::$api_url ); ?>';
window.pum_review_uuid = '<?php echo esc_attr( $uuid ); ?>';
window.pum_review_trigger = {
group: '<?php echo esc_attr( self::get_trigger_group() ); ?>',
code: '<?php echo esc_attr( self::get_trigger_code() ); ?>',
pri: '<?php echo esc_attr( self::get_current_trigger( 'pri' ) ); ?>'
};
</script>
<ul>
<li>
<a class="pum-dismiss" target="_blank" href="<?php echo esc_attr( $trigger['link'] ); ?>" data-reason="am_now"> <strong><?php _e( 'Ok, you deserve it', 'popup-maker' ); ?></strong> </a>
</li>
<li>
<a href="#" class="pum-dismiss" data-reason="maybe_later">
<?php _e( 'Nope, maybe later', 'popup-maker' ); ?>
</a>
</li>
<li>
<a href="#" class="pum-dismiss" data-reason="already_did">
<?php _e( 'I already did', 'popup-maker' ); ?>
</a>
</li>
</ul>
<?php
$html = ob_get_clean();
$alerts[] = [
'code' => 'review_request',
'message' => '<strong>' . $trigger['message'] . '<br />~ danieliser' . '</strong>',
'html' => $html,
'type' => 'success',
];
return $alerts;
}
/**
* Render admin notices if available.
*
* @deprecated 1.8.0
*/
public static function admin_notices() {
if ( self::hide_notices() ) {
return;
}
$group = self::get_trigger_group();
$code = self::get_trigger_code();
$pri = self::get_current_trigger( 'pri' );
$trigger = self::get_current_trigger();
// Used to anonymously distinguish unique site+user combinations in terms of effectiveness of each trigger.
$uuid = wp_hash( home_url() . '-' . get_current_user_id() );
?>
<script type="text/javascript">
(function ($) {
var trigger = {
group: '<?php echo esc_attr( $group ); ?>',
code: '<?php echo esc_attr( $code ); ?>',
pri: '<?php echo esc_attr( $pri ); ?>'
};
function dismiss(reason) {
$.ajax({
method: "POST",
dataType: "json",
url: ajaxurl,
data: {
action: 'pum_review_action',
nonce: '<?php echo wp_create_nonce( 'pum_review_action' ); ?>',
group: trigger.group,
code: trigger.code,
pri: trigger.pri,
reason: reason
}
});
<?php if ( ! empty( self::$api_url ) ) : ?>
$.ajax({
method: "POST",
dataType: "json",
url: '<?php echo esc_attr( self::$api_url ); ?>',
data: {
trigger_group: trigger.group,
trigger_code: trigger.code,
reason: reason,
uuid: '<?php echo esc_attr( $uuid ); ?>'
}
});
<?php endif; ?>
}
$(document)
.on('click', '.pum-notice .pum-dismiss', function (event) {
var $this = $(this),
reason = $this.data('reason'),
notice = $this.parents('.pum-notice');
notice.fadeTo(100, 0, function () {
notice.slideUp(100, function () {
notice.remove();
});
});
dismiss(reason);
})
.ready(function () {
setTimeout(function () {
$('.pum-notice button.notice-dismiss').click(function (event) {
dismiss('maybe_later');
});
}, 1000);
});
}(jQuery));
</script>
<style>
.pum-notice p {
margin-bottom: 0;
}
.pum-notice img.logo {
float: right;
margin-left: 10px;
width: 128px;
padding: 0.25em;
border: 1px solid #ccc;
}
</style>
<div class="notice notice-success is-dismissible pum-notice">
<p>
<img class="logo" src="<?php echo POPMAKE_URL; ?>/assets/images/icon-256x256.jpg" />
<strong>
<?php esc_html_e( $trigger['message'] ); ?>
<br />
~ danieliser
</strong>
</p>
<ul>
<li>
<a class="pum-dismiss" target="_blank" href="<?php echo esc_attr( $trigger['link'] ); ?>" data-reason="am_now">
<strong><?php esc_html_e( 'Ok, you deserve it', 'popup-maker' ); ?></strong>
</a>
</li>
<li>
<a href="#" class="pum-dismiss" data-reason="maybe_later">
<?php esc_html_e( 'Nope, maybe later', 'popup-maker' ); ?>
</a>
</li>
<li>
<a href="#" class="pum-dismiss" data-reason="already_did">
<?php esc_html_e( 'I already did', 'popup-maker' ); ?>
</a>
</li>
</ul>
</div>
<?php
}
/**
* Checks if notices should be shown.
*
* @return bool
*/
public static function hide_notices() {
$trigger_code = self::get_trigger_code();
$conditions = [
self::already_did(),
self::last_dismissed() && strtotime( self::last_dismissed() . ' +2 weeks' ) > time(),
empty( $trigger_code ),
];
return in_array( true, $conditions );
}
/**
* Gets the last dismissed date.
*
* @return false|string
*/
public static function last_dismissed() {
$user_id = get_current_user_id();
return get_user_meta( $user_id, '_pum_reviews_last_dismissed', true );
}
/**
* Sort array by priority value
*
* @param $a
* @param $b
*
* @return int
*/
public static function sort_by_priority( $a, $b ) {
if ( ! isset( $a['pri'] ) || ! isset( $b['pri'] ) || $a['pri'] === $b['pri'] ) {
return 0;
}
return ( $a['pri'] < $b['pri'] ) ? - 1 : 1;
}
/**
* Sort array in reverse by priority value
*
* @param $a
* @param $b
*
* @return int
*/
public static function rsort_by_priority( $a, $b ) {
if ( ! isset( $a['pri'] ) || ! isset( $b['pri'] ) || $a['pri'] === $b['pri'] ) {
return 0;
}
return ( $a['pri'] < $b['pri'] ) ? 1 : - 1;
}
}
PUM_Modules_Reviews::init();