plugin_slug = $plugin->get_plugin_slug();
$this->plugin_settings = $plugin->get_plugin_settings();
$this->plugin_default_settings = $plugin->default_settings();
$this->plugin_basename = plugin_basename(WPMM_PATH . $this->plugin_slug . '.php');
// Load admin style sheet and JavaScript.
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_styles'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
// Add the options page and menu item.
add_action('admin_menu', array($this, 'add_plugin_menu'));
// Add an action link pointing to the options page
if (is_multisite() && is_plugin_active_for_network($this->plugin_basename)) {
// settings link will point to admin_url of the main blog, not to network_admin_url
add_filter('network_admin_plugin_action_links_' . $this->plugin_basename, array($this, 'add_settings_link'));
} else {
add_filter('plugin_action_links_' . $this->plugin_basename, array($this, 'add_settings_link'));
}
// Add admin notices
add_action('admin_notices', array($this, 'add_notices'));
// Add ajax methods
add_action('wp_ajax_wpmm_subscribers_export', array($this, 'subscribers_export'));
add_action('wp_ajax_wpmm_subscribers_empty_list', array($this, 'subscribers_empty_list'));
add_action('wp_ajax_wpmm_dismiss_notices', array($this, 'dismiss_notices'));
add_action('wp_ajax_wpmm_reset_settings', array($this, 'reset_settings'));
// Add text to footer
add_filter('admin_footer_text', array($this, 'admin_footer_text'), 5);
}
public static function get_instance() {
if (null == self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
/**
* Load CSS files
*
* @since 2.0.0
* @return type
*/
public function enqueue_admin_styles() {
if (!isset($this->plugin_screen_hook_suffix)) {
return;
}
$screen = get_current_screen();
if ($this->plugin_screen_hook_suffix == $screen->id) {
$wp_scripts = wp_scripts();
$ui = $wp_scripts->query('jquery-ui-core');
wp_enqueue_style($this->plugin_slug . '-admin-jquery-ui-styles', '//ajax.googleapis.com/ajax/libs/jqueryui/' . (!empty($ui->ver) ? $ui->ver : '1.11.4') . '/themes/smoothness/jquery-ui' . WPMM_ASSETS_SUFFIX . '.css', array(), WP_Maintenance_Mode::VERSION);
wp_enqueue_style($this->plugin_slug . '-admin-chosen', WPMM_CSS_URL . 'chosen' . WPMM_ASSETS_SUFFIX . '.css', array(), WP_Maintenance_Mode::VERSION);
wp_enqueue_style($this->plugin_slug . '-admin-timepicker-addon-script', WPMM_CSS_URL . 'jquery-ui-timepicker-addon' . WPMM_ASSETS_SUFFIX . '.css', array(), WP_Maintenance_Mode::VERSION);
wp_enqueue_style($this->plugin_slug . '-admin-styles', WPMM_CSS_URL . 'style-admin' . WPMM_ASSETS_SUFFIX . '.css', array('wp-color-picker'), WP_Maintenance_Mode::VERSION);
}
}
/**
* Load JS files and their dependencies
*
* @since 2.0.0
* @return
*/
public function enqueue_admin_scripts() {
if (!isset($this->plugin_screen_hook_suffix)) {
return;
}
$screen = get_current_screen();
if ($this->plugin_screen_hook_suffix == $screen->id) {
wp_enqueue_media();
wp_enqueue_script($this->plugin_slug . '-admin-timepicker-addon-script', WPMM_JS_URL . 'jquery-ui-timepicker-addon' . WPMM_ASSETS_SUFFIX . '.js', array('jquery', 'jquery-ui-datepicker'), WP_Maintenance_Mode::VERSION);
wp_enqueue_script($this->plugin_slug . '-admin-script', WPMM_JS_URL . 'scripts-admin' . WPMM_ASSETS_SUFFIX . '.js', array('jquery', 'wp-color-picker'), WP_Maintenance_Mode::VERSION);
wp_enqueue_script($this->plugin_slug . '-admin-chosen', WPMM_JS_URL . 'chosen.jquery' . WPMM_ASSETS_SUFFIX . '.js', array(), WP_Maintenance_Mode::VERSION);
wp_localize_script($this->plugin_slug . '-admin-script', 'wpmm_vars', array(
'ajax_url' => admin_url('admin-ajax.php'),
'plugin_url' => admin_url('options-general.php?page=' . $this->plugin_slug)
));
}
// For global actions like dismiss notices
wp_enqueue_script($this->plugin_slug . '-admin-global', WPMM_JS_URL . 'scripts-admin-global' . WPMM_ASSETS_SUFFIX . '.js', array('jquery'), WP_Maintenance_Mode::VERSION);
}
/**
* Export subscribers list in CSV format (refactor @ 2.0.4)
*
* @since 2.0.0
* @global object $wpdb
* @throws Exception
*/
public function subscribers_export() {
global $wpdb;
try {
// check capabilities
if (!current_user_can('manage_options')) {
throw new Exception(__('You do not have access to this resource.', $this->plugin_slug));
}
// get subscribers and export
$results = $wpdb->get_results("SELECT email, insert_date FROM {$wpdb->prefix}wpmm_subscribers ORDER BY id_subscriber DESC", ARRAY_A);
if (!empty($results)) {
$filename = 'subscribers-list-' . date('Y-m-d') . '.csv';
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=' . $filename);
$fp = fopen('php://output', 'w');
fputcsv($fp, array('email', 'insert_date'));
foreach ($results as $item) {
fputcsv($fp, $item);
}
fclose($fp);
}
} catch (Exception $ex) {
wp_send_json_error($ex->getMessage());
}
}
/**
* Empty subscribers list
*
* @since 2.0.4
* @global object $wpdb
* @throws Exception
*/
public function subscribers_empty_list() {
global $wpdb;
try {
// check capabilities
if (!current_user_can('manage_options')) {
throw new Exception(__('You do not have access to this resource.', $this->plugin_slug));
}
// delete all subscribers
$wpdb->query("DELETE FROM {$wpdb->prefix}wpmm_subscribers");
wp_send_json_success(sprintf(__('You have %d subscriber(s)', $this->plugin_slug), 0));
} catch (Exception $ex) {
wp_send_json_error($ex->getMessage());
}
}
/**
* Reset settings (refactor @ 2.0.4)
*
* @since 2.0.0
* @throws Exception
*/
public function reset_settings() {
try {
// check capabilities
if (!current_user_can('manage_options')) {
throw new Exception(__('You do not have access to this resource.', $this->plugin_slug));
}
// check nonce existence
if (empty($_POST['_wpnonce'])) {
throw new Exception(__('The nonce field must not be empty.', $this->plugin_slug));
}
// check tab existence
if (empty($_POST['tab'])) {
throw new Exception(__('The tab slug must not be empty.', $this->plugin_slug));
}
// check nonce validation
if (!wp_verify_nonce($_POST['_wpnonce'], 'tab-' . $_POST['tab'])) {
throw new Exception(__('Security check.', $this->plugin_slug));
}
// check existence in plugin default settings
$tab = $_POST['tab'];
if (empty($this->plugin_default_settings[$tab])) {
throw new Exception(__('The tab slug must exist.', $this->plugin_slug));
}
// update options using the default values
$this->plugin_settings[$tab] = $this->plugin_default_settings[$tab];
update_option('wpmm_settings', $this->plugin_settings);
wp_send_json_success();
} catch (Exception $ex) {
wp_send_json_error($ex->getMessage());
}
}
/**
* Add plugin in Settings menu
*
* @since 2.0.0
*/
public function add_plugin_menu() {
$this->plugin_screen_hook_suffix = add_options_page(
__('WP Maintenance Mode', $this->plugin_slug), __('WP Maintenance Mode', $this->plugin_slug), 'manage_options', $this->plugin_slug, array($this, 'display_plugin_settings')
);
}
/**
* Settings page
*
* @since 2.0.0
* @global object $wp_roles
*/
public function display_plugin_settings() {
global $wp_roles;
// save settings
$this->save_plugin_settings();
// show settings
include_once(WPMM_VIEWS_PATH . 'settings.php');
}
/**
* Save settings
*
* @since 2.0.0
*/
public function save_plugin_settings() {
if (!empty($_POST) && !empty($_POST['tab'])) {
if (!wp_verify_nonce($_POST['_wpnonce'], 'tab-' . $_POST['tab'])) {
die(__('Security check.', $this->plugin_slug));
}
// DO SOME SANITIZATIONS
$tab = $_POST['tab'];
switch ($tab) {
case 'general':
$_POST['options']['general']['status'] = (int) $_POST['options']['general']['status'];
if (!empty($_POST['options']['general']['status']) && $_POST['options']['general']['status'] == 1) {
$_POST['options']['general']['status_date'] = date('Y-m-d H:i:s');
}
$_POST['options']['general']['bypass_bots'] = (int) $_POST['options']['general']['bypass_bots'];
$_POST['options']['general']['backend_role'] = !empty($_POST['options']['general']['backend_role']) ? $_POST['options']['general']['backend_role'] : array();
$_POST['options']['general']['frontend_role'] = !empty($_POST['options']['general']['frontend_role']) ? $_POST['options']['general']['frontend_role'] : array();
$_POST['options']['general']['meta_robots'] = (int) $_POST['options']['general']['meta_robots'];
$_POST['options']['general']['redirection'] = esc_url($_POST['options']['general']['redirection']);
if (!empty($_POST['options']['general']['exclude'])) {
$exclude_array = explode("\n", $_POST['options']['general']['exclude']);
// we need to be sure that empty lines will not be saved
$_POST['options']['general']['exclude'] = array_filter(array_map('trim', $exclude_array));
} else {
$_POST['options']['general']['exclude'] = array();
}
$_POST['options']['general']['notice'] = (int) $_POST['options']['general']['notice'];
$_POST['options']['general']['admin_link'] = (int) $_POST['options']['general']['admin_link'];
// delete cache when is already activated, when is activated and when is deactivated
if (
isset($this->plugin_settings['general']['status']) && isset($_POST['options']['general']['status']) &&
(
($this->plugin_settings['general']['status'] == 1 && in_array($_POST['options']['general']['status'], array(0, 1))) ||
($this->plugin_settings['general']['status'] == 0 && $_POST['options']['general']['status'] == 1)
)
) {
$this->delete_cache();
}
break;
case 'design':
$custom_css = array();
// CONTENT & CUSTOM CSS
$_POST['options']['design']['title'] = sanitize_text_field($_POST['options']['design']['title']);
$_POST['options']['design']['heading'] = sanitize_text_field($_POST['options']['design']['heading']);
if (!empty($_POST['options']['design']['heading_color'])) {
$_POST['options']['design']['heading_color'] = sanitize_text_field($_POST['options']['design']['heading_color']);
$custom_css['heading_color'] = '.wrap h1 { color: ' . $_POST['options']['design']['heading_color'] . '; }';
}
add_filter('safe_style_css', array($this, 'add_safe_style_css')); // add before we save
$_POST['options']['design']['text'] = wp_kses_post($_POST['options']['design']['text']);
remove_filter('safe_style_css', array($this, 'add_safe_style_css')); // remove after we save
if (!empty($_POST['options']['design']['text_color'])) {
$_POST['options']['design']['text_color'] = sanitize_text_field($_POST['options']['design']['text_color']);
$custom_css['text_color'] = '.wrap h2 { color: ' . $_POST['options']['design']['text_color'] . '; }';
}
// BACKGROUND & CUSTOM CSS
if (!empty($_POST['options']['design']['bg_type'])) {
$_POST['options']['design']['bg_type'] = sanitize_text_field($_POST['options']['design']['bg_type']);
if ($_POST['options']['design']['bg_type'] == 'color' && !empty($_POST['options']['design']['bg_color'])) {
$_POST['options']['design']['bg_color'] = sanitize_text_field($_POST['options']['design']['bg_color']);
$custom_css['bg_color'] = 'body { background-color: ' . $_POST['options']['design']['bg_color'] . '; }';
}
if ($_POST['options']['design']['bg_type'] == 'custom' && !empty($_POST['options']['design']['bg_custom'])) {
$_POST['options']['design']['bg_custom'] = esc_url($_POST['options']['design']['bg_custom']);
$custom_css['bg_url'] = '.background { background: url(' . $_POST['options']['design']['bg_custom'] . ') no-repeat center top fixed; background-size: cover; }';
}
if ($_POST['options']['design']['bg_type'] == 'predefined' && !empty($_POST['options']['design']['bg_predefined'])) {
$_POST['options']['design']['bg_predefined'] = sanitize_text_field($_POST['options']['design']['bg_predefined']);
$custom_css['bg_url'] = '.background { background: url(' . esc_url(WPMM_URL . 'assets/images/backgrounds/' . $_POST['options']['design']['bg_predefined']) . ') no-repeat center top fixed; background-size: cover; }';
}
}
$_POST['options']['design']['custom_css'] = $custom_css;
// delete cache when is activated
if (!empty($this->plugin_settings['general']['status']) && $this->plugin_settings['general']['status'] == 1) {
$this->delete_cache();
}
break;
case 'modules':
$custom_css = array();
// COUNTDOWN & CUSTOM CSS
$_POST['options']['modules']['countdown_status'] = (int) $_POST['options']['modules']['countdown_status'];
$_POST['options']['modules']['countdown_start'] = sanitize_text_field($_POST['options']['modules']['countdown_start']);
$_POST['options']['modules']['countdown_details'] = array_map('trim', $_POST['options']['modules']['countdown_details']);
$_POST['options']['modules']['countdown_details']['days'] = isset($_POST['options']['modules']['countdown_details']['days']) && is_numeric($_POST['options']['modules']['countdown_details']['days']) ? $_POST['options']['modules']['countdown_details']['days'] : 0;
$_POST['options']['modules']['countdown_details']['hours'] = isset($_POST['options']['modules']['countdown_details']['hours']) && is_numeric($_POST['options']['modules']['countdown_details']['hours']) ? $_POST['options']['modules']['countdown_details']['hours'] : 1;
$_POST['options']['modules']['countdown_details']['minutes'] = isset($_POST['options']['modules']['countdown_details']['minutes']) && is_numeric($_POST['options']['modules']['countdown_details']['minutes']) ? $_POST['options']['modules']['countdown_details']['minutes'] : 0;
if (!empty($_POST['options']['modules']['countdown_color'])) {
$_POST['options']['modules']['countdown_color'] = sanitize_text_field($_POST['options']['modules']['countdown_color']);
$custom_css['countdown_color'] = '.wrap .countdown span { color: ' . $_POST['options']['modules']['countdown_color'] . '; }';
}
// SUBSCRIBE & CUSTOM CSS
$_POST['options']['modules']['subscribe_status'] = (int) $_POST['options']['modules']['subscribe_status'];
$_POST['options']['modules']['subscribe_text'] = sanitize_text_field($_POST['options']['modules']['subscribe_text']);
if (!empty($_POST['options']['modules']['subscribe_text_color'])) {
$_POST['options']['modules']['subscribe_text_color'] = sanitize_text_field($_POST['options']['modules']['subscribe_text_color']);
$custom_css['subscribe_text_color'] = '.wrap h3, .wrap .subscribe_wrapper { color: ' . $_POST['options']['modules']['subscribe_text_color'] . '; }';
}
// SOCIAL NETWORKS
$_POST['options']['modules']['social_status'] = (int) $_POST['options']['modules']['social_status'];
$_POST['options']['modules']['social_target'] = (int) $_POST['options']['modules']['social_target'];
$_POST['options']['modules']['social_github'] = sanitize_text_field($_POST['options']['modules']['social_github']);
$_POST['options']['modules']['social_dribbble'] = sanitize_text_field($_POST['options']['modules']['social_dribbble']);
$_POST['options']['modules']['social_twitter'] = sanitize_text_field($_POST['options']['modules']['social_twitter']);
$_POST['options']['modules']['social_facebook'] = sanitize_text_field($_POST['options']['modules']['social_facebook']);
$_POST['options']['modules']['social_pinterest'] = sanitize_text_field($_POST['options']['modules']['social_pinterest']);
$_POST['options']['modules']['social_google+'] = sanitize_text_field($_POST['options']['modules']['social_google+']);
$_POST['options']['modules']['social_linkedin'] = sanitize_text_field($_POST['options']['modules']['social_linkedin']);
// CONTACT
$_POST['options']['modules']['contact_status'] = (int) $_POST['options']['modules']['contact_status'];
$_POST['options']['modules']['contact_email'] = sanitize_text_field($_POST['options']['modules']['contact_email']);
$_POST['options']['modules']['contact_effects'] = sanitize_text_field($_POST['options']['modules']['contact_effects']);
// GOOGLE ANALYTICS
$_POST['options']['modules']['ga_status'] = (int) $_POST['options']['modules']['ga_status'];
$_POST['options']['modules']['ga_code'] = wpmm_sanitize_ga_code($_POST['options']['modules']['ga_code']);
$_POST['options']['modules']['custom_css'] = $custom_css;
// delete cache when is activated
if (!empty($this->plugin_settings['general']['status']) && $this->plugin_settings['general']['status'] == 1) {
$this->delete_cache();
}
break;
}
$this->plugin_settings[$tab] = $_POST['options'][$tab];
update_option('wpmm_settings', $this->plugin_settings);
}
}
/**
* Add new safe inline style css (use by wp_kses_attr in wp_kses_post)
* - bug discovered by cokemorgan: https://github.com/Designmodocom/WP-Maintenance-Mode/issues/56
*
* @since 2.0.3
* @param array $properties
* @return array
*/
public function add_safe_style_css($properties) {
$new_properties = array(
'min-height',
'max-height',
'min-width',
'max-width'
);
return array_merge($new_properties, $properties);
}
/**
* Delete cache if any cache plugin (wp_cache or w3tc) is activated
*
* @since 2.0.1
*/
public function delete_cache() {
// Super Cache Plugin
if (function_exists('wp_cache_clear_cache')) {
wp_cache_clear_cache(is_multisite() && is_plugin_active_for_network($this->plugin_basename) ? get_current_blog_id() : '');
}
// W3 Total Cache Plugin
if (function_exists('w3tc_pgcache_flush')) {
w3tc_pgcache_flush();
}
}
/**
* Add settings link
*
* @since 2.0.0
* @param array $links
* @return array
*/
public function add_settings_link($links) {
return array_merge(
array(
'wpmm_settings' => '' . __('Settings', $this->plugin_slug) . ''
), $links
);
}
/**
* Add notices - will be displayed on dashboard
*
* @since 2.0.0
*/
public function add_notices() {
$screen = get_current_screen();
$notices = array();
if ($this->plugin_screen_hook_suffix != $screen->id) {
// notice if plugin is activated
if ($this->plugin_settings['general']['status'] == 1 && $this->plugin_settings['general']['notice'] == 1) {
$notices['is_activated'] = array(
'class' => 'error',
'msg' => sprintf(__('The Maintenance Mode is active. Please don\'t forget to deactivate as soon as you are done.', $this->plugin_slug), admin_url('options-general.php?page=' . $this->plugin_slug))
);
}
// show notice if plugin has a notice saved
$wpmm_notice = get_option('wpmm_notice');
if (!empty($wpmm_notice) && is_array($wpmm_notice)) {
$notices['other'] = $wpmm_notice;
}
} else {
// delete wpmm_notice
delete_option('wpmm_notice');
// notice promo for codepad
ob_start();
include_once(WPMM_VIEWS_PATH . 'promo-strictthemes.php');
$notices['promo-strictthemes'] = array(
'class' => 'wpmm_notices updated notice is-dismissible',
'msg' => ob_get_clean()
);
}
// get dismissed notices
$dismissed_notices = $this->get_dismissed_notices(get_current_user_id());
// template
include_once(WPMM_VIEWS_PATH . 'notice.php');
}
/**
* Dismiss plugin notices via AJAX
*
* @throws Exception
*/
public function dismiss_notices() {
try {
if (empty($_POST['notice_key'])) {
throw new Exception(__('Notice key cannot be empty.', $this->plugin_slug));
}
// save new notice key
$notice_key = sanitize_text_field($_POST['notice_key']);
$this->save_dismissed_notices(get_current_user_id(), $notice_key);
wp_send_json_success();
} catch (Exception $ex) {
wp_send_json_error($ex->getMessage());
}
}
/**
* Get dismissed notices
*
* @param int $user_id
* @return array
*/
public function get_dismissed_notices($user_id) {
$dismissed_notices = get_user_meta($user_id, $this->dismissed_notices_key, true);
return array_filter(explode(',', $dismissed_notices), 'trim');
}
/**
* Save dismissed notices
* - save as string because of http://wordpress.stackexchange.com/questions/13353/problem-storing-arrays-with-update-user-meta
*
* @param int $user_id
* @param string $notice_key
*/
public function save_dismissed_notices($user_id, $notice_key) {
$dismissed_notices = $this->get_dismissed_notices($user_id);
$dismissed_notices[] = $notice_key;
update_user_meta($user_id, $this->dismissed_notices_key, implode(',', $dismissed_notices));
}
/**
* Display custom text on plugin settings page
*
* @param string $text
*/
public function admin_footer_text($text) {
$screen = get_current_screen();
if ($this->plugin_screen_hook_suffix == $screen->id) {
$text = sprintf(__('If you like WP Maintenance Mode please leave us a %s rating. A huge thank you from WP Maintenance Mode makers in advance!', $this->plugin_slug), '★★★★★');
}
return $text;
}
}
}