File: //proc/self/cwd/wp-content/plugins/wp-smushit/core/modules/bulk/class-background-bulk-smush.php
<?php
namespace Smush\Core\Modules\Bulk;
use Smush\Core\Error_Handler;
use Smush\Core\Helper;
use Smush\Core\Server_Utils;
use Smush\Core\Stats\Global_Stats;
use Smush\Core\Media_Library\Media_Library_Last_Process;
use WP_Smush;
class Background_Bulk_Smush {
const REQUIRED_MYSQL_VERSION = '5.6';
/**
* @var Bulk_Smush_Background_Process
*/
private $background_process;
private $mail;
private $logger;
private $global_stats;
private $server_utils;
/**
* Static instance
*
* @var self
*/
private static $instance;
public static function get_instance() {
if ( empty( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
public function __construct() {
$process_manager = new Background_Process_Manager(
is_multisite(),
get_current_blog_id()
);
$this->background_process = $process_manager->create_process();
$this->mail = new Mail( 'wp_smush_background' );
$this->logger = Helper::logger();
$this->global_stats = Global_Stats::get();
$this->server_utils = new Server_Utils();
if ( ! $this->should_use_background() ) {
return;
}
$this->register_ajax_handler( 'bulk_smush_start', array( $this, 'bulk_smush_start' ) );
$this->register_ajax_handler( 'bulk_smush_cancel', array( $this, 'bulk_smush_cancel' ) );
$this->register_ajax_handler( 'bulk_smush_get_status', array( $this, 'bulk_smush_get_status' ) );
$this->register_ajax_handler( 'bulk_smush_get_global_stats', array( $this, 'bulk_smush_get_global_stats' ) );
add_filter( 'wp_smush_script_data', array( $this, 'localize_background_stats' ) );
add_action( 'init', array( $this, 'cancel_programmatically' ) );
}
public function get_background_process() {
return $this->background_process;
}
public function cancel_programmatically() {
$background_disabled = ! $this->is_background_enabled();
$constant_value = defined( 'WP_SMUSH_STOP_BACKGROUND_PROCESSING' ) && WP_SMUSH_STOP_BACKGROUND_PROCESSING;
$filter_value = apply_filters( 'wp_smush_stop_background_processing', false );
$capability = is_multisite() ? 'manage_network' : 'manage_options';
$param_value = ! empty( $_GET['wp_smush_stop_background_processing'] ) && current_user_can( $capability );
$should_cancel = $background_disabled || $constant_value || $filter_value || $param_value;
$status = $this->background_process->get_status();
if ( $should_cancel && $status->is_in_processing() && ! $status->is_cancelled() ) {
$this->logger->notice( 'Cancelling background processing because a constant/query param/filter indicated that the process needs to be stopped.' );
$this->background_process->cancel();
}
}
public function bulk_smush_start() {
$this->check_ajax_referrer();
$process = $this->background_process;
$in_processing = $process->get_status()->is_in_processing();
if ( $in_processing ) {
// Already in progress
wp_send_json_error();
}
$tasks = $this->prepare_background_tasks();
if ( $tasks ) {
do_action( 'wp_smush_bulk_smush_start' );
$process->start( $tasks );
wp_send_json_success( $process->get_status()->to_array() );
}
wp_send_json_error();
}
public function bulk_smush_cancel() {
$this->check_ajax_referrer();
if ( ! $this->background_process->get_status()->is_cancelled() ) {
$this->background_process->cancel();
}
wp_send_json_success();
}
public function bulk_smush_get_status() {
$this->check_ajax_referrer();
$is_process_stuck = Media_Library_Last_Process::get_instance()->is_process_stuck();
wp_send_json_success( array_merge(
$this->background_process->get_status()->to_array(),
array(
'is_process_stuck' => $is_process_stuck,
'in_process_notice' => $this->get_in_process_notice(),
)
) );
}
public function bulk_smush_get_global_stats() {
$this->check_ajax_referrer();
$stats = WP_Smush::get_instance()->admin()->get_global_stats_with_bulk_smush_content();
wp_send_json_success( $stats );
}
private function check_ajax_referrer() {
check_ajax_referer( 'wp-smush-ajax', '_nonce' );
// Check capability.
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
}
}
private function register_ajax_handler( $action, $handler ) {
add_action( "wp_ajax_$action", $handler );
}
/**
* @return Smush_Background_Task[]
*/
private function prepare_background_tasks() {
$smush_tasks = $this->prepare_smush_tasks();
$resmush_tasks = $this->prepare_resmush_tasks();
return array_merge(
$smush_tasks,
$resmush_tasks
);
}
private function prepare_smush_tasks() {
$to_smush = $this->global_stats->get_optimize_list()->get_ids();
if ( empty( $to_smush ) || ! is_array( $to_smush ) ) {
$to_smush = array();
}
return array_map( function ( $image_id ) {
return new Smush_Background_Task(
Smush_Background_Task::TASK_TYPE_SMUSH,
$image_id
);
}, $to_smush );
}
private function prepare_resmush_tasks() {
$to_resmush = $this->global_stats->get_redo_ids();
return array_map( function ( $image_id ) {
return new Smush_Background_Task(
Smush_Background_Task::TASK_TYPE_RESMUSH,
$image_id
);
}, $to_resmush );
}
private function prepare_error_tasks() {
$error_items_to_retry = $this->global_stats->get_error_list()->get_ids();
return array_map( function ( $image_id ) {
return new Smush_Background_Task(
Smush_Background_Task::TASK_TYPE_ERROR,
$image_id
);
}, $error_items_to_retry );
}
public function localize_background_stats( $script_data ) {
global $current_screen;
$is_bulk_smush_page = isset( $current_screen->id )
&& strpos( $current_screen->id, '_page_smush-bulk' ) !== false;
if ( $is_bulk_smush_page ) {
$script_data['bo_stats'] = $this->background_process->get_status()->to_array();
}
return $script_data;
}
/**
* Whether BO is in processing or not.
*
* @return boolean
*/
public function is_in_processing() {
return $this->background_process->get_status()->is_in_processing();
}
/**
* Whether BO is completed or not.
*
* @return boolean
*/
public function is_completed() {
return $this->background_process->get_status()->is_completed();
}
/**
* Whether BO is dead or not.
*
* @return boolean
*/
public function is_dead() {
return $this->background_process->get_status()->is_dead();
}
/**
* Get total items.
*
* @return int
*/
public function get_total_items() {
return $this->background_process->get_status()->get_total_items();
}
/**
* Get processed items.
*
* @return int
*/
public function get_processed_items() {
return $this->background_process->get_status()->get_processed_items();
}
/**
* Get failed items.
*
* @return int
*/
public function get_failed_items() {
return $this->background_process->get_status()->get_failed_items();
}
/**
* Get revival count.
*
* @return int
*/
public function get_revival_count() {
return $this->background_process->get_revival_count();
}
/**
* Get process id.
*/
public function get_process_id() {
return $this->background_process->get_process_id();
}
/**
* Get email address of recipient.
*
* @return string
*/
public function get_mail_recipient() {
$emails = $this->mail->get_mail_recipients();
return ! empty( $emails ) ? $emails[0] : get_option( 'admin_email' );
}
public function get_in_process_notice() {
return $this->mail->reporting_email_enabled()
? $this->get_email_enabled_notice()
: $this->get_email_disabled_notice();
}
private function get_email_disabled_notice() {
$email_setting_link = sprintf(
'<a href="#background_email-settings-row">%s</a>',
esc_html__( 'Enable the email notification', 'wp-smushit' )
);
/* translators: %s: a link */
return sprintf( __( 'Feel free to close this page while Smush works its magic in the background. %s to receive an email when the process finishes.', 'wp-smushit' ), $email_setting_link );
}
private function get_email_enabled_notice() {
$mail_recipient = $this->get_mail_recipient();
/* translators: %s: Email address */
return sprintf( __( 'Feel free to close this page while Smush works its magic in the background. We’ll email you at <strong>%s</strong> when it’s done.', 'wp-smushit' ), $mail_recipient );
}
public function is_background_enabled() {
if ( ! $this->can_use_background() ) {
return false;
}
return defined( 'WP_SMUSH_BACKGROUND' ) && WP_SMUSH_BACKGROUND;
}
public function should_use_background() {
return $this->is_background_enabled()
&& $this->is_background_supported();
}
public function is_background_supported() {
return $this->is_mysql_requirement_met();
}
public function can_use_background() {
return WP_Smush::is_pro() || ! empty( get_site_option( 'wp_smush_pre_3_12_6_site' ) );
}
/**
* We need the right version of MySQL for locks used by the Mutex class
* @return bool|int
*/
private function is_mysql_requirement_met() {
return version_compare( $this->get_actual_mysql_version(), $this->get_required_mysql_version(), '>=' );
}
public function get_required_mysql_version() {
return self::REQUIRED_MYSQL_VERSION;
}
public function get_actual_mysql_version() {
return $this->server_utils->get_mysql_version();
}
public function start_bulk_smush_direct() {
if ( ! $this->should_use_background() ) {
return false;
}
$process = $this->background_process;
$in_processing = $process->get_status()->is_in_processing();
if ( $in_processing ) {
return $process->get_status()->to_array();
}
if ( ! Helper::loopback_supported() ) {
$this->logger->error( 'Loopback check failed. Not starting a new background process.' );
return false;
}
$tasks = $this->prepare_background_tasks();
if ( $tasks ) {
do_action( 'wp_smush_bulk_smush_start' );
$process->start( $tasks );
}
return $process->get_status()->to_array();
}
}