PluginProbe ʕ •ᴥ•ʔ
Gallery : FooGallery / 3.3.0
Gallery : FooGallery v3.3.0
3.3.0 3.1.31 3.1.32 3.1.34 3.1.36 3.2.0 3.2.6 trunk 1.10.3 2.0.24 2.1.34 2.2.44 2.3.3 2.4.32 3.0.6 3.1.11 3.1.12 3.1.13 3.1.20 3.1.25 3.1.26 3.1.26.1 3.1.26.2
foogallery / includes / class-thumbnails.php
foogallery / includes Last commit date
abilities 1 week ago admin 1 week ago compatibility 1 week ago extensions 1 week ago foopluginbase 1 week ago public 1 week ago thumbs 1 week ago asset-manifest.php 1 week ago class-attachment-filters.php 1 week ago class-command-palette.php 1 week ago class-foogallery-animated-gif-support.php 1 week ago class-foogallery-attachment-custom-class.php 1 week ago class-foogallery-attachment-filename.php 1 week ago class-foogallery-attachment-type.php 1 week ago class-foogallery-attachment.php 1 week ago class-foogallery-cache.php 1 week ago class-foogallery-common-fields.php 1 week ago class-foogallery-crop-position.php 1 week ago class-foogallery-datasource-media_library.php 1 week ago class-foogallery-debug.php 1 week ago class-foogallery-delayed-runtime-loader.php 1 week ago class-foogallery-extensions-compatibility.php 1 week ago class-foogallery-force-https.php 1 week ago class-foogallery-lazyload.php 1 week ago class-foogallery-license-constant-handler.php 1 week ago class-foogallery-lightbox.php 1 week ago class-foogallery-no-javascript-fallback.php 1 week ago class-foogallery-paging.php 1 week ago class-foogallery-password-protect.php 1 week ago class-foogallery-sitemaps.php 1 week ago class-foogallery-widget.php 1 week ago class-foogallery.php 1 week ago class-gallery-advanced-settings.php 1 week ago class-il8n.php 1 week ago class-override-thumbnail.php 1 week ago class-posttypes.php 1 week ago class-previews.php 1 week ago class-retina.php 1 week ago class-thumbnail-dimensions.php 1 week ago class-thumbnails.php 1 week ago class-version-check.php 1 week ago constants.php 1 week ago functions.php 1 week ago gallery-management-functions.php 1 week ago includes.php 1 week ago index.php 1 week ago render-functions.php 1 week ago
class-thumbnails.php
364 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 /*
8 * FooGallery Thumbnail Resizing class
9 */
10
11 if ( !class_exists( 'FooGallery_Thumbnails' ) ) {
12
13 class FooGallery_Thumbnails {
14
15 function __construct() {
16 add_filter( 'foogallery_attachment_resize_thumbnail', array( $this, 'resize' ), 10, 3 );
17
18 add_filter( 'foogallery_test_thumb_url', array( $this, 'override_test_thumb_url' ) );
19
20 add_filter( 'foogallery_thumbnail_resize_args', array( $this, 'check_for_force_original_thumb') );
21 }
22
23 function check_for_force_original_thumb( $args ){
24 global $current_foogallery;
25
26 if ( isset( $current_foogallery ) ) {
27 $args['force_use_original_thumb'] = $current_foogallery->force_use_original_thumbs;
28 }
29
30 return $args;
31 }
32
33 function resize( $original_image_src, $args, $thumbnail_object ) {
34 global $current_foogallery;
35 global $foogallery_last_generated_thumb_url;
36
37 $arg_defaults = array(
38 'width' => 0,
39 'height' => 0,
40 'crop' => true,
41 'jpeg_quality' => foogallery_thumbnail_jpeg_quality(),
42 'thumb_resize_animations' => true,
43 'foogallery_attachment_id'=> $thumbnail_object->ID
44 );
45
46 if ( isset( $current_foogallery ) ) {
47 $arg_defaults['foogallery_id'] = $current_foogallery->ID;
48 }
49
50 $args = wp_parse_args( $args, $arg_defaults );
51
52 //allow for plugins to change the thumbnail creation args
53 $args = apply_filters( 'foogallery_thumbnail_resize_args', $args, $original_image_src, $thumbnail_object );
54
55 //check the current arguments passed in by the shortcode
56 global $current_foogallery_arguments;
57 if ( isset( $current_foogallery_arguments ) && isset( $current_foogallery_arguments['template'] ) ) {
58 $thumbnail_args = apply_filters( 'foogallery_calculate_thumbnail_dimensions-' . $current_foogallery_arguments['template'], $args, $current_foogallery_arguments );
59 $args = wp_parse_args( $thumbnail_args, $args );
60 }
61
62 //allow for plugins to change the thumbnail creation args one final time
63 $args = apply_filters( 'foogallery_thumbnail_resize_args_final', $args, $original_image_src, $thumbnail_object );
64 $requires_image_processing = ! empty( $args['watermark_options'] );
65
66 $width = (int)$args['width'];
67 $height = (int)$args['height'];
68 $crop = (bool)$args['crop'];
69
70 if ( 0 === $width && 0 === $height && ! $requires_image_processing ) {
71 return $original_image_src;
72 }
73
74 //we can force the use of the originally uploaded full-size image
75 $force_use_original_image = isset( $args['force_use_original_image'] ) && true === $args['force_use_original_image'];
76
77 if ( ! $requires_image_processing && $thumbnail_object->ID > 0 && $force_use_original_image ) {
78 $fullsize = wp_get_attachment_image_src( $thumbnail_object->ID, 'fullsize' );
79
80 return $fullsize[0];
81 }
82
83 //we can force the use of the original WP icon or WP-generated thumb by passing through args individually
84 $force_use_original_thumb = isset( $args['force_use_original_thumb'] ) && true === $args['force_use_original_thumb'];
85
86 if ( ! $requires_image_processing && $thumbnail_object->ID > 0 && $force_use_original_thumb ) {
87 $thumbnail_icon = wp_get_attachment_image_src( $thumbnail_object->ID, array( $width, $height ) );
88
89 return $thumbnail_icon[0];
90 }
91
92 //we can force the use of original WP thumbs by passing through args individually, or by saved settings
93 $use_original_thumbs = ( isset( $args['use_original_thumbs'] ) && true === $args['use_original_thumbs'] ) || 'on' === foogallery_get_setting( 'use_original_thumbs' );
94
95 if ( ! $requires_image_processing && $use_original_thumbs ) {
96
97 $option_thumbnail_size_w = get_option( 'thumbnail_size_w' );
98 $option_thumbnail_size_h = get_option( 'thumbnail_size_h' );
99 $option_thumbnail_crop = get_option( 'thumbnail_crop' );
100
101 //check if we are trying to get back the default thumbnail that we already have
102 if ( $thumbnail_object->ID > 0 && $width == $option_thumbnail_size_w && $height == $option_thumbnail_size_h && $crop == $option_thumbnail_crop ) {
103 $thumbnail_attributes = wp_get_attachment_image_src( $thumbnail_object->ID );
104
105 return $thumbnail_attributes[0];
106 }
107 }
108
109 //remove invalid resize args
110 if ( array_key_exists( 'height', $args ) && 0 === $args['height'] ) {
111 unset( $args['height'] );
112 }
113
114 $force_resize = false;
115
116 //only worry about upscaling if we have supplied both a width and height for cropping
117 if ( array_key_exists( 'height', $args ) && $args['height'] > 0 &&
118 array_key_exists( 'width', $args ) && $args['width'] > 0 ) {
119 //check if we must upscale smaller images
120 if ( 'on' === foogallery_get_setting( 'thumb_resize_upscale_small' ) ) {
121 $force_resize = true;
122 if ( !isset( $args['background_fill'] ) ) {
123 $color = foogallery_get_setting( 'thumb_resize_upscale_small_color', '' );
124 if ( $color !== 'auto' && $color !== 'transparent' ) {
125 $colors = foogallery_rgb_to_color_array( $color );
126 $color = sprintf( "%03d%03d%03d000", $colors[0], $colors[1], $colors[2] );
127 }
128 $args['background_fill'] = $color;
129 }
130 }
131 }
132
133 //do some checks to see if the image is smaller
134 if ( $requires_image_processing || $force_resize || $this->should_resize( $thumbnail_object, $args ) ) {
135 /**
136 * Filters the source URL immediately before the active thumbnail engine runs.
137 *
138 * @param string $original_image_src Original image source URL.
139 * @param array $args Final thumbnail generation arguments.
140 * @param FooGalleryAttachment $thumbnail_object Current attachment.
141 */
142 $thumbnail_source = apply_filters( 'foogallery_thumbnail_resize_source', $original_image_src, $args, $thumbnail_object );
143
144 //save the generated thumb url to a global so that we can use it later if needed
145 $foogallery_last_generated_thumb_url = foogallery_thumb( $thumbnail_source, $args );
146 } else {
147 $foogallery_last_generated_thumb_url = apply_filters('foogallery_thumbnail_resize_small_image', $original_image_src, $args );
148 }
149
150 return $foogallery_last_generated_thumb_url;
151 }
152
153 function should_resize($thumbnail_object, $args) {
154 $original_width = $thumbnail_object->width;
155 $original_height = $thumbnail_object->height;
156
157 if ( $original_width === $original_height && $original_height === 0 ) {
158 //we do not have the original dimensions, so assume we must resize!
159 return true;
160 }
161
162 $new_width = isset( $args['width'] ) ? $args['width'] : 0;
163 $new_height = isset( $args['height'] ) ? $args['height'] : 0;
164
165 if ( $new_width > 0 && $new_height > 0 ) {
166 return $original_width > $new_width || $original_height > $new_height;
167 } else if ( $new_width > 0 ) {
168 return $original_width > $new_width;
169 }
170 return $original_height > $new_height;
171 }
172
173 function run_thumbnail_generation_tests() {
174 if ( !foogallery_thumb_active_engine()->requires_thumbnail_generation_tests() ) {
175 return array(
176 'success' => true
177 );
178 }
179
180 $test_image_url = foogallery_test_thumb_url();
181
182 //next, generate a thumbnail
183 $test_args = array(
184 'width' => 20,
185 'height' => 20,
186 'crop' => true,
187 'jpeg_quality' => foogallery_thumbnail_jpeg_quality()
188 );
189
190 //first, clear any previous cached files
191 $engine = foogallery_thumb_active_engine();
192 $engine->clear_local_cache_for_file( $test_image_url );
193
194 $generated_thumb = $engine->generate( $test_image_url, $test_args );
195
196 $success = $test_image_url !== $generated_thumb;
197 $file_info = wp_check_filetype( $test_image_url );
198
199 $test_results = array(
200 'success' => $success,
201 'thumb' => $generated_thumb,
202 'error' => $engine->get_last_error(),
203 'file_info' => $file_info
204 );
205
206 do_action( 'foogallery_thumbnail_generation_test', $test_results );
207
208 return $test_results;
209 }
210
211 function override_test_thumb_url( $test_thumb_url ) {
212 if ( 'on' !== foogallery_get_setting( 'override_thumb_test', false ) ) {
213 $image_url = $this->find_first_image_in_media_library();
214
215 if ( $image_url !== false ) {
216 return $image_url;
217 }
218 }
219
220 //if we get here, then either, we have set the override_thumb_test setting,
221 //or there are no good images to use from the media library
222 return $test_thumb_url;
223 }
224
225 /**
226 * Finds a suitable image in the Media Library for thumbnail test pages.
227 *
228 * @param int $min_width Minimum image width.
229 * @param int $min_height Minimum image height.
230 * @param int[] $excluded_attachment_ids Attachment IDs that must not be selected.
231 * @param array $excluded_image_urls Image URLs that must not be selected.
232 * @return string|false Image URL, or false when no suitable image exists.
233 */
234 public static function find_first_image_in_media_library( $min_width = 50, $min_height = 50, $excluded_attachment_ids = array(), $excluded_image_urls = array() ) {
235 static $cached = array();
236
237 $min_width = absint( $min_width );
238 $min_height = absint( $min_height );
239 $excluded_attachment_ids = array_values( array_filter( array_map( 'absint', (array) $excluded_attachment_ids ) ) );
240 $excluded_image_urls = array_values( array_filter( array_map( 'trim', (array) $excluded_image_urls ) ) );
241 $cache_key = $min_width . 'x' . $min_height . ':' . wp_json_encode( array( $excluded_attachment_ids, $excluded_image_urls ) );
242 $excluded_image_paths = array();
243 foreach ( $excluded_image_urls as $excluded_image_url ) {
244 $excluded_image_path = wp_parse_url( $excluded_image_url, PHP_URL_PATH );
245 if ( ! empty( $excluded_image_path ) ) {
246 $excluded_image_paths[] = rawurldecode( $excluded_image_path );
247 }
248 }
249
250 if ( array_key_exists( $cache_key, $cached ) ) {
251 return $cached[ $cache_key ];
252 }
253
254 // Try a small set of recent images with minimal query overhead.
255 $args = array(
256 'post_type' => 'attachment',
257 'post_mime_type' => 'image',
258 'post_status' => 'inherit',
259 'posts_per_page' => 25,
260 'orderby' => 'date',
261 'order' => 'DESC',
262 'fields' => 'ids',
263 'no_found_rows' => true,
264 'update_post_meta_cache' => false,
265 'update_post_term_cache' => false,
266 );
267 if ( ! empty( $excluded_attachment_ids ) ) {
268 $args['post__not_in'] = $excluded_attachment_ids;
269 }
270
271 $query_images = new WP_Query( $args );
272 if ( empty( $query_images->posts ) ) {
273 $cached[ $cache_key ] = false;
274 return $cached[ $cache_key ];
275 }
276 foreach ( $query_images->posts as $image_id ) {
277 $local_path = get_attached_file( $image_id );
278 $image_url = wp_get_attachment_url( $image_id );
279 $image_path = is_string( $image_url ) ? wp_parse_url( $image_url, PHP_URL_PATH ) : '';
280
281 if ( empty( $image_url )
282 || ( ! empty( $image_path ) && in_array( rawurldecode( $image_path ), $excluded_image_paths, true ) )
283 || ! self::image_meets_minimum_test_dimensions( $image_id, $local_path, $min_width, $min_height ) ) {
284 continue;
285 }
286
287 if ( $local_path && file_exists( $local_path ) ) {
288 $cached[ $cache_key ] = $image_url;
289 return $cached[ $cache_key ];
290 }
291
292 if ( ! empty( $image_url ) ) {
293 if ( self::image_file_exists( $image_url ) || self::image_file_exists( $image_url, true ) ) {
294 $cached[ $cache_key ] = $image_url;
295 return $cached[ $cache_key ];
296 }
297 }
298 }
299
300 $cached[ $cache_key ] = false;
301 return $cached[ $cache_key ];
302 }
303
304 /**
305 * Checks whether an attachment is large enough to be useful for test pages.
306 *
307 * @param int $image_id Attachment ID.
308 * @param string|bool $local_path Local file path.
309 * @param int $min_width Minimum width.
310 * @param int $min_height Minimum height.
311 *
312 * @return bool
313 */
314 static function image_meets_minimum_test_dimensions( $image_id, $local_path, $min_width, $min_height ) {
315 if ( $min_width <= 0 && $min_height <= 0 ) {
316 return true;
317 }
318
319 $metadata = wp_get_attachment_metadata( $image_id );
320 if ( isset( $metadata['width'], $metadata['height'] ) ) {
321 return intval( $metadata['width'] ) >= $min_width && intval( $metadata['height'] ) >= $min_height;
322 }
323
324 if ( $local_path && file_exists( $local_path ) ) {
325 // phpcs:ignore -- Compatibility is guarded by function_exists().
326 $size = function_exists( 'wp_getimagesize' ) ? wp_getimagesize( $local_path ) : @getimagesize( $local_path );
327
328 if ( isset( $size[0], $size[1] ) ) {
329 return intval( $size[0] ) >= $min_width && intval( $size[1] ) >= $min_height;
330 }
331 }
332
333 return true;
334 }
335
336 /**
337 * Check if a remote image file exists.
338 *
339 * @param string $url The url to the remote image.
340 * @param bool $force_https Whether to force the url to be https.
341 *
342 * @return bool Whether the remote image exists.
343 */
344 static function image_file_exists( $url, $force_https = false ) {
345 if ( $force_https ) {
346 $url = str_replace( 'http://', 'https://', $url );
347 }
348
349 $response = wp_remote_head( $url, array(
350 'timeout' => 2,
351 'redirection' => 0,
352 'reject_unsafe_urls' => true,
353 ) );
354
355 if ( is_wp_error( $response ) ) {
356 return false;
357 }
358
359 $code = wp_remote_retrieve_response_code( $response );
360 return ( $code >= 200 && $code < 400 ) || 403 === $code;
361 }
362 }
363 }
364