null, 'video_id' => null, 'url' => null, 'title' => null, 'description' => null, 'thumbnail' => null, 'author' => null, 'tags' => null, ); switch ($url['host'][0]) { /* youtube */ case 'youtube': { parse_str($url['query'], $url['query']); if (empty($url['query']['v'])) return false; $video['video_id'] = $url['query']['v']; } case 'youtu': // youtu.be (short-url service) { $video['type'] = 'youtube'; if (empty($video['video_id'])) { if ($url['host'][1] != 'be') return false; $url['path'] = explode('/', $url['path']); $video['video_id'] = $url['path'][1]; } $video['url'] = 'http://youtube.com/watch?v='.$video['video_id']; $video['title'] = 'YouTube #'.$video['video_id']; if (!$safe_mode) { $api_url = 'http://gdata.youtube.com/feeds/api/videos/'.$video['video_id'].'?v=2&alt=json'; $json = gvideo_download_remote_file($api_url, true); if ($json===false || $json=='file_error') return false; if (strip_tags($json) == 'GDataInvalidRequestUriExceptionInvalid id') return false; // unknown video if (strip_tags($json) == 'GDataServiceForbiddenExceptionPrivate video') return false; // private video $json = json_decode($json, true); $video = array_merge($video, array( 'title' => $json['entry']['media$group']['media$title']['$t'], 'description' => $json['entry']['media$group']['media$description']['$t'], 'thumbnail' => $json['entry']['media$group']['media$thumbnail'][2]['url'], 'author' => $json['entry']['author'][0]['name']['$t'], )); if (!empty($json['entry']['media$group']['media$keywords']['$t'])) { $video['tags'] = $json['entry']['media$group']['media$keywords']['$t']; } } break; } /* vimeo */ case 'vimeo': { $video['type'] = 'vimeo'; $url['path'] = explode('/', $url['path']); $video['video_id'] = $url['path'][1]; $video['url'] = 'http://vimeo.com/'.$video['video_id']; $video['title'] = 'Vimeo #'.$video['video_id']; if (!$safe_mode) { // simple API for public videos $api_url_1 = 'http://vimeo.com/api/v2/video/'.$video['video_id'].'.json'; $json = gvideo_download_remote_file($api_url_1, true); if ($json!==false && $json!='file_error' && trim($json)!=$video['video_id'].' not found.') { $json = json_decode($json, true); $video = array_merge($video, array( 'title' => $json[0]['title'], 'description' => $json[0]['description'], 'thumbnail' => $json[0]['thumbnail_large'], 'author' => $json[0]['user_name'], 'tags' => $json[0]['tags'], )); } else { // oEmbed API, for private videos, doesn't return keywords $api_url_2 = 'http://vimeo.com/api/oembed.json?url='.rawurlencode($video['url']); $json = gvideo_download_remote_file($api_url_2, true); if ($json===false || $json=='file_error') return false; $json = json_decode($json, true); $video = array_merge($video, array( 'title' => $json['title'], 'description' => $json['description'], 'thumbnail' => $json['thumbnail_url'], 'author' => $json['author_name'], )); } } break; } /* dailymotion */ case 'dailymotion': { $url['path'] = explode('/', $url['path']); if ($url['path'][1] != 'video') return false; $video['video_id'] = $url['path'][2]; } case 'dai': // dai.ly (short-url service) { $video['type'] = 'dailymotion'; if (empty($video['video_id'])) { if ($url['host'][1] != 'ly') return false; $video['video_id'] = ltrim($url['path'], '/'); } $video['url'] = 'http://dailymotion.com/video/'.$video['video_id']; $video['title'] = 'Dailymotion #'.$video['video_id']; if (!$safe_mode) { $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 $json = gvideo_download_remote_file($api_url, true); if ($json===false || $json=='file_error') return false; $json = json_decode($json, true); if (@$json['error']['type'] == 'access_forbidden') return false; // private video $json['thumbnail_large_url'] = preg_replace('#\?([0-9]+)$#', null, $json['thumbnail_large_url']); $video = array_merge($video, array( 'title' => $json['title'], 'description' => $json['description'], 'thumbnail' => $json['thumbnail_large_url'], 'author' => $json['owner.username'], 'tags' => implode(',', $json['tags']), )); } break; } /* wat */ case 'wat': { if ($safe_mode) return false; $html = gvideo_download_remote_file($source_url, true); if ($html===false || $html=='file_error') return false; $video['type'] = 'wat'; $video['url'] = $source_url; preg_match('#]+)">#', $html, $matches); if (empty($matches[1])) return false; $video['video_id'] = $matches[1]; preg_match('#]*)">#', $html, $matches); $video['title'] = $matches[1]; preg_match('#]*)">#s', $html, $matches); $video['description'] = $matches[1]; preg_match('#]+)">#', $html, $matches); $video['thumbnail'] = $matches[1]; preg_match('#]+)">#', $html, $matches); $video['author'] = $matches[1]; preg_match_all('#]+)">#', $html, $matches); $video['tags'] = implode(',', $matches[1]); break; } /* wideo */ case 'wideo': { $video['type'] = 'wideo'; $url['path'] = explode('/', $url['path']); $video['video_id'] = rtrim($url['path'][2], '.html'); $video['url'] = 'http://wideo.fr/video/'.$video['video_id'].'.html'; $video['title'] = 'Wideo #'.$video['video_id']; if (!$safe_mode) { $html = gvideo_download_remote_file($source_url, true); if ($html===false || $html=='file_error') return false; preg_match('#]*)" />#', $html, $matches); $video['title'] = $matches[1]; preg_match('#]*)" />#s', $html, $matches); $video['description'] = $matches[1]; preg_match('#]+)" />#', $html, $matches); $video['thumbnail'] = $matches[1]; preg_match('#
  • Auteur : ]*)>(.*?)#', $html, $matches); $video['author'] = $matches[1]; preg_match('#]+)" />#', $html, $matches); $video['tags'] = $matches[1]; } break; } default: return false; } return $video; } /** * @params: * $video (from parse_video_url) * $config : * - category, integer * - add_film_frame, boolean * - sync_description, boolean * - sync_tags, boolean * - with, integer * - height, integer * - autoplay, integer (0-1) */ function add_video($video, $config) { global $page, $conf; $query = ' SELECT picture_id FROM '.GVIDEO_TABLE.' WHERE type = "'.$video['type'].'" AND video_id = "'.$video['video_id'].'" ;'; $result = pwg_query($query); if (pwg_db_num_rows($result)) { $page['warnings'][] = l10n('This video was already registered'); list($image_id) = pwg_db_fetch_row($result); return $image_id; } include_once(PHPWG_ROOT_PATH . 'admin/include/functions_upload.inc.php'); // download thumbnail $thumb_ext = empty($video['thumbnail']) ? 'jpg' : get_extension($video['thumbnail']); $thumb_name = $video['type'].'-'.$video['video_id'].'-'.uniqid().'.'.$thumb_ext; $thumb_source = $conf['data_location'].$thumb_name; if (empty($video['thumbnail']) or gvideo_download_remote_file($video['thumbnail'], $thumb_source) !== true) { $thumb_source = $conf['data_location'].get_filename_wo_extension($thumb_name).'.jpg'; copy(GVIDEO_PATH.'mimetypes/'.$video['type'].'.jpg', $thumb_source); } if ($config['add_film_frame']) { add_film_frame($thumb_source); } // add image and update infos $image_id = add_uploaded_file($thumb_source, $thumb_name, array($config['category'])); $updates = array( 'name' => pwg_db_real_escape_string($video['title']), 'author' => pwg_db_real_escape_string($video['author']), 'is_gvideo' => 1, ); if ($config['sync_description'] and !empty($video['description'])) { $updates['comment'] = pwg_db_real_escape_string($video['description']); } if ($config['sync_tags'] and !empty($video['tags'])) { $tags = pwg_db_real_escape_string($video['tags']); set_tags(get_tag_ids($tags), $image_id); } single_update( IMAGES_TABLE, $updates, array('id' => $image_id), true ); // register video if (!preg_match('#^([0-9]*)$#', $config['width']) or !preg_match('#^([0-9]*)$#', $config['height'])) { $config['width'] = $config['height'] = ''; } if ($config['autoplay']!='0' and $config['autoplay']!='1') { $config['autoplay'] = ''; } $insert = array( 'picture_id' => $image_id, 'url' => $video['url'], 'type' => $video['type'], 'video_id' => $video['video_id'], 'width' => $config['width'], 'height' => $config['height'], 'autoplay' => $config['autoplay'], ); single_insert( GVIDEO_TABLE, $insert ); return $image_id; } /** * test if a download method is available * @return: bool */ if (!function_exists('test_remote_download')) { function test_remote_download() { return function_exists('curl_init') || ini_get('allow_url_fopen'); } } /** * download a remote file * - needs cURL or allow_url_fopen * - take care of SSL urls * * @param: string source url * @param: mixed destination file (if true, file content is returned) */ function gvideo_download_remote_file($src, $dest, $headers=array()) { if (empty($src)) { return false; } $return = ($dest === true) ? true : false; $headers[] = 'Accept-language: en'; /* curl */ if (function_exists('curl_init')) { if (!$return) { $newf = fopen($dest, "wb"); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $src); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'); curl_setopt($ch, CURLOPT_TIMEOUT, 30); if (!ini_get('safe_mode')) { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 1); } if (strpos($src, 'https://') !== false) { curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); } if (!$return) { curl_setopt($ch, CURLOPT_FILE, $newf); } else { curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); } $out = curl_exec($ch); curl_close($ch); if ($out === false) { return 'file_error'; } else if (!$return) { fclose($newf); return true; } else { return $out; } } /* file get content */ else if (ini_get('allow_url_fopen')) { if (strpos($src, 'https://') !== false and !extension_loaded('openssl')) { return false; } $opts = array( 'http' => array( 'method' => "GET", 'user_agent' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 'header' => implode("\r\n", $headers), ) ); $context = stream_context_create($opts); if (($file = file_get_contents($src, false, $context)) === false) { return 'file_error'; } if (!$return) { file_put_contents($dest, $file); return true; } else { return $file; } } return false; } /** * and film frame to an image (need GD library) * @param: string source * @param: string destination (if null, the source is modified) * @return: void */ function add_film_frame($src, $dest=null) { if (empty($dest)) { $dest = $src; } // we need gd library if (!function_exists('imagecreatetruecolor')) { if ($dest != $src) copy($src, $dest); return; } // open source image switch (strtolower(get_extension($src))) { case 'jpg': case 'jpeg': $srcImage = imagecreatefromjpeg($src); break; case 'png': $srcImage = imagecreatefrompng($src); break; case 'gif': $srcImage = imagecreatefromgif($src); break; default: if ($dest != $src) copy($src, $dest); return; } // source properties $srcWidth = imagesx($srcImage); $srcHeight = imagesy($srcImage); $const = intval($srcWidth * 0.04); $bandRadius = floor($const/8); // band properties $imgBand = imagecreatetruecolor($srcWidth + 6*$const, $srcHeight + 3*$const); $black = imagecolorallocate($imgBand, 0, 0, 0); $white = imagecolorallocate($imgBand, 245, 245, 245); // and dots $y_start = intval(($srcHeight + 3*$const) / 2); $aug = intval($y_start / 5) + 1; $i = 0; while ($y_start + $i*$aug < $srcHeight + 3*$const) { imagefilledroundrectangle($imgBand, (3/4)*$const, $y_start + $i*$aug - $const/2, (9/4)*$const - 1, $y_start + $i*$aug + $const/2 - 1, $white, $bandRadius); imagefilledroundrectangle($imgBand, (3/4)*$const, $y_start - $i*$aug - $const/2, (9/4)*$const - 1, $y_start - $i*$aug + $const/2 - 1, $white, $bandRadius); 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); 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); ++$i; } // add source to band imagecopy($imgBand, $srcImage, 3*$const, (3/2)*$const, 0, 0, $srcWidth, $srcHeight); // save image switch (strtolower(get_extension($dest))) { case 'jpg': case 'jpeg': imagejpeg($imgBand, $dest, 85); break; case 'png': imagepng($imgBand, $dest); break; case 'gif': imagegif($imgBand, $dest); break; } } /** * create a rectangle with round corners * http://www.php.net/manual/fr/function.imagefilledrectangle.php#42815 */ function imagefilledroundrectangle(&$img, $x1, $y1, $x2, $y2, $color, $radius) { imagefilledrectangle($img, $x1+$radius, $y1, $x2-$radius, $y2, $color); if ($radius > 0) { imagefilledrectangle($img, $x1, $y1+$radius, $x2, $y2-$radius, $color); imagefilledellipse($img, $x1+$radius, $y1+$radius, $radius*2, $radius*2, $color); imagefilledellipse($img, $x2-$radius, $y1+$radius, $radius*2, $radius*2, $color); imagefilledellipse($img, $x1+$radius, $y2-$radius, $radius*2, $radius*2, $color); imagefilledellipse($img, $x2-$radius, $y2-$radius, $radius*2, $radius*2, $color); } }