Bez popisu

class.jetpack-photon-image.php 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <?php
  2. /**
  3. * The Image Class.
  4. *
  5. * @package automattic/jetpack
  6. */
  7. /**
  8. * Represents a resizable image, exposing properties necessary for properly generating srcset.
  9. */
  10. class Jetpack_Photon_Image {
  11. /**
  12. * @var string $filename Attachment's Filename.
  13. */
  14. public $filename;
  15. /**
  16. * @var string/WP_Erorr $mime_type Attachment's mime-type, WP_Error on failure when recalculating the dimensions.
  17. */
  18. private $mime_type;
  19. /**
  20. * @var int $original_width Image original width.
  21. */
  22. private $original_width;
  23. /**
  24. * @var int $original_width Image original height.
  25. */
  26. private $original_height;
  27. /**
  28. * @var int $width Current attachment's width.
  29. */
  30. private $width;
  31. /**
  32. * @var int $height Current attachment's height.
  33. */
  34. private $height;
  35. /**
  36. * @var bool $is_resized Whether the attachment has been resized yet, or not.
  37. */
  38. private $is_resized = false;
  39. /**
  40. * Constructs the image object.
  41. *
  42. * The $data array should provide at least
  43. * file : string Image file path
  44. * width : int Image width
  45. * height : int Image height
  46. *
  47. * @param array $data Array of attachment metadata, typically value of _wp_attachment_metadata postmeta
  48. * @param string|\WP_Error $mime_type Typically value returned from get_post_mime_type function.
  49. */
  50. public function __construct( $data, $mime_type ) {
  51. $this->filename = $data['file'];
  52. $this->width = $this->original_width = $data['width'];
  53. $this->height = $this->original_height = $data['height'];
  54. $this->mime_type = $mime_type;
  55. }
  56. /**
  57. * Resizes the image to given size.
  58. *
  59. * @param array $size_data Array of width, height, and crop properties of a size.
  60. *
  61. * @return bool|\WP_Error True if resize was successful, WP_Error on failure.
  62. */
  63. public function resize( $size_data ) {
  64. $dimensions = $this->image_resize_dimensions( $size_data['width'], $size_data['height'], $size_data['crop'] );
  65. if ( true === is_wp_error( $dimensions ) ) {
  66. return $dimensions; // Returns \WP_Error.
  67. }
  68. if ( true === is_wp_error( $this->mime_type ) ) {
  69. return $this->mime_type; // Returns \WP_Error.
  70. }
  71. $this->set_width_height( $dimensions );
  72. return $this->is_resized = true;
  73. }
  74. /**
  75. * Generates size data for usage in $metadata['sizes'];.
  76. *
  77. * @param array $size_data Array of width, height, and crop properties of a size.
  78. *
  79. * @return array|\WP_Error An array containing file, width, height, and mime-type keys and it's values. WP_Error on failure.
  80. */
  81. public function get_size( $size_data ) {
  82. $is_resized = $this->resize( $size_data );
  83. if ( true === is_wp_error( $is_resized ) ) {
  84. return $is_resized;
  85. }
  86. return array(
  87. 'file' => $this->get_filename(),
  88. 'width' => $this->get_width(),
  89. 'height' => $this->get_height(),
  90. 'mime-type' => $this->get_mime_type(),
  91. );
  92. }
  93. /**
  94. * Resets the image to it's original dimensions.
  95. *
  96. * @return bool True on successful reset to original dimensions.
  97. */
  98. public function reset_to_original() {
  99. $this->width = $this->original_width;
  100. $this->height = $this->original_height;
  101. $this->is_resized = false;
  102. return true;
  103. }
  104. /**
  105. * Return the basename filename. If the image has been resized, including
  106. * the resizing params for Jetpack CDN.
  107. *
  108. * @return string Basename of the filename.
  109. */
  110. public function get_filename() {
  111. return wp_basename( $this->get_raw_filename() );
  112. }
  113. /**
  114. * Return the absolute filename. If the image has been resized, including
  115. * the resizing params for Jetpack CDN.
  116. *
  117. * @return string Filename.
  118. */
  119. public function get_raw_filename() {
  120. return $this->is_resized() ? $this->get_resized_filename() : $this->filename;
  121. }
  122. /**
  123. * Returns current image width. Either original, or after resize.
  124. *
  125. * @return int
  126. */
  127. public function get_width() {
  128. return (int) $this->width;
  129. }
  130. /**
  131. * Returns current image height. Either original, or after resize.
  132. *
  133. * @return int
  134. */
  135. public function get_height() {
  136. return (int) $this->height;
  137. }
  138. /**
  139. * Returns image mime type.
  140. *
  141. * @return string|WP_Error Image's mime type or WP_Error if it was not determined.
  142. */
  143. public function get_mime_type() {
  144. return $this->mime_type;
  145. }
  146. /**
  147. * Checks the resize status of the image.
  148. *
  149. * @return bool If the image has been resized.
  150. */
  151. public function is_resized() {
  152. return ( true === $this->is_resized );
  153. }
  154. /**
  155. * Get filename with proper args for the Photon service.
  156. *
  157. * @return string Filename with query args for Photon service
  158. */
  159. protected function get_resized_filename() {
  160. $query_args = array(
  161. 'resize' => join(
  162. ',',
  163. array(
  164. $this->get_width(),
  165. $this->get_height(),
  166. )
  167. ),
  168. );
  169. return add_query_arg( $query_args, $this->filename );
  170. }
  171. /**
  172. * Get resize dimensions used for the Jetpack CDN service.
  173. *
  174. * Converts the list of values returned from `image_resize_dimensions()` to
  175. * associative array for the sake of more readable code no relying on index
  176. * nor `list`.
  177. *
  178. * @param int $max_width
  179. * @param int $max_height
  180. * @param bool|array $crop
  181. *
  182. * @return array|\WP_Error Array of dimensions matching the parameters to imagecopyresampled. WP_Error on failure.
  183. */
  184. protected function image_resize_dimensions( $max_width, $max_height, $crop ) {
  185. $dimensions = image_resize_dimensions( $this->original_width, $this->original_height, $max_width, $max_height, $crop );
  186. if ( ! $dimensions ) {
  187. return new WP_Error( 'error_getting_dimensions', __( 'Could not calculate resized image dimensions' ), $this->filename );
  188. }
  189. return array_combine(
  190. array(
  191. 'dst_x',
  192. 'dst_y',
  193. 'src_x',
  194. 'src_y',
  195. 'dst_w',
  196. 'dst_h',
  197. 'src_w',
  198. 'src_h',
  199. ),
  200. $dimensions
  201. );
  202. }
  203. /**
  204. * Sets proper width and height from dimensions.
  205. *
  206. * @param array $dimensions an array of image dimensions.
  207. * @return void
  208. */
  209. protected function set_width_height( $dimensions ) {
  210. $this->width = (int) $dimensions['dst_w'];
  211. $this->height = (int) $dimensions['dst_h'];
  212. }
  213. }