PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/blog/wp-content/plugins/video/video.php

https://bitbucket.org/sergiohzlz/reportaprod
PHP | 512 lines | 393 code | 27 blank | 92 comment | 41 complexity | ae9d82b3c1decbc4649f6e69fefebb93 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @package video
  4. * @category video
  5. * @author Automattic Inc
  6. * @link http://automattic.com/wordpress-plugins/#videopress VideoPress
  7. * @version 1.2.2
  8. * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  9. */
  10. /*
  11. Plugin Name: VideoPress
  12. Plugin URI: http://wordpress.org/extend/plugins/video/
  13. Description: Upload new videos to <a href="http://videopress.com/">VideoPress</a>, edit metadata, and easily insert VideoPress videos into posts and pages using shortcodes. Requires a <a href="http://wordpress.com/">WordPress.com</a> account and a WordPress.com blog with the <a href="http://en.wordpress.com/products/#videopress">VideoPress upgrade</a>.
  14. Author: Automattic, Niall Kennedy, Joseph Scott
  15. Contributor: Hailin Wu
  16. Author URI: http://automattic.com/wordpress-plugins/#videopress
  17. Version: 1.2.2
  18. Stable tag: 1.2.2
  19. License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. */
  21. include_once( dirname(__FILE__) . '/settings.php' );
  22. add_action( 'media_buttons', 'videopress_media_buttons', 999 );
  23. /**
  24. * Add a video button to the post composition screen
  25. * @since 0.1.0
  26. */
  27. function videopress_media_buttons( ) {
  28. echo '<a href="https://public-api.wordpress.com/videopress-plugin.php?page=video-plugin&amp;video_plugin=1&amp;iframe&amp;TB_iframe=true" id="add_video" class="thickbox" title="VideoPress"><img src="';
  29. echo esc_url( plugins_url( ) . '/' . dirname( plugin_basename( __FILE__ ) ) . '/camera-video.png' );
  30. echo '" alt="VideoPress" width="16" height="16" /></a>';
  31. }
  32. //allow either [videopress xyz] or [wpvideo xyz] for backward compatibility
  33. add_shortcode( 'videopress', 'videopress_shortcode' );
  34. add_shortcode( 'wpvideo', 'videopress_shortcode' );
  35. /**
  36. * Validate user-supplied guid values against expected inputs
  37. *
  38. * @since 1.1
  39. * @param string $guid video identifier
  40. * @return bool true if passes validation test
  41. */
  42. function __videopress_is_valid_guid( $guid ) {
  43. if ( !empty($guid) && ctype_alnum($guid))
  44. return true;
  45. else
  46. return false;
  47. }
  48. /**
  49. * Search a given content string for VideoPress shortcodes. Return an array of shortcodes with guid and attribute values.
  50. *
  51. * @see do_shortcode()
  52. * @param string $content post content string
  53. * @return array Array of shortcode data. GUID as the key and other customization parameters as value. empty array if no matches found.
  54. */
  55. function find_all_videopress_shortcodes( $content ) {
  56. $r = preg_match_all( '/(.?)\[(wpvideo)\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)/s', $content, $matches, PREG_SET_ORDER );
  57. if ( $r === false || $r === 0 )
  58. return array();
  59. unset( $r );
  60. $guids = array();
  61. foreach ( $matches as $m ) {
  62. // allow [[foo]] syntax for escaping a tag
  63. if ( $m[1] == '[' && $m[6] == ']' )
  64. continue;
  65. $attr = shortcode_parse_atts( $m[3] );
  66. if ( __videopress_is_valid_guid( $attr[0] ) ) {
  67. $guid = $attr[0];
  68. unset( $attr[0] );
  69. $guids[$guid] = $attr;
  70. unset( $guid );
  71. }
  72. unset( $attr );
  73. }
  74. return $guids;
  75. }
  76. /**
  77. * Insert video handlers into HTML <head> if posts with video shortcodes exist.
  78. * If video posts are present add SWFObject JS and attach events for each movie container's identifier.
  79. */
  80. function video_embed_head() {
  81. global $posts;
  82. if ( is_feed() || !is_array($posts) || get_option( 'video_player_freedom', false )===true )
  83. return;
  84. $guids = array();
  85. foreach ($posts as $post) {
  86. $guids = array_merge( $guids, find_all_videopress_shortcodes( $post->post_content ) );
  87. }
  88. if ( is_array($guids) && count($guids) > 0 ) {
  89. echo '<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>';
  90. $embed_seq = 0;
  91. $script_block = '<script type="text/javascript" charset="utf-8">' . "\n" . '// <![CDATA[' . "\n"; // escape the JS block for strict parsers
  92. foreach ($guids as $guid) {
  93. $script_block .= "swfobject.registerObject('video$embed_seq','10.0.0');";
  94. $embed_seq++;
  95. }
  96. echo $script_block . "\n" . '// ]]>' . "\n" . '</script>';
  97. }
  98. }
  99. add_action('wp_head', 'video_embed_head');
  100. /**
  101. * Extract the site's host domain for statistics and comparison against an allowed site list in the case of restricted embeds.
  102. *
  103. * @since 1.2
  104. * @param string $url absolute URL
  105. * @return bool|string host component of the URL, or false if none found
  106. */
  107. function videopress_host( $url ) {
  108. if ( empty($url) || !function_exists('parse_url') )
  109. return false;
  110. if ( version_compare(PHP_VERSION, '5.1.2', '>=') ) {
  111. return parse_url($url, PHP_URL_HOST);
  112. } else {
  113. $url_parts = parse_url($url);
  114. if ( $url_parts!==false && isset($url_parts['host']) )
  115. return $url_parts['host'];
  116. }
  117. }
  118. /**
  119. * Prepare key-value pairs for inclusion as an URI's query parameters
  120. * Emulate http_build_query if current version of PHP does not include the function.
  121. *
  122. * @since 1.2
  123. * @uses build_http_query if present
  124. * @param array $args key-value pairs to include as query parameters
  125. * @return string prepped query parameter string
  126. */
  127. function videopress_http_build_query( $args ) {
  128. if ( function_exists('http_build_query') ) {
  129. return http_build_query( $args, '', '&' );
  130. }
  131. else {
  132. $str_builder = array();
  133. foreach ( $args as $key => $value ) {
  134. $str_builder[] = urlencode($key) . '=' . urlencode($value);
  135. }
  136. return implode('&', $str_builder);
  137. }
  138. }
  139. /**
  140. * Only allow legitimate Flash parameters and their values
  141. *
  142. * @since 1.2
  143. * @link http://kb2.adobe.com/cps/127/tn_12701.html Flash object and embed attributes
  144. * @link http://kb2.adobe.com/cps/133/tn_13331.html devicefont
  145. * @link http://kb2.adobe.com/cps/164/tn_16494.html allowscriptaccess
  146. * @link http://www.adobe.com/devnet/flashplayer/articles/full_screen_mode.html full screen mode
  147. * @link http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001079.html allownetworking
  148. * @param array $flash_params Flash parameters expressed in key-value form
  149. * @return array validated Flash parameters
  150. */
  151. function videopress_esc_flash_params( $flash_params ) {
  152. static $allowed_params = array(
  153. 'swliveconnect' => array('true', 'false'),
  154. 'play' => array('true', 'false'),
  155. 'loop' => array('true', 'false'),
  156. 'menu' => array('true', 'false'),
  157. 'quality' => array('low', 'autolow', 'autohigh', 'medium', 'high', 'best'),
  158. 'scale' => array('default', 'noorder', 'exactfit'),
  159. 'align' => array('l', 'r', 't'),
  160. 'salign' => array('l', 'r', 't', 'tl', 'tr', 'bl', 'br'),
  161. 'wmode' => array('window', 'opaque', 'transparent'),
  162. 'devicefont' => array('_sans', '_serif', '_typewriter'),
  163. 'allowscriptaccess' => array('always', 'samedomain', 'never'),
  164. 'allownetworking' => array('all','internal', 'none'),
  165. 'seamlesstabbing' => array('true', 'false'),
  166. 'allowfullscreen' => array('true', 'false'),
  167. 'base',
  168. 'bgcolor',
  169. 'flashvars'
  170. );
  171. $allowed_params_keys = array_keys( $allowed_params );
  172. $filtered_params = array();
  173. foreach( $flash_params as $param=>$value ) {
  174. if ( empty($param) || empty($value) )
  175. continue;
  176. $param = strtolower($param);
  177. if ( in_array($param, $allowed_params_keys) ) {
  178. if ( isset( $allowed_params[$param] ) && is_array( $allowed_params[$param] ) ) {
  179. $value = strtolower($value);
  180. if ( in_array( $value, $allowed_params[$param] ) )
  181. $filtered_params[$param] = $value;
  182. } else {
  183. $filtered_params[$param] = $value;
  184. }
  185. }
  186. }
  187. unset( $allowed_params_keys );
  188. /**
  189. * Flash specifies sameDomain, not samedomain. change from lowercase value for preciseness
  190. */
  191. if ( isset( $filtered_params['allowscriptaccess'] ) && $filtered_params['allowscriptaccess'] === 'samedomain' )
  192. $filtered_params['allowscriptaccess'] = 'sameDomain';
  193. return $filtered_params;
  194. }
  195. /**
  196. * Display helper fallback markup for user agents unable to display embedded Flash content.
  197. *
  198. * @since 1.2
  199. * @return string p element with helper text
  200. */
  201. function videopress_flash_fallback_markup() {
  202. return '<p class="robots-nocontent">' . sprintf( __('This movie requires <a rel="%s" href="%s">Adobe Flash</a> for playback.', 'video'), 'nofollow', 'http://www.adobe.com/go/getflashplayer') . '</p>';
  203. }
  204. /**
  205. * Build a HTML markup string for the double-baked object Flash player
  206. *
  207. * @since 1.2
  208. * @param object $video Video response
  209. * @param string $element_id element identifier determined by the embed sequence
  210. * @param int $width video player width
  211. * @param int $height video player height
  212. * @param string $element object|embed|video
  213. * @param string $params_define define runtime parameters inline or as flashvars param. any value other than 'inline' is ignored.
  214. * @param array $options allow extension of standard runtime variables with player customizations. autoplay
  215. */
  216. function videopress_flash_object_markup( $video, $element_id, $width, $height, $element='object', $params_define='flashvars', $options=array() ) {
  217. if ( !isset($video->title) || empty($video->title) ) {
  218. $loading_text = esc_attr( __('Loading video...', 'video') );
  219. $title_fallback = '';
  220. } else {
  221. $loading_text = esc_attr($video->title);
  222. $title_fallback = '<p><strong>' . esc_html($video->title) . '</strong></p>';
  223. }
  224. if ( is_ssl() || $element==='embed' || !isset($video->posterframe) || empty($video->posterframe) ) {
  225. $thumbnail = '';
  226. } else {
  227. $thumbnail = '<div class="videopress-thumbnail"><img ';
  228. if ( isset($video->title) && !empty($video->title) )
  229. $thumbnail .= 'alt="' . esc_attr($video->title) . '" ';
  230. $thumbnail .= 'src="' . esc_url( $video->posterframe ) . "\" width=\"$width\" height=\"$height\" /></div>";
  231. }
  232. if ( $element==='embed' || $element==='object' ) {
  233. $flash_params = (array) $video->swf->params;
  234. if ( isset( $video->swf->vars ) && !empty( $video->swf->vars ) ) {
  235. $flash_vars = (array) $video->swf->vars;
  236. $flash_vars['site'] = 'wporg';
  237. if ( !empty($options) && isset( $options['autoplay'] ) && $options['autoplay']===true )
  238. $flash_vars['autoPlay'] = 'true';
  239. $flash_params['flashvars'] = videopress_http_build_query( $flash_vars );
  240. unset($flash_vars);
  241. }
  242. $flash_params = videopress_esc_flash_params( apply_filters( 'video_flash_params', $flash_params, 10, 1 ) );
  243. if ( $params_define === 'inline' && isset( $flash_params['flashvars'] ) ) {
  244. $src = esc_url( $video->swf->url . '&' . $flash_params['flashvars'], array( 'http' ) );
  245. unset( $flash_params['flashvars'] );
  246. } else {
  247. $src = esc_url( $video->swf->url, array('http') );
  248. }
  249. if ( $element === 'embed' ) {
  250. $params_attributes='';
  251. foreach ( $flash_params as $attribute=>$value ) {
  252. $params_attributes .= ' ' . esc_html($attribute) . '="' . esc_attr($value) . '"';
  253. }
  254. return "<embed id=\"$element_id\" type=\"application/x-shockwave-flash\" src=\"$src\" width=\"$width\" height=\"$height\" title=\"$loading_text\"$params_attributes /></embed>";
  255. } elseif ( $element === 'object' ) {
  256. $params_elements = '';
  257. foreach ( $flash_params as $name=>$value ) {
  258. $params_elements .= '<param name="' . esc_attr($name) . '" value="' . esc_attr($value) . '" />' . "\n";
  259. }
  260. unset( $flash_params );
  261. $flash_help = videopress_flash_fallback_markup();
  262. return <<<OBJECT
  263. <object id="$element_id" class="videopress" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="$width" height="$height" standby="$loading_text">
  264. <param name="movie" value="$src" />
  265. $params_elements
  266. <!--[if !IE]>-->
  267. <object type="application/x-shockwave-flash" data="$src" width="$width" height="$height" standby="$loading_text">
  268. $params_elements
  269. <!--<![endif]-->
  270. {$thumbnail}{$title_fallback}{$flash_help}
  271. <!--[if !IE]>-->
  272. </object>
  273. <!--<![endif]-->
  274. </object>
  275. OBJECT;
  276. }
  277. } elseif ( $element === 'video' && isset( $video->ogv ) ) {
  278. $fallback_help_text = '<p class="robots-nocontent">' . sprintf( __('You do not have sufficient <a rel="%s" href="%s">freedom levels</a> to view this video.', 'video'), 'nofollow', 'http://www.gnu.org/philosophy/free-sw.html') . '</p>';
  279. $src = esc_url( $video->ogv->url , 'http' );
  280. if ( isset($options['autoplay']) && $options['autoplay']===true )
  281. $load .= 'autoplay="true"';
  282. else
  283. $load .= 'preload="none"';
  284. return <<<VIDEO
  285. <video id="$element_id" width="$width" height="$height" poster="{$video->posterframe}" controls="true" $load>
  286. <source src="$src" type="video/ogg; codecs=&quot;{$video->ogv->codecs}&quot;" />
  287. {$thumbnail}{$title_fallback}{$fallback_help_text}
  288. </video>
  289. VIDEO;
  290. }
  291. return '';
  292. }
  293. /**
  294. * Request information for the given VideoPress guid and optional desired width from VideoPress servers
  295. *
  296. * @param string $guid VideoPress identifier
  297. * @param int $maxwidth Maximum desired video width, or 0 if no width specified.
  298. * @return
  299. */
  300. function videopress_remote_video_info( $guid, $maxwidth=0 ) {
  301. $blog_domain = videopress_host( get_bloginfo('url') );
  302. if ( empty($blog_domain) )
  303. return;
  304. $maxwidth = absint( $maxwidth );
  305. $request_params = array('guid'=>$guid, 'domain'=>$blog_domain);
  306. if ( $maxwidth > 0 )
  307. $request_params['maxwidth'] = $maxwidth;
  308. $response = wp_remote_get( 'http://videopress.com/data/wordpress.json?' . videopress_http_build_query( $request_params ) );
  309. unset( $request_params );
  310. $response_body = wp_remote_retrieve_body( $response );
  311. if ( is_wp_error($response) ) {
  312. if ( in_array( 'http_request_failed', $response->get_error_codes() ) ) {
  313. if ( $response->get_error_message('http_request_failed') === '403: Forbidden' )
  314. return new WP_Error( 'http403', __videopress_error_placeholder( __('Embed error', 'video'), '<div>' . sprintf( __('<strong>%s</strong> is not an allowed embed site.', 'video'), esc_html($blog_domain) ) . '</div><div>' . __('Publisher limits playback of video embeds.', 'video') . '</div>' ) );
  315. }
  316. return;
  317. } elseif ( wp_remote_retrieve_response_code( $response ) != 200 || empty( $response_body ) ) {
  318. return;
  319. }
  320. return json_decode( $response_body );
  321. }
  322. /**
  323. * Replaces wpvideo shortcode and customization parameters with full HTML markup for video playback
  324. *
  325. * @since 0.1.0
  326. * @link http://codex.wordpress.org/Shortcode_API
  327. *
  328. * @param array $attr an array of attributes: video guid, width (w), height (h), freedom, and autoplay
  329. * @return string HTML markup enabling video playback for the given video, or empty string if incorrect syntax
  330. */
  331. function videopress_shortcode( $attr ) {
  332. global $content_width, $current_blog;
  333. static $embed_seq = -1;
  334. $guid = $attr[0];
  335. if ( !__videopress_is_valid_guid($guid) )
  336. return '';
  337. extract( shortcode_atts( array(
  338. 'w'=>0,
  339. 'h'=>0,
  340. 'freedom'=>false,
  341. 'autoplay'=>false
  342. ), $attr ) );
  343. $width = absint($w);
  344. unset($w);
  345. $height = absint($h);
  346. unset($h);
  347. $freedom = (bool) $freedom;
  348. $autoplay = (bool) $autoplay;
  349. if ( isset($content_width) && $width > $content_width )
  350. $width = $height = 0;
  351. if ( $width === 0 && isset($content_width) && $content_width > 0 )
  352. $width = $content_width;
  353. $key = "video-info-by-$guid-$width";
  354. $cached_video = wp_cache_get( $key, 'video-info' );
  355. if ( empty($cached_video) ) {
  356. $video = videopress_remote_video_info( $guid, $width );
  357. if ( is_wp_error($video) ) {
  358. if ( current_user_can('edit_posts') )
  359. return $video->get_error_message();
  360. else
  361. return '';
  362. } elseif( !empty($video) ) {
  363. wp_cache_set( $key, serialize($video), 'video_info', 24*60*60 );
  364. }
  365. } else {
  366. $video = unserialize($cached_video);
  367. }
  368. if ( empty($video) )
  369. return '';
  370. $embed_seq++;
  371. /**
  372. * Width and/or height may be provided in the shortcode or in the response
  373. * Maintain aspect ratio of the original video unless shortcode specifies both a width and a height
  374. */
  375. if ( 0 === $width && 0 === $height ) {
  376. $width = $video->width;
  377. $height = $video->height;
  378. }
  379. if ( 0 == $width )
  380. $width = (int) ( ( $video->width * $height ) / $video->height );
  381. elseif (0 == $height)
  382. $height = (int) ( ( $video->height * $width ) / $video->width );
  383. if ( $width %2 === 1 )
  384. $width--;
  385. if ( $height %2 === 1 )
  386. $height--;
  387. $element_id = 'video' . $embed_seq;
  388. $options = array();
  389. if ( $autoplay===true )
  390. $options['autoplay'] = true;
  391. if ( get_option( 'video_player_freedom', false ) || $freedom===true ) {
  392. // HTML5 video Ogg Theora, Vorbis
  393. return videopress_flash_object_markup( $video, $element_id, $width, $height, 'video', null, $options );
  394. } elseif ( is_feed() ) {
  395. /**
  396. * Some feed readers such as Google Reader only accept an embed HTML element and ignore all parameters, including FlashVars.
  397. * Create special embed markup and include FlashVars values in the SWF URI
  398. */
  399. return videopress_flash_object_markup( $video, $element_id, $width, $height, 'embed', 'inline', $options );
  400. } else {
  401. // double-baked object
  402. return videopress_flash_object_markup( $video, $element_id, $width, $height, 'object', null, $options ); // object with FlashVars
  403. }
  404. }
  405. /**
  406. * Display a VideoPress error message if an embed is unsuccessful
  407. *
  408. * @param string $text main error display plaintext
  409. * @param string $subtext additional information about the error. may include HTML.
  410. * @param string $text_type type of the text message display
  411. * @param int $width width of the error display element
  412. * @param int $height height of the error display element
  413. */
  414. function __videopress_error_placeholder( $text='', $subtext='', $text_type='error', $width=400, $height=300, $context='blog' ) {
  415. $text = esc_html( $text ); // escape text for inclusion in HTML
  416. if ($text_type == 'error' )
  417. $text = "<span class='video-plh-error'>$text</span>";
  418. $class = $width >= 380? 'video-plh-full' : 'video-plh-thumb';
  419. if ( $context == 'blog' ) {
  420. $align = 'center';
  421. $margin = 'margin:auto';
  422. }
  423. else {
  424. $align = 'left';
  425. $margin = '';
  426. }
  427. $mid_width = $width - 16;
  428. $res = '';
  429. if ( !is_feed() ) {
  430. $res = <<<STYLE
  431. <style type="text/css">
  432. .video-plh {font-family:Trebuchet MS, Arial, sans-serif;text-align:$align;margin:3px;}
  433. .video-plh-notice {background-color:black;color:white;display:table;#position:relative;line-height:1.0em;text-align:$align;$margin;}
  434. .video-plh-mid {text-align:$align;display:table-cell;#position:absolute;#top:50%;#left:0;vertical-align:middle;padding: 8px;}
  435. .video-plh-text {#position:relative;#top:-50%;text-align:center;line-height:35px;}
  436. .video-plh-sub {}
  437. .video-plh-full {font-size:28px;}
  438. .video-plh-full .video-plh-sub {font-size:14px;}
  439. .video-plh-thumb {font-size:18px;}
  440. .video-plh-thumb .video-plh-sub {font-size:12px;}
  441. .video-plh-sub {line-height: 120%; margin-top:1em;}
  442. .video-plh-error {color:#f2643d;}
  443. </style>
  444. STYLE;
  445. }
  446. $res .= <<<BODY
  447. <div class="video-plh $class">
  448. <div class="video-plh-notice" style='width:{$width}px;height:{$height}px;'>
  449. <div class="video-plh-mid" style='width:{$mid_width}px;'>
  450. <div class="video-plh-text">
  451. $text
  452. <div class="video-plh-sub">$subtext</div>
  453. </div>
  454. </div>
  455. </div>
  456. </div>
  457. BODY;
  458. return $res;
  459. }
  460. ?>