e107_core/bbcodes/bb_youtube.php
<?php
/**
* Copyright (C) e107 Inc (e107.org), Licensed under GNU GPL (http://www.gnu.org/licenses/gpl.txt)
*
* YouTube BBcode
*/
if (!defined('e107_INIT')) { exit; }
/**
* Youtube handling
*
* [youtube=tiny|small|medium|large|huge or width,height]ID{&query options}[/youtube]
*
* examples:
* [youtube=560,340]N2wivHYCRho?hd=1&color1=&color2=&cc_load_policy=0&autoplay=0[/youtube]
* [youtube=big|privacy]N2wivHYCRho?hd=1&hl=en[/youtube]
*
* Will also convert Youtube embed code, and youtube 'watch' urls. (http://www.youtube.com/watch?v=)
* Youtube ID is the only required data!
* TODO - use swfobject JS - XHTML validation
*/
/**
* Class-based bbcode validation
*
* Class name must be 'bb_'.bbname - where bbname is the name of the bbcode. (Note some bbcodes begin '_', and this is retained)
*
* This class must contain exactly two public methods:
* toDB($code_text, $parm) - called prior to text being saved
* toHTML($code_text, $parm) - called prior to text being displayed
*/
class bb_youtube extends e_bb_base
{
/**
* Called prior to save
*
* If user has posted the complete youtube 'copy and paste' text between the tags, parse it and generate the relevant bbcode
*/
function toDB($code_text, $parm)
{
$bbpars = array();
$widthString = '';
$parm = trim($parm);
// Convert Simple URLs.
if(strpos($code_text,"youtube.com/watch?v=")!==FALSE || strpos($code_text,"youtube.com/watch#!v=")!==FALSE )
{
$validUrls = array("http://", "https://", "www.","youtube.com/watch?v=","youtube.com/watch#!v=");
$tmp = str_replace($validUrls,'',$code_text);
$qrs = explode("&",$tmp);
$code_text = $qrs[0];
unset($qrs);
}
if ($parm)
{
if (strpos($parm, '|') !== FALSE)
{
list($widthString, $parm) = explode('|', $parm);
}
elseif (in_array($parm, array('tiny', 'small', 'medium','large', 'big', 'huge')) || (strpos($parm, ',') !== FALSE))
{ // Assume we're just setting a width
$widthString = $parm;
$parm = '';
}
if ($parm)
{
$bbpars = explode('&', $parm);
}
}
/*
echo '<br />Parm= '.$parm;
echo "<br />COde= ".htmlspecialchars($code_text);
echo "<br />Width= ".$widthString;
*/
$params = array(); // Accumulator for parameters from youtube code
$ok = 0;
if (strpos($code_text, '<') === FALSE)
{ // 'Properly defined' bbcode (we hope)
$picRef = $code_text;
}
else
{
//libxml_use_internal_errors(TRUE);
if (FALSE === ($info = simplexml_load_string($code_text)))
{
//print_a($matches);
//$xmlErrs = libxml_get_errors();
//print_a($xmlErrs);
$ok = 1;
}
else
{
$info1 = (array)$info;
if (!isset($info1['embed']))
{
$ok = 2;
}
else
{
$info2 = (array)$info1['embed'];
if (!isset($info2['@attributes']))
{
$ok = 3;
}
}
}
if ($ok != 0)
{
print_a($info);
return '[sanitised]'.$ok.'B'.htmlspecialchars($matches[0]).'B[/sanitised]';
}
$target = (array)$info2['@attributes'];
unset($info);
$ws = varset($target['width'], 0);
$hs = varset($target['height'], 0);
if (($ws == 0) || ($hs == 0) || !isset($target['src'])) return '[sanitised]A'.htmlspecialchars($matches[0]).'A[/sanitised]';
if (!$widthString)
{
$widthString = $ws.','.$hs; // Set size of window
}
list($url, $query) = explode('?', $target['src']);
if (strpos($url, 'youtube-nocookie.com') !== FALSE)
{
$bb_params[] = 'privacy';
}
parse_str($query, $vals); // Various options set here
if (varset($vals['allowfullscreen'], 'true') != 'true')
{
$params[] = 'fs=0';
}
if (varset($vals['border'], 0) != 0)
{
$params[] = 'border=1';
}
if (varset($vals['rel'], 1) != 1)
{
$params[] = 'rel='.intval($vals['rel']);
}
if (varset($vals['hd'], 1) != 0)
{
$params[] = 'hd='.intval($vals['hd']);
}
if (varset($vals['hl'], 1) != 0)
{
$params[] = 'hl='.$vals['hl'];
}
if (varset($vals['color1'], 1) != 0)
{
$params[] = 'color1='.$vals['color1'];
}
if (varset($vals['color2'], 1) != 0)
{
$params[] = 'color2='.$vals['color2'];
}
if (varset($vals['cc_load_policy'], 1) != 0)
{
$params[] = 'cc_load_policy='.intval($vals['cc_load_policy']);
}
if (ADMIN && varset($vals['autoplay'], 1) != 0)
{
$params[] = 'autoplay='.intval($vals['autoplay']);
}
$picRef = substr($url, strrpos($url, '/') + 1);
}
$yID = preg_replace('/[^0-9a-z]/i', '', $picRef);
//if (($yID != $picRef) || (strlen($yID) > 20))
// { // Possible hack attempt
// }
// $params = array_merge($params, $bbpars); // Any parameters set in bbcode override those in HTML
// Could check for valid array indices here
$paramString = implode('&', $params);
if ($paramString) $picRef .= '?'.$paramString;
if($widthString)
{
$widthString = "=".$widthString;
if(count($bbpars))
{
$widthString .= "|".implode("&",$bbpars);
}
}
$ans = '[youtube'.$widthString.']'.$picRef.'[/youtube]';
return $ans;
}
/**
* Translate youtube bbcode into the appropriate <EMBED> object
*/
function toHTML($code_text, $parm)
{
if(empty($code_text)) return '';
$t = explode('|', $parm, 2);
$dimensions = varset($t[0]);
$tmp = varset($t[1]);
if($tmp)
{
parse_str(varset($tmp, ''), $bbparm);
}
if(strpos($code_text,"&")!==FALSE && strpos($code_text,"?")===FALSE) // DEPRECATED
{
$parms = explode('&', $code_text, 2);
}
else
{
$parms = explode('?', $code_text, 2); // CORRECT SEPARATOR
}
$code_text = $parms[0];
parse_str(varset($parms[1], ''), $params);
// print_a($params);
if(empty($dimensions)) $dimensions = 'medium'; // (default as per YouTube spec)
// formula: width x (height+25px)
switch ($dimensions)
{
case 'tiny':
$params['w'] = 320; // 200;
$params['h'] = 205; // 180;
break;
case 'small':
$params['w'] = 560; // 445;
$params['h'] = 340; // 364;
break;
case 'medium':
$params['w'] = 640; // 500;
$params['h'] = 385; // 405;
break;
case 'big':
case 'large':
$params['w'] = 853; // 660;
$params['h'] = 505; // 525;
break;
case 'huge':
$params['w'] = 1280; // 980;
$params['h'] = 745; // 765;
break;
default: // maximum 1920 x 1080 (+25)
$dim = explode(',', $dimensions, 2);
$params['w'] = (integer) varset($dim[0], 445);
if($params['w'] > 1920 || $params['w'] < 100) $params['w'] = 640;
$params['h'] = (integer) varset($dim[1], 364);
if($params['h'] > 1105 || $params['h'] < 67) $params['h'] = 385;
break;
}
$yID = preg_replace('/[^0-9a-z\-_\&\?]/i', '', $code_text);
$url = isset($bbparm['privacy']) ? 'https://www.youtube-nocookie.com/v/' : 'https://www.youtube.com/v/';
$url .= $yID.'?';
if(isset($params['nofull']) || !varset($params['fs']))
{
$fscr = 'false';
$url = $url.'fs='.intval($params['fs']);
}
else
{
$fscr = 'true';
$url = $url.'fs=1';
}
if(isset($params['border'])) $url = $url.'&border='.intval($params['border']);
if(isset($params['norel'])) // BC non-standard val.
{
$url = $url.'&rel=0';
}
elseif(isset($params['rel']))
{
$url = $url.'&rel='.intval($params['rel']);
}
if(isset($params['hd'])) $url = $url.'&hd='.intval($params['hd']);
$hl = 'en_US';
if(isset($params['hl']))
{
$params['hl'] = preg_replace('/[^0-9a-z\-_]/i', '', $params['hl']);
if(strlen($params['hl']) == 2 || strlen($params['hl']) == 5)
{
$hl = $params['hl'];
}
}
$url = $url.'&hl='.$hl;
$color = array();
if(isset($params['color1'])) $color[1] = $params['color1'];
if(isset($params['color2'])) $color[2] = $params['color2'];
foreach ($color as $key => $value)
{
if (ctype_xdigit($value) && strlen($value) == 6)
{
$url = $url.'&color'.$key.'='.$value;
}
}
if(isset($params['cc_load_policy']))
{
$url .= "&cc_load_policy=".intval($params['cc_load_policy']);
}
if(isset($params['autoplay']))
{
$url .= "&autoplay=".intval($params['autoplay']);
}
$class = "bbcode ".e107::getBB()->getClass('youtube'); // consistent classes across all themes.
$ret = "<!-- Start YouTube-".$dimensions."-".$yID." -->\n"; // <-- DO NOT MODIFY - used for detection by bbcode handler.
if(e107::getConfig()->get('youtube_bbcode_responsive') == 1) // Responsive Mode.
{
$ret .= e107::getParser()->toVideo($yID.".youtube");
}
else // Legacy Mode.
{
$ret .= '<object class="'.$class.'" width="'.$params['w'].'" height="'.$params['h'].'" >
<param name="movie" value="'.$url.'" />
<param name="allowFullScreen" value="'.$fscr.'" />
<param name="allowscriptaccess" value="always" />
<param name="wmode" value="transparent" />
';
// Not XHTML - but needed for compatibility.
$ret .= '<embed class="'.$class.'" src="'.$url.'" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="'.$fscr.'" wmode="transparent" width="'.$params['w'].'" height="'.$params['h'].'" />';
$ret .= '</object>';
}
$ret .= "<!-- End YouTube -->"; // <-- DO NOT MODIFY.
return $ret;
}
// Wysiwyg representation of bbcode render.
function toWYSIWYG($code_text,$parm)
{
//eg. an image of the video thumbnail
}
}
?>