PageRenderTime 36ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-includes/class-wp-image-editor.php

https://gitlab.com/Gashler/dp
PHP | 403 lines | 126 code | 48 blank | 229 comment | 22 complexity | 5518e3700d780e3b0be8d97efff17213 MD5 | raw file
  1. <?php
  2. /**
  3. * Base WordPress Image Editor
  4. *
  5. * @package WordPress
  6. * @subpackage Image_Editor
  7. */
  8. /**
  9. * Base image editor class from which implementations extend
  10. *
  11. * @since 3.5.0
  12. */
  13. abstract class WP_Image_Editor {
  14. protected $file = null;
  15. protected $size = null;
  16. protected $mime_type = null;
  17. protected $default_mime_type = 'image/jpeg';
  18. protected $quality = 90;
  19. /**
  20. * Each instance handles a single file.
  21. */
  22. public function __construct( $file ) {
  23. $this->file = $file;
  24. }
  25. /**
  26. * Checks to see if current environment supports the editor chosen.
  27. * Must be overridden in a sub-class.
  28. *
  29. * @since 3.5.0
  30. * @access public
  31. * @abstract
  32. *
  33. * @param array $args
  34. * @return boolean
  35. */
  36. public static function test( $args = array() ) {
  37. return false;
  38. }
  39. /**
  40. * Checks to see if editor supports the mime-type specified.
  41. * Must be overridden in a sub-class.
  42. *
  43. * @since 3.5.0
  44. * @access public
  45. * @abstract
  46. *
  47. * @param string $mime_type
  48. * @return boolean
  49. */
  50. public static function supports_mime_type( $mime_type ) {
  51. return false;
  52. }
  53. /**
  54. * Loads image from $this->file into editor.
  55. *
  56. * @since 3.5.0
  57. * @access protected
  58. * @abstract
  59. *
  60. * @return boolean|WP_Error True if loaded; WP_Error on failure.
  61. */
  62. abstract public function load();
  63. /**
  64. * Saves current image to file.
  65. *
  66. * @since 3.5.0
  67. * @access public
  68. * @abstract
  69. *
  70. * @param string $destfilename
  71. * @param string $mime_type
  72. * @return array|WP_Error {'path'=>string, 'file'=>string, 'width'=>int, 'height'=>int, 'mime-type'=>string}
  73. */
  74. abstract public function save( $destfilename = null, $mime_type = null );
  75. /**
  76. * Resizes current image.
  77. *
  78. * @since 3.5.0
  79. * @access public
  80. * @abstract
  81. *
  82. * @param int $max_w
  83. * @param int $max_h
  84. * @param boolean $crop
  85. * @return boolean|WP_Error
  86. */
  87. abstract public function resize( $max_w, $max_h, $crop = false );
  88. /**
  89. * Processes current image and saves to disk
  90. * multiple sizes from single source.
  91. *
  92. * 'width' and 'height' are required.
  93. * 'crop' defaults to false when not provided.
  94. *
  95. * @since 3.5.0
  96. * @access public
  97. * @abstract
  98. *
  99. * @param array $sizes { {'width'=>int, 'height'=>int, ['crop'=>bool]}, ... }
  100. * @return array
  101. */
  102. abstract public function multi_resize( $sizes );
  103. /**
  104. * Crops Image.
  105. *
  106. * @since 3.5.0
  107. * @access public
  108. * @abstract
  109. *
  110. * @param string|int $src The source file or Attachment ID.
  111. * @param int $src_x The start x position to crop from.
  112. * @param int $src_y The start y position to crop from.
  113. * @param int $src_w The width to crop.
  114. * @param int $src_h The height to crop.
  115. * @param int $dst_w Optional. The destination width.
  116. * @param int $dst_h Optional. The destination height.
  117. * @param boolean $src_abs Optional. If the source crop points are absolute.
  118. * @return boolean|WP_Error
  119. */
  120. abstract public function crop( $src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = null, $src_abs = false );
  121. /**
  122. * Rotates current image counter-clockwise by $angle.
  123. *
  124. * @since 3.5.0
  125. * @access public
  126. * @abstract
  127. *
  128. * @param float $angle
  129. * @return boolean|WP_Error
  130. */
  131. abstract public function rotate( $angle );
  132. /**
  133. * Flips current image.
  134. *
  135. * @since 3.5.0
  136. * @access public
  137. * @abstract
  138. *
  139. * @param boolean $horz Flip along Horizontal Axis
  140. * @param boolean $vert Flip along Vertical Axis
  141. * @return boolean|WP_Error
  142. */
  143. abstract public function flip( $horz, $vert );
  144. /**
  145. * Streams current image to browser.
  146. *
  147. * @since 3.5.0
  148. * @access public
  149. * @abstract
  150. *
  151. * @param string $mime_type
  152. * @return boolean|WP_Error
  153. */
  154. abstract public function stream( $mime_type = null );
  155. /**
  156. * Gets dimensions of image.
  157. *
  158. * @since 3.5.0
  159. * @access public
  160. *
  161. * @return array {'width'=>int, 'height'=>int}
  162. */
  163. public function get_size() {
  164. return $this->size;
  165. }
  166. /**
  167. * Sets current image size.
  168. *
  169. * @since 3.5.0
  170. * @access protected
  171. *
  172. * @param int $width
  173. * @param int $height
  174. */
  175. protected function update_size( $width = null, $height = null ) {
  176. $this->size = array(
  177. 'width' => (int) $width,
  178. 'height' => (int) $height
  179. );
  180. return true;
  181. }
  182. /**
  183. * Sets Image Compression quality on a 1-100% scale.
  184. *
  185. * @since 3.5.0
  186. * @access public
  187. *
  188. * @param int $quality Compression Quality. Range: [1,100]
  189. * @return boolean
  190. */
  191. public function set_quality( $quality ) {
  192. $this->quality = apply_filters( 'wp_editor_set_quality', $quality );
  193. return ( (bool) $this->quality );
  194. }
  195. /**
  196. * Returns preferred mime-type and extension based on provided
  197. * file's extension and mime, or current file's extension and mime.
  198. *
  199. * Will default to $this->default_mime_type if requested is not supported.
  200. *
  201. * Provides corrected filename only if filename is provided.
  202. *
  203. * @since 3.5.0
  204. * @access protected
  205. *
  206. * @param string $filename
  207. * @param string $mime_type
  208. * @return array { filename|null, extension, mime-type }
  209. */
  210. protected function get_output_format( $filename = null, $mime_type = null ) {
  211. $new_ext = $file_ext = null;
  212. $file_mime = null;
  213. // By default, assume specified type takes priority
  214. if ( $mime_type ) {
  215. $new_ext = $this->get_extension( $mime_type );
  216. }
  217. if ( $filename ) {
  218. $file_ext = strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) );
  219. $file_mime = $this->get_mime_type( $file_ext );
  220. }
  221. else {
  222. // If no file specified, grab editor's current extension and mime-type.
  223. $file_ext = strtolower( pathinfo( $this->file, PATHINFO_EXTENSION ) );
  224. $file_mime = $this->mime_type;
  225. }
  226. // Check to see if specified mime-type is the same as type implied by
  227. // file extension. If so, prefer extension from file.
  228. if ( ! $mime_type || ( $file_mime == $mime_type ) ) {
  229. $mime_type = $file_mime;
  230. $new_ext = $file_ext;
  231. }
  232. // Double-check that the mime-type selected is supported by the editor.
  233. // If not, choose a default instead.
  234. if ( ! $this->supports_mime_type( $mime_type ) ) {
  235. $mime_type = apply_filters( 'image_editor_default_mime_type', $this->default_mime_type );
  236. $new_ext = $this->get_extension( $mime_type );
  237. }
  238. if ( $filename ) {
  239. $ext = '';
  240. $info = pathinfo( $filename );
  241. $dir = $info['dirname'];
  242. if( isset( $info['extension'] ) )
  243. $ext = $info['extension'];
  244. $filename = trailingslashit( $dir ) . wp_basename( $filename, ".$ext" ) . ".{$new_ext}";
  245. }
  246. return array( $filename, $new_ext, $mime_type );
  247. }
  248. /**
  249. * Builds an output filename based on current file, and adding proper suffix
  250. *
  251. * @since 3.5.0
  252. * @access public
  253. *
  254. * @param string $suffix
  255. * @param string $dest_path
  256. * @param string $extension
  257. * @return string filename
  258. */
  259. public function generate_filename( $suffix = null, $dest_path = null, $extension = null ) {
  260. // $suffix will be appended to the destination filename, just before the extension
  261. if ( ! $suffix )
  262. $suffix = $this->get_suffix();
  263. $info = pathinfo( $this->file );
  264. $dir = $info['dirname'];
  265. $ext = $info['extension'];
  266. $name = wp_basename( $this->file, ".$ext" );
  267. $new_ext = strtolower( $extension ? $extension : $ext );
  268. if ( ! is_null( $dest_path ) && $_dest_path = realpath( $dest_path ) )
  269. $dir = $_dest_path;
  270. return trailingslashit( $dir ) . "{$name}-{$suffix}.{$new_ext}";
  271. }
  272. /**
  273. * Builds and returns proper suffix for file based on height and width.
  274. *
  275. * @since 3.5.0
  276. * @access public
  277. *
  278. * @return string suffix
  279. */
  280. public function get_suffix() {
  281. if ( ! $this->get_size() )
  282. return false;
  283. return "{$this->size['width']}x{$this->size['height']}";
  284. }
  285. /**
  286. * Either calls editor's save function or handles file as a stream.
  287. *
  288. * @since 3.5.0
  289. * @access protected
  290. *
  291. * @param string|stream $filename
  292. * @param callable $function
  293. * @param array $arguments
  294. * @return boolean
  295. */
  296. protected function make_image( $filename, $function, $arguments ) {
  297. if ( $stream = wp_is_stream( $filename ) ) {
  298. ob_start();
  299. } else {
  300. // The directory containing the original file may no longer exist when using a replication plugin.
  301. wp_mkdir_p( dirname( $filename ) );
  302. }
  303. $result = call_user_func_array( $function, $arguments );
  304. if ( $result && $stream ) {
  305. $contents = ob_get_contents();
  306. $fp = fopen( $filename, 'w' );
  307. if ( ! $fp )
  308. return false;
  309. fwrite( $fp, $contents );
  310. fclose( $fp );
  311. }
  312. if ( $stream ) {
  313. ob_end_clean();
  314. }
  315. return $result;
  316. }
  317. /**
  318. * Returns first matched mime-type from extension,
  319. * as mapped from wp_get_mime_types()
  320. *
  321. * @since 3.5.0
  322. * @access protected
  323. *
  324. * @param string $extension
  325. * @return string|boolean
  326. */
  327. protected static function get_mime_type( $extension = null ) {
  328. if ( ! $extension )
  329. return false;
  330. $mime_types = wp_get_mime_types();
  331. $extensions = array_keys( $mime_types );
  332. foreach( $extensions as $_extension ) {
  333. if ( preg_match( "/{$extension}/i", $_extension ) ) {
  334. return $mime_types[$_extension];
  335. }
  336. }
  337. return false;
  338. }
  339. /**
  340. * Returns first matched extension from Mime-type,
  341. * as mapped from wp_get_mime_types()
  342. *
  343. * @since 3.5.0
  344. * @access protected
  345. *
  346. * @param string $mime_type
  347. * @return string|boolean
  348. */
  349. protected static function get_extension( $mime_type = null ) {
  350. $extensions = explode( '|', array_search( $mime_type, wp_get_mime_types() ) );
  351. if ( empty( $extensions[0] ) )
  352. return false;
  353. return $extensions[0];
  354. }
  355. }