Current File : /home/aventura/www/site/wp-content/plugins/wp-smushit/extras/free-dashboard/module.php |
<?php
/**
* WPMUDEV Frash - Free Dashboard Notification module.
* Used by wordpress.org hosted plugins.
*
* @version 1.1.0
* @author Incsub (Philipp Stracker)
*/
if ( ! class_exists( 'WDev_Frash' ) ) {
class WDev_Frash {
/**
* List of all registered plugins.
*
* @since 1.0.0
* @var array
*/
protected $plugins = array();
/**
* Module options that are stored in database.
* Timestamps are stored here.
*
* Note that this option is stored in site-meta for multisite installs.
*
* @since 1.0.0
* @var array
*/
protected $stored = array();
/**
* Initializes and returns the singleton instance.
*
* @since 1.0.0
*/
static public function instance() {
static $Inst = null;
if ( null === $Inst ) {
$Inst = new WDev_Frash();
}
return $Inst;
}
/**
* Set up the WDev_Frash module. Private singleton constructor.
*
* @since 1.0.0
*/
private function __construct() {
$this->read_stored_data();
$this->add_action( 'wdev-register-plugin', 5 );
$this->add_action( 'load-index.php' );
$this->add_action( 'wp_ajax_frash_act' );
$this->add_action( 'wp_ajax_frash_dismiss' );
}
/**
* Load persistent module-data from the WP Database.
*
* @since 1.0.0
*/
protected function read_stored_data() {
$data = get_site_option( 'wdev-frash', false, false );
if ( ! is_array( $data ) ) {
$data = array();
}
// A list of all plugins with timestamp of first registration.
if ( ! isset( $data['plugins'] ) || ! is_array( $data['plugins'] ) ) {
$data['plugins'] = array();
}
// A list with pending messages and earliest timestamp for display.
if ( ! isset( $data['queue'] ) || ! is_array( $data['queue'] ) ) {
$data['queue'] = array();
}
// A list with all messages that were handles already.
if ( ! isset( $data['done'] ) || ! is_array( $data['done'] ) ) {
$data['done'] = array();
}
$this->stored = $data;
}
/**
* Save persistent module-data to the WP database.
*
* @since 1.0.0
*/
protected function store_data() {
update_site_option( 'wdev-frash', $this->stored );
}
/**
* Action handler for 'wdev-register-plugin'
* Register an active plugin.
*
* @since 1.0.0
* @param string $plugin_id WordPress plugin-ID (see: plugin_basename).
* @param string $title Plugin name for display.
* @param string $url_wp URL to the plugin on wp.org (domain not needed)
* @param string $cta_email Title of the Email CTA button.
* @param string $drip_plugin Optional. Plugin-param for the getdrip rule.
*/
public function wdev_register_plugin( $plugin_id, $title, $url_wp, $cta_email = '', $drip_plugin = '' ) {
// Ignore incorrectly registered plugins to avoid errors later.
if ( empty( $plugin_id ) ) { return; }
if ( empty( $title ) ) { return; }
if ( empty( $url_wp ) ) { return; }
if ( false === strpos( $url_wp, '://' ) ) {
$url_wp = 'https://wordpress.org/' . trim( $url_wp, '/' );
}
$this->plugins[$plugin_id] = (object) array(
'id' => $plugin_id,
'title' => $title,
'url_wp' => $url_wp,
'cta_email' => $cta_email,
'drip_plugin' => $drip_plugin,
);
/*
* When the plugin is registered the first time we store some infos
* in the persistent module-data that help us later to find out
* if/which message should be displayed.
*/
if ( empty( $this->stored['plugins'][$plugin_id] ) ) {
// First register the plugin permanently.
$this->stored['plugins'][$plugin_id] = time();
// Second schedule the messages to display.
$hash = md5( $plugin_id . '-email' );
$this->stored['queue'][$hash] = array(
'plugin' => $plugin_id,
'type' => 'email',
'show_at' => time(), // Earliest time to display note.
);
$hash = md5( $plugin_id . '-rate' );
$this->stored['queue'][$hash] = array(
'plugin' => $plugin_id,
'type' => 'rate',
'show_at' => time() + 7 * DAY_IN_SECONDS,
);
// Finally save the details.
$this->store_data();
}
}
/**
* Ajax handler called when the user chooses the CTA button.
*
* @since 1.0.0
*/
public function wp_ajax_frash_act() {
$plugin = $_POST['plugin_id'];
$type = $_POST['type'];
$this->mark_as_done( $plugin, $type, 'ok' );
echo 1;
exit;
}
/**
* Ajax handler called when the user chooses the dismiss button.
*
* @since 1.0.0
*/
public function wp_ajax_frash_dismiss() {
$plugin = $_POST['plugin_id'];
$type = $_POST['type'];
$this->mark_as_done( $plugin, $type, 'ignore' );
echo 1;
exit;
}
/**
* Action handler for 'load-index.php'
* Set-up the Dashboard notification.
*
* @since 1.0.0
*/
public function load_index_php() {
if ( is_super_admin() ) {
$this->add_action( 'all_admin_notices' );
}
}
/**
* Action handler for 'admin_notices'
* Display the Dashboard notification.
*
* @since 1.0.0
*/
public function all_admin_notices() {
$info = $this->choose_message();
if ( ! $info ) { return; }
$this->render_message( $info );
}
/**
* Check to see if there is a pending message to display and returns
* the message details if there is.
*
* Note that this function is only called on the main Dashboard screen
* and only when logged in as super-admin.
*
* @since 1.0.0
* @return object|false
* string $type [rate|email] Which message type?
* string $plugin WordPress plugin ID?
*/
protected function choose_message() {
$obj = false;
$chosen = false;
$earliest = false;
$now = time();
// The "current" time can be changed via $_GET to test the module.
if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! empty( $_GET['time'] ) ) {
$custom_time = $_GET['time'];
if ( ' ' == $custom_time[0] ) { $custom_time[0] = '+'; }
if ( $custom_time ) { $now = strtotime( $custom_time ); }
if ( ! $now ) { $now = time(); }
}
$tomorrow = $now + DAY_IN_SECONDS;
foreach ( $this->stored['queue'] as $hash => $item ) {
$show_at = intval( $item['show_at'] );
$is_sticky = ! empty( $item['sticky'] );
if ( ! isset( $this->plugins[ $item['plugin'] ] ) ) {
// Deactivated plugin before the message was displayed.
continue;
}
$plugin = $this->plugins[ $item['plugin'] ];
$can_display = true;
if ( wp_is_mobile() ) {
// Do not display rating message on mobile devices.
if ( 'rate' == $item['type'] ) {
$can_display = false;
}
}
if ( 'email' == $item['type'] ) {
if ( ! $plugin->drip_plugin || ! $plugin->cta_email ) {
// Do not display email message with missing email params.
$can_display = false;
}
}
if ( $now < $show_at ) {
// Do not display messages that are not due yet.
$can_display = false;
}
if ( ! $can_display ) { continue; }
if ( $is_sticky ) {
// If sticky item is present then choose it!
$chosen = $hash;
break;
} elseif ( ! $earliest || $earliest < $show_at ) {
$earliest = $show_at;
$chosen = $hash;
// Don't use `break` because a sticky item might follow...
// Find the item with the earliest schedule.
}
}
if ( $chosen ) {
// Make the chosen item sticky.
$this->stored['queue'][$chosen]['sticky'] = true;
// Re-schedule other messages that are due today.
foreach ( $this->stored['queue'] as $hash => $item ) {
$show_at = intval( $item['show_at'] );
if ( empty( $item['sticky'] ) && $tomorrow > $show_at ) {
$this->stored['queue'][$hash]['show_at'] = $tomorrow;
}
}
// Save the changes.
$this->store_data();
$obj = (object) $this->stored['queue'][$chosen];
}
return $obj;
}
/**
* Moves a message from the queue to the done list.
*
* @since 1.0.0
* @param string $plugin Plugin ID.
* @param string $type [rate|email] Message type.
* @param string $state [ok|ignore] Button clicked.
*/
protected function mark_as_done( $plugin, $type, $state ) {
$done_item = false;
foreach ( $this->stored['queue'] as $hash => $item ) {
unset( $this->stored['queue'][$hash]['sticky'] );
if ( $item['plugin'] == $plugin && $item['type'] == $type ) {
$done_item = $item;
unset( $this->stored['queue'][$hash] );
}
}
if ( $done_item ) {
$done_item['state'] = $state;
$done_item['hash'] = $hash;
$done_item['handled_at'] = time();
unset( $done_item['sticky'] );
$this->stored['done'][] = $done_item;
$this->store_data();
}
}
/**
* Renders the actual Notification message.
*
* @since 1.0.0
*/
protected function render_message( $info ) {
$plugin = $this->plugins[$info->plugin];
$css_url = plugin_dir_url( __FILE__ ) . '/admin.css';
$js_url = plugin_dir_url( __FILE__ ) . '/admin.js';
?>
<link rel="stylesheet" type="text/css" href="<?php echo esc_url( $css_url ); ?>" />
<div class="notice frash-notice frash-notice-<?php echo esc_attr( $info->type ); ?>" style="display:none">
<input type="hidden" name="type" value="<?php echo esc_attr( $info->type ); ?>" />
<input type="hidden" name="plugin_id" value="<?php echo esc_attr( $info->plugin ); ?>" />
<input type="hidden" name="url_wp" value="<?php echo esc_attr( $plugin->url_wp ); ?>" />
<input type="hidden" name="drip_plugin" value="<?php echo esc_attr( $plugin->drip_plugin ); ?>" />
<?php
if ( 'email' == $info->type ) {
$this->render_email_message( $plugin );
} elseif ( 'rate' == $info->type ) {
$this->render_rate_message( $plugin );
}
?>
</div>
<script src="<?php echo esc_url( $js_url ); ?>"></script>
<?php
}
/**
* Output the contents of the email message.
* No return value. The code is directly output.
*
* @since 1.0.0
*/
protected function render_email_message( $plugin ) {
$user = wp_get_current_user();
$user_name = $user->display_name;
$admin_email = get_site_option( 'admin_email' );
$msg = __( "We're happy that you've chosen to install %s! Are you interested in how to make the most of this plugin? How would you like a quick 5 day email crash course with actionable advice on building your membership site? Only the info you want, no subscription!", 'wdev_frash' );
$msg = apply_filters( 'wdev-email-message-' . $plugin->id, $msg );
?>
<div class="frash-notice-logo"><span></span></div>
<div class="frash-notice-message">
<?php
printf(
$msg,
'<strong>' . $plugin->title . '</strong>'
);
?>
</div>
<div class="frash-notice-cta">
<input type="email" name="email" value="<?php echo esc_attr( $admin_email ); ?>" />
<button class="frash-notice-act button-primary" data-msg="<?php _e( 'Thanks :)', 'wdev_frash' ); ?>">
<?php echo esc_html( $plugin->cta_email ); ?>
</button>
<button class="frash-notice-dismiss" data-msg="<?php _e( 'Saving', 'wdev_frash' ); ?>">
<?php _e( 'No thanks', 'wdev_frash' ); ?>
</button>
</div>
<?php
}
/**
* Output the contents of the rate-this-plugin message.
* No return value. The code is directly output.
*
* @since 1.0.0
*/
protected function render_rate_message( $plugin ) {
$user = wp_get_current_user();
$user_name = $user->display_name;
$msg = __( "Hey %s, you've been using %s for a while now, and we hope you're happy with it.", 'wdev_frash' ) . '<br />'. __( "We've spent countless hours developing this free plugin for you, and we would really appreciate it if you dropped us a quick rating!", 'wdev_frash' );
$msg = apply_filters( 'wdev-rating-message-' . $plugin->id, $msg );
?>
<div class="frash-notice-logo"><span></span></div>
<div class="frash-notice-message">
<?php
printf(
$msg,
'<strong>' . $user_name . '</strong>',
'<strong>' . $plugin->title . '</strong>'
);
?>
</div>
<div class="frash-notice-cta">
<button class="frash-notice-act button-primary" data-msg="<?php _e( 'Thanks :)', 'wdev_frash' ); ?>">
<?php
printf(
__( 'Rate %s', 'wdev_frash' ),
esc_html( $plugin->title )
); ?>
</button>
<button class="frash-notice-dismiss" data-msg="<?php _e( 'Saving', 'wdev_frash' ); ?>">
<?php _e( 'No thanks', 'wdev_frash' ); ?>
</button>
</div>
<?php
}
/**
* Registers a new action handler. The callback function has the same
* name as the action hook.
*
* @since 1.0.0
*/
protected function add_action( $hook, $params = 1 ) {
$method_name = strtolower( $hook );
$method_name = preg_replace( '/[^a-z0-9]/', '_', $method_name );
$handler = array( $this, $method_name );
add_action( $hook, $handler, 5, $params );
}
}
// Initialize the module.
WDev_Frash::instance();
}