Edit File by line

Deprecated: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in /home/sportsfever/public_html/filemanger/function.php on line 93
/home/sportsfe.../httpdocs/clone/wp-conte.../plugins/wp-smush.../core/s3
File: class-s3-controller.php
<?php
[0] Fix | Delete
[1] Fix | Delete
namespace Smush\Core\S3;
[2] Fix | Delete
[3] Fix | Delete
use DeliciousBrains\WP_Offload_Media\Integrations\Media_Library;
[4] Fix | Delete
use DeliciousBrains\WP_Offload_Media\Items\Media_Library_Item;
[5] Fix | Delete
use Smush\Core\Controller;
[6] Fix | Delete
use Smush\Core\File_System;
[7] Fix | Delete
use Smush\Core\Helper;
[8] Fix | Delete
use Smush\Core\Media\Media_Item;
[9] Fix | Delete
use Smush\Core\Media\Media_Item_Cache;
[10] Fix | Delete
use Smush\Core\Settings;
[11] Fix | Delete
use WDEV_Logger;
[12] Fix | Delete
[13] Fix | Delete
class S3_Controller extends Controller {
[14] Fix | Delete
const AS3CF_GET_ATTACHED_FILE_PRIORITY = - 10;
[15] Fix | Delete
private $media_item_cache;
[16] Fix | Delete
/**
[17] Fix | Delete
* @var WP_Offload_Media_Api
[18] Fix | Delete
*/
[19] Fix | Delete
private $wp_offload_media;
[20] Fix | Delete
/**
[21] Fix | Delete
* @var WDEV_Logger
[22] Fix | Delete
*/
[23] Fix | Delete
private $logger;
[24] Fix | Delete
/**
[25] Fix | Delete
* @var Settings
[26] Fix | Delete
*/
[27] Fix | Delete
private $settings;
[28] Fix | Delete
/**
[29] Fix | Delete
* @var File_System
[30] Fix | Delete
*/
[31] Fix | Delete
private $fs;
[32] Fix | Delete
[33] Fix | Delete
public function __construct() {
[34] Fix | Delete
$this->media_item_cache = Media_Item_Cache::get_instance();
[35] Fix | Delete
$this->wp_offload_media = new WP_Offload_Media_Api();
[36] Fix | Delete
$this->logger = Helper::logger()->integrations();
[37] Fix | Delete
$this->settings = Settings::get_instance();
[38] Fix | Delete
$this->fs = new File_System();
[39] Fix | Delete
[40] Fix | Delete
$this->register_action( 'init', array( $this, 'maybe_initialize' ), - 10 );
[41] Fix | Delete
}
[42] Fix | Delete
[43] Fix | Delete
public function maybe_initialize() {
[44] Fix | Delete
$wp_offload_media_active = $this->wp_offload_media_active();
[45] Fix | Delete
if ( ! $wp_offload_media_active || ! $this->settings->is_s3_active() ) {
[46] Fix | Delete
return;
[47] Fix | Delete
}
[48] Fix | Delete
[49] Fix | Delete
// TODO: PNG2Jpg file names should not exist on the server?
[50] Fix | Delete
// TODO: check whether we need to check is_plugin_setup, remove-local-file and copy-to-s3 settings from wp-offload
[51] Fix | Delete
[52] Fix | Delete
$this->support_s3_image_optimization();
[53] Fix | Delete
[54] Fix | Delete
$this->support_s3_backup_and_restore();
[55] Fix | Delete
[56] Fix | Delete
add_filter( 'wp_smush_media_item_size', array( $this, 'initialize_s3_size' ), 10, 4 );
[57] Fix | Delete
}
[58] Fix | Delete
[59] Fix | Delete
public function before_restore( $callback, $priority ) {
[60] Fix | Delete
add_action( 'wp_smush_before_restore_backup', $callback, $priority, 2 );
[61] Fix | Delete
}
[62] Fix | Delete
[63] Fix | Delete
public function before_restore_attempt( $callback, $priority ) {
[64] Fix | Delete
add_action( 'wp_smush_before_restore_backup_attempt', $callback, $priority, 1 );
[65] Fix | Delete
}
[66] Fix | Delete
[67] Fix | Delete
public function after_restore( $callback, $priority ) {
[68] Fix | Delete
add_action( 'wp_smush_after_restore_backup', $callback, $priority, 3 );
[69] Fix | Delete
}
[70] Fix | Delete
[71] Fix | Delete
public function disable_s3_auto_download() {
[72] Fix | Delete
add_filter( 'as3cf_get_attached_file_copy_back_to_local', array( $this, 'return_false' ) );
[73] Fix | Delete
}
[74] Fix | Delete
[75] Fix | Delete
public function enable_back_s3_auto_download() {
[76] Fix | Delete
add_filter( 'as3cf_get_attached_file_copy_back_to_local', array( $this, 'return_false' ) );
[77] Fix | Delete
}
[78] Fix | Delete
[79] Fix | Delete
public function download_all_sizes( $attachment_id ) {
[80] Fix | Delete
$media_item = $this->media_item_cache->get( $attachment_id );
[81] Fix | Delete
if ( ! $this->is_media_item_valid( $media_item ) ) {
[82] Fix | Delete
return;
[83] Fix | Delete
}
[84] Fix | Delete
[85] Fix | Delete
foreach ( $media_item->get_sizes() as $size ) {
[86] Fix | Delete
if ( ! is_a( $size, '\Smush\Core\S3\S3_Media_Item_Size' ) ) {
[87] Fix | Delete
$this->log_error( 'Something went wrong while trying to download the images for Smush.' );
[88] Fix | Delete
continue;
[89] Fix | Delete
}
[90] Fix | Delete
[91] Fix | Delete
if ( ! $this->fs->file_exists( $size->get_local_path() ) ) {
[92] Fix | Delete
$this->download_remote_file( $attachment_id, $size->get_local_path() );
[93] Fix | Delete
}
[94] Fix | Delete
}
[95] Fix | Delete
}
[96] Fix | Delete
[97] Fix | Delete
public function download_backup_file( $file_path, $attachment_id ) {
[98] Fix | Delete
if ( ! $this->fs->file_exists( $file_path ) ) {
[99] Fix | Delete
$this->download_remote_file( $attachment_id, $file_path );
[100] Fix | Delete
}
[101] Fix | Delete
}
[102] Fix | Delete
[103] Fix | Delete
private function download_remote_file( $attachment_id, $file_path ) {
[104] Fix | Delete
$s3_library_item = $this->get_s3_media_item( $attachment_id );
[105] Fix | Delete
if ( $s3_library_item ) {
[106] Fix | Delete
$this->wp_offload_media->copy_provider_file_to_server( $s3_library_item, $file_path );
[107] Fix | Delete
}
[108] Fix | Delete
[109] Fix | Delete
if ( ! $this->fs->file_exists( $file_path ) ) {
[110] Fix | Delete
$this->log_error( "Failed to download remote file $attachment_id." );
[111] Fix | Delete
}
[112] Fix | Delete
}
[113] Fix | Delete
[114] Fix | Delete
public function disable_s3_update_attachment( $data ) {
[115] Fix | Delete
add_filter( 'as3cf_pre_update_attachment_metadata', array( $this, 'return_true' ) );
[116] Fix | Delete
[117] Fix | Delete
return $data;
[118] Fix | Delete
}
[119] Fix | Delete
[120] Fix | Delete
public function enable_back_s3_update_attachment() {
[121] Fix | Delete
remove_filter( 'as3cf_pre_update_attachment_metadata', array( $this, 'return_true' ) );
[122] Fix | Delete
}
[123] Fix | Delete
[124] Fix | Delete
public function return_true() {
[125] Fix | Delete
return true;
[126] Fix | Delete
}
[127] Fix | Delete
[128] Fix | Delete
public function return_false() {
[129] Fix | Delete
return false;
[130] Fix | Delete
}
[131] Fix | Delete
[132] Fix | Delete
/**
[133] Fix | Delete
* @return bool
[134] Fix | Delete
*/
[135] Fix | Delete
private function wp_offload_media_active() {
[136] Fix | Delete
return function_exists( 'as3cf_init' ) || function_exists( 'as3cf_pro_init' );
[137] Fix | Delete
}
[138] Fix | Delete
[139] Fix | Delete
/**
[140] Fix | Delete
* @param Media_Item $media_item
[141] Fix | Delete
*
[142] Fix | Delete
* @return bool
[143] Fix | Delete
*/
[144] Fix | Delete
private function is_media_item_valid( $media_item ) {
[145] Fix | Delete
$invalid = ! $media_item || empty( $media_item->get_wp_metadata() );
[146] Fix | Delete
if ( $invalid ) {
[147] Fix | Delete
$this->log_error( 'Media item is not valid.' );
[148] Fix | Delete
}
[149] Fix | Delete
[150] Fix | Delete
return ! $invalid;
[151] Fix | Delete
}
[152] Fix | Delete
[153] Fix | Delete
public function disable_s3_get_attached_file_filters() {
[154] Fix | Delete
// Make sure smush always gets local paths
[155] Fix | Delete
$this->disable_stream_wrapper_file();
[156] Fix | Delete
// S3 auto downloads an image when get_attached_file is called, we want to disable this, because we will explicitly download all media item sizes.
[157] Fix | Delete
$this->disable_s3_auto_download();
[158] Fix | Delete
// Reset media items, so they have to fetch the new values
[159] Fix | Delete
$this->media_item_cache->reset_all();
[160] Fix | Delete
}
[161] Fix | Delete
[162] Fix | Delete
public function enable_back_s3_get_attached_file_filters() {
[163] Fix | Delete
$this->enable_back_stream_wrapper_file();
[164] Fix | Delete
$this->enable_back_s3_auto_download();
[165] Fix | Delete
$this->media_item_cache->reset_all();
[166] Fix | Delete
}
[167] Fix | Delete
[168] Fix | Delete
private function disable_stream_wrapper_file() {
[169] Fix | Delete
add_filter(
[170] Fix | Delete
'as3cf_get_attached_file',
[171] Fix | Delete
array( $this, 'return_local_file_path' ),
[172] Fix | Delete
self::AS3CF_GET_ATTACHED_FILE_PRIORITY, // Our callback needs to run before the s3 callback get_stream_wrapper_file
[173] Fix | Delete
2
[174] Fix | Delete
);
[175] Fix | Delete
}
[176] Fix | Delete
[177] Fix | Delete
private function enable_back_stream_wrapper_file() {
[178] Fix | Delete
remove_filter( 'as3cf_get_attached_file', array(
[179] Fix | Delete
$this,
[180] Fix | Delete
'return_local_file_path',
[181] Fix | Delete
), self::AS3CF_GET_ATTACHED_FILE_PRIORITY );
[182] Fix | Delete
}
[183] Fix | Delete
[184] Fix | Delete
public function return_local_file_path( $url, $file_path ) {
[185] Fix | Delete
return $file_path;
[186] Fix | Delete
}
[187] Fix | Delete
[188] Fix | Delete
/**
[189] Fix | Delete
* @param callable $callback
[190] Fix | Delete
*
[191] Fix | Delete
* @return void
[192] Fix | Delete
*/
[193] Fix | Delete
private function before_smush( $callback, $priority ) {
[194] Fix | Delete
add_action( 'wp_smush_before_smush_file', $callback, $priority );
[195] Fix | Delete
}
[196] Fix | Delete
[197] Fix | Delete
private function before_smush_attempt( $callback, $priority ) {
[198] Fix | Delete
add_action( 'wp_smush_before_smush_attempt', $callback, $priority );
[199] Fix | Delete
}
[200] Fix | Delete
[201] Fix | Delete
/**
[202] Fix | Delete
* @param callable $callback
[203] Fix | Delete
*
[204] Fix | Delete
* @return void
[205] Fix | Delete
*/
[206] Fix | Delete
private function after_smush( $callback, $priority ) {
[207] Fix | Delete
add_action( 'wp_smush_after_smush_file', $callback, $priority );
[208] Fix | Delete
}
[209] Fix | Delete
[210] Fix | Delete
/**
[211] Fix | Delete
* @param $attachment_id
[212] Fix | Delete
*
[213] Fix | Delete
* @return void
[214] Fix | Delete
*/
[215] Fix | Delete
public function trigger_update_attachment_metadata( $attachment_id ) {
[216] Fix | Delete
$media_item = $this->media_item_cache->get( $attachment_id );
[217] Fix | Delete
if ( ! $this->is_media_item_valid( $media_item ) ) {
[218] Fix | Delete
return;
[219] Fix | Delete
}
[220] Fix | Delete
wp_update_attachment_metadata( $attachment_id, $media_item->get_wp_metadata() );
[221] Fix | Delete
}
[222] Fix | Delete
[223] Fix | Delete
/**
[224] Fix | Delete
* @param $size
[225] Fix | Delete
* @param $key
[226] Fix | Delete
* @param $metadata
[227] Fix | Delete
* @param $media_item Media_Item
[228] Fix | Delete
*
[229] Fix | Delete
* @return S3_Media_Item_Size
[230] Fix | Delete
*/
[231] Fix | Delete
public function initialize_s3_size( $size, $key, $metadata, $media_item ) {
[232] Fix | Delete
return new S3_Media_Item_Size(
[233] Fix | Delete
$key,
[234] Fix | Delete
$media_item->get_id(),
[235] Fix | Delete
$media_item->get_dir(),
[236] Fix | Delete
$media_item->get_base_url(),
[237] Fix | Delete
$metadata
[238] Fix | Delete
);
[239] Fix | Delete
}
[240] Fix | Delete
[241] Fix | Delete
/**
[242] Fix | Delete
* @param $attachment_id
[243] Fix | Delete
*
[244] Fix | Delete
* @return Media_Library_Item|null
[245] Fix | Delete
*/
[246] Fix | Delete
private function get_s3_media_item( $attachment_id ) {
[247] Fix | Delete
return $this->wp_offload_media->is_attachment_served_by_provider( $attachment_id, true );
[248] Fix | Delete
}
[249] Fix | Delete
[250] Fix | Delete
/**
[251] Fix | Delete
* @return void
[252] Fix | Delete
*/
[253] Fix | Delete
private function support_s3_image_optimization() {
[254] Fix | Delete
/**
[255] Fix | Delete
* Prevent frequent offloading attempts
[256] Fix | Delete
*/
[257] Fix | Delete
// During the optimization we might call wp_update_attachment_metadata multiple times. Prevent any offload attempts while smushing is in progress.
[258] Fix | Delete
$this->before_smush( array( $this, 'disable_s3_update_attachment' ), 10 );
[259] Fix | Delete
[260] Fix | Delete
/**
[261] Fix | Delete
* Ensure smush has access to local files during optimization
[262] Fix | Delete
*/
[263] Fix | Delete
// Download any of the sizes that don't exist locally
[264] Fix | Delete
$this->before_smush( array( $this, 'download_all_sizes' ), 20 );
[265] Fix | Delete
[266] Fix | Delete
/**
[267] Fix | Delete
* Delete remote version before uploading optimized
[268] Fix | Delete
*/
[269] Fix | Delete
// When all optimizations are completed, the new files will be uploaded.
[270] Fix | Delete
// Note that this is especially important for Png2Jpg optimization for getting rid of the old files from the servers. The new files are nothing like the old ones.
[271] Fix | Delete
add_action( 'wp_smush_png_jpg_converted', array( $this, 'delete_old_png_files_after_convert' ), 10, 4 );
[272] Fix | Delete
[273] Fix | Delete
/**
[274] Fix | Delete
* Trigger offloading after smush is done
[275] Fix | Delete
*/
[276] Fix | Delete
// Turn offloading back on
[277] Fix | Delete
$this->after_smush( array( $this, 'enable_back_s3_update_attachment' ), 20 );
[278] Fix | Delete
// Trigger offloading
[279] Fix | Delete
$this->after_smush( array( $this, 'trigger_update_attachment_metadata' ), 30 );
[280] Fix | Delete
[281] Fix | Delete
/**
[282] Fix | Delete
* Delay offloading on new media upload when auto smush is on
[283] Fix | Delete
*/
[284] Fix | Delete
$auto_smush_on = $this->settings->get( 'auto' );
[285] Fix | Delete
if ( $auto_smush_on ) {
[286] Fix | Delete
/**
[287] Fix | Delete
* We need to prevent {@see Media_Library::wp_update_attachment_metadata()} from getting called
[288] Fix | Delete
*/
[289] Fix | Delete
[290] Fix | Delete
// New media upload triggers wp_update_attachment_metadata which triggers offloading. Make sure offloading is postponed until smush is done.
[291] Fix | Delete
add_filter( 'add_attachment', array( $this, 'disable_s3_update_attachment' ) );
[292] Fix | Delete
[293] Fix | Delete
$priority = 100; // This has to be higher than other methods attached to this hook because $media_item->is_skipped() depends on those other methods
[294] Fix | Delete
$this->after_attachment_upload( array( $this, 'offload_if_media_item_not_optimizable' ), $priority );
[295] Fix | Delete
$this->before_smush_attempt( array( $this, 'offload_if_media_item_not_optimizable' ), $priority );
[296] Fix | Delete
}
[297] Fix | Delete
}
[298] Fix | Delete
[299] Fix | Delete
/**
[300] Fix | Delete
* @return void
[301] Fix | Delete
*/
[302] Fix | Delete
private function support_s3_backup_and_restore() {
[303] Fix | Delete
/**
[304] Fix | Delete
* Disable remote file filters during the restore process
[305] Fix | Delete
*/
[306] Fix | Delete
$this->before_restore_attempt( array( $this, 'disable_s3_get_attached_file_filters' ), 10 );
[307] Fix | Delete
[308] Fix | Delete
/**
[309] Fix | Delete
* Ensure smush has access to local files during restoration
[310] Fix | Delete
*/
[311] Fix | Delete
$this->before_restore( array( $this, 'download_backup_file' ), 10 );
[312] Fix | Delete
/**
[313] Fix | Delete
* Disable offloading
[314] Fix | Delete
*/
[315] Fix | Delete
$this->before_restore( array( $this, 'disable_s3_update_attachment' ), 20 );
[316] Fix | Delete
[317] Fix | Delete
/**
[318] Fix | Delete
* Delete remote version before uploading restored
[319] Fix | Delete
*/
[320] Fix | Delete
// When the restoration is completed, the new files will be uploaded. Again, this is especially important for Png2Jpg
[321] Fix | Delete
add_action( 'wp_smush_after_restore_png_jpg', array( $this, 'delete_old_jpg_files_after_restore' ), 10, 2 );
[322] Fix | Delete
[323] Fix | Delete
/**
[324] Fix | Delete
* Trigger offloading after restore is done
[325] Fix | Delete
*/
[326] Fix | Delete
$this->after_restore( array( $this, 'enable_back_s3_update_attachment' ), 20 );
[327] Fix | Delete
[328] Fix | Delete
$this->after_restore( array( $this, 'enable_back_s3_get_attached_file_filters' ), 30 );
[329] Fix | Delete
[330] Fix | Delete
$this->after_restore( function ( $restored, $backup_file_path, $attachment_id ) {
[331] Fix | Delete
if ( $restored ) {
[332] Fix | Delete
$this->wp_offload_media->delete_remote_files( $backup_file_path, $attachment_id );
[333] Fix | Delete
$this->trigger_update_attachment_metadata( $attachment_id );
[334] Fix | Delete
}
[335] Fix | Delete
}, 40 );
[336] Fix | Delete
}
[337] Fix | Delete
[338] Fix | Delete
private function log_error( $error ) {
[339] Fix | Delete
$this->logger->error( "Smush S3 Integration: $error" );
[340] Fix | Delete
}
[341] Fix | Delete
[342] Fix | Delete
private function is_media_item_optimizable( Media_Item $media_item ) {
[343] Fix | Delete
return ! $this->is_media_item_not_optimizable( $media_item );
[344] Fix | Delete
}
[345] Fix | Delete
[346] Fix | Delete
/**
[347] Fix | Delete
* @param Media_Item $media_item
[348] Fix | Delete
*
[349] Fix | Delete
* @return bool
[350] Fix | Delete
*/
[351] Fix | Delete
private function is_media_item_not_optimizable( Media_Item $media_item ) {
[352] Fix | Delete
return ! $media_item->is_valid() || $media_item->has_errors() || $media_item->is_skipped();
[353] Fix | Delete
}
[354] Fix | Delete
[355] Fix | Delete
public function offload_if_media_item_not_optimizable( $attachment_id ) {
[356] Fix | Delete
$media_item = $this->media_item_cache->get( $attachment_id );
[357] Fix | Delete
if ( $this->is_media_item_not_optimizable( $media_item ) ) {
[358] Fix | Delete
// If there is an error we want the image to be offloaded explicitly
[359] Fix | Delete
$this->enable_back_s3_update_attachment();
[360] Fix | Delete
$this->trigger_update_attachment_metadata( $attachment_id );
[361] Fix | Delete
}
[362] Fix | Delete
// We have already added hooks for enabling back and triggering offloading after successful smush.
[363] Fix | Delete
}
[364] Fix | Delete
[365] Fix | Delete
private function after_attachment_upload( $callback, $priority ) {
[366] Fix | Delete
add_action( 'wp_smush_after_attachment_upload', $callback, $priority );
[367] Fix | Delete
}
[368] Fix | Delete
[369] Fix | Delete
public function delete_old_png_files_after_convert( $attachment_id, $image_metadata, $media_item_stats, $png_file_paths ) {
[370] Fix | Delete
if ( empty( $png_file_paths ) ) {
[371] Fix | Delete
return;
[372] Fix | Delete
}
[373] Fix | Delete
[374] Fix | Delete
$this->after_smush( function () use ( $png_file_paths, $attachment_id ) {
[375] Fix | Delete
$this->wp_offload_media->delete_remote_files( $png_file_paths, $attachment_id );
[376] Fix | Delete
}, 50 );
[377] Fix | Delete
}
[378] Fix | Delete
[379] Fix | Delete
public function delete_old_jpg_files_after_restore( $media_item, $jpg_file_paths ) {
[380] Fix | Delete
if ( empty( $jpg_file_paths ) ) {
[381] Fix | Delete
return;
[382] Fix | Delete
}
[383] Fix | Delete
[384] Fix | Delete
$attachment_id = $media_item->get_id();
[385] Fix | Delete
$this->after_restore( function ( $restored ) use ( $jpg_file_paths, $attachment_id ) {
[386] Fix | Delete
if ( $restored ) {
[387] Fix | Delete
$this->wp_offload_media->delete_remote_files( $jpg_file_paths, $attachment_id );
[388] Fix | Delete
}
[389] Fix | Delete
}, 50 );
[390] Fix | Delete
}
[391] Fix | Delete
}
[392] Fix | Delete
[393] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function