Advertisement
Guest User

Untitled

a guest
Nov 18th, 2017
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.60 KB | None | 0 0
  1. <?php
  2. /**
  3. * Class td_video_support - tagDiv video support V 2.0 @since 4 nov 2015
  4. * downloads the video thumbnail and puts it asa a featured image to the post
  5. */
  6. class td_video_support{
  7.  
  8. private static $on_save_post_post_id; // here we keep the post_id when the save_post hook runs. We need the post_id to pass it to the other hook @see on_add_attachment_set_featured_image
  9. private static $fb_access_token = 'EAAC0twN8wjQBAEksmaw1653RnNFVQC2gZAdW2nN9zMHsG8LDLWptfvQM1Vty1miNOPsfZBm49T8S2Q3MibZCSjs2Tdvp0tQRfRusVdInNBvElIn6MEZAB9RMnifqPfZCOnj0gVZA19ttZB6mcmAs43u73Be02qZCRfEJ4RZAFXZCxnOgZDZD';
  10.  
  11. private static $caching_time = 10800; //seconds -> 3 hours
  12.  
  13. /**
  14. * Render a video on the fornt end from URL
  15. * @param $videoUrl - the video url that we want to render
  16. *
  17. * @return string - the player HTML
  18. */
  19. static function render_video($videoUrl) {
  20. $buffy = '';
  21. switch (self::detect_video_service($videoUrl)) {
  22. case 'youtube':
  23. $buffy .= '
  24. <div class="wpb_video_wrapper">
  25. <iframe id="td_youtube_player" width="600" height="560" src="' . 'https://www.youtube.com/embed/' . self::get_youtube_id($videoUrl) . '?enablejsapi=1&autoplay=1&feature=oembed&wmode=opaque&vq=hd720' . self::get_youtube_time_param($videoUrl) . '" frameborder="0" allowfullscreen=""></iframe>
  26. <script type="text/javascript">
  27. var tag = document.createElement("script");
  28. tag.src = "https://www.youtube.com/iframe_api";
  29.  
  30. var firstScriptTag = document.getElementsByTagName("script")[0];
  31. firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  32.  
  33. var player;
  34.  
  35. function onYouTubeIframeAPIReady() {
  36. player = new YT.Player("td_youtube_player", {
  37. height: "720",
  38. width: "960",
  39. events: {
  40. "onReady": onPlayerReady
  41. }
  42. });
  43. }
  44.  
  45. function onPlayerReady(event) {
  46. player.setPlaybackQuality("hd720");
  47. }
  48. </script>
  49.  
  50. </div>
  51.  
  52. ';
  53.  
  54. break;
  55. case 'dailymotion':
  56. $buffy .= '
  57. <div class="wpb_video_wrapper">
  58. <iframe frameborder="0" width="600" height="560" src="' . td_global::$http_or_https . '://www.dailymotion.com/embed/video/' . self::get_dailymotion_id($videoUrl) . '"></iframe>
  59. </div>
  60. ';
  61. break;
  62. case 'vimeo':
  63. $buffy = '
  64. <div class="wpb_video_wrapper">
  65. <iframe src="' . td_global::$http_or_https . '://player.vimeo.com/video/' . self::get_vimeo_id($videoUrl) . '" width="500" height="212" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
  66. </div>
  67. ';
  68. break;
  69. case 'facebook':
  70. /* $buffy = '
  71. <div class="wpb_video_wrapper td-facebook-video">
  72. <iframe src="' . td_global::$http_or_https . '://www.facebook.com/plugins/video.php?href=' . urlencode($videoUrl) . '&show_text=0" width="' . $width . '" height="' . $height . '" scrolling="no" frameborder="0" allowTransparency="true" allowFullScreen="true" ></iframe>
  73. </div>
  74. ';
  75. */
  76.  
  77. /**
  78. * cache & oembed implementation
  79. */
  80. $cache_key = self::get_facebook_id($videoUrl);
  81. $group = 'td_facebook_video';
  82.  
  83. if (td_remote_cache::is_expired($group, $cache_key) === true) {
  84.  
  85. // cache is expired - do a request
  86. $facebook_api_json = td_remote_http::get_page('https://www.facebook.com/plugins/video/oembed.json/?url=' . urlencode($videoUrl) , __CLASS__);
  87.  
  88. if ($facebook_api_json !== false) {
  89. $facebook_api = @json_decode($facebook_api_json);
  90.  
  91. //json data decode
  92. if ($facebook_api === null and json_last_error() !== JSON_ERROR_NONE) {
  93. td_log::log(__FILE__, __FUNCTION__, 'json decode failed for facebook video embed api', $videoUrl);
  94. }
  95.  
  96. if (is_object($facebook_api) and !empty($facebook_api->html)) {
  97.  
  98. //add the html to the buffer
  99. $buffy = '<div class="wpb_video_wrapper">' . $facebook_api->html . '</div>';
  100.  
  101. //set the cache
  102. td_remote_cache::set($group, $cache_key, $facebook_api->html, self::$caching_time);
  103. }
  104.  
  105. } else {
  106. td_log::log(__FILE__, __FUNCTION__, 'facebook api html data cannot be retrieved/json request failed', $videoUrl);
  107. }
  108.  
  109. } else {
  110. // cache is valid
  111. $api_html_embed_data = td_remote_cache::get($group, $cache_key);
  112. $buffy = '<div class="wpb_video_wrapper">' . $api_html_embed_data . '</div>';
  113. }
  114. break;
  115. case 'twitter':
  116.  
  117. /**
  118. * cache & oembed implementation
  119. */
  120.  
  121. $cache_key = self::get_twitter_id($videoUrl);
  122. $group = 'td_twitter_video';
  123.  
  124.  
  125. if (td_remote_cache::is_expired($group, $cache_key) === true) {
  126.  
  127. // cache is expired - do a request
  128. $twitter_json = td_remote_http::get_page('https://publish.twitter.com/oembed?url=' . urlencode($videoUrl) . '&widget_type=video&align=center' , __CLASS__);
  129.  
  130. if ($twitter_json !== false) {
  131. $twitter_api = @json_decode($twitter_json);
  132.  
  133. //json data decode
  134. if ($twitter_api === null and json_last_error() !== JSON_ERROR_NONE) {
  135. td_log::log(__FILE__, __FUNCTION__, 'json decode failed for twitter video embed api', $videoUrl);
  136. }
  137.  
  138. if (is_object($twitter_api) and !empty($twitter_api->html)) {
  139.  
  140. //add the html to the buffer
  141. $buffy = '<div class="wpb_video_wrapper">' . $twitter_api->html . '</div>';
  142.  
  143. //set the cache
  144. td_remote_cache::set($group, $cache_key, $twitter_api->html, self::$caching_time);
  145. }
  146.  
  147. } else {
  148. td_log::log(__FILE__, __FUNCTION__, 'twitter api html data cannot be retrieved/json request failed', $videoUrl);
  149. }
  150.  
  151. } else {
  152. // cache is valid
  153. $api_html_embed_data = td_remote_cache::get($group, $cache_key);
  154. $buffy = '<div class="wpb_video_wrapper">' . $api_html_embed_data . '</div>';
  155. }
  156.  
  157. break;
  158. }
  159. return $buffy;
  160. }
  161.  
  162.  
  163. /**
  164. * Downloads the video thumb on the save_post hook
  165. * @param $post_id
  166. */
  167. static function on_save_post_get_video_thumb($post_id) {
  168.  
  169. //verify post is not a revision
  170. if ( !wp_is_post_revision( $post_id ) ) {
  171. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
  172. return;
  173. }
  174.  
  175. $td_post_video = td_util::get_post_meta_array($post_id, 'td_post_video');
  176.  
  177. //check to see if the url is valid
  178. if (empty($td_post_video['td_video']) or self::validate_video_url($td_post_video['td_video']) === false) {
  179. return;
  180. }
  181.  
  182. if (!empty($td_post_video['td_last_video']) and $td_post_video['td_last_video'] == $td_post_video['td_video']) {
  183. //we did not update the url
  184. return;
  185. }
  186.  
  187. $videoThumbUrl = self::get_thumb_url($td_post_video['td_video']);
  188.  
  189. if (!empty($videoThumbUrl)) {
  190. self::$on_save_post_post_id = $post_id;
  191.  
  192. // add the function above to catch the attachments creation
  193. add_action('add_attachment', array(__CLASS__, 'on_add_attachment_set_featured_image'));
  194.  
  195. // load the attachment from the URL
  196. media_sideload_image($videoThumbUrl, $post_id, $post_id);
  197.  
  198. // we have the Image now, and the function above will have fired too setting the thumbnail ID in the process, so lets remove the hook so we don't cause any more trouble
  199. remove_action('add_attachment', array(__CLASS__, 'on_add_attachment_set_featured_image'));
  200. }
  201. }
  202. }
  203.  
  204.  
  205.  
  206. /**
  207. * set the last uploaded image as a featured image. We 'upload' the video thumb via the media_sideload_image call from above
  208. * @internal
  209. */
  210. static function on_add_attachment_set_featured_image($att_id){
  211. update_post_meta(self::$on_save_post_post_id, '_thumbnail_id', $att_id);
  212. }
  213.  
  214.  
  215. /**
  216. * detects if we have a recognized video service and makes sure that it's a valid url
  217. * @param $videoUrl
  218. * @return bool
  219. */
  220. private static function validate_video_url($videoUrl) {
  221. if (self::detect_video_service($videoUrl) === false) {
  222. return false;
  223. }
  224. if (!preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $videoUrl)) {
  225. return false;
  226. }
  227. return true;
  228. }
  229.  
  230.  
  231. /**
  232. * Returns the video thumb url from the video URL
  233. * @param $videoUrl
  234. * @return string
  235. */
  236. private static function get_thumb_url($videoUrl) {
  237.  
  238. switch (self::detect_video_service($videoUrl)) {
  239. case 'youtube':
  240. $yt_1920_url = td_global::$http_or_https . '://img.youtube.com/vi/' . self::get_youtube_id($videoUrl) . '/maxresdefault.jpg';
  241. $yt_640_url = td_global::$http_or_https . '://img.youtube.com/vi/' . self::get_youtube_id($videoUrl) . '/sddefault.jpg';
  242. $yt_480_url = td_global::$http_or_https . '://img.youtube.com/vi/' . self::get_youtube_id($videoUrl) . '/hqdefault.jpg';
  243.  
  244. if (!self::is_404($yt_1920_url)) {
  245. return $yt_1920_url;
  246. }
  247.  
  248. elseif (!self::is_404($yt_640_url)) {
  249. return $yt_640_url;
  250. }
  251.  
  252. elseif (!self::is_404($yt_480_url)) {
  253. return $yt_480_url;
  254. }
  255.  
  256. else {
  257. td_log::log(__FILE__, __FUNCTION__, 'No suitable thumb found for youtube.', $videoUrl);
  258. }
  259. break;
  260.  
  261. case 'dailymotion':
  262. $dailymotion_api_json = td_remote_http::get_page('https://api.dailymotion.com/video/' . self::get_dailymotion_id($videoUrl) . '?fields=thumbnail_url', __CLASS__);
  263. if ($dailymotion_api_json !== false) {
  264. $dailymotion_api = @json_decode($dailymotion_api_json);
  265. if ($dailymotion_api === null and json_last_error() !== JSON_ERROR_NONE) {
  266. td_log::log(__FILE__, __FUNCTION__, 'json decaode failed for daily motion api', $videoUrl);
  267. return '';
  268. }
  269.  
  270. if (!empty($dailymotion_api) and !empty($dailymotion_api->thumbnail_url)) {
  271. return $dailymotion_api->thumbnail_url;
  272. }
  273. }
  274. break;
  275.  
  276. case 'vimeo':
  277. $url = 'http://vimeo.com/api/oembed.json?url=https://vimeo.com/' . self::get_vimeo_id($videoUrl);
  278.  
  279. $response = wp_remote_get($url, array(
  280. 'timeout' => 10,
  281. 'sslverify' => false,
  282. 'user-agent' => 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0'
  283. ));
  284.  
  285. if (!is_wp_error($response)) {
  286. $td_result = @json_decode(wp_remote_retrieve_body($response));
  287. $result = $td_result->thumbnail_url;
  288. $result = preg_replace("#_[0-9]+(x)?[0-9]+\.jpg#", '.jpg', $result);
  289.  
  290. return $result;
  291. }
  292. break;
  293.  
  294. case 'facebook':
  295. $facebook_api_json = td_remote_http::get_page('https://graph.facebook.com/v2.7/' . self::get_facebook_id($videoUrl) . '/thumbnails?access_token=' . self::$fb_access_token , __CLASS__);
  296.  
  297. if ( $facebook_api_json !== false ) {
  298. $facebook_api = @json_decode($facebook_api_json);
  299. if ($facebook_api === null and json_last_error() !== JSON_ERROR_NONE) {
  300. td_log::log(__FILE__, __FUNCTION__, 'json decode failed for facebook api', $videoUrl);
  301. return '';
  302. }
  303.  
  304. if (is_object($facebook_api) and !empty($facebook_api)) {
  305. foreach ($facebook_api->data as $result) {
  306. if ($result->is_preferred !== false) {
  307. return ($result->uri);
  308. }
  309. }
  310.  
  311. }
  312. }
  313. break;
  314.  
  315. case 'twitter':
  316. if (!class_exists('TwitterApiClient')) {
  317. require_once 'wp-admin/external/twitter-client.php';
  318. $Client = new TwitterApiClient;
  319. $Client->set_oauth (YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET, SOME_ACCESS_KEY, SOME_ACCESS_SECRET);
  320. try {
  321. $path = 'statuses/show';
  322. $args = array (
  323. 'id' => self::get_twitter_id($videoUrl),
  324. 'include_entities' => true
  325. );
  326. $data = @$Client->call( $path, $args, 'GET' );
  327.  
  328. //json data decode
  329. if ($data === null) {
  330. td_log::log(__FILE__, __FUNCTION__, 'api call failed for twitter video thumbnail request api', $videoUrl);
  331. }
  332.  
  333. if (empty($data['entities']['media'])){
  334. add_filter( 'redirect_post_location', array( __CLASS__, 'td_twitter_notice_on_redirect_post_location' ), 99 );
  335.  
  336. } else {
  337. return $data['entities']['media'][0]['media_url'] . ':large';
  338. }
  339. }
  340. catch( TwitterApiException $Ex ){
  341. //twitter rate limit will show here
  342. //echo 'Caught exception: ', $Ex->getMessage();
  343. //print_r($Ex);
  344. }
  345. } else {
  346. add_filter( 'redirect_post_location', array( __CLASS__, 'td_twitter_class_notice_on_redirect_post_location' ), 99 );
  347. }
  348. }
  349. return '';
  350. }
  351.  
  352.  
  353. /*
  354. * youtube
  355. */
  356. private static function get_youtube_id($videoUrl) {
  357. $query_string = array();
  358. parse_str(parse_url($videoUrl, PHP_URL_QUERY), $query_string);
  359.  
  360. if (empty($query_string["v"])) {
  361. //explode at ? mark
  362. $yt_short_link_parts_explode1 = explode('?', $videoUrl);
  363.  
  364. //short link: http://youtu.be/AgFeZr5ptV8
  365. $yt_short_link_parts = explode('/', $yt_short_link_parts_explode1[0]);
  366. if (!empty($yt_short_link_parts[3])) {
  367. return $yt_short_link_parts[3];
  368. }
  369.  
  370. return $yt_short_link_parts[0];
  371. } else {
  372. return $query_string["v"];
  373. }
  374. }
  375.  
  376. /*
  377. * youtube t param from url (ex: http://youtu.be/AgFeZr5ptV8?t=5s)
  378. */
  379. private static function get_youtube_time_param($videoUrl) {
  380. $query_string = array();
  381. parse_str(parse_url($videoUrl, PHP_URL_QUERY), $query_string);
  382. if (!empty($query_string["t"])) {
  383.  
  384. if (strpos($query_string["t"], 'm')) {
  385. //take minutes
  386. $explode_for_minutes = explode('m', $query_string["t"]);
  387. $minutes = trim($explode_for_minutes[0]);
  388.  
  389. //take seconds
  390. $explode_for_seconds = explode('s', $explode_for_minutes[1]);
  391. $seconds = trim($explode_for_seconds[0]);
  392.  
  393. $startTime = ($minutes * 60) + $seconds;
  394. } else {
  395. //take seconds
  396. $explode_for_seconds = explode('s', $query_string["t"]);
  397. $seconds = trim($explode_for_seconds[0]);
  398.  
  399. $startTime = $seconds;
  400. }
  401.  
  402. return '&start=' . $startTime;
  403. } else {
  404. return '';
  405. }
  406. }
  407.  
  408. /*
  409. * Vimeo id
  410. */
  411. private static function get_vimeo_id($videoUrl) {
  412. sscanf(parse_url($videoUrl, PHP_URL_PATH), '/%d', $video_id);
  413. return $video_id;
  414. }
  415.  
  416. /*
  417. * Dailymotion
  418. */
  419. private static function get_dailymotion_id($videoUrl) {
  420. $id = strtok(basename($videoUrl), '_');
  421. if (strpos($id,'#video=') !== false) {
  422. $videoParts = explode('#video=', $id);
  423. if (!empty($videoParts[1])) {
  424. return $videoParts[1];
  425. }
  426. } else {
  427. return $id;
  428. }
  429. return '';
  430. }
  431.  
  432. /**
  433. * Facebook
  434. * @param $videoUrl
  435. * @return string - the fb video id
  436. */
  437. private static function get_facebook_id($videoUrl) {
  438.  
  439. /**
  440. * https://www.facebook.com/{page-name}/videos/{video-id}/
  441. * https://www.facebook.com/{username}/videos/{video-id}/ - user's video must be public
  442. * https://www.facebook.com/video.php?v={video-id}
  443. * https://www.facebook.com/video.php?id={video-id} - this video url does not work in this format
  444. */
  445.  
  446. if (strpos($videoUrl, '//www.facebook.com') !== false) {
  447.  
  448. $id = basename($videoUrl);
  449. if (strpos($id,'video.php?v=') !== false) {
  450. $query = parse_url($videoUrl, PHP_URL_QUERY);
  451. parse_str($query, $vars);
  452. return $vars['v'];
  453. } else {
  454. return $id;
  455. }
  456. }
  457. return '';
  458. }
  459.  
  460. /**
  461. * Twitter
  462. * @param $videoUrl
  463. * @return string - the tweet id
  464. */
  465. private static function get_twitter_id($videoUrl) {
  466.  
  467. /**
  468. * https://twitter.com/video/status/760619209114071040
  469. */
  470.  
  471. if (strpos($videoUrl, 'twitter.com') !== false) {
  472. $id = basename($videoUrl);
  473. return $id;
  474. }
  475. return '';
  476. }
  477.  
  478. /**
  479. * appends a query variable to the URL query, to show the 'non supported embeddable twitter videos' notice, on the redirect_post_location hook
  480. * @param $location - the destination URL
  481. * @return mixed
  482. */
  483. static function td_twitter_notice_on_redirect_post_location( $location ) {
  484. remove_filter( 'redirect_post_location', array( __CLASS__, 'td_twitter_notice_on_redirect_post_location' ), 99 );
  485. return add_query_arg( 'td_twitter_video', 'error_notice', $location );
  486. }
  487.  
  488. /**
  489. * the twitter video notice for non supported embeddable twitter videos
  490. */
  491. static function td_twitter_on_admin_notices() {
  492. if ( ! isset( $_GET['td_twitter_video'] ) ) {
  493. return;
  494. }
  495.  
  496. ?>
  497. <div class="notice notice-error is-dismissible">
  498. <p>Sorry, but the twitter video you have used is not supported by twitter api, so the video thumb image cannot be retrieved!<br>
  499. Some twitter videos, like Vine and Amplify or other content videos are not available through the twitter API therefore resources, like video thumb images, are not available.</p>
  500. </div>
  501. <?php
  502. }
  503.  
  504. /**
  505. * appends a query variable to the URL query, to show the 'class already defined' notice, on the redirect_post_location hook
  506. * @param $location - the destination URL
  507. * @return mixed
  508. */
  509. static function td_twitter_class_notice_on_redirect_post_location( $location ) {
  510. remove_filter( 'redirect_post_location', array( __CLASS__, 'td_twitter_class_notice_on_redirect_post_location' ), 99 );
  511. return add_query_arg( 'td_twitter_video_class', 'class_notice', $location );
  512. }
  513.  
  514. /**
  515. * the twitter video notice for class already defined
  516. */
  517. static function td_twitter_class_on_admin_notices() {
  518. if ( ! isset( $_GET['td_twitter_video_class'] ) ) {
  519. return;
  520. }
  521.  
  522. ?>
  523. <div class="notice notice-error">
  524. <p>The twitter api class is already defined! It might have been already defined by one of your plugins so please try without having any plugins active!</p>
  525. </div>
  526. <?php
  527. }
  528.  
  529. /*
  530. * Detect the video service from url
  531. */
  532. private static function detect_video_service($videoUrl) {
  533. $videoUrl = strtolower($videoUrl);
  534. if (strpos($videoUrl,'youtube.com') !== false or strpos($videoUrl,'youtu.be') !== false) {
  535. return 'youtube';
  536. }
  537. if (strpos($videoUrl,'dailymotion.com') !== false) {
  538. return 'dailymotion';
  539. }
  540. if (strpos($videoUrl,'vimeo.com') !== false) {
  541. return 'vimeo';
  542. }
  543. if (strpos($videoUrl,'facebook.com') !== false) {
  544. return 'facebook';
  545. }
  546.  
  547. if (strpos($videoUrl,'twitter.com') !== false) {
  548. return 'twitter';
  549. }
  550.  
  551. return false;
  552. }
  553.  
  554. /**
  555. * detect a 404 page
  556. * @param $url
  557. * @return bool
  558. */
  559. private static function is_404($url) {
  560. $headers = @get_headers($url);
  561. if (!empty($headers[0]) and strpos($headers[0],'404') !== false) {
  562. return true;
  563. }
  564. return false;
  565. }
  566.  
  567.  
  568. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement