Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
natchbone
/
wp-smushit
/
core
/
media-library
:
class-media-library-last-process.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace Smush\Core\Media_Library; use Smush\Core\Array_Utils; use Smush\Core\Controller; use Smush\Core\Helper; use Smush\Core\Modules\Background\Mutex; use Smush\Core\Modules\Bulk\Background_Bulk_Smush; use Smush\Core\Settings; class Media_Library_Last_Process extends Controller { const PROCESS_KEY = 'wp_smush_media_library_last_process'; const START_TIME = 'start_time'; const END_TIME = 'end_time'; const LAST_ATTACHMENT = 'last_attachment'; const FIRST_STUCK_ATTACHMENT = 'first_stuck_attachment'; const PROCESS_TIME_OUT = 120;// 2 mins. /** * @var Array_Utils */ private $array_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() { $this->array_utils = new Array_Utils(); // Register actions to cache data for displaying stuck notice of background process. $this->register_action( 'wp_smush_bulk_smush_start', array( $this, 'record_process_start_time' ), 5 ); $this->register_action( 'wp_smush_before_smush_file', array( $this, 'record_bulk_smush_last_processed_attachment' ), 5 ); if ( ! $this->should_track() ) { return; } $scan_background_process = Background_Media_Library_Scanner::get_instance()->get_background_process(); $this->register_action( $scan_background_process->action_name( 'started' ), array( $this, 'record_process_start_time' ), 5 ); $this->register_action( $scan_background_process->action_name( 'dead' ), array( $this, 'record_process_end_time' ), 5 ); $this->register_action( 'wp_smush_after_smush_file', array( $this, 'record_last_processed_attachment_elapsed_time' ), 5 ); // Background Bulk Smush. $this->register_action( 'wp_smush_bulk_smush_dead', array( $this, 'record_process_end_time' ), 5 ); $bulk_smush_background_process = Background_Bulk_Smush::get_instance()->get_background_process(); $this->register_action( $bulk_smush_background_process->action_name( 'cron' ), array( $this, 'check_bulk_smush_process' ), 5 ); $this->register_action( 'wp_ajax_bulk_smush_get_status', array( $this, 'check_bulk_smush_process_stuck_on_ajax_get_status' ), 5 ); } public function should_run() { return Background_Bulk_Smush::get_instance()->should_use_background(); } public function should_track() { return Settings::get_instance()->get( 'usage' ); } private function get_ajax_nonce( $query_arg = '_ajax_nonce' ) { $nonce = ''; if ( $query_arg && isset( $_REQUEST[ $query_arg ] ) ) { $nonce = wp_unslash( $_REQUEST[ $query_arg ] ); } elseif ( isset( $_REQUEST['_ajax_nonce'] ) ) { $nonce = wp_unslash( $_REQUEST['_ajax_nonce'] ); } elseif ( isset( $_REQUEST['_wpnonce'] ) ) { $nonce = wp_unslash( $_REQUEST['_wpnonce'] ); } return $nonce; } public function record_bulk_smush_last_processed_attachment( $attachment_id ) { if ( ! $this->is_bulk_smush_processing() ) { return; } $this->set_last_processed_attachment( $attachment_id ); } private function is_bulk_smush_processing() { if ( ! wp_doing_ajax() || empty( $_REQUEST['action'] ) ) { return false; } $bulk_process_actions = array( 'wp_smush_bulk_smush_background_process', 'wp_smushit_bulk', ); $action = wp_unslash( $_REQUEST['action'] ); foreach ( $bulk_process_actions as $bulk_action ) { if ( str_starts_with( $action, $bulk_action ) ) { return true; } } return false; } public function check_bulk_smush_process() { if ( $this->should_check_stuck() && $this->is_process_stuck() ) { $this->set_first_stuck_attachment(); do_action( 'wp_smush_bulk_smush_stuck', $this ); Helper::logger()->warning( sprintf( 'The Bulk Smush process has been stuck for %1$s minutes at image %2$d ( %3$s minutes )', round( $this->get_seconds_since_last_image_processing_started() / 60, 2 ), $this->get_last_process_attachment_id(), round( $this->get_last_process_attachment_elapsed_time() / 60, 2 ) ) ); } } private function should_check_stuck() { $first_stuck_attachment = $this->get_process_item( self::FIRST_STUCK_ATTACHMENT ); return empty( $first_stuck_attachment ); } public function check_bulk_smush_process_stuck_on_ajax_get_status() { $nonce = $this->get_ajax_nonce(); // Check capability. if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'wp-smush-ajax' ) || ! Helper::is_user_allowed( 'manage_options' ) ) { return; } $this->check_bulk_smush_process(); } private function set_last_processed_attachment( $attachment_id ) { $this->set_process_item( self::LAST_ATTACHMENT, array( 'id' => $attachment_id, 'start_time' => time(), ) ); } private function set_first_stuck_attachment() { $last_process_attachment = $this->get_last_processed_attachment(); $last_process_attachment['elapsed_time'] = $this->get_seconds_since_last_image_processing_started(); $this->set_process_item( self::FIRST_STUCK_ATTACHMENT, $last_process_attachment ); } public function is_process_stuck() { $elapsed_time = $this->get_seconds_since_last_image_processing_started(); return $elapsed_time > self::PROCESS_TIME_OUT; } public function record_last_processed_attachment_elapsed_time() { $last_process_attachment = $this->get_last_processed_attachment(); $last_process_attachment['attachment_elapsed_time'] = $this->get_last_process_attachment_elapsed_time(); $this->set_process_item( self::LAST_ATTACHMENT, $last_process_attachment ); } public function get_last_process_attachment_elapsed_time() { $last_process_attachment = $this->get_last_processed_attachment(); $attachment_elapsed_time = (int) $this->array_utils->get_array_value( $last_process_attachment, 'attachment_elapsed_time', - 1 ); if ( $attachment_elapsed_time > - 1 ) { return $attachment_elapsed_time; } return $this->get_seconds_since_last_image_processing_started(); } public function get_seconds_since_last_image_processing_started() { $last_process_attachment = $this->get_last_processed_attachment(); $start_time = (int) $this->array_utils->get_array_value( $last_process_attachment, 'start_time' ); if ( empty( $start_time ) ) { return 0; } $end_time = time(); return $end_time - $start_time; } public function get_last_process_attachment_id() { $last_process_attachment = $this->get_last_processed_attachment(); return $this->array_utils->get_array_value( $last_process_attachment, 'id', 0 ); } private function get_last_processed_attachment() { return $this->get_process_item( self::LAST_ATTACHMENT, array() ); } public function record_process_start_time() { $this->reset_process_option(); $this->set_process_start_time(); } public function record_process_end_time() { $this->set_process_end_time(); } private function reset_process_option() { delete_option( self::PROCESS_KEY ); wp_cache_delete( self::PROCESS_KEY, 'options' ); } private function set_process_start_time() { $this->set_process_item( self::START_TIME, microtime( true ) ); } private function set_process_end_time() { $this->set_process_item( self::END_TIME, microtime( true ) ); } public function get_process_elapsed_time() { $start_time = $this->get_process_start_time(); $end_time = $this->get_process_end_time(); return (int) ( $end_time - $start_time ); } public function get_process_start_time() { return $this->get_process_item( self::START_TIME ); } private function get_process_end_time() { return $this->get_process_item( self::END_TIME, time() ); } private function get_process_item( $item, $default_value = false ) { $process_option = $this->get_process_option(); return $this->array_utils->get_array_value( $process_option, $item, $default_value ); } private function set_process_item( $item, $value ) { ( new Mutex( self::PROCESS_KEY ) )->execute( function () use ( $item, $value ) { $process_option = $this->get_process_option(); $process_option[ $item ] = $value; $this->update_process_option( $process_option ); } ); } private function get_process_option() { $last_process = get_option( self::PROCESS_KEY, array() ); return $this->array_utils->ensure_array( $last_process ); } private function update_process_option( $last_process_option ) { update_option( self::PROCESS_KEY, $last_process_option, false ); } }