PageRenderTime 27ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/components/com_easyblog/helpers/videos.php

https://bitbucket.org/pastor399/newcastleunifc
PHP | 603 lines | 381 code | 124 blank | 98 comment | 32 complexity | bf022f5a4020bc9f5f30a47916321e10 MD5 | raw file
  1. <?php
  2. /**
  3. * @package EasyBlog
  4. * @copyright Copyright (C) 2010 Stack Ideas Private Limited. All rights reserved.
  5. * @license GNU/GPL, see LICENSE.php
  6. *
  7. * EasyBlog is free software. This version may have been modified pursuant
  8. * to the GNU General Public License, and as distributed it includes or
  9. * is derivative of works licensed under the GNU General Public License or
  10. * other free or open source software licenses.
  11. * See COPYRIGHT.php for copyright notices and details.
  12. */
  13. defined('_JEXEC') or die('Restricted access');
  14. require_once( EBLOG_HELPERS . DIRECTORY_SEPARATOR . 'helper.php' );
  15. class EasyBlogVideosHelper
  16. {
  17. private $patterns = array(
  18. 'youtube.com' => 'youtube',
  19. 'youtu.be' => 'youtube',
  20. 'vimeo.com' => 'vimeo',
  21. 'yahoo.com' => 'yahoo',
  22. 'metacafe.com' => 'metacafe',
  23. 'google.com' => 'google',
  24. 'mtv.com' => 'mtv',
  25. 'liveleak.com' => 'liveleak',
  26. 'revver.com' => 'revver',
  27. 'dailymotion.com' => 'dailymotion',
  28. 'nicovideo.jp' => 'nicovideo',
  29. 'blip.tv' => 'blip'
  30. );
  31. public function strip( $content )
  32. {
  33. // In case Joomla tries to entity the contents, we need to replace accordingly.
  34. $content = str_ireplace( '&quot;' , '"' , $content );
  35. $pattern = array('/\{video:.*?\}/',
  36. '/\{"video":.*?\}/',
  37. '/\[embed=.*?\].*?\[\/embed\]/'
  38. );
  39. $replace = array('','');
  40. return preg_replace( $pattern , $replace , $content );
  41. }
  42. /*
  43. isPlain - return only video url in the content when is true. else, return embeded video object
  44. */
  45. public function processVideos( $content, $isPlain = false )
  46. {
  47. // @since 3.5
  48. // New pattern uses [embed=videolink] to process embedded videos from external URLs.
  49. //
  50. // videolink - External video URLs like Youtube, Google videos, MTV
  51. // video - Internal video URLs that are uploaded via media manager
  52. $pattern = '/\[embed=(.*)\](.*)\[\/embed\]/i';
  53. preg_match_all( $pattern , $content , $matches , PREG_SET_ORDER );
  54. if( !empty( $matches ) )
  55. {
  56. foreach( $matches as $match )
  57. {
  58. $type = $match[1];
  59. $search = $match[0];
  60. $result = $match[2];
  61. switch( $type )
  62. {
  63. // Videos that are linked from external sites such as Youtube.
  64. case 'videolink':
  65. $content = $this->processExternalVideos( $content , $isPlain , $search , $result );
  66. break;
  67. // Normal video embeds that are uploaded via media manager.
  68. case 'video':
  69. $content = $this->processInternalVideos( $content , $isPlain , $search , $result );
  70. break;
  71. }
  72. }
  73. }
  74. // @legacy Prior to 3.5, internal videos uses the format of <div class="easyblog-placeholder-video">
  75. $content = $this->processInternalVideos( $content , $isPlain );
  76. // @legacy Prior to 3.5, videos only uses {"video":"url" } so we still need to replace this if it exists.
  77. $content = $this->processExternalVideos( $content , $isPlain );
  78. return $content;
  79. }
  80. public function processInternalVideos( $content , $isPlain = false , $findText = '' , $result = '' )
  81. {
  82. $cfg = EasyBlogHelper::getConfig();
  83. // Since 3.0 uses a different video format, we need to do some tests here.
  84. if( $result )
  85. {
  86. require_once( EBLOG_CLASSES . DIRECTORY_SEPARATOR . 'json.php' );
  87. $json = new Services_JSON();
  88. $data = $json->decode( $result );
  89. $file = trim( $data->file , '/\\' );
  90. $width = $data->width;
  91. $height = $data->height;
  92. $autostart = $data->autostart;
  93. $place = $data->place;
  94. if( $place == 'shared' )
  95. {
  96. $url = rtrim( JURI::root() , '/' ) . '/' . trim( str_ireplace( '\\' , '/' , $cfg->get( 'main_shared_path' ) ) , '/\\') . '/' . $file;
  97. }
  98. else
  99. {
  100. $place = explode( ':' , $place );
  101. $url = rtrim( JURI::root() , '/' ) . '/' . trim( $cfg->get( 'main_image_path' ) , '/\\') . '/' . $place[1] . '/' . $file;
  102. }
  103. $theme = new CodeThemes();
  104. // Give a unique id for the video.
  105. $theme->set( 'uid' , uniqid() );
  106. $theme->set( 'width' , $width );
  107. $theme->set( 'height' , $height );
  108. $theme->set( 'autoplay' , $autostart );
  109. $theme->set( 'url' , $url );
  110. $output = $theme->fetch( 'blog.video.php' );
  111. $content = str_ireplace( $findText , $output , $content );
  112. return $content;
  113. }
  114. // @legacy Legacy support for prior to 3.5
  115. // This should be removed later.
  116. $pattern = '#"easyblog-video*[^>]*#is';
  117. $html = $content;
  118. preg_match( $pattern , $content , $matches );
  119. if( !empty($matches) && isset( $matches[0 ] ) )
  120. {
  121. // Match the value
  122. $input = $matches[ 0 ];
  123. preg_match( '/value="(.*})"/i' , $input , $data );
  124. if( isset( $data[1] ) )
  125. {
  126. $json = new Services_JSON();
  127. $data[1] = str_ireplace( '"' , '' , $data[ 1 ] );
  128. $obj = $json->decode( $data[ 1 ] );
  129. $theme = new CodeThemes();
  130. $uri = rtrim( JURI::root() , '/' ) . '/' . str_ireplace( "\\" , '/' , rtrim( $cfg->get( 'main_image_path' ) , '/' ) ) . '/' . $userId;
  131. $uri .= '/' . $obj->path;
  132. $storage = str_ireplace( '/' , DIRECTORY_SEPARATOR , rtrim( $cfg->get( 'main_image_path' ) , '/' ) );
  133. if( !isset( $obj->autoplay ) )
  134. {
  135. $obj->autoplay = false;
  136. }
  137. $theme->set( 'url' , $uri );
  138. $theme->set( 'width' , $obj->width );
  139. $theme->set( 'height' , $obj->height );
  140. $theme->set( 'autoplay' , false );
  141. $theme->set( 'video' , $obj );
  142. $theme->set( 'uid' , uniqid() );
  143. $output = $theme->fetch( 'blog.video.php' );
  144. $pattern = array( '#<div class="easyblog-placeholder-video(.*?)</div>(.*?)#is' );
  145. $content = preg_replace( $pattern , $output , $content );
  146. // Remove unwanted data
  147. $content = preg_replace( '#<p>&nbsp;</p>(|\n|\r\n)<p><input class="easyblog-video(.*?)</p>#is' , '' , $content );
  148. return $content;
  149. }
  150. }
  151. return $content;
  152. }
  153. /**
  154. * Processes external video links such as youtube, vimeo etc.
  155. *
  156. * @access public
  157. *
  158. */
  159. public function processExternalVideos( $content , $isPlain = false , $findText = '' , $jsonString = '' )
  160. {
  161. $cfg = EasyBlogHelper::getConfig();
  162. if( !empty( $jsonString ) )
  163. {
  164. $json = new Services_JSON();
  165. $data = $json->decode( $jsonString );
  166. $search = !empty( $findText ) ? $findText : $jsonString;
  167. if( $isPlain )
  168. {
  169. $html = ' ' . $data->video . ' ';
  170. $content = str_ireplace( $search , $html , $content );
  171. }
  172. else
  173. {
  174. // @task: Ensure that the width doesn't exceed the maximum width settings.
  175. $data->width = $data->width > $cfg->get( 'max_video_width' ) ? $cfg->get( 'max_video_width' ) : $data->width;
  176. // @task: Ensure that the height doesn't exceed the maximum height settings.
  177. $data->height = $data->height > $cfg->get( 'max_video_height' ) ? $cfg->get( 'max_video_height' ) : $data->height;
  178. $data->video = strip_tags( $data->video );
  179. $output = $this->processVideoLink( $data->video , $data->width , $data->height );
  180. if( $output !== false )
  181. {
  182. $content = str_ireplace( $search , $output , $content );
  183. }
  184. }
  185. }
  186. if( empty( $jsonString ) )
  187. {
  188. // @since 2.0.3515, video:"url" has been changed to "video":"url"
  189. $pattern = '/\{"video":.*?\}/i';
  190. // In case Joomla tries to entity the contents, we need to replace accordingly.
  191. $tmpContent = str_ireplace( '&quot;' , '"' , $content );
  192. preg_match_all( $pattern , $tmpContent , $matches );
  193. $videos = $matches[0];
  194. // @since 2.0.3515 Legacy support for older codes video:"url"
  195. if( empty( $videos ) )
  196. {
  197. $pattern = '/\{video:.*?\}/i';
  198. preg_match_all( $pattern , $tmpContent , $matches );
  199. $videos = $matches[0];
  200. }
  201. foreach( $videos as $video )
  202. {
  203. $json = new Services_JSON();
  204. $data = $json->decode( $video );
  205. $search = !empty( $findText ) ? $findText : $video;
  206. if( $isPlain )
  207. {
  208. $html = ' ' . $data->video . ' ';
  209. $content = str_ireplace( $search , $html , $content );
  210. }
  211. else
  212. {
  213. // @task: Ensure that the width doesn't exceed the maximum width settings.
  214. $data->width = $data->width > $cfg->get( 'max_video_width' ) ? $cfg->get( 'max_video_width' ) : $data->width;
  215. // @task: Ensure that the height doesn't exceed the maximum height settings.
  216. $data->height = $data->height > $cfg->get( 'max_video_height' ) ? $cfg->get( 'max_video_height' ) : $data->height;
  217. $data->video = strip_tags( $data->video );
  218. $output = $this->processVideoLink( $data->video , $data->width , $data->height );
  219. if( $output !== false )
  220. {
  221. $content = str_ireplace( $search , $output , $content );
  222. }
  223. }
  224. }
  225. }
  226. return $content;
  227. }
  228. /**
  229. * Given a set of content, try to match and return the list of videos that are found in the content.
  230. * This is only applicable for videos that are supported by the library.
  231. *
  232. * @author imarklee
  233. * @access public
  234. * @param string $content The html contents that we should look for.
  235. * @return Array An array of videos that are found.
  236. */
  237. public function getHTMLArray( $content )
  238. {
  239. // This will eventually contain all the video objects
  240. $result = array();
  241. // Store temporary content for legacy fixes.
  242. $tmpContent = $content;
  243. // @since 3.5
  244. // New pattern uses [embed=videolink] to process embedded videos from external URLs.
  245. //
  246. // videolink - External video URLs like Youtube, Google videos, MTV
  247. // video - Internal video URLs that are uploaded via media manager
  248. $pattern = '/\[embed=(.*)\](.*)\[\/embed\]/i';
  249. preg_match_all( $pattern , $content , $matches , PREG_SET_ORDER );
  250. if( !empty( $matches ) )
  251. {
  252. foreach( $matches as $match )
  253. {
  254. $type = $match[1];
  255. $search = $match[0];
  256. $rawJSON = $match[2];
  257. if( $type == 'videolink' || $type == 'video' )
  258. {
  259. $data = $this->parseJSON( $rawJSON );
  260. // Let's remove it from the temporary content.
  261. $tmpContent = str_ireplace( $search , '' , $tmpContent );
  262. switch( $type )
  263. {
  264. // Videos that are linked from external sites such as Youtube.
  265. case 'videolink':
  266. $html = $this->processVideoLink( $data->video , $data->width , $data->height );
  267. break;
  268. // Normal video embeds that are uploaded via media manager.
  269. case 'video':
  270. $html = $this->processInternalVideoLink( $content , $rawJSON );
  271. break;
  272. }
  273. // Now, let's add the data object back to the result list.
  274. $result[] = $html;
  275. }
  276. }
  277. }
  278. // @legacy prior to EasyBlog 3.5
  279. // @since 2.0.3515, video:"url" has been changed to "video":"url"
  280. $pattern = '/\{"video":.*?\}/i';
  281. // In case Joomla tries to entity the contents, we need to replace accordingly.
  282. $tmpContent = str_ireplace( '&quot;' , '"' , $tmpContent );
  283. // @task: We search in $tmpContent instead of $content because the new [embed] codes might already replace the values.
  284. preg_match_all( $pattern , $tmpContent , $matches );
  285. $videos = $matches[0];
  286. if( empty( $videos ) )
  287. {
  288. return $result;
  289. }
  290. foreach( $videos as $video )
  291. {
  292. $data = $this->parseJSON( $video );
  293. $output = $this->processVideoLink( $data->video , $data->width , $data->height );
  294. if( $output !== false )
  295. {
  296. $result[] = $output;
  297. }
  298. }
  299. return $result;
  300. }
  301. /**
  302. * Given a set of content, try to match and return the list of videos that are found in the content.
  303. * This is only applicable for videos that are supported by the library.
  304. *
  305. * @author imarklee
  306. * @access public
  307. * @param string $content The html contents that we should look for.
  308. * @return Array An array of videos that are found.
  309. */
  310. public function getVideoObjects( $content )
  311. {
  312. // This will eventually contain all the video objects
  313. $result = array();
  314. // Store temporary content for legacy fixes.
  315. $tmpContent = $content;
  316. // @since 3.5
  317. // New pattern uses [embed=videolink] to process embedded videos from external URLs.
  318. //
  319. // videolink - External video URLs like Youtube, Google videos, MTV
  320. // video - Internal video URLs that are uploaded via media manager
  321. $pattern = '/\[embed=(.*)\](.*)\[\/embed\]/i';
  322. preg_match_all( $pattern , $content , $matches , PREG_SET_ORDER );
  323. if( !empty( $matches ) )
  324. {
  325. foreach( $matches as $match )
  326. {
  327. $type = $match[1];
  328. $search = $match[0];
  329. $rawJSON = $match[2];
  330. $data = $this->parseJSON( $rawJSON );
  331. // Let's remove it from the temporary content.
  332. $tmpContent = str_ireplace( $search , '' , $tmpContent );
  333. switch( $type )
  334. {
  335. // Videos that are linked from external sites such as Youtube.
  336. case 'videolink':
  337. $data->html = $this->processVideoLink( $data->video , $data->width , $data->height );
  338. break;
  339. // Normal video embeds that are uploaded via media manager.
  340. case 'video':
  341. // TODO
  342. break;
  343. }
  344. // Now, let's add the data object back to the result list.
  345. $result[] = $data;
  346. }
  347. }
  348. // @legacy prior to EasyBlog 3.5
  349. // @since 2.0.3515, video:"url" has been changed to "video":"url"
  350. $pattern = '/\{"video":.*?\}/i';
  351. // In case Joomla tries to entity the contents, we need to replace accordingly.
  352. $tmpContent = str_ireplace( '&quot;' , '"' , $tmpContent );
  353. // @task: We search in $tmpContent instead of $content because the new [embed] codes might already replace the values.
  354. preg_match_all( $pattern , $tmpContent , $matches );
  355. $videos = $matches[0];
  356. if( empty( $videos ) )
  357. {
  358. return $result;
  359. }
  360. foreach( $videos as $video )
  361. {
  362. $data = $this->parseJSON( $video );
  363. $output = $this->processVideoLink( $data->video , $data->width , $data->height );
  364. if( $output !== false )
  365. {
  366. $data->html = $output;
  367. $result[] = $data;
  368. }
  369. }
  370. return $result;
  371. }
  372. private function parseJSON( $jsonRaw )
  373. {
  374. // Initialize the JSON library
  375. $json = new Services_JSON();
  376. return $json->decode( $jsonRaw );
  377. }
  378. private function getDomain( $link )
  379. {
  380. if( stristr( $link , 'http://') === false && stristr( $link , 'https://') === false )
  381. {
  382. $link = 'http://' . $link;
  383. }
  384. $link = parse_url( $link );
  385. $link = explode( '.' , $link[ 'host' ] );
  386. $domain = $link[ count( $link ) - 2 ] . '.' . $link[ count( $link ) - 1 ];
  387. return $domain;
  388. }
  389. public function processInternalVideoLink( $content , $jsonString = '' )
  390. {
  391. $cfg = EasyBlogHelper::getConfig();
  392. // Since 3.0 uses a different video format, we need to do some tests here.
  393. if( $jsonString )
  394. {
  395. require_once( EBLOG_CLASSES . DIRECTORY_SEPARATOR . 'json.php' );
  396. $json = new Services_JSON();
  397. $data = $json->decode( $jsonString );
  398. $file = trim( $data->file , '/\\' );
  399. $width = $data->width;
  400. $height = $data->height;
  401. $autostart = $data->autostart;
  402. $place = $data->place;
  403. if( $place == 'shared' )
  404. {
  405. $url = rtrim( JURI::root() , '/' ) . '/' . trim( str_ireplace( '\\' , '/' , $cfg->get( 'main_shared_path' ) ) , '/\\') . '/' . $file;
  406. }
  407. else
  408. {
  409. $place = explode( ':' , $place );
  410. $url = rtrim( JURI::root() , '/' ) . '/' . trim( $cfg->get( 'main_image_path' ) , '/\\') . '/' . $place[1] . '/' . $file;
  411. }
  412. $theme = new CodeThemes();
  413. // Give a unique id for the video.
  414. $theme->set( 'uid' , uniqid() );
  415. $theme->set( 'width' , $width );
  416. $theme->set( 'height' , $height );
  417. $theme->set( 'autoplay' , $autostart );
  418. $theme->set( 'url' , $url );
  419. $output = $theme->fetch( 'blog.video.php' );
  420. return $output;
  421. }
  422. // @legacy Legacy support for prior to 3.5
  423. // This should be removed later.
  424. $pattern = '#"easyblog-video*[^>]*#is';
  425. preg_match( $pattern , $content , $matches );
  426. if( !empty($matches) && isset( $matches[0 ] ) )
  427. {
  428. // Match the value
  429. $input = $matches[ 0 ];
  430. preg_match( '/value="(.*})"/i' , $input , $data );
  431. if( isset( $data[1] ) )
  432. {
  433. $json = new Services_JSON();
  434. $data[1] = str_ireplace( '"' , '' , $data[ 1 ] );
  435. $obj = $json->decode( $data[ 1 ] );
  436. $theme = new CodeThemes();
  437. $uri = rtrim( JURI::root() , '/' ) . '/' . str_ireplace( "\\" , '/' , rtrim( $cfg->get( 'main_image_path' ) , '/' ) ) . '/' . $userId;
  438. $uri .= '/' . $obj->path;
  439. $storage = str_ireplace( '/' , DIRECTORY_SEPARATOR , rtrim( $cfg->get( 'main_image_path' ) , '/' ) );
  440. if( !isset( $obj->autoplay ) )
  441. {
  442. $obj->autoplay = false;
  443. }
  444. $theme->set( 'url' , $uri );
  445. $theme->set( 'width' , $obj->width );
  446. $theme->set( 'height' , $obj->height );
  447. $theme->set( 'autoplay' , false );
  448. $theme->set( 'video' , $obj );
  449. $theme->set( 'uid' , uniqid() );
  450. $output = $theme->fetch( 'blog.video.php' );
  451. $pattern = array( '#<div class="easyblog-placeholder-video(.*?)</div>(.*?)#is' );
  452. $content = preg_replace( $pattern , $output , $content );
  453. return $content;
  454. }
  455. }
  456. }
  457. public function processVideoLink( $link , $width , $height )
  458. {
  459. $domain = $this->getDomain( $link );
  460. if( !array_key_exists( $domain , $this->patterns ) )
  461. {
  462. $content = str_ireplace( $video , $html , $content );
  463. return false;
  464. }
  465. $provider = JString::strtolower( $this->patterns[ $domain ] );
  466. $path = EBLOG_CLASSES . DIRECTORY_SEPARATOR . 'videos' . DIRECTORY_SEPARATOR . $provider . '.php';
  467. require_once( $path );
  468. $class = 'EasyBlogVideo' . ucfirst( $this->patterns[ $domain ] );
  469. if( class_exists( $class ) )
  470. {
  471. $object = new $class();
  472. $html = $object->getEmbedHTML( $link , $width , $height );
  473. return $html;
  474. }
  475. return false;
  476. }
  477. }