Download all files FTP
This commit is contained in:
@@ -0,0 +1,759 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Easy Updates Manager admin controller.
|
||||
* Initializes the admin panel options and load the admin dependencies
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class MPSUM_Admin {
|
||||
|
||||
/**
|
||||
* Holds the class instance.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
* @var MPSUM_Admin $instance
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Holds the URL to the admin panel page
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
* @var string $url
|
||||
*/
|
||||
private static $url = '';
|
||||
|
||||
/**
|
||||
* Holds the slug to the admin panel page
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
* @var string $slug
|
||||
*/
|
||||
private static $slug = 'mpsum-update-options';
|
||||
|
||||
/**
|
||||
* Set a class instance.
|
||||
*
|
||||
* Set a class instance.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
*/
|
||||
public static function run() {
|
||||
if (null == self::$instance) {
|
||||
self::$instance = new self;
|
||||
}
|
||||
return self::$instance;
|
||||
} //end get_instance
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function __construct() {
|
||||
add_action('init', array( $this, 'init' ), 9);
|
||||
add_filter('set-screen-option', array( $this, 'add_screen_option_save' ), 10, 3);
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Save the screen options.
|
||||
*
|
||||
* @since 6.2.0
|
||||
* @param string $status Screen option status
|
||||
* @param string $option Screen option
|
||||
* @param string $value Screen value
|
||||
* @return string Returns value if succeeds, otherwise status
|
||||
*/
|
||||
public function add_screen_option_save( $status, $option, $value ) {
|
||||
return MPSUM_Admin_Screen_Options::save_options($status, $option, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URL to the admin panel page.
|
||||
*
|
||||
* Return the URL to the admin panel page.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
*
|
||||
* @return string URL to the admin panel page.
|
||||
*/
|
||||
public static function get_url() {
|
||||
$url = self::$url;
|
||||
if (empty($url)) {
|
||||
if (is_multisite()) {
|
||||
$url = add_query_arg(array( 'page' => self::get_slug() ), network_admin_url('index.php'));
|
||||
} else {
|
||||
$url = add_query_arg(array( 'page' => self::get_slug() ), admin_url('index.php'));
|
||||
}
|
||||
self::$url = $url;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the slug for the admin panel page.
|
||||
*
|
||||
* Return the slug for the admin panel page.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
*
|
||||
* @return string slug to the admin panel page.
|
||||
*/
|
||||
public static function get_slug() {
|
||||
return self::$slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the admin menu.
|
||||
*
|
||||
* Initialize the admin menu.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal Uses init action
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
// Plugin and Theme actions
|
||||
if (is_multisite()) {
|
||||
add_action('network_admin_menu', array($this, 'init_network_admin_menus'));
|
||||
add_action('wp_before_admin_bar_render', array($this, 'add_networkadmin_page'));
|
||||
} else {
|
||||
add_action('admin_menu', array($this, 'init_single_site_admin_menus'));
|
||||
}
|
||||
add_action('admin_bar_menu', array($this, 'add_admin_bar'), 100);
|
||||
|
||||
// Disable information bar in modal popup
|
||||
add_action('admin_head', array($this, 'maybe_disable_plugin_information_bar'));
|
||||
|
||||
// todo - maybe load these conditionally based on $_REQUEST[ 'tab' ] param
|
||||
new MPSUM_Admin_Dashboard(self::get_slug());
|
||||
new MPSUM_Admin_Plugins(self::get_slug());
|
||||
new MPSUM_Admin_Themes(self::get_slug());
|
||||
new MPSUM_Admin_Logs(self::get_slug());
|
||||
new MPSUM_Admin_Core(self::get_slug());
|
||||
new MPSUM_Admin_Advanced(self::get_slug());
|
||||
if (!Easy_Updates_Manager()->is_premium()) {
|
||||
new MPSUM_Advanced_Premium();
|
||||
}
|
||||
|
||||
MPSUM_Admin_Screen_Options::maybe_save_dashboard_screen_option();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the help screen.
|
||||
*
|
||||
* Initializes the help screen.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see init
|
||||
* @internal Uses load_{$hook} action
|
||||
*/
|
||||
public function init_help_screen() {
|
||||
new MPSUM_Admin_Help();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the screen options.
|
||||
*
|
||||
* Initializes the screen options.
|
||||
*
|
||||
* @since 6.2
|
||||
* @access public
|
||||
* @see init
|
||||
* @internal Uses load_{$hook} action
|
||||
*/
|
||||
public function init_screen_options() {
|
||||
MPSUM_Admin_Screen_Options::run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted array of EUM options
|
||||
*
|
||||
* Returns formatted array of EUM options.
|
||||
*
|
||||
* @since 6.3
|
||||
* @access public
|
||||
*
|
||||
* @return array EUM implementation options
|
||||
*/
|
||||
private function get_options_for_default() {
|
||||
$options = MPSUM_Updates_Manager::get_options();
|
||||
if (! isset($options['core'])) {
|
||||
$options['core'] = MPSUM_Admin_Core::get_defaults();
|
||||
}
|
||||
if (! isset($options['plugins'])) {
|
||||
$options['plugins'] = array();
|
||||
}
|
||||
if (! isset($options['themes'])) {
|
||||
$options['themes'] = array();
|
||||
}
|
||||
if (! isset($options['plugins_automatic'])) {
|
||||
$options['plugins_automatic'] = array();
|
||||
}
|
||||
if (! isset($options['themes_automatic'])) {
|
||||
$options['themes_automatic'] = array();
|
||||
}
|
||||
if (!isset($options['logs'])) {
|
||||
$options['logs'] = array();
|
||||
}
|
||||
if (!isset($options['advanced'])) {
|
||||
$options['advanced'] = array();
|
||||
}
|
||||
|
||||
return $options;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* When more details modal pops up, maybe disable the footer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_disable_plugin_information_bar() {
|
||||
|
||||
// When the more details modal shows up on the plugins tab, it displays an information footer for active
|
||||
// or inactive installs. It also shows when a plugin is available to update.
|
||||
// This will inject styles into the modal hiding the information bar to prevent
|
||||
// any kind of confusion.
|
||||
if (isset($_GET['eum_action']) && 'EUM_modal' === $_GET['eum_action'] && isset($_GET['_wpnonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'eum-modal')) {
|
||||
echo '<style>#plugin-information-footer{display:none;}</style>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
|
||||
// Get active page and active tab fore enqueuing
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- It gets the page and checks for the active tab.
|
||||
$pagenow = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : false;
|
||||
$is_active_tab = isset($_GET['tab']) ? sanitize_text_field(wp_unslash($_GET['tab'])) : false;
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
// Check to make sure we're on the mpsum admin page
|
||||
if ('mpsum-update-options' != $pagenow) {
|
||||
return;
|
||||
}
|
||||
$min_or_not = ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) ? '' : '.min';
|
||||
|
||||
// Get user data
|
||||
$user_id = get_current_user_id();
|
||||
$dashboard_showing = get_user_meta($user_id, 'mpsum_dashboard', true);
|
||||
|
||||
// Get options
|
||||
$options = MPSUM_Updates_Manager::get_options('core');
|
||||
|
||||
// Modal dependencies on the plugins and logs tab
|
||||
if ('plugins' === $is_active_tab) {
|
||||
wp_enqueue_script('plugin-install');
|
||||
wp_enqueue_script('updates');
|
||||
}
|
||||
if ('plugins' === $is_active_tab || 'logs' === $is_active_tab) {
|
||||
wp_enqueue_script('common');
|
||||
wp_enqueue_style('common');
|
||||
wp_enqueue_script('thickbox');
|
||||
wp_enqueue_style('thickbox');
|
||||
}
|
||||
|
||||
$file_path = "includes/blockui/jquery.blockUI$min_or_not";
|
||||
wp_enqueue_script('jquery-blockui', MPSUM_Updates_Manager::get_plugin_url("/$file_path.js"), array('jquery'), (int) filemtime(MPSUM_Updates_Manager::get_plugin_dir("$file_path.js")), true);
|
||||
$file_path = "js/jquery.serializejson$min_or_not";
|
||||
wp_enqueue_script('jquery-serializejson', MPSUM_Updates_Manager::get_plugin_url("/$file_path.js"), array('jquery'), (int) filemtime(MPSUM_Updates_Manager::get_plugin_dir("$file_path.js")), true);
|
||||
$file_path = "js/eum-admin$min_or_not";
|
||||
wp_enqueue_script('mpsum_dashboard_js', MPSUM_Updates_Manager::get_plugin_url("/$file_path.js"), array( 'jquery', 'wp-ajax-response' ), (int) filemtime(MPSUM_Updates_Manager::get_plugin_dir("$file_path.js")), true);
|
||||
$file_path = "js/admin$min_or_not";
|
||||
wp_enqueue_script('mpsum_dashboard_react', MPSUM_Updates_Manager::get_plugin_url("/$file_path.js"), array( 'jquery', 'mpsum_dashboard_js' ), (int) filemtime(MPSUM_Updates_Manager::get_plugin_dir("$file_path.js")), true);
|
||||
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$dashboard_showing = get_user_meta($user_id, 'mpsum_dashboard', true);
|
||||
if (! $dashboard_showing) {
|
||||
$dashboard_showing = 'on';
|
||||
}
|
||||
|
||||
$options = MPSUM_Updates_Manager::get_options();
|
||||
|
||||
$I18N = array(
|
||||
'default' => _x('Default', 'Option as default', 'stops-core-theme-and-plugin-updates'),
|
||||
'on' => _x('On', 'Option enabled', 'stops-core-theme-and-plugin-updates'),
|
||||
'off' => _x('Off', 'Option disabled', 'stops-core-theme-and-plugin-updates'),
|
||||
'nothing' => __('Nothing', 'stops-core-theme-and-plugin-updates'),
|
||||
'everything' => __('Everything', 'stops-core-theme-and-plugin-updates'),
|
||||
'custom' => _x('Custom', 'Option allows for configuration', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_on' => __('Auto update everything', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_off' => __('Disable auto updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_custom_tooltip' => __('Customize each option individually', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_default' => __('WordPress default settings', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_default_tooltip' => __('WordPress acts like this plugin is not installed.', 'stops-core-theme-and-plugin-updates').' '.__('Only minor core updates, translations, and severe security patches will be automatically updated.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_off_tooltip' => __('No automatic updates should occur.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_default_status' => __('You have selected default.', 'stops-core-theme-and-plugin-updates').' '.__('WordPress will behave as if this plugin is not installed for automatic updates.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_on_status' => __('Automatic updates are on for everything.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_on_tooltip' => __('Auto update everything.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_off_status' => __('Automatic updates are off for everything.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_custom_status' => __('You have selected to customize the updates below.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates' => __('Quick configuration actions', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_updates_description' => __('Press a button below for quick configuration; this is a quick way to change several other settings below in one go.', 'stops-core-theme-and-plugin-updates'),
|
||||
'major_releases' => __('Major WordPress releases', 'stops-core-theme-and-plugin-updates'),
|
||||
'major_releases_description' => __('Automatically update to new major releases of WordPress (e.g., 4.1, 4.2, 4.3).', 'stops-core-theme-and-plugin-updates'),
|
||||
'major_releases_label_on' => __('Enable major releases', 'stops-core-theme-and-plugin-updates'),
|
||||
'major_releases_label_on_status' => __('Automatic major release updates are now turned on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'major_releases_label_off' => __('Disable major releases', 'stops-core-theme-and-plugin-updates'),
|
||||
'major_releases_label_off_status' => __('Automatic major release updates are now turned off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'minor_releases' => _x('Minor WordPress releases', 'Minor releases for WordPress', 'stops-core-theme-and-plugin-updates'),
|
||||
'minor_releases_description' => __('Automatically update to new minor releases in your current series (e.g., 4.1.1, 4.1.2, 4.1.3).', 'stops-core-theme-and-plugin-updates'),
|
||||
'minor_releases_label_on' => __('Enable minor releases', 'stops-core-theme-and-plugin-updates'),
|
||||
'minor_releases_label_on_status' => __('Automatic minor release updates are now turned on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'minor_releases_label_off' => __('Disable minor releases', 'stops-core-theme-and-plugin-updates'),
|
||||
'minor_releases_label_off_status' => __('Automatic minor release updates are now turned off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'development_releases' => _x('Development updates (Core)', 'Beta and RC releases for WordPress core', 'stops-core-theme-and-plugin-updates'),
|
||||
'development_releases_description' => __('Allow your install to receive development updates for WordPress core (for advanced users only)', 'stops-core-theme-and-plugin-updates'),
|
||||
'development_releases_label_on' => __('Allow development versions to be replaced with a new minor/major version', 'stops-core-theme-and-plugin-updates'),
|
||||
'development_releases_label_on_status' => __('Automatic development release updates are now turned on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'development_releases_label_off' => __('Disable development updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'development_releases_label_off_status' => __('Automatic development release updates are now turned off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_releases' => _x('Translation updates', 'Enable or disable translation updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_releases_description' => __('Automatically update your translations.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_releases_label_on' => __('Enable translation updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_releases_label_on_status' => __('Automatic translation updates are now turned on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_releases_label_off' => __('Disable translation updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_releases_label_off_status' => __('Automatic translation updates are now turned off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'select_individually' => __('Select individually', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_plugin_updates' => __('Automatic plugin updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_plugin_updates_description' => __('Automatically update your plugins.', 'stops-core-theme-and-plugin-updates').' '.__('Select always on, always off, the WordPress default, or select plugins individually using the plugins tab.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_plugin_updates_default_status' => __('Automatic updates for plugins are now at their default setting (default is off).', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_plugin_updates_on_status' => __('Automatic updates for plugins are now on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_plugin_updates_off_status' => __('Automatic updates for plugins are now off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_plugin_updates_individual_status' => __('Automatic updates for plugins can be customized in the plugins tab.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_theme_updates' => __('Automatic theme updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_theme_updates_description' => __('Automatically update your themes.', 'stops-core-theme-and-plugin-updates').' '.__('Select always on, always off, the WordPress default, or select themes individually using the themes tab.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_theme_updates_default_status' => __('Automatic updates for themes are now at their default setting (default is off).', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_theme_updates_on_status' => __('Automatic updates for themes are now on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_theme_updates_off_status' => __('Automatic updates for themes are now off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'automatic_theme_updates_individual_status' => __('Automatic updates for themes can be customized in the themes tab.', 'stops-core-theme-and-plugin-updates'),
|
||||
'disable_updates' => __('Disable all updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'disable_updates_description' => __('This is a master switch and will enable or disable updates for the WordPress installation.', 'stops-core-theme-and-plugin-updates').' '.__('Switching updates off is not recommended.', 'stops-core-theme-and-plugin-updates'),
|
||||
'disable_updates_label_on' => __('Enable all updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'disable_updates_label_on_status' => __('Updates are allowed; however, you still need to configure the updates below.', 'stops-core-theme-and-plugin-updates'),
|
||||
'disable_updates_label_off' => __('Disable all updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'disable_updates_label_off_status' => __('All updates are disabled.', 'stops-core-theme-and-plugin-updates').' '.__('Individual updates settings (i.e. for automatic updates and for plugin/theme/translation updates) below will be ignored.', 'stops-core-theme-and-plugin-updates'),
|
||||
'logs' => _x('Logs', 'Log what is stored when assets update', 'stops-core-theme-and-plugin-updates'),
|
||||
'logs_description' => __('Logs will show you what assets have updated and will show up in the logs tab.', 'stops-core-theme-and-plugin-updates'),
|
||||
'logs_url' => sprintf('<a href="%s" class="%s" id="%s">%s</a>', esc_url(add_query_arg(array('tab' => 'logs'), MPSUM_Admin::get_url())), 'nav-tab', 'eum-logs', esc_html__('Logs', 'stops-core-theme-and-plugin-updates')),
|
||||
'logs_label_on' => __('Enable logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'logs_label_on_status' => __('Logs are enabled.', 'stops-core-theme-and-plugin-updates').' '.__('You will find logs in the logs tab.', 'stops-core-theme-and-plugin-updates'),
|
||||
'logs_label_off' => __('Disable logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'logs_label_off_status' => __('Logs are disabled.', 'stops-core-theme-and-plugin-updates'),
|
||||
'ratings_nag' => _x('Please give us a rating', 'Asks a user to give a rating for the plugin.', 'stops-core-theme-and-plugin-updates'),
|
||||
'ratings_nag_description' => __('We work very hard on this plugin.', 'stops-core-theme-and-plugin-updates').' '.__('Please show your appreciation and rate the plugin as you see fit.', 'stops-core-theme-and-plugin-updates'),
|
||||
'ratings_nag_label_on' => __('Rate the plugin on WordPress.org', 'stops-core-theme-and-plugin-updates'),
|
||||
'ratings_nag_label_off' => __('I have already left a rating', 'stops-core-theme-and-plugin-updates'),
|
||||
'emails' => __('Notification e-mails', 'stops-core-theme-and-plugin-updates'),
|
||||
'emails_description' => __('This plugin periodically sends update notification e-mails, such as in the case of automatic updates.', 'stops-core-theme-and-plugin-updates').' '.__('By default, the e-mail address used is the one in Settings->General, but you can override this below.', 'stops-core-theme-and-plugin-updates'),
|
||||
'emails_placeholder' => __('Add an e-mail address', 'stops-core-theme-and-plugin-updates'),
|
||||
'emails_input_label' => __('Enter comma-separated e-mail addresses', 'stops-core-theme-and-plugin-updates'),
|
||||
'emails_invalid' => __('One or more e-mail addresses are invalid.', 'stops-core-theme-and-plugin-updates'),
|
||||
'emails_saveed' => __('Your e-mail address settings have been successfully saved.', 'stops-core-theme-and-plugin-updates'),
|
||||
'emails_save' => __('Save e-mail addresses', 'stops-core-theme-and-plugin-updates'),
|
||||
'emails_save_empty' => __('Please enter an e-mail address', 'stops-core-theme-and-plugin-updates'),
|
||||
'emails_saving' => __('Saving...', 'stops-core-theme-and-plugin-updates'),
|
||||
'auto_updates_notification_label' => __('Automatic updates notification e-mails', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_auto_updates_notification_description' => __('Be notified when WordPress core files are updated.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_auto_notification_emails_off_status' => __('Notifications for automatic core update are now off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_auto_notification_emails_on_status' => __('Notifications for automatic core update are now on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_auto_updates_notification_description' => __('Be notified when a plugin automatically updates.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_auto_notification_emails_off_status' => __('Notifications for automatic plugin updates are now off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_auto_notification_emails_on_status' => __('Notifications for automatic plugin updates are now on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_auto_updates_notification_description' => __('Be notified when a theme automatically updates.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_auto_notification_emails_off_status' => __('Notifications for automatic theme updates are now off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_auto_notification_emails_on_status' => __('Notifications for automatic theme updates are now on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_auto_updates_notification_description' => __('Be notified when a translation automatically updates.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_auto_notification_emails_off_status' => __('Notifications for automatic translation updates are now off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_auto_notification_emails_on_status' => __('Notifications for automatic translation updates are now on.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates' => __('WordPress core updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_description' => __('This allows you to configure how WordPress updates are handled, including automatic updates.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_on' => __('Manually update', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_on_tooltip' => __('Update WordPress manually through the updates screen and turn off all automatic updates for WordPress core.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_on_status' => __('Core updates are set to manual.', 'stops-core-theme-and-plugin-updates').' '.__('Update WordPress from the updates screen.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_off' => __('Disable core updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_off_tooltip' => __('Turn off all core WordPress updates and prevent update notices from being shown.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_automatic' => __('Auto update all releases', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_automatic_tooltip' => __('Update WordPress core and minor versions automatically.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_automatic_minor' => __('Auto update all minor versions', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_automatic_minor_tooltip' => __('Default behavior.', 'stops-core-theme-and-plugin-updates').' '.__('WordPress will automatically update minor versions.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_automatic_status' => __('Choose how to automatically update WordPress.', 'stops-core-theme-and-plugin-updates'),
|
||||
'core_updates_label_off_status' => __('Core updates are disabled and will not show up on the updates screen.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates' => __('Plugin updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_description' => __('This allows you to disable or enable all plugin updates, including automatic updates.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_on' => __('Manually update', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_on_tooltip' => __('Manually update your plugins.', 'stops-core-theme-and-plugin-updates').' '.__('Some auto updates may still occur such as security patches.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_on_status' => __('Plugin updates are enabled.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_off' => __('Disable plugin updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_off_tooltip' => __('Turn off all plugin updates and prevent update notices from being shown.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_automatic' => __('Enable auto updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_automatic_tooltip' => __('Automatically upgrade all plugins.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_auto_disabled' => __('Disable auto updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_auto_disabled_tooltip' => __('Turn off automatic updates for plugins.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_individually' => __('Choose per plugin', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_individually_tooltip' => __('Select which plugins receive automatic updates in the plugins tab.', 'stops-core-theme-and-plugin-updates'),
|
||||
'plugin_updates_label_off_status' => __('Plugin updates are disabled.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates' => __('Theme updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_description' => __('This allows you to disable or enable all theme updates.', 'stops-core-theme-and-plugin-updates').' '.__('Disabling this option will also disable automatic updates.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_on' => __('Manually update', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_on_tooltip' => __('Manually update your themes.', 'stops-core-theme-and-plugin-updates').' '.__('Some auto updates may still occur such as security patches.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_on_status' => __('Theme updates are enabled.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_off' => __('Disable theme updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_off_tooltip' => __('Turn off all theme updates and prevent update notices from being shown.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_off_status' => __('Theme updates are disabled.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_automatic' => __('Enable auto updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_automatic_tooltip' => __('Enable automatic updates for all themes.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_auto_disabled' => __('Disable auto updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_auto_disabled_tooltip' => __('Turn off automatic updates for themes.', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_individually' => __('Choose per theme', 'stops-core-theme-and-plugin-updates'),
|
||||
'theme_updates_label_individually_tooltip' => __('Select which themes receive automatic updates in the themes tab.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates' => __('Translation updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates_description' => __('This allows you to disable or enable all translations.', 'stops-core-theme-and-plugin-updates').' '.__('Choose automatic to automatically update your translations.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates_label_on' => __('Manually update', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates_label_on_tooltip' => __('Manually update your translations and receive periodic translations from the WordPress automatic update component.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates_label_on_status' => __('Translation updates are enabled.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates_label_off' => __('Disable translation updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates_label_off_tooltip' => __('Turn off all translation updates and prevent update notices from being shown.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates_label_automatic' => __('Enable auto updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates_automatic_tooltip' => __('Automatically update all translations as they are ready.', 'stops-core-theme-and-plugin-updates'),
|
||||
'translation_updates_label_off_status' => __('Translation updates are disabled.', 'stops-core-theme-and-plugin-updates'),
|
||||
'general_section_title_updates_settings' => __('Updates settings', 'stops-core-theme-and-plugin-updates'),
|
||||
'general_section_title_notifications' => __('Notifications', 'stops-core-theme-and-plugin-updates'),
|
||||
'general_section_title_others' => __('Others', 'stops-core-theme-and-plugin-updates'),
|
||||
'general_section_title_rating' => __('Rating', 'stops-core-theme-and-plugin-updates'),
|
||||
'rollback_updates_notification_label' => __('Updates rollback notification e-mails', 'stops-core-theme-and-plugin-updates'),
|
||||
'rollback_updates_notification_description' => __('Be notified when there are problematic plugins, which updates cause a fatal PHP error.', 'stops-core-theme-and-plugin-updates'),
|
||||
'rollback_updates_notification_emails_off_status' => __('E-mail notifications for problematic plugins are now off.', 'stops-core-theme-and-plugin-updates'),
|
||||
'rollback_updates_notification_emails_on_status' => __('E-mail notifications for problematic plugins are now on.', 'stops-core-theme-and-plugin-updates'),
|
||||
);
|
||||
|
||||
// Show the ratings? Based on a constant and a default option that a user can select.
|
||||
$maybe_show_ratings_nag = 'on';
|
||||
if (isset($options['core']['ratings_nag'])) {
|
||||
$maybe_show_ratings_nag = $options['core']['ratings_nag'];
|
||||
}
|
||||
if (defined('EUM_ENABLE_RATINGS_NAG') && !EUM_ENABLE_RATINGS_NAG) {
|
||||
$maybe_show_ratings_nag = 'off';
|
||||
}
|
||||
|
||||
wp_localize_script('mpsum_dashboard_react', 'mpsum', apply_filters('eum_i18n', array(
|
||||
'spinner' => MPSUM_Updates_Manager::get_plugin_url('/images/spinner.gif'),
|
||||
'tabs' => _x('Tabs', 'Show or hide admin tabs', 'stops-core-theme-and-plugin-updates'),
|
||||
'dashboard' => _x('Show dashboard', 'Show or hide the dashboard', 'stops-core-theme-and-plugin-updates'),
|
||||
'dashboard_showing' => $dashboard_showing,
|
||||
'enabled' => __('Enabled', 'stops-core-theme-and-plugin-updates'),
|
||||
'disabled' => __('Disabled', 'stops-core-theme-and-plugin-updates'),
|
||||
'admin_nonce' => wp_create_nonce('mpsum_options_save'),
|
||||
'eum_nonce' => wp_create_nonce('eum_nonce'),
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'unexpected_response' => __('Unexpected response:', 'stops-core-theme-and-plugin-updates'),
|
||||
'I18N' => $I18N,
|
||||
'saving' => __('Saving...', 'stops-core-theme-and-plugin-updates'),
|
||||
'working' => __('Working...', 'stops-core-theme-and-plugin-updates'),
|
||||
'logo' => MPSUM_Updates_Manager::get_plugin_url('/images/site_icon.png'),
|
||||
'is_premium' => MPSUM_Updates_Manager::get_instance()->is_premium() ? 'true' : 'false',
|
||||
'is_debug' => (defined('WP_DEBUG') && WP_DEBUG) ? 'true' : 'false',
|
||||
'ratings_nag' => $maybe_show_ratings_nag
|
||||
)));
|
||||
$file_path = "css/style$min_or_not";
|
||||
wp_enqueue_style('mpsum_dashboard', MPSUM_Updates_Manager::get_plugin_url("/$file_path.css"), array(), (int) filemtime(MPSUM_Updates_Manager::get_plugin_dir("$file_path.css")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the "Easy Updates Manager" menu.
|
||||
*
|
||||
* @since 8.0.1
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar WordPress Admin bar Instance
|
||||
*/
|
||||
public function add_admin_bar($wp_admin_bar) {
|
||||
|
||||
if (defined('EASY_UPDATES_MANAGER_ADMIN_BAR') && !EASY_UPDATES_MANAGER_ADMIN_BAR) return;
|
||||
|
||||
// Check for valid permissions
|
||||
if (is_multisite() && !current_user_can('manage_network')) {
|
||||
return;
|
||||
}
|
||||
if (!is_multisite() && !current_user_can('update_plugins')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get core options
|
||||
$options = MPSUM_Updates_Manager::get_options('core');
|
||||
|
||||
// Check to see if logs are enabled
|
||||
$admin_bar_enabled = true;
|
||||
if (isset($options['enable_admin_bar']) && 'off' === $options['enable_admin_bar']) {
|
||||
$admin_bar_enabled = false;
|
||||
}
|
||||
if ($admin_bar_enabled) :
|
||||
// Add parent menu
|
||||
$wp_admin_bar->add_menu(array(
|
||||
'id' => 'easy-updates-manager-admin-bar',
|
||||
'title' => __('Updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'href' => self::get_url(),
|
||||
));
|
||||
|
||||
// Add General Tab
|
||||
$wp_admin_bar->add_menu(array(
|
||||
'id' => 'easy-updates-manager-admin-bar-general',
|
||||
'title' => __('General', 'stops-core-theme-and-plugin-updates'),
|
||||
'href' => add_query_arg(array('tab' => 'general'), self::get_url()),
|
||||
'parent' => 'easy-updates-manager-admin-bar'
|
||||
));
|
||||
|
||||
// Add plugins tab
|
||||
$wp_admin_bar->add_menu(array(
|
||||
'id' => 'easy-updates-manager-admin-bar-plugins',
|
||||
'title' => __('Plugins', 'stops-core-theme-and-plugin-updates'),
|
||||
'href' => add_query_arg(array('tab' => 'plugins'), self::get_url()),
|
||||
'parent' => 'easy-updates-manager-admin-bar'
|
||||
));
|
||||
|
||||
// Add Themes tab
|
||||
$wp_admin_bar->add_menu(array(
|
||||
'id' => 'easy-updates-manager-admin-bar-themes',
|
||||
'title' => __('Themes', 'stops-core-theme-and-plugin-updates'),
|
||||
'href' => add_query_arg(array('tab' => 'themes'), self::get_url()),
|
||||
'parent' => 'easy-updates-manager-admin-bar'
|
||||
));
|
||||
|
||||
// Add logs tab
|
||||
$wp_admin_bar->add_menu(array(
|
||||
'id' => 'easy-updates-manager-admin-bar-logs',
|
||||
'title' => __('Logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'href' => add_query_arg(array('tab' => 'logs'), self::get_url()),
|
||||
'parent' => 'easy-updates-manager-admin-bar'
|
||||
));
|
||||
|
||||
$wp_admin_bar->add_menu(array(
|
||||
'id' => 'easy-updates-manager-admin-bar-advanced',
|
||||
'title' => __('Advanced', 'stops-core-theme-and-plugin-updates'),
|
||||
'href' => add_query_arg(array('tab' => 'advanced'), self::get_url()),
|
||||
'parent' => 'easy-updates-manager-admin-bar'
|
||||
));
|
||||
|
||||
if (!MPSUM_Updates_Manager::get_instance()->is_premium()) {
|
||||
$wp_admin_bar->add_menu(array(
|
||||
'id' => 'easy-updates-manager-admin-bar-premium',
|
||||
'title' => __('Premium', 'stops-core-theme-and-plugin-updates'),
|
||||
'href' => add_query_arg(array('tab' => 'premium'), self::get_url()),
|
||||
'parent' => 'easy-updates-manager-admin-bar'
|
||||
));
|
||||
}
|
||||
endif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a sub-menu page for multisite.
|
||||
*
|
||||
* Adds a sub-menu page for multisite.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see init
|
||||
* @internal Uses network_admin_menu action
|
||||
*/
|
||||
public function init_network_admin_menus() {
|
||||
$hook = add_dashboard_page(__('Updates options', 'stops-core-theme-and-plugin-updates'), __('Updates options', 'stops-core-theme-and-plugin-updates'), 'manage_options', self::get_slug(), array( $this, 'output_admin_interface' ));
|
||||
add_action('admin_enqueue_scripts', array( $this, 'enqueue_scripts' ));
|
||||
add_action("load-$hook", array( $this, 'init_help_screen' ));
|
||||
add_action("load-$hook", array( $this, 'init_screen_options' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a sub-menu page for single-site.
|
||||
*
|
||||
* Adds a sub-menu page for single-site.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see init
|
||||
* @internal Uses admin_menu action
|
||||
*/
|
||||
public function init_single_site_admin_menus() {
|
||||
$hook = add_dashboard_page(__('Updates options', 'stops-core-theme-and-plugin-updates'), __('Updates options', 'stops-core-theme-and-plugin-updates'), 'manage_options', self::get_slug(), array( $this, 'output_admin_interface' ));
|
||||
add_action('admin_enqueue_scripts', array( $this, 'enqueue_scripts' ));
|
||||
add_action("load-$hook", array( $this, 'init_help_screen' ));
|
||||
add_action("load-$hook", array( $this, 'init_screen_options' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs admin interface for sub-menu.
|
||||
*
|
||||
* Outputs admin interface for sub-menu.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see init_network_admin_menus, init_single_site_admin_menus
|
||||
*/
|
||||
public function output_admin_interface() {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1 id="eum-main-heading">
|
||||
<?php
|
||||
$eum_white_label = apply_filters('eum_whitelabel_name', __('Easy Updates Manager', 'stops-core-theme-and-plugin-updates'));
|
||||
echo esc_html($eum_white_label);
|
||||
?>
|
||||
</h1>
|
||||
<?php
|
||||
$tabs = array();
|
||||
|
||||
$tabs[] = array(
|
||||
'url' => add_query_arg(array( 'tab' => 'general' ), self::get_url()), /* URL to the tab */
|
||||
'label' => esc_html__('General', 'stops-core-theme-and-plugin-updates'),
|
||||
'get' => 'general', /*$_GET variable*/
|
||||
'action' => 'mpsum_admin_tab_dashboard' /* action variable in do_action */
|
||||
);
|
||||
|
||||
$tabs[] = array(
|
||||
'url' => add_query_arg(array( 'tab' => 'plugins' ), self::get_url()), /* URL to the tab */
|
||||
'label' => esc_html__('Plugins', 'stops-core-theme-and-plugin-updates'),
|
||||
'get' => 'plugins', /*$_GET variable*/
|
||||
'action' => 'mpsum_admin_tab_plugins' /* action variable in do_action */
|
||||
);
|
||||
$tabs[] = array(
|
||||
'url' => add_query_arg(array( 'tab' => 'themes' ), self::get_url()), /* URL to the tab */
|
||||
'label' => esc_html__('Themes', 'stops-core-theme-and-plugin-updates'),
|
||||
'get' => 'themes', /*$_GET variable*/
|
||||
'action' => 'mpsum_admin_tab_themes' /* action variable in do_action */
|
||||
);
|
||||
$tabs[] = array(
|
||||
'url' => add_query_arg(array( 'tab' => 'logs' ), self::get_url()), /* URL to the tab */
|
||||
'label' => esc_html__('Logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'get' => 'logs', /*$_GET variable*/
|
||||
'action' => 'mpsum_admin_tab_logs' /* action variable in do_action */
|
||||
);
|
||||
$tabs[] = array(
|
||||
'url' => add_query_arg(array( 'tab' => 'advanced' ), self::get_url()), /* URL to the tab */
|
||||
'label' => esc_html__('Advanced', 'stops-core-theme-and-plugin-updates'),
|
||||
'get' => 'advanced', /*$_GET variable*/
|
||||
'action' => 'mpsum_admin_tab_advanced' /* action variable in do_action */
|
||||
);
|
||||
if (!Easy_Updates_Manager()->is_premium()) {
|
||||
$tabs[] = array(
|
||||
'url' => add_query_arg(array( 'tab' => 'premium' ), self::get_url()), /* URL to the tab */
|
||||
'label' => esc_html__('Premium', 'stops-core-theme-and-plugin-updates'),
|
||||
'get' => 'premium', /*$_GET variable*/
|
||||
'action' => 'mpsum_admin_tab_premium' /* action variable in do_action */
|
||||
);
|
||||
}
|
||||
$tabs_count = count($tabs);
|
||||
if ($tabs && !empty($tabs)) {
|
||||
$tab_html = '<h2 class="nav-tab-wrapper">';
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It gets active tab.
|
||||
$active_tab = isset($_GET['tab']) ? sanitize_text_field(wp_unslash($_GET['tab'])) : 'general';
|
||||
$is_tab_match = false;
|
||||
if ('general' == $active_tab) {
|
||||
$active_tab = 'general';
|
||||
} else {
|
||||
foreach ($tabs as $tab) {
|
||||
$tab_get = isset($tab['get']) ? $tab['get'] : '';
|
||||
if ($active_tab === $tab_get) {
|
||||
$is_tab_match = true;
|
||||
}
|
||||
}
|
||||
if (!$is_tab_match) {
|
||||
$active_tab = 'general';
|
||||
}
|
||||
}
|
||||
$do_action = false;
|
||||
foreach ($tabs as $tab) {
|
||||
$classes = array( 'nav-tab' );
|
||||
$tab_get = isset($tab['get']) ? $tab['get'] : '';
|
||||
if ($active_tab == $tab_get) {
|
||||
$classes[] = 'nav-tab-active';
|
||||
$do_action = isset($tab['action']) ? $tab['action'] : false;
|
||||
} elseif (!$is_tab_match && 'general' === $tab_get) {
|
||||
$classes[] = 'nav-tab-active';
|
||||
$do_action = isset($tab['action']) ? $tab['action'] : false;
|
||||
}
|
||||
$tab_url = isset($tab['url']) ? $tab['url'] : '';
|
||||
$tab_html .= sprintf('<a href="%s" class="%s" id="eum-%s">%s</a>', esc_url($tab_url), esc_attr(implode(' ', $classes)), esc_attr($tab_get), esc_html($tab['label']));
|
||||
}
|
||||
$tab_html .= '</h2>';
|
||||
if ($tabs_count > 1) {
|
||||
echo wp_kses_post($tab_html);
|
||||
}
|
||||
if ($do_action) {
|
||||
|
||||
/**
|
||||
* Perform a tab action.
|
||||
*
|
||||
* Perform a tab action.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param string $action Can be mpsum_admin_tab_main, mpsum_admin_tab_plugins, mpsum_admin_tab_themes, and mpsum_admin_tab_advanced.
|
||||
*/
|
||||
do_action($do_action);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
</div><!-- .wrap -->
|
||||
<?php
|
||||
} //end output_admin_interface
|
||||
|
||||
/**
|
||||
* Adds plugin settings page link to plugin links in WordPress Dashboard Plugins Page
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @param array $settings Uses $prefix . "plugin_action_links_$plugin_file" action
|
||||
* @return array Array of settings
|
||||
*/
|
||||
public function plugin_settings_link( $settings ) {
|
||||
$admin_anchor = sprintf('<a href="%s">%s</a>', esc_url($this->get_url()), esc_html__('Configure', 'stops-core-theme-and-plugin-updates'));
|
||||
|
||||
if (! is_array($settings)) {
|
||||
return array( $admin_anchor );
|
||||
} else {
|
||||
return array_merge(array( $admin_anchor ), $settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Easy Updates Manager option to the admin bar
|
||||
*
|
||||
* @since 8.0.1
|
||||
* @access public
|
||||
* @see init
|
||||
*/
|
||||
public function add_networkadmin_page() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
if (!is_object($wp_admin_bar) || !is_super_admin() || !function_exists('is_admin_bar_showing') || !is_admin_bar_showing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wp_admin_bar->add_node(array(
|
||||
'parent' => 'network-admin',
|
||||
'id' => 'eum-admin-settings',
|
||||
'title' => __('Easy Updates Manager', 'stops-core-theme-and-plugin-updates'),
|
||||
'href' => self::get_url()
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Controls the advanced tab and handles the saving of its options.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class MPSUM_Admin_Advanced {
|
||||
|
||||
/**
|
||||
* Holds the slug to the admin panel page
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $slug
|
||||
*/
|
||||
private $slug = '';
|
||||
|
||||
/**
|
||||
* Holds the tab name
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $tab
|
||||
*/
|
||||
private $tab = 'advanced';
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $slug Slug to the admin panel page
|
||||
*/
|
||||
public function __construct( $slug = '' ) {
|
||||
$this->slug = $slug;
|
||||
// Admin Tab Actions
|
||||
MPSUM_Exclude_Users::get_instance();
|
||||
MPSUM_Force_Updates::get_instance();
|
||||
MPSUM_Admin_Bar::get_instance();
|
||||
MPSUM_Reset_Options::get_instance();
|
||||
if (!Easy_Updates_Manager()->is_premium()) {
|
||||
MPSUM_Admin_Advanced_Preview::get_instance();
|
||||
}
|
||||
add_action('mpsum_admin_tab_advanced', array( $this, 'tab_output' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the HTML interface for the advanced tab.
|
||||
*
|
||||
* Output the HTML interface for the advanced tab.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal Uses the mpsum_admin_tab_main action
|
||||
*/
|
||||
public function tab_output() {
|
||||
Easy_Updates_Manager()->include_template('admin-tab-advanced.php');
|
||||
} //end tab_output
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (class_exists('MPSUM_Admin_Advanced_Preview')) return;
|
||||
|
||||
/**
|
||||
* Adds a preview of the premium tabs in the advanced tab.
|
||||
*/
|
||||
class MPSUM_Admin_Advanced_Preview {
|
||||
|
||||
/**
|
||||
* MPSUM_Admin_Advanced_Preview constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
add_action('eum_advanced_headings', array($this, 'headings'), 190);
|
||||
add_action('eum_advanced_settings', array($this, 'settings'), 190);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a singleton instance
|
||||
*
|
||||
* @return MPSUM_Admin_Advanced_Preview object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
private function get_items() {
|
||||
$items = array(
|
||||
'auto-backup' => array(
|
||||
'label' => __('Automatic backup', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __('Takes an automatic backup before your website is updated via an integration with UpdraftPlus', 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'backup'
|
||||
),
|
||||
'auto-update-scheduling' => array(
|
||||
'label' => __('Automatic update scheduling', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __('Choose the most convenient time of day to run your automatic updates.', 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'schedule'
|
||||
),
|
||||
'delay-auto-updates' => array(
|
||||
'label' => __('Delay automatic updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __('Delays the deployment of available automatic updates by a set time, to prevent installing short-lived (e.g. buggy) updates.', 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'hourglass_empty'
|
||||
),
|
||||
'anonymize' => array(
|
||||
'label' => __('Anonymize updates', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __('Controls what is sent to the WordPress.org API; stop sending unnecessary/personal/analytics data.', 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'cloud_off'
|
||||
),
|
||||
'webhook' => array(
|
||||
'label' => __('Webhook', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __('Integrates with third-party services to allow automatic updates to be triggered via cron or tools like Zapier.', 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'all_out'
|
||||
),
|
||||
'version-control-protection' => array(
|
||||
'label' => __('Version control protection', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __("Prevent updates to themes and plugins under version control.", 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'code'
|
||||
),
|
||||
'unmaintained-plugins' => array(
|
||||
'label' => __('Unmaintained plugins', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __("Check for unmaintained plugins in the WordPress plugin directory.", 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'hourglass_empty'
|
||||
),
|
||||
'plugin-safe-mode' => array(
|
||||
'label' => __('Plugin safe mode', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __("Prevent updates that are not compatible with your current WordPress version or your server's PHP version.", 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'security'
|
||||
),
|
||||
'export-import' => array(
|
||||
'label' => __('Export / import settings', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __('Export your settings from one site to another for quicker setup.', 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'save'
|
||||
),
|
||||
'dead-plugins' => array(
|
||||
'label' => __('Dead plugins', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __('Runs a check and alerts you about plugins that have been removed from the WordPress directory.', 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'check_circle'
|
||||
),
|
||||
'white-label' => array(
|
||||
'label' => __('White-label', 'stops-core-theme-and-plugin-updates'),
|
||||
'desc' => __('Customize what branding and notices your clients see in the plugin.', 'stops-core-theme-and-plugin-updates'),
|
||||
'icon' => 'label'
|
||||
),
|
||||
);
|
||||
|
||||
$items = apply_filters('mpsum_premium_items_list', $items);
|
||||
|
||||
return is_array($items) ? $items : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature heading
|
||||
*/
|
||||
public function headings() {
|
||||
foreach ($this->get_items() as $key => $item) {
|
||||
printf('<div class="premium-only" data-menu_name="advanced-premium-preview_'.esc_attr($key).'">%s <span class="eum-advanced-menu-text">%s</span><span class="eum-advanced-menu-premium-only">%s</span></div>', '<i class="material-icons">'.esc_html($item['icon']).'</i>', esc_html($item['label']), esc_html__('Premium', 'stops-core-theme-and-plugin-updates'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature settings
|
||||
*/
|
||||
public function settings() {
|
||||
foreach ($this->get_items() as $key => $item) {
|
||||
Easy_Updates_Manager()->include_template('advanced-premium-preview.php', false, array('key' => $key, 'item' => $item));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (class_exists('MPSUM_Admin_Bar')) return;
|
||||
|
||||
/**
|
||||
* Class MPSUM_Admin_Bar
|
||||
*
|
||||
* Forces automatic updates to take place immediately
|
||||
*/
|
||||
class MPSUM_Admin_Bar {
|
||||
|
||||
/**
|
||||
* MPSUM_Admin_Bar constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
add_action('eum_advanced_headings', array($this, 'heading'), 97);
|
||||
add_action('eum_advanced_settings', array($this, 'settings'), 97);
|
||||
add_filter('eum_i18n', array($this, 'disable_admin_bar_i18n'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a singleton instance
|
||||
*
|
||||
* @return MPSUM_Admin_Bar object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature heading
|
||||
*
|
||||
* @param array $i18n Internalization array
|
||||
*
|
||||
* @return array Updated internalization array
|
||||
*/
|
||||
function disable_admin_bar_i18n($i18n) {
|
||||
$i18n['disable_admin_bar'] = __('Disable', 'stops-core-theme-and-plugin-updates');
|
||||
$i18n['enable_admin_bar'] = __('Enable', 'stops-core-theme-and-plugin-updates');
|
||||
return $i18n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature heading
|
||||
*/
|
||||
public function heading() {
|
||||
printf('<div data-menu_name="admin-bar">%s <span class="eum-advanced-menu-text">%s</span></div>', '<i class="material-icons">menu</i>', esc_html__('Admin bar menu display', 'stops-core-theme-and-plugin-updates'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature settings
|
||||
*/
|
||||
public function settings() {
|
||||
Easy_Updates_Manager()->include_template('admin-bar.php');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/**
|
||||
* Controls the main (general) tab and handles the saving of its options.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class MPSUM_Admin_Core {
|
||||
|
||||
/**
|
||||
* Holds the slug to the admin panel page
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $slug
|
||||
*/
|
||||
private $slug = '';
|
||||
|
||||
/**
|
||||
* Holds the tab name
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
* @var string $tab
|
||||
*/
|
||||
private $tab = 'main';
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $slug Slug to the admin panel page
|
||||
*/
|
||||
public function __construct( $slug = '' ) {
|
||||
$this->slug = $slug;
|
||||
// Admin Tab Actions
|
||||
add_action('mpsum_admin_tab_main', array( $this, 'tab_output' ));
|
||||
add_action('admin_init', array( $this, 'maybe_save_options' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tab defaults.
|
||||
*
|
||||
* Get default core plugin options.
|
||||
* Use array_intersect_key to ensure that only options that are keyed that reflect to the $default_options_values being fetched and eliminate the rest which are considered as unrelated options
|
||||
* Use wp_parse_args to add back the default options that are not being defined or processed during the filteritation
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
*
|
||||
* @return array Associative array of default options
|
||||
*/
|
||||
public static function get_defaults() {
|
||||
|
||||
$default_option_values = array(
|
||||
'all_updates' => 'on',
|
||||
'version_control' => 'off',
|
||||
'core_updates' => 'on',
|
||||
'plugin_updates' => 'on',
|
||||
'theme_updates' => 'on',
|
||||
'translation_updates' => 'on',
|
||||
'automatic_development_updates' => 'off',
|
||||
'notification_core_update_emails' => 'on',
|
||||
'logs' => 'on',
|
||||
'email_addresses' => array(),
|
||||
'ratings_nag' => 'on',
|
||||
'plugin_auto_updates_notification_emails' => 'on',
|
||||
'theme_auto_updates_notification_emails' => 'on',
|
||||
'translation_auto_updates_notification_emails' => 'on',
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter the default plugin configuration.
|
||||
*
|
||||
* @since 6.0.5
|
||||
*
|
||||
* @param array associative array of options
|
||||
*/
|
||||
$filtered_option_values = array_intersect_key((array) apply_filters('mpsum_default_options', $default_option_values), $default_option_values);
|
||||
|
||||
return wp_parse_args($filtered_option_values, $default_option_values);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether to save the main options or not.
|
||||
*
|
||||
* Determine whether to save the main options or not.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal Uses admin_init action
|
||||
*/
|
||||
public function maybe_save_options() {
|
||||
if (!current_user_can('install_plugins')) return;
|
||||
if (!isset($_GET['page']) || $_GET['page'] != $this->slug) return;
|
||||
if (!isset($_REQUEST['action'])) return;
|
||||
if (!isset($_POST['options'])) return;
|
||||
if ('mpsum_save_core_options' !== $_REQUEST['action']) return;
|
||||
check_admin_referer('mpsum_main_update', '_mpsum');
|
||||
|
||||
$query_args = array();
|
||||
$query_args['updated'] = "1";
|
||||
$query_args['tab'] = 'main';
|
||||
|
||||
|
||||
|
||||
// Save options
|
||||
$options = wp_unslash($_POST['options']); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- This is sanitized further down in the function.
|
||||
|
||||
if (isset($_POST['reset'])) {
|
||||
$options = self::get_defaults();
|
||||
}
|
||||
|
||||
$options_to_save = array();
|
||||
|
||||
// Check for valid e-mail address
|
||||
if (isset($options['email_addresses'])) {
|
||||
$email_addresses = explode(',', $options['email_addresses']);
|
||||
$email_addresses_to_save = array();
|
||||
if (count($email_addresses) > 0) {
|
||||
foreach ($email_addresses as $email) {
|
||||
$email = trim($email);
|
||||
if (! is_email($email) && ! empty($email)) {
|
||||
$email_addresses_to_save = array();
|
||||
$query_args['bad_email'] = 1;
|
||||
break;
|
||||
} else {
|
||||
if (! empty($email)) {
|
||||
$email_addresses_to_save[] = $email;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$options_to_save['email_addresses'] = $email_addresses_to_save;
|
||||
}
|
||||
|
||||
foreach ($options as $key => $value) {
|
||||
if ('email_addresses' == $key) continue;
|
||||
|
||||
$option_value = sanitize_text_field($value);
|
||||
$options_to_save[sanitize_key($key)] = $option_value;
|
||||
}
|
||||
|
||||
MPSUM_Updates_Manager::update_options($options_to_save, 'core');
|
||||
|
||||
// Redirect back to settings screen
|
||||
wp_redirect(esc_url_raw(add_query_arg($query_args, MPSUM_Admin::get_url())));
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the HTML interface for the main tab.
|
||||
*
|
||||
* Output the HTML interface for the main tab.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal Uses the mpsum_admin_tab_main action
|
||||
*/
|
||||
public function tab_output() {
|
||||
$options = MPSUM_Updates_Manager::get_options('core');
|
||||
$options = wp_parse_args($options, self::get_defaults());
|
||||
|
||||
if (isset($_GET['updated'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Not part of a form
|
||||
$message = __('Options saved.', 'stops-core-theme-and-plugin-updates');
|
||||
?>
|
||||
<br />
|
||||
<div class="updated"><p><strong><?php echo esc_html($message); ?></strong></p></div>
|
||||
<?php
|
||||
if (isset($_GET['bad_email'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Not part of a form
|
||||
?>
|
||||
<div class="error"><p><strong><?php echo esc_html__('The e-mail address is not valid', 'stops-core-theme-and-plugin-updates'); ?></strong></p></div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<form action="<?php echo esc_url(add_query_arg(array())); ?>" method="post">
|
||||
<?php
|
||||
// This used to be an option; but now we always have it on, because of how useful it is to tracing issues.
|
||||
$logs = 'on';
|
||||
?>
|
||||
<input type="hidden" name="options[logs]" value="<?php echo esc_attr($logs); ?>" />
|
||||
<h3><?php esc_html_e('Global settings', 'stops-core-theme-and-plugin-updates'); ?></h3>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('All updates', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[all_updates]" value="on" id="all_updates_on" <?php checked('on', $options['all_updates']); ?> /> <label for="all_updates_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[all_updates]" value="off" id="all_updates_off" <?php checked('off', $options['all_updates']); ?> /> <label for="all_updates_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p class="description"><?php esc_html_e('If this option is disabled, this will override all settings.', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('WordPress core updates', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[core_updates]" value="on" id="core_updates_on" <?php checked('on', $options['core_updates']); ?> /> <label for="core_updates_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[core_updates]" value="off" id="core_updates_off" <?php checked('off', $options['core_updates']); ?> /> <label for="core_updates_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p class="description"><?php esc_html_e('Prevents WordPress from showing it needs to be updated.', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('All plugin updates', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[plugin_updates]" value="on" id="plugin_updates_on" <?php checked('on', $options['plugin_updates']); ?> /> <label for="plugin_updates_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label><br />
|
||||
<p><input type="radio" name="options[plugin_updates]" value="off" id="plugin_updates_off" <?php checked('off', $options['plugin_updates']); ?> /> <label for="plugin_updates_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('All theme updates', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[theme_updates]" value="on" id="theme_updates_on" <?php checked('on', $options['theme_updates']); ?> /> <label for="theme_updates_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[theme_updates]" value="off" id="theme_updates_off" <?php checked('off', $options['theme_updates']); ?> /> <label for="theme_updates_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('All translation updates', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[translation_updates]" value="on" id="translation_updates_on" <?php checked('on', $options['translation_updates']); ?> /> <label for="translation_updates_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[translation_updates]" value="off" id="translation_updates_off" <?php checked('off', $options['translation_updates']); ?> /> <label for="translation_updates_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3><?php esc_html_e('Automatic updates', 'stops-core-theme-and-plugin-updates'); ?></h3>
|
||||
<p><?php esc_html_e('These options will enable or disable automatic updates (background updates) of certain parts of WordPress.', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('Major releases', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[automatic_major_updates]" value="on" id="automatic_major_on" <?php checked('on', $options['automatic_major_updates']); ?> /> <label for="automatic_major_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[automatic_major_updates]" value="off" id="automatic_major_off" <?php checked('off', $options['automatic_major_updates']); ?> /> <label for="automatic_major_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p class="description"><?php esc_html_e('Automatically update to new major releases (e.g., 4.1, 4.2, 4.3).', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('Minor releases', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[automatic_minor_updates]" value="on" id="automatic_minor_on" <?php checked('on', $options['automatic_minor_updates']); ?> /> <label for="automatic_minor_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label><br />
|
||||
<p><input type="radio" name="options[automatic_minor_updates]" value="off" id="automatic_minor_off" <?php checked('off', $options['automatic_minor_updates']); ?> /> <label for="automatic_minor_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label>
|
||||
<p class="description"><?php esc_html_e('Automatically update to new minor releases in your current series (e.g., 4.1.1, 4.1.2, 4.1.3).', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('Development updates (Core)', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[automatic_development_updates]" value="on" id="automatic_dev_on" <?php checked('on', $options['automatic_development_updates']); ?> /> <label for="automatic_dev_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[automatic_development_updates]" value="off" id="automatic_dev_off" <?php checked('off', $options['automatic_development_updates']); ?> /> <label for="automatic_dev_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p class="description"><?php esc_html_e('Update automatically to bleeding edge releases.', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('Automatic plugin updates', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[automatic_plugin_updates]" value="on" id="automatic_plugin_on" <?php checked('on', $options['automatic_plugin_updates']); ?> /> <label for="automatic_plugin_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[automatic_plugin_updates]" value="off" id="automatic_plugin_off" <?php checked('off', $options['automatic_plugin_updates']); ?> /> <label for="automatic_plugin_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[automatic_plugin_updates]" value="default" id="automatic_plugin_default" <?php checked('default', $options['automatic_plugin_updates']); ?> /> <label for="automatic_plugin_default"><?php esc_html_e('Default', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[automatic_plugin_updates]" value="individual" id="automatic_plugin_individual" <?php checked('individual', $options['automatic_plugin_updates']); ?> /> <label for="automatic_plugin_individual"><?php esc_html_e('Select individually', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p class="description"><?php echo esc_html__('Automatically update your plugins.', 'stops-core-theme-and-plugin-updates').' '.esc_html__('Select always on, always off, the WordPress default, or select plugins individually.', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('Automatic theme updates', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[automatic_theme_updates]" value="on" id="automatic_theme_on" <?php checked('on', $options['automatic_theme_updates']); ?> /> <label for="automatic_theme_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[automatic_theme_updates]" value="off" id="automatic_theme_off" <?php checked('off', $options['automatic_theme_updates']); ?> /> <label for="automatic_theme_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[automatic_theme_updates]" value="default" id="automatic_theme_default" <?php checked('default', $options['automatic_theme_updates']); ?> /> <label for="automatic_theme_default"><?php esc_html_e('Default', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[automatic_theme_updates]" value="individual" id="automatic_theme_individual" <?php checked('individual', $options['automatic_theme_updates']); ?> /> <label for="automatic_theme_individual"><?php esc_html_e('Select individually', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p class="description"><?php echo esc_html__('Automatically update your themes.', 'stops-core-theme-and-plugin-updates').' '.esc_html__('Select always on, always off, the WordPress default, or select themes individually.', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('Translation updates', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[automatic_translation_updates]" value="on" id="automatic_translation_on" <?php checked('on', $options['automatic_translation_updates']); ?> /> <label for="automatic_translation_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[automatic_translation_updates]" value="off" id="automatic_translation_off" <?php checked('off', $options['automatic_translation_updates']); ?> /> <label for="automatic_translation_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p class="description"><?php esc_html_e('Automatically update your translations.', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3><?php esc_html_e('Notifications', 'stops-core-theme-and-plugin-updates'); ?></h3>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('Core e-mails', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<input type="hidden" name="options[notification_core_update_emails]" value="off" />
|
||||
<p><input type="checkbox" name="options[notification_core_update_emails]" value="on" id="notification_core_update_emails_on" <?php checked('on', $options['notification_core_update_emails']); ?> /> <label for="notification_core_update_emails_on"><?php esc_html_e('Core update e-mails', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<?php /* Hidden checkboxes until changes make into core. Shooting for WordPress 4.5 */ ?>
|
||||
<input type="hidden" name="options[notification_core_update_emails_plugins]" value="on" />
|
||||
<input type="hidden" name="options[notification_core_update_emails_themes]" value="on" />
|
||||
<input type="hidden" name="options[notification_core_update_emails_translations]" value="on" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('Notification e-mail', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<?php
|
||||
$email_addresses = array();
|
||||
if (isset($options['email_addresses']) && is_array($options['email_addresses'])) {
|
||||
foreach ($options['email_addresses'] as $email) {
|
||||
if (! is_email($email)) {
|
||||
$email_addresses = array();
|
||||
break;
|
||||
} else {
|
||||
$email_addresses[] = $email;
|
||||
}
|
||||
}
|
||||
if (! empty($email_addresses)) {
|
||||
$email_addresses = implode(',', $options['email_addresses']);
|
||||
} else {
|
||||
$email_addresses = '';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<input type="text" name="options[email_addresses]" value="<?php echo esc_attr($email_addresses); ?>" style="width: 50%" /><br />
|
||||
<p class="description"><?php echo esc_html_e('e-mails can be comma separated', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3><?php esc_html_e('Miscellaneous', 'stops-core-theme-and-plugin-updates'); ?></h3>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('Browser nag', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[misc_browser_nag]" value="on" id="misc_browser_nag_on" <?php checked('on', $options['misc_browser_nag']); ?> /> <label for="misc_browser_nag_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[misc_browser_nag]" value="off" id="misc_browser_nag_off" <?php checked('off', $options['misc_browser_nag']); ?> /> <label for="misc_browser_nag_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p class="description"><?php esc_html_e('Removes the browser nag for people using older browsers.', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e('WordPress version in footer', 'stops-core-theme-and-plugin-updates'); ?></th>
|
||||
<td>
|
||||
<p><input type="radio" name="options[misc_wp_footer]" value="on" id="misc_wp_footer_on" <?php checked('on', $options['misc_wp_footer']); ?> /> <label for="misc_wp_footer_on"><?php esc_html_e('Enabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p><input type="radio" name="options[misc_wp_footer]" value="off" id="misc_wp_footer_off" <?php checked('off', $options['misc_wp_footer']); ?> /> <label for="misc_wp_footer_off"><?php esc_html_e('Disabled', 'stops-core-theme-and-plugin-updates'); ?></label></p>
|
||||
<p class="description"><?php esc_html_e('Removes the WordPress version in the footer.', 'stops-core-theme-and-plugin-updates'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="hidden" name="action" value='mpsum_save_core_options' />
|
||||
<?php
|
||||
wp_nonce_field('mpsum_main_update', '_mpsum');
|
||||
echo '<p class="submit">';
|
||||
submit_button(__('Save changes', 'stops-core-theme-and-plugin-updates'), 'primary', 'submit', false);
|
||||
echo ' ';
|
||||
submit_button(__('Reset to defaults', 'stops-core-theme-and-plugin-updates'), 'secondary', 'reset', false);
|
||||
echo '</p>';
|
||||
?>
|
||||
</form>
|
||||
<?php
|
||||
} //end tab_output_plugins
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Controls the main (general) tab and handles the saving of its options.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class MPSUM_Admin_Dashboard {
|
||||
|
||||
/**
|
||||
* Holds the slug to the admin panel page
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $slug
|
||||
*/
|
||||
private $slug = '';
|
||||
|
||||
/**
|
||||
* Holds the tab name
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $tab
|
||||
*/
|
||||
private $tab = 'main';
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $slug Slug to the admin panel page
|
||||
*/
|
||||
public function __construct( $slug = '' ) {
|
||||
$this->slug = $slug;
|
||||
// Admin Tab Actions
|
||||
add_action('mpsum_admin_tab_dashboard', array( $this, 'tab_output' ));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output the HTML interface for the main tab.
|
||||
*
|
||||
* Output the HTML interface for the main tab.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal Uses the mpsum_admin_tab_main action
|
||||
*/
|
||||
public function tab_output() {
|
||||
Easy_Updates_Manager()->include_template('admin-tab-main.php');
|
||||
return; // Squiz.PHP.NonExecutableCode.ReturnNotRequired
|
||||
} //end tab_output_plugins
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* Help Screen for Easy Updates Manager
|
||||
* Initializes and outputs the help screen for the plugin.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class MPSUM_Admin_Help {
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
$screen = get_current_screen();
|
||||
|
||||
$content1_strings = array(
|
||||
'website' => __('Our website', 'stops-core-theme-and-plugin-updates'),
|
||||
'donate' => __('Donate', 'stops-core-theme-and-plugin-updates'),
|
||||
'support' => __('Support on WordPress', 'stops-core-theme-and-plugin-updates'),
|
||||
'premium_support' => __('Premium support', 'stops-core-theme-and-plugin-updates'),
|
||||
'official' => __('Documentation', 'stops-core-theme-and-plugin-updates'),
|
||||
);
|
||||
$content1 = '<p>';
|
||||
$content1 .= '<a href="https://easyupdatesmanager.com" class="button">' . esc_html($content1_strings['website']) . '</a> ';
|
||||
$content1 .= '<a href="http://wordpress.org/support/plugin/stops-core-theme-and-plugin-updates" class="button">' . esc_html($content1_strings['support']) . '</a> ';
|
||||
$content1 .= '<a href="https://easyupdatesmanager.com/support/" class="button">' . esc_html($content1_strings['premium_support']) . '</a> ';
|
||||
$content1 .= '<a href="https://easyupdatesmanager.com/documentation/" class="button">' . esc_html($content1_strings['official']) . '</a>';
|
||||
$content1 .= '</p>';
|
||||
$content1 .= '<p>';
|
||||
$content1 .= esc_html__('This is the Easy Updates Manager settings help tab.', 'stops-core-theme-and-plugin-updates').' '.esc_html__('Here you will find helpful information on what Easy Updates Manager does and how to use it.', 'stops-core-theme-and-plugin-updates');
|
||||
$content1 .= '</p>';
|
||||
$content1 .= sprintf('<div><p><strong>%s - </strong>%s</p></div>', esc_html__('Please note!', 'stops-core-theme-and-plugin-updates'), esc_html__('If either your WordPress core, theme, or plugins get too out of date, you may run into compatibility problems.', 'stops-core-theme-and-plugin-updates').' '.esc_html__('Check the capability tab for more information.', 'stops-core-theme-and-plugin-updates'));
|
||||
|
||||
$content2 = sprintf('<div><p><a href="https://easyupdatesmanager.com/documentation/">%s</a></p></div>', esc_html__('Check out our documentation for updated documentation and videos.', 'stops-core-theme-and-plugin-updates'));
|
||||
|
||||
$content4_strings = array(
|
||||
'intro' => __('You will see multiple tabs where you can configure the update options.', 'stops-core-theme-and-plugin-updates'),
|
||||
'general' => sprintf('<strong>%s</strong> - %s', __('General', 'stops-core-theme-and-plugin-updates'), __('Use this screen to finely tune which updates and automatic updates you would like to see.', 'stops-core-theme-and-plugin-updates')),
|
||||
'plugins' => sprintf('<strong>%s</strong> - %s', __('Plugins', 'stops-core-theme-and-plugin-updates'), __('If plugin updates are enabled and/or automatic updates for plugins are enabled, you can configure which plugins will receive updates and/or automatic updates.', 'stops-core-theme-and-plugin-updates')),
|
||||
'themes' => sprintf('<strong>%s</strong> - %s', __('Themes', 'stops-core-theme-and-plugin-updates'), __('If theme updates are enabled and/or automatic updates for themes are enabled, you can configure which themes will receive updates and/or automatic updates.', 'stops-core-theme-and-plugin-updates')),
|
||||
'logs' => sprintf('<strong>%s</strong> - %s', __('Logs', 'stops-core-theme-and-plugin-updates'), __('Logs all plugin, theme, and core updates.', 'stops-core-theme-and-plugin-updates').' '.__('This tab is visible by default.', 'stops-core-theme-and-plugin-updates')),
|
||||
'advanced' => sprintf('<strong>%s</strong> - %s', __('Advanced', 'stops-core-theme-and-plugin-updates'), __('Reset all options or allow certain users to see all updates regardless of what settings you have set.', 'stops-core-theme-and-plugin-updates')),
|
||||
|
||||
);
|
||||
$content4_allowed_tags = array('p' => array(),'strong' => array(),'br' => array());
|
||||
$content4 = wp_kses('<p>' . $content4_strings['intro'] . '<br><br>' . $content4_strings['general'] . '<br><br>' . $content4_strings['plugins'] . '<br><br>' . $content4_strings['themes'] . '<br><br>' . $content4_strings['logs'] . '<br><br>' . $content4_strings['advanced'] . '</p>', $content4_allowed_tags);
|
||||
|
||||
$content6 = '<p>';
|
||||
$content6 .= esc_html__('WordPress encourages you to update your plugins, themes, and core to make sure that there are no bugs.', 'stops-core-theme-and-plugin-updates').' '.esc_html__('Even though you most likely want to disable all the updates and never think about updating again, you should still consider updating every once in a while to avoid major bugs and errors on your WordPress website.', 'stops-core-theme-and-plugin-updates');
|
||||
$content6 .= sprintf('<h4>%s</h4>', esc_html__('This plugin is tested with the most recent versions of WordPress to ensure that there are no major issues.', 'stops-core-theme-and-plugin-updates'));
|
||||
$content6 .= '</p>';
|
||||
|
||||
$screen->add_help_tab(array(
|
||||
'id' => 'help_tab_content_1',
|
||||
'title' => __('Overview', 'stops-core-theme-and-plugin-updates'),
|
||||
'content' => $content1,
|
||||
));
|
||||
|
||||
$screen->add_help_tab(array(
|
||||
'id' => 'help_tab_content_4',
|
||||
'title' => __('Navigation', 'stops-core-theme-and-plugin-updates'),
|
||||
'content' => $content4,
|
||||
));
|
||||
|
||||
$screen->add_help_tab(array(
|
||||
'id' => 'help_tab_content_2',
|
||||
'title' => __('Documentation', 'stops-core-theme-and-plugin-updates'),
|
||||
'content' => wpautop($content2),
|
||||
));
|
||||
|
||||
$screen->add_help_tab(array(
|
||||
'id' => 'help_tab_content_6',
|
||||
'title' => __('Capability', 'stops-core-theme-and-plugin-updates'),
|
||||
'content' => wpautop($content6),
|
||||
));
|
||||
|
||||
} //end constructor
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Controls the logs tab.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 6.0.0
|
||||
*/
|
||||
class MPSUM_Admin_Logs {
|
||||
|
||||
/**
|
||||
* Holds the slug to the admin panel page
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $slug
|
||||
*/
|
||||
private $slug = '';
|
||||
|
||||
/**
|
||||
* Holds the tab name
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
* @var string $tab
|
||||
*/
|
||||
private $tab = 'logs';
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $slug Slug to the admin panel page
|
||||
*/
|
||||
public function __construct( $slug = '' ) {
|
||||
$this->slug = $slug;
|
||||
// Admin Tab Actions
|
||||
add_action('mpsum_admin_tab_logs', array( $this, 'tab_output_logs' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the HTML interface for the logs tab.
|
||||
*
|
||||
* Output the HTML interface for the logs tab.
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal Uses the mpsum_admin_tab_logs action
|
||||
*/
|
||||
public function tab_output_logs() {
|
||||
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- his are ignored as they are passed to the template
|
||||
$paged = isset($data['data']['paged']) ? $data['data']['paged'] : '1';
|
||||
$view = isset($data['data']['view']) ? $data['data']['view'] : 'all';
|
||||
$m = isset($data['data']['m']) ? $data['data']['m'] : 'all';
|
||||
$status = isset($data['data']['status']) ? $data['data']['status'] : 'all';
|
||||
$action_type = isset($data['data']['action_type']) ? $data['data']['action_type'] : 'all';
|
||||
$type = isset($data['data']['type']) ? $data['data']['type'] : 'all';
|
||||
$is_search = isset($data['data']['is_search']) ? $data['data']['is_search'] : false;
|
||||
$search_term = isset($data['data']['search_term']) ? $data['data']['search_term'] : '';
|
||||
$order = isset($data['data']['order']) ? $data['data']['order'] : 'DESC';
|
||||
// phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
|
||||
|
||||
$args = array('paged' => $paged, 'view' => $view, 'status' => $status, 'action_type' => $action_type, 'type' => $type, 'm' => $m, 'is_search' => $is_search, 'search_term' => $search_term, 'order' => $order );
|
||||
Easy_Updates_Manager()->include_template('admin-tab-logs.php', false, $args);
|
||||
} //end tab_output_plugins
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Controls the plugins tab and handles the saving of its options.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class MPSUM_Admin_Plugins {
|
||||
|
||||
/**
|
||||
* Holds the slug to the admin panel page
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $slug
|
||||
*/
|
||||
private $slug = '';
|
||||
|
||||
/**
|
||||
* Holds the tab name
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $tab
|
||||
*/
|
||||
private $tab = 'plugins';
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $slug Slug to the admin panel page
|
||||
*/
|
||||
public function __construct( $slug = '' ) {
|
||||
$this->slug = $slug;
|
||||
|
||||
// Admin Tab Actions
|
||||
add_action('mpsum_admin_tab_plugins', array($this, 'tab_output'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the plugins can be updated or not.
|
||||
*
|
||||
* Determine whether the plugins can be updated or not.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @return bool True if the plugins can be updated, false if not.
|
||||
*/
|
||||
public static function can_update_plugins() {
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['all_updates']) && 'off' == $core_options['all_updates']) {
|
||||
return false;
|
||||
}
|
||||
if (isset($core_options['plugin_updates']) && 'off' == $core_options['plugin_updates']) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the HTML interface for the plugins tab.
|
||||
*
|
||||
* Output the HTML interface for the plugins tab.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal Uses the mpsum_admin_tab_plugins action
|
||||
*/
|
||||
public function tab_output() {
|
||||
$params = array(
|
||||
'can_update' => self::can_update_plugins(),
|
||||
'slug' => $this->slug,
|
||||
'tab' => $this->tab,
|
||||
'paged' => '1',
|
||||
'view' => 'all'
|
||||
);
|
||||
Easy_Updates_Manager()->include_template('admin-tab-plugins.php', false, $params);
|
||||
} //end tab_output_plugins
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* Screen options screen for Easy Updates Manager
|
||||
* Initializes and outputs the screen options screen for the plugin.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 6.2.0
|
||||
*/
|
||||
class MPSUM_Admin_Screen_Options {
|
||||
|
||||
/**
|
||||
* Holds the class instance.
|
||||
*
|
||||
* @since 6.2.0
|
||||
* @access static
|
||||
* @var MPSUM_Admin $instance
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 6.2.0
|
||||
* @access private
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->set_screen_options();
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Save screen option.
|
||||
*
|
||||
* @since 6.2.0
|
||||
* @access static
|
||||
* @param string $status Save option status
|
||||
* @param string $option Option name
|
||||
* @param string $value Option value
|
||||
* @return string Returns value if succeeds, otherwise status
|
||||
*/
|
||||
public static function save_options( $status, $option, $value ) {
|
||||
if ('mpsum_items_per_page' == $option) {
|
||||
return $value;
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a class instance.
|
||||
*
|
||||
* Set a class instance.
|
||||
*
|
||||
* @since 6.2.0
|
||||
* @access static
|
||||
*/
|
||||
public static function run() {
|
||||
if (null == self::$instance) {
|
||||
self::$instance = new self;
|
||||
}
|
||||
} //end get_instance
|
||||
|
||||
/**
|
||||
* Set screen options for items per page.
|
||||
*
|
||||
* Set screen options for items per page.
|
||||
*
|
||||
* @since 6.2.0
|
||||
* @access private
|
||||
*/
|
||||
private function set_screen_options() {
|
||||
$args = array(
|
||||
'label' => __('Items per page', 'stops-core-theme-and-plugin-updates'),
|
||||
'default' => 100,
|
||||
'option' => 'mpsum_items_per_page'
|
||||
);
|
||||
|
||||
add_screen_option('per_page', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save dashboard screen options.
|
||||
*
|
||||
* Save dashboard screen options.
|
||||
*
|
||||
* @since 6.2.0
|
||||
* @access static
|
||||
*/
|
||||
public static function maybe_save_dashboard_screen_option() {
|
||||
if (!isset($_REQUEST['mpsum_dashboard'])) return;
|
||||
|
||||
if (!isset($_REQUEST['screenoptionnonce']) || !wp_verify_nonce($_REQUEST['screenoptionnonce'], 'screen-options-nonce')) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- No need to sanitize nonces
|
||||
return;
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$dashboard = sanitize_text_field(wp_unslash($_REQUEST['mpsum_dashboard']));
|
||||
if ('on' !== $dashboard) {
|
||||
$dashboard = 'off';
|
||||
}
|
||||
update_user_meta($user_id, 'mpsum_dashboard', $dashboard);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Controls the themes tab and handles the saving of its options.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class MPSUM_Admin_Themes {
|
||||
|
||||
/**
|
||||
* Holds the slug to the admin panel page
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $slug
|
||||
*/
|
||||
private $slug = '';
|
||||
|
||||
/**
|
||||
* Holds the tab name
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
* @var string $tab
|
||||
*/
|
||||
private $tab = 'themes';
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $slug Slug to the admin panel page
|
||||
*/
|
||||
public function __construct( $slug = '' ) {
|
||||
$this->slug = $slug;
|
||||
|
||||
// Admin Tab Actions
|
||||
add_action('mpsum_admin_tab_themes', array( $this, 'tab_output' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the themes can be updated or not.
|
||||
*
|
||||
* Determine whether the themes can be updated or not.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @return bool True if the themes can be updated, false if not.
|
||||
*/
|
||||
public static function can_update_themes() {
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['all_updates']) && 'off' == $core_options['all_updates']) {
|
||||
return false;
|
||||
}
|
||||
if (isset($core_options['theme_updates']) && 'off' == $core_options['theme_updates']) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the HTML interface for the themes tab.
|
||||
*
|
||||
* Output the HTML interface for the themes tab.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal Uses the mpsum_admin_tab_themes action
|
||||
*/
|
||||
public function tab_output() {
|
||||
$params = array(
|
||||
'can_update' => self::can_update_themes(),
|
||||
'slug' => $this->slug,
|
||||
'tab' => $this->tab,
|
||||
'paged' => '1',
|
||||
'view' => 'all'
|
||||
);
|
||||
Easy_Updates_Manager()->include_template('admin-tab-themes.php', false, $params);
|
||||
} //end tab_output_plugins
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (class_exists('MPSUM_Advanced_Premium')) return;
|
||||
|
||||
/**
|
||||
* Class MPSUM_Advanced_Premium
|
||||
*
|
||||
* Add an advanced tab for going premium
|
||||
*/
|
||||
class MPSUM_Advanced_Premium {
|
||||
|
||||
/**
|
||||
* MPSUM_Advanced_Premium constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('mpsum_admin_tab_premium', array($this, 'settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a singleton instance
|
||||
*
|
||||
* @return MPSUM_Advanced_Premium object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature settings
|
||||
*/
|
||||
public function settings() {
|
||||
Easy_Updates_Manager()->include_template('advanced-premium.php');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (class_exists('MPSUM_Check_Plugin_Install_Status')) return;
|
||||
|
||||
/**
|
||||
* Class MPSUM_Check_Plugin_Install_Status
|
||||
* Credit: https://github.com/WebDevStudios/WDS-Active-Plugin-Data
|
||||
*/
|
||||
class MPSUM_Check_Plugin_Install_Status {
|
||||
|
||||
/**
|
||||
* List available plugins
|
||||
*
|
||||
* @var array Available plugins in /wp-content/plugins/
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
private $available_plugins = array();
|
||||
|
||||
/**
|
||||
* List every plugin for every site
|
||||
*
|
||||
* @var array Active plugins list for every site
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
private $all_sites_active_plugins = array();
|
||||
|
||||
/**
|
||||
* List of sites.
|
||||
*
|
||||
* @var array List of sites
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
private $sites = array();
|
||||
|
||||
/**
|
||||
* MPSUM_Check_Plugin_Install_Status constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
if (is_multisite()) {
|
||||
$this->get_all_sites_active_plugins();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a singleton instance
|
||||
*
|
||||
* @return MPSUM_Check_Plugin_Install_Status object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for our available plugins
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
public function get_available_plugins() {
|
||||
if (empty($this->available_plugins)) {
|
||||
$this->available_plugins = get_plugins();
|
||||
}
|
||||
return $this->available_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for our sites
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
public function get_sites() {
|
||||
$blog_count = get_blog_count();
|
||||
if (empty($this->sites)) {
|
||||
$this->sites = get_sites(array('deleted' => false, 'number' => $blog_count));
|
||||
}
|
||||
return $this->sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active plugins list for every site and store to a transient
|
||||
*
|
||||
* @return array of all active site plugins
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
public function get_all_sites_active_plugins() {
|
||||
if (!empty($this->all_sites_active_plugins)) {
|
||||
return $this->all_sites_active_plugins;
|
||||
}
|
||||
$exists = get_site_transient('eum_all_sites_active_plugins');
|
||||
if ($exists) {
|
||||
$this->all_sites_active_plugins = $exists;
|
||||
return $this->all_sites_active_plugins;
|
||||
}
|
||||
$sites = $this->get_sites();
|
||||
if (empty($sites)) {
|
||||
return;
|
||||
}
|
||||
foreach ($sites as $site) {
|
||||
$blog_id = absint($site->blog_id);
|
||||
switch_to_blog($blog_id);
|
||||
$option = get_option('active_plugins');
|
||||
$this->all_sites_active_plugins[$blog_id] = array();
|
||||
$this->all_sites_active_plugins[$blog_id] = MPSUM_Updates_Manager::unserialize($option);
|
||||
}
|
||||
restore_current_blog();
|
||||
set_site_transient('eum_all_sites_active_plugins', $this->all_sites_active_plugins, 86400);
|
||||
return $this->all_sites_active_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a plugin is active on any site in the network
|
||||
*
|
||||
* @param string $plugin_file plugin to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_plugin_active_on_any_site($plugin_file) {
|
||||
$active = false;
|
||||
foreach ($this->get_all_sites_active_plugins() as $plugins) {
|
||||
if (in_array($plugin_file, $plugins)) {
|
||||
$active = true;
|
||||
}
|
||||
}
|
||||
return $active;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (class_exists('MPSUM_Check_Theme_Install_Status')) return;
|
||||
|
||||
/**
|
||||
* Class MPSUM_Check_Plugin_Install_Status
|
||||
* Credit: https://github.com/WebDevStudios/WDS-Active-Plugin-Data
|
||||
*/
|
||||
class MPSUM_Check_Theme_Install_Status {
|
||||
|
||||
/**
|
||||
* List available themes
|
||||
*
|
||||
* @var array Available themes in /wp-content/themes/
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
private $available_themes = array();
|
||||
|
||||
/**
|
||||
* List every theme for every site
|
||||
*
|
||||
* @var array Active themes list for every site
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
private $all_sites_active_themes = array();
|
||||
|
||||
/**
|
||||
* List of sites.
|
||||
*
|
||||
* @var array List of sites
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
private $sites = array();
|
||||
|
||||
/**
|
||||
* MPSUM_Check_Theme_Install_Status constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
if (is_multisite()) {
|
||||
$this->get_all_sites_active_themes();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a singleton instance
|
||||
*
|
||||
* @return MPSUM_Check_Theme_Install_Status object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for our available themes
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
public function get_available_themes() {
|
||||
if (empty($this->available_themes)) {
|
||||
$this->available_themes = wp_get_themes();
|
||||
}
|
||||
return $this->available_themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for our sites
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
public function get_sites() {
|
||||
$blog_count = get_blog_count();
|
||||
if (empty($this->sites)) {
|
||||
$this->sites = get_sites(array('deleted' => false, 'number' => $blog_count));
|
||||
}
|
||||
return $this->sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active themes list for every site and store to a transient
|
||||
*
|
||||
* @return array of all active site themes
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
public function get_all_sites_active_themes() {
|
||||
$exists = get_site_transient('eum_all_sites_active_themes');
|
||||
if ($exists) {
|
||||
$this->all_sites_active_themes = $exists;
|
||||
return $this->all_sites_active_themes;
|
||||
}
|
||||
$sites = $this->get_sites();
|
||||
if (empty($sites)) {
|
||||
return;
|
||||
}
|
||||
foreach ($sites as $site) {
|
||||
$blog_id = absint($site->blog_id);
|
||||
$themes = wp_get_themes(array('blog_id' => $blog_id));
|
||||
$this->all_sites_active_themes[$blog_id] = array();
|
||||
if (!empty($themes)) {
|
||||
$this->all_sites_active_themes[$blog_id] = MPSUM_Updates_Manager::unserialize($themes);
|
||||
}
|
||||
}
|
||||
set_site_transient('eum_all_sites_active_themes', $this->all_sites_active_themes, 86400);
|
||||
return $this->all_sites_active_themes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,603 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
/**
|
||||
* All commands that are intended to be available for calling from any sort of control interface (e.g. wp-admin, UpdraftCentral) go in here. All public methods should either return the data to be returned, or a WP_Error with associated error code, message and error data.
|
||||
*/
|
||||
class MPSUM_Commands {
|
||||
|
||||
/**
|
||||
* Holds instance of MPSUM_Admin_Ajax class
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private $admin_ajax;
|
||||
|
||||
/**
|
||||
* Holds instance of MPSUM_Premium_Admin_Ajax class
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private $premium_admin_ajax;
|
||||
|
||||
/**
|
||||
* MPSUM_Commands class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->admin_ajax = MPSUM_Admin_Ajax::get_instance();
|
||||
if (Easy_Updates_Manager()->is_premium()) {
|
||||
$this->premium_admin_ajax = MPSUM_Premium_Admin_Ajax::get_instance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve and return version of the plugin
|
||||
*
|
||||
* @return string Version of the plugin
|
||||
*/
|
||||
public function get_version() {
|
||||
return EASY_UPDATES_MANAGER_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves core options and returns to construct general tab content
|
||||
*
|
||||
* @return array|string An array of core options or error message
|
||||
*/
|
||||
public function get_general_contents() {
|
||||
$options = MPSUM_Updates_Manager::get_options('core', true);
|
||||
if (empty($options)) {
|
||||
$options = MPSUM_Admin_Core::get_defaults();
|
||||
} elseif (is_array($options)) {
|
||||
$options = wp_parse_args($options, MPSUM_Admin_Core::get_defaults());
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves core options and return updated core options
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return array|string An array of core options or an error message
|
||||
*/
|
||||
public function save_general_options($data) {
|
||||
$options = $data['data']['data'];
|
||||
$decoded_options = $this->_get_decoded_options($options);
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core', true);
|
||||
$decoded_options['email_addresses'] = $core_options['email_addresses'];
|
||||
MPSUM_Updates_Manager::update_options($decoded_options, 'core');
|
||||
return MPSUM_Updates_Manager::get_options('core');
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves email notification emails
|
||||
*
|
||||
* @param string $email_addresses Email addresses (may be comma separated)
|
||||
*
|
||||
* @return string A success or error message.
|
||||
*/
|
||||
public function save_notification_emails($email_addresses) {
|
||||
$email_addresses = trim($email_addresses);
|
||||
|
||||
// Check for empty amail addresses and save empty email options.
|
||||
if (empty($email_addresses)) {
|
||||
$options = MPSUM_Updates_Manager::get_options('core', true);
|
||||
$options['email_addresses'] = '';
|
||||
MPSUM_Updates_Manager::update_options($options, 'core');
|
||||
return __('Your e-mail addresses have been saved.', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
|
||||
// Check for valid emails.
|
||||
$email_validation = MPSUM_Utils::validate_emails($email_addresses); // $email_addresses holds a string of email addresses. May be comma separated.
|
||||
|
||||
// Save emails if valid.
|
||||
if (! $email_validation['errors']) {
|
||||
$options = MPSUM_Updates_Manager::get_options('core', true);
|
||||
$options['email_addresses'] = $email_validation['emails'];
|
||||
MPSUM_Updates_Manager::update_options($options, 'core');
|
||||
return __('Your e-mail addresses have been saved.', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return __('One or more of the e-mail addresses is invalid.', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
|
||||
/**
|
||||
* UC Sends `id`s of button elements which is converted to option key here
|
||||
*
|
||||
* @param array $options An array of updated options from remote call
|
||||
*
|
||||
* @return array An array of decoded options
|
||||
*/
|
||||
private function _get_decoded_options($options) {
|
||||
$decoded_options = array();
|
||||
foreach ($options as $option) {
|
||||
$pos = strrpos($option, '-');
|
||||
$value = substr($option, $pos+1);
|
||||
$key = substr($option, 0, strlen($option) - (strlen($value) + 1));
|
||||
$key = str_replace('-', '_', $key);
|
||||
$decoded_options[$key] = $value;
|
||||
}
|
||||
return $decoded_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin tab content template
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns plugin tab content as HTML string
|
||||
*/
|
||||
public function get_plugins_contents($data) {
|
||||
if (!current_user_can('update_plugins')) {
|
||||
return __('User has insufficient capability to update plugins', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
$args = $this->_get_paged_view_status($data);
|
||||
if (! isset($args['slug'])) {
|
||||
$args['slug'] = 'mpsum-update-options';
|
||||
}
|
||||
return Easy_Updates_Manager()->include_template('admin-tab-plugins.php', true, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves plugin update options
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns plugin tab content as HTML string
|
||||
*/
|
||||
public function save_plugins_update_options($data) {
|
||||
$args = $this->_get_paged_view_status($data);
|
||||
parse_str($data['data']['data'], $updated_options);
|
||||
$this->admin_ajax->save_plugins_update_options($updated_options);
|
||||
return Easy_Updates_Manager()->include_template('admin-tab-plugins.php', true, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves plugin options performed via bulk actions
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns plugin tab content as HTML string
|
||||
*/
|
||||
public function bulk_action_plugins_update_options($data) {
|
||||
$args = $this->_get_paged_view_status($data);
|
||||
parse_str($data['data']['data'], $updated_options);
|
||||
$this->admin_ajax->bulk_action_plugins_update_options($updated_options);
|
||||
return Easy_Updates_Manager()->include_template('admin-tab-plugins.php', true, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme tab content template
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns theme tab content as HTML string
|
||||
*/
|
||||
public function get_themes_contents($data) {
|
||||
if (!current_user_can('update_themes')) {
|
||||
return __('User has insufficient capability to update themes', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
$args = $this->_get_paged_view_status($data);
|
||||
if (! isset($args['slug'])) {
|
||||
$args['slug'] = 'mpsum-update-options';
|
||||
}
|
||||
return Easy_Updates_Manager()->include_template('admin-tab-themes.php', true, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves theme update options
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns theme tab content as HTML string
|
||||
*/
|
||||
public function save_themes_update_options($data) {
|
||||
$args = $this->_get_paged_view_status($data);
|
||||
parse_str($data['data']['data'], $updated_options);
|
||||
$this->admin_ajax->save_themes_update_options($updated_options);
|
||||
return Easy_Updates_Manager()->include_template('admin-tab-themes.php', true, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves theme options performed via bulk actions
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns theme tab content as HTML string
|
||||
*/
|
||||
public function bulk_action_themes_update_options($data) {
|
||||
$args = $this->_get_paged_view_status($data);
|
||||
parse_str($data['data']['data'], $updated_options);
|
||||
$this->admin_ajax->bulk_action_themes_update_options($updated_options);
|
||||
return Easy_Updates_Manager()->include_template('admin-tab-themes.php', true, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs tab content template
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns logs tab content as HTML string
|
||||
*/
|
||||
public function get_logs_contents($data) {
|
||||
|
||||
$paged = isset($data['data']['paged']) ? $data['data']['paged'] : '1';
|
||||
$view = isset($data['data']['view']) ? $data['data']['view'] : 'all';
|
||||
$m = isset($data['data']['m']) ? $data['data']['m'] : 'all';
|
||||
$status = isset($data['data']['status']) ? $data['data']['status'] : 'all';
|
||||
$action_type = isset($data['data']['action_type']) ? $data['data']['action_type'] : 'all';
|
||||
$type = isset($data['data']['type']) ? $data['data']['type'] : 'all';
|
||||
$order = isset($data['data']['order']) ? $data['data']['order'] : 'DESC';
|
||||
$is_search = isset($data['data']['is_search']) ? $data['data']['is_search'] : false;
|
||||
$search_term = isset($data['data']['search_term']) ? $data['data']['search_term'] : '';
|
||||
|
||||
$args = array('paged' => $paged, 'view' => $view, 'status' => $status, 'action_type' => $action_type, 'type' => $type, 'm' => $m, 'is_search' => $is_search, 'search_term' => $search_term, 'order' => $order);
|
||||
if (! isset($args['slug'])) {
|
||||
$args['slug'] = 'mpsum-update-options';
|
||||
}
|
||||
return Easy_Updates_Manager()->include_template('admin-tab-logs.php', true, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advanced tab content template
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns advanced tab content as HTML string
|
||||
*/
|
||||
public function get_advanced_contents() {
|
||||
new MPSUM_Admin_Advanced();
|
||||
if (Easy_Updates_Manager()->is_premium()) {
|
||||
new MPSUM_Premium();
|
||||
}
|
||||
return Easy_Updates_Manager()->include_template('admin-tab-advanced.php', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether logging is enabled or not
|
||||
*
|
||||
* @return bool Return true if logging is enabled, otherwise false
|
||||
*/
|
||||
public function is_logs_enabled() {
|
||||
$options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($options['logs']) && 'on' == $options['logs']) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces updates immediately
|
||||
*
|
||||
* @return string Confirmation message of forced updates
|
||||
*/
|
||||
public function force_updates() {
|
||||
return $this->admin_ajax->force_updates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves logs settings
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Confirmation message of saved log option
|
||||
*/
|
||||
public function save_logs_settings($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to save options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->save_logs_settings($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export settings as json file
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function export_settings() {
|
||||
if (!$this->user_can_update()) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->export_settings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Export settings as json file
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function import_settings($data) {
|
||||
if (!$this->user_can_update()) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->import_settings($data['data']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves excluded users option
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Confirmation message of saved users
|
||||
*/
|
||||
public function save_excluded_users($data) {
|
||||
if (!current_user_can('promote_users')) {
|
||||
return __('User has insufficient capability to promote users', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->admin_ajax->save_excluded_users($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable auto back
|
||||
*
|
||||
* @return string Confirmation message of enabling auto backup
|
||||
*/
|
||||
public function enable_auto_backup() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to take backups', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->enable_auto_backup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable auto back
|
||||
*
|
||||
* @return string Confirmation message of enabling auto backup
|
||||
*/
|
||||
public function disable_auto_backup() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to take backups', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->disable_auto_backup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save update cron schedule
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns next schedule message
|
||||
*/
|
||||
public function save_cron_schedule($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to take backups', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->save_cron_schedule($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save delayed update duration
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns success message
|
||||
*/
|
||||
public function save_delay_updates($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->save_delay_updates($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save anonymize update options
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return string Returns success message
|
||||
*/
|
||||
public function save_anonymize_updates($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->save_anonymize_updates($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enables logging
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function enable_logs() {
|
||||
return $this->admin_ajax->enable_logs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if plugins are in the WordPress Directory
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string|array Result of ajax call
|
||||
*/
|
||||
public function check_plugins($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->check_plugins($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables White-list
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function whitelist_save($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->whitelist_save($data['data']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset White-list
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function whitelist_reset($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->whitelist_reset($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables webhook
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function enable_webhook($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->enable_webhook($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables webhook
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function disable_webhook($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->disable_webhook($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables safe mode
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function enable_safe_mode($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->enable_safe_mode($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables safe mode
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function disable_safe_mode($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->disable_safe_mode($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables Version Control Protection
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function enable_version_control($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->enable_version_control_protection($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables Version Control Protection
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function disable_version_control($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->disable_version_control_protection($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables Unmaintained Plugin Check
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function enable_unmaintained_plugins_check($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->enable_unmaintained_plugins($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables Unmaintained Plugin Check
|
||||
*
|
||||
* @param array $data An array of updated options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function disable_unmaintained_plugins_check($data) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
return $this->premium_admin_ajax->disable_unmaintained_plugins($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears logs
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function clear_logs() {
|
||||
return $this->admin_ajax->clear_logs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all options
|
||||
*
|
||||
* @return string Confirmation message
|
||||
*/
|
||||
public function reset_options() {
|
||||
return $this->admin_ajax->reset_options();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns paged argument and view filter argument
|
||||
*
|
||||
* @param array $data - Data from the remote call
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function _get_paged_view_status($data) {
|
||||
$paged = isset($data['data']['paged']) ? $data['data']['paged'] : '1';
|
||||
$view = isset($data['data']['view']) ? $data['data']['view'] : 'all';
|
||||
return array('paged' => $paged, 'view' => $view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether you can do updates to core, plugins and themes
|
||||
*
|
||||
* @return bool True if user can do updates, false otherwise
|
||||
*/
|
||||
private function user_can_update() {
|
||||
if (current_user_can('update_themes') && current_user_can('update_plugins') && current_user_can('update_core')) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (class_exists('MPSUM_CONSTANT_CHECKS')) return;
|
||||
|
||||
/**
|
||||
* Class MPSUM_CONSTANT_CHECKS
|
||||
*
|
||||
* Checks for wp-config constants that may disable the plugin.
|
||||
*/
|
||||
class MPSUM_CONSTANT_CHECKS {
|
||||
|
||||
/**
|
||||
* MPSUM_Reset_Options constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a singleton instance
|
||||
*
|
||||
* @return MPSUM_Reset_Options object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of constants which are active but prohibited
|
||||
*
|
||||
* @return array a list of constants that may prevent automatic updates from being work properly
|
||||
*/
|
||||
public function get_prohibited_active_constants() {
|
||||
$constants = array();
|
||||
if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
|
||||
$constants[] = 'DISABLE_WP_CRON';
|
||||
}
|
||||
return $constants;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
<?php
|
||||
/**
|
||||
* Controller class for disabling updates throughout WordPress.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class MPSUM_Disable_Updates {
|
||||
|
||||
/**
|
||||
* Holds the class instance.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
* @var MPSUM_Disable_Updates $instance
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
private $is_core_updating_allowed = true;
|
||||
|
||||
/**
|
||||
* Set a class instance.
|
||||
*
|
||||
* Set a class instance.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
*/
|
||||
public static function run() {
|
||||
if (null == self::$instance) {
|
||||
self::$instance = new self;
|
||||
}
|
||||
} //end get_instance
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Read in the plugin options and determine which updates are disabled.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function __construct() {
|
||||
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
|
||||
// Disable Footer Nag
|
||||
if (defined('EUM_ENABLE_WORDPRESS_FOOTER_VERSION') && !EUM_ENABLE_WORDPRESS_FOOTER_VERSION) {
|
||||
add_filter('update_footer', '__return_empty_string', 11);
|
||||
}
|
||||
|
||||
// Disable Browser Nag
|
||||
if (defined('EUM_ENABLE_BROWSER_NAG') && !EUM_ENABLE_BROWSER_NAG) {
|
||||
add_action('wp_dashboard_setup', array( $this, 'disable_browser_nag' ), 9);
|
||||
add_action('wp_network_dashboard_setup', array( $this, 'disable_browser_nag' ), 9);
|
||||
}
|
||||
|
||||
// Recommended patch from Flywheel to turn on plugin and theme auto-updates.
|
||||
add_action('wp_update_plugins', array($this, 'maybe_auto_update'), 20);
|
||||
|
||||
// Disable All Updates
|
||||
if (isset($core_options['all_updates']) && 'off' == $core_options['all_updates']) {
|
||||
new MPSUM_Disable_Updates_All();
|
||||
return;
|
||||
} else {
|
||||
add_filter('automatic_updater_disabled', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('file_mod_allowed', array('MPSUM_Utils', 'allow_file_modifications_for_automatic_updating'), PHP_INT_MAX - 10, 2);
|
||||
}
|
||||
|
||||
// Enable or disable version control protection
|
||||
if (Easy_Updates_Manager()->is_premium()) {
|
||||
if (isset($core_options['version_control']) && 'on' == $core_options['version_control']) {
|
||||
new MPSUM_Disable_VCS();
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($core_options['core_updates']) && 'off' == $core_options['core_updates']) {
|
||||
// Completely disable WordPress Updates
|
||||
new MPSUM_Disable_Updates_WordPress();
|
||||
} else {
|
||||
// Core Development Updates
|
||||
add_filter('allow_dev_auto_core_updates', array($this, 'core_should_update_to_new_version'), PHP_INT_MAX - 10);
|
||||
|
||||
// Core Major Updates
|
||||
add_filter('allow_major_auto_core_updates', array($this, 'core_should_update_to_new_version'), PHP_INT_MAX - 10);
|
||||
|
||||
// Core Minor Updates
|
||||
add_filter('allow_minor_auto_core_updates', array($this, 'core_should_update_to_new_version'), PHP_INT_MAX - 10);
|
||||
|
||||
// Core Global Updates - a hook for making final decision as to whether core updating is allowed after examining other core-related hooks, also ensuring that no other filters will override our value
|
||||
add_filter('auto_update_core', array($this, 'is_core_updating_allowed'), PHP_INT_MAX - 10);
|
||||
if (!isset($core_options['core_updates']) || 'on' == $core_options['core_updates']) $this->is_core_updating_allowed = false; // on means manually update
|
||||
|
||||
// Manually update / Disables Core Automatic Updates
|
||||
// When the __return_false function is hooked to the three filters above, that means core automatic updates is disabled or it's a manually update
|
||||
}
|
||||
|
||||
// Disable Plugin Updates
|
||||
if (isset($core_options['plugin_updates']) && 'off' == $core_options['plugin_updates']) {
|
||||
new MPSUM_Disable_Updates_Plugins();
|
||||
}
|
||||
|
||||
// Disable Theme Updates
|
||||
if (isset($core_options['theme_updates']) && 'off' == $core_options['theme_updates']) {
|
||||
new MPSUM_Disable_Updates_Themes();
|
||||
}
|
||||
|
||||
// Disable Translation Updates
|
||||
if (isset($core_options['translation_updates']) && 'off' == $core_options['translation_updates']) {
|
||||
new MPSUM_Disable_Updates_Translations();
|
||||
}
|
||||
|
||||
// Enable Translation Updates
|
||||
if (isset($core_options['translation_updates']) && 'automatic' == $core_options['translation_updates']) {
|
||||
add_filter('auto_update_translation', '__return_true', PHP_INT_MAX - 10);
|
||||
add_filter('async_update_translation', '__return_true', PHP_INT_MAX - 10);
|
||||
}
|
||||
|
||||
// Disable Translation Updates
|
||||
if (!isset($core_options['translation_updates']) || in_array($core_options['translation_updates'], array('on', 'automatic_off'))) { // After 9.0.12 version, translation 'Disable auto updates' is removed and is united to 'Manually update' as they are just the same
|
||||
add_filter('auto_update_translation', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('async_update_translation', '__return_false', PHP_INT_MAX - 10);
|
||||
}
|
||||
|
||||
// Disable the Update Notification
|
||||
if (isset($core_options['notification_core_update_emails_plugins']) && 'off' == $core_options['notification_core_update_emails_plugins']) {
|
||||
add_filter('send_update_notification_email', array( $this, 'maybe_disable_emails' ), 10, 3);
|
||||
}
|
||||
if (isset($core_options['notification_core_update_emails_themes']) && 'off' == $core_options['notification_core_update_emails_themes']) {
|
||||
add_filter('send_update_notification_email', array( $this, 'maybe_disable_emails' ), 10, 3);
|
||||
}
|
||||
if (isset($core_options['notification_core_update_emails_translations']) && 'off' == $core_options['notification_core_update_emails_translations']) {
|
||||
add_filter('send_update_notification_email', array( $this, 'maybe_disable_emails' ), 10, 3);
|
||||
}
|
||||
|
||||
// Enable Plugin Auto-updates
|
||||
if (isset($core_options['plugin_updates'])) {
|
||||
if ('automatic' === $core_options['plugin_updates']) {
|
||||
add_filter('auto_update_plugin', '__return_true', PHP_INT_MAX - 10, 2);
|
||||
} elseif ('individual' == $core_options['plugin_updates']) {
|
||||
add_filter('auto_update_plugin', array( $this, 'automatic_updates_plugins' ), PHP_INT_MAX - 10, 2);
|
||||
} elseif ('automatic_off' == $core_options['plugin_updates']) {
|
||||
add_filter('auto_update_plugin', '__return_false', PHP_INT_MAX - 10, 2);
|
||||
} elseif ('on' === $core_options['plugin_updates']) { // if manually update option (on) is selected then the auto_update_plugin filter should return boolean false
|
||||
add_filter('auto_update_plugin', '__return_false', 1, 2); // should be one that corresponds with earlier execution (as early as it could)
|
||||
}
|
||||
} else {
|
||||
// if none of the plugin updates setting is selected (it can happen on a fresh EUM install) also return boolean false for the auto_update_plugin filter
|
||||
add_filter('auto_update_plugin', '__return_false', 1, 2); // should be one that corresponds with earlier execution (as early as it could)
|
||||
}
|
||||
|
||||
// Enable Theme Auto-updates
|
||||
if (isset($core_options['theme_updates'])) {
|
||||
if ('automatic' === $core_options['theme_updates']) {
|
||||
add_filter('auto_update_theme', '__return_true', PHP_INT_MAX - 10, 2);
|
||||
} elseif ('individual' == $core_options['theme_updates']) {
|
||||
add_filter('auto_update_theme', array( $this, 'automatic_updates_theme' ), PHP_INT_MAX - 10, 2);
|
||||
} elseif ('automatic_off' == $core_options['theme_updates']) {
|
||||
add_filter('auto_update_theme', '__return_false', PHP_INT_MAX - 10, 2);
|
||||
} elseif ('on' === $core_options['theme_updates']) { // if manually update option (on) is selected then the auto_update_theme filter should return boolean false
|
||||
add_filter('auto_update_theme', '__return_false', 1, 2); // should be one that corresponds with earlier execution (as early as it could)
|
||||
}
|
||||
} else {
|
||||
add_filter('auto_update_theme', '__return_false', 1, 2); // should be one that corresponds with earlier execution (as early as it could)
|
||||
}
|
||||
|
||||
|
||||
// Prevent updates on themes/plugins
|
||||
add_filter('site_transient_update_plugins', array( $this, 'disable_plugin_notifications' ), PHP_INT_MAX - 10);
|
||||
add_filter('site_transient_update_themes', array( $this, 'disable_theme_notifications' ), PHP_INT_MAX - 10);
|
||||
add_filter('http_request_args', array( $this, 'http_request_args_remove_plugins_themes' ), 5, 2);
|
||||
|
||||
// Divi compatibility which allows automatic updates to occur
|
||||
if (isset($GLOBALS['et_core_updates'])) {
|
||||
$divi_upgrader = $GLOBALS['et_core_updates'];
|
||||
remove_action('after_setup_theme', array($divi_upgrader, 'remove_theme_update_actions'), 11);
|
||||
}
|
||||
|
||||
// Initialize and configure notification email filters, whether to disable or enable based on pre-defined user settings
|
||||
MPSUM_Send_Email_Notifications::get_instance();
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Maybe auto update based on if plugin cron has run
|
||||
* Recommended patch from Flywheel to enable plugin/theme upgrades.
|
||||
*
|
||||
* @since 9.0.3
|
||||
*/
|
||||
public function maybe_auto_update() {
|
||||
if (wp_doing_cron() && ! doing_action('wp_maybe_auto_update')) {
|
||||
do_action('wp_maybe_auto_update');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe disable updates.
|
||||
*
|
||||
* Disable background translation emails, plugin emails, theme emails
|
||||
*
|
||||
* @since 5.2.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @param boolean $bool Whether to disable or not
|
||||
* @param string $type ( theme, plugin , translation )
|
||||
* @return boolean
|
||||
*/
|
||||
public function maybe_disable_emails($bool, $type) {
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['notification_core_update_emails_plugins']) && 'off' == $core_options['notification_core_update_emails_plugins'] && 'plugin' == $type) {
|
||||
return false;
|
||||
}
|
||||
if (isset($core_options['notification_core_update_emails_themes']) && 'off' == $core_options['notification_core_update_emails_themes'] && 'theme' == $type) {
|
||||
return false;
|
||||
}
|
||||
if (isset($core_options['notification_core_update_emails_translations']) && 'off' == $core_options['notification_core_update_emails_translations'] && 'translation' == $type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $bool;
|
||||
|
||||
}
|
||||
/**
|
||||
* Disable the out-of-date browser nag on the WordPress Dashboard.
|
||||
*
|
||||
* Disable the out-of-date browser nag on the WordPress Dashboard.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal uses wp_dashboard_setup action on single-site, wp_network_dashboard_setup action on multisite
|
||||
*/
|
||||
public function disable_browser_nag() {
|
||||
remove_meta_box('dashboard_browser_nag', 'dashboard-network', 'normal');
|
||||
remove_meta_box('dashboard_browser_nag', 'dashboard', 'normal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables plugin automatic updates on an individual basis.
|
||||
*
|
||||
* Enables plugin automatic updates on an individual basis.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal uses auto_update_plugin filter
|
||||
*
|
||||
* @param bool $update Whether the item has automatic updates enabled
|
||||
* @param object $item Object holding the asset to be updated
|
||||
* @return bool True of automatic updates enabled, false if not
|
||||
*/
|
||||
public function automatic_updates_plugins($update, $item) {
|
||||
$plugin_automatic_options = MPSUM_Updates_Manager::get_options('plugins_automatic');
|
||||
if (MPSUM_Utils::is_wp_site_health_plugin_theme($item) || (isset($item->plugin) && in_array($item->plugin, $plugin_automatic_options))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables theme automatic updates on an individual basis.
|
||||
*
|
||||
* Enables theme automatic updates on an individual basis.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal uses auto_update_theme filter
|
||||
*
|
||||
* @param bool $update Whether the item has automatic updates enabled
|
||||
* @param object $item Object holding the asset to be updated
|
||||
* @return bool True of automatic updates enabled, false if not
|
||||
*/
|
||||
public function automatic_updates_theme($update, $item) {
|
||||
$theme_automatic_options = MPSUM_Updates_Manager::get_options('themes_automatic');
|
||||
if (MPSUM_Utils::is_wp_site_health_plugin_theme($item) || (isset($item->theme) && in_array($item->theme, $theme_automatic_options))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables plugin notifications on an individual basis.
|
||||
*
|
||||
* Disables plugin notifications on an individual basis.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal uses site_transient_update_plugins filter
|
||||
*
|
||||
* @param object $plugins Plugins that may have update notifications
|
||||
* @return object Updated plugins list with updates
|
||||
*/
|
||||
public function disable_plugin_notifications($plugins) {
|
||||
if (!isset($plugins->response) || empty($plugins->response)) return $plugins;
|
||||
|
||||
$plugin_options = MPSUM_Updates_Manager::get_options('plugins');
|
||||
foreach ($plugin_options as $plugin) {
|
||||
unset($plugins->response[$plugin]);
|
||||
}
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables theme notifications on an individual basis.
|
||||
*
|
||||
* Disables theme notifications on an individual basis.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal uses site_transient_update_themes filter
|
||||
*
|
||||
* @param object $themes Themes that may have update notifications
|
||||
* @return object Updated themes list with updates
|
||||
*/
|
||||
public function disable_theme_notifications($themes) {
|
||||
if (!isset($themes->response) || empty($themes->response)) return $themes;
|
||||
|
||||
$theme_options = MPSUM_Updates_Manager::get_options('themes');
|
||||
foreach ($theme_options as $theme) {
|
||||
unset($themes->response[$theme]);
|
||||
}
|
||||
return $themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables theme and plugin http requests on an individual basis.
|
||||
*
|
||||
* Disables theme and plugin http requests on an individual basis.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
* @internal uses http_request_args filter
|
||||
*
|
||||
* @param array $r Request array
|
||||
* @param string $url URL requested
|
||||
* @return array Updated Request array
|
||||
*/
|
||||
public function http_request_args_remove_plugins_themes($r, $url) {
|
||||
if (!MPSUM_Utils::is_wp_api($url)) {
|
||||
return $r;
|
||||
}
|
||||
|
||||
if (isset($r['body']['plugins'])) {
|
||||
$r_plugins = json_decode($r['body']['plugins'], true);
|
||||
if (!empty($r_plugins['active'])) {
|
||||
if (is_array($r_plugins['active'])) {
|
||||
$plugin_options = MPSUM_Updates_Manager::get_options('plugins');
|
||||
foreach ($plugin_options as $plugin) {
|
||||
unset($r_plugins[$plugin]);
|
||||
if (false !== $key = array_search($plugin, $r_plugins['active'])) {
|
||||
unset($r_plugins['active'][$key]);
|
||||
$r_plugins['active'] = array_values($r_plugins['active']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log("EUM: http_request_args_remove_plugins_themes(): the 'plugins' parameter was non-empty, but not an array; please report this in a support channel: ".serialize($r_plugins['active'])); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Logging allowed only in debug mode.
|
||||
}
|
||||
}
|
||||
$r['body']['plugins'] = wp_json_encode($r_plugins);
|
||||
}
|
||||
}
|
||||
if (isset($r['body']['themes'])) {
|
||||
$r_themes = json_decode($r['body']['themes'], true);
|
||||
$theme_options = MPSUM_Updates_Manager::get_options('themes');
|
||||
foreach ($theme_options as $theme) {
|
||||
unset($r_themes[$theme]);
|
||||
}
|
||||
$r['body']['themes'] = wp_json_encode($r_themes);
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether WordPress Core should update to a new version or not
|
||||
*
|
||||
* @return boolean True if we should update to the new version, false otherwise
|
||||
*/
|
||||
public function core_should_update_to_new_version() {
|
||||
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
|
||||
if (doing_filter('allow_dev_auto_core_updates')) {
|
||||
$this->is_core_updating_allowed = isset($core_options['core_updates']) && in_array($core_options['core_updates'], array('automatic', 'automatic_minor')) && isset($core_options['automatic_development_updates']) && 'on' == $core_options['automatic_development_updates'] ? true : false;
|
||||
} elseif (doing_filter('allow_major_auto_core_updates')) {
|
||||
$this->is_core_updating_allowed = isset($core_options['core_updates']) && 'automatic' === $core_options['core_updates'] ? true : false;
|
||||
} elseif (doing_filter('allow_minor_auto_core_updates')) {
|
||||
$this->is_core_updating_allowed = isset($core_options['core_updates']) && in_array($core_options['core_updates'], array('automatic', 'automatic_minor')) ? true : false;
|
||||
}
|
||||
|
||||
return $this->is_core_updating_allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value that previously has been looked over the core-related filters as to whether core updating is allowed or not
|
||||
*/
|
||||
public function is_core_updating_allowed() {
|
||||
return $this->is_core_updating_allowed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/**
|
||||
* Disables all WordPress updates.
|
||||
*
|
||||
* Disables all WordPress updates.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Disable all updates
|
||||
* Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
|
||||
*/
|
||||
class MPSUM_Disable_Updates_All {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('admin_init', array( $this, 'admin_init' ));
|
||||
|
||||
/*
|
||||
* Disable Theme Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
add_filter('pre_transient_update_themes', array( $this, 'last_checked_now' ));
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
add_filter('pre_site_transient_update_themes', array( $this, 'last_checked_now' ));
|
||||
|
||||
/*
|
||||
* Disable Plugin Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
add_action('pre_transient_update_plugins', array( $this, 'last_checked_now' ));
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
add_filter('pre_site_transient_update_plugins', array( $this, 'last_checked_now' ));
|
||||
|
||||
/*
|
||||
* Disable Core Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
add_filter('pre_transient_update_core', array( $this, 'last_checked_now' ));
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
add_filter('pre_site_transient_update_core', array( $this, 'last_checked_now' ));
|
||||
|
||||
|
||||
/*
|
||||
* Disable All Automatic Updates
|
||||
* 3.7+
|
||||
*
|
||||
* @author sLa NGjI's @ slangji.wordpress.com
|
||||
*/
|
||||
add_filter('auto_update_translation', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('async_update_translation', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('automatic_updater_disabled', '__return_true', PHP_INT_MAX - 10);
|
||||
add_filter('allow_minor_auto_core_updates', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('allow_major_auto_core_updates', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('allow_dev_auto_core_updates', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('auto_update_core', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('wp_auto_update_core', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('auto_core_update_send_email', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('send_core_update_notification_email', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('auto_update_plugin', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('auto_update_theme', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('automatic_updates_send_debug_email', '__return_false', PHP_INT_MAX - 10);
|
||||
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Initialize and load the plugin stuff
|
||||
*
|
||||
* @since 1.3
|
||||
* @author scripts@schloebe.de
|
||||
*/
|
||||
function admin_init() {
|
||||
/*
|
||||
* Disable Theme Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
remove_action('load-themes.php', 'wp_update_themes');
|
||||
remove_action('load-update.php', 'wp_update_themes');
|
||||
remove_action('admin_init', '_maybe_update_themes');
|
||||
remove_action('wp_update_themes', 'wp_update_themes');
|
||||
wp_clear_scheduled_hook('wp_update_themes');
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
remove_action('load-update-core.php', 'wp_update_themes');
|
||||
wp_clear_scheduled_hook('wp_update_themes');
|
||||
|
||||
|
||||
/*
|
||||
* Disable Plugin Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
remove_action('load-plugins.php', 'wp_update_plugins');
|
||||
remove_action('load-update.php', 'wp_update_plugins');
|
||||
remove_action('admin_init', '_maybe_update_plugins');
|
||||
remove_action('wp_update_plugins', 'wp_update_plugins');
|
||||
wp_clear_scheduled_hook('wp_update_plugins');
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
remove_action('load-update-core.php', 'wp_update_plugins');
|
||||
wp_clear_scheduled_hook('wp_update_plugins');
|
||||
|
||||
|
||||
/*
|
||||
* Disable Core Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
remove_action('wp_version_check', 'wp_version_check');
|
||||
remove_action('admin_init', '_maybe_update_core');
|
||||
wp_clear_scheduled_hook('wp_version_check');
|
||||
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
wp_clear_scheduled_hook('wp_version_check');
|
||||
|
||||
|
||||
/*
|
||||
* 3.7+
|
||||
*/
|
||||
remove_action('wp_maybe_auto_update', 'wp_maybe_auto_update');
|
||||
remove_action('admin_init', 'wp_maybe_auto_update');
|
||||
remove_action('admin_init', 'wp_auto_update_core');
|
||||
wp_clear_scheduled_hook('wp_maybe_auto_update');
|
||||
}
|
||||
|
||||
/**
|
||||
* Last checked for updates
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function last_checked_now() {
|
||||
include ABSPATH . WPINC . '/version.php';
|
||||
$current = new stdClass;
|
||||
$current->updates = array();
|
||||
$current->version_checked = $wp_version;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- $wp_version is being populated via the version.php include
|
||||
$current->last_checked = time();
|
||||
|
||||
return $current;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* Disables all WordPress plugin updates.
|
||||
*
|
||||
* Disables all WordPress plugin updates.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Disable plugin updates
|
||||
* Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
|
||||
*/
|
||||
class MPSUM_Disable_Updates_Plugins {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('admin_init', array($this, 'admin_init'));
|
||||
|
||||
/*
|
||||
* Disable Plugin Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
add_action('pre_transient_update_plugins', array($this, 'last_checked_now'), 10, 2);
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
add_filter('pre_site_transient_update_plugins', array($this, 'last_checked_now'), 10, 2);
|
||||
|
||||
/*
|
||||
* Disable All Automatic Updates (3.7+)
|
||||
*/
|
||||
add_filter('auto_update_plugin', '__return_false');
|
||||
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Initialize and load the plugin stuff
|
||||
*
|
||||
* @since 1.3
|
||||
* @author scripts@schloebe.de
|
||||
*/
|
||||
function admin_init() {
|
||||
/*
|
||||
* Disable Plugin Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
remove_action('load-plugins.php', 'wp_update_plugins');
|
||||
remove_action('load-update.php', 'wp_update_plugins');
|
||||
remove_action('admin_init', '_maybe_update_plugins');
|
||||
remove_action('wp_update_plugins', 'wp_update_plugins');
|
||||
wp_clear_scheduled_hook('wp_update_plugins');
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
remove_action('load-update-core.php', 'wp_update_plugins');
|
||||
wp_clear_scheduled_hook('wp_update_plugins');
|
||||
|
||||
add_action('upgrader_process_complete', array($this, 'maybe_clear_transient'), 10, 2);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the auto updater is complete
|
||||
*
|
||||
* @param WP_Upgrader $wp_upgrader WP Upgrder Instance
|
||||
* @param array $update_type Type of upgrade it's doing
|
||||
*/
|
||||
public function maybe_clear_transient($wp_upgrader, $update_type) {
|
||||
if (isset($update_type['type']) && 'translation' === $update_type['type']) {
|
||||
delete_site_transient('eum_plugins_checked');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Last checked core updates
|
||||
*
|
||||
* @param string $transient Specify transients
|
||||
* @param string $key Name of the transient
|
||||
* @return object
|
||||
*/
|
||||
public function last_checked_now($transient, $key) {
|
||||
$checked = get_site_transient('eum_plugins_checked');
|
||||
if ($checked) return $checked;
|
||||
remove_action('pre_transient_update_plugins', array($this, 'last_checked_now'), 10, 2);
|
||||
remove_filter('pre_site_transient_update_plugins', array($this, 'last_checked_now'), 10, 2);
|
||||
delete_site_transient($key);
|
||||
wp_update_plugins();
|
||||
$option = get_site_transient($key);
|
||||
include ABSPATH . WPINC . '/version.php';
|
||||
$current = new stdClass;
|
||||
$current->updates = array();
|
||||
$current->version_checked = $wp_version;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- $wp_version is being populated via the version.php include
|
||||
$current->last_checked = time();
|
||||
if (isset($option->translations)) {
|
||||
$current->translations = $option->translations;
|
||||
}
|
||||
add_action('pre_transient_update_plugins', array($this, 'last_checked_now'), 10, 2);
|
||||
add_filter('pre_site_transient_update_plugins', array($this, 'last_checked_now'), 10, 2);
|
||||
set_site_transient('eum_plugins_checked', $current, 6 * 60 * 60);
|
||||
return $current;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* Disables all WordPress theme updates.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Disable theme updates
|
||||
* Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
|
||||
*/
|
||||
class MPSUM_Disable_Updates_Themes {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('admin_init', array($this, 'admin_init'));
|
||||
|
||||
|
||||
/*
|
||||
* Disable Theme Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
add_filter('pre_transient_update_themes', array($this, 'last_checked_now'), 10, 2);
|
||||
|
||||
/*
|
||||
* 3.0 - Commented it out to allow translations - Ronald Huereca
|
||||
*/
|
||||
add_filter('pre_site_transient_update_themes', array($this, 'last_checked_now'), 10, 2);
|
||||
|
||||
/*
|
||||
* Disable All Automatic Updates
|
||||
* 3.7+
|
||||
*
|
||||
* @author sLa NGjI's @ slangji.wordpress.com
|
||||
*/
|
||||
add_filter('auto_update_theme', '__return_false');
|
||||
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Initialize and load the plugin stuff
|
||||
*
|
||||
* @since 1.3
|
||||
* @author scripts@schloebe.de
|
||||
*/
|
||||
function admin_init() {
|
||||
/*
|
||||
* Disable Theme Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
remove_action('load-themes.php', 'wp_update_themes');
|
||||
remove_action('load-update.php', 'wp_update_themes');
|
||||
remove_action('admin_init', '_maybe_update_themes');
|
||||
remove_action('wp_update_themes', 'wp_update_themes');
|
||||
wp_clear_scheduled_hook('wp_update_themes');
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
remove_action('load-update-core.php', 'wp_update_themes');
|
||||
wp_clear_scheduled_hook('wp_update_themes');
|
||||
|
||||
add_action('upgrader_process_complete', array($this, 'maybe_clear_transient'), 10, 2);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the auto updater is complete
|
||||
*
|
||||
* @param WP_Upgrader $wp_upgrader WP Upgrder Instance
|
||||
* @param array $update_type Type of upgrade it's doing
|
||||
*/
|
||||
public function maybe_clear_transient($wp_upgrader, $update_type) {
|
||||
if (isset($update_type['type']) && 'translation' === $update_type['type']) {
|
||||
delete_site_transient('eum_themes_checked');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Last checked core updates
|
||||
*
|
||||
* @param string $transient Specify transients
|
||||
* @param string $key Name of the transient
|
||||
* @return object
|
||||
*/
|
||||
public function last_checked_now($transient, $key) {
|
||||
$checked = get_site_transient('eum_themes_checked');
|
||||
if ($checked) return $checked;
|
||||
remove_action('pre_transient_update_themes', array( $this, 'last_checked_now'), 10, 2);
|
||||
remove_filter('pre_site_transient_update_themes', array($this, 'last_checked_now'), 10, 2);
|
||||
delete_site_transient($key);
|
||||
wp_update_themes();
|
||||
$option = get_site_transient($key);
|
||||
include ABSPATH . WPINC . '/version.php';
|
||||
$current = new stdClass;
|
||||
$current->updates = array();
|
||||
$current->version_checked = $wp_version;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- $wp_version is being populated via the inclusion of version.php
|
||||
$current->last_checked = time();
|
||||
if (isset($option->translations)) {
|
||||
$current->translations = $option->translations;
|
||||
}
|
||||
add_action('pre_transient_update_themes', array($this, 'last_checked_now'), 10, 2);
|
||||
add_filter('pre_site_transient_update_themes', array($this, 'last_checked_now'), 10, 2);
|
||||
set_site_transient('eum_themes_checked', $current, 6 * 60 * 60);
|
||||
return $current;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Disables all WordPress translation updates.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Disable translations updates
|
||||
* Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
|
||||
*/
|
||||
class MPSUM_Disable_Updates_Translations {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
/*
|
||||
* Disable All Automatic Updates
|
||||
* 3.7+
|
||||
*
|
||||
* @author sLa NGjI's @ slangji.wordpress.com
|
||||
*/
|
||||
add_filter('auto_update_translation', '__return_false');
|
||||
add_filter('async_update_translation', '__return_false');
|
||||
|
||||
/*
|
||||
* Disable Theme Translations
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
add_filter('pre_transient_update_themes', array($this, 'remove_translations'), 10, 2);
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
add_filter('pre_site_transient_update_themes', array($this, 'remove_translations'), 10, 2);
|
||||
|
||||
|
||||
/*
|
||||
* Disable Plugin Translations
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
add_action('pre_transient_update_plugins', array($this, 'remove_translations'), 10, 2);
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
add_filter('pre_site_transient_update_plugins', array($this, 'remove_translations'), 10, 2);
|
||||
|
||||
|
||||
/*
|
||||
* Disable Core Translations
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
add_filter('pre_transient_update_core', array($this, 'remove_translations'), 10, 2);
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
add_filter('pre_site_transient_update_core', array($this, 'remove_translations'), 10, 2);
|
||||
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Remove translations
|
||||
*
|
||||
* @param array $transient Transient options
|
||||
* @param value $key Transient value name
|
||||
* @return array
|
||||
*/
|
||||
public function remove_translations($transient, $key) {
|
||||
remove_filter('pre_transient_update_themes', array($this, 'remove_translations'), 10, 2);
|
||||
remove_filter('pre_site_transient_update_themes', array($this, 'remove_translations'), 10, 2);
|
||||
remove_filter('pre_transient_update_plugins', array($this, 'remove_translations'), 10, 2);
|
||||
remove_filter('pre_site_transient_update_plugins', array($this, 'remove_translations'), 10, 2);
|
||||
remove_filter('pre_transient_update_core', array($this, 'remove_translations'), 10, 2);
|
||||
remove_filter('pre_site_transient_update_core', array($this, 'remove_translations'), 10, 2);
|
||||
$option = get_site_transient($key);
|
||||
if (isset($option->translations)) {
|
||||
$option->translations = array();
|
||||
}
|
||||
add_filter('pre_transient_update_themes', array($this, 'remove_translations'), 10, 2);
|
||||
add_filter('pre_site_transient_update_themes', array($this, 'remove_translations'), 10, 2);
|
||||
add_filter('pre_transient_update_plugins', array($this, 'remove_translations'), 10, 2);
|
||||
add_filter('pre_site_transient_update_plugins', array($this, 'remove_translations'), 10, 2);
|
||||
add_filter('pre_transient_update_core', array($this, 'remove_translations'), 10, 2);
|
||||
add_filter('pre_site_transient_update_core', array($this, 'remove_translations'), 10, 2);
|
||||
;
|
||||
return $option;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* Disables all core WordPress updates.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 5.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Disable WordPress core updates
|
||||
* Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
|
||||
*/
|
||||
class MPSUM_Disable_Updates_WordPress {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('admin_init', array($this, 'admin_init'));
|
||||
|
||||
|
||||
/*
|
||||
* Disable Core Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
add_filter('pre_transient_update_core', array($this, 'last_checked_now'), 10, 2);
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
add_filter('pre_site_transient_update_core', array($this, 'last_checked_now'), 10, 2);
|
||||
|
||||
|
||||
/*
|
||||
* Disable All Automatic Updates
|
||||
* 3.7+
|
||||
*
|
||||
* @author sLa NGjI's @ slangji.wordpress.com
|
||||
*/
|
||||
add_filter('allow_minor_auto_core_updates', '__return_false');
|
||||
add_filter('allow_major_auto_core_updates', '__return_false');
|
||||
add_filter('allow_dev_auto_core_updates', '__return_false');
|
||||
add_filter('auto_update_core', '__return_false');
|
||||
add_filter('wp_auto_update_core', '__return_false');
|
||||
add_filter('auto_core_update_send_email', '__return_false');
|
||||
add_filter('send_core_update_notification_email', '__return_false');
|
||||
add_filter('automatic_updates_send_debug_email', '__return_false');
|
||||
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Initialize and load the plugin stuff
|
||||
*
|
||||
* @since 1.3
|
||||
* @author scripts@schloebe.de
|
||||
*/
|
||||
function admin_init() {
|
||||
/*
|
||||
* Disable Core Updates
|
||||
* 2.8 to 3.0
|
||||
*/
|
||||
remove_action('wp_version_check', 'wp_version_check');
|
||||
remove_action('admin_init', '_maybe_update_core');
|
||||
wp_clear_scheduled_hook('wp_version_check');
|
||||
|
||||
|
||||
/*
|
||||
* 3.0
|
||||
*/
|
||||
wp_clear_scheduled_hook('wp_version_check');
|
||||
|
||||
|
||||
/*
|
||||
* 3.7+
|
||||
*/
|
||||
remove_action('wp_maybe_auto_update', 'wp_maybe_auto_update');
|
||||
remove_action('admin_init', 'wp_maybe_auto_update');
|
||||
remove_action('admin_init', 'wp_auto_update_core');
|
||||
wp_clear_scheduled_hook('wp_maybe_auto_update');
|
||||
|
||||
add_action('upgrader_process_complete', array($this, 'maybe_clear_transient'), 10, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the auto updater is complete
|
||||
*
|
||||
* @param WP_Upgrader $wp_upgrader WP Upgrder Instance
|
||||
* @param array $update_type Type of upgrade it's doing
|
||||
*/
|
||||
public function maybe_clear_transient($wp_upgrader, $update_type) {
|
||||
if (isset($update_type['type']) && 'translation' === $update_type['type']) {
|
||||
delete_site_transient('eum_core_checked');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Last checked core updates
|
||||
*
|
||||
* @param string $transient Specify transients
|
||||
* @param string $key Name of the transient
|
||||
* @return object
|
||||
*/
|
||||
public function last_checked_now($transient, $key) {
|
||||
$checked = get_site_transient('eum_core_checked');
|
||||
if ($checked) return $checked;
|
||||
remove_action('pre_transient_update_core', array($this, 'last_checked_now'), 10, 2);
|
||||
remove_filter('pre_site_transient_update_core', array($this, 'last_checked_now'), 10, 2);
|
||||
delete_site_transient($key);
|
||||
wp_version_check();
|
||||
$option = get_site_transient($key);
|
||||
include ABSPATH . WPINC . '/version.php';
|
||||
$current = new stdClass;
|
||||
$current->updates = array();
|
||||
$current->version_checked = $wp_version;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- $wp_version is being populated via the version.php include
|
||||
$current->last_checked = time();
|
||||
if (isset($option->translations)) {
|
||||
$current->translations = $option->translations;
|
||||
}
|
||||
add_action('pre_transient_update_core', array($this, 'last_checked_now'), 10, 2);
|
||||
add_filter('pre_site_transient_update_core', array($this, 'last_checked_now'), 10, 2);
|
||||
set_site_transient('eum_core_checked', $current, 6 * 60 * 60);
|
||||
return $current;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Disables all VCS updates.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 8.0.6
|
||||
*
|
||||
* Credit: https://github.com/cliffordp/tk-exclude-vcs-updates
|
||||
*/
|
||||
class MPSUM_Disable_VCS {
|
||||
|
||||
/**
|
||||
* Store the VCS variables.
|
||||
*
|
||||
* @var array $vcs
|
||||
*/
|
||||
private $vcs = array();
|
||||
|
||||
/**
|
||||
* Store a list of excluded plugins.
|
||||
*
|
||||
* @var array $excluded_plugins
|
||||
*/
|
||||
private $excluded_plugins = array();
|
||||
|
||||
/**
|
||||
* Store a list of excluded themes.
|
||||
*
|
||||
* @var array $excluded_themes
|
||||
*/
|
||||
private $excluded_themes = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->vcs = array(
|
||||
'.git',
|
||||
'.hg', // Mercurial
|
||||
'.svn',
|
||||
);
|
||||
|
||||
// Exclude plugins from VCS
|
||||
add_filter('site_transient_update_plugins', array($this, 'process_plugin_updates'), 100);
|
||||
add_filter('site_transient_update_themes', array($this, 'process_theme_updates'), 100);
|
||||
add_action('admin_notices', array($this, 'notice'), 5);
|
||||
add_action('network_admin_notices', array($this, 'notice'), 5);
|
||||
add_action('eum_plugins_tab_header', array($this, 'show_eum_plugins_tab_warning'));
|
||||
add_action('eum_themes_tab_header', array($this, 'show_eum_themes_tab_warning'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude themes under version control.
|
||||
*
|
||||
* @param stdClass $value
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function process_theme_updates($value) {
|
||||
if (isset($value->response)) {
|
||||
foreach ($value->response as $theme_name => $theme_data) {
|
||||
$theme_location = trailingslashit(WP_CONTENT_DIR) . 'themes/' . trailingslashit($theme_name);
|
||||
|
||||
foreach ($this->vcs as $vcs_name) {
|
||||
$find = trailingslashit($theme_location) . $vcs_name;
|
||||
if (file_exists($find)) {
|
||||
$theme = wp_get_theme($theme_name);
|
||||
$this->excluded_themes[] = $theme->get('Name');
|
||||
unset($value->response[$theme_name]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a VCS warning on the EUM plugins tab
|
||||
*/
|
||||
public function show_eum_plugins_tab_warning() {
|
||||
$this->excluded_plugins = array_unique($this->excluded_plugins);
|
||||
if (!empty($this->excluded_plugins)) {
|
||||
$plugin_list = sprintf('<strong>%s</strong>', esc_html(implode(', ', $this->excluded_plugins)));
|
||||
}
|
||||
if (empty($plugin_list)) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="notice notice-warning">
|
||||
<?php
|
||||
// Translators: %s is a list of plugin that are under version control and will not be updated.
|
||||
echo '<p>' . sprintf(esc_html__('The following plugins are under version control and will not be updated: %s', 'stops-core-theme-and-plugin-updates'), wp_kses($plugin_list, array('strong' => array()))) . '</p>';
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a VCS warning on the EUM themes tab
|
||||
*/
|
||||
public function show_eum_themes_tab_warning() {
|
||||
$this->excluded_themes = array_unique($this->excluded_themes);
|
||||
if (!empty($this->excluded_themes)) {
|
||||
$theme_list = sprintf('<strong>%s</strong>', esc_html(implode(', ', $this->excluded_themes)));
|
||||
}
|
||||
if (empty($theme_list)) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="notice notice-warning">
|
||||
<?php
|
||||
// Translators: %s is a list of theme that are under version control and will not be updated.
|
||||
echo '<p>' . sprintf(esc_html__('The following themes are under version control and will not be updated: %s', 'stops-core-theme-and-plugin-updates'), wp_kses($theme_list, array('strong' => array()))) . '</p>';
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude plugins under version control.
|
||||
*
|
||||
* @param stdClass $value
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function process_plugin_updates($value) {
|
||||
if (isset($value->response) && defined('WP_PLUGIN_DIR')) {
|
||||
foreach ($value->response as $plugin_file => $plugin_data) {
|
||||
$plugin_dir_name = plugin_dir_path($plugin_file);
|
||||
$plugin_location = trailingslashit(WP_PLUGIN_DIR) . $plugin_dir_name;
|
||||
|
||||
foreach ($this->vcs as $vcs_name) {
|
||||
$find = trailingslashit($plugin_location) . $vcs_name;
|
||||
if (file_exists($find)) {
|
||||
if (!function_exists('get_plugins')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
$plugin = get_plugins();
|
||||
foreach ($plugin as $plugin_key => $plugin_array) {
|
||||
if ($plugin_key === $plugin_data->plugin) {
|
||||
$this->excluded_plugins[] = $plugin_array['Name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
unset($value->response[$plugin_file]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a notice in the upgrade screen that plugins/themes are under version control.
|
||||
*/
|
||||
public function notice() {
|
||||
$current_screen = get_current_screen();
|
||||
if (empty($this->excluded_plugins) && empty($this->excluded_themes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->excluded_plugins = array_unique($this->excluded_plugins);
|
||||
$this->excluded_themes = array_unique($this->excluded_themes);
|
||||
|
||||
if ('update-core' === $current_screen->base || 'update-core-network' === $current_screen->base) {
|
||||
$plugin_list = '';
|
||||
$theme_list = '';
|
||||
|
||||
if (!empty($this->excluded_plugins)) {
|
||||
$plugin_list = sprintf('<strong>%s</strong>', implode(', ', $this->excluded_plugins));
|
||||
}
|
||||
if (!empty($this->excluded_themes)) {
|
||||
$theme_list = sprintf('<strong>%s</strong>', implode(', ', $this->excluded_themes));
|
||||
}
|
||||
?>
|
||||
<div class="notice notice-warning">
|
||||
<?php
|
||||
if (!empty($plugin_list)) {
|
||||
// Translators: %s is a list of plugin that are under version control and will not be updated.
|
||||
echo '<p>' . sprintf(esc_html__('The following plugins are under version control and will not be updated: %s', 'stops-core-theme-and-plugin-updates'), wp_kses($plugin_list, array('strong' => array()))) . '</p>';
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
if (!empty($theme_list)) {
|
||||
// Translators: %s is a list of theme that are under version control and will not be updated.
|
||||
echo '<p>' . sprintf(esc_html__('The following themes are under version control and will not be updated: %s', 'stops-core-theme-and-plugin-updates'), wp_kses($theme_list, array('strong' => array()))) . '</p>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (class_exists('MPSUM_Exclude_Users')) return;
|
||||
|
||||
/**
|
||||
* Class MPSUM_Exclude_Users
|
||||
*
|
||||
* Handles user exclusion for plugin settings
|
||||
*/
|
||||
class MPSUM_Exclude_Users {
|
||||
|
||||
/**
|
||||
* MPSUM_Exclude_Users constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
add_action('eum_advanced_headings', array($this, 'heading'));
|
||||
add_action('eum_advanced_settings', array($this, 'settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a singleton instance
|
||||
*
|
||||
* @return MPSUM_Exclude_Users object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature heading
|
||||
*/
|
||||
public function heading() {
|
||||
printf('<div data-menu_name="exclude-users" class="active-menu">%s <span class="eum-advanced-menu-text">%s</span></div>', '<i class="material-icons">stop_screen_share</i>', esc_html__('Exclude users', 'stops-core-theme-and-plugin-updates'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature settings
|
||||
*/
|
||||
public function settings() {
|
||||
Easy_Updates_Manager()->include_template('exclude-users.php');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (class_exists('MPSUM_Force_Updates')) return;
|
||||
|
||||
/**
|
||||
* Class MPSUM_Force_Updates
|
||||
*
|
||||
* Forces automatic updates to take place immediately
|
||||
*/
|
||||
class MPSUM_Force_Updates {
|
||||
|
||||
/**
|
||||
* MPSUM_Force_Updates constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
add_action('eum_advanced_headings', array($this, 'heading'), 97);
|
||||
add_action('eum_advanced_settings', array($this, 'settings'), 97);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a singleton instance
|
||||
*
|
||||
* @return MPSUM_Force_Updates object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature heading
|
||||
*/
|
||||
public function heading() {
|
||||
printf('<div data-menu_name="force-updates">%s <span class="eum-advanced-menu-text">%s</span></div>', '<i class="material-icons">sync</i>', esc_html__('Force automatic updates', 'stops-core-theme-and-plugin-updates'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature settings
|
||||
*/
|
||||
public function settings() {
|
||||
Easy_Updates_Manager()->include_template('force-updates.php');
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,688 @@
|
||||
<?php
|
||||
/**
|
||||
* Easy Updates Manager log controller
|
||||
*
|
||||
* Initializes the log table and sets up actions/events
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 6.0.0
|
||||
*/
|
||||
class MPSUM_Logs {
|
||||
|
||||
/**
|
||||
* Holds the class instance.
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @access static
|
||||
* @var MPSUM_Logs $instance
|
||||
*/
|
||||
public static $instance = null;
|
||||
|
||||
/**
|
||||
* Holds log messages
|
||||
*
|
||||
* @var array An array of log messages
|
||||
*/
|
||||
protected $log_messages = array();
|
||||
|
||||
/**
|
||||
* Holds update method information
|
||||
*
|
||||
* @var bool Determines whether auto update or manual
|
||||
*/
|
||||
protected $auto_update = false;
|
||||
|
||||
// Format: key=<version>, value=array of method names to call
|
||||
private static $db_updates = array(
|
||||
'1.1.6' => array(
|
||||
'build_table',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Holds version number of the table
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @access private
|
||||
* @var string $slug
|
||||
*/
|
||||
private static $version = '1.1.6';
|
||||
|
||||
/**
|
||||
* Holds a variable for checkin the logs table
|
||||
*
|
||||
* @since 8.0.1
|
||||
* @access private
|
||||
* @var bool $log_table_exists
|
||||
*/
|
||||
private static $log_table_exists = false;
|
||||
|
||||
/**
|
||||
* Set a class instance.
|
||||
*
|
||||
* Set a class instance.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @access static
|
||||
*/
|
||||
public static function run() {
|
||||
if (null == self::$instance) {
|
||||
self::$instance = new self;
|
||||
}
|
||||
return self::$instance;
|
||||
} //end get_instance
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Initialize the class
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @access private
|
||||
*/
|
||||
protected function __construct() {
|
||||
register_shutdown_function(array($this, 'perform_shutdown_task'));
|
||||
|
||||
$this->check_updates();
|
||||
|
||||
add_action('pre_auto_update', array($this, 'pre_auto_update'));
|
||||
add_filter('eum_i18n', array($this, 'logs_i18n'));
|
||||
add_filter('upgrader_package_options', array($this, 'initialize_log_messages'), 10, 1);
|
||||
add_action('automatic_updates_complete', array($this, 'log_automatic_updates'));
|
||||
add_action('upgrader_process_complete', array($this, 'log_updates'), 1, 2);
|
||||
add_filter('upgrader_pre_download', array($this, 'initialize_core_log_messages'), 10, 3);
|
||||
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Make sure PHP fatal errors are caught during an manual/automatic update and try to log anything that gets updated
|
||||
*/
|
||||
public function perform_shutdown_task() {
|
||||
self::maybe_log_updates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write remaining update information in the $log_messages variable into the database (if any)
|
||||
*/
|
||||
private function maybe_log_updates() {
|
||||
if (!is_array($this->log_messages) || empty($this->log_messages)) return;
|
||||
try {
|
||||
$stacktrace = maybe_serialize(apply_filters('eum_normalized_call_stack_args', $this->normalise_call_stack_args(debug_backtrace(false)))); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace, PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection -- Using debug_backtrace() to normalize call stack for logging purposes.
|
||||
} catch (Exception $e) {
|
||||
$stacktrace = serialize(array()); // if an exception still happens even after the call stack is already normalised then we won't provide stacktrace for a log entry
|
||||
// @codingStandardsIgnoreLine
|
||||
} catch (Error $e) {
|
||||
$stacktrace = serialize(array());
|
||||
}
|
||||
foreach ($this->log_messages as $type => $entities) {
|
||||
if (!is_array($entities) || empty($entities)) continue;
|
||||
foreach ($entities as $data) {
|
||||
$this->insert_log($data['name'], $type, $data['from'], $data['to'], $this->auto_update ? 'automatic' : 'manual', doing_action('upgrader_process_complete') || doing_action('automatic_updates_complete') ? 1 : 0, get_current_user_id(), '', $stacktrace);
|
||||
}
|
||||
}
|
||||
$this->log_messages = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize information of an update for each plugin/theme/translation before running the update operation. The information will be stored in the $log_messages variable keyed by the name of what entity is being updated
|
||||
*
|
||||
* @param array $options Package options used by the upgrader
|
||||
* @return array An array of associative arrays keyed by some strings
|
||||
*/
|
||||
public function initialize_log_messages($options) {
|
||||
if (isset($options['hook_extra'], $options['hook_extra']['action']) && 'update' !== $options['hook_extra']['action']) return $options;
|
||||
if (isset($options['hook_extra'], $options['hook_extra']['plugin'])) {
|
||||
$current = get_site_transient('update_plugins');
|
||||
if (isset($current->response[$options['hook_extra']['plugin']])) {
|
||||
$plugins = get_plugins(); // It's not expensive calling this API as WordPress has already cached the result in a WP Cache object
|
||||
if (!isset($this->log_messages['plugin'])) $this->log_messages['plugin'] = array();
|
||||
$this->log_messages['plugin'][$options['hook_extra']['plugin']] = array(
|
||||
'name' => isset($plugins[$options['hook_extra']['plugin']]) && isset($plugins[$options['hook_extra']['plugin']]['Name']) ? $plugins[$options['hook_extra']['plugin']]['Name'] : 'Unknown',
|
||||
'from' => isset($plugins[$options['hook_extra']['plugin']]) && isset($plugins[$options['hook_extra']['plugin']]['Version']) ? $plugins[$options['hook_extra']['plugin']]['Version'] : 0,
|
||||
'to' => isset($current->response[$options['hook_extra']['plugin']]) && is_object($current->response[$options['hook_extra']['plugin']]) && isset($current->response[$options['hook_extra']['plugin']]->new_version) ? $current->response[$options['hook_extra']['plugin']]->new_version : 0,
|
||||
'status' => 0
|
||||
);
|
||||
}
|
||||
} elseif (isset($options['hook_extra'], $options['hook_extra']['theme'])) {
|
||||
$current = get_site_transient('update_themes');
|
||||
if (isset($current->response[$options['hook_extra']['theme']])) {
|
||||
$themes = wp_get_themes(); // It's not expensive calling this API as WordPress has already cached the result as a static variable inside the function
|
||||
if (!isset($this->log_messages['theme'])) $this->log_messages['theme'] = array();
|
||||
$this->log_messages['theme'][$options['hook_extra']['theme']] = array(
|
||||
'name' => isset($themes[$options['hook_extra']['theme']]) && is_a($themes[$options['hook_extra']['theme']], 'WP_Theme') ? $themes[$options['hook_extra']['theme']]->get('Name') : 'Unknown',
|
||||
'from' => isset($themes[$options['hook_extra']['theme']]) && is_a($themes[$options['hook_extra']['theme']], 'WP_Theme') ? $themes[$options['hook_extra']['theme']]->get('Version') : 0,
|
||||
'to' => isset($current->response[$options['hook_extra']['theme']]) && isset($current->response[$options['hook_extra']['theme']]['new_version']) ? $current->response[$options['hook_extra']['theme']]['new_version'] : 0,
|
||||
'status' => 0
|
||||
);
|
||||
}
|
||||
} elseif (isset($options['hook_extra']) && isset($options['hook_extra']['language_update_type']) && isset($options['hook_extra']['language_update'])) { // translation
|
||||
if (!isset($this->log_messages['translation'])) $this->log_messages['translation'] = array();
|
||||
switch ($options['hook_extra']['language_update_type']) {
|
||||
case 'plugin':
|
||||
$current = get_site_transient('update_plugins');
|
||||
if (empty($current->translations)) break;
|
||||
$plugins = get_plugins();
|
||||
$plugins_by_slug = wp_parse_args(wp_list_pluck($current->no_update, 'plugin', 'slug'), wp_list_pluck($current->response, 'plugin', 'slug'));
|
||||
foreach ($current->translations as $translation) {
|
||||
if (isset($options['hook_extra']['language_update']->slug) && $translation['slug'] !== $options['hook_extra']['language_update']->slug) continue;
|
||||
if (isset($plugins[$plugins_by_slug[$translation['slug']]])) {
|
||||
$this->log_messages['translation'][$translation['slug']] = array(
|
||||
'name' => isset($plugins[$plugins_by_slug[$translation['slug']]]['Name']) ? $plugins[$plugins_by_slug[$translation['slug']]]['Name']. ' ('.$translation['language'].')' : 'Unknown ('.$translation['language'].')',
|
||||
'from' => isset($options['hook_extra']['language_update']->version) ? $options['hook_extra']['language_update']->version : 0,
|
||||
'to' => isset($translation['version']) ? $translation['version'] : 0,
|
||||
'status' => 0
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'theme':
|
||||
$current = get_site_transient('update_themes');
|
||||
if (empty($current->translations)) break;
|
||||
$themes = wp_get_themes();
|
||||
foreach ($current->translations as $translation) {
|
||||
if (isset($options['hook_extra']['language_update']->slug) && $translation['slug'] !== $options['hook_extra']['language_update']->slug) continue;
|
||||
if (isset($themes[$translation['slug']])) {
|
||||
$this->log_messages['translation'][$translation['slug']] = array(
|
||||
'name' => is_a($themes[$translation['slug']], 'WP_Theme') ? $themes[$translation['slug']]->get('Name'). ' ('.$translation['language'].')' : 'Unknown ('.$translation['language'].')',
|
||||
'from' => isset($options['hook_extra']['language_update']->version) ? $options['hook_extra']['language_update']->version : 0,
|
||||
'to' => isset($translation['version']) ? $translation['version'] : 0,
|
||||
'status' => 0
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// core
|
||||
$current = get_site_transient('update_core');
|
||||
if (empty($current->translations)) break;
|
||||
foreach ($current->translations as $translation) {
|
||||
$this->log_messages['translation']['wordpress_default_'.$translation['language']] = array(
|
||||
'name' => 'WordPress ('.$translation['language'].')',
|
||||
'from' => isset($options['hook_extra']['language_update']->version) ? $options['hook_extra']['language_update']->version : 0,
|
||||
'to' => isset($translation['version']) ? $translation['version'] : 0,
|
||||
'status' => 0
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize information of a core update before downloading its package. The information will be stored in the $log_messages variable keyed by 'core' string
|
||||
*
|
||||
* @param bool $reply Whether to bail without returning the package. Default false
|
||||
* @param string $package The package file name
|
||||
* @param WP_Upgrader $upgrader The WP_Upgrader instance
|
||||
*/
|
||||
public function initialize_core_log_messages($reply, $package, $upgrader) {
|
||||
add_filter('upgrader_post_install', array($this, 'set_update_status_by_result'), 10, 3);
|
||||
if (is_a($upgrader, 'Core_Upgrader')) {
|
||||
global $wp_version;
|
||||
$current = get_site_transient('update_core');
|
||||
if (!isset($this->log_messages['core']) || !is_array($this->log_messages['core'])) $this->log_messages['core'] = array();
|
||||
$item = array(
|
||||
'name' => 'WordPress',
|
||||
'from' => $wp_version,
|
||||
'to' => 0,
|
||||
'status' => 0,
|
||||
'notes' => ''
|
||||
);
|
||||
add_action('_core_updated_successfully', array($this, 'set_core_update_success_status'));
|
||||
add_filter('update_feedback', array($this, 'set_core_update_notes'), 1, 1);
|
||||
if (!$current || empty($current->updates)) return $reply;
|
||||
foreach ($current->updates as $update) {
|
||||
if (($this->auto_update && 'autoupdate' !== $update->response) || (!$this->auto_update && 'autoupdate' === $update->response)) continue;
|
||||
if (empty($update->packages)) continue;
|
||||
foreach ($update->packages as $download_url) {
|
||||
if ($download_url === $package) {
|
||||
$item['to'] = $update->current;
|
||||
$item['name'] .= " ({$update->locale})";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (version_compare($wp_version, $item['to'], '==') && empty($this->log_messages['core'])) {
|
||||
$item['name'] .= ' (Reinstall)';
|
||||
$this->log_messages['core']['reinstall'] = $item;
|
||||
} elseif (version_compare($wp_version, $item['to'], '<') && empty($this->log_messages['core'])) {
|
||||
$this->log_messages['core']['new'] = $item;
|
||||
} elseif (!empty($this->log_messages['core'])) {
|
||||
$item['name'] .= ' (Rollback)';
|
||||
$item['from'] = isset($this->log_messages['core']['new']) ? $this->log_messages['core']['new']['to'] : $item['from'];
|
||||
$item['to'] = isset($this->log_messages['core']['new']) ? $this->log_messages['core']['new']['from'] : $item['to'];
|
||||
$this->log_messages['core']['rollback'] = $item;
|
||||
}
|
||||
}
|
||||
return $reply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the information of updates to the log table, it fires when the upgrader process is complete during either manual or automatic operation and it logs only if the $log_messages variable class is not empty
|
||||
*
|
||||
* @param WP_Upgrader $wp_upgrader WP_Upgrader instance. In other contexts, $this, might be a Theme_Upgrader, Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader instance
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters
|
||||
*/
|
||||
public function log_updates($wp_upgrader, $hook_extra) {
|
||||
if (isset($hook_extra['action']) && 'update' !== $hook_extra['action']) return;
|
||||
try {
|
||||
$stacktrace = maybe_serialize(apply_filters('eum_normalized_call_stack_args', $this->normalise_call_stack_args(debug_backtrace(false)))); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace, PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection -- Using debug_backtrace() to normalize call stack for logging purposes.
|
||||
} catch (Exception $e) {
|
||||
$stacktrace = serialize(array()); // if an exception still happens even after the call stack is already normalised then we won't provide stacktrace for a log entry
|
||||
// @codingStandardsIgnoreLine
|
||||
} catch (Error $e) {
|
||||
$stacktrace = serialize(array());
|
||||
}
|
||||
$notes = '';
|
||||
if (is_a($wp_upgrader->skin, 'Automatic_Upgrader_Skin')) {
|
||||
foreach ($wp_upgrader->skin->get_upgrade_messages() as $message) {
|
||||
$notes .= $message . "\n\r\n\r";
|
||||
}
|
||||
}
|
||||
switch ($hook_extra['type']) {
|
||||
case 'translation':
|
||||
foreach ($hook_extra['translations'] as $translation) {
|
||||
$key = 'core' !== $translation['type'] && isset($this->log_messages['translation'][$translation['slug']]) ? $translation['slug'] : ('core' === $translation['type'] && isset($this->log_messages['translation']['wordpress_default_'.$translation['language']]) ? 'wordpress_default_'.$translation['language'] : '');
|
||||
if ('' === $key) continue;
|
||||
if (!isset($this->log_messages['translation'][$key])) continue;
|
||||
$this->insert_log($this->log_messages['translation'][$key]['name'], 'translation', $this->log_messages['translation'][$key]['from'], $this->log_messages['translation'][$key]['to'], $this->auto_update ? 'automatic' : 'manual', $this->log_messages['translation'][$key]['status'], get_current_user_id(), $notes, $stacktrace);
|
||||
unset($this->log_messages['translation'][$key]);
|
||||
}
|
||||
if (empty($this->log_messages['translation'])) unset($this->log_messages['translation']);
|
||||
break;
|
||||
case 'core':
|
||||
foreach ($this->log_messages['core'] as $core_type => $data) {
|
||||
$this->insert_log($data['name'], $hook_extra['type'], $data['from'], $data['to'], $this->auto_update ? 'automatic' : 'manual', $data['status'], get_current_user_id(), $notes ? $notes : $data['notes'], $stacktrace);
|
||||
unset($this->log_messages['core'][$core_type]);
|
||||
}
|
||||
if (empty($this->log_messages['core'])) unset($this->log_messages['core']);
|
||||
break;
|
||||
case 'plugin':
|
||||
$plugins = isset($hook_extra['plugins']) && is_array($hook_extra['plugins']) ? $hook_extra['plugins'] : (isset($hook_extra['plugin']) ? $hook_extra['plugin'] : array());
|
||||
foreach ((array) $plugins as $plugin) {
|
||||
if (!isset($this->log_messages['plugin'][$plugin])) continue;
|
||||
$this->insert_log($this->log_messages['plugin'][$plugin]['name'], $hook_extra['type'], $this->log_messages['plugin'][$plugin]['from'], $this->log_messages['plugin'][$plugin]['to'], $this->auto_update ? 'automatic' : 'manual', $this->log_messages['plugin'][$plugin]['status'], get_current_user_id(), $notes, $stacktrace);
|
||||
unset($this->log_messages['plugin'][$plugin]);
|
||||
}
|
||||
if (empty($this->log_messages['plugin'])) unset($this->log_messages['plugin']);
|
||||
break;
|
||||
case 'theme':
|
||||
$themes = isset($hook_extra['themes']) && is_array($hook_extra['themes']) ? $hook_extra['themes'] : (isset($hook_extra['theme']) ? $hook_extra['theme'] : array());
|
||||
foreach ((array) $themes as $theme) {
|
||||
if (!isset($this->log_messages['theme'][$theme])) continue;
|
||||
$this->insert_log($this->log_messages['theme'][$theme]['name'], $hook_extra['type'], $this->log_messages['theme'][$theme]['from'], $this->log_messages['theme'][$theme]['to'], $this->auto_update ? 'automatic' : 'manual', $this->log_messages['theme'][$theme]['status'], get_current_user_id(), $notes, $stacktrace);
|
||||
unset($this->log_messages['theme'][$theme]);
|
||||
}
|
||||
if (empty($this->log_messages['theme'])) unset($this->log_messages['theme']);
|
||||
break;
|
||||
}
|
||||
self::maybe_log_updates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set notes to the $log_messages variable class during update of the WP core
|
||||
*
|
||||
* @param string $note The core update feedback messages
|
||||
*/
|
||||
public function set_core_update_notes($note) {
|
||||
if (!is_array($this->log_messages['core']) || empty($this->log_messages['core']) || !is_string($note)) return $note; // yes, the docblock states that $note is in string type, but that's not always true as somehow it can be WP_Error object
|
||||
end($this->log_messages['core']);
|
||||
if (!isset($this->log_messages['core'][key($this->log_messages['core'])]['notes']) || !is_string($this->log_messages['core'][key($this->log_messages['core'])]['notes'])) $this->log_messages['core'][key($this->log_messages['core'])]['notes'] = '';
|
||||
$this->log_messages['core'][key($this->log_messages['core'])]['notes'] .= $note . "\n\r\n\r";
|
||||
reset($this->log_messages['core']);
|
||||
return $note;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set success to the core update status after WordPress core has been successfully updated
|
||||
*
|
||||
* Hooked to the {@see '_core_updated_successfully'} action, added when initializing core log info
|
||||
*/
|
||||
public function set_core_update_success_status() {
|
||||
remove_filter('update_feedback', array($this, 'set_core_update_notes'), 1, 1);
|
||||
if (!is_array($this->log_messages['core']) || empty($this->log_messages['core'])) return;
|
||||
end($this->log_messages['core']);
|
||||
$this->log_messages['core'][key($this->log_messages['core'])]['status'] = 1;
|
||||
reset($this->log_messages['core']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use result data to set update status of plugin/theme/translation after an installation has finished
|
||||
*
|
||||
* @param bool $response Installation response
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters
|
||||
* @param array $result Installation result data
|
||||
* @return bool Installation response
|
||||
*/
|
||||
public function set_update_status_by_result($response, $hook_extra, $result) {
|
||||
if (isset($hook_extra['action']) && 'update' !== $hook_extra['action']) return $response;
|
||||
if (isset($hook_extra['plugin']) && isset($this->log_messages['plugin'][$hook_extra['plugin']])) {
|
||||
$this->log_messages['plugin'][$hook_extra['plugin']]['status'] = $result && !is_wp_error($result) ? 1 : 0;
|
||||
} elseif (isset($hook_extra['theme']) && isset($this->log_messages['theme'][$hook_extra['theme']])) {
|
||||
$this->log_messages['theme'][$hook_extra['theme']]['status'] = $result && !is_wp_error($result) ? 1 : 0;
|
||||
} elseif (isset($hook_extra['language_update_type']) && isset($hook_extra['language_update'])) {
|
||||
switch ($hook_extra['language_update_type']) {
|
||||
case 'core':
|
||||
$this->log_messages['translation']['wordpress_default_'.$hook_extra['language_update']->language]['status'] = $result && !is_wp_error($result) ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
// plugins and themes
|
||||
$this->log_messages['translation'][$hook_extra['language_update']->slug]['status'] = $result && !is_wp_error($result) ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log update information to the log table when automatic updates is complete, and if the $log_messages variable class is not empty. This is final attempt to log updates to the database but this could also mean that nothing has to be done as in the previous action (upgrader_process_complete) the information has already been logged and has been removed from the $log_messages variable
|
||||
* The reason why this method is hooked to the `automatic_updates_complete` and why we still need it is that in some cases when an error occurs during automatic updates the `upgrader_process_complete` action won't get executed, but this action `automatic_updates_complete`/method will. Actually, without having this method we can still log the info on shutdown, but it lacks of notes
|
||||
*
|
||||
* @param array $update_results The results of all attempted updates
|
||||
*/
|
||||
public function log_automatic_updates($update_results) {
|
||||
if (empty($update_results)) return;
|
||||
try {
|
||||
$stacktrace = maybe_serialize(apply_filters('eum_normalized_call_stack_args', $this->normalise_call_stack_args(debug_backtrace(false)))); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace, PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection -- Using debug_backtrace() to normalize call stack for logging purposes.
|
||||
} catch (Exception $e) {
|
||||
$stacktrace = serialize(array()); // if an exception still happens even after the call stack is already normalised then we won't provide stacktrace for a log entry
|
||||
// @codingStandardsIgnoreLine
|
||||
} catch (Error $e) {
|
||||
$stacktrace = serialize(array());
|
||||
}
|
||||
foreach ($update_results as $type => $results) {
|
||||
foreach ($results as $result) {
|
||||
$notes = '';
|
||||
if (!isset($result->messages)) $result->messages = array();
|
||||
foreach ($result->messages as $message) {
|
||||
$notes .= $message . "\n\r\n\r";
|
||||
}
|
||||
if ('core' === $type) {
|
||||
if (!isset($this->log_messages[$type])) continue;
|
||||
foreach ($this->log_messages[$type] as $core_type => $data) {
|
||||
$this->insert_log($data['name'], $type, $data['from'], $data['to'], 'automatic', $data['status'], get_current_user_id(), $notes ? $notes : $data['notes'], $stacktrace);
|
||||
unset($this->log_messages[$type][$core_type]);
|
||||
}
|
||||
if (empty($this->log_messages[$type])) unset($this->log_messages[$type]);
|
||||
} elseif ('translation' === $type) {
|
||||
if (!isset($this->log_messages[$type], $this->log_messages[$type][$result->item->slug])) continue;
|
||||
$this->insert_log($this->log_messages[$type][$result->item->slug]['name'], $type, $this->log_messages[$type][$result->item->slug]['from'], $this->log_messages[$type][$result->item->slug]['to'], 'automatic', isset($result->result) && $result->result && !is_wp_error($result->result) ? 1 : 0, get_current_user_id(), $notes, $stacktrace);
|
||||
unset($this->log_messages[$type][$result->item->slug]);
|
||||
if (empty($this->log_messages[$type])) unset($this->log_messages[$type]);
|
||||
} else {
|
||||
if (!isset($this->log_messages[$type], $this->log_messages[$type][$result->item->$type])) continue;
|
||||
$this->insert_log($this->log_messages[$type][$result->item->$type]['name'], $type, $this->log_messages[$type][$result->item->$type]['from'], $this->log_messages[$type][$result->item->$type]['to'], 'automatic', isset($result->result) && $result->result && !is_wp_error($result->result) ? 1 : 0, get_current_user_id(), $notes, $stacktrace);
|
||||
unset($this->log_messages[$type][$result->item->$type]);
|
||||
if (empty($this->log_messages[$type])) unset($this->log_messages[$type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
self::maybe_log_updates();
|
||||
}
|
||||
|
||||
/**
|
||||
* See if any database schema updates are needed, and perform them if so.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function check_updates() {
|
||||
$our_version = self::$version;
|
||||
$db_version = get_site_option('mpsum_log_table_version', '0');
|
||||
if (version_compare($our_version, $db_version, '>')) {
|
||||
foreach (self::$db_updates as $version => $updates) {
|
||||
if (version_compare($version, $db_version, '>')) {
|
||||
foreach ($updates as $update) {
|
||||
call_user_func(array(__CLASS__, $update));
|
||||
}
|
||||
}
|
||||
}
|
||||
MPSUM_Updates_Manager::update_option('mpsum_log_table_version', $our_version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add webhook i18n
|
||||
*
|
||||
* @param array $i18n Array of internationalized strings
|
||||
* @return array Updated array of internationalized strings
|
||||
*/
|
||||
public function logs_i18n($i18n) {
|
||||
$i18n['logs_no_items'] = __('No items found.', 'stops-core-theme-and-plugin-updates');
|
||||
return $i18n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set update method as automatic
|
||||
*/
|
||||
public function pre_auto_update() {
|
||||
$this->auto_update = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and returns name of give update object
|
||||
*
|
||||
* @param object $translation Translation object
|
||||
*
|
||||
* @return array An array of name and version of updates
|
||||
*/
|
||||
public function get_update_name($translation) {
|
||||
$translation = (object) $translation;
|
||||
$type = $translation->type;
|
||||
$result = array();
|
||||
switch ($type) {
|
||||
case 'core':
|
||||
$result[$type]['name'] = 'WordPress';
|
||||
break;
|
||||
case 'theme':
|
||||
$theme = wp_get_theme($translation->slug);
|
||||
if ($theme->exists())
|
||||
$result[$type]['name'] = $theme->get('Name') . ' (' . $translation->language . ')';
|
||||
$result[$type]['new_version'] = $theme->get('Version');
|
||||
break;
|
||||
case 'plugin':
|
||||
if (! function_exists('get_plugins')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
$plugin = get_plugins('/' . $translation->slug);
|
||||
$plugin = reset($plugin);
|
||||
if ($plugin)
|
||||
$result[$type]['name'] = $plugin['Name'] . ' (' . $translation->language . ')';
|
||||
$result[$type]['new_version'] = $plugin['Version'];
|
||||
break;
|
||||
}
|
||||
$result[$type]['version'] = $translation->version;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts result of upgrade process message to log table
|
||||
*
|
||||
* @param string $name Upgrade name
|
||||
* @param string $type Type of upgrade
|
||||
* @param string $version_from Upgrade from version number
|
||||
* @param string $version Upgrade to version number
|
||||
* @param string $action Action type, manual or automatic
|
||||
* @param int $status Status of upgrade
|
||||
* @param int $user_id User responsible for the upgrade
|
||||
*/
|
||||
public function insert_log($name, $type, $version_from, $version, $action, $status, $user_id = 0, $notes = '', $stacktrace = '' ) {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->base_prefix . 'eum_logs';
|
||||
if ('' == $version_from) $version_from = '0.00';
|
||||
$notes = str_replace('…', '', $notes);
|
||||
|
||||
// Strip URLs from notes
|
||||
$notes = preg_replace('/\?.*/', '', $notes);
|
||||
|
||||
$wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Direct database query is required for inserting log data.
|
||||
$table_name,
|
||||
array(
|
||||
'user_id' => $user_id,
|
||||
'name' => $name,
|
||||
'type' => $type,
|
||||
'version_from' => $version_from,
|
||||
'version' => $version,
|
||||
'action' => $action,
|
||||
'status' => $status,
|
||||
'date' => current_time('mysql'),
|
||||
'notes' => $notes,
|
||||
'stacktrace' => $stacktrace,
|
||||
),
|
||||
array(
|
||||
'%d',
|
||||
'%s',
|
||||
'%s',
|
||||
'%s',
|
||||
'%s',
|
||||
'%s',
|
||||
'%s',
|
||||
'%s',
|
||||
'%s',
|
||||
'%s',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of an translation item being updated.
|
||||
*
|
||||
* @since 6.0.3
|
||||
* @access private
|
||||
* @param string $type type of translation update
|
||||
* @param string $slug Slug of item
|
||||
* @return string The name of the item being updated.
|
||||
*/
|
||||
public function get_name_for_update($type, $slug) {
|
||||
if (! function_exists('get_plugins')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
switch ($type) {
|
||||
case 'core':
|
||||
return 'WordPress'; // Not translated
|
||||
|
||||
case 'theme':
|
||||
$theme = wp_get_theme($slug);
|
||||
if ($theme->exists())
|
||||
return $theme->Get('Name');
|
||||
break;
|
||||
case 'plugin':
|
||||
$plugin_data = get_plugins('/' . $slug);
|
||||
$plugin_data = reset($plugin_data);
|
||||
if ($plugin_data)
|
||||
return $plugin_data['Name'];
|
||||
break;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the log table
|
||||
*
|
||||
* Creates the log table
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @access public
|
||||
*/
|
||||
public static function build_table() {
|
||||
global $wpdb;
|
||||
$tablename = $wpdb->base_prefix . 'eum_logs';
|
||||
|
||||
// Get collation - From /wp-admin/includes/schema.php
|
||||
$charset_collate = '';
|
||||
if (! empty($wpdb->charset))
|
||||
$charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
|
||||
if (! empty($wpdb->collate))
|
||||
$charset_collate .= " COLLATE $wpdb->collate";
|
||||
|
||||
$sql = "CREATE TABLE {$tablename} (
|
||||
log_id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
user_id BIGINT(20) NOT NULL DEFAULT 0,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
type VARCHAR(255) NOT NULL,
|
||||
version_from VARCHAR(255) NOT NULL,
|
||||
version VARCHAR(255) NOT NULL,
|
||||
action VARCHAR(255) NOT NULL,
|
||||
status VARCHAR(255) NOT NULL,
|
||||
notes TEXT NOT NULL,
|
||||
stacktrace TEXT DEFAULT NULL,
|
||||
date DATETIME NOT NULL,
|
||||
PRIMARY KEY (log_id)
|
||||
) {$charset_collate};";
|
||||
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
||||
dbDelta($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether log table exists or not
|
||||
*
|
||||
* @return boolean True if table exists, otherwise false
|
||||
*/
|
||||
private function log_table_exists() {
|
||||
if (true === self::$log_table_exists) {
|
||||
return;
|
||||
}
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix.'eum_logs';
|
||||
self::$log_table_exists = (bool) $wpdb->get_var("SHOW TABLES LIKE '$table_name'"); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Query is safe as it does not involve user input and is used for checking table existence.
|
||||
return self::$log_table_exists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the log table
|
||||
*
|
||||
* Clears the log table
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @access static
|
||||
*/
|
||||
public static function clear() {
|
||||
global $wpdb;
|
||||
$tablename = $wpdb->base_prefix . 'eum_logs';
|
||||
$sql = "delete from $tablename";
|
||||
$wpdb->query($sql); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Query is safe as it does not include user input and is intended for direct execution.
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the log table
|
||||
*
|
||||
* Drops the log table
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @access static
|
||||
*/
|
||||
public static function drop() {
|
||||
global $wpdb;
|
||||
$tablename = $wpdb->base_prefix . 'eum_logs';
|
||||
$sql = "drop table if exists $tablename";
|
||||
$wpdb->query($sql); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Query is safe as it does not involve user input and is intended for direct execution.
|
||||
delete_site_option('mpsum_log_table_version');
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise call stacks by clearing out unnecessary objects from their arguments list, leaving the arguments as a string if they're not in an array/object type. The call stacks should be one that is generated by debug_backtrace() function.
|
||||
*
|
||||
* @param array $backtrace The output of the debug_backtrace() function
|
||||
* @return array An array of associative arrays after being normalised
|
||||
*/
|
||||
public function normalise_call_stack_args($backtrace) {
|
||||
$normalised_backtrace = $backtrace;
|
||||
foreach ((array) $backtrace as $index => $element) {
|
||||
$normalised_backtrace[$index]['args'] = array();
|
||||
foreach ($backtrace[$index]['args'] as $arg_index => $arg) {
|
||||
if (is_object($arg)) {
|
||||
$normalised_backtrace[$index]['args'][$arg_index] = "Object(".get_class($backtrace[$index]['args'][$arg_index]).")";
|
||||
} elseif (is_array($arg)) {
|
||||
$normalised_backtrace[$index]['args'][$arg_index] = "Array(".count($backtrace[$index]['args'][$arg_index]).")";
|
||||
} elseif (!is_string($backtrace[$index]['args'][$arg_index])) {
|
||||
$normalised_backtrace[$index]['args'][$arg_index] = '';
|
||||
} else {
|
||||
$normalised_backtrace[$index]['args'][$arg_index] = $backtrace[$index]['args'][$arg_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $normalised_backtrace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,952 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Easy Updates Manager Logs List Table class.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage MPSUM_List_Table
|
||||
* @since 6.0.0
|
||||
* @access private
|
||||
*/
|
||||
class MPSUM_Logs_List_Table extends MPSUM_List_Table {
|
||||
|
||||
private $tab = 'logs';
|
||||
|
||||
private $action_type = '';
|
||||
|
||||
private $order = 'DESC';
|
||||
|
||||
private $type = '';
|
||||
|
||||
private $url = '';
|
||||
|
||||
private $month = '0';
|
||||
|
||||
private $page = '1';
|
||||
|
||||
private $status = 'all';
|
||||
|
||||
private $is_search = false;
|
||||
|
||||
private $search_term = '';
|
||||
|
||||
private $date_start = '';
|
||||
|
||||
private $date_end = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see WP_List_Table::__construct() for more information on default arguments.
|
||||
*
|
||||
* @global object $post_type_object
|
||||
* @global wpdb $wpdb
|
||||
*
|
||||
* @param array $args An associative array of arguments.
|
||||
*/
|
||||
public function __construct($args = array()) {
|
||||
|
||||
parent::__construct(array(
|
||||
'singular'=> 'log',
|
||||
'plural' => 'logs',
|
||||
'screen' => isset($args['screen']) ? $args['screen'] : 'eum_logs_tab',
|
||||
'ajax' => true
|
||||
));
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- Verified in our AJAX handler.
|
||||
if (isset($_REQUEST['action']) && ('eum_ajax' === $_REQUEST['action'] || 'eum_export_logs' === $_REQUEST['action'] || 'eum_export_csv' === $_REQUEST['action'] || 'eum_export_json' === $_REQUEST['action'])) {
|
||||
$this->action_type = isset($_REQUEST['action_type']) ? sanitize_text_field(wp_unslash($_REQUEST['action_type'])) : 'all';
|
||||
|
||||
$this->type = isset($_REQUEST['type']) ? sanitize_text_field(wp_unslash($_REQUEST['type'])) : 'all';
|
||||
$month = isset($_REQUEST['m']) ? sanitize_text_field(wp_unslash($_REQUEST['m'])) : '';
|
||||
if (strlen($month) > 4) {
|
||||
$this->month = $month;
|
||||
}
|
||||
// Format start date
|
||||
$date_start = isset($_REQUEST['date_start']) ? sanitize_text_field(wp_unslash($_REQUEST['date_start'])) : '';
|
||||
if ('' !== $date_start) {
|
||||
$this->date_start = strtotime($date_start);
|
||||
$this->date_start = date('Y-m-d H:i:s', $this->date_start); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date -- Using date function for export data.
|
||||
}
|
||||
|
||||
// Format end date
|
||||
$date_end = isset($_REQUEST['date_end']) ? sanitize_text_field(wp_unslash($_REQUEST['date_end'])) : '';
|
||||
if ('' !== $date_end) {
|
||||
$this->date_end = strtotime($date_end);
|
||||
$this->date_end = date('Y-m-d H:i:s', $this->date_end); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date -- Using date function for export data.
|
||||
}
|
||||
|
||||
$this->url = add_query_arg(array('tab' => 'logs'), MPSUM_Admin::get_url());
|
||||
|
||||
if (isset($_REQUEST['status']) && in_array($_REQUEST['status'], array('all', '2', '1', '0'))) {
|
||||
$this->status = sanitize_text_field(wp_unslash($_REQUEST['status']));
|
||||
}
|
||||
|
||||
$this->page = isset($_REQUEST['paged']) ? sanitize_text_field(wp_unslash($_REQUEST['paged'])) : '1';
|
||||
$this->order = isset($_REQUEST['order']) ? sanitize_text_field(wp_unslash($_REQUEST['order'])) : 'DESC';
|
||||
|
||||
if (isset($_REQUEST['view']) && 'search' == $_REQUEST['view']) {
|
||||
$this->is_search = true;
|
||||
if (isset($_REQUEST['search_term'])) {
|
||||
$this->search_term = sanitize_text_field(wp_unslash($_REQUEST['search_term']));
|
||||
} elseif (isset($_REQUEST['term'])) {
|
||||
$this->search_term = sanitize_text_field(wp_unslash($_REQUEST['term']));
|
||||
}
|
||||
} else {
|
||||
$this->is_search = false;
|
||||
$this->search_term = '';
|
||||
}
|
||||
} else {
|
||||
$this->action_type = isset($args['action_type']) ? $args['action_type'] : 'all';
|
||||
$this->type = isset($args['type']) ? $args['type'] : 'all';
|
||||
if (isset($args['m']) && strlen($args['m']) > 4) {
|
||||
$this->month = $args['m'];
|
||||
}
|
||||
|
||||
$this->url = add_query_arg(array('tab' => 'logs'), MPSUM_Admin::get_url());
|
||||
|
||||
if (isset($args['status']) && in_array($args['status'], array('all', '2', '1', '0'))) {
|
||||
$this->status = $args['status'];
|
||||
}
|
||||
|
||||
$this->page = isset($args['paged']) ? $args['paged'] : '1';
|
||||
$this->order = isset($args['order']) ? $args['order'] : 'DESC';
|
||||
if (isset($args['view']) && 'search' == $args['view']) {
|
||||
$this->is_search = true;
|
||||
$this->search_term = isset($args['search_term']) ? $args['search_term'] : $args['term'];
|
||||
} else {
|
||||
$this->is_search = false;
|
||||
$this->search_term = '';
|
||||
}
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare items
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepare_items() {
|
||||
global $wpdb;
|
||||
|
||||
$tablename = $wpdb->base_prefix . 'eum_logs';
|
||||
|
||||
// Get logs per page
|
||||
$user_id = get_current_user_id();
|
||||
$per_page = get_user_meta($user_id, 'mpsum_items_per_page', true);
|
||||
if (! is_numeric($per_page)) {
|
||||
$per_page = 100;
|
||||
}
|
||||
|
||||
// Show the last thousand records if exporting
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified in our AJAX handler.
|
||||
if (isset($_REQUEST['action']) && ('eum_export_logs' === $_REQUEST['action'] || 'eum_export_csv' === $_REQUEST['action'] || 'eum_export_json' === $_REQUEST['action'])) {
|
||||
$per_page = 1000;
|
||||
}
|
||||
|
||||
$offset = ($this->page - 1) * $per_page;
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Already prepared query.
|
||||
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Direct database query is required to fetch logs data without relying on caching.
|
||||
if ($this->is_search) {
|
||||
|
||||
// Try to get username
|
||||
$maybe_user = false;
|
||||
if (is_numeric($this->search_term)) {
|
||||
$maybe_user = get_user_by('id', $this->search_term);
|
||||
} elseif (is_email($this->search_term)) {
|
||||
$maybe_user = get_user_by('email', $this->search_term);
|
||||
} else {
|
||||
$maybe_user = get_user_by('slug', $this->search_term);
|
||||
if (!$maybe_user) {
|
||||
$maybe_user = get_user_by('login', $this->search_term);
|
||||
}
|
||||
}
|
||||
|
||||
// If no user, search the name field
|
||||
if (!$maybe_user) {
|
||||
$wild = '%';
|
||||
$select = "select log_id, user_id, name, type, version_from, version, action, status, date, notes, stacktrace from $tablename WHERE 1=1 AND name LIKE %s";
|
||||
$term = $wild . $this->search_term . $wild;
|
||||
$orderby = " order by log_id DESC";
|
||||
$limit = " limit %d,%d";
|
||||
|
||||
// Calculate no. of logs separately, because filters may be on
|
||||
$query = $select . $orderby;
|
||||
$prepared_query = $wpdb->remove_placeholder_escape($wpdb->prepare($query, $term));
|
||||
$wpdb->get_results($prepared_query);
|
||||
$log_count = $wpdb->num_rows;
|
||||
|
||||
// Now perform the real query
|
||||
$query = $select . $orderby . $limit;
|
||||
$query = $wpdb->remove_placeholder_escape($wpdb->prepare($query, $term, $offset, $per_page));
|
||||
$this->items = $wpdb->get_results($query);
|
||||
} else {
|
||||
$user_id = $maybe_user->ID;
|
||||
$select = "select log_id, user_id, name, type, version_from, version, action, status, date, notes, stacktrace from $tablename WHERE 1=1 AND user_id = %d";
|
||||
|
||||
$orderby = " order by log_id DESC";
|
||||
$limit = " limit %d,%d";
|
||||
|
||||
// Calculate no. of logs separately, because filters may be on
|
||||
$query = $select . $orderby;
|
||||
$wpdb->get_results($wpdb->prepare($query, $user_id));
|
||||
$log_count = $wpdb->num_rows;
|
||||
|
||||
// Now perform the real query
|
||||
$query = $select . $orderby . $limit;
|
||||
$query = $wpdb->prepare($query, $user_id, $offset, $per_page);
|
||||
$this->items = $wpdb->get_results($query);
|
||||
}
|
||||
} else {
|
||||
$where = '';
|
||||
if (isset($this->month) && strlen($this->month) > 4) {
|
||||
$where .= $wpdb->prepare(" AND YEAR($tablename.date)=%d", substr($this->month, 0, 4));
|
||||
if (strlen($this->month) > 5) {
|
||||
$where .= $wpdb->prepare(" AND MONTH($tablename.date)=%d", substr($this->month, 4, 2));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->date_start) && '' !== $this->date_start && isset($this->date_end) && '' !== $this->date_end) {
|
||||
$where .= $wpdb->prepare(" AND (date BETWEEN %s AND %s)", $this->date_start, $this->date_end);
|
||||
}
|
||||
|
||||
if (isset($this->status) && 'all' !== $this->status) {
|
||||
$where .= $wpdb->prepare(" and $tablename.status = %d ", absint($this->status));
|
||||
}
|
||||
|
||||
if (isset($this->action_type) && 'all' !== $this->action_type) {
|
||||
$where .= $wpdb->prepare(" and $tablename.action = %s ", sanitize_text_field($this->action_type));
|
||||
}
|
||||
|
||||
if (isset($this->type) && 'all' !== $this->type) {
|
||||
$where .= $wpdb->prepare(" and $tablename.type = %s ", sanitize_text_field($this->type));
|
||||
}
|
||||
|
||||
|
||||
$select = "select log_id, user_id, name, type, version_from, version, action, status, date, notes, stacktrace from $tablename WHERE 1=1 ";
|
||||
$orderby = ' order by ' . sanitize_sql_orderby("log_id {$this->order}");
|
||||
$limit = " limit %d,%d";
|
||||
|
||||
// Calculate no. of logs separately, because filters may be on
|
||||
$query = $select . $where . $orderby;
|
||||
$wpdb->get_results($query);
|
||||
|
||||
$log_count = $wpdb->num_rows;
|
||||
|
||||
$query = $select . $where . $orderby . $limit;
|
||||
$query = $wpdb->prepare($query, $offset, $per_page);
|
||||
$this->items = $wpdb->get_results($query);
|
||||
}
|
||||
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
|
||||
|
||||
|
||||
|
||||
/* -- Register the Columns -- */
|
||||
$this->_column_headers = array(
|
||||
$this->get_columns(), // columns
|
||||
array(), // hidden
|
||||
$this->get_sortable_columns(), // sortable
|
||||
);
|
||||
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $log_count,
|
||||
'per_page' => $per_page,
|
||||
'total_pages' => ceil($log_count / $per_page),
|
||||
'paged' => isset($this->page) ? $this->page : '1',
|
||||
'status' => $this->status,
|
||||
'tab' => $this->tab,
|
||||
'action_type' => isset($this->action_type) ? $this->action_type : 'all',
|
||||
'type' => isset($this->type) ? $this->type : 'bottom',
|
||||
'view' => empty($this->is_search) ? 'all' : 'search',
|
||||
'term' => empty($this->search_term) ? '' : $this->search_term
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the table navigation above or below the table
|
||||
*
|
||||
* @since 8.0.1
|
||||
* @access protected
|
||||
* @param string $which Which extra table nav to use
|
||||
*/
|
||||
protected function display_tablenav($which) {
|
||||
if ('top' == $which) {
|
||||
wp_nonce_field('bulk-' . $this->_args['plural']);
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="tablenav <?php echo esc_attr($which); ?>">
|
||||
|
||||
<div class="alignleft actions bulkactions">
|
||||
<?php $this->bulk_actions($which); ?>
|
||||
</div>
|
||||
<?php
|
||||
$this->extra_tablenav($which);
|
||||
if ('bottom' == $which) {
|
||||
$this->pagination($which);
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a monthly dropdown for filtering items
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @access protected
|
||||
* @global wpdb $wpdb
|
||||
*/
|
||||
protected function months_dropdown($post_type) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Declaration of MPSUM_Logs_List_Table::months_dropdown should be compatible with MPSUM_List_Table::months_dropdown so we can leave $post_type as its needed
|
||||
global $wpdb, $wp_locale;
|
||||
$tablename = $wpdb->base_prefix . 'eum_logs';
|
||||
$query = "SELECT DISTINCT YEAR(date) AS year, MONTH(date) AS month FROM $tablename ORDER BY date DESC";
|
||||
|
||||
$months = $wpdb->get_results($query); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Query does not contain placeholder, so preparing is not necessary.
|
||||
|
||||
$month_count = count($months);
|
||||
if (!$month_count || (1 == $month_count && 0 == $months[0]->month))
|
||||
return;
|
||||
|
||||
?>
|
||||
<label for="filter-by-date" class="screen-reader-text"><?php esc_html_e('Filter by date', 'stops-core-theme-and-plugin-updates'); ?></label>
|
||||
<select name="m" id="filter-by-date">
|
||||
<option <?php selected($this->month, 0); ?> value="0"><?php esc_html_e('All dates', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<?php
|
||||
foreach ($months as $arc_row) {
|
||||
if (0 == $arc_row->year)
|
||||
continue;
|
||||
|
||||
$month = zeroise($arc_row->month, 2);
|
||||
$year = $arc_row->year;
|
||||
|
||||
printf("<option %s value='%s'>%s</option>\n",
|
||||
selected($this->month, $year . $month, false),
|
||||
esc_attr($arc_row->year . $month),
|
||||
esc_html($wp_locale->get_month($month) . ' ' . $year)
|
||||
);
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Type order
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function order_dropdown() {
|
||||
?>
|
||||
<label for="filter-by-order" class="screen-reader-text"><?php esc_html_e('Order', 'stops-core-theme-and-plugin-updates'); ?></label>
|
||||
<select name="order" id="filter-by-order">
|
||||
<option<?php selected($this->order, 'ASC'); ?> value="ASC"><?php echo esc_html_x('ASC', 'Ascending type', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option<?php selected($this->order, 'DESC'); ?> value="DESC"><?php echo esc_html_x('DESC', 'Descending type', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Type dropdown
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function type_dropdown() {
|
||||
?>
|
||||
<label for="filter-by-type" class="screen-reader-text"><?php esc_html_e('Filter by upgrade type', 'stops-core-theme-and-plugin-updates'); ?></label>
|
||||
<select name="type" id="filter-by-type">
|
||||
<option<?php selected($this->type, 'all'); ?> value="all"><?php echo esc_html_x('All types', 'Upgrade types: translation, core, plugin, theme', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option<?php selected($this->type, 'core'); ?> value="core"><?php echo esc_html_x('Core', 'Show WordPress core updates', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option<?php selected($this->type, 'plugin'); ?> value="plugin"><?php echo esc_html_x('Plugins', 'Show WordPress plugin updates', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option<?php selected($this->type, 'theme'); ?> value="theme"><?php echo esc_html_x('Themes', 'Show WordPress theme updates', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option<?php selected($this->type, 'translation'); ?> value="translation"><?php echo esc_html_x('Translations', 'Show WordPress translation updates', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Status dropdown
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function status_dropdown() {
|
||||
?>
|
||||
<label for="filter-by-success" class="screen-reader-text"><?php esc_html_e('Filter by status', 'stops-core-theme-and-plugin-updates'); ?></label>
|
||||
<select name="status" id="filter-by-success">
|
||||
<option <?php selected($this->status, 'all'); ?> value="all"><?php esc_html_e('All statuses', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option <?php selected($this->status, 1); ?> value="1"><?php echo esc_html_x('Success', 'Show status updates that are successful', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option <?php selected($this->status, 0); ?> value="0"><?php echo esc_html_x('Failures', 'Show status updates that are not successful', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option <?php selected($this->status, 2); ?> value="2"><?php echo esc_html_x('Update not compatible', 'Show status updates that do not meet safe mode requirements', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Action dropdown
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function action_dropdown() {
|
||||
?>
|
||||
<label for="filter-by-action" class="screen-reader-text"><?php esc_html_e('Filter by action', 'stops-core-theme-and-plugin-updates'); ?></label>
|
||||
<select name="action_type" id="filter-by-action">
|
||||
<option <?php selected($this->action_type, 'all'); ?> value="all"><?php esc_html_e('All actions', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option <?php selected($this->action_type, 'automatic'); ?> value="automatic"><?php echo esc_html_x('Automatic updates', 'Show log items that are automatic updates only', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
<option <?php selected($this->action_type, 'manual'); ?> value="manual"><?php echo esc_html_x('Manual updates', 'Show log items that are manual updates only', 'stops-core-theme-and-plugin-updates'); ?></option>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra table nav
|
||||
*
|
||||
* @global int $cat
|
||||
* @param string $which Specify which table
|
||||
*/
|
||||
protected function extra_tablenav($which) {
|
||||
?>
|
||||
<form id="logs-filter" action="<?php echo esc_url($this->url); ?>" method="GET">
|
||||
<input type="hidden" name="page" value="mpsum-update-options" />
|
||||
<input type="hidden" name="tab" value="logs" />
|
||||
<div class="alignleft">
|
||||
<?php
|
||||
if ('top' === $which && !is_singular()) {
|
||||
|
||||
$this->months_dropdown(isset($this->screen->post_type) ? $this->screen->post_type : '');
|
||||
$this->status_dropdown();
|
||||
$this->action_dropdown();
|
||||
$this->type_dropdown();
|
||||
$this->order_dropdown();
|
||||
|
||||
submit_button(__('Filter', 'stops-core-theme-and-plugin-updates'), 'button', 'filter_action', false, array('id' => 'post-query-submit'));
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
if (MPSUM_Updates_Manager::get_instance()->is_premium() && 'bottom' === $which) {
|
||||
?>
|
||||
<form id="log-export" action="<?php echo esc_url($this->url); ?>" method="get">
|
||||
<div class="alignleft">
|
||||
<?php submit_button(__('Export', 'stops-core-theme-and-plugin-updates'), array('primary', 'large'), 'export_action', false, array('id' => 'log-export')); ?>
|
||||
<div class="export-date-range" style="display: none">
|
||||
<h3><?php esc_html_e('Begin export', 'stops-core-theme-and-plugin-updates'); ?></h3>
|
||||
<div class="eum-export-date">
|
||||
<input type="text" id="export_date_start" name="export_date_start" />
|
||||
<strong><label for="export_date_start" style="display:block;"><?php esc_html_e('Start', 'stops-core-theme-and-plugin-updates');?></label></strong>
|
||||
</div>
|
||||
<div class="eum-export-date">
|
||||
<input type="text" id="export_date_end" name="export_date_end" />
|
||||
<strong><label for="export_date_start" style="display:block;"><?php esc_html_e('End', 'stops-core-theme-and-plugin-updates');?></label></strong>
|
||||
</div>
|
||||
<div class="mpsum-notice mpsum-regular mpsum-clear"><?php echo esc_html__('The date range is optional.', 'stops-core-theme-and-plugin-updates').' '.esc_html__('If left blank, the last 1000 log entries will be exported.', 'stops-core-theme-and-plugin-updates'); ?></div>
|
||||
<div class="export-button">
|
||||
<input type="hidden" id="export-ajax-url" value="<?php echo esc_url(add_query_arg(array('action' => 'eum_export_logs', 'nonce' => wp_create_nonce('eum_export_logs'), 'action_type' => 'all'), admin_url('admin-ajax.php')));?>" />
|
||||
<a href="#" id="eum-export-go" class="button-primary thickbox open-plugin-details-modal" name="<?php esc_html_e('Export logs', 'stops-core-theme-and-plugin-updates');?>"><?php esc_html_e('Go', 'stops-core-theme-and-plugin-updates'); ?></a> <a href="#" class="button-secondary export-cancel"><?php esc_html_e('Cancel', 'stops-core-theme-and-plugin-updates'); ?></a>
|
||||
</div>
|
||||
</div><!-- .export-date-range -->
|
||||
</div><!-- .alignleft -->
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<form id="search-filter" action="<?php echo esc_url($this->url); ?>" method="get">
|
||||
<?php
|
||||
if (MPSUM_Updates_Manager::get_instance()->is_premium() && 'top' === $which) {
|
||||
?>
|
||||
<div class="alignright">
|
||||
<input type="text" name="eum-log-search" id="eum-log-search" value="<?php echo esc_attr($this->search_term); ?>" /><?php submit_button(__('Search', 'stops-core-theme-and-plugin-updates'), 'button', 'search_action', false, array('id' => 'log-query-search')); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</form><!-- #search-filter -->
|
||||
<?php
|
||||
/**
|
||||
* Fires immediately following the closing "actions" div in the tablenav for the posts
|
||||
* list table.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @param string $which The location of the extra table nav markup: 'top' or 'bottom'.
|
||||
*/
|
||||
do_action('manage_posts_extra_tablenav', $which);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table classes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_table_classes() {
|
||||
return array('widefat', 'fixed', 'striped');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
$columns = array(
|
||||
'user' => _x('User', 'Column header for logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'name' => _x('Name', 'Column header for logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'type' => _x('Type', 'Column header for logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'version_from' => _x('From', 'Column header for version number in logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'version' => _x('To', 'Column header for version number in logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'action' => _x('Action', 'Column header for logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'status' => _x('Status', 'Column header for logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'date' => _x('Date', 'Column header for logs', 'stops-core-theme-and-plugin-updates'),
|
||||
'notes' => _x('Notes', 'Column header for notes', 'stops-core-theme-and-plugin-updates'),
|
||||
'stacktrace' => _x('Stack Trace', 'Column header for stacktrace', 'stops-core-theme-and-plugin-updates'),
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display rows
|
||||
*/
|
||||
public function display_rows() {
|
||||
foreach ($this->items as $record) {
|
||||
$this->single_row($record);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display CSV data
|
||||
*/
|
||||
public function display_csv() {
|
||||
$fp = fopen('php://temp', 'w+'); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- Using fopen on 'php://temp' for temporary in-memory storage.
|
||||
foreach ($this->items as $record) {
|
||||
$row_columns = array();
|
||||
foreach ($record as $record_key => $record_data) {
|
||||
if ('log_id' == $record_key) continue;
|
||||
switch ($record_key) {
|
||||
case 'user_id':
|
||||
if (0 == $record_data) {
|
||||
$row_columns[] = _x('None', 'No user found', 'stops-core-theme-and-plugin-updates');
|
||||
} else {
|
||||
$user = get_user_by('id', $record_data);
|
||||
if ($user) {
|
||||
$row_columns[] = $user->user_nicename;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'name':
|
||||
$row_columns[] = $record_data;
|
||||
break;
|
||||
case 'type':
|
||||
if ('core' == $record_data) {
|
||||
$row_columns[] = ucfirst(_x('core', 'update type', 'stops-core-theme-and-plugin-updates'));
|
||||
} elseif ('translation' == $record_data) {
|
||||
$row_columns[] = ucfirst(_x('translation', 'update type', 'stops-core-theme-and-plugin-updates'));
|
||||
} elseif ('plugin' == $record_data) {
|
||||
$row_columns[] =ucfirst(_x('plugin', 'update type', 'stops-core-theme-and-plugin-updates'));
|
||||
} elseif ('theme' == $record_data) {
|
||||
$row_columns[] = ucfirst(_x('theme', 'update type', 'stops-core-theme-and-plugin-updates'));
|
||||
} else {
|
||||
$row_columns[] = ucfirst($record_data);
|
||||
}
|
||||
break;
|
||||
case 'version_from':
|
||||
$row_columns[] = $record_data;
|
||||
break;
|
||||
case 'version':
|
||||
$row_columns[] = $record_data;
|
||||
break;
|
||||
case 'action':
|
||||
if ('manual' == $record_data) {
|
||||
$row_columns[] = ucfirst(_x('manual', 'update type - manual or automatic updates', 'stops-core-theme-and-plugin-updates'));
|
||||
} elseif ('automatic' == $record_data) {
|
||||
$row_columns[] = ucfirst(_x('automatic', 'update type - manual or automatic updates', 'stops-core-theme-and-plugin-updates'));
|
||||
} else {
|
||||
$row_columns[] = ucfirst($record_data);
|
||||
}
|
||||
break;
|
||||
case 'status':
|
||||
if (1 == $record_data) {
|
||||
$row_columns[] = __('Success', 'stops-core-theme-and-plugin-updates');
|
||||
} elseif (2 == $record_data) {
|
||||
$row_columns[] = _x('Update requirements not met', 'Show status updates that are in safe mode', 'stops-core-theme-and-plugin-updates');
|
||||
} else {
|
||||
$row_columns[] = __('Failure', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
$row_columns[] = $record_data;
|
||||
break;
|
||||
case 'notes':
|
||||
$row_columns[] = $record_data;
|
||||
break;
|
||||
case 'stacktrace':
|
||||
$row_columns[] = $this->get_stacktrace_column($record_data);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputcsv($fp, $row_columns);
|
||||
}
|
||||
rewind($fp);
|
||||
$csv_contents = stream_get_contents($fp);
|
||||
fclose($fp); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Using fclose to properly close the temporary file handle.
|
||||
echo $csv_contents;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- needs to be output exactly as it is
|
||||
}
|
||||
|
||||
/**
|
||||
* Display JSON data
|
||||
*
|
||||
* @param array $posts posts to be displayed
|
||||
*/
|
||||
public function display_json() {
|
||||
$json_array = array();
|
||||
foreach ($this->items as $record) {
|
||||
$log_id = 0;
|
||||
$row_data = array();
|
||||
|
||||
|
||||
foreach ($record as $record_key => $record_data) {
|
||||
if ('log_id' == $record_key) {
|
||||
$log_id = $record_data;
|
||||
continue;
|
||||
}
|
||||
$row_data[$record_key] = $record_data;
|
||||
}
|
||||
$json_array[$log_id] = $row_data;
|
||||
}
|
||||
echo json_encode($json_array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stacktrace column
|
||||
*
|
||||
* @param string $stacktrace raw stacktrace data
|
||||
* @return array
|
||||
*/
|
||||
private function get_stacktrace_column($stacktrace) {
|
||||
$stacktrace = is_serialized($stacktrace) ? MPSUM_Updates_Manager::unserialize($stacktrace) : $stacktrace;
|
||||
if (!is_array($stacktrace)) $stacktrace = array();
|
||||
$trace = array_reverse($stacktrace);
|
||||
$stackrarr = array();
|
||||
$i = 1;
|
||||
$truncate_paths = array(wp_normalize_path(WP_CONTENT_DIR), wp_normalize_path(ABSPATH));
|
||||
foreach ($trace as $node) {
|
||||
$stack = '';
|
||||
if (isset($node['file']) && ($node['line'])) {
|
||||
$filename = $node['file'];
|
||||
$stack = "#$i " . str_replace($truncate_paths, '', wp_normalize_path($filename)) . " (" . $node['line'] . "): ";
|
||||
}
|
||||
if (isset($node['class'])) {
|
||||
$stack .= $node['class'].$node['type'].$node['function'];
|
||||
$stack .= "(";
|
||||
$args = '';
|
||||
foreach ((array) $node['args'] as $arg) {
|
||||
if (is_string($arg)) {
|
||||
if (!empty($args)) $args .= ", ";
|
||||
$args .= ('' === $arg) ? "''" : $arg;
|
||||
}
|
||||
// if the argument is not in a string type, then this will ensure compatibility with older data from the older versions, also will prevent PHP warning "Array to string conversion"
|
||||
}
|
||||
$stack .= "$args)";
|
||||
} else {
|
||||
if (in_array($node['function'], array('do_action', 'apply_filters', 'do_action_ref_array', 'apply_filters_ref_array'), true)) {
|
||||
$stack .= $node['function'] . "('".$node['args'][0]."')";
|
||||
} elseif (in_array($node['function'], array('include', 'include_once', 'require', 'require_once'), true)) {
|
||||
$filename = isset($node['args'][0]) ? $node['args'][0] : '';
|
||||
$stack .= $node['function'] . "('" . str_replace($truncate_paths, '', wp_normalize_path($filename)) . "')";
|
||||
} else {
|
||||
$stack .= $node['function'];
|
||||
}
|
||||
}
|
||||
$stackrarr[] = $stack."\r\n";
|
||||
$i++;
|
||||
}
|
||||
return implode(" ", $stackrarr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Single row
|
||||
*
|
||||
* @param array $record log record
|
||||
* @return void
|
||||
*/
|
||||
public function single_row($record) {
|
||||
|
||||
?>
|
||||
<tr id="log-<?php echo esc_attr($record->log_id); ?>">
|
||||
<?php
|
||||
foreach ($record as $record_key => $record_data) {
|
||||
if ('log_id' == $record_key) continue;
|
||||
echo '<td>';
|
||||
switch ($record_key) {
|
||||
case 'user_id':
|
||||
if (0 == $record_data) {
|
||||
echo esc_html_x('None', 'No user found', 'stops-core-theme-and-plugin-updates');
|
||||
} else {
|
||||
$user = get_user_by('id', $record_data);
|
||||
if ($user) {
|
||||
echo esc_html($user->user_nicename);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'name':
|
||||
echo esc_html($record_data);
|
||||
break;
|
||||
case 'type':
|
||||
if ('core' == $record_data) {
|
||||
echo esc_html(ucfirst(_x('core', 'update type', 'stops-core-theme-and-plugin-updates')));
|
||||
} elseif ('translation' == $record_data) {
|
||||
echo esc_html(ucfirst(_x('translation', 'update type', 'stops-core-theme-and-plugin-updates')));
|
||||
} elseif ('plugin' == $record_data) {
|
||||
echo esc_html(ucfirst(_x('plugin', 'update type', 'stops-core-theme-and-plugin-updates')));
|
||||
} elseif ('theme' == $record_data) {
|
||||
echo esc_html(ucfirst(_x('theme', 'update type', 'stops-core-theme-and-plugin-updates')));
|
||||
} else {
|
||||
echo esc_html(ucfirst($record_data));
|
||||
}
|
||||
break;
|
||||
case 'version_from':
|
||||
echo esc_html($record_data);
|
||||
break;
|
||||
case 'version':
|
||||
echo esc_html($record_data);
|
||||
break;
|
||||
case 'action':
|
||||
if ('manual' == $record_data) {
|
||||
echo esc_html(ucfirst(_x('manual', 'update type - manual or automatic updates', 'stops-core-theme-and-plugin-updates')));
|
||||
} elseif ('automatic' == $record_data) {
|
||||
echo esc_html(ucfirst(_x('automatic', 'update type - manual or automatic updates', 'stops-core-theme-and-plugin-updates')));
|
||||
} else {
|
||||
echo esc_html(ucfirst($record_data));
|
||||
}
|
||||
break;
|
||||
case 'status':
|
||||
if (1 == $record_data) {
|
||||
echo esc_html__('Success', 'stops-core-theme-and-plugin-updates');
|
||||
} elseif (2 == $record_data) {
|
||||
echo esc_html_x('Update requirements not met', 'Show status updates that are in safe mode', 'stops-core-theme-and-plugin-updates');
|
||||
} else {
|
||||
echo esc_html__('Failure', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
echo esc_html($record_data);
|
||||
break;
|
||||
case 'notes':
|
||||
if (!empty($record_data)) {
|
||||
printf('<a href="#" class="eum-note-expand">%s</a>', esc_html__('Show notes', 'stops-core-theme-and-plugin-updates'));
|
||||
printf('<div style="display: none">%s</div>', wp_kses_post(wpautop($record_data)));
|
||||
}
|
||||
break;
|
||||
case 'stacktrace':
|
||||
if (!empty($record_data)) {
|
||||
$stacktrace = trim($this->get_stacktrace_column($record_data));
|
||||
printf('<a href="#TB_inline?&width=600&height=290&inlineId=trace-%s" title="%s" class="thickbox">%s</a>', esc_html($record->log_id), esc_html__('Trace', 'stops-core-theme-and-plugin-updates'), esc_html__('Show Trace', 'stops-core-theme-and-plugin-updates'));
|
||||
printf('<div id="trace-%s" style="display: none">%s</div>', esc_attr($record->log_id), wp_kses_post(wpautop($stacktrace)));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
?>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures response content of ajax call and returns it
|
||||
*/
|
||||
public function ajax_response() {
|
||||
|
||||
$this->prepare_items();
|
||||
extract($this->_args);
|
||||
extract($this->_pagination_args, EXTR_SKIP);
|
||||
|
||||
ob_start();
|
||||
$this->views();
|
||||
$views = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
if (!empty($_REQUEST['no_placeholder'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified in our AJAX handler.
|
||||
$this->display_rows();
|
||||
} else {
|
||||
$this->display_rows_or_placeholder();
|
||||
}
|
||||
$rows = ob_get_clean();
|
||||
|
||||
// We don't have to update column header, but may be needed later, if sorting is introduced
|
||||
ob_start();
|
||||
$this->print_column_headers();
|
||||
$headers = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
$this->pagination('top');
|
||||
$pagination_top = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
$this->pagination('bottom');
|
||||
$pagination_bottom = ob_get_clean();
|
||||
$response = array();
|
||||
$response['views'] = array($views);
|
||||
$response['rows'] = array($rows);
|
||||
$response['pagination']['top'] = $pagination_top;
|
||||
$response['pagination']['bottom'] = $pagination_bottom;
|
||||
$response['headers'] = $headers;
|
||||
|
||||
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- Both $total_items and $total_pages can be ignored as they are extracted as part of $this->_pagination_args on line 714
|
||||
|
||||
if (isset($total_items)) {
|
||||
/* Translators: %s is the number of total logs. */
|
||||
$response['total_items_i18n'] = sprintf(_n('%s log', '%s logs', $total_items, 'stops-core-theme-and-plugin-updates'), number_format_i18n($total_items));
|
||||
}
|
||||
|
||||
if (isset($total_pages)) {
|
||||
$response['total_pages'] = $total_pages;
|
||||
$response['total_pages_i18n'] = number_format_i18n($total_pages);
|
||||
}
|
||||
|
||||
// phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
|
||||
|
||||
wp_send_json($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the pagination.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $which Which extra table nav to use
|
||||
*/
|
||||
protected function pagination($which) {
|
||||
if (empty($this->_pagination_args)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$total_items = $this->_pagination_args['total_items'];
|
||||
$total_pages = $this->_pagination_args['total_pages'];
|
||||
$tab = $this->_pagination_args['tab'];
|
||||
$view = $this->_pagination_args['view'];
|
||||
$term = $this->_pagination_args['term'];
|
||||
$current = $this->_pagination_args['paged'];
|
||||
|
||||
$infinite_scroll = false;
|
||||
if (isset($this->_pagination_args['infinite_scroll'])) {
|
||||
$infinite_scroll = $this->_pagination_args['infinite_scroll'];
|
||||
}
|
||||
|
||||
/* Translators: %s is the number of total items. */
|
||||
$output = '<span class="displaying-num">' . sprintf(_n('%s item', '%s items', $total_items), number_format_i18n($total_items)) . '</span>'; // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
|
||||
$current_url = set_url_scheme('http://' . sanitize_text_field(wp_unslash((isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '') . (isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''))));
|
||||
|
||||
$current_url = remove_query_arg(array('hotkeys_highlight_last', 'hotkeys_highlight_first'), $current_url);
|
||||
|
||||
$page_links = array();
|
||||
|
||||
$total_pages_before = '<span class="paging-input">';
|
||||
$total_pages_after = '</span>';
|
||||
|
||||
$disable_first = $disable_last = $disable_prev = $disable_next = false;
|
||||
|
||||
if (1 == $current) {
|
||||
$disable_first = true;
|
||||
$disable_prev = true;
|
||||
}
|
||||
if (2 == $current) {
|
||||
$disable_first = true;
|
||||
}
|
||||
if ($current == $total_pages || 0 == $total_items) {
|
||||
$disable_last = true;
|
||||
$disable_next = true;
|
||||
}
|
||||
if ($current == $total_pages - 1) {
|
||||
$disable_last = true;
|
||||
}
|
||||
|
||||
if ($disable_first) {
|
||||
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">«</span>';
|
||||
} else {
|
||||
$page_links[] = sprintf("<a class='first-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
|
||||
esc_url(add_query_arg(array('tab' => $tab, 'view' => $view, 'term' => $term, 'paged' => 1), $current_url)),
|
||||
__('First page'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
'«'
|
||||
);
|
||||
}
|
||||
|
||||
if ($disable_prev) {
|
||||
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">‹</span>';
|
||||
} else {
|
||||
$page_links[] = sprintf("<a class='prev-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
|
||||
esc_url(add_query_arg(array('paged' => max(1, $current-1), 'tab' => $tab, 'view' => $view, 'term' => $term), $current_url)),
|
||||
__('Previous page'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
'‹'
|
||||
);
|
||||
}
|
||||
|
||||
if ('bottom' == $which) {
|
||||
$html_current_page = $current;
|
||||
$total_pages_before = '<span class="screen-reader-text">' . __('Current Page') . '</span><span id="table-paging" class="paging-input" data-tab="' . $tab . '">'; // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
} else {
|
||||
$html_current_page = sprintf("%s<input class='current-page' id='current-page-selector' type='text' name='paged' value='%s' size='%d' aria-describedby='table-paging' data-tab='%s' data-view='%s' />",
|
||||
'<label for="current-page-selector" class="screen-reader-text">' . __('Current Page') . '</label>', // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
$current,
|
||||
strlen($total_pages),
|
||||
$tab,
|
||||
$view
|
||||
);
|
||||
}
|
||||
$html_total_pages = sprintf("<span class='total-pages'>%s</span>", number_format_i18n($total_pages));
|
||||
if (0 == $total_items) {
|
||||
$html_current_page = 0;
|
||||
$html_total_pages = 0;
|
||||
}
|
||||
/* Translators: 1: Current page number, 2: Total number of pages. */
|
||||
$page_links[] = $total_pages_before . sprintf(_x('%1$s of %2$s', 'paging'), $html_current_page, $html_total_pages) . $total_pages_after; // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
|
||||
if ($disable_next) {
|
||||
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">›</span>';
|
||||
} else {
|
||||
$page_links[] = sprintf("<a class='next-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
|
||||
esc_url(add_query_arg(array('paged' => min($total_pages, $current+1), 'tab' => $tab, 'view' => $view, 'term' => $term), $current_url)),
|
||||
__('Next page'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
'›'
|
||||
);
|
||||
}
|
||||
|
||||
if ($disable_last) {
|
||||
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">»</span>';
|
||||
} else {
|
||||
$page_links[] = sprintf("<a class='last-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
|
||||
esc_url(add_query_arg(array('paged' => $total_pages, 'tab' => $tab, 'view' => $view, 'term' => $term), $current_url)),
|
||||
__('Last page'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
'»'
|
||||
);
|
||||
}
|
||||
|
||||
$pagination_links_class = 'pagination-links';
|
||||
if (! empty($infinite_scroll)) {
|
||||
$pagination_links_class = ' hide-if-js';
|
||||
}
|
||||
$output .= "\n<span class='$pagination_links_class'>" . join("\n", $page_links) . '</span>';
|
||||
|
||||
if ($total_pages) {
|
||||
$page_class = $total_pages < 2 ? ' one-page' : '';
|
||||
} else {
|
||||
$page_class = ' no-pages';
|
||||
}
|
||||
$this->_pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";
|
||||
|
||||
echo $this->_pagination;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- needs to be presented in html
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,717 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Easy Updates Manager Plugins List Table class.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage MPSUM_List_Table
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
*/
|
||||
class MPSUM_Plugins_List_Table extends MPSUM_List_Table {
|
||||
|
||||
private $tab = 'plugins';
|
||||
|
||||
private $status = 'all';
|
||||
|
||||
private $allowed_statuses = array();
|
||||
|
||||
private $page = '1';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see WP_List_Table::__construct() for more information on default arguments.
|
||||
*
|
||||
* @param array $args An associative array of arguments.
|
||||
*/
|
||||
public function __construct($args = array()) {
|
||||
|
||||
parent::__construct(array(
|
||||
'singular' => 'plugin',
|
||||
'plural' => 'plugins',
|
||||
'screen' => isset($args['screen']) ? $args['screen'] : 'eum_plugins_tab',
|
||||
'ajax' => true
|
||||
));
|
||||
|
||||
// Get plugins transient
|
||||
$this->plugins_transient = get_site_transient('update_plugins');
|
||||
|
||||
$this->allowed_statuses = apply_filters('eum_plugins_list_table_allowed_statuses', array('all', 'update_disabled', 'update_enabled', 'automatic'));
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- Verified in our AJAX handler
|
||||
if (isset($_REQUEST['action']) && 'eum_ajax' === $_REQUEST['action']) {
|
||||
$this->status = 'all';
|
||||
if (isset($_REQUEST['view']) && in_array($_REQUEST['view'], array_values(array_diff($this->allowed_statuses, array($this->status))))) {
|
||||
$this->status = sanitize_text_field(wp_unslash($_REQUEST['view']));
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['s']))
|
||||
$_SERVER['REQUEST_URI'] = add_query_arg('s', sanitize_text_field(wp_unslash($_REQUEST['s'])));
|
||||
|
||||
$this->page = isset($_REQUEST['paged']) ? sanitize_text_field(wp_unslash($_REQUEST['paged'])) : '1';
|
||||
} else {
|
||||
$this->status = 'all';
|
||||
if (isset($args['view']) && in_array($args['view'], array_values(array_diff($this->allowed_statuses, array($this->status))))) {
|
||||
$this->status = $args['view'];
|
||||
}
|
||||
|
||||
$this->page = isset($args['paged']) ? $args['paged'] : '1';
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table classes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_table_classes() {
|
||||
return array('widefat', $this->_args['plural']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax user capability check
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function ajax_user_can() {
|
||||
return current_user_can('activate_plugins');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares plugin items to display
|
||||
*
|
||||
* Prepares plugin items by setting pagination variables, order, filter
|
||||
*/
|
||||
public function prepare_items() {
|
||||
|
||||
global $orderby, $order, $totals;
|
||||
$order = 'DESC';
|
||||
$orderby = 'Name';
|
||||
|
||||
/**
|
||||
* Filter the full array of plugins to list in the Plugins list table.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @see get_plugins()
|
||||
*
|
||||
* @param array $plugins An array of plugins to display in the list table.
|
||||
*/
|
||||
if (!function_exists('get_plugins')) {
|
||||
include_once ABSPATH . "wp-admin/includes/plugin.php";
|
||||
}
|
||||
|
||||
$plugins = array(
|
||||
'all' => apply_filters('all_plugins', get_plugins()),
|
||||
'update_enabled' => array(),
|
||||
'update_disabled' => array(),
|
||||
'automatic' => array()
|
||||
);
|
||||
|
||||
$plugin_info = get_site_transient('update_plugins');
|
||||
|
||||
$plugin_options = MPSUM_Updates_Manager::get_options('plugins');
|
||||
$plugin_automatic_options = MPSUM_Updates_Manager::get_options('plugins_automatic');
|
||||
foreach ((array) $plugins['all'] as $plugin_file => $plugin_data) {
|
||||
// Extra info if known. array_merge() ensures $plugin_data has precedence if keys collide.
|
||||
if (isset($plugin_info->response[$plugin_file])) {
|
||||
$plugins['all'][$plugin_file] = $plugin_data = array_merge((array) $plugin_info->response[$plugin_file], $plugin_data);
|
||||
} elseif (isset($plugin_info->no_update[$plugin_file])) {
|
||||
$plugins['all'][$plugin_file] = $plugin_data = array_merge((array) $plugin_info->no_update[$plugin_file], $plugin_data);
|
||||
}
|
||||
|
||||
|
||||
if (false !== $key = array_search($plugin_file, $plugin_options)) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $key is unused
|
||||
$plugins['update_disabled'][$plugin_file] = $plugin_data;
|
||||
} else {
|
||||
$plugins['update_enabled'][$plugin_file] = $plugin_data;
|
||||
if (in_array($plugin_file, $plugin_automatic_options)) {
|
||||
$plugins['automatic'][$plugin_file] = $plugin_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$plugins = apply_filters('eum_plugins_list_table_prepare_items', $plugins);
|
||||
|
||||
$totals = array();
|
||||
foreach ($plugins as $type => $list)
|
||||
$totals[$type] = count($list);
|
||||
|
||||
// Disable the automatic updates view
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['plugin_updates']) && 'individual' !== $core_options['plugin_updates']) {
|
||||
unset($totals['automatic']);
|
||||
$plugins['automatic'] = array();
|
||||
}
|
||||
|
||||
if (empty($plugins[$this->status]))
|
||||
$this->status = 'all';
|
||||
|
||||
$this->items = array();
|
||||
foreach ($plugins[$this->status] as $plugin_file => $plugin_data) {
|
||||
// Translate, Don't Apply Markup, Sanitize HTML
|
||||
remove_action("after_plugin_row_$plugin_file", 'wp_plugin_update_row', 10, 2);
|
||||
$this->items[$plugin_file] = _get_plugin_data_markup_translate($plugin_file, $plugin_data, false, true);
|
||||
}
|
||||
|
||||
$total_this_page = $totals[$this->status];
|
||||
|
||||
// Get plugins per page
|
||||
$user_id = get_current_user_id();
|
||||
$plugins_per_page = get_user_meta($user_id, 'mpsum_items_per_page', true);
|
||||
if (! is_numeric($plugins_per_page)) {
|
||||
$plugins_per_page = 100;
|
||||
}
|
||||
|
||||
$start = ($this->page - 1) * $plugins_per_page;
|
||||
|
||||
if ($total_this_page > $plugins_per_page)
|
||||
$this->items = array_slice($this->items, $start, $plugins_per_page);
|
||||
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_this_page,
|
||||
'per_page' => $plugins_per_page,
|
||||
'total_pages' => ceil($total_this_page / $plugins_per_page),
|
||||
// Set plugin status value (useful for AJAX)
|
||||
'view' => $this->status,
|
||||
'tab' => $this->tab,
|
||||
'paged' => $this->page
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures response content of ajax call and returns it
|
||||
*/
|
||||
public function ajax_response() {
|
||||
|
||||
$this->prepare_items();
|
||||
extract($this->_args);
|
||||
extract($this->_pagination_args, EXTR_SKIP);
|
||||
|
||||
ob_start();
|
||||
$this->views();
|
||||
$views = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
if (!empty($_REQUEST['no_placeholder'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified in our AJAX handler
|
||||
$this->display_rows();
|
||||
} else {
|
||||
$this->display_rows_or_placeholder();
|
||||
}
|
||||
$rows = ob_get_clean();
|
||||
|
||||
// We don't have to update column header, but may be needed later, if sorting is introduced
|
||||
ob_start();
|
||||
$this->print_column_headers();
|
||||
$headers = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
$this->pagination('top');
|
||||
$pagination_top = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
$this->pagination('bottom');
|
||||
$pagination_bottom = ob_get_clean();
|
||||
$response = array();
|
||||
$response['views'] = array($views);
|
||||
$response['rows'] = array($rows);
|
||||
$response['pagination']['top'] = $pagination_top;
|
||||
$response['pagination']['bottom'] = $pagination_bottom;
|
||||
$response['headers'] = $headers;
|
||||
|
||||
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- Both $total_items and $total_pages can be ignored as they are extracted as part of $this->_pagination_args on line 186
|
||||
|
||||
if (isset($total_items)) {
|
||||
/* Translators: %s is the number of plugins. */
|
||||
$response['total_items_i18n'] = sprintf(_n('%s plugin', '%s plugins', $total_items), number_format_i18n($total_items)); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
}
|
||||
|
||||
if (isset($total_pages)) {
|
||||
$response['total_pages'] = $total_pages;
|
||||
$response['total_pages_i18n'] = number_format_i18n($total_pages);
|
||||
}
|
||||
|
||||
// phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
|
||||
|
||||
wp_send_json($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call back function for search functionality
|
||||
*
|
||||
* @static string $term Term to search
|
||||
* @param array $plugin Plugin name
|
||||
* @return boolean Returns true if term found, otherwise false
|
||||
*/
|
||||
public function _search_callback($plugin) {
|
||||
static $term;
|
||||
if (is_null($term))
|
||||
$term = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified in our AJAX handler
|
||||
|
||||
foreach ($plugin as $value) {
|
||||
if (false !== stripos(wp_strip_all_tags($value), $term)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback order
|
||||
*
|
||||
* @global string $orderby
|
||||
* @global string $order
|
||||
* @param array $plugin_a Plugin A
|
||||
* @param array $plugin_b Plugin B
|
||||
* @return int
|
||||
*/
|
||||
public function _order_callback($plugin_a, $plugin_b) {
|
||||
global $orderby, $order;
|
||||
|
||||
$a = $plugin_a[$orderby];
|
||||
$b = $plugin_b[$orderby];
|
||||
|
||||
if ($a == $b)
|
||||
return 0;
|
||||
|
||||
if ('DESC' == $order) {
|
||||
return ($a < $b) ? 1 : -1;
|
||||
} else {
|
||||
return ($a < $b) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No items
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function no_items() {
|
||||
global $plugins;
|
||||
|
||||
if (!empty($plugins['all'])) {
|
||||
esc_html_e('No plugins found.', 'stops-core-theme-and-plugin-updates');
|
||||
} else {
|
||||
esc_html_e('You do not appear to have any plugins available at this time.', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'cb' => !in_array($this->status, array('mustuse', 'dropins')) ? '<input type="checkbox" />' : '',
|
||||
'name' => esc_html__('Plugin', 'stops-core-theme-and-plugin-updates'),
|
||||
'description' => esc_html__('Description', 'stops-core-theme-and-plugin-updates'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sotable columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_sortable_columns() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get views
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_views() {
|
||||
global $totals;
|
||||
|
||||
$status_links = array();
|
||||
foreach ($totals as $type => $count) {
|
||||
if (!$count)
|
||||
continue;
|
||||
|
||||
switch ($type) {
|
||||
case 'all':
|
||||
/* Translators: %s is the number of total plugins. */
|
||||
$text = _nx('All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $count, 'plugins', 'stops-core-theme-and-plugin-updates');
|
||||
break;
|
||||
case 'update_enabled':
|
||||
/* Translators: %s is the number of total updates enabled plugins. */
|
||||
$text = _n('Updates enabled <span class="count">(%s)</span>', 'Updates enabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates');
|
||||
break;
|
||||
case 'update_disabled':
|
||||
/* Translators: %s is the number of total updates disabled plugins. */
|
||||
$text = _n('Updates disabled <span class="count">(%s)</span>', 'Updates disabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates');
|
||||
break;
|
||||
case 'automatic':
|
||||
/* Translators: %s is the number of total automatic updates plugins. */
|
||||
$text = _n('Automatic updates <span class="count">(%s)</span>', 'Automatic updates <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates');
|
||||
break;
|
||||
default:
|
||||
$text = apply_filters('eum_plugins_list_table_text_view', '', $type, $count);
|
||||
break;
|
||||
}
|
||||
|
||||
if ('search' != $type) {
|
||||
$plugin_url = MPSUM_Admin::get_url();
|
||||
$query_args = array(
|
||||
'tab' => $this->tab,
|
||||
'view' => $type
|
||||
);
|
||||
$status_links[$type] = sprintf("<a href='%s' data-view='%s' %s>%s</a>",
|
||||
add_query_arg($query_args, $plugin_url),
|
||||
$this->status,
|
||||
($type == $this->status) ? ' class="current"' : '',
|
||||
sprintf($text, number_format_i18n($count))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $status_links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bulk actions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_bulk_actions() {
|
||||
$actions = array();
|
||||
|
||||
$actions['allow-update-selected'] = esc_html__('Plugin updates on', 'stops-core-theme-and-plugin-updates');
|
||||
$actions['disallow-update-selected'] = esc_html__('Plugin updates off', 'stops-core-theme-and-plugin-updates');
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['plugin_updates']) && 'individual' == $core_options['plugin_updates']) {
|
||||
$actions['allow-automatic-selected'] = esc_html__('Automatic updates on', 'stops-core-theme-and-plugin-updates');
|
||||
$actions['disallow-automatic-selected'] = esc_html__('Automatic updates off', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
|
||||
return apply_filters('eum_plugins_list_table_bulk_actions', $actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk action
|
||||
*
|
||||
* @param string $which Specify which bulk action
|
||||
* @return null
|
||||
*/
|
||||
public function bulk_actions($which = '') {
|
||||
|
||||
if (in_array($this->status, array('mustuse', 'dropins')))
|
||||
return;
|
||||
|
||||
parent::bulk_actions($which);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra table Nav
|
||||
*
|
||||
* @param string $which Specify which table nav
|
||||
* @return null
|
||||
*/
|
||||
protected function extra_tablenav($which) {
|
||||
|
||||
if (! in_array($this->status, array('recently_activated', 'mustuse', 'dropins')))
|
||||
return;
|
||||
|
||||
echo '<div class="alignleft actions">';
|
||||
|
||||
if (! $this->screen->in_admin('network') && 'recently_activated' == $this->status) {
|
||||
submit_button(esc_html__('Clear list', 'stops-core-theme-and-plugin-updates'), 'button', 'clear-recent-list', false);
|
||||
} elseif ('top' == $which && 'mustuse' == $this->status) {
|
||||
echo '<p>' .
|
||||
sprintf(
|
||||
/* translators: %s is the MU plugin directory path. */
|
||||
esc_html__('Files in the %s directory are executed automatically.', 'stops-core-theme-and-plugin-updates'),
|
||||
'<code>' . esc_html(str_replace(ABSPATH, '/', WPMU_PLUGIN_DIR)) . '</code>'
|
||||
) .
|
||||
'</p>';
|
||||
} elseif ('top' == $which && 'dropins' == $this->status) {
|
||||
echo '<p>' .
|
||||
sprintf(
|
||||
/* translators: %s is the wp-content directory path. */
|
||||
esc_html__('Drop-ins are advanced plugins in the %s directory that replace WordPress functionality when present.', 'stops-core-theme-and-plugin-updates'),
|
||||
'<code>' . esc_html(str_replace(ABSPATH, '', WP_CONTENT_DIR)) . '</code>'
|
||||
) .
|
||||
'</p>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Currect action
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function current_action() {
|
||||
if (isset($_POST['clear-recent-list'])) // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified in our AJAX handler
|
||||
return 'clear-recent-list';
|
||||
|
||||
return parent::current_action();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display rows
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function display_rows() {
|
||||
|
||||
if (is_multisite() && ! $this->screen->in_admin('network') && in_array($this->status, array('mustuse', 'dropins')))
|
||||
return;
|
||||
|
||||
foreach ($this->items as $plugin_file => $plugin_data)
|
||||
$this->single_row(array($plugin_file, $plugin_data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Single row
|
||||
*
|
||||
* @global string $s
|
||||
* @global array $totals
|
||||
* @param array $item Single row item
|
||||
*/
|
||||
public function single_row($item) {
|
||||
|
||||
list($plugin_file, $plugin_data) = $item;
|
||||
|
||||
/**
|
||||
* Filter the action links that show up under each plugin row.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param string Relative plugin file path
|
||||
* @param array $plugin_data An array of plugin data.
|
||||
* @param string $this->status Status of the plugin.
|
||||
*/
|
||||
$class = 'active';
|
||||
$plugin_options = MPSUM_Updates_Manager::get_options('plugins');
|
||||
if (false !== $key = array_search($plugin_file, $plugin_options)) {
|
||||
$class = 'inactive';
|
||||
}
|
||||
$checkbox_id = "checkbox_" . md5($plugin_data['Name']);
|
||||
/* translators: %s is the plugin name. */
|
||||
$checkbox = "<label class='screen-reader-text' for='" . $checkbox_id . "' >" . sprintf(esc_html__('Select %s', 'stops-core-theme-and-plugin-updates'), $plugin_data['Name']) . "</label>"
|
||||
. "<input type='checkbox' name='checked[]' value='" . esc_attr($plugin_file) . "' id='" . $checkbox_id . "' />";
|
||||
$description = $plugin_data['Description'] ? $plugin_data['Description'] : '';
|
||||
$plugin_name = $plugin_data['Name'];
|
||||
$plugin_slug = $item[0];
|
||||
|
||||
$id = sanitize_title($plugin_name);
|
||||
|
||||
echo "<tr id='" . esc_attr($id) . "' class='" . esc_attr($class) . "'>";
|
||||
|
||||
list($columns, $hidden, $sortable, $primary) = $this->get_column_info();// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- THis can be ignored as it is a list and are used below
|
||||
|
||||
foreach ($columns as $column_name => $column_display_name) {
|
||||
|
||||
$is_style_display_none = in_array($column_name, $hidden);
|
||||
|
||||
switch ($column_name) {
|
||||
case 'cb':
|
||||
echo "<th scope='row' class='check-column'>$checkbox</th>";// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- needs to be presented in html
|
||||
break;
|
||||
case 'name':
|
||||
echo "<td class='plugin-title'" . ($is_style_display_none ? ' style="display:none;"' : '') . "'>";
|
||||
$icon = '<span class="dashicons dashicons-admin-plugins"></span>';
|
||||
$preferred_icons = array('svg', '1x', '2x', 'default');
|
||||
foreach ($preferred_icons as $preferred_icon) {
|
||||
if (isset($plugin_data['icons'][$preferred_icon]) && ! empty($plugin_data['icons'][$preferred_icon])) {
|
||||
$icon = '<img src="' . esc_url($plugin_data['icons'][$preferred_icon]) . '" alt="" />';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
echo wp_kses($icon, array('span' => array('class' => true), 'img' => array('src' => true, 'alt' => true)));
|
||||
echo '<div class="eum-plugins-name-actions">';
|
||||
echo "<h3 class='eum-plugins-name'>".esc_html($plugin_name)."</h3>";
|
||||
echo '<div class="eum-plugins-wrapper">';
|
||||
printf('<h4>%s</h4>', esc_html__('Plugin updates', 'stops-core-theme-and-plugin-updates'));
|
||||
|
||||
echo '<div class="toggle-wrapper toggle-wrapper-plugins">';
|
||||
|
||||
$enable_class = $disable_class = '';
|
||||
$checked = 'false';
|
||||
$key = in_array($plugin_slug, $plugin_options);
|
||||
if (! $key) {
|
||||
$enable_class = 'eum-enabled eum-active';
|
||||
$checked = 'true';
|
||||
} else {
|
||||
$disable_class = 'eum-disabled eum-active';
|
||||
}
|
||||
|
||||
printf('<input type="hidden" name="plugins[%s]" value="%s">',
|
||||
esc_attr($plugin_slug),
|
||||
esc_attr($checked)
|
||||
);
|
||||
|
||||
printf('<button aria-label="%s" class="eum-toggle-button eum-enabled %s" data-checked="%s" value="on">%s</button>',
|
||||
esc_attr__('Allow updates', 'stops-core-theme-and-plugin-updates'),
|
||||
esc_attr($enable_class),
|
||||
esc_attr($plugin_slug),
|
||||
esc_html__('Allowed', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
|
||||
printf('<button aria-label="%s" class="eum-toggle-button eum-disabled %s" data-checked="%s value="off">%s</button>',
|
||||
esc_attr__('Disallow updates', 'stops-core-theme-and-plugin-updates'),
|
||||
esc_attr($disable_class),
|
||||
esc_attr($plugin_slug),
|
||||
esc_html__('Blocked', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
|
||||
echo '</div></div>';
|
||||
|
||||
// Automatic Link
|
||||
$plugin_automatic_options = MPSUM_Updates_Manager::get_options('plugins_automatic');
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['plugin_updates']) && 'individual' == $core_options['plugin_updates']) {
|
||||
printf('<div class="eum-plugins-automatic-wrapper" %s>', ($key) ? 'style="display: none;"' : '');
|
||||
printf('<h4>%s</h4>', esc_html__('Automatic updates', 'stops-core-theme-and-plugin-updates'));
|
||||
echo '<div class="toggle-wrapper toggle-wrapper-plugins-automatic">';
|
||||
$enable_class = $disable_class = '';
|
||||
$checked = 'false';
|
||||
if (in_array($plugin_slug, $plugin_automatic_options)) {
|
||||
$enable_class = 'eum-active';
|
||||
$checked = 'true';
|
||||
} else {
|
||||
$disable_class = 'eum-active';
|
||||
}
|
||||
|
||||
printf('<input type="hidden" name="plugins_automatic[%s]" value="%s">',
|
||||
esc_attr($plugin_slug),
|
||||
esc_attr($checked)
|
||||
);
|
||||
|
||||
printf('<button aria-label="%s" class="eum-toggle-button eum-enabled %s" data-checked="%s" value="on">%s</button>',
|
||||
esc_html__('Enable automatic updates', 'stops-core-theme-and-plugin-updates'),
|
||||
esc_attr($enable_class),
|
||||
esc_attr($plugin_slug),
|
||||
esc_html__('On', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
|
||||
printf('<button aria-label="%s" class="eum-toggle-button eum-disabled %s" data-checked="%s" value="off">%s</button>',
|
||||
esc_attr__('Enable automatic updates', 'stops-core-theme-and-plugin-updates'),
|
||||
esc_attr($disable_class),
|
||||
esc_attr($plugin_slug),
|
||||
esc_html__('Off', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
|
||||
echo '</div></div>';
|
||||
}
|
||||
do_action('eum_populate_plugins_list_table_column', $column_name, $item);
|
||||
echo '</div>';
|
||||
echo "</td>";
|
||||
break;
|
||||
case 'description':
|
||||
echo "<td class='column-description desc'" . ($is_style_display_none ? ' style="display:none;"' : '') . ">
|
||||
<div class='plugin-description'><p>".($description ? esc_html($description) : ' ')."</p></div>
|
||||
<div class='".esc_attr($class)." second plugin-version-author-uri'>";
|
||||
|
||||
$plugin_meta = array();
|
||||
if (!empty($plugin_data['Version'])) {
|
||||
/* translators: %s is the plugin version. */
|
||||
$plugin_meta[] = sprintf(esc_html__('Version %s', 'stops-core-theme-and-plugin-updates'), $plugin_data['Version']);
|
||||
}
|
||||
if (!empty($plugin_data['Author'])) {
|
||||
$author = $plugin_data['Author'];
|
||||
if (!empty($plugin_data['AuthorURI']))
|
||||
$author = '<a href="' . $plugin_data['AuthorURI'] . '">' . $plugin_data['Author'] . '</a>';
|
||||
/* translators: %s is the plugin author. */
|
||||
$plugin_meta[] = sprintf(esc_html__('By %s', 'stops-core-theme-and-plugin-updates'), $author);
|
||||
}
|
||||
|
||||
// Details link using API info, if available
|
||||
if (isset($plugin_data['slug']) && current_user_can('install_plugins')) {
|
||||
$plugin_meta[] = sprintf('<a href="%s" class="thickbox open-plugin-details-modal" aria-label="%s" data-title="%s">%s</a>',
|
||||
esc_url(wp_nonce_url(network_admin_url('plugin-install.php?tab=plugin-information&plugin=' . $plugin_data['slug'] .
|
||||
'&eum_action=EUM_modal&TB_iframe=true&width=600&height=550'), 'eum-modal')),
|
||||
/* translators: %s is the plugin name. */
|
||||
esc_attr(sprintf(esc_html__('More information about %s', 'stops-core-theme-and-plugin-updates'), $plugin_name)),
|
||||
esc_attr($plugin_name),
|
||||
esc_html__('View details', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
} elseif (! empty($plugin_data['PluginURI'])) {
|
||||
$plugin_meta[] = sprintf('<a href="%s">%s</a>',
|
||||
esc_url($plugin_data['PluginURI']),
|
||||
esc_html__('Visit plugin site', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filter the array of row meta for each plugin in the Plugins list table.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $plugin_meta An array of the plugin's metadata,
|
||||
* including the version, author,
|
||||
* author URI, and plugin URI.
|
||||
* @param string $plugin_file Path to the plugin file, relative to the plugins directory.
|
||||
* @param array $plugin_data An array of plugin data.
|
||||
* @param string $this->status Status of the plugin. Defaults are 'All', 'Active',
|
||||
* 'Inactive', 'Recently Activated', 'Upgrade', 'Must-Use',
|
||||
* 'Drop-ins', 'Search'.
|
||||
*/
|
||||
$plugin_meta = apply_filters('plugin_row_meta', $plugin_meta, $plugin_file, $plugin_data, $this->status);
|
||||
echo implode(' | ', $plugin_meta);// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- needs to be presented in html
|
||||
|
||||
// Premium only - Check if plugin has been removed from the repo
|
||||
if (MPSUM_Updates_Manager::get_instance()->is_premium()) {
|
||||
MPSUM_Check_Plugins_Removed::get_instance()->check_if_plugin_removed($plugin_file);
|
||||
}
|
||||
|
||||
// Show active status for blogs
|
||||
if (is_multisite()) {
|
||||
if (is_plugin_active_for_network($plugin_file)) {
|
||||
printf('<div class="mpsum-success mpsum-bold">%s</div>', esc_html__('This plugin is active for your network.', 'stops-core-theme-and-plugin-updates'));
|
||||
} else {
|
||||
printf('<div class="mpsum-notice mpsum-regular"><a href="#" data-plugin-file="%s" class="eum-list-plugins-action">%s</a><div class="eum-list-plugins"></div></div>', esc_attr($plugin_file), esc_html__('View all sites that have this plugin installed.', 'stops-core-theme-and-plugin-updates'));
|
||||
}
|
||||
} else {
|
||||
if (is_plugin_active($plugin_file)) {
|
||||
printf('<div class="mpsum-success mpsum-bold">%s</div>', esc_html__('This plugin is active for your site.', 'stops-core-theme-and-plugin-updates'));
|
||||
} else {
|
||||
printf('<div class="mpsum-error mpsum-bold">%s</div>', esc_html__('This plugin is inactive for your site.', 'stops-core-theme-and-plugin-updates').' '.esc_html__('Consider removing it.', 'stops-core-theme-and-plugin-updates'));
|
||||
}
|
||||
}
|
||||
|
||||
// Show safe mode options if enabled
|
||||
if (MPSUM_Updates_Manager::get_instance()->is_premium()) {
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['safe_mode']) && 'on' === $core_options['safe_mode']) {
|
||||
$safe_mode_instance = MPSUM_Safe_Mode::get_instance();
|
||||
$plugin_object = $safe_mode_instance->perform_api_check($plugin_file);
|
||||
$safe_mode_instance->maybe_output_check_safe_mode($plugin_object);
|
||||
}
|
||||
}
|
||||
echo "</div></td>";
|
||||
break;
|
||||
default:
|
||||
echo "<td class='" . esc_attr($column_name)." column-" . esc_attr($column_name) . "'" . ($is_style_display_none ? ' style="display:none;"' : '') . ">";
|
||||
|
||||
/**
|
||||
* Fires inside each custom column of the Plugins list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $column_name Name of the column.
|
||||
* @param string $plugin_file Path to the plugin file.
|
||||
* @param array $plugin_data An array of plugin data.
|
||||
*/
|
||||
do_action('manage_plugins_custom_column', $column_name, $plugin_file, $plugin_data);
|
||||
echo "</td>";
|
||||
}
|
||||
}
|
||||
|
||||
echo "</tr>";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (class_exists('MPSUM_Reset_Options')) return;
|
||||
|
||||
/**
|
||||
* Class MPSUM_Reset_Options
|
||||
*
|
||||
* Resets plugin options as if freshly installed
|
||||
*/
|
||||
class MPSUM_Reset_Options {
|
||||
|
||||
/**
|
||||
* MPSUM_Reset_Options constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
add_action('eum_advanced_headings', array($this, 'heading'), 99);
|
||||
add_action('eum_advanced_settings', array($this, 'settings'), 99);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a singleton instance
|
||||
*
|
||||
* @return MPSUM_Reset_Options object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature heading
|
||||
*/
|
||||
public function heading() {
|
||||
printf('<div data-menu_name="reset-options">%s <span class="eum-advanced-menu-text">%s</span></div>', '<i class="material-icons">delete_outline</i>', esc_html__('Reset options', 'stops-core-theme-and-plugin-updates'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs feature settings
|
||||
*/
|
||||
public function settings() {
|
||||
Easy_Updates_Manager()->include_template('reset-options.php');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
/**
|
||||
* Controller class for configuring and sending notifications emails upon the completion or failure of a plugin, theme, translation, or core background update (automatic updates)
|
||||
*/
|
||||
class MPSUM_Send_Email_Notifications {
|
||||
|
||||
/**
|
||||
* Holds the class instance.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Set a class instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if (null == self::$instance) {
|
||||
self::$instance = new self;
|
||||
}
|
||||
return self::$instance;
|
||||
} //end get_instance
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Read in the options and determine which notifications are disabled.
|
||||
*/
|
||||
private function __construct() {
|
||||
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
add_filter('automatic_updates_send_debug_email', '__return_false', PHP_INT_MAX - 10);
|
||||
$send_email = !isset($core_options['notification_core_update_emails']) || 'on' === $core_options['notification_core_update_emails'];
|
||||
$send_email = $send_email || !isset($core_options['plugin_auto_updates_notification_emails']) || 'on' === $core_options['plugin_auto_updates_notification_emails'];
|
||||
$send_email = $send_email || !isset($core_options['theme_auto_updates_notification_emails']) || 'on' === $core_options['theme_auto_updates_notification_emails'];
|
||||
$send_email = $send_email || !isset($core_options['translation_auto_updates_notification_emails']) || 'on' === $core_options['translation_auto_updates_notification_emails'];
|
||||
if ($send_email) {
|
||||
add_action('automatic_updates_complete', array($this, 'send_notification_emails'), 100, 1);
|
||||
}
|
||||
add_filter('auto_core_update_send_email', '__return_false', PHP_INT_MAX - 10);
|
||||
add_filter('auto_plugin_update_send_email', '__return_false', PHP_INT_MAX - 10, 2);
|
||||
add_filter('auto_theme_update_send_email', '__return_false', PHP_INT_MAX - 10, 2);
|
||||
if (isset($core_options['notification_core_update_emails']) && 'off' === $core_options['notification_core_update_emails']) {
|
||||
add_filter('send_core_update_notification_email', '__return_false', PHP_INT_MAX - 10);
|
||||
} else {
|
||||
add_filter('send_core_update_notification_email', array($this, 'email_flood_control'), PHP_INT_MAX - 10);
|
||||
}
|
||||
|
||||
} //end constructor
|
||||
|
||||
/**
|
||||
* Send notification emails
|
||||
*
|
||||
* @param array $update_results The results of all attempted updates
|
||||
*/
|
||||
public function send_notification_emails($update_results) {
|
||||
if (empty($update_results)) return;
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
$body = array();
|
||||
$failures = 0;
|
||||
|
||||
// Core
|
||||
if ((!isset($core_options['notification_core_update_emails']) || 'on' === $core_options['notification_core_update_emails']) && isset($update_results['core'])) {
|
||||
$result = $update_results['core'][0];
|
||||
if ($result->result && ! is_wp_error($result->result)) {
|
||||
/* translators: %s: WordPress version. */
|
||||
$body[] = sprintf(__('SUCCESS: WordPress was successfully updated to %s'), $result->name); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
} else {
|
||||
/* translators: %s: WordPress version. */
|
||||
$body[] = sprintf(__('FAILED: WordPress failed to update to %s'), $result->name); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
$failures++;
|
||||
}
|
||||
$body[] = '';
|
||||
}
|
||||
|
||||
// Plugins, Themes, Translations
|
||||
$entities = array();
|
||||
if (!isset($core_options['plugin_auto_updates_notification_emails']) || 'on' === $core_options['plugin_auto_updates_notification_emails']) $entities[] = 'plugin';
|
||||
if (!isset($core_options['theme_auto_updates_notification_emails']) || 'on' === $core_options['theme_auto_updates_notification_emails']) $entities[] = 'theme';
|
||||
if (!isset($core_options['translation_auto_updates_notification_emails']) || 'on' === $core_options['translation_auto_updates_notification_emails']) $entities[] = 'translation';
|
||||
|
||||
foreach ($entities as $type) {
|
||||
if (!isset($update_results[$type])) {
|
||||
if (false !== ($key = array_search($type, $entities))) {
|
||||
unset($entities[$key]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$success_items = array();
|
||||
foreach ($update_results[$type] as $key => $item) {
|
||||
if ($item->result && !is_wp_error($item->result)) {
|
||||
$success_items[] = $item;
|
||||
} elseif (empty($item->name) || empty($item->item->current_version) || empty($item->item->new_version)) {
|
||||
unset($update_results[$type][$key]);
|
||||
}
|
||||
}
|
||||
$update_results[$type] = array_values($update_results[$type]);
|
||||
|
||||
if ($success_items) {
|
||||
$messages = array(
|
||||
'plugin' => __('The following plugins were successfully updated:'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
'theme' => __('The following themes were successfully updated:'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
'translation' => __('The following translations were successfully updated:'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
);
|
||||
|
||||
$body[] = $messages[$type];
|
||||
if (in_array($type, array('plugin', 'theme'))) {
|
||||
foreach ($success_items as $entity) {
|
||||
$url = isset($entity->item->url) && '' !== $entity->item->url ? ' - '.$entity->item->url : '';
|
||||
/* Translators: 1: Name of item, 2: Current version, 3: New version, 4: Item URL. */
|
||||
$body[] = ' * ' . sprintf(__('SUCCESS: %1$s (from version %2$s to %3$s)%4$s'), $entity->name, $entity->item->current_version, $entity->item->new_version, $url); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
}
|
||||
} else {
|
||||
foreach (wp_list_pluck($success_items, 'name') as $name) {
|
||||
/* translators: %s is Name of item. */
|
||||
$body[] = ' * ' . sprintf(__('SUCCESS: %s'), $name); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
}
|
||||
}
|
||||
$body[] = '';
|
||||
}
|
||||
|
||||
if ($success_items !== $update_results[$type]) {
|
||||
// Failed updates.
|
||||
$messages = array(
|
||||
'plugin' => __('The following plugins failed to update:'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
'theme' => __('The following themes failed to update:'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
'translation' => __('The following translations failed to update:'), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
);
|
||||
|
||||
$body[] = $messages[$type];
|
||||
|
||||
foreach ($update_results[$type] as $item) {
|
||||
if (!$item->result || is_wp_error($item->result)) {
|
||||
/* translators: %s is Name of item. */
|
||||
$body[] = ' * ' . sprintf(__('FAILED: %s'), $item->name); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
$failures++;
|
||||
}
|
||||
}
|
||||
$body[] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$site_title = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
|
||||
|
||||
if ($failures) {
|
||||
/* translators: %s is Site title. */
|
||||
$subject = sprintf(__('[%s] Background Update Failed'), $site_title); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
} else {
|
||||
/* translators: %s is Site title. */
|
||||
$subject = sprintf(__('[%s] Background Update Finished'), $site_title); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
}
|
||||
|
||||
if (!empty($body)) {
|
||||
/* translators: %s: Network home URL. */
|
||||
array_unshift($body, sprintf(__('WordPress site: %s'), network_home_url('/'))); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
/* Translators: %s is the label name. */
|
||||
$body[] = trim(sprintf(__("Thanks! -- The %s team", 'stops-core-theme-and-plugin-updates'), apply_filters('eum_whitelabel_name', __('Easy Updates Manager', 'stops-core-theme-and-plugin-updates'))));
|
||||
$body[] = '';
|
||||
|
||||
$body[] = trim(__('UPDATE LOG ==========')); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
$body[] = '';
|
||||
}
|
||||
|
||||
if (!isset($core_options['notification_core_update_emails']) || 'on' === $core_options['notification_core_update_emails']) $entities[] = 'core';
|
||||
|
||||
foreach ($entities as $type) {
|
||||
if (!isset($update_results[$type])) {
|
||||
if (false !== ($key = array_search($type, $entities))) {
|
||||
unset($entities[$key]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($update_results[$type] as $update) {
|
||||
$body[] = $update->name;
|
||||
$body[] = str_repeat('-', strlen($update->name));
|
||||
|
||||
foreach ($update->messages as $message) {
|
||||
$body[] = ' ' . html_entity_decode(str_replace('…', '...', $message));
|
||||
}
|
||||
|
||||
if (is_wp_error($update->result)) {
|
||||
$results = array('update' => $update->result);
|
||||
|
||||
if ('rollback_was_required' === $update->result->get_error_code()) {
|
||||
$results = (array) $update->result->get_error_data();
|
||||
}
|
||||
|
||||
foreach ($results as $result_type => $result) {
|
||||
if (!is_wp_error($result)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('rollback' === $result_type) {
|
||||
/* translators: 1: Error code, 2: Error message. */
|
||||
$body[] = ' ' . sprintf(__('Rollback Error: [%1$s] %2$s'), $result->get_error_code(), $result->get_error_message()); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
} else {
|
||||
/* translators: 1: Error code, 2: Error message. */
|
||||
$body[] = ' ' . sprintf(__('Error: [%1$s] %2$s'), $result->get_error_code(), $result->get_error_message()); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- WordPress core handles the translation.
|
||||
}
|
||||
if ($result->get_error_data()) {
|
||||
$body[] = ' ' . implode(', ', (array) $result->get_error_data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$body[] = '';
|
||||
}
|
||||
}
|
||||
if (!empty($entities) && !empty($body)) {
|
||||
$email = array(
|
||||
'to' => get_site_option('admin_email'),
|
||||
'subject' => $subject,
|
||||
'body' => implode("\n", $body),
|
||||
'headers' => '',
|
||||
);
|
||||
$email = $this->maybe_change_automatic_update_email($email);
|
||||
wp_mail($email['to'], wp_specialchars_decode($email['subject']), $email['body'], $email['headers']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flood control WordPress core update notifications; called by the WP filter send_core_update_notification_email
|
||||
*
|
||||
* @since 8.0.6
|
||||
* @access public
|
||||
* @see __construct
|
||||
*
|
||||
* @param bool $value Whether to send emails or not.
|
||||
*
|
||||
* @return bool Whether to send emails or not.
|
||||
*/
|
||||
public function email_flood_control($value) {
|
||||
$no_core_email_before = get_site_option('eum_no_core_email_before');
|
||||
if (!$no_core_email_before || time() > $no_core_email_before) {
|
||||
// Set site option for the next 24 hours to prevent users from being overwhelmed with emails.
|
||||
update_site_option('eum_no_core_email_before', apply_filters('eum_no_core_email_before', time() + 86400));
|
||||
return $value;
|
||||
}
|
||||
// Blocked because we've already been here in the last 24 hours
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe change automatic update email
|
||||
*
|
||||
* @since 6.1.0
|
||||
* @access public
|
||||
* @see __construct
|
||||
*
|
||||
* @param array $email array
|
||||
*
|
||||
* @return array email array
|
||||
*/
|
||||
public function maybe_change_automatic_update_email( $email ) {
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
$email_addresses = isset($core_options['email_addresses']) ? $core_options['email_addresses'] : array();
|
||||
$email_addresses_to_override = array();
|
||||
foreach ($email_addresses as $emails) {
|
||||
if (is_email($emails)) {
|
||||
$email_addresses_to_override[] = $emails;
|
||||
}
|
||||
}
|
||||
if (! empty($email_addresses_to_override)) {
|
||||
$email['to'] = $email_addresses_to_override;
|
||||
}
|
||||
return $email;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,651 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Easy Updates Manager Themes List Table class.
|
||||
*
|
||||
* @package Easy Updates Manager
|
||||
* @subpackage MPSUM_List_Table
|
||||
* @since 5.0.0
|
||||
* @access private
|
||||
*/
|
||||
class MPSUM_Themes_List_Table extends MPSUM_List_Table {
|
||||
|
||||
public $site_id;
|
||||
|
||||
public $is_site_themes;
|
||||
|
||||
private $tab = 'themes';
|
||||
|
||||
private $status = 'all';
|
||||
|
||||
private $allowed_statuses = array();
|
||||
|
||||
private $page = '1';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see WP_List_Table::__construct() for more information on default arguments.
|
||||
*
|
||||
* @param array $args An associative array of arguments.
|
||||
*/
|
||||
public function __construct($args = array()) {
|
||||
parent::__construct(array(
|
||||
'singular' => 'theme',
|
||||
'plural' => 'themes',
|
||||
'screen' => isset($args['screen']) ? $args['screen'] : 'eum_themes_tab',
|
||||
'ajax' => true
|
||||
));
|
||||
|
||||
$this->allowed_statuses = apply_filters('eum_themes_list_table_allowed_statuses', array('all', 'update_disabled', 'update_enabled', 'automatic'));
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- Verified in our AJAX handler
|
||||
if (isset($_REQUEST['action']) && 'eum_ajax' === $_REQUEST['action']) {
|
||||
$this->status = isset($_REQUEST['view']) ? sanitize_text_field(wp_unslash($_REQUEST['view'])) : 'all';
|
||||
if (!in_array($this->status, $this->allowed_statuses))
|
||||
$this->status = 'all';
|
||||
|
||||
$this->page = isset($_REQUEST['paged']) ? sanitize_text_field(wp_unslash($_REQUEST['paged'])) : '1';
|
||||
} else {
|
||||
$this->status = isset($args['view']) ? $args['view'] : 'all';
|
||||
if (!in_array($this->status, $this->allowed_statuses))
|
||||
$this->status = 'all';
|
||||
|
||||
$this->page = isset($args['paged']) ? $args['paged'] : 1;
|
||||
}
|
||||
|
||||
$this->is_site_themes = ('site-themes-network' == $this->screen->id) ? true : false;
|
||||
|
||||
if ($this->is_site_themes)
|
||||
$this->site_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
|
||||
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table classes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_table_classes() {
|
||||
// todo: remove and add CSS for .themes
|
||||
return array('widefat', 'plugins');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax user capability check
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function ajax_user_can() {
|
||||
if ($this->is_site_themes) {
|
||||
return current_user_can('manage_sites');
|
||||
} else {
|
||||
return current_user_can('manage_network_themes');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares theme items to display
|
||||
*
|
||||
* Prepares theme items by setting pagination variables, order, filter
|
||||
*/
|
||||
public function prepare_items() {
|
||||
global $totals;
|
||||
$order = 'DESC';
|
||||
$orderby = 'Name';
|
||||
|
||||
$themes = array(
|
||||
/**
|
||||
* Filter the full array of WP_Theme objects to list in the Multisite
|
||||
* themes list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param array $all An array of WP_Theme objects to display in the list table.
|
||||
*/
|
||||
'all' => apply_filters('all_themes', wp_get_themes()),
|
||||
'update_enabled' => array(),
|
||||
'update_disabled' => array(),
|
||||
'automatic' => array()
|
||||
|
||||
);
|
||||
|
||||
$theme_options = MPSUM_Updates_Manager::get_options('themes');
|
||||
$theme_automatic_options = MPSUM_Updates_Manager::get_options('themes_automatic');
|
||||
foreach ((array) $themes['all'] as $theme => $theme_data) {
|
||||
if (false !== $key = array_search($theme, $theme_options)) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Need to double check this one as I cant see Key being used and wonder if it needs to be $theme?
|
||||
$themes['update_disabled'][$theme] = $theme_data;
|
||||
} else {
|
||||
$themes['update_enabled'][$theme] = $theme_data;
|
||||
if (in_array($theme, $theme_automatic_options)) {
|
||||
$themes['automatic'][$theme] = $theme_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$themes = apply_filters('eum_themes_list_table_prepare_items', $themes);
|
||||
|
||||
$totals = array();
|
||||
|
||||
foreach ($themes as $type => $list)
|
||||
$totals[$type] = count($list);
|
||||
|
||||
// Disable the automatic updates view
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['theme_updates']) && 'individual' !== $core_options['theme_updates']) {
|
||||
unset($totals['automatic']);
|
||||
$themes['automatic'] = array();
|
||||
}
|
||||
|
||||
if (empty($themes[$this->status]))
|
||||
$this->status = 'all';
|
||||
|
||||
$this->items = $themes[$this->status];
|
||||
WP_Theme::sort_by_name($this->items);
|
||||
|
||||
$this->has_items = ! empty($themes['all']);
|
||||
$total_this_page = $totals[$this->status];
|
||||
|
||||
if ($orderby) {
|
||||
$orderby = ucfirst($orderby);
|
||||
$order = strtoupper($order);
|
||||
|
||||
if ('Name' == $orderby) {
|
||||
if ('ASC' == $order)
|
||||
$this->items = array_reverse($this->items);
|
||||
} else {
|
||||
uasort($this->items, array($this, '_order_callback'));
|
||||
}
|
||||
}
|
||||
|
||||
// Get themes per page
|
||||
$user_id = get_current_user_id();
|
||||
$themes_per_page = get_user_meta($user_id, 'mpsum_items_per_page', true);
|
||||
if (! is_numeric($themes_per_page)) {
|
||||
$themes_per_page = 100;
|
||||
}
|
||||
|
||||
$start = ($this->page - 1) * $themes_per_page;
|
||||
|
||||
if ($total_this_page > $themes_per_page)
|
||||
$this->items = array_slice($this->items, $start, $themes_per_page, true);
|
||||
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_this_page,
|
||||
'per_page' => $themes_per_page,
|
||||
'total_pages' => ceil($total_this_page / $themes_per_page),
|
||||
'view' => $this->status,
|
||||
'tab' => $this->tab,
|
||||
'paged' => $this->page
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Search Callback
|
||||
*
|
||||
* @staticvar string $term
|
||||
* @param string $theme WP Theme
|
||||
* @return bool
|
||||
*/
|
||||
public function _search_callback($theme) {
|
||||
static $term;
|
||||
if (is_null($term))
|
||||
$term = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified in our AJAX handler
|
||||
|
||||
foreach (array('Name', 'Description', 'Author', 'Author', 'AuthorURI') as $field) {
|
||||
// Don't mark up; Do translate.
|
||||
if (false !== stripos($theme->display($field, false, true), $term))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (false !== stripos($theme->get_stylesheet(), $term))
|
||||
return true;
|
||||
|
||||
if (false !== stripos($theme->get_template(), $term))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order callback
|
||||
* Not used by any core columns.
|
||||
*
|
||||
* @global string $orderby
|
||||
* @global string $order
|
||||
* @param array $theme_a Theme A
|
||||
* @param array $theme_b Theme B
|
||||
* @return int
|
||||
*/
|
||||
public function _order_callback($theme_a, $theme_b) {
|
||||
global $orderby, $order;
|
||||
|
||||
$a = $theme_a[$orderby];
|
||||
$b = $theme_b[$orderby];
|
||||
|
||||
if ($a == $b)
|
||||
return 0;
|
||||
|
||||
if ('DESC' == $order) {
|
||||
return ($a < $b) ? 1 : -1;
|
||||
} else {
|
||||
return ($a < $b) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No Items
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function no_items() {
|
||||
if (! $this->has_items) {
|
||||
esc_html_e('No themes found.', 'stops-core-theme-and-plugin-updates');
|
||||
} else {
|
||||
esc_html_e('You do not appear to have any themes available at this time.', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'cb' => '<input type="checkbox" />',
|
||||
'name' => __('Theme', 'stops-core-theme-and-plugin-updates'),
|
||||
'description' => __('Description', 'stops-core-theme-and-plugin-updates'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sortable columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_sortable_columns() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get views
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_views() {
|
||||
global $totals;
|
||||
|
||||
$status_links = array();
|
||||
foreach ($totals as $type => $count) {
|
||||
if (!$count)
|
||||
continue;
|
||||
|
||||
switch ($type) {
|
||||
case 'all':
|
||||
/* Translators: %s: Total number of theme. */
|
||||
$text = _nx('All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $count, 'themes', 'stops-core-theme-and-plugin-updates');
|
||||
break;
|
||||
case 'update_disabled':
|
||||
/* Translators: %s: Total number of updates disabled theme. */
|
||||
$text = _n('Updates disabled <span class="count">(%s)</span>', 'Updates Disabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates');
|
||||
break;
|
||||
case 'update_enabled':
|
||||
/* Translators: %s: Total number of updates enabled theme. */
|
||||
$text = _n('Updates enabled <span class="count">(%s)</span>', 'Updates enabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates');
|
||||
break;
|
||||
case 'automatic':
|
||||
/* Translators: %s: Total number of automatic updates enabled theme. */
|
||||
$text = _n('Automatic updates <span class="count">(%s)</span>', 'Automatic updates <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates');
|
||||
break;
|
||||
default:
|
||||
$text = apply_filters('eum_themes_list_table_text_view', '', $type, $count);
|
||||
break;
|
||||
}
|
||||
|
||||
if ('search' != $type) {
|
||||
$theme_url = MPSUM_Admin::get_url();
|
||||
$query_args = array(
|
||||
'tab' => $this->tab,
|
||||
'view' => $type
|
||||
);
|
||||
|
||||
$status_links[$type] = sprintf("<a href='%s' data-view='%s' %s>%s</a>",
|
||||
add_query_arg($query_args, $theme_url),
|
||||
$this->status,
|
||||
($type == $this->status) ? ' class="current"' : '',
|
||||
sprintf($text, number_format_i18n($count))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $status_links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bulk actions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_bulk_actions() {
|
||||
$actions = array();
|
||||
|
||||
$actions['allow-update-selected'] = esc_html__('Theme updates on', 'stops-core-theme-and-plugin-updates');
|
||||
$actions['disallow-update-selected'] = esc_html__('Theme updates off', 'stops-core-theme-and-plugin-updates');
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['theme_updates']) && 'individual' == $core_options['theme_updates']) {
|
||||
$actions['allow-automatic-selected'] = esc_html__('Automatic updates on', 'stops-core-theme-and-plugin-updates');
|
||||
$actions['disallow-automatic-selected'] = esc_html__('Automatic updates off', 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
|
||||
return apply_filters('eum_themes_list_table_bulk_actions', $actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display rows
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function display_rows() {
|
||||
foreach ($this->items as $theme)
|
||||
$this->single_row($theme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Single row theme
|
||||
*
|
||||
* @param object $theme The specified WP_Theme object
|
||||
*/
|
||||
public function single_row($theme) {
|
||||
$this->status = 'all';
|
||||
$stylesheet = $theme->get_stylesheet();
|
||||
remove_action("after_theme_row_$stylesheet", 'wp_theme_update_row', 10, 2);
|
||||
|
||||
/**
|
||||
* Filter the action links that show up under each theme row.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param array Array of action links
|
||||
* @param WP_Theme $theme WP_Theme object
|
||||
* @param string $this->status Status of the theme.
|
||||
*/
|
||||
$checkbox_id = "checkbox_" . md5($theme->get('Name'));
|
||||
$checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr($stylesheet) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select', 'stops-core-theme-and-plugin-updates') . " " . $theme->display('Name') . "</label>";
|
||||
|
||||
$id = sanitize_html_class($theme->get_stylesheet());
|
||||
$class = 'active';
|
||||
$theme_options = MPSUM_Updates_Manager::get_options('themes');
|
||||
if (false !== $key = array_search($stylesheet, $theme_options)) {
|
||||
$class = 'inactive';
|
||||
}
|
||||
echo "<tr id='".esc_attr($id)."' class='".esc_attr($class)."'>";
|
||||
|
||||
list($columns, $hidden) = $this->get_column_info();
|
||||
|
||||
foreach ($columns as $column_name => $column_display_name) {
|
||||
|
||||
$is_hidden = in_array($column_name, $hidden);
|
||||
|
||||
switch ($column_name) {
|
||||
case 'cb':
|
||||
echo "<th scope='row' class='check-column'>$checkbox</th>";// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- needs to be presented in html
|
||||
break;
|
||||
case 'name':
|
||||
echo "<td class='theme-title'" . ($is_hidden ? ' style = "display: none;"' : '') . ">";
|
||||
echo "<img src='" . esc_url($theme->get_screenshot()) . "' width='85' height='64' class='updates-table-screenshot' alt='' />";
|
||||
echo '<div class="eum-themes-name-actions">';
|
||||
echo "<h3 class='eum-themes-name'>" . esc_html($theme->display('Name')) . "</h3>";
|
||||
echo '<div class="eum-themes-wrapper">';
|
||||
printf('<h4>%s</h4>', esc_html__('Theme updates', 'stops-core-theme-and-plugin-updates'));
|
||||
|
||||
echo '<div class="toggle-wrapper toggle-wrapper-themes">';
|
||||
|
||||
$enable_class = $disable_class = '';
|
||||
$checked = 'false';
|
||||
$key = in_array($stylesheet, $theme_options);
|
||||
if (! $key) {
|
||||
$enable_class = 'eum-enabled eum-active';
|
||||
$checked = 'true';
|
||||
} else {
|
||||
$disable_class = 'eum-disabled eum-active';
|
||||
}
|
||||
|
||||
printf('<input type="hidden" name="themes[%s]" value="%s">',
|
||||
esc_attr($stylesheet),
|
||||
esc_attr($checked)
|
||||
);
|
||||
|
||||
printf('<button aria-label="%s" class="eum-toggle-button eum-enabled %s" data-checked="%s">%s</button>',
|
||||
esc_attr__('Allow updates', 'stops-core-theme-and-plugin-updates'),
|
||||
esc_attr($enable_class),
|
||||
esc_attr($stylesheet),
|
||||
esc_html__('Allowed', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
|
||||
printf('<button aria-label="%s" class="eum-toggle-button eum-disabled %s" data-checked="%s">%s</button>',
|
||||
esc_attr__('Disallow updates', 'stops-core-theme-and-plugin-updates'),
|
||||
esc_attr($disable_class),
|
||||
esc_attr($stylesheet),
|
||||
esc_html__('Blocked', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
|
||||
echo '</div></div>';
|
||||
|
||||
// Automatic Link
|
||||
$theme_automatic_options = MPSUM_Updates_Manager::get_options('themes_automatic');
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
if (isset($core_options['theme_updates']) && 'individual' == $core_options['theme_updates']) {
|
||||
printf('<div class="eum-themes-automatic-wrapper" %s>', ($key) ? 'style="display: none;"' : '');
|
||||
printf('<h4>%s</h4>', esc_html__('Automatic updates', 'stops-core-theme-and-plugin-updates'));
|
||||
echo '<div class="toggle-wrapper toggle-wrapper-themes-automatic">';
|
||||
$enable_class = $disable_class = '';
|
||||
if (in_array($stylesheet, $theme_automatic_options)) {
|
||||
$enable_class = 'eum-active';
|
||||
$checked = 'true';
|
||||
} else {
|
||||
$disable_class = 'eum-active';
|
||||
$checked = 'false';
|
||||
}
|
||||
|
||||
printf('<input type="hidden" name="themes_automatic[%s]" value="%s">',
|
||||
esc_attr($stylesheet),
|
||||
esc_attr($checked)
|
||||
);
|
||||
|
||||
printf('<button aria-label="%s" class="eum-toggle-button eum-enabled %s" data-checked="%s">%s</button>',
|
||||
esc_html__('Enable automatic updates', 'stops-core-theme-and-plugin-updates'),
|
||||
esc_attr($enable_class),
|
||||
esc_attr($stylesheet),
|
||||
esc_html__('On', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
|
||||
printf('<button aria-label="%s" class="eum-toggle-button eum-disabled %s" data-checked="%s">%s</button>',
|
||||
esc_attr__('Enable automatic updates', 'stops-core-theme-and-plugin-updates'),
|
||||
esc_attr($disable_class),
|
||||
esc_attr($stylesheet),
|
||||
esc_html__('Off', 'stops-core-theme-and-plugin-updates')
|
||||
);
|
||||
|
||||
echo '</div></div>';
|
||||
}
|
||||
do_action('eum_populate_themes_list_table_column', $column_name, $theme);
|
||||
echo '</div>';
|
||||
echo "</td>";
|
||||
break;
|
||||
case 'description':
|
||||
echo "<td class='column-description desc'" . ($is_hidden ? ' style = "display: none;"' : '') . ">";
|
||||
if ($theme->errors()) {
|
||||
$pre = 'broken' == $this->status ? __('Broken theme:', 'stops-core-theme-and-plugin-updates') . ' ' : '';
|
||||
echo '<p><strong class="attention">' . esc_html($pre . $theme->errors()->get_error_message()) . '</strong></p>';
|
||||
}
|
||||
echo "<div class='theme-description'><p>" . esc_html($theme->display('Description')) . "</p></div>
|
||||
<div class='second theme-version-author-uri'>";
|
||||
|
||||
$theme_meta = array();
|
||||
|
||||
if ($theme->get('Version')) {
|
||||
/* translators: %s: Theme version. */
|
||||
$theme_meta[] = sprintf(__('Version %s', 'stops-core-theme-and-plugin-updates'), $theme->display('Version'));
|
||||
}
|
||||
|
||||
/* translators: %s: Theme author. */
|
||||
$theme_meta[] = sprintf(__('By %s', 'stops-core-theme-and-plugin-updates'), $theme->display('Author'));
|
||||
|
||||
if ($theme->get('ThemeURI'))
|
||||
$theme_meta[] = '<a href="' . $theme->display('ThemeURI') . '" title="' . esc_attr__('Visit theme homepage', 'stops-core-theme-and-plugin-updates') . '">' . __('Visit theme site', 'stops-core-theme-and-plugin-updates') . '</a>';
|
||||
|
||||
/**
|
||||
* Filter the array of row meta for each theme in the Multisite themes
|
||||
* list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param array $theme_meta An array of the theme's metadata,
|
||||
* including the version, author, and
|
||||
* theme URI.
|
||||
* @param string $stylesheet Directory name of the theme.
|
||||
* @param WP_Theme $theme WP_Theme object.
|
||||
* @param string $this->status Status of the theme.
|
||||
*/
|
||||
$theme_meta = apply_filters('theme_row_meta', $theme_meta, $stylesheet, $theme, $this->status);
|
||||
echo implode(' | ', $theme_meta);// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- needs to be presented in html
|
||||
|
||||
// Show active status for blogs
|
||||
if (is_multisite()) {
|
||||
$themes = wp_get_themes(array('allowed' => true));
|
||||
$is_allowed_theme = array();
|
||||
foreach ($themes as $style => $theme_data) {
|
||||
if ($style === $stylesheet) {
|
||||
$is_allowed_theme[] = $stylesheet;
|
||||
}
|
||||
}
|
||||
$is_allowed_stylesheet = false;
|
||||
foreach ($is_allowed_theme as $allowed_stylesheet) {
|
||||
if ($allowed_stylesheet === $stylesheet) {
|
||||
$is_allowed_stylesheet = true;
|
||||
}
|
||||
}
|
||||
if ($is_allowed_stylesheet) {
|
||||
printf('<div class="mpsum-success mpsum-regular"><a href="#" data-theme-file="%s" class="eum-list-themes-action">%s</a><div class="eum-list-themes"></div></div>', esc_attr($stylesheet), esc_html__('View all sites that have this theme installed.', 'stops-core-theme-and-plugin-updates'));
|
||||
} else {
|
||||
printf('<div class="mpsum-notice mpsum-regular">%s<br /><a href="#" data-theme-file="%s" class="eum-list-themes-action">%s</a><div class="eum-list-themes"></div></div>', esc_html__('This theme is not allowed to be activated on your network of sites, but may be enabled for specific sites.', 'stops-core-theme-and-plugin-updates'), esc_attr($stylesheet), esc_html__('View all sites that have this theme installed.', 'stops-core-theme-and-plugin-updates'));
|
||||
}
|
||||
} else {
|
||||
if (get_stylesheet() === $stylesheet) {
|
||||
printf('<div class="mpsum-success mpsum-regular">%s</div>', esc_html__('This theme is active for your site.', 'stops-core-theme-and-plugin-updates'));
|
||||
} else {
|
||||
printf('<div class="mpsum-error mpsum-bold">%s</div>', esc_html__('This theme is inactive for your site.', 'stops-core-theme-and-plugin-updates'));
|
||||
}
|
||||
}
|
||||
|
||||
echo "</div></td>";
|
||||
break;
|
||||
|
||||
default:
|
||||
echo "<td class='" . esc_attr($column_name) . " column-" . esc_attr($column_name) . "'" . ($is_hidden ? ' style = "display: none;"' : '') . ">";
|
||||
|
||||
/**
|
||||
* Fires inside each custom column of the Multisite themes list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $column_name Name of the column.
|
||||
* @param string $stylesheet Directory name of the theme.
|
||||
* @param WP_Theme $theme Current WP_Theme object.
|
||||
*/
|
||||
do_action('manage_themes_custom_column', $column_name, $stylesheet, $theme);
|
||||
echo "</td>";
|
||||
}
|
||||
}
|
||||
|
||||
echo "</tr>";
|
||||
|
||||
if ($this->is_site_themes)
|
||||
remove_action("after_theme_row_$stylesheet", 'wp_theme_update_row');
|
||||
|
||||
/**
|
||||
* Fires after each row in the Multisite themes list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $stylesheet Directory name of the theme.
|
||||
* @param WP_Theme $theme Current WP_Theme object.
|
||||
* @param string $this->status Status of the theme.
|
||||
*/
|
||||
do_action('after_theme_row', $stylesheet, $theme, $this->status);
|
||||
|
||||
/**
|
||||
* Fires after each specific row in the Multisite themes list table.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$stylesheet`, refers to the
|
||||
* directory name of the theme, most often synonymous with the template
|
||||
* name of the theme.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param string $stylesheet Directory name of the theme.
|
||||
* @param WP_Theme $theme Current WP_Theme object.
|
||||
* @param string $this->status Status of the theme.
|
||||
*/
|
||||
do_action("after_theme_row_$stylesheet", $stylesheet, $theme, $this->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures response of ajax calls and returns it
|
||||
*/
|
||||
public function ajax_response() {
|
||||
$this->prepare_items();
|
||||
extract($this->_args);
|
||||
extract($this->_pagination_args, EXTR_SKIP);
|
||||
ob_start();
|
||||
$this->views();
|
||||
$views = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
if (!empty($_REQUEST['no_placeholder'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified in our AJAX handler
|
||||
$this->display_rows();
|
||||
} else {
|
||||
$this->display_rows_or_placeholder();
|
||||
}
|
||||
$rows = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
$this->print_column_headers();
|
||||
$headers = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
$this->pagination('top');
|
||||
$pagination_top = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
$this->pagination('bottom');
|
||||
$pagination_bottom = ob_get_clean();
|
||||
$response = array();
|
||||
$response['views'] = array($views);
|
||||
$response['rows'] = array($rows);
|
||||
$response['pagination']['top'] = $pagination_top;
|
||||
$response['pagination']['bottom'] = $pagination_bottom;
|
||||
$response['headers'] = $headers;
|
||||
|
||||
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- $total_items and $total_pages are being exc tracted on line 585
|
||||
|
||||
if (isset($total_items)) {
|
||||
/* Translators: %s: Total number of themes. */
|
||||
$response['total_items_i18n'] = sprintf(_n('%s theme', '%s themes', $total_items, 'stops-core-theme-and-plugin-updates'), number_format_i18n($total_items));
|
||||
}
|
||||
|
||||
if (isset($total_pages)) {
|
||||
$response['total_pages'] = $total_pages;
|
||||
$response['total_pages_i18n'] = number_format_i18n($total_pages);
|
||||
}
|
||||
|
||||
// phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
|
||||
|
||||
wp_send_json($response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
/**
|
||||
* This file is the bootstrapper for UpdraftCentral integration: i.e. it registers what is necessary to deal with commands in the eum namespace.
|
||||
*/
|
||||
class MPSUM_UpdraftCentral {
|
||||
|
||||
/**
|
||||
* MPSUM_UpdraftCentral constructor. Registers required action hooks
|
||||
*/
|
||||
public function __construct() {
|
||||
add_filter('updraftplus_remotecontrol_command_classes', array($this, 'updraftcentral_remotecontrol_command_classes'));
|
||||
add_filter('updraftcentral_remotecontrol_command_classes', array($this, 'updraftcentral_remotecontrol_command_classes'));
|
||||
add_action('updraftcentral_command_class_wanted', array($this, 'updraftcentral_command_class_wanted'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register our class
|
||||
*
|
||||
* @param string $command_classes Passing over an array of command classes.
|
||||
* @return array An array of command classes
|
||||
*/
|
||||
public function updraftcentral_remotecontrol_command_classes($command_classes) {
|
||||
if (is_array($command_classes)) $command_classes['eum'] = 'UpdraftCentral_EUM_Commands';
|
||||
return $command_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the class when required
|
||||
*
|
||||
* @param string $command_php_class Passing over if there are any command classes.
|
||||
*/
|
||||
public function updraftcentral_command_class_wanted($command_php_class) {
|
||||
if ('UpdraftCentral_EUM_Commands' == $command_php_class) {
|
||||
// This fragment is only needed for compatibility with UD < 1.12.30 - thenceforth, the class can be assumed to exist.
|
||||
if (!class_exists('UpdraftCentral_Commands')) {
|
||||
include_once(apply_filters('updraftcentral_command_base_class_at', UPDRAFTPLUS_DIR.'/central/commands.php'));
|
||||
}
|
||||
include_once(MPSUM_Updates_Manager::get_plugin_dir('includes/MPSUM_UpdraftCentral_EUM_Commands.php'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
/**
|
||||
* This is a small glue class, which makes available all the commands in WP_Optimize_Commands, and translates the response from WP_Optimize_Commands (which is either data to return, or a WP_Error) into the format used by UpdraftCentral.
|
||||
*/
|
||||
class UpdraftCentral_EUM_Commands extends UpdraftCentral_Commands {
|
||||
|
||||
private $commands;
|
||||
|
||||
/**
|
||||
* UpdraftCentral_EUM_Commands class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->commands = new MPSUM_Commands();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping function for remote calls
|
||||
*
|
||||
* @param string $name Command name
|
||||
* @param array $arguments Arguments for the method call
|
||||
*
|
||||
* @return array Response to the remote call
|
||||
*/
|
||||
public function __call($name, $arguments) {
|
||||
if (!current_user_can('manage_options')) {
|
||||
$result = __('User has insufficient capability to manage options', 'stops-core-theme-and-plugin-updates');
|
||||
} elseif ('_post_action' == $name || '_pre_action' == $name) {
|
||||
return array('result' => 'empty_action');
|
||||
} else {
|
||||
$result = call_user_func_array(array($this->commands, $name), $arguments);
|
||||
}
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $this->_generic_error_response($result->get_error_code(), $result->get_error_data());
|
||||
} else {
|
||||
return $this->_response($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
/**
|
||||
* Easy Updates Manager utility class.
|
||||
*/
|
||||
class MPSUM_Utils {
|
||||
|
||||
/**
|
||||
* MPSUM_Utils constructor
|
||||
*/
|
||||
private function __construct() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns instance of singleton pattern
|
||||
*
|
||||
* @return MPSUM_Utils
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the URL is a WordPress API call
|
||||
*
|
||||
* @param string $url The URL to be checked
|
||||
*
|
||||
* @return true if WP API, false if not
|
||||
*/
|
||||
public static function is_wp_api($url) {
|
||||
$parsed_url = wp_parse_url($url);
|
||||
if (isset($parsed_url['host']) && 'api.wordpress.org' === strtolower($parsed_url['host'])) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates email addresses and returns an error if not valid
|
||||
*
|
||||
* @since 9.0.0
|
||||
*
|
||||
* @param string $email_addresses (can be comma separated)
|
||||
*
|
||||
* @return array Return an 'errors' key (boolean) and an 'original_emails' key (string) with original passed email addresses. 'emails' key (array) contains validated email addresses.
|
||||
*/
|
||||
public static function validate_emails($email_addresses) {
|
||||
$emails = explode(',', $email_addresses);
|
||||
$email_errors = false;
|
||||
foreach ($emails as &$email) {
|
||||
$email = trim($email);
|
||||
if (!is_email($email)) {
|
||||
|
||||
// Email error. Get out.
|
||||
$email_errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return array(
|
||||
'errors' => $email_errors,
|
||||
'original_emails' => $email_addresses,
|
||||
'emails' => $emails,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks whether a specific plugin is installed, and returns information about it
|
||||
*
|
||||
* @since 8.0.1
|
||||
*
|
||||
* @param string $slug Specify plugin slug
|
||||
*
|
||||
* @return array Returns an array of details such as if installed, the name of the plugin and if it is active.
|
||||
*/
|
||||
public function is_installed($slug) {
|
||||
|
||||
// Needed to have the 'get_plugins()' function
|
||||
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
||||
|
||||
// Gets all plugins available
|
||||
$get_plugins = get_plugins();
|
||||
|
||||
$active_plugins = $this->get_active_plugins();
|
||||
$plugin_info = array();
|
||||
$plugin_info['installed'] = false;
|
||||
$plugin_info['active'] = false;
|
||||
|
||||
// Loops around each plugin available.
|
||||
foreach ($get_plugins as $key => $value) {
|
||||
// If the plugin name matches that of the specified name, it will gather details.
|
||||
if ($value['TextDomain'] != $slug) {
|
||||
continue;
|
||||
}
|
||||
$plugin_info['installed'] = true;
|
||||
$plugin_info['name'] = $key;
|
||||
$plugin_info['version'] = $value['Version'];
|
||||
if (in_array($key, $active_plugins)) {
|
||||
$plugin_info['active'] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $plugin_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of plugins active on either the current site, or site-wide
|
||||
*
|
||||
* @since 8.0.1
|
||||
*
|
||||
* @return array - a list of plugin paths (relative to the plugin directory)
|
||||
*/
|
||||
public function get_active_plugins() {
|
||||
|
||||
// Gets all active plugins on the current site
|
||||
$active_plugins = get_option('active_plugins');
|
||||
|
||||
if (is_multisite()) {
|
||||
$network_active_plugins = get_site_option('active_sitewide_plugins');
|
||||
if (!empty($network_active_plugins)) {
|
||||
$network_active_plugins = array_keys($network_active_plugins);
|
||||
$active_plugins = array_merge($active_plugins, $network_active_plugins);
|
||||
}
|
||||
}
|
||||
|
||||
return $active_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of plugins active on either the current site or passed blog id
|
||||
*
|
||||
* @since 8.0.1
|
||||
*
|
||||
* @param $int $blog_id Blog ID of site if on multisite
|
||||
*
|
||||
* @return array - a list of plugin paths (relative to the plugin directory)
|
||||
*/
|
||||
public function get_single_site_active_plugins($blog_id = 1) {
|
||||
if (is_multisite()) switch_to_blog($blog_id);
|
||||
// Gets all active plugins on the current site
|
||||
$active_plugins = get_option('active_plugins', array());
|
||||
if (is_multisite()) restore_current_blog();
|
||||
return $active_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of plugins active for the network
|
||||
*
|
||||
* @since 8.0.1
|
||||
*
|
||||
* @return array - a list of plugin paths (relative to the plugin directory)
|
||||
*/
|
||||
public function get_network_active_plugins() {
|
||||
$network_active_plugins = get_site_option('active_sitewide_plugins', array());
|
||||
$network_active_plugins = array_keys($network_active_plugins);
|
||||
return $network_active_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if auomatic updates are on or off
|
||||
*
|
||||
* @since 8.0.1
|
||||
*
|
||||
* @return bool - true if automatic updates are on, false if not
|
||||
*/
|
||||
public function is_automatic_updates_enabled() {
|
||||
$options = MPSUM_Updates_Manager::get_options('core');
|
||||
|
||||
// Check automatic update options
|
||||
if (isset($options['automatic_development_updates'], $options['automatic_major_updates'], $options['automatic_minor_updates'], $options['automatic_plugin_updates'], $options['automatic_theme_updates'], $options['automatic_translation_updates'])) {
|
||||
// Check to see if off is on for all updates
|
||||
if ('off' == $options['automatic_development_updates'] && 'off' == $options['automatic_major_updates'] && 'off' == $options['automatic_minor_updates'] && 'off' == $options['automatic_plugin_updates'] && 'off' == $options['automatic_theme_updates'] && 'off' == $options['automatic_translation_updates']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check core update options
|
||||
if (isset($options['core_updates'], $options['plugin_updates'], $options['theme_updates'], $options['translation_updates'])) {
|
||||
if ('off' == $options['core_updates'] && 'off' == $options['plugin_updates'] && 'off' == $options['theme_updates'] && 'off' == $options['translation_updates']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see what emails to send to
|
||||
*
|
||||
* @since 8.0.1
|
||||
*
|
||||
* @return mixed - Can be a string with an email address or an array of email addresses
|
||||
*/
|
||||
public function get_emails() {
|
||||
// Prepare E-mail Addresses to send to
|
||||
$core_options = MPSUM_Updates_Manager::get_options('core');
|
||||
$email_addresses = isset($core_options['email_addresses']) ? $core_options['email_addresses'] : array();
|
||||
$email_addresses_to_override = array();
|
||||
$emails_to_send = '';
|
||||
foreach ($email_addresses as $emails) {
|
||||
if (is_email($emails)) {
|
||||
$email_addresses_to_override[] = $emails;
|
||||
}
|
||||
}
|
||||
if (!empty($email_addresses_to_override)) {
|
||||
$emails_to_send = $email_addresses_to_override;
|
||||
} else {
|
||||
if (is_multisite()) {
|
||||
$emails_to_send = get_site_option('admin_email');
|
||||
} else {
|
||||
$emails_to_send = get_option('admin_email');
|
||||
}
|
||||
}
|
||||
return $emails_to_send;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for free and premium version of EUM and disables free version if both are available
|
||||
*
|
||||
* @since 8.0.1
|
||||
*/
|
||||
public function maybe_deactivate_free_version() {
|
||||
if (!function_exists('get_plugins')) include_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
||||
$get_plugins = get_plugins();
|
||||
$free_available = $free_plugin_active = $premium_available = $premium_plugin_active = $free_slug = $premium_slug = false;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Both $free_available and $premium_available are used and being set but Ci has flagged this as unused. Its fine to ignore.
|
||||
foreach ($get_plugins as $key => $value) {
|
||||
if ('Easy Updates Manager' === $value['Name']) {
|
||||
$free_available = true;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- $free_available Filter use
|
||||
$free_slug = $key;
|
||||
if (is_multisite()) {
|
||||
if (is_plugin_active_for_network($free_slug)) {
|
||||
$free_plugin_active = true;
|
||||
}
|
||||
} else {
|
||||
if (is_plugin_active($free_slug)) {
|
||||
$free_plugin_active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ('Easy Updates Manager Premium' === $value['Name']) {
|
||||
$premium_available = true;
|
||||
$premium_slug = $key;
|
||||
if (is_multisite()) {
|
||||
if (is_plugin_active_for_network($premium_slug)) {
|
||||
$premium_plugin_active = true;
|
||||
}
|
||||
} else {
|
||||
if (is_plugin_active($premium_slug)) {
|
||||
$premium_plugin_active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($premium_plugin_active && $free_plugin_active) {
|
||||
deactivate_plugins($free_slug);
|
||||
add_action('admin_notices', array(MPSUM_Updates_Manager::get_instance(), 'show_admin_notice_premium'));
|
||||
add_action('network_admin_notices', array(MPSUM_Updates_Manager::get_instance(), 'show_admin_notice_premium'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if ai plugin is alive in the file system.
|
||||
*
|
||||
* @since 9.0.0
|
||||
*
|
||||
* @param string $plugin_file Plugin relative to the plugin's directory.
|
||||
*
|
||||
* @return true if plugin exists, false if not
|
||||
*/
|
||||
public function plugin_exists( $plugin_file ) {
|
||||
$plugin_dir = WP_PLUGIN_DIR;
|
||||
if (file_exists($plugin_dir . '/' . $plugin_file)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given item is a fake plugin/theme that is used by WP Site Health for diagnosing auto-updating problems
|
||||
*
|
||||
* @param object $item Object holding the asset to be updated
|
||||
* @return boolean True if the given parameter is an object that contains fake WP's Site Health plugin or theme
|
||||
*/
|
||||
public static function is_wp_site_health_plugin_theme($item) {
|
||||
if (isset($item->theme) && 'a-fake-theme' === $item->theme) return true;
|
||||
if (isset($item->plugin) && 'a-fake-plugin/a-fake-plugin.php' === $item->plugin) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow and force file modifications for automatic updating
|
||||
*
|
||||
* @param boolean $file_mod_allowed Whether file modifications are allowed
|
||||
* @param string $context The usage context
|
||||
* @return boolean True if the context is automatic updater, false if file modification isn't allowed
|
||||
*/
|
||||
public static function allow_file_modifications_for_automatic_updating($file_mod_allowed, $context) {
|
||||
if ('automatic_updater' === $context) return true;
|
||||
return $file_mod_allowed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,623 @@
|
||||
/*!
|
||||
* jQuery blockUI plugin
|
||||
* Version 2.71.0-2020.12.08
|
||||
* Requires jQuery v1.12 or later
|
||||
*
|
||||
* Examples at: http://malsup.com/jquery/block/
|
||||
* Copyright (c) 2007-2013 M. Alsup
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* Thanks to Amir-Hossein Sobhi for some excellent contributions!
|
||||
*/
|
||||
|
||||
;(function() {
|
||||
/*jshint eqeqeq:false curly:false latedef:false */
|
||||
"use strict";
|
||||
|
||||
function setup($) {
|
||||
var migrateDeduplicateWarnings = jQuery.migrateDeduplicateWarnings || false;
|
||||
jQuery.migrateDeduplicateWarnings = false;
|
||||
|
||||
$.fn._fadeIn = $.fn.fadeIn;
|
||||
|
||||
var noOp = $.noop || function() {};
|
||||
|
||||
// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
|
||||
// confusing userAgent strings on Vista)
|
||||
var msie = /MSIE/.test(navigator.userAgent);
|
||||
var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
|
||||
var mode = document.documentMode || 0;
|
||||
var setExpr = "function" === typeof document.createElement('div').style.setExpression;
|
||||
|
||||
// global $ methods for blocking/unblocking the entire page
|
||||
$.blockUI = function(opts) { install(window, opts); };
|
||||
$.unblockUI = function(opts) { remove(window, opts); };
|
||||
|
||||
// convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
|
||||
$.growlUI = function(title, message, timeout, onClose) {
|
||||
var $m = $('<div class="growlUI"></div>');
|
||||
if (title) $m.append('<h1>'+title+'</h1>');
|
||||
if (message) $m.append('<h2>'+message+'</h2>');
|
||||
if (timeout === undefined) timeout = 3000;
|
||||
|
||||
// Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
|
||||
var callBlock = function(opts) {
|
||||
opts = opts || {};
|
||||
|
||||
$.blockUI({
|
||||
message: $m,
|
||||
fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
|
||||
fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
|
||||
timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
|
||||
centerY: false,
|
||||
showOverlay: false,
|
||||
onUnblock: onClose,
|
||||
css: $.blockUI.defaults.growlCSS
|
||||
});
|
||||
};
|
||||
|
||||
callBlock();
|
||||
var nonmousedOpacity = $m.css('opacity');
|
||||
$m.on('mouseover', function() {
|
||||
callBlock({
|
||||
fadeIn: 0,
|
||||
timeout: 30000
|
||||
});
|
||||
|
||||
var displayBlock = $('.blockMsg');
|
||||
displayBlock.stop(); // cancel fadeout if it has started
|
||||
displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
|
||||
}).on('mouseout', function() {
|
||||
$('.blockMsg').fadeOut(1000);
|
||||
});
|
||||
// End konapun additions
|
||||
};
|
||||
|
||||
// plugin method for blocking element content
|
||||
$.fn.block = function(opts) {
|
||||
if ( this[0] === window ) {
|
||||
$.blockUI( opts );
|
||||
return this;
|
||||
}
|
||||
var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
|
||||
this.each(function() {
|
||||
var $el = $(this);
|
||||
if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
|
||||
return;
|
||||
$el.unblock({ fadeOut: 0 });
|
||||
});
|
||||
|
||||
return this.each(function() {
|
||||
if ($.css(this,'position') == 'static') {
|
||||
this.style.position = 'relative';
|
||||
$(this).data('blockUI.static', true);
|
||||
}
|
||||
this.style.zoom = 1; // force 'hasLayout' in ie
|
||||
install(this, opts);
|
||||
});
|
||||
};
|
||||
|
||||
// plugin method for unblocking element content
|
||||
$.fn.unblock = function(opts) {
|
||||
if ( this[0] === window ) {
|
||||
$.unblockUI( opts );
|
||||
return this;
|
||||
}
|
||||
return this.each(function() {
|
||||
remove(this, opts);
|
||||
});
|
||||
};
|
||||
|
||||
$.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
|
||||
|
||||
// override these in your code to change the default behavior and style
|
||||
$.blockUI.defaults = {
|
||||
// message displayed when blocking (use null for no message)
|
||||
message: '<h1>Please wait...</h1>',
|
||||
|
||||
title: null, // title string; only used when theme == true
|
||||
draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
|
||||
|
||||
theme: false, // set to true to use with jQuery UI themes
|
||||
|
||||
// styles for the message when blocking; if you wish to disable
|
||||
// these and use an external stylesheet then do this in your code:
|
||||
// $.blockUI.defaults.css = {};
|
||||
css: {
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
width: '30%',
|
||||
top: '40%',
|
||||
left: '35%',
|
||||
textAlign: 'center',
|
||||
color: '#000',
|
||||
border: '3px solid #aaa',
|
||||
backgroundColor:'#fff',
|
||||
cursor: 'wait'
|
||||
},
|
||||
|
||||
// minimal style set used when themes are used
|
||||
themedCSS: {
|
||||
width: '30%',
|
||||
top: '40%',
|
||||
left: '35%'
|
||||
},
|
||||
|
||||
// styles for the overlay
|
||||
overlayCSS: {
|
||||
backgroundColor: '#000',
|
||||
opacity: 0.6,
|
||||
cursor: 'wait'
|
||||
},
|
||||
|
||||
// style to replace wait cursor before unblocking to correct issue
|
||||
// of lingering wait cursor
|
||||
cursorReset: 'default',
|
||||
|
||||
// styles applied when using $.growlUI
|
||||
growlCSS: {
|
||||
width: '350px',
|
||||
top: '10px',
|
||||
left: '',
|
||||
right: '10px',
|
||||
border: 'none',
|
||||
padding: '5px',
|
||||
opacity: 0.6,
|
||||
cursor: 'default',
|
||||
color: '#fff',
|
||||
backgroundColor: '#000',
|
||||
'-webkit-border-radius':'10px',
|
||||
'-moz-border-radius': '10px',
|
||||
'border-radius': '10px'
|
||||
},
|
||||
|
||||
// IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
|
||||
// (hat tip to Jorge H. N. de Vasconcelos)
|
||||
/*jshint scripturl:true */
|
||||
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
|
||||
|
||||
// force usage of iframe in non-IE browsers (handy for blocking applets)
|
||||
forceIframe: false,
|
||||
|
||||
// z-index for the blocking overlay
|
||||
baseZ: 1000,
|
||||
|
||||
// set these to true to have the message automatically centered
|
||||
centerX: true, // <-- only effects element blocking (page block controlled via css above)
|
||||
centerY: true,
|
||||
|
||||
// allow body element to be stetched in ie6; this makes blocking look better
|
||||
// on "short" pages. disable if you wish to prevent changes to the body height
|
||||
allowBodyStretch: true,
|
||||
|
||||
// enable if you want key and mouse events to be disabled for content that is blocked
|
||||
bindEvents: true,
|
||||
|
||||
// be default blockUI will suppress tab navigation from leaving blocking content
|
||||
// (if bindEvents is true)
|
||||
constrainTabKey: true,
|
||||
|
||||
// fadeIn time in millis; set to 0 to disable fadeIn on block
|
||||
fadeIn: 200,
|
||||
|
||||
// fadeOut time in millis; set to 0 to disable fadeOut on unblock
|
||||
fadeOut: 400,
|
||||
|
||||
// time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
|
||||
timeout: 0,
|
||||
|
||||
// disable if you don't want to show the overlay
|
||||
showOverlay: true,
|
||||
|
||||
// if true, focus will be placed in the first available input field when
|
||||
// page blocking
|
||||
focusInput: true,
|
||||
|
||||
// elements that can receive focus
|
||||
focusableElements: ':input:enabled:visible',
|
||||
|
||||
// suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
|
||||
// no longer needed in 2012
|
||||
// applyPlatformOpacityRules: true,
|
||||
|
||||
// callback method invoked when fadeIn has completed and blocking message is visible
|
||||
onBlock: null,
|
||||
|
||||
// callback method invoked when unblocking has completed; the callback is
|
||||
// passed the element that has been unblocked (which is the window object for page
|
||||
// blocks) and the options that were passed to the unblock call:
|
||||
// onUnblock(element, options)
|
||||
onUnblock: null,
|
||||
|
||||
// callback method invoked when the overlay area is clicked.
|
||||
// setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
|
||||
onOverlayClick: null,
|
||||
|
||||
// don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
|
||||
quirksmodeOffsetHack: 4,
|
||||
|
||||
// class name of the message block
|
||||
blockMsgClass: 'blockMsg',
|
||||
|
||||
// if it is already blocked, then ignore it (don't unblock and reblock)
|
||||
ignoreIfBlocked: false
|
||||
};
|
||||
|
||||
// private data and functions follow...
|
||||
|
||||
var pageBlock = null;
|
||||
var pageBlockEls = [];
|
||||
|
||||
function install(el, opts) {
|
||||
var css, themedCSS;
|
||||
var full = (el == window);
|
||||
var msg = (opts && opts.message !== undefined ? opts.message : undefined);
|
||||
opts = $.extend({}, $.blockUI.defaults, opts || {});
|
||||
|
||||
if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
|
||||
return;
|
||||
|
||||
opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
|
||||
css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
|
||||
if (opts.onOverlayClick)
|
||||
opts.overlayCSS.cursor = 'pointer';
|
||||
|
||||
themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
|
||||
msg = msg === undefined ? opts.message : msg;
|
||||
|
||||
// remove the current block (if there is one)
|
||||
if (full && pageBlock)
|
||||
remove(window, {fadeOut:0});
|
||||
|
||||
// if an existing element is being used as the blocking content then we capture
|
||||
// its current place in the DOM (and current display style) so we can restore
|
||||
// it when we unblock
|
||||
if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
|
||||
var node = msg.jquery ? msg[0] : msg;
|
||||
var data = {};
|
||||
$(el).data('blockUI.history', data);
|
||||
data.el = node;
|
||||
data.parent = node.parentNode;
|
||||
data.display = node.style.display;
|
||||
data.position = node.style.position;
|
||||
if (data.parent)
|
||||
data.parent.removeChild(node);
|
||||
}
|
||||
|
||||
$(el).data('blockUI.onUnblock', opts.onUnblock);
|
||||
var z = opts.baseZ;
|
||||
|
||||
// blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
|
||||
// layer1 is the iframe layer which is used to suppress bleed through of underlying content
|
||||
// layer2 is the overlay layer which has opacity and a wait cursor (by default)
|
||||
// layer3 is the message content that is displayed while blocking
|
||||
var lyr1, lyr2, lyr3, s;
|
||||
if (msie || opts.forceIframe)
|
||||
lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>');
|
||||
else
|
||||
lyr1 = $('<div class="blockUI" style="display:none"></div>');
|
||||
|
||||
if (opts.theme)
|
||||
lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
|
||||
else
|
||||
lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
|
||||
|
||||
if (opts.theme && full) {
|
||||
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
|
||||
if ( opts.title ) {
|
||||
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>';
|
||||
}
|
||||
s += '<div class="ui-widget-content ui-dialog-content"></div>';
|
||||
s += '</div>';
|
||||
}
|
||||
else if (opts.theme) {
|
||||
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
|
||||
if ( opts.title ) {
|
||||
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>';
|
||||
}
|
||||
s += '<div class="ui-widget-content ui-dialog-content"></div>';
|
||||
s += '</div>';
|
||||
}
|
||||
else if (full) {
|
||||
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
|
||||
}
|
||||
else {
|
||||
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
|
||||
}
|
||||
lyr3 = $(s);
|
||||
|
||||
// if we have a message, style it
|
||||
if (msg) {
|
||||
if (opts.theme) {
|
||||
lyr3.css(themedCSS);
|
||||
lyr3.addClass('ui-widget-content');
|
||||
}
|
||||
else
|
||||
lyr3.css(css);
|
||||
}
|
||||
|
||||
// style the overlay
|
||||
if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
|
||||
lyr2.css(opts.overlayCSS);
|
||||
lyr2.css('position', full ? 'fixed' : 'absolute');
|
||||
|
||||
// make iframe layer transparent in IE
|
||||
if (msie || opts.forceIframe)
|
||||
lyr1.css('opacity',0.0);
|
||||
|
||||
//$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
|
||||
var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
|
||||
$.each(layers, function() {
|
||||
this.appendTo($par);
|
||||
});
|
||||
|
||||
if (opts.theme && opts.draggable && $.fn.draggable) {
|
||||
lyr3.draggable({
|
||||
handle: '.ui-dialog-titlebar',
|
||||
cancel: 'li'
|
||||
});
|
||||
}
|
||||
|
||||
// ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
|
||||
var expr = setExpr && ( "CSS1Compat" !== document.compatMode || $('object,embed', full ? null : el).length > 0);
|
||||
if (ie6 || expr) {
|
||||
// give body 100% height
|
||||
if (full && opts.allowBodyStretch && "CSS1Compat" === document.compatMode)
|
||||
$('html,body').css('height','100%');
|
||||
|
||||
// fix ie6 issue when blocked element has a border width
|
||||
if ((ie6 || "CSS1Compat" !== document.compatMode) && !full) {
|
||||
var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
|
||||
var fixT = t ? '(0 - '+t+')' : 0;
|
||||
var fixL = l ? '(0 - '+l+')' : 0;
|
||||
}
|
||||
|
||||
// simulate fixed position
|
||||
$.each(layers, function(i,o) {
|
||||
var s = o[0].style;
|
||||
s.position = 'absolute';
|
||||
if (i < 2) {
|
||||
if (full)
|
||||
s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - ("CSS1Compat" === document.compatMode?0:'+opts.quirksmodeOffsetHack+') + "px"');
|
||||
else
|
||||
s.setExpression('height','this.parentNode.offsetHeight + "px"');
|
||||
if (full)
|
||||
s.setExpression('width','"CSS1Compat" === document.compatMode && document.documentElement.clientWidth || document.body.clientWidth + "px"');
|
||||
else
|
||||
s.setExpression('width','this.parentNode.offsetWidth + "px"');
|
||||
if (fixL) s.setExpression('left', fixL);
|
||||
if (fixT) s.setExpression('top', fixT);
|
||||
}
|
||||
else if (opts.centerY) {
|
||||
if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
|
||||
s.marginTop = 0;
|
||||
}
|
||||
else if (!opts.centerY && full) {
|
||||
var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
|
||||
var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
|
||||
s.setExpression('top',expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// show the message
|
||||
if (msg) {
|
||||
if (opts.theme)
|
||||
lyr3.find('.ui-widget-content').append(msg);
|
||||
else
|
||||
lyr3.append(msg);
|
||||
if (msg.jquery || msg.nodeType)
|
||||
$(msg).show();
|
||||
}
|
||||
|
||||
if ((msie || opts.forceIframe) && opts.showOverlay)
|
||||
lyr1.show(); // opacity is zero
|
||||
if (opts.fadeIn) {
|
||||
var cb = opts.onBlock ? opts.onBlock : noOp;
|
||||
var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
|
||||
var cb2 = msg ? cb : noOp;
|
||||
if (opts.showOverlay)
|
||||
lyr2._fadeIn(opts.fadeIn, cb1);
|
||||
if (msg)
|
||||
lyr3._fadeIn(opts.fadeIn, cb2);
|
||||
}
|
||||
else {
|
||||
if (opts.showOverlay)
|
||||
lyr2.show();
|
||||
if (msg)
|
||||
lyr3.show();
|
||||
if (opts.onBlock)
|
||||
opts.onBlock.bind(lyr3)();
|
||||
}
|
||||
|
||||
// bind key and mouse events
|
||||
bind(1, el, opts);
|
||||
|
||||
if (full) {
|
||||
pageBlock = lyr3[0];
|
||||
pageBlockEls = $(opts.focusableElements,pageBlock);
|
||||
if (opts.focusInput)
|
||||
setTimeout(focus, 20);
|
||||
}
|
||||
else
|
||||
center(lyr3[0], opts.centerX, opts.centerY);
|
||||
|
||||
if (opts.timeout) {
|
||||
// auto-unblock
|
||||
var to = setTimeout(function() {
|
||||
if (full)
|
||||
$.unblockUI(opts);
|
||||
else
|
||||
$(el).unblock(opts);
|
||||
}, opts.timeout);
|
||||
$(el).data('blockUI.timeout', to);
|
||||
}
|
||||
}
|
||||
|
||||
// remove the block
|
||||
function remove(el, opts) {
|
||||
var count;
|
||||
var full = (el == window);
|
||||
var $el = $(el);
|
||||
var data = $el.data('blockUI.history');
|
||||
var to = $el.data('blockUI.timeout');
|
||||
if (to) {
|
||||
clearTimeout(to);
|
||||
$el.removeData('blockUI.timeout');
|
||||
}
|
||||
opts = $.extend({}, $.blockUI.defaults, opts || {});
|
||||
bind(0, el, opts); // unbind events
|
||||
|
||||
if (opts.onUnblock === null) {
|
||||
opts.onUnblock = $el.data('blockUI.onUnblock');
|
||||
$el.removeData('blockUI.onUnblock');
|
||||
}
|
||||
|
||||
var els;
|
||||
if (full) // crazy selector to handle odd field errors in ie6/7
|
||||
els = $('body').children().filter('.blockUI').add('body > .blockUI');
|
||||
else
|
||||
els = $el.find('>.blockUI');
|
||||
|
||||
// fix cursor issue
|
||||
if ( opts.cursorReset ) {
|
||||
if ( els.length > 1 )
|
||||
els[1].style.cursor = opts.cursorReset;
|
||||
if ( els.length > 2 )
|
||||
els[2].style.cursor = opts.cursorReset;
|
||||
}
|
||||
|
||||
if (full)
|
||||
pageBlock = pageBlockEls = null;
|
||||
|
||||
if (opts.fadeOut) {
|
||||
count = els.length;
|
||||
els.stop().fadeOut(opts.fadeOut, function() {
|
||||
if ( --count === 0)
|
||||
reset(els,data,opts,el);
|
||||
});
|
||||
}
|
||||
else
|
||||
reset(els, data, opts, el);
|
||||
}
|
||||
|
||||
// move blocking element back into the DOM where it started
|
||||
function reset(els,data,opts,el) {
|
||||
var $el = $(el);
|
||||
if ( $el.data('blockUI.isBlocked') )
|
||||
return;
|
||||
|
||||
els.each(function(i,o) {
|
||||
// remove via DOM calls so we don't lose event handlers
|
||||
if (this.parentNode)
|
||||
this.parentNode.removeChild(this);
|
||||
});
|
||||
|
||||
if (data && data.el) {
|
||||
data.el.style.display = data.display;
|
||||
data.el.style.position = data.position;
|
||||
data.el.style.cursor = 'default'; // #59
|
||||
if (data.parent)
|
||||
data.parent.appendChild(data.el);
|
||||
$el.removeData('blockUI.history');
|
||||
}
|
||||
|
||||
if ($el.data('blockUI.static')) {
|
||||
$el.css('position', 'static'); // #22
|
||||
}
|
||||
|
||||
if (typeof opts.onUnblock == 'function')
|
||||
opts.onUnblock(el,opts);
|
||||
|
||||
// fix issue in Safari 6 where block artifacts remain until reflow
|
||||
var body = $(document.body), w = body.width(), cssW = body[0].style.width;
|
||||
body.width(w-1).width(w);
|
||||
body[0].style.width = cssW;
|
||||
}
|
||||
|
||||
// bind/unbind the handler
|
||||
function bind(b, el, opts) {
|
||||
var full = el == window, $el = $(el);
|
||||
|
||||
// don't bother unbinding if there is nothing to unbind
|
||||
if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
|
||||
return;
|
||||
|
||||
$el.data('blockUI.isBlocked', b);
|
||||
|
||||
// don't bind events when overlay is not in use or if bindEvents is false
|
||||
if (!full || !opts.bindEvents || (b && !opts.showOverlay))
|
||||
return;
|
||||
|
||||
// bind anchors and inputs for mouse and key events
|
||||
var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
|
||||
if (b)
|
||||
$(document).on(events, opts, handler);
|
||||
else
|
||||
$(document).off(events, handler);
|
||||
|
||||
// former impl...
|
||||
// var $e = $('a,:input');
|
||||
// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
|
||||
}
|
||||
|
||||
// event handler to suppress keyboard/mouse events when blocking
|
||||
function handler(e) {
|
||||
// allow tab navigation (conditionally)
|
||||
if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
|
||||
if (pageBlock && e.data.constrainTabKey) {
|
||||
var els = pageBlockEls;
|
||||
var fwd = !e.shiftKey && e.target === els[els.length-1];
|
||||
var back = e.shiftKey && e.target === els[0];
|
||||
if (fwd || back) {
|
||||
setTimeout(function(){focus(back);},10);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
var opts = e.data;
|
||||
var target = $(e.target);
|
||||
if (target.hasClass('blockOverlay') && opts.onOverlayClick)
|
||||
opts.onOverlayClick(e);
|
||||
|
||||
// allow events within the message content
|
||||
if (target.parents('div.' + opts.blockMsgClass).length > 0)
|
||||
return true;
|
||||
|
||||
// allow events for content that is not being blocked
|
||||
return target.parents().children().filter('div.blockUI').length === 0;
|
||||
}
|
||||
|
||||
function focus(back) {
|
||||
if (!pageBlockEls)
|
||||
return;
|
||||
var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
|
||||
if (e)
|
||||
e.focus();
|
||||
}
|
||||
|
||||
function center(el, x, y) {
|
||||
var p = el.parentNode, s = el.style;
|
||||
var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
|
||||
var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
|
||||
if (x) s.left = l > 0 ? (l+'px') : '0';
|
||||
if (y) s.top = t > 0 ? (t+'px') : '0';
|
||||
}
|
||||
|
||||
function sz(el, p) {
|
||||
return parseInt($.css(el,p),10)||0;
|
||||
}
|
||||
jQuery.migrateDeduplicateWarnings = migrateDeduplicateWarnings;
|
||||
}
|
||||
|
||||
|
||||
/*global define:true */
|
||||
if (typeof define === 'function' && define.amd && define.amd.jQuery) {
|
||||
define(['jquery'], setup);
|
||||
} else {
|
||||
setup(jQuery);
|
||||
}
|
||||
|
||||
})();
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
if (!defined('EASY_UPDATES_MANAGER_MAIN_PATH')) die('No direct access allowed');
|
||||
|
||||
if (!class_exists('Updraft_Notices_1_2')) require_once(EASY_UPDATES_MANAGER_MAIN_PATH.'/vendor/team-updraft/common-libs/src/updraft-notices/updraft-notices.php');
|
||||
|
||||
/**
|
||||
* Class Easy_Updates_Manager_Notices
|
||||
*/
|
||||
class Easy_Updates_Manager_Notices extends Updraft_Notices_1_2 {
|
||||
|
||||
protected static $_instance = null;
|
||||
|
||||
private $initialized = false;
|
||||
|
||||
protected $self_affiliate_id = 212;
|
||||
|
||||
protected $notices_content = array();
|
||||
|
||||
/**
|
||||
* Creates and returns the only notice instance
|
||||
*
|
||||
* @return Object a Easy_Updates_Manager_Notices instance
|
||||
*/
|
||||
public static function instance() {
|
||||
if (empty(self::$_instance)) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets any parent notices and adds its own notices to the notice array
|
||||
*
|
||||
* @return Array returns an array of notices
|
||||
*/
|
||||
protected function populate_notices_content() {
|
||||
$parent_notice_content = parent::populate_notices_content();
|
||||
$child_notice_content = array(
|
||||
'updraftplus' => array(
|
||||
'prefix' => '',
|
||||
'title' => __('Always run the UpdraftPlus backup plugin before you update', 'stops-core-theme-and-plugin-updates'),
|
||||
'text' => __("UpdraftPlus is the world’s highest ranking and most popular backup plugin.", 'stops-core-theme-and-plugin-updates'),
|
||||
'image' => 'notices/updraft_logo.png',
|
||||
'button_link' => 'https://wordpress.org/plugins/updraftplus/',
|
||||
'button_meta' => 'updraftplus',
|
||||
'dismiss_time' => 'dismiss_page_notice_until',
|
||||
'supported_positions' => $this->anywhere,
|
||||
'validity_function' => 'is_updraftplus_installed',
|
||||
),
|
||||
'updraftcentral' => array(
|
||||
'prefix' => '',
|
||||
'title' => __('Save time and money.', 'stops-core-theme-and-plugin-updates').' '.__('Manage multiple sites from one location.', 'stops-core-theme-and-plugin-updates'),
|
||||
'text' => __('Back up, update and manage multiple WordPress websites centrally.', 'stops-core-theme-and-plugin-updates'),
|
||||
'image' => 'notices/updraftcentral_logo.png',
|
||||
'button_link' => 'https://teamupdraft.com/updraftcentral/?utm_source=eum-plugin&utm_medium=referral&utm_campaign=paac&utm_content=updraftcentral&utm_creative_format=advert',
|
||||
'button_meta' => 'updraftcentral',
|
||||
'dismiss_time' => 'dismiss_page_notice_until',
|
||||
'supported_positions' => $this->anywhere,
|
||||
'validity_function' => 'is_updraftcentral_installed',
|
||||
),
|
||||
'aios' => array(
|
||||
'prefix' => '',
|
||||
'title' => __('Secure your site', 'stops-core-theme-and-plugin-updates'),
|
||||
'text' => __("The ‘All-In-One’ Security plugin from TeamUpdraft.", "stops-core-theme-and-plugin-updates"),
|
||||
'image' => 'notices/aios_logo.png',
|
||||
'button_link' => 'https://teamupdraft.com/all-in-one-security/?utm_source=eum-plugin&utm_medium=referral&utm_campaign=paac&utm_content=aios&utm_creative_format=advert',
|
||||
'button_meta' => 'aios',
|
||||
'dismiss_time' => 'dismiss_page_notice_until',
|
||||
'supported_positions' => $this->anywhere,
|
||||
'validity_function' => 'is_aios_installed',
|
||||
),
|
||||
'wp-optimize' => array(
|
||||
'prefix' => '',
|
||||
'title' => 'Speed up your site',
|
||||
'text' => __("Make your site fast and efficient with our cutting-edge speed optimization plugin.", 'stops-core-theme-and-plugin-updates'),
|
||||
'image' => 'notices/wp_optimize_logo.png',
|
||||
'button_link' => 'https://wordpress.org/plugins/wp-optimize/',
|
||||
'button_meta' => 'wp-optimize',
|
||||
'dismiss_time' => 'dismiss_page_notice_until',
|
||||
'supported_positions' => $this->anywhere,
|
||||
'validity_function' => 'is_wpo_installed',
|
||||
),
|
||||
|
||||
// The sale adverts content starts here
|
||||
'blackfriday' => array(
|
||||
'prefix' => '',
|
||||
'title' => __('Black Friday - 20% off Easy Updates Manager Premium until November 30th', 'stops-core-theme-and-plugin-updates'),
|
||||
'text' => __('To benefit, use this discount code:', 'stops-core-theme-and-plugin-updates') . ' ',
|
||||
'image' => 'notices/black_friday.png',
|
||||
'button_link' => 'https://easyupdatesmanager.com/',
|
||||
'button_meta' => 'eum_premium',
|
||||
'dismiss_time' => 'dismiss_season_notice_until',
|
||||
'discount_code' => 'blackfridaysale2022',
|
||||
'valid_from' => '2022-11-20 00:00:00',
|
||||
'valid_to' => '2022-11-30 23:59:59',
|
||||
'supported_positions' => $this->dashboard_top_or_report,
|
||||
'validity_function' => 'is_premium_installed',
|
||||
)
|
||||
);
|
||||
|
||||
return array_merge($parent_notice_content, $child_notice_content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method to setup the notices
|
||||
*/
|
||||
public function notices_init() {
|
||||
if ($this->initialized) return;
|
||||
$this->initialized = true;
|
||||
$this->notices_content = (defined('EASY_UPDATES_MANAGER_NOADS_B') && EASY_UPDATES_MANAGER_NOADS_B) ? array() : $this->populate_notices_content();
|
||||
$min_or_not = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
|
||||
$file_path = "css/easy-updates-manager-notices$min_or_not";
|
||||
wp_enqueue_style('easy-updates-manager-notices-css', MPSUM_Updates_Manager::get_plugin_url("/$file_path.css"), array(), (int) filemtime(MPSUM_Updates_Manager::get_plugin_dir("$file_path.css")));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will call the parent is_plugin_installed and pass in the product updraftplus to check if that plugin is installed if it is then we shouldn't display the notice
|
||||
*
|
||||
* @param string $product the plugin slug
|
||||
* @param boolean $also_require_active a bool to indicate if the plugin should also be active
|
||||
* @return boolean a bool to indicate if the notice should be displayed or not
|
||||
*/
|
||||
protected function is_updraftplus_installed($product = 'updraftplus', $also_require_active = false) {
|
||||
return parent::is_plugin_installed($product, $also_require_active);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will call the parent is_plugin_installed and pass in the product updraftcentral to check if that plugin is installed if it is then we shouldn't display the notice
|
||||
*
|
||||
* @param string $product the plugin slug
|
||||
* @param boolean $also_require_active a bool to indicate if the plugin should also be active
|
||||
* @return boolean a bool to indicate if the notice should be displayed or not
|
||||
*/
|
||||
protected function is_updraftcentral_installed($product = 'updraftcentral', $also_require_active = false) {
|
||||
return parent::is_plugin_installed($product, $also_require_active);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will call the is premium function in the Easy_Updates_Manager_Notices object to check if this install is premium and if it is we won't display the notice
|
||||
*
|
||||
* @param string $product the plugin slug
|
||||
* @param boolean $also_require_active a bool to indicate if the plugin should also be active
|
||||
* @return boolean a bool to indicate if we should display the notice or not
|
||||
*/
|
||||
protected function is_wpo_installed($product = 'wp-optimize', $also_require_active = false) {
|
||||
return parent::is_plugin_installed($product, $also_require_active);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the AIOS plugin is installed or not
|
||||
*
|
||||
* @param string $product the plugin slug
|
||||
* @param boolean $also_require_active a bool to indicate if the plugin should also be active
|
||||
* @return boolean a bool to indicate if we should display the notice or not
|
||||
*/
|
||||
protected function is_aios_installed($product = 'all-in-one-wp-security-and-firewall', $also_require_active = false) {
|
||||
return parent::is_plugin_installed($product, $also_require_active);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will check if the premium EUM is installed and if so return false, otherwise true
|
||||
*
|
||||
* @return boolean - false if EUM premium is installed otherwise true
|
||||
*/
|
||||
protected function is_premium_installed() {
|
||||
return MPSUM_Updates_Manager::get_instance()->is_premium() ? false : true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method calls the parent version and will work out if the user is using a non english language and if so returns true so that they can see the translation advert.
|
||||
*
|
||||
* @param String $plugin_base_dir the plugin base directory
|
||||
* @param String $product_name the name of the plugin
|
||||
* @return Boolean returns true if the user is using a non english language and could translate otherwise false
|
||||
*/
|
||||
protected function translation_needed($plugin_base_dir, $product_name) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Easy_Updates_Manager_Notices::translation_needed should be compatible with Updraft_Notices_1_0::translation_needed so these variables are needed
|
||||
return parent::translation_needed(EASY_UPDATES_MANAGER_MAIN_PATH, 'stops-core-theme-and-plugin-updates');
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks to see if the notices dismiss_time parameter has been dismissed
|
||||
*
|
||||
* @param String $dismiss_time a string containing the dimiss time ID
|
||||
* @return Boolean returns true if the notice has been dismissed and shouldn't be shown otherwise display it
|
||||
*/
|
||||
protected function check_notice_dismissed($dismiss_time) {
|
||||
$time_now = (defined('EASY_UPDATES_MANAGER_NOTICES_FORCE_TIME') ? EASY_UPDATES_MANAGER_NOTICES_FORCE_TIME : time());
|
||||
$dismiss = ($time_now < get_site_option('easy_updates_manager_' . $dismiss_time, 0));
|
||||
return $dismiss;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check notice data for seasonal info and return true if we should display this notice.
|
||||
*
|
||||
* @param array $notice_data Data about notice
|
||||
* @return bool Determines whether to skip seasonal notice or not
|
||||
*/
|
||||
protected function skip_seasonal_notices($notice_data) {
|
||||
$time_now = defined('EASY_UPDATES_MANAGER_FORCE_TIME_NOTICES_FORCE_TIME') ? EASY_UPDATES_MANAGER_FORCE_TIME_NOTICES_FORCE_TIME : time();
|
||||
$valid_from = strtotime($notice_data['valid_from']);
|
||||
$valid_to = strtotime($notice_data['valid_to']);
|
||||
$dismiss = $this->check_notice_dismissed($notice_data['dismiss_time']);
|
||||
if (($time_now >= $valid_from && $time_now <= $valid_to) && !$dismiss) {
|
||||
// return true so that we return this notice to be displayed
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will create the chosen notice and the template to use and depending on the parameters either echo it to the page or return it
|
||||
*
|
||||
* @param Array $advert_information an array with the notice information in
|
||||
* @param Boolean $return_instead_of_echo a bool value to indicate if the notice should be printed to page or returned
|
||||
* @param String $position a string to indicate what template should be used
|
||||
* @return String a notice to display
|
||||
*/
|
||||
protected function render_specified_notice($advert_information, $return_instead_of_echo = false, $position = 'top') {
|
||||
|
||||
if ('bottom' == $position) {
|
||||
$template_file = 'bottom-notice.php';
|
||||
} elseif ('report' == $position) {
|
||||
$template_file = 'report.php';
|
||||
} elseif ('report-plain' == $position) {
|
||||
$template_file = 'report-plain.php';
|
||||
} else {
|
||||
$template_file = 'horizontal-notice.php';
|
||||
}
|
||||
|
||||
$extract_variables = array_merge($advert_information, array('easy_updates_manager_notices' => $this));
|
||||
|
||||
return Easy_Updates_Manager()->include_template('notices/'.$template_file, $return_instead_of_echo, $extract_variables);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user