PluginProbe ʕ •ᴥ•ʔ
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN / 4.1.0
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN v4.1.0
4.1.0 4.0.3 4.0.2 2.8.1 2.9.1 3.0.0 3.0.1 3.0.2 3.1.1 3.10.1 3.10.2 3.10.3 3.11.1 3.12.3 3.12.4 3.12.5 3.12.6 3.13.0 3.13.1 3.13.2 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.2 3.16.4 3.16.5 3.16.6 3.17.0 3.17.1 3.18.0 3.18.1 3.2.0.1 3.2.1 3.2.2.1 3.2.4 3.20.0 3.21.1 3.22.1 3.22.3 3.23.0 3.23.1 3.23.2 3.23.3 3.23.4 3.24.0 3.24.0-beta.2 3.3.0 3.3.1 3.3.2 3.4.1 3.4.2 3.6.1 3.6.3 3.7.0 3.7.1 3.7.2 3.7.3 3.8.2 3.8.3 3.8.4 3.8.5 3.8.7 3.8.8 3.9.0 3.9.1 3.9.11 3.9.2 3.9.4 3.9.5 3.9.8 3.9.9 trunk 1.0.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.2 1.2.1 1.2.10 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.5.1 1.6.5.2 1.6.5.3 1.6.5.4 1.7 1.7.1 1.7.1.1 2.0 2.0.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.6.2 2.0.6.3 2.0.6.5 2.0.7 2.0.7.1 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2 2.2.1 2.2.2 2.3 2.3.1 2.4 2.4.2 2.4.3 2.4.4 2.4.5 2.5.2 2.5.3 2.6.1 2.6.2 2.6.3 2.7 2.7.1 2.7.4 2.7.4.1 2.7.5 2.7.6 2.7.8 2.7.8.1 2.7.9.1 2.8.0 2.8.0.1
wp-smushit / core / class-optimization-controller.php
wp-smushit / core Last commit date
api 2 days ago background 2 days ago backups 2 days ago bulk 2 days ago cache 2 days ago cli 2 days ago external 2 days ago frontend 2 days ago integrations 2 days ago lazy-load 2 days ago media 2 days ago media-library 2 days ago membership 2 days ago modules 2 days ago parser 2 days ago photon 2 days ago png2jpg 2 days ago product-analytics 2 days ago rating-notification 2 days ago resize 2 days ago security 2 days ago smush 2 days ago srcset 2 days ago stats 2 days ago threads 2 days ago transform 2 days ago class-abstract-settings-dto.php 2 days ago class-activity-log-controller.php 2 days ago class-animated-status-controller.php 2 days ago class-array-utils.php 2 days ago class-attachment-id-list.php 2 days ago class-backup-size.php 2 days ago class-configs.php 2 days ago class-controller.php 2 days ago class-core.php 2 days ago class-cron-controller.php 2 days ago class-deprecated-hooks.php 2 days ago class-error-handler.php 2 days ago class-file-system.php 2 days ago class-file-utils.php 2 days ago class-format-utils.php 2 days ago class-helper.php 2 days ago class-hub-connector.php 2 days ago class-installer.php 2 days ago class-keyword-exclusions.php 2 days ago class-modules.php 2 days ago class-multisite-utils.php 2 days ago class-optimization-controller.php 2 days ago class-optimizer.php 2 days ago class-plugin-settings-watcher.php 2 days ago class-rest.php 2 days ago class-server-utils.php 2 days ago class-settings-controller.php 2 days ago class-settings-dto.php 2 days ago class-settings-sanitizer.php 2 days ago class-settings.php 2 days ago class-shim.php 2 days ago class-smush-file.php 2 days ago class-stats.php 2 days ago class-string-utils.php 2 days ago class-time-utils.php 2 days ago class-timer.php 2 days ago class-upload-dir.php 2 days ago class-url-utils.php 2 days ago class-urls-exclusions.php 2 days ago class-wp-query-utils.php 2 days ago wp-compat.php 2 days ago
class-optimization-controller.php
248 lines
1 <?php
2
3 namespace Smush\Core;
4
5 use Smush\Core\Media\Media_Item_Cache;
6 use Smush\Core\Media\Media_Item_Optimizer;
7 use Smush\Core\Media_Library\Media_Library_Row;
8 use Smush\Core\Membership\Membership;
9 use Smush\Core\Smush\Smush_Optimization;
10 use Smush\Core\Smush\Smusher;
11 use Smush\Core\Smush\Smusher_Options_Provider;
12 use Smush\Core\Stats\Global_Stats;
13
14 /**
15 * // TODO: [WPMUDEV SMUSH UI] create tests
16 */
17 class Optimization_Controller extends Controller {
18
19 /**
20 * @var Optimization_Controller
21 */
22 private static $instance;
23 /**
24 * @var Global_Stats
25 */
26 private $global_stats;
27
28 private $membership;
29 /**
30 * @var Settings
31 */
32 private $settings;
33 private $media_item_cache;
34 private $optimizer;
35
36 private function __construct() {
37 $this->global_stats = Global_Stats::get();
38 $this->membership = Membership::get_instance();
39 $this->settings = Settings::get_instance();
40 $this->media_item_cache = Media_Item_Cache::get_instance();
41 $this->optimizer = Optimizer::get_instance();
42
43 $this->register_action( 'wp_smush_image_sizes_changed', array( $this, 'mark_global_stats_as_outdated' ) );
44 $this->register_action( 'wp_smush_settings_updated', array(
45 $this,
46 'maybe_mark_global_stats_as_outdated',
47 ), 10, 2 );
48
49 $this->register_action( 'wp_ajax_optimize_attachment', array( $this, 'optimize_attachment' ) );
50 $this->register_action( 'wp_async_wp_generate_attachment_metadata', array(
51 $this,
52 'auto_optimize_attachment_async',
53 ) );
54 $this->register_filter(
55 'wp_generate_attachment_metadata',
56 array( $this, 'maybe_auto_optimize_attachment_sync' ), 15, 2
57 );
58 $this->register_action( 'wp_async_wp_save_image_editor_file', array( $this, 'handle_editor_upload_async' ), '', 2 );
59 // Fix SSL CA certificates issue.
60 $this->register_action( 'wp_smush_before_smush_file', array( $this, 'fix_ssl_ca_certificate_error' ) );
61 }
62
63 public static function get_instance() {
64 if ( empty( self::$instance ) ) {
65 self::$instance = new self();
66 }
67
68 return self::$instance;
69 }
70
71 public function mark_global_stats_as_outdated() {
72 $this->global_stats->mark_as_outdated();
73 }
74
75 public function maybe_mark_global_stats_as_outdated( $old_settings, $settings ) {
76 $old_original = ! empty( $old_settings['original'] );
77 $new_original = ! empty( $settings['original'] );
78 $original_status_changed = $old_original !== $new_original;
79 if ( $original_status_changed ) {
80 $this->mark_global_stats_as_outdated();
81 }
82 }
83
84 public function optimize_attachment() {
85 if ( ! isset( $_REQUEST['attachment_id'] ) ) {
86 wp_send_json_error(
87 array( 'error_msg' => esc_html__( 'No attachment ID was provided.', 'wp-smushit' ) )
88 );
89 }
90
91 if ( ! check_ajax_referer( 'wp-smush-ajax', '_nonce', false ) ) {
92 wp_send_json_error(
93 array( 'error_msg' => esc_html__( 'Nonce verification failed', 'wp-smushit' ) )
94 );
95 }
96
97 if ( ! Helper::is_user_allowed( 'upload_files' ) ) {
98 wp_send_json_error(
99 array( 'error_msg' => esc_html__( "You don't have permission to work with uploaded files.", 'wp-smushit' ) )
100 );
101 }
102
103 if ( $this->membership->is_api_hub_access_required() ) {
104 wp_send_json_error(
105 array( 'error_msg' => esc_html__( 'A WPMU DEV Hub connection is required to optimize images.', 'wp-smushit' ) )
106 );
107 }
108
109 $attachment_id = (int) $_REQUEST['attachment_id'];
110 $optimizer = $this->optimizer;
111 $is_optimized = $optimizer->optimize( $attachment_id );
112 $media_lib_item = Media_Library_Row::get_instance( $attachment_id );
113 $markup = $media_lib_item->generate_markup();
114
115 if ( $is_optimized ) {
116 wp_send_json_success( $markup );
117 } else {
118 $errors = $optimizer->get_errors();
119
120 wp_send_json_error( array(
121 'error' => $errors->get_error_code(),
122 'error_msg' => $errors->get_error_message(),
123 'html_stats' => $markup,
124 'show_warning' => $this->membership->should_show_premium_status_warning( $attachment_id ),
125 ) );
126 }
127 }
128
129 public function auto_optimize_attachment_async( $id ) {
130 // If we don't have image id or auto Smush is disabled, return.
131 if ( empty( $id ) || ! $this->optimizer->should_auto_optimize( $id ) ) {
132 return;
133 }
134
135 $this->optimizer->optimize( $id );
136 }
137
138 public function maybe_auto_optimize_attachment_sync( $meta, $id ) {
139 // We need to check if this call originated from Gutenberg and allow only media.
140 if ( Helper::is_non_rest_media() ) {
141 // If not - return image metadata.
142 return $meta;
143 }
144
145 $upload_attachment = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_SPECIAL_CHARS );
146 $is_upload_attachment = 'upload-attachment' === $upload_attachment || isset( $_POST['post_id'] );
147
148 // Our async task runs when action is upload-attachment and post_id found. So do not run on these conditions.
149 if ( $is_upload_attachment && defined( 'WP_SMUSH_ASYNC' ) && WP_SMUSH_ASYNC ) {
150 return $meta;
151 }
152
153 $generating_metadata = doing_filter( 'wp_generate_attachment_metadata' );
154 if ( $generating_metadata && ! $this->optimizer->should_auto_optimize( $id ) ) {
155 return $meta;
156 }
157
158 $this->optimizer->optimize( $id );
159
160 return $meta;
161 }
162
163 /**
164 * This method runs when a media item is edited.
165 *
166 * TODO: this method has been replicated from another method but there are unanswered questions:
167 * - Can't we optimize the full media item instead of just the full size?
168 * - We should probably not do anything if the media item was not previously optimized, because in that case we can just treat it as the other unoptimized items and take care of it during bulk smush.
169 */
170 public function handle_editor_upload_async( $id, $post_data ) {
171 if ( ! $this->optimizer->should_auto_optimize( $id ) ) {
172 return;
173 }
174
175 $filepath = empty( $post_data['filepath'] ) ? '' : $post_data['filepath'];
176 if ( ! $filepath || ! file_exists( $filepath ) ) {
177 return;
178 }
179
180 // Get before stats
181 $before_file_size = filesize( $filepath );
182
183 $smusher_options = ( new Smusher_Options_Provider() )->get_options();
184 $smusher = new Smusher( $smusher_options );
185 $smusher->smush( array( $filepath ) );
186 if ( $smusher->has_errors() ) {
187 return;
188 }
189
190 $media_item = Media_Item_Cache::get_instance()->get( $id );
191 $attached_file = $media_item->get_attached_file();
192 if ( $attached_file !== $filepath ) {
193 return;
194 }
195
196 $after_file_size = filesize( $filepath );
197 $media_item_optimizer = new Media_Item_Optimizer( $media_item );
198 $smush_optimization = $media_item_optimizer->get_optimization( Smush_Optimization::get_key() );
199 $smush_optimization_total_stats = $media_item_optimizer->get_stats( Smush_Optimization::get_key() );
200 $smush_optimization_full_size_stats = $media_item_optimizer->get_size_stats(
201 Smush_Optimization::get_key(),
202 $media_item->get_main_size()->get_key()
203 );
204
205 if ( $smush_optimization->is_optimized() ) {
206 $smush_optimization_total_stats->set_size_before(
207 $smush_optimization_total_stats->get_size_before()
208 - $smush_optimization_full_size_stats->get_size_before()
209 + $before_file_size
210 );
211 $smush_optimization_total_stats->set_size_after(
212 $smush_optimization_total_stats->get_size_after()
213 - $smush_optimization_full_size_stats->get_size_after()
214 + $after_file_size
215 );
216 $smush_optimization_full_size_stats->set_size_before( $before_file_size );
217 $smush_optimization_full_size_stats->set_size_after( $after_file_size );
218 $smush_optimization->save();
219 }
220 }
221
222 /**
223 * Fix SSL CA Certificate issue.
224 *
225 * @since 3.9.6
226 *
227 * Check for use of http url (Hostgator mostly) - got it from smush_image.
228 */
229 public function fix_ssl_ca_certificate_error() {
230 // Return if the member defined it.
231 if ( defined( 'WP_SMUSH_API_HTTP' ) ) {
232 return;
233 }
234 static $use_http;
235 /**
236 * Fix for Hostgator.
237 * Check for use of http url (Hostgator mostly).
238 */
239 if ( is_null( $use_http ) ) {
240 $use_http = $this->settings->get_setting( 'wp-smush-use_http' );
241 }
242
243 if ( $use_http ) {
244 define( 'WP_SMUSH_API_HTTP', 'http://smushpro.wpmudev.com/1.0/' );
245 }
246 }
247 }
248