X7ROOT File Manager
Current Path:
/usr/src/litespeed-wp-plugin/7.8.0.1/litespeed-cache/src
usr
/
src
/
litespeed-wp-plugin
/
7.8.0.1
/
litespeed-cache
/
src
/
??
..
??
activation.cls.php
(17.31 KB)
??
admin-display.cls.php
(48.47 KB)
??
admin-settings.cls.php
(11.12 KB)
??
admin.cls.php
(6.13 KB)
??
api.cls.php
(10.36 KB)
??
avatar.cls.php
(8.65 KB)
??
base.cls.php
(37.66 KB)
??
cdn
??
cdn.cls.php
(15.92 KB)
??
cloud-auth-callback.trait.php
(10.43 KB)
??
cloud-auth-ip.trait.php
(4.33 KB)
??
cloud-auth.trait.php
(9.38 KB)
??
cloud-misc.trait.php
(10.32 KB)
??
cloud-node.trait.php
(5.95 KB)
??
cloud-request.trait.php
(19.68 KB)
??
cloud.cls.php
(7.32 KB)
??
conf.cls.php
(19.53 KB)
??
control.cls.php
(24.35 KB)
??
core.cls.php
(20.97 KB)
??
crawler-map.cls.php
(19.41 KB)
??
crawler.cls.php
(44.72 KB)
??
css.cls.php
(17.77 KB)
??
data.cls.php
(22.21 KB)
??
data.upgrade.func.php
(5.72 KB)
??
data_structure
??
db-optm.cls.php
(15.35 KB)
??
debug2.cls.php
(18.4 KB)
??
doc.cls.php
(5.45 KB)
??
error.cls.php
(7.35 KB)
??
esi.cls.php
(27.18 KB)
??
file.cls.php
(10.57 KB)
??
guest.cls.php
(2.75 KB)
??
gui.cls.php
(36.57 KB)
??
health.cls.php
(2.83 KB)
??
htaccess.cls.php
(29.81 KB)
??
img-optm-manage.trait.php
(30.85 KB)
??
img-optm-pull.trait.php
(22.1 KB)
??
img-optm-send.trait.php
(21.9 KB)
??
img-optm.cls.php
(5.26 KB)
??
import.cls.php
(4.29 KB)
??
import.preset.cls.php
(5.5 KB)
??
lang.cls.php
(17.02 KB)
??
localization.cls.php
(4.03 KB)
??
media.cls.php
(44.08 KB)
??
metabox.cls.php
(5.29 KB)
??
object-cache-wp.cls.php
(18.82 KB)
??
object-cache.cls.php
(20.95 KB)
??
object.lib.php
(14.16 KB)
??
optimize.cls.php
(38.64 KB)
??
optimizer.cls.php
(10.5 KB)
??
placeholder.cls.php
(17.93 KB)
??
purge.cls.php
(34.41 KB)
??
report.cls.php
(6.12 KB)
??
rest.cls.php
(9.08 KB)
??
root.cls.php
(14.29 KB)
??
router.cls.php
(20.76 KB)
??
str.cls.php
(3.08 KB)
??
tag.cls.php
(9.26 KB)
??
task.cls.php
(7.05 KB)
??
tool.cls.php
(4.17 KB)
??
ucss.cls.php
(16.35 KB)
??
utility.cls.php
(26.01 KB)
??
vary.cls.php
(21.33 KB)
??
vpi.cls.php
(9.38 KB)
Editing: img-optm-manage.trait.php
<?php /** * Image optimization management trait * * @package LiteSpeed * @since 7.8 */ namespace LiteSpeed; defined( 'WPINC' ) || exit(); /** * Trait Img_Optm_Manage * * Handles image optimization management operations: clean, destroy, rescan, backup, batch_switch, etc. */ trait Img_Optm_Manage { /** * Check if an attachment has optimization records * * @since 7.8 * @access public * @param int $post_id The attachment post ID. * @param array|null $metadata Optional. Attachment metadata for file path check. * @return bool True if has optimization records. */ public function has_optm_record( $post_id, $metadata = null ) { global $wpdb; if ( ! $post_id ) { return false; } // Check post meta if ( get_post_meta( $post_id, self::DB_SIZE, true ) || get_post_meta( $post_id, self::DB_SET, true ) ) { return true; } // Check img_optm table (legacy) if ( $this->__data->tb_exist( 'img_optm' ) ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(1) FROM `$this->_table_img_optm` WHERE post_id = %d", $post_id ) ); if ( $count > 0 ) { return true; } } // Check img_optming table if ( $this->__data->tb_exist( 'img_optming' ) ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(1) FROM `$this->_table_img_optming` WHERE post_id = %d", $post_id ) ); if ( $count > 0 ) { return true; } } // Check if optimized files exist (.webp, .avif) if ( null === $metadata ) { $metadata = wp_get_attachment_metadata( $post_id ); } if ( ! empty( $metadata['file'] ) ) { $short_file_path = $metadata['file']; if ( $this->__media->info( $short_file_path . '.webp', $post_id ) ) { return true; } if ( $this->__media->info( $short_file_path . '.avif', $post_id ) ) { return true; } } return false; } /** * Clean up all unfinished queue locally and to Cloud server * * @since 2.1.2 * @access public */ public function clean() { global $wpdb; // Reset img_optm table's queue if ( $this->__data->tb_exist( 'img_optming' ) ) { // Get min post id to mark $q = "SELECT MIN(post_id) FROM `$this->_table_img_optming`"; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $min_pid = $wpdb->get_var( $q ) - 1; if ( $this->_summary['next_post_id'] > $min_pid ) { $this->_summary['next_post_id'] = $min_pid; self::save_summary(); } $q = "DELETE FROM `$this->_table_img_optming`"; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $wpdb->query( $q ); } $msg = __( 'Cleaned up unfinished data successfully.', 'litespeed-cache' ); Admin_Display::success( $msg ); } /** * Reset image counter * * @since 7.0 * @access private */ private function _reset_counter() { self::debug( 'reset image optm counter' ); $this->_summary['next_post_id'] = 0; self::save_summary(); $this->clean(); $msg = __( 'Reset image optimization counter successfully.', 'litespeed-cache' ); Admin_Display::success( $msg ); } /** * Destroy all optimized images * * @since 3.0 * @access private */ private function _destroy() { global $wpdb; self::debug( 'executing DESTROY process' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $offset = ! empty( $_GET['litespeed_i'] ) ? absint( wp_unslash( $_GET['litespeed_i'] ) ) : 0; /** * Limit images each time before redirection to fix Out of memory issue. #665465 * * @since 2.9.8 */ // Start deleting files $limit = apply_filters( 'litespeed_imgoptm_destroy_max_rows', 500 ); $img_q = "SELECT b.post_id, b.meta_value FROM `$wpdb->posts` a LEFT JOIN `$wpdb->postmeta` b ON b.post_id = a.ID WHERE b.meta_key = '_wp_attachment_metadata' AND a.post_type = 'attachment' AND a.post_status = 'inherit' AND a.post_mime_type IN ('image/jpeg', 'image/png', 'image/gif') ORDER BY a.ID LIMIT %d,%d "; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $q = $wpdb->prepare( $img_q, [ $offset * $limit, $limit ] ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $list = $wpdb->get_results( $q ); $i = 0; foreach ( $list as $v ) { if ( ! $v->post_id ) { continue; } $meta_value = $this->_parse_wp_meta_value( $v ); if ( ! $meta_value ) { continue; } ++$i; $this->tmp_pid = $v->post_id; $this->tmp_path = pathinfo( $meta_value['file'], PATHINFO_DIRNAME ) . '/'; $this->_destroy_optm_file( $meta_value, true ); if ( ! empty( $meta_value['sizes'] ) ) { array_map( [ $this, '_destroy_optm_file' ], $meta_value['sizes'] ); } } self::debug( 'batch switched images total: ' . $i ); ++$offset; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $to_be_continued = $wpdb->get_row( $wpdb->prepare( $img_q, [ $offset * $limit, 1 ] ) ); if ( $to_be_continued ) { // Check if post_id is beyond next_post_id self::debug( '[next_post_id] ' . $this->_summary['next_post_id'] . ' [cursor post id] ' . $to_be_continued->post_id ); if ( $to_be_continued->post_id <= $this->_summary['next_post_id'] ) { self::debug( 'redirecting to next' ); return Router::self_redirect( Router::ACTION_IMG_OPTM, self::TYPE_DESTROY ); } self::debug( '🎊 Finished destroying' ); } // Delete postmeta info $q = "DELETE FROM `$wpdb->postmeta` WHERE meta_key = %s"; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $wpdb->query( $wpdb->prepare( $q, self::DB_SIZE ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $wpdb->query( $wpdb->prepare( $q, self::DB_SET ) ); // Delete img_optm table $this->__data->tb_del( 'img_optm' ); $this->__data->tb_del( 'img_optming' ); // Clear options table summary info self::delete_option( '_summary' ); self::delete_option( self::DB_NEED_PULL ); $msg = __( 'Destroy all optimization data successfully.', 'litespeed-cache' ); Admin_Display::success( $msg ); } /** * Destroy optm file * * @since 3.0 * @access private * @param array $meta_value The meta value array containing file info. * @param bool $is_ori_file Whether this is the original file. */ private function _destroy_optm_file( $meta_value, $is_ori_file = false ) { $short_file_path = $meta_value['file']; if ( ! $is_ori_file ) { $short_file_path = $this->tmp_path . $short_file_path; } self::debug( 'deleting ' . $short_file_path ); // del webp $this->__media->info( $short_file_path . '.webp', $this->tmp_pid ) && $this->__media->del( $short_file_path . '.webp', $this->tmp_pid ); $this->__media->info( $short_file_path . '.optm.webp', $this->tmp_pid ) && $this->__media->del( $short_file_path . '.optm.webp', $this->tmp_pid ); // del avif $this->__media->info( $short_file_path . '.avif', $this->tmp_pid ) && $this->__media->del( $short_file_path . '.avif', $this->tmp_pid ); $this->__media->info( $short_file_path . '.optm.avif', $this->tmp_pid ) && $this->__media->del( $short_file_path . '.optm.avif', $this->tmp_pid ); $extension = pathinfo( $short_file_path, PATHINFO_EXTENSION ); $local_filename = substr( $short_file_path, 0, -strlen( $extension ) - 1 ); $bk_file = $local_filename . '.bk.' . $extension; $bk_optm_file = $local_filename . '.bk.optm.' . $extension; // del optimized ori if ( $this->__media->info( $bk_file, $this->tmp_pid ) ) { self::debug( 'deleting optim ori' ); $this->__media->del( $short_file_path, $this->tmp_pid ); $this->__media->rename( $bk_file, $short_file_path, $this->tmp_pid ); } $this->__media->info( $bk_optm_file, $this->tmp_pid ) && $this->__media->del( $bk_optm_file, $this->tmp_pid ); } /** * Rescan to find new generated images * * @since 1.6.7 * @access private */ private function _rescan() { // phpcs:ignore Squiz.PHP.NonExecutableCode exit( 'tobedone' ); // phpcs:disable Squiz.PHP.NonExecutableCode global $wpdb; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $offset = ! empty( $_GET['litespeed_i'] ) ? absint( wp_unslash( $_GET['litespeed_i'] ) ) : 0; $limit = 500; self::debug( 'rescan images' ); // Get images $q = "SELECT b.post_id, b.meta_value FROM `$wpdb->posts` a, `$wpdb->postmeta` b WHERE a.post_type = 'attachment' AND a.post_status = 'inherit' AND a.post_mime_type IN ('image/jpeg', 'image/png', 'image/gif') AND a.ID = b.post_id AND b.meta_key = '_wp_attachment_metadata' ORDER BY a.ID LIMIT %d, %d "; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $list = $wpdb->get_results( $wpdb->prepare( $q, $offset * $limit, $limit + 1 ) ); // last one is the seed for next batch if ( ! $list ) { $msg = __( 'Rescanned successfully.', 'litespeed-cache' ); Admin_Display::success( $msg ); self::debug( 'rescan bypass: no gathered image found' ); return; } if ( count( $list ) === $limit + 1 ) { $to_be_continued = true; array_pop( $list ); // last one is the seed for next round, discard here. } else { $to_be_continued = false; } // Prepare post_ids to inquery gathered images $pid_set = []; $scanned_list = []; foreach ( $list as $v ) { $meta_value = $this->_parse_wp_meta_value( $v ); if ( ! $meta_value ) { continue; } $scanned_list[] = [ 'pid' => $v->post_id, 'meta' => $meta_value, ]; $pid_set[] = $v->post_id; } // Build gathered images $q = "SELECT src, post_id FROM `$this->_table_img_optm` WHERE post_id IN (" . implode( ',', array_fill( 0, count( $pid_set ), '%d' ) ) . ')'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $list = $wpdb->get_results( $wpdb->prepare( $q, $pid_set ) ); foreach ( $list as $v ) { $this->_existed_src_list[] = $v->post_id . '.' . $v->src; } // Find new images foreach ( $scanned_list as $v ) { $meta_value = $v['meta']; // Parse all child src and put them into $this->_img_in_queue, missing ones to $this->_img_in_queue_missed $this->tmp_pid = $v['pid']; $this->tmp_path = pathinfo( $meta_value['file'], PATHINFO_DIRNAME ) . '/'; $this->_append_img_queue( $meta_value, true ); if ( ! empty( $meta_value['sizes'] ) ) { foreach ( $meta_value['sizes'] as $img_size_name => $img_size ) { $this->_append_img_queue( $img_size, false, $img_size_name ); } } } self::debug( 'rescanned [img] ' . count( $this->_img_in_queue ) ); $count = count( $this->_img_in_queue ); if ( $count > 0 ) { // Save to DB $this->_save_raw(); } if ( $to_be_continued ) { return Router::self_redirect( Router::ACTION_IMG_OPTM, self::TYPE_RESCAN ); } $msg = $count ? sprintf( __( 'Rescanned %d images successfully.', 'litespeed-cache' ), $count ) : __( 'Rescanned successfully.', 'litespeed-cache' ); Admin_Display::success( $msg ); // phpcs:enable Squiz.PHP.NonExecutableCode } /** * Calculate bkup original images storage * * @since 2.2.6 * @access private */ private function _calc_bkup() { global $wpdb; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $offset = ! empty( $_GET['litespeed_i'] ) ? absint( wp_unslash( $_GET['litespeed_i'] ) ) : 0; $limit = 500; if ( ! $offset ) { $this->_summary['bk_summary'] = [ 'date' => time(), 'count' => 0, 'sum' => 0, ]; } $img_q = "SELECT b.post_id, b.meta_value FROM `$wpdb->posts` a LEFT JOIN `$wpdb->postmeta` b ON b.post_id = a.ID WHERE b.meta_key = '_wp_attachment_metadata' AND a.post_type = 'attachment' AND a.post_status = 'inherit' AND a.post_mime_type IN ('image/jpeg', 'image/png', 'image/gif') ORDER BY a.ID LIMIT %d,%d "; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $q = $wpdb->prepare( $img_q, [ $offset * $limit, $limit ] ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $list = $wpdb->get_results( $q ); foreach ( $list as $v ) { if ( ! $v->post_id ) { continue; } $meta_value = $this->_parse_wp_meta_value( $v ); if ( ! $meta_value ) { continue; } $this->tmp_pid = $v->post_id; $this->tmp_path = pathinfo( $meta_value['file'], PATHINFO_DIRNAME ) . '/'; $this->_get_bk_size( $meta_value, true ); if ( ! empty( $meta_value['sizes'] ) ) { array_map( [ $this, '_get_bk_size' ], $meta_value['sizes'] ); } } $this->_summary['bk_summary']['date'] = time(); self::save_summary(); self::debug( '_calc_bkup total: ' . $this->_summary['bk_summary']['count'] . ' [size] ' . $this->_summary['bk_summary']['sum'] ); ++$offset; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $to_be_continued = $wpdb->get_row( $wpdb->prepare( $img_q, [ $offset * $limit, 1 ] ) ); if ( $to_be_continued ) { return Router::self_redirect( Router::ACTION_IMG_OPTM, self::TYPE_CALC_BKUP ); } $msg = __( 'Calculated backups successfully.', 'litespeed-cache' ); Admin_Display::success( $msg ); } /** * Calculate single size * * @since 2.2.6 * @access private * @param array $meta_value The meta value array containing file info. * @param bool $is_ori_file Whether this is the original file. */ private function _get_bk_size( $meta_value, $is_ori_file = false ) { $short_file_path = $meta_value['file']; if ( ! $is_ori_file ) { $short_file_path = $this->tmp_path . $short_file_path; } $extension = pathinfo( $short_file_path, PATHINFO_EXTENSION ); $local_filename = substr( $short_file_path, 0, -strlen( $extension ) - 1 ); $bk_file = $local_filename . '.bk.' . $extension; $img_info = $this->__media->info( $bk_file, $this->tmp_pid ); if ( ! $img_info ) { return; } ++$this->_summary['bk_summary']['count']; $this->_summary['bk_summary']['sum'] += $img_info['size']; } /** * Delete bkup original images storage * * @since 2.5 * @access public */ public function rm_bkup() { global $wpdb; if ( ! $this->__data->tb_exist( 'img_optming' ) ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended $offset = ! empty( $_GET['litespeed_i'] ) ? absint( wp_unslash( $_GET['litespeed_i'] ) ) : 0; $limit = 500; if ( empty( $this->_summary['rmbk_summary'] ) ) { $this->_summary['rmbk_summary'] = [ 'date' => time(), 'count' => 0, 'sum' => 0, ]; } $img_q = "SELECT b.post_id, b.meta_value FROM `$wpdb->posts` a LEFT JOIN `$wpdb->postmeta` b ON b.post_id = a.ID WHERE b.meta_key = '_wp_attachment_metadata' AND a.post_type = 'attachment' AND a.post_status = 'inherit' AND a.post_mime_type IN ('image/jpeg', 'image/png', 'image/gif') ORDER BY a.ID LIMIT %d,%d "; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $q = $wpdb->prepare( $img_q, [ $offset * $limit, $limit ] ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $list = $wpdb->get_results( $q ); foreach ( $list as $v ) { if ( ! $v->post_id ) { continue; } $meta_value = $this->_parse_wp_meta_value( $v ); if ( ! $meta_value ) { continue; } $this->tmp_pid = $v->post_id; $this->tmp_path = pathinfo( $meta_value['file'], PATHINFO_DIRNAME ) . '/'; $this->_del_bk_file( $meta_value, true ); if ( ! empty( $meta_value['sizes'] ) ) { array_map( [ $this, '_del_bk_file' ], $meta_value['sizes'] ); } } $this->_summary['rmbk_summary']['date'] = time(); self::save_summary(); self::debug( 'rm_bkup total: ' . $this->_summary['rmbk_summary']['count'] . ' [size] ' . $this->_summary['rmbk_summary']['sum'] ); ++$offset; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $to_be_continued = $wpdb->get_row( $wpdb->prepare( $img_q, [ $offset * $limit, 1 ] ) ); if ( $to_be_continued ) { return Router::self_redirect( Router::ACTION_IMG_OPTM, self::TYPE_RM_BKUP ); } $msg = __( 'Removed backups successfully.', 'litespeed-cache' ); Admin_Display::success( $msg ); } /** * Delete single file * * @since 2.5 * @access private * @param array $meta_value The meta value array containing file info. * @param bool $is_ori_file Whether this is the original file. */ private function _del_bk_file( $meta_value, $is_ori_file = false ) { $short_file_path = $meta_value['file']; if ( ! $is_ori_file ) { $short_file_path = $this->tmp_path . $short_file_path; } $extension = pathinfo( $short_file_path, PATHINFO_EXTENSION ); $local_filename = substr( $short_file_path, 0, -strlen( $extension ) - 1 ); $bk_file = $local_filename . '.bk.' . $extension; $img_info = $this->__media->info( $bk_file, $this->tmp_pid ); if ( ! $img_info ) { return; } ++$this->_summary['rmbk_summary']['count']; $this->_summary['rmbk_summary']['sum'] += $img_info['size']; $this->__media->del( $bk_file, $this->tmp_pid ); } /** * Count images * * @since 1.6 * @access public * @return array Image count data. */ public function img_count() { global $wpdb; $q = "SELECT count(*) FROM `$wpdb->posts` a LEFT JOIN `$wpdb->postmeta` b ON b.post_id = a.ID WHERE b.meta_key = '_wp_attachment_metadata' AND a.post_type = 'attachment' AND a.post_status = 'inherit' AND a.post_mime_type IN ('image/jpeg', 'image/png', 'image/gif') "; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $groups_all = $wpdb->get_var( $q ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $groups_new = $wpdb->get_var( $q . ' AND ID>' . (int) $this->_summary['next_post_id'] . ' ORDER BY ID' ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $groups_done = $wpdb->get_var( $q . ' AND ID<=' . (int) $this->_summary['next_post_id'] . ' ORDER BY ID' ); $q = "SELECT b.post_id FROM `$wpdb->posts` a LEFT JOIN `$wpdb->postmeta` b ON b.post_id = a.ID WHERE b.meta_key = '_wp_attachment_metadata' AND a.post_type = 'attachment' AND a.post_status = 'inherit' AND a.post_mime_type IN ('image/jpeg', 'image/png', 'image/gif') ORDER BY a.ID DESC LIMIT 1 "; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $max_id = $wpdb->get_var( $q ); $count_list = [ 'max_id' => $max_id, 'groups_all' => $groups_all, 'groups_new' => $groups_new, 'groups_done' => $groups_done, ]; // images count from work table if ( $this->__data->tb_exist( 'img_optming' ) ) { $q = "SELECT COUNT(DISTINCT post_id),COUNT(*) FROM `$this->_table_img_optming` WHERE optm_status = %d"; $groups_to_check = [ self::STATUS_RAW, self::STATUS_REQUESTED, self::STATUS_NOTIFIED, self::STATUS_ERR_FETCH ]; foreach ( $groups_to_check as $v ) { $count_list[ 'img.' . $v ] = 0; $count_list[ 'group.' . $v ] = 0; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared list( $count_list[ 'group.' . $v ], $count_list[ 'img.' . $v ] ) = $wpdb->get_row( $wpdb->prepare( $q, $v ), ARRAY_N ); } } return $count_list; } /** * Check if fetch cron is running * * @since 1.6.2 * @access public * @param bool $bool_res Whether to return boolean result. * @return bool|array Boolean result or array with last run time and status. */ public function cron_running( $bool_res = true ) { $last_run = ! empty( $this->_summary['last_pull'] ) ? $this->_summary['last_pull'] : 0; $is_running = $last_run && time() - $last_run < 120; if ( $bool_res ) { return $is_running; } return [ $last_run, $is_running ]; } /** * Update fetch cron timestamp tag * * @since 1.6.2 * @access private * @param bool $done Whether the cron job is done. */ private function _update_cron_running( $done = false ) { $this->_summary['last_pull'] = time(); if ( $done ) { // Only update cron tag when its from the active running cron if ( $this->_cron_ran ) { // Rollback for next running $this->_summary['last_pull'] -= 120; } else { return; } } self::save_summary(); $this->_cron_ran = true; } /** * Batch switch images to ori/optm version * * @since 1.6.2 * @access public * @param string $type The switch type (batch_switch_ori or batch_switch_optm). */ public function batch_switch( $type ) { if ( defined( 'LITESPEED_CLI' ) || wp_doing_cron() ) { $offset = 0; while ( 'done' !== $offset ) { Admin_Display::info( "Starting switch to $type [offset] $offset" ); $offset = $this->_batch_switch( $type, $offset ); } } else { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $offset = ! empty( $_GET['litespeed_i'] ) ? absint( wp_unslash( $_GET['litespeed_i'] ) ) : 0; $new_offset = $this->_batch_switch( $type, $offset ); if ( 'done' !== $new_offset ) { return Router::self_redirect( Router::ACTION_IMG_OPTM, $type ); } } $msg = __( 'Switched images successfully.', 'litespeed-cache' ); Admin_Display::success( $msg ); } /** * Switch images per offset * * @since 1.6.2 * @access private * @param string $type The switch type. * @param int $offset The current offset. * @return int|string Next offset or 'done'. */ private function _batch_switch( $type, $offset ) { global $wpdb; $limit = 500; $this->tmp_type = $type; $img_q = "SELECT b.post_id, b.meta_value FROM `$wpdb->posts` a LEFT JOIN `$wpdb->postmeta` b ON b.post_id = a.ID WHERE b.meta_key = '_wp_attachment_metadata' AND a.post_type = 'attachment' AND a.post_status = 'inherit' AND a.post_mime_type IN ('image/jpeg', 'image/png', 'image/gif') ORDER BY a.ID LIMIT %d,%d "; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $q = $wpdb->prepare( $img_q, [ $offset * $limit, $limit ] ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $list = $wpdb->get_results( $q ); $i = 0; foreach ( $list as $v ) { if ( ! $v->post_id ) { continue; } $meta_value = $this->_parse_wp_meta_value( $v ); if ( ! $meta_value ) { continue; } ++$i; $this->tmp_pid = $v->post_id; $this->tmp_path = pathinfo( $meta_value['file'], PATHINFO_DIRNAME ) . '/'; $this->_switch_bk_file( $meta_value, true ); if ( ! empty( $meta_value['sizes'] ) ) { array_map( [ $this, '_switch_bk_file' ], $meta_value['sizes'] ); } } self::debug( 'batch switched images total: ' . $i . ' [type] ' . $type ); ++$offset; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $to_be_continued = $wpdb->get_row( $wpdb->prepare( $img_q, [ $offset * $limit, 1 ] ) ); if ( $to_be_continued ) { return $offset; } return 'done'; } /** * Switch backup file between original and optimized * * @since 1.6.2 * @access private * @param array $meta_value The meta value array containing file info. * @param bool $is_ori_file Whether this is the original file. */ private function _switch_bk_file( $meta_value, $is_ori_file = false ) { $short_file_path = $meta_value['file']; if ( ! $is_ori_file ) { $short_file_path = $this->tmp_path . $short_file_path; } $extension = pathinfo( $short_file_path, PATHINFO_EXTENSION ); $local_filename = substr( $short_file_path, 0, -strlen( $extension ) - 1 ); $bk_file = $local_filename . '.bk.' . $extension; $bk_optm_file = $local_filename . '.bk.optm.' . $extension; // self::debug('_switch_bk_file ' . $bk_file . ' [type] ' . $this->tmp_type); // switch to ori if ( self::TYPE_BATCH_SWITCH_ORI === $this->tmp_type || 'orig' === $this->tmp_type ) { // self::debug('switch to orig ' . $bk_file); if ( ! $this->__media->info( $bk_file, $this->tmp_pid ) ) { return; } $this->__media->rename( $local_filename . '.' . $extension, $bk_optm_file, $this->tmp_pid ); $this->__media->rename( $bk_file, $local_filename . '.' . $extension, $this->tmp_pid ); } elseif ( self::TYPE_BATCH_SWITCH_OPTM === $this->tmp_type || 'optm' === $this->tmp_type ) { // switch to optm // self::debug('switch to optm ' . $bk_file); if ( ! $this->__media->info( $bk_optm_file, $this->tmp_pid ) ) { return; } $this->__media->rename( $local_filename . '.' . $extension, $bk_file, $this->tmp_pid ); $this->__media->rename( $bk_optm_file, $local_filename . '.' . $extension, $this->tmp_pid ); } } /** * Switch image between original one and optimized one * * @since 1.6.2 * @access private * @param string $type The switch type (webpXXX, avifXXX, or origXXX where XXX is the post ID). */ private function _switch_optm_file( $type ) { Admin_Display::success( __( 'Switched to optimized file successfully.', 'litespeed-cache' ) ); return; // phpcs:disable Squiz.PHP.NonExecutableCode global $wpdb; $pid = substr( $type, 4 ); $switch_type = substr( $type, 0, 4 ); $q = "SELECT src,post_id FROM `$this->_table_img_optm` WHERE post_id = %d AND optm_status = %d"; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $list = $wpdb->get_results( $wpdb->prepare( $q, [ $pid, self::STATUS_PULLED ] ) ); $msg = 'Unknown Msg'; foreach ( $list as $v ) { // to switch webp file if ( 'webp' === $switch_type ) { if ( $this->__media->info( $v->src . '.webp', $v->post_id ) ) { $this->__media->rename( $v->src . '.webp', $v->src . '.optm.webp', $v->post_id ); self::debug( 'Disabled WebP: ' . $v->src ); $msg = __( 'Disabled WebP file successfully.', 'litespeed-cache' ); } elseif ( $this->__media->info( $v->src . '.optm.webp', $v->post_id ) ) { $this->__media->rename( $v->src . '.optm.webp', $v->src . '.webp', $v->post_id ); self::debug( 'Enable WebP: ' . $v->src ); $msg = __( 'Enabled WebP file successfully.', 'litespeed-cache' ); } } elseif ( 'avif' === $switch_type ) { // to switch avif file if ( $this->__media->info( $v->src . '.avif', $v->post_id ) ) { $this->__media->rename( $v->src . '.avif', $v->src . '.optm.avif', $v->post_id ); self::debug( 'Disabled AVIF: ' . $v->src ); $msg = __( 'Disabled AVIF file successfully.', 'litespeed-cache' ); } elseif ( $this->__media->info( $v->src . '.optm.avif', $v->post_id ) ) { $this->__media->rename( $v->src . '.optm.avif', $v->src . '.avif', $v->post_id ); self::debug( 'Enable AVIF: ' . $v->src ); $msg = __( 'Enabled AVIF file successfully.', 'litespeed-cache' ); } } else { // to switch original file $extension = pathinfo( $v->src, PATHINFO_EXTENSION ); $local_filename = substr( $v->src, 0, -strlen( $extension ) - 1 ); $bk_file = $local_filename . '.bk.' . $extension; $bk_optm_file = $local_filename . '.bk.optm.' . $extension; // revert ori back if ( $this->__media->info( $bk_file, $v->post_id ) ) { $this->__media->rename( $v->src, $bk_optm_file, $v->post_id ); $this->__media->rename( $bk_file, $v->src, $v->post_id ); self::debug( 'Restore original img: ' . $bk_file ); $msg = __( 'Restored original file successfully.', 'litespeed-cache' ); } elseif ( $this->__media->info( $bk_optm_file, $v->post_id ) ) { $this->__media->rename( $v->src, $bk_file, $v->post_id ); $this->__media->rename( $bk_optm_file, $v->src, $v->post_id ); self::debug( 'Switch to optm img: ' . $v->src ); $msg = __( 'Switched to optimized file successfully.', 'litespeed-cache' ); } } } Admin_Display::success( $msg ); // phpcs:enable Squiz.PHP.NonExecutableCode } /** * Delete one optm data and recover original file * * @since 2.4.2 * @access public * @param int $post_id The post ID to reset. * @param bool $silent Whether to suppress success message. Default false. */ public function reset_row( $post_id, $silent = false ) { global $wpdb; if ( ! $post_id ) { return; } self::debug( '_reset_row [pid] ' . $post_id ); // TODO: Load image sub files $img_q = "SELECT b.post_id, b.meta_value FROM `$wpdb->postmeta` b WHERE b.post_id =%d AND b.meta_key = '_wp_attachment_metadata'"; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $q = $wpdb->prepare( $img_q, [ $post_id ] ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $v = $wpdb->get_row( $q ); $meta_value = $this->_parse_wp_meta_value( $v ); if ( $meta_value ) { $this->tmp_pid = $v->post_id; $this->tmp_path = pathinfo( $meta_value['file'], PATHINFO_DIRNAME ) . '/'; $this->_destroy_optm_file( $meta_value, true ); if ( ! empty( $meta_value['sizes'] ) ) { array_map( [ $this, '_destroy_optm_file' ], $meta_value['sizes'] ); } } delete_post_meta( $post_id, self::DB_SIZE ); delete_post_meta( $post_id, self::DB_SET ); // Delete records from img_optm and img_optming tables if ( $this->__data->tb_exist( 'img_optm' ) ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $wpdb->query( $wpdb->prepare( "DELETE FROM `$this->_table_img_optm` WHERE post_id = %d", $post_id ) ); } if ( $this->__data->tb_exist( 'img_optming' ) ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $wpdb->query( $wpdb->prepare( "DELETE FROM `$this->_table_img_optming` WHERE post_id = %d", $post_id ) ); } if ( ! $silent ) { $msg = __( 'Reset the optimized data successfully.', 'litespeed-cache' ); Admin_Display::success( $msg ); } } /** * Show an image's optm status * * @since 1.6.5 * @access public * @return array Response data with image info. */ public function check_img() { global $wpdb; // phpcs:ignore WordPress.Security.NonceVerification.Missing $pid = isset( $_POST['data'] ) ? absint( wp_unslash( $_POST['data'] ) ) : 0; self::debug( 'Check image [ID] ' . $pid ); $data = []; $data['img_count'] = $this->img_count(); $data['optm_summary'] = self::get_summary(); $data['_wp_attached_file'] = get_post_meta( $pid, '_wp_attached_file', true ); $data['_wp_attachment_metadata'] = get_post_meta( $pid, '_wp_attachment_metadata', true ); // Get img_optm data $q = "SELECT * FROM `$this->_table_img_optm` WHERE post_id = %d"; // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared $list = $wpdb->get_results( $wpdb->prepare( $q, $pid ) ); $img_data = []; if ( $list ) { foreach ( $list as $v ) { $img_data[] = [ 'id' => $v->id, 'optm_status' => $v->optm_status, 'src' => $v->src, 'srcpath_md5' => $v->srcpath_md5, 'src_md5' => $v->src_md5, 'server_info' => $v->server_info, ]; } } $data['img_data'] = $img_data; return [ '_res' => 'ok', 'data' => $data, ]; } }
Upload File
Create Folder