PageRenderTime 50ms CodeModel.GetById 2ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/ml-slider/inc/metaslider.imagehelper.class.php

https://gitlab.com/thisishayat/itv-2016
PHP | 371 lines | 207 code | 72 blank | 92 comment | 63 complexity | 27ff7910a2ded1b410380656b6155e0d MD5 | raw file
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) {
  3. exit; // disable direct access
  4. }
  5. /**
  6. * Helper class for resizing images, returning the correct URL to the image etc
  7. */
  8. class MetaSliderImageHelper {
  9. private $crop_type = 'smart';
  10. private $container_width; // slideshow width
  11. private $container_height; // slideshow height
  12. private $id; // slide/attachment ID
  13. private $url;
  14. private $path; // path to attachment on server
  15. private $use_image_editor;
  16. /**
  17. * Constructor
  18. *
  19. * @param integer $slide_id
  20. * @param integer $width - required width of image
  21. * @param integer $height - required height of image
  22. * @param string $smart_crop
  23. */
  24. public function __construct( $slide_id, $width, $height, $crop_type, $use_image_editor = true ) {
  25. $upload_dir = wp_upload_dir();
  26. $this->id = $slide_id;
  27. $this->url = apply_filters("metaslider_attachment_url", $upload_dir['baseurl'] . "/" . get_post_meta( $slide_id, '_wp_attached_file', true ), $slide_id);
  28. $this->path = get_attached_file( $slide_id );
  29. $this->container_width = $width;
  30. $this->container_height = $height;
  31. $this->use_image_editor = $use_image_editor;
  32. $this->set_crop_type($crop_type);
  33. }
  34. /**
  35. * Add in backwards compatibility for old versions of MS Pro
  36. * 'true' = smart, 'false' = standard, 'disabled' = disabled
  37. *
  38. * @param string $crop_type
  39. */
  40. private function set_crop_type( $crop_type ) {
  41. switch ( $crop_type ) {
  42. case "false":
  43. case "standard":
  44. $this->crop_type = 'standard'; // smart crop enabled
  45. break;
  46. case "disabled":
  47. $this->crop_type = 'disabled'; // cropping disabled
  48. break;
  49. case "disabled_pad":
  50. $this->crop_type = 'disabled'; // cropping disabled
  51. break;
  52. case "true":
  53. case "smart":
  54. default:
  55. $this->crop_type = 'smart';
  56. }
  57. }
  58. /**
  59. * Return the crop dimensions.
  60. *
  61. * Smart Crop: If the image is smaller than the container width or height, then return
  62. * dimensions that respect the container size ratio. This ensures image displays in a
  63. * sane manner in responsive sliders
  64. *
  65. * @param integer $image_width
  66. * @param integer $image_height
  67. * @return array image dimensions
  68. */
  69. private function get_crop_dimensions( $image_width, $image_height ) {
  70. if ( $this->crop_type == 'standard' ) {
  71. return array( 'width' => absint( $this->container_width ), 'height' => absint( $this->container_height ) );
  72. }
  73. if ( $this->crop_type == 'disabled' ) {
  74. return array( 'width' => absint( $image_width ), 'height' => absint( $image_height ) );
  75. }
  76. $container_width = $this->container_width;
  77. $container_height = $this->container_height;
  78. /**
  79. * Slideshow Width == Slide Width
  80. */
  81. if ( $image_width == $container_width && $image_height == $container_height ) {
  82. $new_slide_width = $container_width;
  83. $new_slide_height = $container_height;
  84. }
  85. if ( $image_width == $container_width && $image_height < $container_height ) {
  86. $new_slide_height = $image_height;
  87. $new_slide_width = $container_width / ( $container_height / $image_height );
  88. }
  89. if ( $image_width == $container_width && $image_height > $container_height ) {
  90. $new_slide_width = $container_width;
  91. $new_slide_height = $container_height;
  92. }
  93. /**
  94. * Slideshow Width < Slide Width
  95. */
  96. if ( $image_width < $container_width && $image_height == $container_height ) {
  97. $new_slide_width = $image_width;
  98. $new_slide_height = $image_height / ( $container_width / $image_width );
  99. }
  100. /**
  101. * Slide is smaller than slidehow - both width and height
  102. */
  103. if ( $image_width < $container_width && $image_height < $container_height ) {
  104. if ( $container_width > $container_height ) {
  105. // wide
  106. if ( $image_width > $image_height ) {
  107. // wide
  108. $new_slide_height = $image_height;
  109. $new_slide_width = $container_width / ( $container_height / $image_height );
  110. if ( $new_slide_width > $image_width ) {
  111. $new_slide_width = $image_width;
  112. $new_slide_height = $container_height / ( $container_width / $image_width );
  113. }
  114. } else {
  115. // tall
  116. $new_slide_width = $image_width;
  117. $new_slide_height = $container_height / ( $container_width / $image_width );
  118. if ( $new_slide_height > $image_height ) {
  119. $new_slide_height = $image_height;
  120. $new_slide_width = $container_width / ( $container_height / $image_height );
  121. }
  122. }
  123. } else {
  124. // tall
  125. if ( $image_width > $image_height ) {
  126. // wide
  127. $new_slide_height = $image_height;
  128. $new_slide_width = $container_width / ( $container_height / $image_height );
  129. if ( $new_slide_width > $image_width ) {
  130. $new_slide_width = $image_width;
  131. $new_slide_height = $container_height / ( $container_width / $image_width );
  132. }
  133. } else {
  134. // tall
  135. $new_slide_width = $image_width;
  136. $new_slide_height = $container_height / ( $container_width / $image_width );
  137. if ( $new_slide_height > $image_height ) {
  138. $new_slide_height = $image_height;
  139. $new_slide_width = $container_width / ( $container_height / $image_height );
  140. }
  141. }
  142. }
  143. }
  144. if ( $image_width < $container_width && $image_height > $container_height ) {
  145. $new_slide_width = $image_width;
  146. $new_slide_height = $container_height / ( $container_width / $image_width );
  147. }
  148. /**
  149. * Slideshow Width > Slide Width
  150. */
  151. if ( $image_width > $container_width && $image_height == $container_height ) {
  152. $new_slide_width = $container_width;
  153. $new_slide_height = $container_height;
  154. }
  155. if ( $image_width > $container_width && $image_height < $container_height ) {
  156. $new_slide_height = $image_height;
  157. $new_slide_width = $container_width / ( $container_height / $image_height );
  158. }
  159. if ( $image_width > $container_width && $image_height > $container_height ) {
  160. $new_slide_width = $container_width;
  161. $new_slide_height = $container_height;
  162. }
  163. return array( 'width' => floor( $new_slide_width ), 'height' => floor( $new_slide_height ) );
  164. }
  165. /**
  166. * Return the image URL, crop the image to the correct dimensions if required
  167. *
  168. * @param bool $force_resize
  169. * @return string resized image URL
  170. */
  171. function get_image_url( $force_resize = false ) {
  172. // Get the image file path
  173. if ( ! strlen( $this->path ) ) {
  174. return apply_filters( 'metaslider_resized_image_url', $this->url, $this->url );
  175. }
  176. // get the full image size dimensions
  177. $orig_size = $this->get_original_image_dimensions();
  178. // bail out if we can't find the image dimensions, return the full URL
  179. if ( $orig_size == false ) {
  180. return apply_filters( 'metaslider_resized_image_url', $this->url, $this->url );
  181. }
  182. // get our crop dimensions (this is the size we want to display)
  183. $dest_size = $this->get_crop_dimensions( $orig_size['width'], $orig_size['height'] );
  184. // if the full size is the same as the required size, return the full URL
  185. if ( $orig_size['width'] == $dest_size['width'] && $orig_size['height'] == $dest_size['height'] ) {
  186. return apply_filters( 'metaslider_resized_image_url', $this->url, $this->url );
  187. }
  188. // construct the file name
  189. $dest_file_name = $this->get_destination_file_name( $dest_size );
  190. if ( file_exists( $dest_file_name ) && ! $force_resize ) {
  191. // good. no need for resize, just return the URL
  192. $dest_url = str_replace( basename( $this->url ), basename( $dest_file_name ), $this->url );
  193. }
  194. else if ( $this->use_image_editor ) {
  195. // resize, assuming we're allowed to use the image editor
  196. $dest_url = $this->resize_image( $orig_size, $dest_size, $dest_file_name );
  197. }
  198. else {
  199. // fall back to the full URL
  200. $dest_url = $this->url;
  201. }
  202. $dest_url = apply_filters( 'metaslider_resized_image_url', $dest_url, $this->url );
  203. return $dest_url;
  204. }
  205. /**
  206. * Get the image dimensions for the original image.
  207. *
  208. * Fall back to using the WP_Image_Editor if the size is not stored in metadata
  209. *
  210. * @return array
  211. */
  212. private function get_original_image_dimensions() {
  213. $size = array();
  214. // try and get the image size from metadata
  215. $meta = wp_get_attachment_metadata( $this->id );
  216. if ( isset( $meta['width'], $meta['height'] ) ) {
  217. return $meta;
  218. }
  219. if ( $this->use_image_editor ) {
  220. // get the size from the image itself
  221. $image = wp_get_image_editor( $this->path );
  222. if ( ! is_wp_error( $image ) ) {
  223. $size = $image->get_size();
  224. return $size;
  225. }
  226. }
  227. return false;
  228. }
  229. /**
  230. * Return the file name for the required image size
  231. *
  232. * @param array $dest_size image dimensions (width/height) in pixels
  233. * @return string path and file name
  234. */
  235. private function get_destination_file_name( $dest_size ) {
  236. $info = pathinfo( $this->path );
  237. $dir = $info['dirname'];
  238. $ext = $info['extension'];
  239. $name = wp_basename( $this->path, ".$ext" );
  240. $dest_file_name = "{$dir}/{$name}-{$dest_size['width']}x{$dest_size['height']}.{$ext}";
  241. return $dest_file_name;
  242. }
  243. /**
  244. * Use WP_Image_Editor to create a resized image and return the URL for that image
  245. *
  246. * @param array $orig_size
  247. * @param array $dest_size
  248. * @return string
  249. */
  250. private function resize_image( $orig_size, $dest_size, $dest_file_name ) {
  251. // load image
  252. $image = wp_get_image_editor( $this->path );
  253. // editor will return an error if the path is invalid
  254. if ( is_wp_error( $image ) ) {
  255. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  256. if ( is_admin() && current_user_can( $capability ) ) {
  257. echo '<div id="message" class="error">';
  258. echo "<p><strong>ERROR</strong> Slide ID: {$this->id} - <i>" . $image->get_error_message() . "</i></p>";
  259. echo "</div>";
  260. }
  261. return $this->url;
  262. }
  263. $crop_position = $this->get_crop_position();
  264. $dims = image_resize_dimensions( $orig_size['width'], $orig_size['height'], $dest_size['width'], $dest_size['height'], $crop_position );
  265. if ( $dims ) {
  266. list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims;
  267. $image->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h );
  268. }
  269. $saved = $image->save( $dest_file_name );
  270. if ( is_wp_error( $saved ) ) {
  271. return $this->url;
  272. }
  273. // Record the new size so that the file is correctly removed when the media file is deleted.
  274. $backup_sizes = get_post_meta( $this->id, '_wp_attachment_backup_sizes', true );
  275. if ( ! is_array( $backup_sizes ) ) {
  276. $backup_sizes = array();
  277. }
  278. $backup_sizes["resized-{$dest_size['width']}x{$dest_size['height']}"] = $saved;
  279. update_post_meta( $this->id, '_wp_attachment_backup_sizes', $backup_sizes );
  280. $url = str_replace( basename( $this->url ), basename( $saved['path'] ), $this->url );
  281. return $url;
  282. }
  283. /**
  284. * Get the image crop position
  285. *
  286. * @return array
  287. */
  288. private function get_crop_position() {
  289. $crop_position = get_post_meta( $this->id, 'ml-slider_crop_position', true );
  290. if ( $crop_position ) {
  291. $parts = explode( "-", $crop_position );
  292. if ( isset( $parts[0], $parts[1] ) ) {
  293. return array($parts[0], $parts[1]);
  294. }
  295. }
  296. // default
  297. return array('center', 'center');
  298. }
  299. }