: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Smush class for storing all Ajax related functionality: Ajax class
* @copyright (c) 2018, Incsub (http://incsub.com)
use Smush\Core\Error_Handler;
use Smush\Core\Media\Media_Item_Cache;
use Smush\Core\Modules\Smush;
if ( ! defined( 'WPINC' ) ) {
* Class Ajax for storing all Ajax related functionality.
public function __construct() {
$this->settings = Settings::get_instance();
// Handle skip quick setup action.
add_action( 'wp_ajax_skip_smush_setup', array( $this, 'skip_smush_setup' ) );
// Ajax request for quick setup.
add_action( 'wp_ajax_smush_setup', array( $this, 'smush_setup' ) );
add_action( 'wp_ajax_smush_hide_tutorials', array( $this, 'hide_tutorials' ) );
// Handle the smush pro dismiss features notice ajax.
add_action( 'wp_ajax_dismiss_upgrade_notice', array( $this, 'dismiss_upgrade_notice' ) );
// Handle the smush pro dismiss features notice ajax.
add_action( 'wp_ajax_dismiss_update_info', array( $this, 'dismiss_update_info' ) );
// Handle ajax request to dismiss the s3 warning.
add_action( 'wp_ajax_dismiss_s3support_alert', array( $this, 'dismiss_s3support_alert' ) );
add_action( 'wp_ajax_hide_api_message', array( $this, 'hide_api_message' ) );
add_action( 'wp_ajax_smush_show_warning', array( $this, 'show_warning_ajax' ) );
// Detect conflicting plugins.
add_action( 'wp_ajax_smush_dismiss_notice', array( $this, 'dismiss_notice' ) );
// Handle Smush Single Ajax.
add_action( 'wp_ajax_wp_smushit_manual', array( $this, 'smush_manual' ) );
// Handle resmush operation.
add_action( 'wp_ajax_smush_resmush_image', array( $this, 'resmush_image' ) );
// Scan images as per the latest settings.
add_action( 'wp_ajax_scan_for_resmush', array( $this, 'scan_images' ) );
add_action( 'wp_ajax_get_stats', array( $this, 'get_stats' ) );
// Ignore image from bulk Smush.
add_action( 'wp_ajax_wp_smushit_bulk', array( $this, 'process_smush_request' ) );
// Remove from skip list.
// Handle Ajax request for directory smush stats (stats meta box).
add_action( 'wp_ajax_get_dir_smush_stats', array( $this, 'get_dir_smush_stats' ) );
add_action( 'wp_ajax_smush_toggle_lazy_load', array( $this, 'smush_toggle_lazy_load' ) );
add_action( 'wp_ajax_smush_remove_icon', array( $this, 'remove_icon' ) );
add_action( 'wp_ajax_smush_upload_config', array( $this, 'upload_config' ) );
add_action( 'wp_ajax_smush_save_config', array( $this, 'save_config' ) );
add_action( 'wp_ajax_smush_apply_config', array( $this, 'apply_config' ) );
add_action( 'wp_ajax_recheck_api_status', array( $this, 'recheck_api_status' ) );
// Hide the new features modal.
add_action( 'wp_ajax_hide_new_features', array( $this, 'hide_new_features_modal' ) );
/***************************************
* Process ajax action for skipping Smush setup.
public function skip_smush_setup() {
check_ajax_referer( 'smush_quick_setup' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
update_option( 'skip-smush-setup', true );
* Ajax action to save settings from quick setup.
public function smush_setup() {
check_ajax_referer( 'smush_quick_setup', '_wpnonce' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
$quick_settings = array();
// Get the settings from $_POST.
if ( ! empty( $_POST['smush_settings'] ) ) {
// Required $quick_settings data is escaped later on in code.
$quick_settings = json_decode( wp_unslash( $_POST['smush_settings'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// Check the last settings stored in db.
$settings = $this->settings->get();
// Available settings for free/pro version.
$available = array( 'auto', 'lossy', 'strip_exif', 'original', 'lazy_load', 'usage' );
$highest_lossy_level = $this->settings->get_highest_lossy_level();
foreach ( $settings as $name => $values ) {
// Update only specified settings.
if ( ! in_array( $name, $available, true ) ) {
// Skip premium features if not a member.
if ( ! in_array( $name, Settings::$basic_features, true ) && 'usage' !== $name && ! WP_Smush::is_pro() ) {
// Update value in settings.
if ( 'lossy' === $name ) {
$settings['lossy'] = ! empty( $quick_settings->{$name} ) ? $highest_lossy_level : Settings::LEVEL_LOSSLESS;
$settings[ $name ] = (bool) $quick_settings->{$name};
// If Smush originals is selected, enable backups.
if ( 'original' === $name && $settings[ $name ] && WP_Smush::is_pro() ) {
$settings['backup'] = true;
// If lazy load enabled - init defaults.
if ( 'lazy_load' === $name && $quick_settings->{$name} ) {
$this->settings->init_lazy_load_defaults();
// Update the resize sizes.
$this->settings->set_setting( 'wp-smush-settings', $settings );
update_option( 'skip-smush-setup', true );
public function hide_tutorials() {
check_ajax_referer( 'wp-smush-ajax' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
update_option( 'wp-smush-hide-tutorials', true, false );
/***************************************
* Store a key/value to hide the smush features on bulk page
* There is no js code related to this action, it seems we are no longer use it, better to clean it?
public function dismiss_upgrade_notice() {
check_ajax_referer( 'wp-smush-ajax' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
update_site_option( 'wp-smush-hide_upgrade_notice', true );
// No Need to send json response for other requests.
* @param bool $remove_notice Remove notice.
public function dismiss_update_info( $remove_notice = false ) {
check_ajax_referer( 'wp-smush-ajax' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
WP_Smush::get_instance()->core()->mod->smush->dismiss_update_info( $remove_notice );
* Hide S3 support alert by setting a flag.
public function dismiss_s3support_alert() {
check_ajax_referer( 'wp-smush-ajax' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
update_site_option( 'wp-smush-hide_s3support_alert', 1 );
public function hide_api_message() {
check_ajax_referer( 'wp-smush-ajax' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
$api_message = get_site_option( 'wp-smush-api_message', array() );
if ( ! empty( $api_message ) && is_array( $api_message ) ) {
$api_message[ key( $api_message ) ]['status'] = 'hide';
update_site_option( 'wp-smush-api_message', $api_message );
* Send JSON response whether to show or not the warning
public function show_warning_ajax() {
check_ajax_referer( 'wp-smush-ajax' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
$show = WP_Smush::get_instance()->core()->mod->smush->show_warning();
wp_send_json( (int) $show );
* Dismiss the plugin conflicts notice.
public function dismiss_notice() {
check_ajax_referer( 'wp-smush-ajax' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
if ( empty( $_REQUEST['key'] ) ) {
$this->set_notice_dismissed( sanitize_key( $_REQUEST['key'] ) );
private function set_notice_dismissed( $notice ) {
$option_id = 'wp-smush-dismissed-notices';
$dismissed_notices = get_option( $option_id, array() );
$dismissed_notices[ $notice ] = true;
update_option( $option_id, $dismissed_notices );
/***************************************
* Handle the Ajax request for smushing single image
public function smush_manual() {
if ( ! check_ajax_referer( 'wp-smush-ajax', '_nonce', false ) ) {
'error_msg' => esc_html__( 'Nonce verification failed', 'wp-smushit' ),
if ( ! Helper::is_user_allowed( 'upload_files' ) ) {
'error_msg' => esc_html__( "You don't have permission to work with uploaded files.", 'wp-smushit' ),
if ( ! isset( $_GET['attachment_id'] ) ) {
'error_msg' => esc_html__( 'No attachment ID was provided.', 'wp-smushit' ),
$attachment_id = (int) $_GET['attachment_id'];
// Pass on the attachment id to smush single function.
WP_Smush::get_instance()->core()->mod->smush->smush_single( $attachment_id );
public function resmush_image() {
if ( empty( $_POST['attachment_id'] ) || empty( $_POST['_nonce'] ) ) {
'error_msg' => esc_html__( 'Image not smushed, fields empty.', 'wp-smushit' ),
if ( ! wp_verify_nonce( wp_unslash( $_POST['_nonce'] ), 'wp-smush-resmush-' . (int) $_POST['attachment_id'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
'error_msg' => esc_html__( "Image couldn't be smushed as the nonce verification failed, try reloading the page.", 'wp-smushit' ),
if ( ! Helper::is_user_allowed( 'upload_files' ) ) {
'error_msg' => esc_html__( "You don't have permission to work with uploaded files.", 'wp-smushit' ),
$image_id = (int) $_POST['attachment_id'];
WP_Smush::get_instance()->core()->mod->smush->smush_single( $image_id );
* Scans all the smushed attachments to check if they need to be resmushed as per the
* current settings, as user might have changed one of the configurations "Lossy", "Keep Original", "Preserve Exif"
* @todo: Needs some refactoring big time
public function scan_images() {
check_ajax_referer( 'save_wp_smush_options', 'wp_smush_options_nonce' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
'notice' => esc_html__( "You don't have permission to do this.", 'wp-smushit' ),
// Scanning for NextGen or Media Library.
$type = isset( $_REQUEST['type'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['type'] ) ) : '';
* @hooked wp_smush_nextgen_scan_stats Smush\Core\Integrations\NextGen\Admin::scan_images()
$stats = apply_filters( "wp_smush_{$type}_scan_stats", array() );
return wp_send_json_success( $stats );
public function get_stats() {
check_ajax_referer( 'wp-smush-ajax', '_nonce' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'wp-smushit' ), 403 );
$admin = WP_Smush::get_instance()->admin();
$stats = $admin->get_global_stats_with_bulk_smush_content();
wp_send_json_success( $stats );
/***************************************
* Processes the Smush request and sends back the next id for smushing.
public function process_smush_request() {
check_ajax_referer( 'wp-smush-ajax', '_nonce' );
if ( ! Helper::is_user_allowed( 'manage_options' ) ) {
'error' => 'unauthorized',
'error_message' => esc_html__( "You don't have permission to do this.", 'wp-smushit' ),
$new_bulk_smush = ! empty( $_REQUEST['new_bulk_smush_started'] ) && $_REQUEST['new_bulk_smush_started'] !== 'false';
do_action( 'wp_smush_bulk_smush_start' );
// If the bulk smush needs to be stopped.
if ( ! WP_Smush::is_pro() && ! Core::check_bulk_limit() ) {
'error' => 'limit_exceeded',
if ( ! empty( $_REQUEST['attachment_id'] ) ) {
$attachment_id = (int) $_REQUEST['attachment_id'];