compatibility
5 months ago
config
5 months ago
css
5 months ago
data
3 years ago
images
3 years ago
js
5 months ago
vendor
4 months ago
views
2 months ago
class-tiny-apache-rewrite.php
2 months ago
class-tiny-bulk-optimization.php
5 months ago
class-tiny-cli.php
5 months ago
class-tiny-compress-client.php
5 months ago
class-tiny-compress-fopen.php
5 months ago
class-tiny-compress.php
5 months ago
class-tiny-conversion.php
2 months ago
class-tiny-diagnostics.php
5 months ago
class-tiny-exception.php
5 months ago
class-tiny-helpers.php
5 months ago
class-tiny-image-size.php
5 months ago
class-tiny-image.php
5 months ago
class-tiny-logger.php
2 months ago
class-tiny-notices.php
2 months ago
class-tiny-php.php
5 months ago
class-tiny-picture.php
4 months ago
class-tiny-plugin.php
2 months ago
class-tiny-settings.php
2 months ago
class-tiny-source-base.php
2 months ago
class-tiny-source-image.php
5 months ago
class-tiny-source-picture.php
5 months ago
class-tiny-wp-base.php
5 months ago
class-tiny-bulk-optimization.php
159 lines
| 1 | <?php |
| 2 | /* |
| 3 | * Tiny Compress Images - WordPress plugin. |
| 4 | * Copyright (C) 2015-2018 Tinify B.V. |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms of the GNU General Public License as published by the Free |
| 8 | * Software Foundation; either version 2 of the License, or (at your option) |
| 9 | * any later version. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, but WITHOUT |
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 14 | * more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License along |
| 17 | * with this program; if not, write to the Free Software Foundation, Inc., 51 |
| 18 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 19 | */ |
| 20 | |
| 21 | class Tiny_Bulk_Optimization { |
| 22 | // Page the retrieved database results for memory purposes |
| 23 | // in case the media library is extremely big. |
| 24 | const PAGING_SIZE = 25000; |
| 25 | |
| 26 | public static function get_optimization_statistics( $settings, $result = null ) { |
| 27 | $stats = array(); |
| 28 | $stats['uploaded-images'] = 0; |
| 29 | $stats['optimized-image-sizes'] = 0; |
| 30 | $stats['available-unoptimized-sizes'] = 0; |
| 31 | $stats['optimized-library-size'] = 0; |
| 32 | $stats['unoptimized-library-size'] = 0; |
| 33 | $stats['estimated_credit_use'] = 0; |
| 34 | $stats['available-for-optimization'] = array(); |
| 35 | |
| 36 | if ( is_null( $result ) ) { |
| 37 | $last_image_id = null; |
| 38 | do { |
| 39 | $result = self::wpdb_retrieve_images_and_metadata( $last_image_id ); |
| 40 | $stats = self::populate_optimization_statistics( $settings, $result, $stats ); |
| 41 | $last_image = end( $result ); |
| 42 | if ( isset( $last_image['ID'] ) ) { |
| 43 | $last_image_id = $last_image['ID']; |
| 44 | } |
| 45 | } while ( sizeof( $result ) == self::PAGING_SIZE ); |
| 46 | } else { |
| 47 | $stats = self::populate_optimization_statistics( $settings, $result, $stats ); |
| 48 | } |
| 49 | unset( $result ); |
| 50 | |
| 51 | if ( 0 != $stats['unoptimized-library-size'] ) { |
| 52 | $stats['display-percentage'] = round( |
| 53 | 100 - |
| 54 | ( $stats['optimized-library-size'] / $stats['unoptimized-library-size'] * 100 ), |
| 55 | 1 |
| 56 | ); |
| 57 | } else { |
| 58 | $stats['display-percentage'] = 0; |
| 59 | } |
| 60 | return $stats; |
| 61 | } |
| 62 | |
| 63 | private static function wpdb_retrieve_images_and_metadata( $start_id ) { |
| 64 | global $wpdb; |
| 65 | |
| 66 | // Retrieve posts that have "_wp_attachment_metadata" image metadata |
| 67 | // and optionally contain "tiny_compress_images" metadata. |
| 68 | $sql_start_id = ( $start_id ? " $wpdb->posts.ID < $start_id AND " : '' ); |
| 69 | $query = |
| 70 | "SELECT |
| 71 | $wpdb->posts.ID, |
| 72 | $wpdb->posts.post_title, |
| 73 | $wpdb->postmeta.meta_value, |
| 74 | wp_postmeta_file.meta_value AS unique_attachment_name, |
| 75 | wp_postmeta_tiny.meta_value AS tiny_meta_value |
| 76 | FROM $wpdb->posts |
| 77 | LEFT JOIN $wpdb->postmeta |
| 78 | ON $wpdb->posts.ID = $wpdb->postmeta.post_id |
| 79 | LEFT JOIN $wpdb->postmeta AS wp_postmeta_file |
| 80 | ON $wpdb->posts.ID = wp_postmeta_file.post_id |
| 81 | AND wp_postmeta_file.meta_key = '_wp_attached_file' |
| 82 | LEFT JOIN $wpdb->postmeta AS wp_postmeta_tiny |
| 83 | ON $wpdb->posts.ID = wp_postmeta_tiny.post_id |
| 84 | AND wp_postmeta_tiny.meta_key = '" . Tiny_Config::META_KEY . "' |
| 85 | WHERE |
| 86 | $sql_start_id |
| 87 | $wpdb->posts.post_type = 'attachment' |
| 88 | AND ( |
| 89 | $wpdb->posts.post_mime_type = 'image/jpeg' OR |
| 90 | $wpdb->posts.post_mime_type = 'image/png' OR |
| 91 | $wpdb->posts.post_mime_type = 'image/webp' |
| 92 | ) |
| 93 | AND $wpdb->postmeta.meta_key = '_wp_attachment_metadata' |
| 94 | GROUP BY unique_attachment_name |
| 95 | ORDER BY ID DESC |
| 96 | LIMIT " . self::PAGING_SIZE; |
| 97 | |
| 98 | // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Query is built from internal IDs and constants only. |
| 99 | return $wpdb->get_results( $query, ARRAY_A ); |
| 100 | } |
| 101 | |
| 102 | private static function populate_optimization_statistics( $settings, $result, $stats ) { |
| 103 | $active_sizes = $settings->get_sizes(); |
| 104 | $active_tinify_sizes = $settings->get_active_tinify_sizes(); |
| 105 | $conversion_enabled = $settings->get_conversion_enabled(); |
| 106 | |
| 107 | for ( $i = 0; $i < sizeof( $result ); $i++ ) { |
| 108 | $wp_metadata = unserialize( (string) $result[ $i ]['meta_value'] ); |
| 109 | $tiny_metadata = isset( $result[ $i ]['tiny_meta_value'] ) ? |
| 110 | unserialize( (string) $result[ $i ]['tiny_meta_value'] ) : |
| 111 | array(); |
| 112 | if ( ! is_array( $tiny_metadata ) ) { |
| 113 | $tiny_metadata = array(); |
| 114 | } |
| 115 | $tiny_image = new Tiny_Image( |
| 116 | $settings, |
| 117 | $result[ $i ]['ID'], |
| 118 | $wp_metadata, |
| 119 | $tiny_metadata, |
| 120 | $active_sizes, |
| 121 | $active_tinify_sizes |
| 122 | ); |
| 123 | $image_stats = $tiny_image->get_statistics( $active_sizes, $active_tinify_sizes ); |
| 124 | |
| 125 | ++$stats['uploaded-images']; |
| 126 | $stats['estimated_credit_use'] += $image_stats['available_uncompressed_sizes']; |
| 127 | if ( $conversion_enabled ) { |
| 128 | $stats['available-unoptimized-sizes'] += |
| 129 | $image_stats['available_unconverted_sizes']; |
| 130 | $stats['optimized-image-sizes'] += |
| 131 | $image_stats['image_sizes_converted']; |
| 132 | $stats['estimated_credit_use'] += |
| 133 | $image_stats['available_unconverted_sizes']; |
| 134 | } else { |
| 135 | $stats['available-unoptimized-sizes'] += |
| 136 | $image_stats['available_uncompressed_sizes']; |
| 137 | $stats['optimized-image-sizes'] += |
| 138 | $image_stats['image_sizes_compressed']; |
| 139 | } |
| 140 | $stats['optimized-library-size'] += $image_stats['compressed_total_size']; |
| 141 | $stats['unoptimized-library-size'] += $image_stats['initial_total_size']; |
| 142 | |
| 143 | $has_conversions = $image_stats['available_unconverted_sizes'] > 0; |
| 144 | $has_compressions = $image_stats['available_uncompressed_sizes'] > 0; |
| 145 | $has_optimizations = $has_compressions || ( |
| 146 | $conversion_enabled && $has_conversions |
| 147 | ); |
| 148 | if ( $has_optimizations ) { |
| 149 | $stats['available-for-optimization'][] = array( |
| 150 | 'ID' => $result[ $i ]['ID'], |
| 151 | 'post_title' => $result[ $i ]['post_title'], |
| 152 | ); |
| 153 | } |
| 154 | }// End for(). |
| 155 | |
| 156 | return $stats; |
| 157 | } |
| 158 | } |
| 159 |