PluginProbe ʕ •ᴥ•ʔ
WP Popular Posts / 5.2.0
WP Popular Posts v5.2.0
4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 5.0.0 5.0.1 5.0.2 5.1.0 5.2.0 5.2.1 5.2.2 5.2.3 5.2.4 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.2.0 6.2.1 6.3.0 6.3.1 6.3.2 6.3.3 6.3.4 6.4.0 6.4.1 6.4.2 7.0.0 7.0.1 7.1.0 7.2.0 7.3.0 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.3.7 7.3.8 7.4.0 trunk 2.3.7 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.2 4.0.3 4.0.5 4.0.6
wordpress-popular-posts / src / Image.php
wordpress-popular-posts / src Last commit date
Activation 5 years ago Admin 5 years ago Container 5 years ago Front 5 years ago Moment 5 years ago Rest 5 years ago Widget 5 years ago Bootstrap.php 5 years ago Cache.php 5 years ago Helper.php 5 years ago I18N.php 5 years ago Image.php 5 years ago Output.php 5 years ago Query.php 5 years ago Settings.php 5 years ago Themer.php 5 years ago Translate.php 5 years ago WordPressPopularPosts.php 5 years ago deprecated.php 5 years ago template-tags.php 5 years ago
Image.php
807 lines
1 <?php
2 /**
3 * This class builds/retrieves the thumbnail image of each popular posts.
4 *
5 *
6 * @package WordPressPopularPosts
7 * @author Hector Cabrera <me@cabrerahector.com>
8 */
9
10 namespace WordPressPopularPosts;
11
12 class Image {
13
14 /**
15 * Default thumbnail.
16 *
17 * @since 2.2.0
18 * @var string
19 */
20 private $default_thumbnail = '';
21
22 /**
23 * Plugin uploads directory.
24 *
25 * @since 3.0.4
26 * @var array
27 */
28 private $uploads_dir = [];
29
30 /**
31 * Admin settings.
32 *
33 * @since 5.0.0
34 * @var array
35 */
36 private $admin_options = [];
37
38 /**
39 * Available image sizes.
40 *
41 * @since 5.0.0
42 * @var array
43 */
44 private $available_sizes = [];
45
46 /**
47 * Construct.
48 *
49 * @since 4.0.0
50 * @param array $admin_options
51 */
52 public function __construct(array $admin_options)
53 {
54 $this->admin_options = $admin_options;
55
56 // Set default thumbnail
57 $this->default_thumbnail = plugins_url() . "/wordpress-popular-posts/assets/images/no_thumb.jpg";
58
59 if ( $this->is_image_url($this->admin_options['tools']['thumbnail']['default']) )
60 $this->default_thumbnail = $this->admin_options['tools']['thumbnail']['default'];
61
62 // Set uploads folder
63 $wp_upload_dir = wp_get_upload_dir();
64 $this->uploads_dir['basedir'] = $wp_upload_dir['basedir'] . "/" . 'wordpress-popular-posts';
65 $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'] . "/" . 'wordpress-popular-posts';
66
67 if ( ! is_dir($this->uploads_dir['basedir']) ) {
68 // Couldn't create the folder, store thumbnails in Uploads
69 if ( ! wp_mkdir_p($this->uploads_dir['basedir']) ) {
70 $this->uploads_dir['basedir'] = $wp_upload_dir['basedir'];
71 $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'];
72 }
73 }
74 }
75
76 /**
77 * Get WPP's uploads folder.
78 *
79 * @since 4.0.0
80 * @access public
81 * @return array|bool
82 */
83 public function get_plugin_uploads_dir()
84 {
85 if ( is_array($this->uploads_dir) && ! empty($this->uploads_dir) )
86 return $this->uploads_dir;
87 return false;
88 }
89
90 /**
91 * Returns an image.
92 *
93 * @since 5.0.0
94 * @param \stdClass $post_object Post object
95 * @param array $size Image size (width & height)
96 * @param string $source Image source
97 * @param bool $crop Whether to crop the image or not
98 * @param string $build Whether to build the image or get an existing one
99 * @return string
100 */
101 public function get($post_object, $size, $source, $crop = true, $build = 'manual')
102 {
103 // Bail, $post_object is not an actual object
104 if ( false === $post_object instanceof \stdClass || ! isset($post_object->id) ) {
105 return '';
106 }
107
108 $alt = '';
109 $classes = ['wpp-thumbnail', 'wpp_' . $source];
110 $filename = $post_object->id . '-' . $source . '-' . $size[0] . 'x' . $size[1];
111 $cached = $this->exists($filename);
112
113 // We have a thumbnail already, return it
114 if ( $cached ) {
115 $classes[] = 'wpp_cached_thumb';
116
117 /**
118 * Filters CSS classes assigned to the thumbnail
119 *
120 * @since 5.0.0
121 * @param array CSS classes
122 * @param int The post ID
123 * @return array The new CSS classes
124 */
125 $classes = apply_filters(
126 'wpp_thumbnail_class_attribute',
127 $classes,
128 $post_object->id
129 );
130
131 /**
132 * Filters CSS classes assigned to the thumbnail
133 *
134 * @since 5.0.0
135 * @param string Original ALT attribute
136 * @param int The post ID
137 * @return string The new ALT attribute
138 */
139 $alt = apply_filters(
140 'wpp_thumbnail_alt_attribute',
141 $this->get_alt_attribute($post_object->id, $source),
142 $post_object->id
143 );
144
145 return $this->render(
146 $cached,
147 $size,
148 is_array($classes) ? implode(' ', $classes) : 'wpp-thumbnail wpp_' . $source,
149 is_string($alt) ? $alt : ''
150 );
151 }
152
153 $thumb_url = null;
154
155 // Return image as-is, no need to create a new thumbnail
156 if (
157 ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] )
158 || ( 'featured' == $source && 'predefined' == $build )
159 ){
160 /**
161 * Filters CSS classes assigned to the thumbnail
162 *
163 * @since 5.0.0
164 * @param array CSS classes
165 * @param int The post ID
166 * @return array The new CSS classes
167 */
168 $classes = apply_filters(
169 'wpp_thumbnail_class_attribute',
170 $classes,
171 $post_object->id
172 );
173
174 // Get custom field image URL
175 if ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] ) {
176 $thumb_url = get_post_meta(
177 $post_object->id,
178 $this->admin_options['tools']['thumbnail']['field'],
179 true
180 );
181
182 if ( ! $thumb_url || ! $this->is_image_url($thumb_url) ) {
183 // Is this an attachment ID instead of an image URL?
184 if ( Helper::is_number($thumb_url) ) {
185 $thumb_url = wp_get_attachment_image_src($thumb_url, 'full');
186 $thumb_url = is_array($thumb_url) ? $thumb_url[0] : null;
187 } else {
188 $thumb_url = null;
189 }
190 }
191
192 if ( $thumb_url ) {
193 /**
194 * Filters CSS classes assigned to the thumbnail
195 *
196 * @since 5.0.0
197 * @param string Original ALT attribute
198 * @param int The post ID
199 * @return string The new ALT attribute
200 */
201 $alt = apply_filters(
202 'wpp_thumbnail_alt_attribute',
203 '',
204 $post_object->id
205 );
206 }
207 }
208 // Get Post Thumbnail
209 else {
210 if (
211 current_theme_supports('post-thumbnails')
212 && has_post_thumbnail($post_object->id)
213 ) {
214 // Find corresponding image size
215 $stock_size = null;
216 $images_sizes = $this->get_sizes();
217
218 foreach ( $images_sizes as $name => $attr ) :
219 if (
220 $attr['width'] == $size[0]
221 && $attr['height'] == $size[1]
222 && $attr['crop'] == $crop
223 ) {
224 $stock_size = $name;
225 break;
226 }
227 endforeach;
228
229 // Couldn't find a matching size so let's go with width/height combo instead
230 // (this should never happen but better safe than sorry!)
231 if ( null == $stock_size ) {
232 $stock_size = $size;
233 }
234
235 $featured_image = get_the_post_thumbnail(
236 $post_object->id,
237 $stock_size
238 );
239
240 if ( strpos($featured_image, 'class="') && is_array($classes) && ! empty($classes) )
241 $featured_image = str_replace('class="', 'class="'. esc_attr(implode(' ', $classes)) . ' ', $featured_image);
242
243 if ( $this->admin_options['tools']['thumbnail']['lazyload'] && false == strpos($featured_image, 'loading="lazy"') ) {
244 $featured_image = str_replace('src="', 'loading="lazy" src="', $featured_image);
245 }
246
247 return $featured_image;
248 }
249 }
250 }
251 // Build a new thumbnail and return it
252 else {
253 $file_path = null;
254
255 if ( 'custom_field' == $source && $this->admin_options['tools']['thumbnail']['resize'] ) {
256 $thumb_url = get_post_meta(
257 $post_object->id,
258 $this->admin_options['tools']['thumbnail']['field'],
259 true
260 );
261
262 if ( ! $thumb_url || ! $this->is_image_url($thumb_url) ) {
263 // Is this an attachment ID instead of an image URL?
264 // If so, try to fetch the image
265 if ( Helper::is_number($thumb_url) ) {
266 $thumb_url = wp_get_attachment_image_src($thumb_url, 'full');
267 $thumb_url = is_array($thumb_url) ? $thumb_url[0] : null;
268 } else {
269 $thumb_url = null;
270 }
271 }
272
273 if ( $thumb_url && $this->is_image_url($thumb_url) ) {
274 $file_path = $this->url_to_path($thumb_url, $post_object->id);
275 }
276 } else {
277 $file_meta = $this->get_file_meta($post_object->id, $source);
278
279 if ( is_array($file_meta) && isset($file_meta['path']) ) {
280 $alt = isset($file_meta['alt']) ? $file_meta['alt'] : '';
281 $file_path = $file_meta['path'];
282 }
283 }
284
285 if ( $file_path ) {
286 $extension = pathinfo($file_path, PATHINFO_EXTENSION);
287 $thumb_url = $this->resize(
288 $file_path,
289 $filename . '.' . $extension,
290 $size,
291 $crop
292 );
293 }
294 }
295
296 if ( ! $thumb_url ) {
297 $classes[] = 'wpp_def_no_src';
298 $thumb_url = $this->get_default_url($post_object->id);
299 }
300
301 return $this->render(
302 $thumb_url,
303 $size,
304 is_array($classes) ? implode(' ', $classes) : 'wpp-thumbnail wpp_' . $source,
305 is_string($alt) ? $alt : ''
306 );
307 }
308
309 /**
310 * Checks whether a given thumbnail exists.
311 *
312 * @since 5.0.0
313 * @access private
314 * @param string $filename
315 * @return string|bool Full URL to image
316 */
317 private function exists($filename)
318 {
319 // Do we have thumbnail already?
320 $file = $this->resolve(trailingslashit($this->get_plugin_uploads_dir()['basedir']) . $filename);
321
322 if ( $file && is_file($file) ) {
323 $extension = pathinfo($file, PATHINFO_EXTENSION);
324 return trailingslashit($this->get_plugin_uploads_dir()['baseurl']) . $filename . '.' . $extension;
325 }
326
327 return false;
328 }
329
330 /**
331 * Resolves filename.
332 *
333 * @since 5.0.0
334 * @access private
335 * @author Ioan Chiriac
336 * @link https://stackoverflow.com/a/29468093/9131961
337 * @param string $name
338 * @return string|bool Resolved path, or false if not found
339 */
340 private function resolve($name)
341 {
342 $info = pathinfo($name);
343
344 // File already contains an extension, return it
345 if ( isset($info['extension']) && ! empty($info['extension']) ) {
346 return $name;
347 }
348
349 $filename = $info['filename'];
350 $len = strlen($filename);
351
352 // open the folder
353 $dh = opendir($info['dirname']);
354
355 if ( ! $dh ) {
356 return false;
357 }
358
359 // scan each file in the folder
360 while ( ($file = readdir($dh)) !== false ) {
361 if ( strncmp($file, $filename, $len) === 0 ) {
362 if ( strlen($name) > $len ) {
363 // if name contains a directory part
364 $name = substr($name, 0, strlen($name) - $len) . $file;
365 } else {
366 // if the name is at the path root
367 $name = $file;
368 }
369
370 closedir($dh);
371 return $name;
372 }
373 }
374
375 // file not found
376 closedir($dh);
377 return false;
378 }
379
380 /**
381 * Retrieves local path to image.
382 *
383 * @since 5.0.0
384 * @access private
385 * @param string $url
386 * @param integer $post_ID
387 * @return string|boolean Path to image, or false if not found
388 */
389 private function url_to_path($url, $post_ID = null)
390 {
391 if ( $this->is_image_url($url) ) {
392 $attachment_id = $this->get_attachment_id($url);
393
394 // Image is hosted locally
395 if ( $attachment_id ) {
396 return get_attached_file($attachment_id);
397 }
398
399 // Image hosted elsewhere?
400 if ( $post_ID && Helper::is_number($post_ID) )
401 return $this->fetch_external_image($post_ID, $url);
402 }
403
404 return false;
405 }
406
407 /**
408 * Gets image meta.
409 *
410 * @since 5.0.0
411 * @access private
412 * @param int $id Post ID
413 * @param string $source Image source
414 * @return array|bool
415 */
416 private function get_file_meta($id, $source)
417 {
418 // get thumbnail path from the Featured Image
419 if ( "featured" == $source ) {
420 if ( $thumbnail_id = get_post_thumbnail_id($id) ) {
421 // image path
422 return [
423 'path' => get_attached_file($thumbnail_id),
424 'alt' => get_post_meta($thumbnail_id, '_wp_attachment_image_alt', true)
425 ];
426 }
427 }
428 // get thumbnail path from first image attachment
429 elseif ( "first_attachment" == $source ) {
430 $args = [
431 'numberposts' => 1,
432 'order' => 'ASC',
433 'post_parent' => $id,
434 'post_type' => 'attachment',
435 'post_mime_type' => 'image'
436 ];
437 $post_attachments = get_children($args);
438
439 if ( ! empty($post_attachments) ) {
440 $first_img = array_shift($post_attachments);
441
442 return [
443 'path' => get_attached_file($first_img->ID),
444 'alt' => get_post_meta($first_img->ID, '_wp_attachment_image_alt', true)
445 ];
446 }
447 }
448 // get thumbnail path from post content
449 elseif ( "first_image" == $source ) {
450 /** @var wpdb $wpdb */
451 global $wpdb;
452
453 if ( $content = $wpdb->get_var("SELECT post_content FROM {$wpdb->posts} WHERE ID = {$id};") ) {
454 // at least one image has been found
455 if ( preg_match('/<img[^>]+>/i', $content, $img) ) {
456 // get img src attribute from the first image found
457 preg_match('/(src)="([^"]*)"/i', $img[0], $src_attr);
458
459 if ( isset($src_attr[2]) && ! empty($src_attr[2]) ) {
460 // get img alt attribute from the first image found
461 $alt = '';
462 preg_match('/(alt)="([^"]*)"/i', $img[0], $alt_attr);
463
464 if ( isset($alt_attr[2]) && !empty($alt_attr[2]) ) {
465 $alt = $alt_attr[2];
466 }
467
468 // image from Media Library
469 if ( $attachment_id = $this->get_attachment_id($src_attr[2]) ) {
470 return [
471 'path' => get_attached_file($attachment_id),
472 'alt' => $alt
473 ];
474 } // external image?
475 else {
476 return [
477 'path' => $this->fetch_external_image($id, $src_attr[2]),
478 'alt' => $alt
479 ];
480 }
481 }
482 }
483 }
484 }
485
486 return false;
487 }
488
489 /**
490 * Gets image ALT attribute.
491 *
492 * @since 5.0.0
493 * @access private
494 * @param int $id Post ID
495 * @param string $source Image source
496 * @return string
497 */
498 private function get_alt_attribute($id, $source)
499 {
500 $alt = '';
501
502 // get thumbnail path from the Featured Image
503 if ( "featured" == $source ) {
504 if ( $thumbnail_id = get_post_thumbnail_id($id) ) {
505 // image path
506 $alt = get_post_meta($thumbnail_id, '_wp_attachment_image_alt', true);
507 }
508 }
509 // get thumbnail path from first image attachment
510 elseif ( "first_attachment" == $source ) {
511 $args = [
512 'numberposts' => 1,
513 'order' => 'ASC',
514 'post_parent' => $id,
515 'post_type' => 'attachment',
516 'post_mime_type' => 'image'
517 ];
518 $post_attachments = get_children($args);
519
520 if ( ! empty($post_attachments) ) {
521 $first_img = array_shift($post_attachments);
522 $alt = get_post_meta($first_img->ID, '_wp_attachment_image_alt', true);
523 }
524 }
525 // get thumbnail path from post content
526 elseif ( "first_image" == $source ) {
527 /** @var wpdb $wpdb */
528 global $wpdb;
529
530 if ( $content = $wpdb->get_var("SELECT post_content FROM {$wpdb->posts} WHERE ID = {$id};") ) {
531 // at least one image has been found
532 if ( preg_match('/<img[^>]+>/i', $content, $img) ) {
533 // get img alt attribute from the first image found
534 preg_match('/(alt)="([^"]*)"/i', $img[0], $alt_attr);
535
536 if ( isset($alt_attr[2]) && !empty($alt_attr[2]) ) {
537 $alt = $alt_attr[2];
538 }
539 }
540 }
541 }
542
543 return $alt;
544 }
545
546 /**
547 * Get the Attachment ID for a given image URL.
548 *
549 * @since 3.0.0
550 * @access private
551 * @author Frankie Jarrett
552 * @link http://frankiejarrett.com/get-an-attachment-id-by-url-in-wordpress/
553 * @param string $url
554 * @return int|null
555 */
556 private function get_attachment_id($url)
557 {
558 $url = Helper::add_scheme(
559 $url,
560 is_ssl() ? 'https://' : 'http://'
561 );
562
563 // Split the $url into two parts with the wp-content directory as the separator.
564 $parse_url = explode(parse_url(WP_CONTENT_URL, PHP_URL_PATH), $url);
565
566 // Get the host of the current site and the host of the $url, ignoring www.
567 $this_host = str_ireplace('www.', '', parse_url(home_url(), PHP_URL_HOST));
568 $file_host = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST));
569
570 // Return nothing if there aren't any $url parts or if the current host and $url host do not match.
571 if (
572 ! isset($parse_url[1])
573 || empty($parse_url[1])
574 || ($this_host != $file_host)
575 ) {
576 return false;
577 }
578
579 // Now we're going to quickly search the DB for any attachment GUID with a partial path match.
580 // Example: /uploads/2013/05/test-image.jpg
581 global $wpdb;
582
583 if ( ! $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->prefix}posts WHERE guid RLIKE %s;", $parse_url[1])) ) {
584 // Maybe it's a resized image, so try to get the full one
585 $parse_url[1] = preg_replace('/-[0-9]{1,4}x[0-9]{1,4}\.(jpg|jpeg|png|gif|bmp)$/i', '.$1', $parse_url[1]);
586 $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->prefix}posts WHERE guid RLIKE %s;", $parse_url[1]));
587 }
588
589 // Returns null if no attachment is found.
590 return isset($attachment[0]) ? $attachment[0] : NULL;
591 }
592
593 /**
594 * Fetchs external images.
595 *
596 * @since 2.3.3
597 * @access private
598 * @param int $id Post ID.
599 * @param string $url Image url.
600 * @return string|bool Image path, or false on failure.
601 */
602 private function fetch_external_image($id, $url)
603 {
604 $full_image_path = trailingslashit($this->get_plugin_uploads_dir()['basedir']) . "{$id}_" . sanitize_file_name(rawurldecode(wp_basename($url)));
605
606 // if the file exists already, return URL and path
607 if ( file_exists($full_image_path) )
608 return $full_image_path;
609
610 $url = Helper::add_scheme(
611 $url,
612 is_ssl() ? 'https://' : 'http://'
613 );
614
615 $accepted_status_codes = [200, 301, 302];
616 $response = wp_remote_head($url, ['timeout' => 5, 'sslverify' => false]);
617
618 if (
619 ! is_wp_error($response)
620 && in_array(wp_remote_retrieve_response_code($response), $accepted_status_codes)
621 ) {
622 require_once(ABSPATH . 'wp-admin/includes/file.php');
623
624 $url = str_replace('https://', 'http://', $url);
625 $tmp = download_url($url);
626
627 // File was downloaded successfully
628 if ( ! is_wp_error($tmp) ) {
629 // Determine image type
630 if ( function_exists('exif_imagetype') ) {
631 $image_type = exif_imagetype($tmp);
632 } else {
633 $image_type = getimagesize($tmp);
634 $image_type = ( isset($image_type[2]) ) ? $image_type[2] : NULL;
635 }
636
637 // Valid image, save it
638 if ( in_array($image_type, [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG]) ) {
639 // move file to Uploads
640 if ( @rename($tmp, $full_image_path) ) {
641 // borrowed from WP - set correct file permissions
642 $stat = stat(dirname($full_image_path));
643 $perms = $stat['mode'] & 0000644;
644 @chmod($full_image_path, $perms);
645
646 return $full_image_path;
647 }
648 }
649
650 // Invalid file, remove it
651 @unlink($tmp);
652 }
653 }
654
655 return false;
656 }
657
658 /**
659 * Resizes image.
660 *
661 * @since 3.0.0
662 * @access private
663 * @param string $path Image path
664 * @param string $filename Image filename
665 * @param array $size Image size
666 * @param bool $crop Whether to crop the image or not
667 * @return string|bool Image URL on success, false on error
668 */
669 private function resize($path, $filename, $size, $crop = true)
670 {
671 $image = wp_get_image_editor($path);
672
673 // valid image, create thumbnail
674 if ( ! is_wp_error($image) ) {
675 /**
676 * Hook to change the image compression quality of WPP's thumbnails.
677 * @since 4.2.1
678 */
679 $quality = apply_filters('wpp_thumbnail_compression_quality', null);
680
681 if ( ! ctype_digit($quality) )
682 $quality = null; // Fallback to core's default
683
684 $image->set_quality($quality);
685
686 $image->resize($size[0], $size[1], $crop);
687 $new_img = $image->save(trailingslashit($this->get_plugin_uploads_dir()['basedir']) . $filename);
688
689 if ( ! is_wp_error($new_img) )
690 return trailingslashit($this->get_plugin_uploads_dir()['baseurl']) . $filename;
691 }
692
693 return false;
694 }
695
696 /**
697 * Render image tag.
698 *
699 * @since 3.0.0
700 * @access public
701 * @param string $src Image URL
702 * @param array $dimension Image's width and height
703 * @param string $class CSS class
704 * @param object $alt Alternative text
705 * @param string $error Error, if the image could not be created
706 * @return string
707 */
708 public function render($src, $size, $class, $alt = '', $error = null)
709 {
710 $img_tag = '';
711
712 if ( $error ) {
713 $img_tag = '<!-- ' . $error . ' --> ';
714 }
715
716 $src = 'src="' . esc_url(is_ssl() ? str_ireplace("http://", "https://", $src) : $src) . '"';
717 $lazyload = ( $this->admin_options['tools']['thumbnail']['lazyload'] ) ? ' loading="lazy"' : '';
718
719 $img_tag .= '<img ' . $src . ' width="' . $size[0] . '" height="' . $size[1] . '" alt="' . esc_attr($alt) . '" class="' . esc_attr($class) . '"' . $lazyload . ' />';
720
721 return apply_filters('wpp_render_image', $img_tag);
722 }
723
724 /**
725 * Gets list of available thumbnails sizes
726 *
727 * @since 3.2.0
728 * @link http://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
729 * @param string $size
730 * @return array|bool
731 */
732 public function get_sizes($size = '')
733 {
734 if ( ! is_array($this->available_sizes) || empty($this->available_sizes) ) {
735 global $_wp_additional_image_sizes;
736
737 $this->available_sizes = [];
738 $get_intermediate_image_sizes = get_intermediate_image_sizes();
739
740 // Create the full array with sizes and crop info
741 foreach( $get_intermediate_image_sizes as $_size ) {
742 if ( in_array($_size, ['thumbnail', 'medium', 'large']) ) {
743 $this->available_sizes[$_size]['width'] = get_option($_size . '_size_w');
744 $this->available_sizes[$_size]['height'] = get_option($_size . '_size_h');
745 $this->available_sizes[$_size]['crop'] = (bool) get_option($_size . '_crop');
746 } elseif ( isset($_wp_additional_image_sizes[$_size]) ) {
747 $this->available_sizes[$_size] = [
748 'width' => $_wp_additional_image_sizes[$_size]['width'],
749 'height' => $_wp_additional_image_sizes[$_size]['height'],
750 'crop' => $_wp_additional_image_sizes[$_size]['crop']
751 ];
752 }
753 }
754 }
755
756 // Get only 1 size if found
757 if ( $size ) {
758 if ( isset($this->available_sizes[$size]) ) {
759 return $this->available_sizes[$size];
760 }
761 return false;
762 }
763
764 return $this->available_sizes;
765 }
766
767 /**
768 * Returns the URL of the default thumbnail image.
769 *
770 * @since 5.0.0
771 * @param int|null
772 * @return string
773 */
774 public function get_default_url($post_ID = null)
775 {
776 if ( has_filter('wpp_default_thumbnail_url') ) {
777 $default_thumbnail_url = apply_filters('wpp_default_thumbnail_url', $this->default_thumbnail, $post_ID);
778
779 if ( $default_thumbnail_url != $this->default_thumbnail && $this->is_image_url($default_thumbnail_url) )
780 return $default_thumbnail_url;
781 }
782
783 return $this->default_thumbnail;
784 }
785
786 /**
787 * Checks whether an URL points to an actual image.
788 *
789 * @since 5.0.0
790 * @access private
791 * @param string
792 * @return array|bool
793 */
794 private function is_image_url($url)
795 {
796 if ( ! filter_var($url, FILTER_VALIDATE_URL) )
797 return false;
798
799 // sanitize URL, just in case
800 $image_url = esc_url($url);
801 // remove querystring
802 preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $image_url, $matches);
803
804 return ( is_array($matches) && ! empty($matches) ) ? $matches : false;
805 }
806 }
807