PluginProbe ʕ •ᴥ•ʔ
WP Popular Posts / 4.1.1
WP Popular Posts v4.1.1
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 / includes / class-wordpress-popular-posts-image.php
wordpress-popular-posts / includes Last commit date
class-wordpress-popular-posts-activator.php 8 years ago class-wordpress-popular-posts-deactivator.php 8 years ago class-wordpress-popular-posts-helper.php 8 years ago class-wordpress-popular-posts-i18n.php 8 years ago class-wordpress-popular-posts-image.php 8 years ago class-wordpress-popular-posts-loader.php 8 years ago class-wordpress-popular-posts-output.php 8 years ago class-wordpress-popular-posts-query.php 8 years ago class-wordpress-popular-posts-rest-controller.php 8 years ago class-wordpress-popular-posts-settings.php 8 years ago class-wordpress-popular-posts-template.php 8 years ago class-wordpress-popular-posts-translate.php 8 years ago class-wordpress-popular-posts-widget.php 8 years ago class-wordpress-popular-posts.php 8 years ago widget-form.php 8 years ago
class-wordpress-popular-posts-image.php
522 lines
1 <?php
2
3 class WPP_Image {
4
5 /**
6 * The array of actions registered with WordPress.
7 *
8 * @since 4.0.0
9 * @access private
10 * @var object|WPP_Image
11 */
12 private static $instance;
13
14 /**
15 * The array of actions registered with WordPress.
16 *
17 * @since 4.0.0
18 * @access private
19 * @var bool $can_create_thumbnails Checks if WPP is able to build thumbnails.
20 */
21 private $can_create_thumbnails;
22
23 /**
24 * Default thumbnail.
25 *
26 * @since 2.2.0
27 * @var string
28 */
29 private $default_thumbnail = '';
30
31 /**
32 * Plugin uploads directory.
33 *
34 * @since 3.0.4
35 * @var array
36 */
37 private $uploads_dir = array();
38
39 /**
40 * Initialize the collections used to maintain the actions and filters.
41 *
42 * @since 4.0.0
43 * @access private
44 */
45 private function __construct() {
46
47 // Check if WPP can create images
48 $this->can_create_thumbnails = ( extension_loaded('ImageMagick') || extension_loaded('imagick') || (extension_loaded('GD') && function_exists('gd_info')) );
49
50 if ( $this->can_create_thumbnails ) {
51
52 // Set default thumbnail
53 $this->default_thumbnail = $this->get_plugin_dir_url() . "public/images/no_thumb.jpg";
54
55 // Set uploads folder
56 $wp_upload_dir = wp_get_upload_dir();
57 $this->uploads_dir['basedir'] = $wp_upload_dir['basedir'] . "/" . 'wordpress-popular-posts';
58 $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'] . "/" . 'wordpress-popular-posts';
59
60 if ( !is_dir($this->uploads_dir['basedir']) ) {
61 if ( !wp_mkdir_p($this->uploads_dir['basedir']) ) {
62 $this->uploads_dir['basedir'] = $wp_upload_dir['basedir'];
63 $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'];
64 }
65 }
66
67 }
68
69 }
70
71 /**
72 * Get an instance of this class.
73 *
74 * @since 4.0.0
75 * @return object|\WPP_Image
76 */
77 public static function get_instance() {
78
79 if ( is_null(self::$instance) ) {
80 self::$instance = new WPP_Image();
81 }
82
83 return self::$instance;
84
85 }
86
87 /**
88 * Tells whether WPP can create thumbnails or not.
89 *
90 * @since 4.0.0
91 * @access public
92 * @return bool
93 */
94 public function can_create_thumbnails() {
95 return $this->can_create_thumbnails;
96 }
97
98 public function get_plugin_dir() {
99 return WP_PLUGIN_DIR . '/wordpress-popular-posts/';
100 }
101
102 public function get_plugin_dir_url() {
103 return plugins_url() . '/wordpress-popular-posts/';
104 }
105
106 /**
107 * Get WPP's uploads folder.
108 *
109 * @since 4.0.0
110 * @access public
111 * @return array|bool
112 */
113 public function get_plugin_uploads_dir() {
114
115 if ( is_array($this->uploads_dir) && !empty($this->uploads_dir) )
116 return $this->uploads_dir;
117
118 return false;
119
120 }
121
122 /**
123 * Retrieves / creates the post thumbnail.
124 *
125 * @since 2.3.3
126 * @param object $post_object Post object (must contain, at least, the properties id and title)
127 * @param string $url Image URL
128 * @param array $size Thumbnail's width and height
129 * @param array $crop Image cropping
130 * @param string $source Image source
131 * @return string
132 */
133 public function get_img( $post_object = null, $url = null, $size = array(80, 80), $crop = true, $source = "featured" ) {
134
135 // WPP cannot create thumbnails
136 if ( !$this->can_create_thumbnails )
137 return '';
138
139 if (
140 ( false === $post_object instanceof stdClass || !isset($post_object->id) )
141 && !filter_var( $url, FILTER_VALIDATE_URL )
142 ) {
143 return $this->render_image( $this->default_thumbnail, $size, 'wpp-thumbnail wpp_def_no_src wpp_' . $source, $post_object );
144 }
145
146 // Get image by post ID (parent)
147 if (
148 isset( $post_object->id )
149 && !$url
150 ) {
151 $file_path = $this->get_image_file_paths( $post_object->id, $source );
152
153 // No images found, return default thumbnail
154 if ( !$file_path ) {
155 return $this->render_image( $this->default_thumbnail, $size, 'wpp-thumbnail wpp_def_noPath wpp_' . $source, $post_object );
156 }
157 }
158 // Get image from URL
159 else {
160 // sanitize URL, just in case
161 $image_url = esc_url( $url );
162 // remove querystring
163 preg_match( '/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $image_url, $matches );
164 $image_url = $matches[0];
165
166 $attachment_id = $this->get_attachment_id( $image_url );
167
168 // Image is hosted locally
169 if ( $attachment_id ) {
170 $file_path = get_attached_file( $attachment_id );
171 }
172 // Image is hosted outside WordPress
173 else {
174 $external_image = $this->fetch_external_image( $post_object->id, $image_url );
175
176 if ( !$external_image ) {
177 return $this->render_image( $this->default_thumbnail, $size, 'wpp-thumbnail wpp_def_noPath wpp_no_external', $post_object );
178 }
179
180 $file_path = $external_image;
181 }
182 }
183
184 $extension = pathinfo( $file_path, PATHINFO_EXTENSION );
185
186 $image_meta = array(
187 'filename' => $post_object->id . '-' . $source . '-' . $size[0] . 'x' . $size[1],
188 'extension' => $extension,
189 'width' => $size[0],
190 'height' => $size[1],
191 'alt' => esc_attr( wp_strip_all_tags( $post_object->title ) ),
192 'crop' => $crop,
193 'source' => $source,
194 'parent_id' => $post_object->id
195 );
196
197 // there is a thumbnail already
198 if ( is_file( trailingslashit( $this->uploads_dir['basedir'] ) . $image_meta['filename'] . '.' . $image_meta['extension'] ) ) {
199 return $this->render_image(
200 trailingslashit( $this->uploads_dir['baseurl'] ) . $image_meta['filename'] . '.' . $image_meta['extension'],
201 $size,
202 'wpp-thumbnail wpp_cached_thumb wpp_' . $source,
203 $post_object
204 );
205 }
206
207 return $this->image_resize( $file_path, $image_meta );
208
209 } // end get_img
210
211 /**
212 * Resizes image.
213 *
214 * @since 3.0.0
215 * @access private
216 * @param object $post_object Post object
217 * @param string $path Image path
218 * @param array $size Image's width and height
219 * @param string $source Image source
220 * @return string
221 */
222 private function image_resize( $path, $image_meta ) {
223
224 $image = wp_get_image_editor( $path );
225
226 // valid image, create thumbnail
227 if ( !is_wp_error($image) ) {
228
229 $image->resize( $image_meta['width'], $image_meta['height'], $image_meta['crop'] );
230 $new_img = $image->save( trailingslashit($this->uploads_dir['basedir']) . $image_meta['filename'] . '.' . $image_meta['extension'] );
231
232 if ( is_wp_error($new_img) ) {
233 return $this->render_image( $this->default_thumbnail, array( $image_meta['width'], $image_meta['height'] ), 'wpp-thumbnail wpp_imgeditor_error wpp_' . $image_meta['source'], null, $new_img->get_error_message() );
234 }
235
236 return $this->render_image( trailingslashit($this->uploads_dir['baseurl']) . $new_img['file'], array( $image_meta['width'], $image_meta['height'] ), 'wpp-thumbnail wpp_imgeditor_thumb wpp_' . $image_meta['source'], null );
237
238 }
239
240 // ELSE
241 // image file path is invalid
242 return $this->render_image( $this->default_thumbnail, array( $image_meta['width'], $image_meta['height'] ), 'wpp-thumbnail wpp_imgeditor_error wpp_' . $image_meta['source'], null, $image->get_error_message() );
243
244 } // end image_resize
245
246 /**
247 * Get image absolute path / URL.
248 *
249 * @since 3.0.0
250 * @access private
251 * @param int $id Post ID
252 * @param string $source Image source
253 * @return array
254 */
255 private function get_image_file_paths( $id, $source ) {
256
257 $file_path = '';
258
259 // get thumbnail path from the Featured Image
260 if ( "featured" == $source ) {
261
262 if ( $thumbnail_id = get_post_thumbnail_id($id) ) {
263 // image path
264 return get_attached_file( $thumbnail_id );
265 }
266
267 }
268 // get thumbnail path from first image attachment
269 elseif ( "first_attachment" == $source ) {
270
271 $args = array(
272 'numberposts' => 1,
273 'order' => 'ASC',
274 'post_parent' => $id,
275 'post_type' => 'attachment',
276 'post_mime_type' => 'image'
277 );
278 $post_attachments = get_children( $args );
279
280 if ( !empty($post_attachments) ) {
281 $first_img = array_shift( $post_attachments );
282 return get_attached_file( $first_img->ID );
283 }
284
285 }
286 // get thumbnail path from post content
287 elseif ( "first_image" == $source ) {
288
289 /** @var wpdb $wpdb */
290 global $wpdb;
291
292 if ( $content = $wpdb->get_var( "SELECT post_content FROM {$wpdb->posts} WHERE ID = {$id};" ) ) {
293
294 // at least one image has been found
295 if ( preg_match( '/<img[^>]+>/i', $content, $img ) ) {
296
297 // get img src attribute from the first image found
298 preg_match( '/(src)="([^"]*)"/i', $img[0], $src_attr );
299
300 if ( isset($src_attr[2]) && !empty($src_attr[2]) ) {
301
302 // image from Media Library
303 if ( $attachment_id = $this->get_attachment_id( $src_attr[2] ) ) {
304
305 $file_path = get_attached_file( $attachment_id );
306
307 // There's a file path, so return it
308 if ( !empty($file_path) ) {
309 return $file_path;
310 }
311
312 } // external image?
313 else {
314 return $this->fetch_external_image( $id, $src_attr[2] );
315 }
316
317 }
318
319 }
320
321 }
322
323 }
324
325 return false;
326
327 } // end get_image_file_paths
328
329 /**
330 * Render image tag.
331 *
332 * @since 3.0.0
333 * @access public
334 * @param string src Image URL
335 * @param array dimension Image's width and height
336 * @param string class CSS class
337 * @param object $post_object Post object (must contain, at least, the properties id and title)
338 * @param string error Error, if the image could not be created
339 * @return string
340 */
341 public function render_image( $src, $size, $class, $post_object, $error = null ) {
342
343 $img_tag = '';
344
345 if ( $error ) {
346 $img_tag = '<!-- ' . $error . ' --> ';
347 }
348
349 $img_tag .= '<img src="' . ( is_ssl() ? str_ireplace( "http://", "https://", $src ) : $src ) . '" width="' . $size[0] . '" height="' . $size[1] . '" alt="' . ( ($post_object instanceof stdClass && isset($post_object->title) ? esc_attr( wp_strip_all_tags($post_object->title) ) : '' ) ) . '" class="' . $class . '" />';
350
351 return apply_filters( 'wpp_render_image', $img_tag );
352
353 } // render_image
354
355 /**
356 * Get the Attachment ID for a given image URL.
357 *
358 * @since 3.0.0
359 * @access private
360 * @author Frankie Jarrett
361 * @link http://frankiejarrett.com/get-an-attachment-id-by-url-in-wordpress/
362 * @param string $url
363 * @return bool|int
364 */
365 private function get_attachment_id( $url ) {
366
367 // Split the $url into two parts with the wp-content directory as the separator.
368 $parse_url = explode( parse_url( WP_CONTENT_URL, PHP_URL_PATH ), $url );
369
370 // Get the host of the current site and the host of the $url, ignoring www.
371 $this_host = str_ireplace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) );
372 $file_host = str_ireplace( 'www.', '', parse_url( $url, PHP_URL_HOST ) );
373
374 // Return nothing if there aren't any $url parts or if the current host and $url host do not match.
375 if (
376 !isset( $parse_url[1] )
377 || empty( $parse_url[1] )
378 || ( $this_host != $file_host )
379 ) {
380 return false;
381 }
382
383 // Now we're going to quickly search the DB for any attachment GUID with a partial path match.
384 // Example: /uploads/2013/05/test-image.jpg
385 global $wpdb;
386
387 if ( !$attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}posts WHERE guid RLIKE %s;", $parse_url[1] ) ) ) {
388 // Maybe it's a resized image, so try to get the full one
389 $parse_url[1] = preg_replace( '/-[0-9]{1,4}x[0-9]{1,4}\.(jpg|jpeg|png|gif|bmp)$/i', '.$1', $parse_url[1] );
390 $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}posts WHERE guid RLIKE %s;", $parse_url[1] ) );
391 }
392
393 // Returns null if no attachment is found.
394 return isset( $attachment[0] ) ? $attachment[0] : NULL;
395
396 } // get_attachment_id
397
398 /**
399 * Fetchs external images.
400 *
401 * @since 2.3.3
402 * @access private
403 * @param int $id Post ID.
404 * @param string $url Image url.
405 * @return bool|int
406 */
407 private function fetch_external_image( $id, $url ){
408
409 $full_image_path = trailingslashit( $this->uploads_dir['basedir'] ) . "{$id}_". sanitize_file_name( rawurldecode(wp_basename( $url )) );
410
411 // if the file exists already, return URL and path
412 if ( file_exists($full_image_path) )
413 return $full_image_path;
414
415 $accepted_status_codes = array( 200, 301, 302 );
416 $response = wp_remote_head( $url, array( 'timeout' => 5, 'sslverify' => false ) );
417
418 if (
419 !is_wp_error($response)
420 && in_array( wp_remote_retrieve_response_code($response), $accepted_status_codes )
421 ) {
422
423 require_once( ABSPATH . 'wp-admin/includes/file.php' );
424 $url = str_replace( 'https://', 'http://', $url );
425 $tmp = download_url( $url );
426
427 if ( !is_wp_error( $tmp ) ) {
428
429 if ( function_exists('exif_imagetype') ) {
430 $image_type = exif_imagetype( $tmp );
431 } else {
432 $image_type = getimagesize( $tmp );
433 $image_type = ( isset($image_type[2]) ) ? $image_type[2] : NULL;
434 }
435
436 if ( in_array($image_type, array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG)) ) {
437
438 // move file to Uploads
439 if ( @rename($tmp, $full_image_path) ) {
440 // borrowed from WP - set correct file permissions
441 $stat = stat( dirname( $full_image_path ) );
442 $perms = $stat['mode'] & 0000644;
443 @chmod( $full_image_path, $perms );
444
445 return $full_image_path;
446 }
447
448 }
449
450 // remove temp file
451 @unlink( $tmp );
452
453 }
454
455 }
456
457 return false;
458
459 } // end fetch_external_image
460
461 /**
462 * Gets list of available thumbnails sizes
463 *
464 * @since 3.2.0
465 * @link http://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
466 * @param string $size
467 * @return array|bool
468 */
469 public function get_image_sizes( $size = '' ) {
470
471 global $_wp_additional_image_sizes;
472
473 $sizes = array();
474 $get_intermediate_image_sizes = get_intermediate_image_sizes();
475
476 // Create the full array with sizes and crop info
477 foreach( $get_intermediate_image_sizes as $_size ) {
478
479 if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
480
481 $sizes[ $_size ]['width'] = get_option( $_size . '_size_w' );
482 $sizes[ $_size ]['height'] = get_option( $_size . '_size_h' );
483 $sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
484
485 } elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
486
487 $sizes[ $_size ] = array(
488 'width' => $_wp_additional_image_sizes[ $_size ]['width'],
489 'height' => $_wp_additional_image_sizes[ $_size ]['height'],
490 'crop' => $_wp_additional_image_sizes[ $_size ]['crop']
491 );
492
493 }
494
495 }
496
497 // Get only 1 size if found
498 if ( $size ) {
499
500 if( isset( $sizes[ $size ] ) ) {
501 return $sizes[ $size ];
502 } else {
503 return false;
504 }
505
506 }
507
508 return $sizes;
509 }
510
511 /**
512 * Sets default thumbnail image.
513 *
514 * @since 4.0.2
515 * @param string $url
516 */
517 public function set_default( $url ) {
518 $this->default_thumbnail = esc_url( $url );
519 }
520
521 } // End WPP_Image class
522