File: /home/firststeps/public_html/wp-content/plugins__/sierotki/includes/iworks/rate/rate.php
<?php
defined( 'ABSPATH' ) || exit; // Exit if accessed directly
/**
* iWorks_Rate - Dashboard Notification module.
*
* @version 2.3.0
* @author iworks (Marcin Pietrzak)
*
*/
if ( ! class_exists( 'iworks_rate' ) ) {
class iworks_rate {
/**
* This class version.
*
* @since 1.0.1
* @var string
*/
private $version = '2.3.0';
/**
* $wpdb->options field name.
*
* @since 1.0.0
* @var string
*/
protected $option_name = 'iworks_rates';
/**
* 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();
/**
* The Plugin ID
*
* @since 2.1.4
* @var string
*/
private $plugin_id;
/**
* Initializes and returns the singleton instance.
*
* @since 1.0.0
*/
public static function instance() {
static $Inst = null;
if ( null === $Inst ) {
$Inst = new iworks_rate();
}
return $Inst;
}
/**
* Set up the iworks_rate module. Private singleton constructor.
*
* @since 1.0.0
*/
private function __construct() {
/**
* settings
*/
$this->stored = wp_parse_args(
get_site_option( $this->option_name, false ),
array()
);
/**
* actions
*/
add_action( 'load-index.php', array( $this, 'load' ) );
add_action( 'iworks-register-plugin', array( $this, 'register' ), 5, 3 );
add_action( 'wp_ajax_iworks_rate_button', array( $this, 'ajax_button' ) );
add_action( 'admin_init', array( $this, 'admin_init' ) );
/**
* own hooks
*/
add_filter( 'iworks_rate_assistance', array( $this, 'filter_get_assistance_widget' ), 10, 2 );
add_filter( 'iworks_rate_love', array( $this, 'filter_get_love_widget' ), 10, 2 );
/**
* advertising
*
* @since 2.1.0
*/
add_filter( 'iworks_rate_advertising_og', array( $this, 'filter_get_advertising_og' ) );
}
/**
* Inicialize admin area
*
* @since 2.0.2
*/
public function admin_init() {
foreach ( $this->plugins as $plugin_file => $plugin ) {
add_filter( 'plugin_action_links_' . $plugin_file, array( $this, 'add_donate_link' ), 10, 4 );
}
}
/**
* Add donate link to plugin_row_meta.
*
* @since 2.0.2
*
* @param array $actions An array of the plugin's metadata, including the version, author, author URI, and plugin URI.
*/
public function add_donate_link( $actions, $plugin_file, $plugin_data, $context ) {
$slug = 'iworks';
if (
isset( $this->plugins[ $plugin_file ] )
&& isset( $this->plugins[ $plugin_file ]['slug'] )
) {
$slug = $this->plugins[ $plugin_file ]['slug'];
}
$settings_page_url = apply_filters( 'iworks_rate_settings_page_url_' . $slug, null );
if ( ! empty( $settings_page_url ) ) {
$actions['settings'] = sprintf(
'<a href="%s">%s</a>',
esc_url( $settings_page_url ),
esc_html__( 'Settings', 'sierotki' )
);
}
$actions['donate'] = sprintf(
'<a href="%s" target="_blank">%s</a>',
esc_url(
add_query_arg(
array(
'utm_source' => $slug,
'utm_medium' => 'plugin-links',
),
'https://ko-fi.com/iworks'
)
),
esc_html__( 'Provide us a coffee', 'sierotki' )
);
return $actions;
}
/**
* Load required hooks and scripts for the admin notice.
*
* @since 2.0.2
*/
public function load() {
/**
* regular message
*/
$plugin_id = $this->choose_plugin();
if ( ! empty( $plugin_id ) ) {
$this->plugin_id = $plugin_id;
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
add_action( 'admin_notices', array( $this, 'show' ) );
return;
}
/**
* anniversary message
*/
$plugin_id = $this->choose_anniversary_plugin();
if ( ! empty( $plugin_id ) ) {
$this->plugin_id = $plugin_id;
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
add_action( 'admin_notices', array( $this, 'show_anniversary' ) );
return;
}
}
/**
* Save persistent module-data to the WP database.
*
* @since 1.0.0
*/
protected function store_data() {
update_site_option( $this->option_name, $this->stored );
}
/**
* Action handler for 'iworks-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 $slug the plugin slug on wp.org
*/
public function register( $plugin_id, $title, $slug ) {
// Ignore incorrectly registered plugins to avoid errors later.
if ( empty( $plugin_id ) || empty( $title ) || empty( $slug ) ) {
return;
}
/**
* collect data
*/
$data = array(
'title' => $title,
'slug' => $slug,
);
/**
* add dat to plugins array
*/
$this->plugins[ $plugin_id ] = $data;
/**
* check for option update
*
* @since 2.0.6
*
*/
$update = false;
/*
* 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[ $plugin_id ] ) ) {
$this->stored[ $plugin_id ] = wp_parse_args(
array(
'registered' => time(),
'show_at' => $this->get_random_future_timestamp( 7, 14 ),
'rated' => 0,
'hide' => 0,
),
$data
);
$update = true;
}
/**
* check slug & mark for update if needed
*
* @since 2.0.6
*/
if ( $this->stored[ $plugin_id ]['slug'] !== $slug ) {
$this->stored[ $plugin_id ]['slug'] = $slug;
$update = true;
}
/**
* check last anniversary days
*
* @since 2.3.0
*/
if ( ! isset( $this->stored[ $plugin_id ]['last_anniversary_days'] ) ) {
$this->stored[ $plugin_id ]['last_anniversary_days'] = floor(
( time() - $this->stored[ $plugin_id ]['registered'] ) / ( 60 * 60 * 24 )
);
$update = true;
}
/**
* check last anniversary
*
* @since 2.3.0
*/
if ( ! isset( $this->stored[ $plugin_id ]['last_anniversary'] ) ) {
$this->stored[ $plugin_id ]['last_anniversary'] = 0;
$update = true;
}
/**
* check title - can be diferent due language
*
* @since 2.0.6
*/
$this->stored[ $plugin_id ]['title'] = $title;
/**
* Finally save the details if it is needed
*/
if ( $update ) {
$this->store_data();
}
}
/**
* Ajax handler called when the user chooses the CTA button.
*
* @since 1.0.0
*/
public function ajax_button() {
/**
* Chekc nonce
*
* @since 2.1.4
*/
if ( ! check_ajax_referer( 'iworks-rate' ) ) {
wp_send_json_error();
}
/**
* get plugin ID
*/
$nonce_value = sanitize_text_field( filter_input( INPUT_POST, '_wpnonce', FILTER_DEFAULT ) );
if ( ! wp_verify_nonce( $nonce_value, 'iworks-rate' ) ) {
wp_send_json_error();
}
$plugin_id = sanitize_text_field( filter_input( INPUT_POST, 'plugin_id', FILTER_DEFAULT ) );
if ( empty( $plugin_id ) ) {
wp_send_json_error();
}
/**
* sanitize plugin_id
*
* @since 2.1.3
*/
$plugin_id = sanitize_text_field( $plugin_id );
if ( ! isset( $this->plugins[ $plugin_id ] ) ) {
wp_send_json_error();
}
/**
* sanitize button value
*
* @since 2.1.3
*/
$value = '';
if ( isset( $_POST['button'] ) ) {
$value = sanitize_text_field( filter_input( INPUT_POST, 'button', FILTER_DEFAULT ) );
}
switch ( $value ) {
case '':
case 'add-review':
$this->add_weeks( $plugin_id );
break;
case 'hide':
$this->add_weeks( $plugin_id );
$this->hide( $plugin_id );
break;
case 'donate':
$this->add_months( $plugin_id );
break;
case 'hide-anniversary':
$this->hide_anniversary( $plugin_id );
break;
}
wp_send_json_success();
}
/**
* Hide the rate notice for a specific plugin.
*
* @since 2.0.0
* @param string $plugin_id The ID of the plugin to hide the notice for.
*/
public function hide( $plugin_id ) {
if ( ! isset( $this->stored[ $plugin_id ] ) ) {
return;
}
$this->stored[ $plugin_id ]['hide'] = time();
$this->store_data();
}
/**
* Hide the anniversary notice for a specific plugin.
*
* @since 2.3.0
* @param string $plugin_id The ID of the plugin to hide the notice for.
*/
public function hide_anniversary( $plugin_id ) {
if ( ! isset( $this->stored[ $plugin_id ] ) ) {
return;
}
++$this->stored[ $plugin_id ]['last_anniversary'];
$this->store_data();
}
/**
* Extend the show_at timestamp by a random number of weeks.
*
* @since 2.0.0
* @param string $plugin_id The ID of the plugin to extend the delay for.
* @access private
*/
private function add_weeks( $plugin_id ) {
if ( ! isset( $this->stored[ $plugin_id ] ) ) {
return;
}
$this->stored[ $plugin_id ]['show_at'] = $this->get_random_future_timestamp( 0, 7, 4, 6 );
$this->store_data();
}
/**
* Extend the show_at timestamp by a random number of months.
*
* @since 2.0.0
* @param string $plugin_id The ID of the plugin to extend the delay for.
* @access private
*/
private function add_months( $plugin_id ) {
if ( ! isset( $this->stored[ $plugin_id ] ) ) {
return;
}
$this->stored[ $plugin_id ]['show_at'] = $this->get_random_future_timestamp( 0, 14, 15, 30 );
$this->store_data();
}
/**
* Ajax handler called when the user chooses the dismiss button.
*
* @since 1.0.0
*/
public function dismiss() {
$plugin = $this->get_plugin_from_post();
if ( is_wp_error( $plugin ) ) {
wp_send_json_error();
}
wp_send_json_success();
}
/**
* Action handler for 'load-index.php'
* Set-up the Dashboard notification.
*
* @since 1.0.0
*/
public function enqueue() {
wp_enqueue_style(
__CLASS__,
plugin_dir_url( __FILE__ ) . 'admin.css',
array(),
$this->version
);
wp_enqueue_script(
__CLASS__,
plugin_dir_url( __FILE__ ) . 'admin.js',
array(),
$this->version,
true
);
}
/**
* Action handler for 'admin_notices'
* Display the Dashboard notification.
*
* @since 1.0.0
*/
public function show() {
$this->render_message( $this->plugin_id );
}
/**
* Action handler for 'admin_notices'
* Display the Dashboard notification.
*
* @since 2.2.0
*/
public function show_anniversary() {
$filename = $this->stored[ $this->plugin_id ]['last_anniversary'] ? 'anniversary' : 'first-year';
$this->render_message( $this->plugin_id, $filename, 'happy-anniversary' );
}
/**
* 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 $plugin WordPress plugin ID?
*/
protected function choose_plugin() {
if ( wp_is_mobile() ) {
return false;
}
/**
* list
*/
$choosen = array();
/**
* change time by filter
*/
$now = intval( apply_filters( 'iworks_rate_set_custom_time', time() ) );
foreach ( $this->stored as $plugin_id => $item ) {
if ( ! isset( $this->plugins[ $plugin_id ] ) ) {
if ( isset( $this->stored[ $plugin_id ] ) ) {
unset( $this->stored[ $plugin_id ] );
$this->store_data();
}
continue;
}
if ( intval( $item['show_at'] ) > $now ) {
continue;
}
if ( YEAR_IN_SECONDS > time() - intval( $item['hide'] ) ) {
continue;
}
$choosen[] = $plugin_id;
}
if ( empty( $choosen ) ) {
return false;
}
return $choosen[ array_rand( $choosen ) ];
}
/**
* Choose a plugin that is eligible for an anniversary rating prompt.
*
* @since 2.2.0
* @access protected
* @return string|false Returns the plugin ID if a matching plugin is found, false otherwise.
*/
protected function choose_anniversary_plugin() {
if ( wp_is_mobile() ) {
return false;
}
/**
* list
*/
$choosen = array();
/**
* change time by filter
*/
$now = intval( apply_filters( 'iworks_rate_set_custom_time', time() ) );
foreach ( $this->stored as $plugin_id => $item ) {
if ( ! isset( $this->plugins[ $plugin_id ] ) ) {
if ( isset( $this->stored[ $plugin_id ] ) ) {
unset( $this->stored[ $plugin_id ] );
$this->store_data();
}
continue;
}
if ( ! isset( $item['last_anniversary_days'] ) ) {
continue;
}
if ( ! isset( $item['last_anniversary'] ) ) {
continue;
}
$anniversary = intval( $item['last_anniversary_days'] / 365 );
if ( $anniversary < $item['last_anniversary'] ) {
continue;
}
$choosen[] = $plugin_id;
}
if ( empty( $choosen ) ) {
return false;
}
return $choosen[ array_rand( $choosen ) ];
}
/**
* Renders the actual Notification message.
*
* @since 1.0.0
*/
protected function render_message( $plugin_id, $filename = 'thanks', $group = '' ) {
$file = $this->get_file( $filename, $group );
$plugin = $this->get_plugin_data_by_plugin_id( $plugin_id );
load_template( $file, true, $plugin );
}
/**
* Get the absolute path to a template file.
*
* @since 2.0.1
* @param string $file The base name of the template file.
* @param string $group Optional. Subdirectory within the templates directory.
* @return string The full path to the template file.
* @access private
*/
private function get_file( $file, $group = '' ) {
return sprintf(
'%s/templates/%s%s%s.php',
__DIR__,
$group,
'' === $group ? '' : '/',
sanitize_title( $file )
);
}
/**
* Get plugin data by its ID.
*
* @since 2.0.1
* @param string $plugin_id The ID of the plugin to get data for.
* @return array|WP_Error Plugin data array or WP_Error on failure.
* @access private
*/
private function get_plugin_data_by_plugin_id( $plugin_id ) {
if ( ! isset( $this->plugins[ $plugin_id ] ) ) {
return new WP_Error(
'no-plugin',
sprintf(
/* translators: %s: plugin id */
esc_html__( 'There is no plugin with id: %s.', 'sierotki' ),
$plugin_id
)
);
}
$plugin = wp_parse_args(
$this->plugins[ $plugin_id ],
$this->stored[ $plugin_id ]
);
$plugin['plugin_id'] = $plugin_id;
$plugin['logo'] = apply_filters( 'iworks_rate_notice_logo_style', '', $plugin );
$plugin['ajax_url'] = admin_url( 'admin-ajax.php' );
$plugin['classes'] = array(
'iworks-rate',
'iworks-rate-' . $plugin['slug'],
'iworks-rate-notice',
);
if ( ! empty( $plugin['logo'] ) ) {
$plugin['classes'][] = 'has-logo';
}
$plugin['url'] = esc_url(
sprintf(
/* translators: %s: plugin slug */
_x( 'https://wordpress.org/plugins/%s', 'plugins home', 'sierotki' ),
$plugin['slug']
)
);
$plugin['support_url'] = esc_url(
sprintf(
/* translators: %s: plugin slug */
_x( 'https://wordpress.org/support/plugin/%s', 'plugins support home', 'sierotki' ),
$plugin['slug']
)
);
/**
* Add utm parameters to donate link.
*
* @since 2.2.0
*
* @param string $donate_url Donate URL.
* @param array $plugin Plugin data.
*/
$plugin['donate_url'] = esc_url(
add_query_arg(
array(
'utm_source' => $plugin['slug'],
'utm_medium' => 'WP-Dashboard',
'utm_campaign' => 'happy-anniversary',
),
'https://ko-fi.com/iworks'
)
);
/**
* Change plugin data.
*
* Allows to change generated plugin data.
*
* @since 2.1.4
*
* @param array $plugin {
* Plugin data.
*
* @type string $plugin_id Plugin ID
* @type string $logo Logo URL
* @type string $ajax_url Admin AJAX URl
* @type array $classes CSS classes
* @type string $url Plugin repository URL
* @type string $support_url Plugin support URL
* }
*/
return apply_filters( 'iworks_rate_plugin_data', $plugin );
}
/**
* Get plugin ID by its slug.
*
* @since 2.0.1
* @param string $slug The plugin slug to search for.
* @return string|WP_Error The plugin ID or WP_Error if not found.
* @access private
*/
private function get_plugin_id_by_slug( $slug ) {
foreach ( $this->stored as $plugin_id => $plugin ) {
if ( $slug === $plugin['slug'] ) {
return $plugin_id;
}
}
return new WP_Error();
}
/**
* Get the URL to install a plugin from the WordPress.org repository.
*
* @since 2.1.0
* @param string $slug The plugin slug to generate install URL for.
* @return string The URL to install the plugin.
* @access private
*/
private function get_install_plugin_url( $slug ) {
return wp_nonce_url(
self_admin_url(
add_query_arg(
array(
'action' => 'install-plugin',
'plugin' => $slug,
),
'update.php'
)
),
'install-plugin_' . $slug
);
}
/**
* Generate a random future timestamp based on days and weeks.
*
* @since 2.1.5
* @param int $day_min Minimum number of days to add.
* @param int $day_max Maximum number of days to add.
* @param int $week_min Minimum number of weeks to add.
* @param int $week_max Maximum number of weeks to add.
* @return int A future timestamp.
* @access private
*/
private function get_random_future_timestamp( $day_min = 0, $day_max = 0, $week_min = 0, $week_max = 0 ) {
$time = time();
/**
* DAY_IN_SECONDS
*/
$days = 0;
if ( 0 < $day_max ) {
$days = $this->rate_rand( $day_min, $day_max );
}
$time += $days * DAY_IN_SECONDS;
/**
* WEEK_IN_SECONDS
*/
$weeks = 0;
if ( 0 < $week_max ) {
$weeks = $this->rate_rand( $week_min, $week_max );
}
$time += $weeks * WEEK_IN_SECONDS;
/**
* returns
*/
return $time;
}
/**
* Generate a random number within a range.
*
* Uses wp_rand() if available, falls back to mt_rand().
*
* @since 2.1.5
* @param int|null $min Lower limit (included).
* @param int|null $max Upper limit (included).
* @return int A random number from the specified range.
* @access private
*/
private function rate_rand( $min = null, $max = null ) {
if ( function_exists( 'wp_rand' ) ) {
return wp_rand( $min, $max );
}
return mt_rand( $min, $max );
}
/**
* Get advertising for "OG — Better Share on Social Media" plugin.
*
* @since 2.1.0
*/
public function filter_get_advertising_og( $data ) {
return array(
'iworks-adverting-og' => array(
'title' => __( 'OpenGraph', 'sierotki' ),
'callback' => array( $this, 'get_advertising_og_content' ),
'context' => 'side',
'priority' => 'low',
),
);
}
/**
* Advertising content for "OG — Better Share on Social Media" plugin.
*
* @since 2.1.0
*/
public function get_advertising_og_content() {
$args = array(
'install_plugin_url' => $this->get_install_plugin_url( 'og' ),
'plugin_name' => __( 'OG — Better Share on Social Media', 'sierotki' ),
'plugin_wp_home' => __( 'https://wordpress.org/plugins/og/', 'sierotki' ),
);
$file = $this->get_file( 'og', 'plugins' );
load_template( $file, true, $args );
}
/**
* @since 2.0.1
*/
public function filter_get_assistance_widget( $content, $slug ) {
$plugin_id = $this->get_plugin_id_by_slug( $slug );
if ( is_wp_error( $plugin_id ) ) {
return $content;
}
$this->enqueue();
$plugin = $this->get_plugin_data_by_plugin_id( $plugin_id );
if ( is_wp_error( $plugin ) ) {
return $content;
}
$file = $this->get_file( 'support', 'widgets' );
ob_start();
load_template( $file, true, $plugin );
$content = ob_get_contents();
ob_end_clean();
return $content;
}
/**
* @since 2.0.1
*/
public function filter_get_love_widget( $content, $slug ) {
$plugin_id = $this->get_plugin_id_by_slug( $slug );
if ( is_wp_error( $plugin_id ) ) {
return $content;
}
$this->enqueue();
$plugin = $this->get_plugin_data_by_plugin_id( $plugin_id );
if ( is_wp_error( $plugin ) ) {
return $content;
}
$file = $this->get_file( 'donate', 'widgets' );
ob_start();
load_template( $file, true, $plugin );
$content = ob_get_contents();
ob_end_clean();
return $content;
}
}
// Initialize the module.
iworks_rate::instance();
}