PageRenderTime 39ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/themes/news/library/extensions/get-the-image.php

https://bitbucket.org/lgorence/quickpress
PHP | 544 lines | 213 code | 101 blank | 230 comment | 47 complexity | df11075e687bc99caccc56ee229376e9 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, AGPL-1.0
  1. <?php
  2. /**
  3. * Get the Image - An advanced post image script for WordPress.
  4. *
  5. * Get the Image was created to be a highly-intuitive image script that displays post-specific images (an
  6. * image-based representation of a post). The script handles old-style post images via custom fields for
  7. * backwards compatibility. It also supports WordPress' built-in featured image functionality. On top of
  8. * those things, it can automatically set attachment images as the post image or scan the post content for
  9. * the first image element used. It can also fall back to a given default image.
  10. *
  11. * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
  12. * General Public License as published by the Free Software Foundation; either version 2 of the License,
  13. * or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
  16. * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. *
  18. * @package GetTheImage
  19. * @version 0.8.0
  20. * @author Justin Tadlock <justin@justintadlock.com>
  21. * @copyright Copyright (c) 2008 - 2012, Justin Tadlock
  22. * @link http://justintadlock.com/archives/2008/05/27/get-the-image-wordpress-plugin
  23. * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  24. */
  25. /* Adds theme support for WordPress 'featured images'. */
  26. add_theme_support( 'post-thumbnails' );
  27. /* Delete the cache when a post or post metadata is updated. */
  28. add_action( 'save_post', 'get_the_image_delete_cache_by_post' );
  29. add_action( 'deleted_post_meta', 'get_the_image_delete_cache_by_meta', 10, 2 );
  30. add_action( 'updated_post_meta', 'get_the_image_delete_cache_by_meta', 10, 2 );
  31. add_action( 'added_post_meta', 'get_the_image_delete_cache_by_meta', 10, 2 );
  32. /**
  33. * The main image function for displaying an image. It supports several arguments that allow developers to
  34. * customize how the script outputs the image.
  35. *
  36. * The image check order is important to note here. If an image is found by any specific check, the script
  37. * will no longer look for images. The check order is 'meta_key', 'the_post_thumbnail', 'attachment',
  38. * 'image_scan', 'callback', and 'default_image'.
  39. *
  40. * @since 0.1.0
  41. * @access public
  42. * @global $post The current post's database object.
  43. * @param array $args Arguments for how to load and display the image.
  44. * @return string|array The HTML for the image. | Image attributes in an array.
  45. */
  46. function get_the_image( $args = array() ) {
  47. /* Set the default arguments. */
  48. $defaults = array(
  49. 'meta_key' => array( 'Thumbnail', 'thumbnail' ), // array|string
  50. 'post_id' => get_the_ID(),
  51. 'attachment' => true,
  52. 'the_post_thumbnail' => true, // WP 2.9+ image function
  53. 'size' => 'thumbnail',
  54. 'default_image' => false,
  55. 'order_of_image' => 1,
  56. 'link_to_post' => true,
  57. 'image_class' => false,
  58. 'image_scan' => false,
  59. 'width' => false,
  60. 'height' => false,
  61. 'format' => 'img',
  62. 'meta_key_save' => false,
  63. 'thumbnail_id_save' => false, // Set 'featured image'.
  64. 'callback' => null,
  65. 'cache' => true,
  66. 'before' => '',
  67. 'after' => '',
  68. 'echo' => true,
  69. 'custom_key' => null, // @deprecated 0.6. Use 'meta_key'.
  70. 'default_size' => null, // @deprecated 0.5. Use 'size'.
  71. );
  72. /* Allow plugins/themes to filter the arguments. */
  73. $args = apply_filters( 'get_the_image_args', $args );
  74. /* Merge the input arguments and the defaults. */
  75. $args = wp_parse_args( $args, $defaults );
  76. /* If $default_size is given, overwrite $size. */
  77. if ( !is_null( $args['default_size'] ) )
  78. $args['size'] = $args['default_size']; // Deprecated 0.5 in favor of $size
  79. /* If $custom_key is set, overwrite $meta_key. */
  80. if ( !is_null( $args['custom_key'] ) )
  81. $args['meta_key'] = $args['custom_key']; // Deprecated 0.6 in favor of $meta_key
  82. /* If $format is set to 'array', don't link to the post. */
  83. if ( 'array' == $args['format'] )
  84. $args['link_to_post'] = false;
  85. /* Extract the array to allow easy use of variables. */
  86. extract( $args );
  87. /* Get cache key based on $args. */
  88. $key = md5( serialize( compact( array_keys( $args ) ) ) );
  89. /* Check for a cached image. */
  90. $image_cache = wp_cache_get( $post_id, 'get_the_image' );
  91. if ( !is_array( $image_cache ) )
  92. $image_cache = array();
  93. /* Set up a default, empty $image_html variable. */
  94. $image_html = '';
  95. /* If there is no cached image, let's see if one exists. */
  96. if ( !isset( $image_cache[$key] ) || empty( $cache ) ) {
  97. /* If a custom field key (array) is defined, check for images by custom field. */
  98. if ( !empty( $meta_key ) )
  99. $image = get_the_image_by_meta_key( $args );
  100. /* If no image found and $the_post_thumbnail is set to true, check for a post image (WP feature). */
  101. if ( empty( $image ) && !empty( $the_post_thumbnail ) )
  102. $image = get_the_image_by_post_thumbnail( $args );
  103. /* If no image found and $attachment is set to true, check for an image by attachment. */
  104. if ( empty( $image ) && !empty( $attachment ) )
  105. $image = get_the_image_by_attachment( $args );
  106. /* If no image found and $image_scan is set to true, scan the post for images. */
  107. if ( empty( $image ) && !empty( $image_scan ) )
  108. $image = get_the_image_by_scan( $args );
  109. /* If no image found and a callback function was given. Callback function must pass back array of <img> attributes. */
  110. if ( empty( $image ) && !is_null( $callback ) && function_exists( $callback ) )
  111. $image = call_user_func( $callback, $args );
  112. /* If no image found and a $default_image is set, get the default image. */
  113. if ( empty( $image ) && !empty( $default_image ) )
  114. $image = get_the_image_by_default( $args );
  115. /* If an image was found. */
  116. if ( !empty( $image ) ) {
  117. /* If $meta_key_save was set, save the image to a custom field. */
  118. if ( !empty( $meta_key_save ) )
  119. get_the_image_meta_key_save( $args, $image['src'] );
  120. /* Format the image HTML. */
  121. $image_html = get_the_image_format( $args, $image );
  122. /* Set the image cache for the specific post. */
  123. $image_cache[$key] = $image_html;
  124. wp_cache_set( $post_id, $image_cache, 'get_the_image' );
  125. }
  126. }
  127. /* If an image was already cached for the post and arguments, use it. */
  128. else {
  129. $image_html = $image_cache[$key];
  130. }
  131. /* Allow plugins/theme to override the final output. */
  132. $image_html = apply_filters( 'get_the_image', $image_html );
  133. /* If $format is set to 'array', return an array of image attributes. */
  134. if ( 'array' == $format ) {
  135. /* Set up a default empty array. */
  136. $out = array();
  137. /* Get the image attributes. */
  138. $atts = wp_kses_hair( $image_html, array( 'http' ) );
  139. /* Loop through the image attributes and add them in key/value pairs for the return array. */
  140. foreach ( $atts as $att )
  141. $out[$att['name']] = $att['value'];
  142. $out['url'] = $out['src']; // @deprecated 0.5 Use 'src' instead of 'url'.
  143. /* Return the array of attributes. */
  144. return $out;
  145. }
  146. /* Or, if $echo is set to false, return the formatted image. */
  147. elseif ( false === $echo ) {
  148. return $args['before'] . $image_html . $args['after'];
  149. }
  150. /* If there is a $post_thumbnail_id, do the actions associated with get_the_post_thumbnail(). */
  151. if ( isset( $image['post_thumbnail_id'] ) )
  152. do_action( 'begin_fetch_post_thumbnail_html', $post_id, $image['post_thumbnail_id'], $size );
  153. /* Display the image if we get to this point. */
  154. echo $args['before'] . $image_html . $args['after'];
  155. /* If there is a $post_thumbnail_id, do the actions associated with get_the_post_thumbnail(). */
  156. if ( isset( $image['post_thumbnail_id'] ) )
  157. do_action( 'end_fetch_post_thumbnail_html', $post_id, $image['post_thumbnail_id'], $size );
  158. }
  159. /* Internal Functions */
  160. /**
  161. * Calls images by custom field key. Script loops through multiple custom field keys. If that particular key
  162. * is found, $image is set and the loop breaks. If an image is found, it is returned.
  163. *
  164. * @since 0.7.0
  165. * @access private
  166. * @param array $args Arguments for how to load and display the image.
  167. * @return array|bool Array of image attributes. | False if no image is found.
  168. */
  169. function get_the_image_by_meta_key( $args = array() ) {
  170. /* If $meta_key is not an array. */
  171. if ( !is_array( $args['meta_key'] ) )
  172. $args['meta_key'] = array( $args['meta_key'] );
  173. /* Loop through each of the given meta keys. */
  174. foreach ( $args['meta_key'] as $meta_key ) {
  175. /* Get the image URL by the current meta key in the loop. */
  176. $image = get_post_meta( $args['post_id'], $meta_key, true );
  177. /* If an image was found, break out of the loop. */
  178. if ( !empty( $image ) )
  179. break;
  180. }
  181. /* If a custom key value has been given for one of the keys, return the image URL. */
  182. if ( !empty( $image ) )
  183. return array( 'src' => $image );
  184. return false;
  185. }
  186. /**
  187. * Checks for images using a custom version of the WordPress 2.9+ get_the_post_thumbnail() function.
  188. * If an image is found, return it and the $post_thumbnail_id. The WordPress function's other filters are
  189. * later added in the display_the_image() function.
  190. *
  191. * @since 0.7.0
  192. * @access private
  193. * @param array $args Arguments for how to load and display the image.
  194. * @return array|bool Array of image attributes. | False if no image is found.
  195. */
  196. function get_the_image_by_post_thumbnail( $args = array() ) {
  197. /* Check for a post image ID (set by WP as a custom field). */
  198. $post_thumbnail_id = get_post_thumbnail_id( $args['post_id'] );
  199. /* If no post image ID is found, return false. */
  200. if ( empty( $post_thumbnail_id ) )
  201. return false;
  202. /* Apply filters on post_thumbnail_size because this is a default WP filter used with its image feature. */
  203. $size = apply_filters( 'post_thumbnail_size', $args['size'] );
  204. /* Get the attachment image source. This should return an array. */
  205. $image = wp_get_attachment_image_src( $post_thumbnail_id, $size );
  206. /* Get the attachment excerpt to use as alt text. */
  207. $alt = trim( strip_tags( get_post_field( 'post_excerpt', $post_thumbnail_id ) ) );
  208. /* Return both the image URL and the post thumbnail ID. */
  209. return array( 'src' => $image[0], 'post_thumbnail_id' => $post_thumbnail_id, 'alt' => $alt );
  210. }
  211. /**
  212. * Check for attachment images. Uses get_children() to check if the post has images attached. If image
  213. * attachments are found, loop through each. The loop only breaks once $order_of_image is reached.
  214. *
  215. * @since 0.7.0
  216. * @access private
  217. * @param array $args Arguments for how to load and display the image.
  218. * @return array|bool Array of image attributes. | False if no image is found.
  219. */
  220. function get_the_image_by_attachment( $args = array() ) {
  221. /* Get the post type of the current post. */
  222. $post_type = get_post_type( $args['post_id'] );
  223. /* Check if the post itself is an image attachment. */
  224. if ( 'attachment' == $post_type && wp_attachment_is_image( $args['post_id'] ) ) {
  225. $attachment_id = $args['post_id'];
  226. }
  227. /* If the post is not an attachment, check if it has any image attachments. */
  228. elseif ( 'attachment' !== $post_type ) {
  229. /* Get attachments for the inputted $post_id. */
  230. $attachments = get_children(
  231. array(
  232. 'post_parent' => $args['post_id'],
  233. 'post_status' => 'inherit',
  234. 'post_type' => 'attachment',
  235. 'post_mime_type' => 'image',
  236. 'order' => 'ASC',
  237. 'orderby' => 'menu_order ID',
  238. 'suppress_filters' => true
  239. )
  240. );
  241. /* Check if any attachments were found. */
  242. if ( !empty( $attachments ) ) {
  243. /* Set the default iterator to 0. */
  244. $i = 0;
  245. /* Loop through each attachment. */
  246. foreach ( $attachments as $id => $attachment ) {
  247. /* Set the attachment ID as the current ID in the loop. */
  248. $attachment_id = $id;
  249. /* Break if/when we hit 'order_of_image'. */
  250. if ( ++$i == $args['order_of_image'] )
  251. break;
  252. }
  253. }
  254. }
  255. /* Check if we have an attachment ID before proceeding. */
  256. if ( !empty( $attachment_id ) ) {
  257. /* Get the attachment image. */
  258. $image = wp_get_attachment_image_src( $id, $args['size'] );
  259. /* Get the attachment excerpt. */
  260. $alt = trim( strip_tags( get_post_field( 'post_excerpt', $id ) ) );
  261. /* Save the attachment as the 'featured image'. */
  262. if ( true === $args['thumbnail_id_save'] )
  263. set_post_thumbnail( $args['post_id'], $id );
  264. /* Return the image URL. */
  265. return array( 'src' => $image[0], 'alt' => $alt );
  266. }
  267. /* Return false for anything else. */
  268. return false;
  269. }
  270. /**
  271. * Scans the post for images within the content. Not called by default with get_the_image(). Shouldn't use
  272. * if using large images within posts, better to use the other options.
  273. *
  274. * @since 0.7.0
  275. * @access private
  276. * @param array $args Arguments for how to load and display the image.
  277. * @return array|bool Array of image attributes. | False if no image is found.
  278. */
  279. function get_the_image_by_scan( $args = array() ) {
  280. /* Search the post's content for the <img /> tag and get its URL. */
  281. preg_match_all( '|<img.*?src=[\'"](.*?)[\'"].*?>|i', get_post_field( 'post_content', $args['post_id'] ), $matches );
  282. /* If there is a match for the image, return its URL. */
  283. if ( isset( $matches ) && !empty( $matches[1][0] ) )
  284. return array( 'src' => $matches[1][0] );
  285. return false;
  286. }
  287. /**
  288. * Used for setting a default image. The function simply returns the image URL it was given in an array.
  289. * Not used with get_the_image() by default.
  290. *
  291. * @since 0.7.0
  292. * @access private
  293. * @param array $args Arguments for how to load and display the image.
  294. * @return array|bool Array of image attributes. | False if no image is found.
  295. */
  296. function get_the_image_by_default( $args = array() ) {
  297. return array( 'src' => $args['default_image'] );
  298. }
  299. /**
  300. * Formats an image with appropriate alt text and class. Adds a link to the post if argument is set. Should
  301. * only be called if there is an image to display, but will handle it if not.
  302. *
  303. * @since 0.7.0
  304. * @access private
  305. * @param array $args Arguments for how to load and display the image.
  306. * @param array $image Array of image attributes ($image, $classes, $alt, $caption).
  307. * @return string $image Formatted image (w/link to post if the option is set).
  308. */
  309. function get_the_image_format( $args = array(), $image = false ) {
  310. /* If there is no image URL, return false. */
  311. if ( empty( $image['src'] ) )
  312. return false;
  313. /* Extract the arguments for easy-to-use variables. */
  314. extract( $args );
  315. /* If there is alt text, set it. Otherwise, default to the post title. */
  316. $image_alt = ( ( !empty( $image['alt'] ) ) ? $image['alt'] : apply_filters( 'the_title', get_post_field( 'post_title', $post_id ) ) );
  317. /* If there is a width or height, set them as HMTL-ready attributes. */
  318. $width = ( ( $width ) ? ' width="' . esc_attr( $width ) . '"' : '' );
  319. $height = ( ( $height ) ? ' height="' . esc_attr( $height ) . '"' : '' );
  320. /* Loop through the custom field keys and add them as classes. */
  321. if ( is_array( $meta_key ) ) {
  322. foreach ( $meta_key as $key )
  323. $classes[] = sanitize_html_class( $key );
  324. }
  325. /* Add the $size and any user-added $image_class to the class. */
  326. $classes[] = sanitize_html_class( $size );
  327. $classes[] = sanitize_html_class( $image_class );
  328. /* Join all the classes into a single string and make sure there are no duplicates. */
  329. $class = join( ' ', array_unique( $classes ) );
  330. /* Add the image attributes to the <img /> element. */
  331. $html = '<img src="' . $image['src'] . '" alt="' . esc_attr( strip_tags( $image_alt ) ) . '" class="' . esc_attr( $class ) . '"' . $width . $height . ' />';
  332. /* If $link_to_post is set to true, link the image to its post. */
  333. if ( $link_to_post )
  334. $html = '<a href="' . get_permalink( $post_id ) . '" title="' . esc_attr( apply_filters( 'the_title', get_post_field( 'post_title', $post_id ) ) ) . '">' . $html . '</a>';
  335. /* If there is a $post_thumbnail_id, apply the WP filters normally associated with get_the_post_thumbnail(). */
  336. if ( !empty( $image['post_thumbnail_id'] ) )
  337. $html = apply_filters( 'post_thumbnail_html', $html, $post_id, $image['post_thumbnail_id'], $size, '' );
  338. return $html;
  339. }
  340. /**
  341. * Saves the image URL as the value of the meta key provided. This allows users to set a custom meta key
  342. * for their image. By doing this, users can trim off database queries when grabbing attachments or get rid
  343. * of expensive scans of the content when using the image scan feature.
  344. *
  345. * @since 0.6.0
  346. * @access private
  347. * @param array $args Arguments for how to load and display the image.
  348. * @param array $image Array of image attributes ($image, $classes, $alt, $caption).
  349. */
  350. function get_the_image_meta_key_save( $args = array(), $image = array() ) {
  351. /* If the $meta_key_save argument is empty or there is no image $url given, return. */
  352. if ( empty( $args['meta_key_save'] ) || empty( $image['src'] ) )
  353. return;
  354. /* Get the current value of the meta key. */
  355. $meta = get_post_meta( $args['post_id'], $args['meta_key_save'], true );
  356. /* If there is no value for the meta key, set a new value with the image $url. */
  357. if ( empty( $meta ) )
  358. add_post_meta( $args['post_id'], $args['meta_key_save'], $image['src'] );
  359. /* If the current value doesn't match the image $url, update it. */
  360. elseif ( $meta !== $image['src'] )
  361. update_post_meta( $args['post_id'], $args['meta_key_save'], $image['src'], $meta );
  362. }
  363. /**
  364. * Deletes the image cache for the specific post when the 'save_post' hook is fired.
  365. *
  366. * @since 0.7.0
  367. * @access private
  368. * @param int $post_id The ID of the post to delete the cache for.
  369. * @return void
  370. */
  371. function get_the_image_delete_cache_by_post( $post_id ) {
  372. wp_cache_delete( $post_id, 'get_the_image' );
  373. }
  374. /**
  375. * Deletes the image cache for a specific post when the 'added_post_meta', 'deleted_post_meta',
  376. * or 'updated_post_meta' hooks are called.
  377. *
  378. * @since 0.7.0
  379. * @access private
  380. * @param int $meta_id The ID of the metadata being updated.
  381. * @param int $post_id The ID of the post to delete the cache for.
  382. * @return void
  383. */
  384. function get_the_image_delete_cache_by_meta( $meta_id, $post_id ) {
  385. wp_cache_delete( $post_id, 'get_the_image' );
  386. }
  387. /**
  388. * @since 0.1.0
  389. * @deprecated 0.3.0
  390. */
  391. function get_the_image_link( $deprecated = '', $deprecated_2 = '', $deprecated_3 = '' ) {
  392. get_the_image();
  393. }
  394. /**
  395. * @since 0.3.0
  396. * @deprecated 0.7.0
  397. */
  398. function image_by_custom_field( $args = array() ) {
  399. return get_the_image_by_meta_key( $args );
  400. }
  401. /**
  402. * @since 0.4.0
  403. * @deprecated 0.7.0
  404. */
  405. function image_by_the_post_thumbnail( $args = array() ) {
  406. return get_the_image_by_post_thumbnail( $args );
  407. }
  408. /**
  409. * @since 0.3.0
  410. * @deprecated 0.7.0
  411. */
  412. function image_by_attachment( $args = array() ) {
  413. return get_the_image_by_attachment( $args );
  414. }
  415. /**
  416. * @since 0.3.0
  417. * @deprecated 0.7.0
  418. */
  419. function image_by_scan( $args = array() ) {
  420. return get_the_image_by_scan( $args );
  421. }
  422. /**
  423. * @since 0.3.0
  424. * @deprecated 0.7.0
  425. */
  426. function image_by_default( $args = array() ) {
  427. return get_the_image_by_default( $args );
  428. }
  429. /**
  430. * @since 0.1.0
  431. * @deprecated 0.7.0
  432. */
  433. function display_the_image( $args = array(), $image = false ) {
  434. return get_the_image_format( $args, $image );
  435. }
  436. /**
  437. * @since 0.5.0
  438. * @deprecated 0.7.0 Replaced by cache delete functions specifically for the post ID.
  439. */
  440. function get_the_image_delete_cache() {
  441. return;
  442. }
  443. ?>