lytro.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. <?php
  2. /**
  3. * Lytro.com Short Code
  4. *
  5. * Format:
  6. * [lytro photo='202' show_arrow='true' show_border='true' show_first_time_user='true' allow_full_view='true']
  7. * [lytro username='lytroweb' photo='431119']
  8. *
  9. * Legend:
  10. * username: the lytro.com username for newer embed format
  11. * photo: the ID or the URL of the photo on lytro.com
  12. * show_arrow: set to false to force-hide the menu in the lower right (not used in v2)
  13. * show_border: set to true to force-show the border
  14. * show_first_time_user: set to false to force-disable the first-time user experience (not used in v2)
  15. * allow_full_view: set to true to allow an external site to have a full-zoom mode (not used in v2)
  16. * enable_help: set to false to hide the question mark/help popup
  17. *
  18. * Output:
  19. * <iframe width="400" height="415" src="https://www.lytro.com/living-pictures/202/embed?showArrow=true&showBorder=true&showFTU=true" frameborder="0" allowfullscreen></iframe>
  20. * <iframe width="400" height="415" src="http://pictures.lytro.com/lytroweb/pictures/431119/embed" frameborder="0" allowfullscreen="" scrolling="no"></iframe>
  21. */
  22. /**
  23. * Lytro.com Short Code Attributes Definition
  24. *
  25. * This helper function returns an array all available
  26. * shortcode attributes, their validation method, default
  27. * value and more.
  28. *
  29. * Keys:
  30. * validate: a callable function or regular expression used to validate the input
  31. * default: default value for shortcode attribute
  32. * query_arg: the related lytro query argument name
  33. *
  34. * @since 4.5.0
  35. */
  36. function jetpack_lytro_shortcode_attributes() {
  37. return array(
  38. 'username' => array(
  39. 'default' => '',
  40. ),
  41. 'photo' => array( // could be ID or URL, validated separately
  42. 'default' => 0,
  43. ),
  44. 'width' => array(
  45. 'validate' => '#^\d+$#',
  46. 'default' => 400,
  47. ),
  48. 'height' => array(
  49. 'validate' => '#^\d+$#',
  50. 'default' => 415,
  51. ),
  52. 'show_arrow' => array(
  53. 'query_arg' => 'showArrow',
  54. 'validate' => '#^(true|false)$#',
  55. 'default' => 'true',
  56. ),
  57. 'show_border' => array(
  58. 'query_arg' => 'showBorder',
  59. 'validate' => '#^(true|false)$#',
  60. 'default' => 'true',
  61. ),
  62. 'show_first_time_user' => array(
  63. 'query_arg' => 'showFTU',
  64. 'validate' => '#^(true|false)$#',
  65. 'default' => 'true',
  66. ),
  67. 'allow_full_view' => array(
  68. 'query_arg' => 'allowFullView',
  69. 'validate' => '#^(true|false)$#',
  70. 'default' => 'true',
  71. ),
  72. 'enable_help' => array(
  73. 'query_arg' => 'enableHelp',
  74. 'validate' => '#^(true|false)$#',
  75. 'default' => 'true',
  76. ),
  77. 'enable_attribution' => array(
  78. 'query_arg' => 'enableAttribution',
  79. 'validate' => '#^(true|false)$#',
  80. 'default' => 'true',
  81. ),
  82. 'enable_logo' => array(
  83. 'query_arg' => 'enableLogo',
  84. 'validate' => '#^(true|false)$#',
  85. 'default' => 'true',
  86. ),
  87. 'enable_fullscreen' => array(
  88. 'query_arg' => 'enableFullscreen',
  89. 'validate' => '#^(true|false)$#',
  90. 'default' => 'true',
  91. ),
  92. 'enable_play' => array(
  93. 'query_arg' => 'enablePlay',
  94. 'validate' => '#^(true|false)$#',
  95. 'default' => 'true',
  96. ),
  97. 'bg_color' => array(
  98. 'query_arg' => 'bgColor',
  99. 'validate' => '/^#(?:[0-9a-fA-F]{3}){1,2}$/',
  100. 'default' => '',
  101. ),
  102. );
  103. }
  104. /**
  105. * Lytro.com Shortcode
  106. *
  107. * Allows embedding Lytro "living pictures" using [lytro photo="200"] or
  108. * [lytro photo="http://www.lytro.com/..."]. Additional attributes
  109. * like show_border, show_arrow, etc have priority over the ones supplied
  110. * in the URL.
  111. *
  112. * @since 4.5.0
  113. *
  114. * @param array $atts Shortcode attributes
  115. *
  116. * @uses jetpack_lytro_shortcode_attributes()
  117. * @return string Embed HTML or a <!-- commented out error -->
  118. */
  119. function jetpack_lytro_shortcode_handler( $atts ) {
  120. $defaults = array();
  121. $attributes = jetpack_lytro_shortcode_attributes();
  122. foreach ( $attributes as $key => $attribute ) {
  123. if ( isset( $attribute['default'] ) ) {
  124. $defaults[$key] = $attribute['default'];
  125. }
  126. }
  127. $atts = shortcode_atts( $defaults, $atts );
  128. // There has to at least be a photo attribute.
  129. if ( empty( $atts['photo'] ) ) {
  130. return '<!-- Lytro Shortcode Error: No Photo ID/URL -->';
  131. }
  132. // The photo attribute might be a URL
  133. if ( ! is_numeric( $atts['photo'] ) ) {
  134. $atts = array_merge( $atts, jetpack_lytro_shortcode_url_to_atts( $atts['photo'] ) );
  135. }
  136. // Validate all attributes by callable function or regular expression.
  137. foreach ( $atts as $key => $value ) {
  138. $attribute = $attributes[$key];
  139. if ( isset( $attribute['validate'] ) ) {
  140. $validate = $attribute['validate'];
  141. $valid = is_callable( $validate ) ? call_user_func( $validate, $value ) : preg_match( $validate, $value );
  142. if ( ! $valid ) {
  143. $atts[$key] = $defaults[$key];
  144. }
  145. }
  146. }
  147. // The photo attribute might have changed, make sure it's still valid.
  148. if ( ! is_numeric( $atts['photo'] ) || ! $atts['photo'] ) {
  149. return '<!-- Lytro Shortcode Error: Invalid Photo ID/URL -->';
  150. }
  151. // Build a query which is then appended to the iframe src.
  152. $query_args = array();
  153. foreach ( $atts as $key => $value ) {
  154. $attribute = $attributes[$key];
  155. if ( isset( $attribute['query_arg'] ) && ! empty( $attribute['query_arg'] ) && ! empty( $value ) ) {
  156. $query_args[$attribute['query_arg']] = $value;
  157. }
  158. }
  159. if ( ! empty( $atts['username'] ) ) {
  160. $src = sprintf( 'https://pictures.lytro.com/%s/pictures/%d/embed', $atts['username'], $atts['photo'] );
  161. } else {
  162. $src = sprintf( 'https://pictures.lytro.com/pictures/%d/embed', $atts['photo'] );
  163. }
  164. // Add query args and build the iframe.
  165. $src = add_query_arg( $query_args, $src );
  166. return '<iframe width="' . esc_attr( $atts['width'] ) . '" height="' . esc_attr( $atts['height'] ) . '" src="' . esc_url( $src ) . '" frameborder="0" allowfullscreen scrolling="no"></iframe>';
  167. }
  168. add_shortcode( 'lytro', 'jetpack_lytro_shortcode_handler' );
  169. /**
  170. * Lytro Shortcode URL to Shortcode Attributes
  171. *
  172. * This helper function parses a Lytro.com URL
  173. * and returns an attributes array.
  174. *
  175. * @since 4.5.0
  176. *
  177. * @uses jetpack_lytro_shortcode_attributes()
  178. */
  179. function jetpack_lytro_shortcode_url_to_atts( $url ) {
  180. $attributes = jetpack_lytro_shortcode_attributes();
  181. $atts = array();
  182. $url = str_replace( '&amp;', '&', $url );
  183. if ( preg_match( '#^https?://(www\.)?lytro\.com/living-pictures/([0-9]+)/?#i', $url, $matches ) ) {
  184. $atts['photo'] = $matches[2];
  185. } elseif ( preg_match( '#^https?://(www\.)?pictures\.lytro\.com/([^/]+)/pictures/([0-9]+)/?#i', $url, $matches ) ) {
  186. $atts['username'] = $matches[2];
  187. $atts['photo'] = $matches[3];
  188. }
  189. $url = parse_url( $url );
  190. if ( isset( $url['query'] ) ) {
  191. parse_str( $url['query'], $qargs );
  192. // Get the attributes with query_args and fill in the $atts array
  193. foreach ( $attributes as $key => $attribute ) {
  194. if ( isset( $attribute['query_arg'] ) && in_array( $attribute['query_arg'], array_keys( $qargs ) ) ) {
  195. $atts[$key] = $qargs[$attribute['query_arg']];
  196. }
  197. }
  198. }
  199. return $atts;
  200. }
  201. /**
  202. * Lytro Shortcode Reversal
  203. *
  204. * Example
  205. * <iframe width="400" height="415" src="https://www.lytro.com/living-pictures/202/embed?showBorder=true" frameborder="0" allowfullscreen></iframe>
  206. * <iframe width="400" height="415" src="http://pictures.lytro.com/lytroweb/pictures/431128/embed" frameborder="0" allowfullscreen="" scrolling="no"></iframe>
  207. *
  208. * Converts to:
  209. * [lytro photo="202" show_border="true" width="400" height="415"]
  210. *
  211. * @since 4.5.0
  212. *
  213. * @uses jetpack_lytro_shortcode_url_to_atts()
  214. * @uses wpcom_shortcodereverse_parseattr()
  215. */
  216. function wpcom_shortcodereverse_lytro( $atts ) {
  217. $atts = wpcom_shortcodereverse_parseattr( $atts );
  218. $shortcode_atts = array();
  219. // Grab the src URL and convert to shortcode attributes
  220. if ( $atts['src'] ) {
  221. $shortcode_atts = jetpack_lytro_shortcode_url_to_atts( $atts['src'] );
  222. }
  223. // Width and height too
  224. if ( $atts['width'] ) {
  225. $shortcode_atts['width'] = $atts['width'];
  226. }
  227. if ( $atts['height'] ) {
  228. $shortcode_atts['height'] = $atts['height'];
  229. }
  230. // Generate the shortcode.
  231. $shortcode = '';
  232. foreach ( $shortcode_atts as $key => $value ) {
  233. $shortcode .= " $key='" . esc_attr( $value ) . "'";
  234. }
  235. $shortcode = "[lytro {$shortcode}]";
  236. return $shortcode;
  237. }
  238. Filter_Embedded_HTML_Objects::register( '#^https?://(www\.)?lytro\.com/living-pictures/#i', 'wpcom_shortcodereverse_lytro', true );
  239. Filter_Embedded_HTML_Objects::register( '#^https?://(www\.)?pictures\.lytro\.com/([^/]+)/pictures/([0-9]+)/embed#i', 'wpcom_shortcodereverse_lytro', true );
  240. /**
  241. * Register Embed Handler
  242. *
  243. * Registers a WordPress Embed handler to allow embedding
  244. * Lytro images by publishing the Lytro URL on a line by itself.
  245. *
  246. * @since 4.5.0
  247. *
  248. * @uses wp_embed_register_handler
  249. */
  250. function jetpack_lytro_register_embed_handler() {
  251. wp_embed_register_handler( 'lytro', '#^https?://(www\.)?lytro\.com/living-pictures/([0-9]+)/?#i', 'jetpack_lytro_embed_handler' );
  252. wp_embed_register_handler( 'lytro-v2', '#^https?://(www\.)?pictures\.lytro\.com/([^/]+)/pictures/([0-9]+)/?#i', 'jetpack_lytro_embed_handler' );
  253. }
  254. add_action( 'init', 'jetpack_lytro_register_embed_handler' );
  255. /**
  256. * Lytro Embed Handler
  257. *
  258. * The embed handler function which converts a Lytro URL
  259. * on a line by itself into an embedded Lytro image.
  260. *
  261. * @since 4.5.0
  262. *
  263. * @see jetpack_lytro_register_embed_handler
  264. * @uses jetpack_lytro_shortcode_url_to_atts
  265. * @uses jetpack_lytro_shortcode_handler
  266. */
  267. function jetpack_lytro_embed_handler( $matches, $attr, $url, $rawattr ) {
  268. return jetpack_lytro_shortcode_handler( jetpack_lytro_shortcode_url_to_atts( $url ) );
  269. }