PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/jetpack/class.photon.php

https://gitlab.com/juanito.abelo/nlmobile
PHP | 619 lines | 331 code | 109 blank | 179 comment | 119 complexity | 27c9321c468f5592d866194202062281 MD5 | raw file
  1. <?php
  2. class Jetpack_Photon {
  3. /**
  4. * Class variables
  5. */
  6. // Oh look, a singleton
  7. private static $__instance = null;
  8. // Allowed extensions must match http://code.trac.wordpress.org/browser/photon/index.php#L31
  9. protected static $extensions = array(
  10. 'gif',
  11. 'jpg',
  12. 'jpeg',
  13. 'png'
  14. );
  15. // Don't access this directly. Instead, use self::image_sizes() so it's actually populated with something.
  16. protected static $image_sizes = null;
  17. /**
  18. * Singleton implementation
  19. *
  20. * @return object
  21. */
  22. public static function instance() {
  23. if ( ! is_a( self::$__instance, 'Jetpack_Photon' ) ) {
  24. self::$__instance = new Jetpack_Photon;
  25. self::$__instance->setup();
  26. }
  27. return self::$__instance;
  28. }
  29. /**
  30. * Silence is golden.
  31. */
  32. private function __construct() {}
  33. /**
  34. * Register actions and filters, but only if basic Photon functions are available.
  35. * The basic functions are found in ./functions.photon.php.
  36. *
  37. * @uses add_action, add_filter
  38. * @return null
  39. */
  40. private function setup() {
  41. // Display warning if site is private
  42. add_action( 'jetpack_activate_module_photon', array( $this, 'action_jetpack_activate_module_photon' ) );
  43. if ( ! function_exists( 'jetpack_photon_url' ) )
  44. return;
  45. // Images in post content and galleries
  46. add_filter( 'the_content', array( __CLASS__, 'filter_the_content' ), 999999 );
  47. add_filter( 'get_post_galleries', array( __CLASS__, 'filter_the_galleries' ), 999999 );
  48. // Core image retrieval
  49. add_filter( 'image_downsize', array( $this, 'filter_image_downsize' ), 10, 3 );
  50. // Helpers for maniuplated images
  51. add_action( 'wp_enqueue_scripts', array( $this, 'action_wp_enqueue_scripts' ), 9 );
  52. }
  53. /**
  54. * Check if site is private and warn user if it is
  55. *
  56. * @uses Jetpack::check_privacy
  57. * @action jetpack_activate_module_photon
  58. * @return null
  59. */
  60. public function action_jetpack_activate_module_photon() {
  61. Jetpack::check_privacy( __FILE__ );
  62. }
  63. /**
  64. ** IN-CONTENT IMAGE MANIPULATION FUNCTIONS
  65. **/
  66. /**
  67. * Match all images and any relevant <a> tags in a block of HTML.
  68. *
  69. * @param string $content Some HTML.
  70. * @return array An array of $images matches, where $images[0] is
  71. * an array of full matches, and the link_url, img_tag,
  72. * and img_url keys are arrays of those matches.
  73. */
  74. public static function parse_images_from_html( $content ) {
  75. $images = array();
  76. if ( preg_match_all( '#(?:<a[^>]+?href=["|\'](?P<link_url>[^\s]+?)["|\'][^>]*?>\s*)?(?P<img_tag><img[^>]+?src=["|\'](?P<img_url>[^\s]+?)["|\'].*?>){1}(?:\s*</a>)?#is', $content, $images ) ) {
  77. foreach ( $images as $key => $unused ) {
  78. // Simplify the output as much as possible, mostly for confirming test results.
  79. if ( is_numeric( $key ) && $key > 0 )
  80. unset( $images[$key] );
  81. }
  82. return $images;
  83. }
  84. return array();
  85. }
  86. /**
  87. * Try to determine height and width from strings WP appends to resized image filenames.
  88. *
  89. * @param string $src The image URL.
  90. * @return array An array consisting of width and height.
  91. */
  92. public static function parse_dimensions_from_filename( $src ) {
  93. $width_height_string = array();
  94. if ( preg_match( '#-(\d+)x(\d+)\.(?:' . implode('|', self::$extensions ) . '){1}$#i', $src, $width_height_string ) ) {
  95. $width = (int) $width_height_string[1];
  96. $height = (int) $width_height_string[2];
  97. if ( $width && $height )
  98. return array( $width, $height );
  99. }
  100. return array( false, false );
  101. }
  102. /**
  103. * Identify images in post content, and if images are local (uploaded to the current site), pass through Photon.
  104. *
  105. * @param string $content
  106. * @uses self::validate_image_url, apply_filters, jetpack_photon_url, esc_url
  107. * @filter the_content
  108. * @return string
  109. */
  110. public static function filter_the_content( $content ) {
  111. $images = Jetpack_Photon::parse_images_from_html( $content );
  112. if ( ! empty( $images ) ) {
  113. $content_width = Jetpack::get_content_width();
  114. $image_sizes = self::image_sizes();
  115. $upload_dir = wp_upload_dir();
  116. foreach ( $images[0] as $index => $tag ) {
  117. // Default to resize, though fit may be used in certain cases where a dimension cannot be ascertained
  118. $transform = 'resize';
  119. // Start with a clean attachment ID each time
  120. $attachment_id = false;
  121. // Flag if we need to munge a fullsize URL
  122. $fullsize_url = false;
  123. // Identify image source
  124. $src = $src_orig = $images['img_url'][ $index ];
  125. // Allow specific images to be skipped
  126. if ( apply_filters( 'jetpack_photon_skip_image', false, $src, $tag ) )
  127. continue;
  128. // Support Automattic's Lazy Load plugin
  129. // Can't modify $tag yet as we need unadulterated version later
  130. if ( preg_match( '#data-lazy-src=["|\'](.+?)["|\']#i', $images['img_tag'][ $index ], $lazy_load_src ) ) {
  131. $placeholder_src = $placeholder_src_orig = $src;
  132. $src = $src_orig = $lazy_load_src[1];
  133. } elseif ( preg_match( '#data-lazy-original=["|\'](.+?)["|\']#i', $images['img_tag'][ $index ], $lazy_load_src ) ) {
  134. $placeholder_src = $placeholder_src_orig = $src;
  135. $src = $src_orig = $lazy_load_src[1];
  136. }
  137. // Check if image URL should be used with Photon
  138. if ( self::validate_image_url( $src ) ) {
  139. // Find the width and height attributes
  140. $width = $height = false;
  141. // First, check the image tag
  142. if ( preg_match( '#width=["|\']?([\d%]+)["|\']?#i', $images['img_tag'][ $index ], $width_string ) )
  143. $width = $width_string[1];
  144. if ( preg_match( '#height=["|\']?([\d%]+)["|\']?#i', $images['img_tag'][ $index ], $height_string ) )
  145. $height = $height_string[1];
  146. // Can't pass both a relative width and height, so unset the height in favor of not breaking the horizontal layout.
  147. if ( false !== strpos( $width, '%' ) && false !== strpos( $height, '%' ) )
  148. $width = $height = false;
  149. // Detect WP registered image size from HTML class
  150. if ( preg_match( '#class=["|\']?[^"\']*size-([^"\'\s]+)[^"\']*["|\']?#i', $images['img_tag'][ $index ], $size ) ) {
  151. $size = array_pop( $size );
  152. if ( false === $width && false === $height && 'full' != $size && array_key_exists( $size, $image_sizes ) ) {
  153. $width = (int) $image_sizes[ $size ]['width'];
  154. $height = (int) $image_sizes[ $size ]['height'];
  155. $transform = $image_sizes[ $size ]['crop'] ? 'resize' : 'fit';
  156. }
  157. } else {
  158. unset( $size );
  159. }
  160. // WP Attachment ID, if uploaded to this site
  161. if ( preg_match( '#class=["|\']?[^"\']*wp-image-([\d]+)[^"\']*["|\']?#i', $images['img_tag'][ $index ], $attachment_id ) && ( 0 === strpos( $src, $upload_dir['baseurl'] ) || apply_filters( 'jetpack_photon_image_is_local', false, compact( 'src', 'tag', 'images', 'index' ) ) ) ) {
  162. $attachment_id = intval( array_pop( $attachment_id ) );
  163. if ( $attachment_id ) {
  164. $attachment = get_post( $attachment_id );
  165. // Basic check on returned post object
  166. if ( is_object( $attachment ) && ! is_wp_error( $attachment ) && 'attachment' == $attachment->post_type ) {
  167. $src_per_wp = wp_get_attachment_image_src( $attachment_id, isset( $size ) ? $size : 'full' );
  168. if ( self::validate_image_url( $src_per_wp[0] ) ) {
  169. $src = $src_per_wp[0];
  170. $fullsize_url = true;
  171. // Prevent image distortion if a detected dimension exceeds the image's natural dimensions
  172. if ( ( false !== $width && $width > $src_per_wp[1] ) || ( false !== $height && $height > $src_per_wp[2] ) ) {
  173. $width = false == $width ? false : min( $width, $src_per_wp[1] );
  174. $height = false == $height ? false : min( $height, $src_per_wp[2] );
  175. }
  176. // If no width and height are found, max out at source image's natural dimensions
  177. // Otherwise, respect registered image sizes' cropping setting
  178. if ( false == $width && false == $height ) {
  179. $width = $src_per_wp[1];
  180. $height = $src_per_wp[2];
  181. $transform = 'fit';
  182. } elseif ( isset( $size ) && array_key_exists( $size, $image_sizes ) && isset( $image_sizes[ $size ]['crop'] ) ) {
  183. $transform = (bool) $image_sizes[ $size ]['crop'] ? 'resize' : 'fit';
  184. }
  185. }
  186. } else {
  187. unset( $attachment_id );
  188. unset( $attachment );
  189. }
  190. }
  191. }
  192. // If image tag lacks width and height arguments, try to determine from strings WP appends to resized image filenames.
  193. if ( false === $width && false === $height ) {
  194. list( $width, $height ) = Jetpack_Photon::parse_dimensions_from_filename( $src );
  195. }
  196. // If width is available, constrain to $content_width
  197. if ( false !== $width && false === strpos( $width, '%' ) && is_numeric( $content_width ) ) {
  198. if ( $width > $content_width && false !== $height && false === strpos( $height, '%' ) ) {
  199. $height = round( ( $content_width * $height ) / $width );
  200. $width = $content_width;
  201. } elseif ( $width > $content_width ) {
  202. $width = $content_width;
  203. }
  204. }
  205. // Set a width if none is found and $content_width is available
  206. // If width is set in this manner and height is available, use `fit` instead of `resize` to prevent skewing
  207. if ( false === $width && is_numeric( $content_width ) ) {
  208. $width = (int) $content_width;
  209. if ( false !== $height )
  210. $transform = 'fit';
  211. }
  212. // Detect if image source is for a custom-cropped thumbnail and prevent further URL manipulation.
  213. if ( ! $fullsize_url && preg_match_all( '#-e[a-z0-9]+(-\d+x\d+)?\.(' . implode('|', self::$extensions ) . '){1}$#i', basename( $src ), $filename ) )
  214. $fullsize_url = true;
  215. // Build URL, first maybe removing WP's resized string so we pass the original image to Photon
  216. if ( ! $fullsize_url ) {
  217. $src = self::strip_image_dimensions_maybe( $src );
  218. }
  219. // Build array of Photon args and expose to filter before passing to Photon URL function
  220. $args = array();
  221. if ( false !== $width && false !== $height && false === strpos( $width, '%' ) && false === strpos( $height, '%' ) )
  222. $args[ $transform ] = $width . ',' . $height;
  223. elseif ( false !== $width )
  224. $args['w'] = $width;
  225. elseif ( false !== $height )
  226. $args['h'] = $height;
  227. $args = apply_filters( 'jetpack_photon_post_image_args', $args, compact( 'tag', 'src', 'src_orig', 'width', 'height' ) );
  228. $photon_url = jetpack_photon_url( $src, $args );
  229. // Modify image tag if Photon function provides a URL
  230. // Ensure changes are only applied to the current image by copying and modifying the matched tag, then replacing the entire tag with our modified version.
  231. if ( $src != $photon_url ) {
  232. $new_tag = $tag;
  233. // If present, replace the link href with a Photoned URL for the full-size image.
  234. if ( ! empty( $images['link_url'][ $index ] ) && self::validate_image_url( $images['link_url'][ $index ] ) )
  235. $new_tag = preg_replace( '#(href=["|\'])' . $images['link_url'][ $index ] . '(["|\'])#i', '\1' . jetpack_photon_url( $images['link_url'][ $index ] ) . '\2', $new_tag, 1 );
  236. // Supplant the original source value with our Photon URL
  237. $photon_url = esc_url( $photon_url );
  238. $new_tag = str_replace( $src_orig, $photon_url, $new_tag );
  239. // If Lazy Load is in use, pass placeholder image through Photon
  240. if ( isset( $placeholder_src ) && self::validate_image_url( $placeholder_src ) ) {
  241. $placeholder_src = jetpack_photon_url( $placeholder_src );
  242. if ( $placeholder_src != $placeholder_src_orig )
  243. $new_tag = str_replace( $placeholder_src_orig, esc_url( $placeholder_src ), $new_tag );
  244. unset( $placeholder_src );
  245. }
  246. // Remove the width and height arguments from the tag to prevent distortion
  247. $new_tag = preg_replace( '#(?<=\s)(width|height)=["|\']?[\d%]+["|\']?\s?#i', '', $new_tag );
  248. // Tag an image for dimension checking
  249. $new_tag = preg_replace( '#(\s?/)?>(\s*</a>)?$#i', ' data-recalc-dims="1"\1>\2', $new_tag );
  250. // Replace original tag with modified version
  251. $content = str_replace( $tag, $new_tag, $content );
  252. }
  253. } elseif ( preg_match( '#^http(s)?://i[\d]{1}.wp.com#', $src ) && ! empty( $images['link_url'][ $index ] ) && self::validate_image_url( $images['link_url'][ $index ] ) ) {
  254. $new_tag = preg_replace( '#(href=["|\'])' . $images['link_url'][ $index ] . '(["|\'])#i', '\1' . jetpack_photon_url( $images['link_url'][ $index ] ) . '\2', $tag, 1 );
  255. $content = str_replace( $tag, $new_tag, $content );
  256. }
  257. }
  258. }
  259. return $content;
  260. }
  261. public static function filter_the_galleries( $galleries ) {
  262. if ( empty( $galleries ) || ! is_array( $galleries ) ) {
  263. return $galleries;
  264. }
  265. // Pass by reference, so we can modify them in place.
  266. foreach ( $galleries as &$this_gallery ) {
  267. if ( is_string( $this_gallery ) ) {
  268. $this_gallery = self::filter_the_content( $this_gallery );
  269. // LEAVING COMMENTED OUT as for the moment it doesn't seem
  270. // necessary and I'm not sure how it would propagate through.
  271. // } elseif ( is_array( $this_gallery )
  272. // && ! empty( $this_gallery['src'] )
  273. // && ! empty( $this_gallery['type'] )
  274. // && in_array( $this_gallery['type'], array( 'rectangle', 'square', 'circle' ) ) ) {
  275. // $this_gallery['src'] = array_map( 'jetpack_photon_url', $this_gallery['src'] );
  276. }
  277. }
  278. unset( $this_gallery ); // break the reference.
  279. return $galleries;
  280. }
  281. /**
  282. ** CORE IMAGE RETRIEVAL
  283. **/
  284. /**
  285. * Filter post thumbnail image retrieval, passing images through Photon
  286. *
  287. * @param string|bool $image
  288. * @param int $attachment_id
  289. * @param string|array $size
  290. * @uses is_admin, apply_filters, wp_get_attachment_url, self::validate_image_url, this::image_sizes, jetpack_photon_url
  291. * @filter image_downsize
  292. * @return string|bool
  293. */
  294. public function filter_image_downsize( $image, $attachment_id, $size ) {
  295. // Don't foul up the admin side of things, and provide plugins a way of preventing Photon from being applied to images.
  296. if ( is_admin() || apply_filters( 'jetpack_photon_override_image_downsize', false, compact( 'image', 'attachment_id', 'size' ) ) )
  297. return $image;
  298. // Get the image URL and proceed with Photon-ification if successful
  299. $image_url = wp_get_attachment_url( $attachment_id );
  300. if ( $image_url ) {
  301. // Check if image URL should be used with Photon
  302. if ( ! self::validate_image_url( $image_url ) )
  303. return $image;
  304. // If an image is requested with a size known to WordPress, use that size's settings with Photon
  305. if ( ( is_string( $size ) || is_int( $size ) ) && array_key_exists( $size, self::image_sizes() ) ) {
  306. $image_args = self::image_sizes();
  307. $image_args = $image_args[ $size ];
  308. $photon_args = array();
  309. // `full` is a special case in WP
  310. // To ensure filter receives consistent data regardless of requested size, `$image_args` is overridden with dimensions of original image.
  311. if ( 'full' == $size ) {
  312. $image_meta = wp_get_attachment_metadata( $attachment_id );
  313. if ( isset( $image_meta['width'], $image_meta['height'] ) ) {
  314. // 'crop' is true so Photon's `resize` method is used
  315. $image_args = array(
  316. 'width' => $image_meta['width'],
  317. 'height' => $image_meta['height'],
  318. 'crop' => true
  319. );
  320. }
  321. }
  322. // Expose determined arguments to a filter before passing to Photon
  323. $transform = $image_args['crop'] ? 'resize' : 'fit';
  324. // Check specified image dimensions and account for possible zero values; photon fails to resize if a dimension is zero.
  325. if ( 0 == $image_args['width'] || 0 == $image_args['height'] ) {
  326. if ( 0 == $image_args['width'] && 0 < $image_args['height'] ) {
  327. $photon_args['h'] = $image_args['height'];
  328. } elseif ( 0 == $image_args['height'] && 0 < $image_args['width'] ) {
  329. $photon_args['w'] = $image_args['width'];
  330. }
  331. } else {
  332. if ( ( 'resize' === $transform ) && $image_meta = wp_get_attachment_metadata( $attachment_id ) ) {
  333. // Lets make sure that we don't upscale images since wp never upscales them as well
  334. $smaller_width = ( ( $image_meta['width'] < $image_args['width'] ) ? $image_meta['width'] : $image_args['width'] );
  335. $smaller_height = ( ( $image_meta['height'] < $image_args['height'] ) ? $image_meta['height'] : $image_args['height'] );
  336. $photon_args[ $transform ] = $smaller_width . ',' . $smaller_height;
  337. } else {
  338. $photon_args[ $transform ] = $image_args['width'] . ',' . $image_args['height'];
  339. }
  340. }
  341. $photon_args = apply_filters( 'jetpack_photon_image_downsize_string', $photon_args, compact( 'image_args', 'image_url', 'attachment_id', 'size', 'transform' ) );
  342. // Generate Photon URL
  343. $image = array(
  344. jetpack_photon_url( $image_url, $photon_args ),
  345. false,
  346. false
  347. );
  348. } elseif ( is_array( $size ) ) {
  349. // Pull width and height values from the provided array, if possible
  350. $width = isset( $size[0] ) ? (int) $size[0] : false;
  351. $height = isset( $size[1] ) ? (int) $size[1] : false;
  352. // Don't bother if necessary parameters aren't passed.
  353. if ( ! $width || ! $height )
  354. return $image;
  355. // Expose arguments to a filter before passing to Photon
  356. $photon_args = array(
  357. 'fit' => $width . ',' . $height
  358. );
  359. $photon_args = apply_filters( 'jetpack_photon_image_downsize_array', $photon_args, compact( 'width', 'height', 'image_url', 'attachment_id' ) );
  360. // Generate Photon URL
  361. $image = array(
  362. jetpack_photon_url( $image_url, $photon_args ),
  363. false,
  364. false
  365. );
  366. }
  367. }
  368. return $image;
  369. }
  370. /**
  371. ** GENERAL FUNCTIONS
  372. **/
  373. /**
  374. * Ensure image URL is valid for Photon.
  375. * Though Photon functions address some of the URL issues, we should avoid unnecessary processing if we know early on that the image isn't supported.
  376. *
  377. * @param string $url
  378. * @uses wp_parse_args
  379. * @return bool
  380. */
  381. protected static function validate_image_url( $url ) {
  382. $parsed_url = @parse_url( $url );
  383. if ( ! $parsed_url )
  384. return false;
  385. // Parse URL and ensure needed keys exist, since the array returned by `parse_url` only includes the URL components it finds.
  386. $url_info = wp_parse_args( $parsed_url, array(
  387. 'scheme' => null,
  388. 'host' => null,
  389. 'port' => null,
  390. 'path' => null
  391. ) );
  392. // Bail if scheme isn't http or port is set that isn't port 80
  393. if ( ( 'http' != $url_info['scheme'] || ! in_array( $url_info['port'], array( 80, null ) ) ) && apply_filters( 'jetpack_photon_reject_https', true ) )
  394. return false;
  395. // Bail if no host is found
  396. if ( is_null( $url_info['host'] ) )
  397. return false;
  398. // Bail if the image alredy went through Photon
  399. if ( preg_match( '#^i[\d]{1}.wp.com$#i', $url_info['host'] ) )
  400. return false;
  401. // Bail if no path is found
  402. if ( is_null( $url_info['path'] ) )
  403. return false;
  404. // Ensure image extension is acceptable
  405. if ( ! in_array( strtolower( pathinfo( $url_info['path'], PATHINFO_EXTENSION ) ), self::$extensions ) )
  406. return false;
  407. // If we got this far, we should have an acceptable image URL
  408. // But let folks filter to decline if they prefer.
  409. return apply_filters( 'photon_validate_image_url', true, $url, $parsed_url );
  410. }
  411. /**
  412. * Checks if the file exists before it passes the file to photon
  413. *
  414. * @param string $src The image URL
  415. * @return string
  416. **/
  417. protected static function strip_image_dimensions_maybe( $src ){
  418. $stripped_src = $src;
  419. // Build URL, first removing WP's resized string so we pass the original image to Photon
  420. if ( preg_match( '#(-\d+x\d+)\.(' . implode('|', self::$extensions ) . '){1}$#i', $src, $src_parts ) ) {
  421. $stripped_src = str_replace( $src_parts[1], '', $src );
  422. $upload_dir = wp_upload_dir();
  423. // Extracts the file path to the image minus the base url
  424. $file_path = substr( $stripped_src, strlen ( $upload_dir['baseurl'] ) );
  425. if( file_exists( $upload_dir["basedir"] . $file_path ) )
  426. $src = $stripped_src;
  427. }
  428. return $src;
  429. }
  430. /**
  431. * Provide an array of available image sizes and corresponding dimensions.
  432. * Similar to get_intermediate_image_sizes() except that it includes image sizes' dimensions, not just their names.
  433. *
  434. * @global $wp_additional_image_sizes
  435. * @uses get_option
  436. * @return array
  437. */
  438. protected static function image_sizes() {
  439. if ( null == self::$image_sizes ) {
  440. global $_wp_additional_image_sizes;
  441. // Populate an array matching the data structure of $_wp_additional_image_sizes so we have a consistent structure for image sizes
  442. $images = array(
  443. 'thumb' => array(
  444. 'width' => intval( get_option( 'thumbnail_size_w' ) ),
  445. 'height' => intval( get_option( 'thumbnail_size_h' ) ),
  446. 'crop' => (bool) get_option( 'thumbnail_crop' )
  447. ),
  448. 'medium' => array(
  449. 'width' => intval( get_option( 'medium_size_w' ) ),
  450. 'height' => intval( get_option( 'medium_size_h' ) ),
  451. 'crop' => false
  452. ),
  453. 'large' => array(
  454. 'width' => intval( get_option( 'large_size_w' ) ),
  455. 'height' => intval( get_option( 'large_size_h' ) ),
  456. 'crop' => false
  457. ),
  458. 'full' => array(
  459. 'width' => null,
  460. 'height' => null,
  461. 'crop' => false
  462. )
  463. );
  464. // Compatibility mapping as found in wp-includes/media.php
  465. $images['thumbnail'] = $images['thumb'];
  466. // Update class variable, merging in $_wp_additional_image_sizes if any are set
  467. if ( is_array( $_wp_additional_image_sizes ) && ! empty( $_wp_additional_image_sizes ) )
  468. self::$image_sizes = array_merge( $images, $_wp_additional_image_sizes );
  469. else
  470. self::$image_sizes = $images;
  471. }
  472. return is_array( self::$image_sizes ) ? self::$image_sizes : array();
  473. }
  474. /**
  475. * Pass og:image URLs through Photon
  476. *
  477. * @param array $tags
  478. * @param array $parameters
  479. * @uses jetpack_photon_url
  480. * @return array
  481. */
  482. function filter_open_graph_tags( $tags, $parameters ) {
  483. if ( empty( $tags['og:image'] ) ) {
  484. return $tags;
  485. }
  486. $photon_args = array(
  487. 'fit' => sprintf( '%d,%d', 2 * $parameters['image_width'], 2 * $parameters['image_height'] ),
  488. );
  489. if ( is_array( $tags['og:image'] ) ) {
  490. $images = array();
  491. foreach ( $tags['og:image'] as $image ) {
  492. $images[] = jetpack_photon_url( $image, $photon_args );
  493. }
  494. $tags['og:image'] = $images;
  495. } else {
  496. $tags['og:image'] = jetpack_photon_url( $tags['og:image'], $photon_args );
  497. }
  498. return $tags;
  499. }
  500. /**
  501. * Enqueue Photon helper script
  502. *
  503. * @uses wp_enqueue_script, plugins_url
  504. * @action wp_enqueue_script
  505. * @return null
  506. */
  507. public function action_wp_enqueue_scripts() {
  508. wp_enqueue_script( 'jetpack-photon', plugins_url( 'modules/photon/photon.js', JETPACK__PLUGIN_FILE ), array( 'jquery' ), 20130122, true );
  509. }
  510. }