source: extensions/gvideo/include/functions.inc.php @ 28268

Last change on this file since 28268 was 28268, checked in by mistic100, 10 years ago

allow to add any video with direct embed code + add batch manager filter

File size: 18.2 KB
Line 
1<?php
2defined('PHPWG_ROOT_PATH') or die('Hacking attempt!');
3
4function parse_video_url($source_url, $safe_mode=false)
5{
6  $source_url = 'http://'.preg_replace('#^http(s?)://#', null, trim($source_url));
7 
8  $url = parse_url($source_url);
9  $url['host'] = str_replace('www.', null, $url['host']);
10  $url['host'] = explode('.', $url['host']);
11 
12  $video = array(
13    'type' => null,
14    'video_id' => null,
15    'url' => null,
16    'title' => null,
17    'description' => null,
18    'thumbnail' => null,
19    'author' => null,
20    'tags' => null,
21  );
22 
23  switch ($url['host'][0])
24  {
25    /* youtube */
26    case 'youtube':
27    {
28      parse_str($url['query'], $url['query']);
29      if (empty($url['query']['v'])) return false;
30     
31      $video['video_id'] = $url['query']['v'];
32    }
33   
34    case 'youtu': // youtu.be (short-url service)
35    {
36      $video['type'] = 'youtube';
37     
38      if (empty($video['video_id']))
39      {
40        if ($url['host'][1] != 'be') return false;
41        $url['path'] = explode('/', $url['path']);
42        $video['video_id'] = $url['path'][1];
43      }
44     
45      $video['url'] = 'http://youtube.com/watch?v='.$video['video_id'];
46      $video['title'] = 'YouTube #'.$video['video_id'];
47     
48      if (!$safe_mode)
49      {
50        $api_url = 'http://gdata.youtube.com/feeds/api/videos/'.$video['video_id'].'?v=2&alt=json';
51        $json = gvideo_download_remote_file($api_url, true);
52       
53        if ($json===false || $json=='file_error') return false;
54        if (strip_tags($json) == 'GDataInvalidRequestUriExceptionInvalid id') return false; // unknown video
55        if (strip_tags($json) == 'GDataServiceForbiddenExceptionPrivate video') return false; // private video
56       
57        $json = json_decode($json, true);
58        $video = array_merge($video, array(
59          'title' => $json['entry']['media$group']['media$title']['$t'],
60          'description' => $json['entry']['media$group']['media$description']['$t'],
61          'thumbnail' => $json['entry']['media$group']['media$thumbnail'][2]['url'],
62          'author' => $json['entry']['author'][0]['name']['$t'],
63          ));
64        if (!empty($json['entry']['media$group']['media$keywords']['$t']))
65        {
66          $video['tags'] = $json['entry']['media$group']['media$keywords']['$t'];
67        }
68      }
69     
70      break;
71    }
72     
73    /* vimeo */
74    case 'vimeo':
75    {
76      $video['type'] = 'vimeo';
77     
78      $url['path'] = explode('/', $url['path']);
79      $video['video_id'] = $url['path'][1];
80     
81      $video['url'] = 'http://vimeo.com/'.$video['video_id'];
82      $video['title'] = 'Vimeo #'.$video['video_id'];
83     
84      if (!$safe_mode)
85      {
86        // simple API for public videos
87        $api_url_1 = 'http://vimeo.com/api/v2/video/'.$video['video_id'].'.json';
88        $json = gvideo_download_remote_file($api_url_1, true);
89       
90        if ($json!==false && $json!='file_error' && trim($json)!=$video['video_id'].' not found.')
91        {
92          $json = json_decode($json, true);
93          $video = array_merge($video, array(
94            'title' => $json[0]['title'],
95            'description' => $json[0]['description'],
96            'thumbnail' => $json[0]['thumbnail_large'],
97            'author' => $json[0]['user_name'],
98            'tags' => $json[0]['tags'],
99            ));
100        }
101        else
102        {
103          // oEmbed API, for private videos, doesn't return keywords
104          $api_url_2 = 'http://vimeo.com/api/oembed.json?url='.rawurlencode($video['url']);
105          $json = gvideo_download_remote_file($api_url_2, true);
106         
107          if ($json===false || $json=='file_error') return false;
108         
109          $json = json_decode($json, true);
110          $video = array_merge($video, array(
111            'title' => $json['title'],
112            'description' => $json['description'],
113            'thumbnail' => $json['thumbnail_url'],
114            'author' => $json['author_name'],
115            ));
116        }
117      }
118     
119      break;
120    }
121     
122    /* dailymotion */
123    case 'dailymotion':
124    {
125      $url['path'] = explode('/', $url['path']);
126      if ($url['path'][1] != 'video') return false;
127      $video['video_id'] = $url['path'][2];
128    }
129   
130    case 'dai':  // dai.ly (short-url service)
131    {
132      $video['type'] = 'dailymotion';
133     
134      if (empty($video['video_id']))
135      {
136        if ($url['host'][1] != 'ly') return false;
137        $video['video_id'] = ltrim($url['path'], '/');
138      }
139     
140      $video['url'] = 'http://dailymotion.com/video/'.$video['video_id'];
141      $video['title'] = 'Dailymotion #'.$video['video_id'];
142     
143      if (!$safe_mode)
144      {
145        $api_url = 'https://api.dailymotion.com/video/'.$video['video_id'].'?fields=description,thumbnail_large_url,title,owner.username,tags'; // DM doesn't accept non secure connection
146        $json = gvideo_download_remote_file($api_url, true);
147       
148        if ($json===false || $json=='file_error') return false;
149       
150        $json = json_decode($json, true);
151        if (@$json['error']['type'] == 'access_forbidden') return false; // private video
152        $json['thumbnail_large_url'] = preg_replace('#\?([0-9]+)$#', null, $json['thumbnail_large_url']);
153       
154        $video = array_merge($video, array(
155          'title' => $json['title'],
156          'description' => $json['description'],
157          'thumbnail' => $json['thumbnail_large_url'],
158          'author' => $json['owner.username'],
159          'tags' => implode(',', $json['tags']),
160          ));
161      }
162     
163      break;
164    }
165     
166    /* wat */
167    case 'wat':
168    {
169      if ($safe_mode) return false;
170     
171      $html = gvideo_download_remote_file($source_url, true);
172
173      if ($html===false || $html=='file_error') return false;
174     
175      $video['type'] = 'wat';
176      $video['url'] = $source_url;
177     
178      preg_match('#<meta name="twitter:player" content="https://www.wat.tv/embedframe/([^">]+)">#', $html, $matches);
179      if (empty($matches[1])) return false;
180      $video['video_id'] = $matches[1];
181
182      preg_match('#<meta property="og:title" content="([^">]*)">#', $html, $matches);
183      $video['title'] = $matches[1];
184     
185      preg_match('#<meta property="og:description" content="([^">]*)">#s', $html, $matches);
186      $video['description'] = $matches[1];
187     
188      preg_match('#<meta property="og:image" content="([^">]+)">#', $html, $matches);
189      $video['thumbnail'] = $matches[1];
190     
191      preg_match('#<meta property="video:director" content="http://www.wat.tv/([^">]+)">#', $html, $matches);
192      $video['author'] = $matches[1];
193     
194      preg_match_all('#<meta property="video:tag" content="([^">]+)">#', $html, $matches);
195      $video['tags'] = implode(',',  $matches[1]);
196     
197      break;
198    }
199     
200    /* wideo */
201    case 'wideo':
202    {
203      $video['type'] = 'wideo';
204     
205      $url['path'] = explode('/', $url['path']);
206      $video['video_id'] = rtrim($url['path'][2], '.html');
207     
208      $video['url'] = 'http://wideo.fr/video/'.$video['video_id'].'.html';
209      $video['title'] = 'Wideo #'.$video['video_id'];
210     
211      if (!$safe_mode)
212      {
213        $html = gvideo_download_remote_file($source_url, true);
214       
215        if ($html===false || $html=='file_error') return false;
216       
217        preg_match('#<meta property="og:title" content="([^">]*)" />#', $html, $matches);
218        $video['title'] = $matches[1];
219       
220        preg_match('#<meta property="og:description" content="([^">]*)" />#s', $html, $matches);
221        $video['description'] = $matches[1];
222       
223        preg_match('#<meta property="og:image" content="([^">]+)" />#', $html, $matches);
224        $video['thumbnail'] = $matches[1];
225       
226        preg_match('#<li id="li_author">Auteur :  <a href=(?:[^>]*)><span>(.*?)</span></a>#', $html, $matches);
227        $video['author'] = $matches[1];
228       
229        preg_match('#<meta name="keywords" content="([^">]+)" />#', $html, $matches);
230        $video['tags'] = $matches[1];
231      }
232     
233      break;
234    }
235
236    default:
237      return false;   
238  }
239 
240  return $video;
241}
242
243/**
244 * @params:
245 *  $video (from parse_video_url)
246 *  $config :
247 *    - category, integer
248 *    - add_film_frame, boolean
249 *    - sync_description, boolean
250 *    - sync_tags, boolean
251 *    - with, integer
252 *    - height, integer
253 *    - autoplay, integer (0-1)
254 */
255function add_video($video, $config)
256{
257  global $page, $conf;
258 
259  $query = '
260SELECT picture_id
261  FROM '.GVIDEO_TABLE.'
262  WHERE type = "'.$video['type'].'"
263    AND video_id = "'.$video['video_id'].'"
264;';
265  $result = pwg_query($query);
266 
267  if (pwg_db_num_rows($result))
268  {
269    $page['warnings'][] = l10n('This video was already registered');
270    list($image_id) = pwg_db_fetch_row($result);
271    return $image_id;
272  }
273 
274  include_once(PHPWG_ROOT_PATH . 'admin/include/functions_upload.inc.php');
275 
276  // download thumbnail
277  $thumb_ext = empty($video['thumbnail']) ? 'jpg' : get_extension($video['thumbnail']);
278  $thumb_name = $video['type'].'-'.$video['video_id'].'-'.uniqid().'.'.$thumb_ext;
279  $thumb_source = $conf['data_location'].$thumb_name;
280 
281  if (empty($video['thumbnail']) or gvideo_download_remote_file($video['thumbnail'], $thumb_source) !== true)
282  {
283    $thumb_source = $conf['data_location'].get_filename_wo_extension($thumb_name).'.jpg';
284    copy(GVIDEO_PATH.'mimetypes/'.$video['type'].'.jpg', $thumb_source);
285  }
286 
287  if ($config['add_film_frame'])
288  {
289    add_film_frame($thumb_source);
290  }
291 
292  // add image and update infos
293  $image_id = add_uploaded_file($thumb_source, $thumb_name, array($config['category']));
294 
295  $updates = array(
296    'name' => pwg_db_real_escape_string($video['title']),
297    'author' => pwg_db_real_escape_string($video['author']),
298    'is_gvideo' => 1,
299    );
300   
301  if ($config['sync_description'] and !empty($video['description']))
302  {
303    $updates['comment'] = pwg_db_real_escape_string($video['description']);
304  }
305 
306  if ($config['sync_tags'] and !empty($video['tags']))
307  {
308    $tags = pwg_db_real_escape_string($video['tags']);
309    set_tags(get_tag_ids($tags), $image_id);
310  }
311 
312  single_update(
313    IMAGES_TABLE,
314    $updates,
315    array('id' => $image_id),
316    true
317    );
318 
319  // register video
320  if (!preg_match('#^([0-9]*)$#', $config['width']) or !preg_match('#^([0-9]*)$#', $config['height']))
321  {
322    $config['width'] = $config['height'] = '';
323  }
324  if ($config['autoplay']!='0' and $config['autoplay']!='1')
325  {
326    $config['autoplay'] = '';
327  }
328 
329  $insert = array(
330    'picture_id' => $image_id,
331    'url' => $video['url'],
332    'type' => $video['type'],
333    'video_id' => $video['video_id'],
334    'width' => $config['width'],
335    'height' => $config['height'],
336    'autoplay' => $config['autoplay'],
337    );
338   
339  single_insert(
340    GVIDEO_TABLE,
341    $insert
342    );
343   
344  return $image_id;
345}
346
347/**
348 * @params:
349 *  $config :
350 *    - url, string
351 *    - category, integer
352 *    - add_film_frame, boolean
353 *    - title, string
354 *    - embed_code, string
355 */
356function add_video_embed($config)
357{
358  global $page, $conf;
359 
360  $query = '
361SELECT picture_id
362  FROM '.GVIDEO_TABLE.'
363  WHERE url = "'.$config['url'].'"
364;';
365  $result = pwg_query($query);
366 
367  if (pwg_db_num_rows($result))
368  {
369    $page['warnings'][] = l10n('This video was already registered');
370    list($image_id) = pwg_db_fetch_row($result);
371    return $image_id;
372  }
373 
374  include_once(PHPWG_ROOT_PATH . 'admin/include/functions_upload.inc.php');
375 
376  // upload thumbnail
377  if (isset($_FILES['thumbnail_file']) && $_FILES['thumbnail_file']['error'] === UPLOAD_ERR_OK)
378  {
379    $source_filepath = $_FILES['thumbnail_file']['tmp_name'];
380    list(,, $type) = getimagesize($source_filepath);
381   
382    if (IMAGETYPE_PNG == $type || IMAGETYPE_GIF == $type || IMAGETYPE_JPEG == $type)
383    {
384      $thumb_name = $_FILES['thumbnail_file']['name'];
385      $thumb_source = $conf['data_location'].$thumb_name;
386      move_uploaded_file($source_filepath, $thumb_source);
387    }
388  }
389 
390  if (!isset($thumb_source))
391  {
392    $thumb_name = 'embed-'.uniqid().'.jpg';
393    $thumb_source = $conf['data_location'].$thumb_name;
394    copy(GVIDEO_PATH.'mimetypes/any.jpg', $thumb_source);
395  }
396 
397  if ($config['add_film_frame'])
398  {
399    add_film_frame($thumb_source);
400  }
401 
402  // add image and update infos
403  $image_id = add_uploaded_file($thumb_source, $thumb_name, array($config['category']));
404 
405  if (empty($config['title']))
406  {
407    $config['title'] = get_filename_wo_extension($thumb_name);
408  }
409 
410  $updates = array(
411    'name' => pwg_db_real_escape_string($config['title']),
412    'is_gvideo' => 1,
413    );
414 
415  single_update(
416    IMAGES_TABLE,
417    $updates,
418    array('id' => $image_id),
419    true
420    );
421
422  $insert = array(
423    'picture_id' => $image_id,
424    'url' => $config['url'],
425    'type' => 'embed',
426    'video_id' => 'embed',
427    'width' => '',
428    'height' => '',
429    'autoplay' => '',
430    'embed' => $config['embed_code']
431    );
432  var_dump($insert);
433  single_insert(
434    GVIDEO_TABLE,
435    $insert
436    );
437   
438  return $image_id;
439}
440
441/**
442 * test if a download method is available
443 * @return: bool
444 */
445if (!function_exists('test_remote_download'))
446{
447  function test_remote_download()
448  {
449    return function_exists('curl_init') || ini_get('allow_url_fopen');
450  }
451}
452
453/**
454 * download a remote file
455 *  - needs cURL or allow_url_fopen
456 *  - take care of SSL urls
457 *
458 * @param: string source url
459 * @param: mixed destination file (if true, file content is returned)
460 */
461function gvideo_download_remote_file($src, $dest, $headers=array())
462{
463  if (empty($src))
464  {
465    return false;
466  }
467 
468  $return = ($dest === true) ? true : false;
469 
470  $headers[] = 'Accept-language: en';
471 
472  /* curl */
473  if (function_exists('curl_init'))
474  {
475    if (!$return)
476    {
477      $newf = fopen($dest, "wb");
478    }
479    $ch = curl_init();
480   
481    curl_setopt($ch, CURLOPT_URL, $src);
482    curl_setopt($ch, CURLOPT_HEADER, false);
483    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
484    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)');
485    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
486    if (!ini_get('safe_mode'))
487    {
488      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
489      curl_setopt($ch, CURLOPT_MAXREDIRS, 1);
490    }
491    if (strpos($src, 'https://') !== false)
492    {
493      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
494      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
495    }
496    if (!$return)
497    {
498      curl_setopt($ch, CURLOPT_FILE, $newf);
499    }
500    else
501    {
502      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
503    }
504   
505    $out = curl_exec($ch);
506    curl_close($ch);
507   
508    if ($out === false)
509    {
510      return 'file_error';
511    }
512    else if (!$return)
513    {
514      fclose($newf);
515      return true;
516    }
517    else
518    {
519      return $out;
520    }
521  }
522  /* file get content */
523  else if (ini_get('allow_url_fopen'))
524  {
525    if (strpos($src, 'https://') !== false and !extension_loaded('openssl'))
526    {
527      return false;
528    }
529   
530    $opts = array(
531      'http' => array(
532        'method' => "GET",
533        'user_agent' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
534        'header' => implode("\r\n", $headers),
535      )
536    );
537
538    $context = stream_context_create($opts);
539   
540    if (($file = file_get_contents($src, false, $context)) === false)
541    {
542      return 'file_error';
543    }
544   
545    if (!$return)
546    {
547      file_put_contents($dest, $file);
548      return true;
549    }
550    else
551    {
552      return $file;
553    }
554  }
555 
556  return false;
557}
558
559/**
560 * and film frame to an image (need GD library)
561 * @param: string source
562 * @param: string destination (if null, the source is modified)
563 * @return: void
564 */
565function add_film_frame($src, $dest=null)
566{
567  if (empty($dest))
568  {
569    $dest = $src;
570  }
571 
572  // we need gd library
573  if (!function_exists('imagecreatetruecolor'))
574  {
575    if ($dest != $src) copy($src, $dest);
576    return;
577  }
578 
579  // open source image
580  switch (strtolower(get_extension($src)))
581  {
582    case 'jpg':
583    case 'jpeg':
584      $srcImage = imagecreatefromjpeg($src);
585      break;
586    case 'png':
587      $srcImage = imagecreatefrompng($src);
588      break;
589    case 'gif':
590      $srcImage = imagecreatefromgif($src);
591      break;
592    default:
593      if ($dest != $src) copy($src, $dest);
594      return;
595  }
596 
597  // source properties
598  $srcWidth = imagesx($srcImage);
599  $srcHeight = imagesy($srcImage);
600  $const = intval($srcWidth * 0.04);
601  $bandRadius = floor($const/8);
602
603  // band properties
604  $imgBand = imagecreatetruecolor($srcWidth + 6*$const, $srcHeight + 3*$const);
605 
606  $black = imagecolorallocate($imgBand, 0, 0, 0);
607  $white = imagecolorallocate($imgBand, 245, 245, 245);
608 
609  // and dots
610  $y_start = intval(($srcHeight + 3*$const) / 2);
611  $aug = intval($y_start / 5) + 1;
612  $i = 0;
613
614  while ($y_start + $i*$aug < $srcHeight + 3*$const)
615  {
616    imagefilledroundrectangle($imgBand, (3/4)*$const, $y_start + $i*$aug - $const/2, (9/4)*$const - 1, $y_start + $i*$aug + $const/2 - 1, $white, $bandRadius);
617    imagefilledroundrectangle($imgBand, (3/4)*$const, $y_start - $i*$aug - $const/2, (9/4)*$const - 1, $y_start - $i*$aug + $const/2 - 1, $white, $bandRadius);
618
619    imagefilledroundrectangle($imgBand, $srcWidth + (15/4)*$const, $y_start + $i*$aug - $const/2, $srcWidth + (21/4)*$const - 1, $y_start + $i*$aug + $const/2 - 1, $white, $bandRadius);
620    imagefilledroundrectangle($imgBand, $srcWidth + (15/4)*$const, $y_start - $i*$aug - $const/2, $srcWidth + (21/4)*$const - 1, $y_start - $i*$aug + $const/2 - 1, $white, $bandRadius);
621
622    ++$i;
623  }
624
625  // add source to band
626  imagecopy($imgBand, $srcImage, 3*$const, (3/2)*$const, 0, 0, $srcWidth, $srcHeight);
627 
628  // save image
629  switch (strtolower(get_extension($dest)))
630  {
631    case 'jpg':
632    case 'jpeg':
633      imagejpeg($imgBand, $dest, 85);
634      break;
635    case 'png':
636      imagepng($imgBand, $dest);
637      break;
638    case 'gif':
639      imagegif($imgBand, $dest);
640      break;
641  }
642}
643
644/**
645 * create a rectangle with round corners
646 * http://www.php.net/manual/fr/function.imagefilledrectangle.php#42815
647 */
648function imagefilledroundrectangle(&$img, $x1, $y1, $x2, $y2, $color, $radius)
649{
650  imagefilledrectangle($img, $x1+$radius, $y1, $x2-$radius, $y2, $color);
651 
652  if ($radius > 0)
653  {
654    imagefilledrectangle($img, $x1, $y1+$radius, $x2, $y2-$radius, $color);
655    imagefilledellipse($img, $x1+$radius, $y1+$radius, $radius*2, $radius*2, $color);
656    imagefilledellipse($img, $x2-$radius, $y1+$radius, $radius*2, $radius*2, $color);
657    imagefilledellipse($img, $x1+$radius, $y2-$radius, $radius*2, $radius*2, $color);
658    imagefilledellipse($img, $x2-$radius, $y2-$radius, $radius*2, $radius*2, $color);
659  }
660}
Note: See TracBrowser for help on using the repository browser.