| Current File : /home/jvzmxxx/wiki1/extensions/EmbedVideo/EmbedVideo.hooks.php |
<?php
/**
* EmbedVideo
* EmbedVideo Hooks
*
* @license MIT
* @package EmbedVideo
* @link https://www.mediawiki.org/wiki/Extension:EmbedVideo
*
**/
class EmbedVideoHooks {
/**
* Temporary storage for the current service object.
*
* @var object
*/
static private $service;
/**
* Description Parameter
*
* @var string
*/
static private $description = false;
/**
* Alignment Parameter
*
* @var string
*/
static private $alignment = false;
/**
* Alignment Parameter
*
* @var string
*/
static private $vAlignment = false;
/**
* Container Parameter
*
* @var string
*/
static private $container = false;
/**
* Valid Arguments for the parseEV function hook.
*
* @var string
*/
static private $validArguments = [
'service' => null,
'id' => null,
'dimensions' => null,
'alignment' => null,
'description' => null,
'container' => null,
'urlargs' => null,
'autoresize' => null,
'valignment' => null
];
/**
* Hook to setup defaults.
*
* @access public
* @return void
*/
public static function onExtension() {
global $wgEmbedVideoDefaultWidth, $wgMediaHandlers, $wgFileExtensions;
$config = ConfigFactory::getDefaultInstance()->makeConfig('main');
if (!isset($wgEmbedVideoDefaultWidth) && (isset($_SERVER['HTTP_X_MOBILE']) && $_SERVER['HTTP_X_MOBILE'] == 'true') && $_COOKIE['stopMobileRedirect'] != 1) {
//Set a smaller default width when in mobile view.
$wgEmbedVideoDefaultWidth = 320;
}
if ($config->get('EmbedVideoEnableAudioHandler')) {
$wgMediaHandlers['application/ogg'] = 'EmbedVideo\AudioHandler';
$wgMediaHandlers['audio/flac'] = 'EmbedVideo\AudioHandler';
$wgMediaHandlers['audio/ogg'] = 'EmbedVideo\AudioHandler';
$wgMediaHandlers['audio/mpeg'] = 'EmbedVideo\AudioHandler';
$wgMediaHandlers['audio/mp4'] = 'EmbedVideo\AudioHandler';
$wgMediaHandlers['audio/wav'] = 'EmbedVideo\AudioHandler';
$wgMediaHandlers['audio/webm'] = 'EmbedVideo\AudioHandler';
$wgMediaHandlers['audio/x-flac'] = 'EmbedVideo\AudioHandler';
}
if ($config->get('EmbedVideoEnableVideoHandler')) {
$wgMediaHandlers['video/mp4'] = 'EmbedVideo\VideoHandler';
$wgMediaHandlers['video/ogg'] = 'EmbedVideo\VideoHandler';
$wgMediaHandlers['video/quicktime'] = 'EmbedVideo\VideoHandler';
$wgMediaHandlers['video/webm'] = 'EmbedVideo\VideoHandler';
$wgMediaHandlers['video/x-matroska'] = 'EmbedVideo\VideoHandler';
}
if ($config->get('EmbedVideoAddFileExtensions')) {
$wgFileExtensions[] = 'flac';
$wgFileExtensions[] = 'mkv';
$wgFileExtensions[] = 'mov';
$wgFileExtensions[] = 'mp3';
$wgFileExtensions[] = 'mp4';
$wgFileExtensions[] = 'oga';
$wgFileExtensions[] = 'ogg';
$wgFileExtensions[] = 'ogv';
$wgFileExtensions[] = 'wav';
$wgFileExtensions[] = 'webm';
}
}
/**
* Sets up this extension's parser functions.
*
* @access public
* @param object Parser object passed as a reference.
* @return boolean true
*/
static public function onParserFirstCallInit( Parser &$parser ) {
$parser->setFunctionHook( "ev", "EmbedVideoHooks::parseEV" );
$parser->setFunctionHook( "evt", "EmbedVideoHooks::parseEVT" );
$parser->setFunctionHook( "evp", "EmbedVideoHooks::parseEVP" );
$parser->setFunctionHook( "evu", "EmbedVideoHooks::parseEVU" );
$parser->setHook( "embedvideo", "EmbedVideoHooks::parseEVTag" );
$parser->setHook('evlplayer', "EmbedVideoHooks::parseEVLPlayer");
$parser->setFunctionHook( 'evl', "EmbedVideoHooks::parseEVL");
// don't step on VideoLink's toes.
if (!class_exists('FXVideoLink')) {
$parser->setHook('vplayer', "EmbedVideoHooks::parseEVLPlayer");
$parser->setFunctionHook( 'vlink', "EmbedVideoHooks::parseEVL");
}
// smart handling of service name tags (if they aren't already implamented)
$tags = $parser->getTags();
$services = \EmbedVideo\VideoService::getAvailableServices();
$create = array_diff( $services, $tags );
// We now have a list of services we can create tags for that aren't already implamented
foreach ($create as $service) {
$parser->setHook( $service, "EmbedVideoHooks::parseServiceTag{$service}" );
}
return true;
}
/**
* Handle passing parseServiceTagSERVICENAME to the parseServiceTag method.
*
* @param string $name
* @param array $args
* @return void
*/
public static function __callStatic( $name, $args ) {
if ( substr($name, 0, 15) == "parseServiceTag" ) {
$service = str_replace( "parseServiceTag", "", $name );
return self::parseServiceTag( $service, $args[0], $args[1], $args[2], $args[3] );
}
}
/**
* Parse tag with service name
*
* @access public
* @param string Raw User Input
* @param array Arguments on the tag.
* @param object Parser object.
* @param object PPFrame object.
* @return string Error Message
*/
static public function parseServiceTag( $service, $input, array $args, Parser $parser, PPFrame $frame ) {
$args = array_merge( self::$validArguments, $args );
// accept input as default, but also allow url param.
if (empty($input) && isset($args['url'])) {
$input = $args['url'];
}
return self::parseEV(
$parser,
$service,
$input,
$args['dimensions'],
$args['alignment'],
$args['description'],
$args['container'],
$args['urlargs'],
$args['autoresize'],
$args['valignment']
);
}
/**
* Parse EVL (and vlink) Tags
* @param Parser $parser
* @return array
*/
static public function parseEVL( Parser &$parser ) {
$args = func_get_args();
array_shift( $args );
// standardise first 2 arguments into strings that parse_str can handle.
$args[0] = "id=".$args[0];
$args[1] = "linktitle=".$args[1];
$options = [];
parse_str( implode( "&", $args ), $options );
// default service to youtube for compatibility with vlink
$options['service'] = isset( $options['service'] ) ? $options['service'] : "youtube";
$options = array_merge( self::$validArguments, $options );
// fix for youtube ids that VideoLink would have handled.
if ($options['service'] == 'youtube' && strpos($options['id'], ';') !== false) {
// transform input like Oh8KRy2WV0o;C5rePhJktn0 into Oh8KRy2WV0o
$options['notice'] = "Use of simi-colon delimited video lists is depricated. Only the first video in this list will play.";
$options['id'] = strstr($options['id'], ';', true);
}
// force start time on youtube videos from "start".
if ($options['service'] == 'youtube' && isset($options['start']) && preg_match('/^([0-9]+:){0,2}[0-9]+(?:\.[0-9]+)?$/', $options['start'])) {
$te = explode(':', $options['start']);
$tc = count($te);
for($i=1, $startTime = floatval($te[0]); $i<$tc; $i++) {
$startTime = $startTime*60 + floatval($te[$i]);
}
if (!isset($options['urlargs']) || empty($options['urlargs'])) {
// just set the url args to the start time string
$options['urlargs'] = "start={$startTime}";
} else {
// break down the url args and inject the start time in.
$urlargs = [];
parse_str($options['urlargs'], $urlargs);
$urlargs['start'] = $startTime;
$options['urlargs'] = http_build_query($urlargs);
}
}
$json = json_encode($options);
$link = Xml::element('a', [
'href' => '#',
'data-video-json' => $json,
'class' => 'embedvideo-evl vplink'
], $options['linktitle']);
$parser->getOutput()->addModules( ['ext.embedVideo-evl', 'ext.embedVideo.styles'] );
return [ $link, 'noparse' => true, 'isHTML' => true ];
}
/**
* Parse EVLPlayer (and vplayer) Tags
* @param string $input
* @param array $args
* @param Parser $parser
* @param PPFrame $frame
* @return array
*/
static public function parseEVLPlayer($input, array $args, Parser $parser, PPFrame $frame ) {
$args = array_merge( self::$validArguments, $args );
$pid = isset($args['id']) ? $args['id'] : 'default';
$w = min(2000, max(240, isset($args['w']) ? (int)$args['w'] : 800));
$h = min(1200, max(80, isset($args['h']) ? (int)$args['h'] : (9*$w/16)));
$style = isset($args['style']) ? ' '.$args['style'] : '';
$class = isset($args['class']) ? ' '.$args['class'] : '';
$div = Html::element('div', array(
'id' => 'vplayerbox-'.$pid,
'class' => 'embedvideo-evlbox vplayerbox'.$class,
'data-size' => $w.'x'.$h,
'style' => $style,
), $input);
return [ $div, 'noParse'=> true, 'isHTML'=> 'true' ];
}
/**
* Embeds a video based on the URL
*
* @access public
* @param object Parser
* @return string Error Message
*/
static public function parseEVU( $parser, $url = null ) {
if ( !$url ) {
return self::error( 'missingparams', $url );
}
$host = parse_url( $url, PHP_URL_HOST );
$host = strtolower($host);
$host = str_ireplace('www.', '', $host); // strip www from any hostname.
$map = \EmbedVideo\VideoService::getServiceHostMap();
$service = false;
if (isset($map[$host])) {
if (!is_array($map[$host])) {
// only one possible anser. Set it.
$service = $map[$host];
} else {
// map by array.
foreach ($map[$host] as $possibleService) {
$evs = \EmbedVideo\VideoService::newFromName($possibleService);
if ($evs) {
$test = $evs->parseVideoID($url);
if ($test !== false && $test !== $url) {
// sucessful parse - safe assumption that this is correct.
$service = $possibleService;
break;
}
}
}
}
} else {
return self::error( 'cantdecode_evu', $url );
}
if (!$service) {
return self::error( 'cantdecode_evu', $url );
}
$arguments = func_get_args();
array_shift( $arguments );
$args = [];
foreach ( $arguments as $argumentPair ) {
$argumentPair = trim( $argumentPair );
if ( !strpos( $argumentPair, '=' ) ) {
continue;
}
list( $key, $value ) = explode( '=', $argumentPair, 2 );
if (!array_key_exists($key, self::$validArguments)) {
continue;
}
$args[$key] = $value;
}
$args = array_merge( self::$validArguments, $args );
return self::parseEV(
$parser,
$service,
$url,
$args['dimensions'],
$args['alignment'],
$args['description'],
$args['container'],
$args['urlargs'],
$args['autoresize'],
$args['valignment']
);
}
/**
* Adapter to call the new style tag.
*
* @access public
* @param object Parser
* @return string Error Message
*/
static public function parseEVP( $parser ) {
wfDeprecated( __METHOD__, '2.0', 'EmbedVideo' );
return self::error( 'evp_deprecated' );
}
/**
* Adapter to call the EV parser tag with template like calls.
*
* @access public
* @param object Parser
* @return string Error Message
*/
static public function parseEVT( $parser ) {
$arguments = func_get_args();
array_shift( $arguments );
foreach ( $arguments as $argumentPair ) {
$argumentPair = trim( $argumentPair );
if ( !strpos( $argumentPair, '=' ) ) {
continue;
}
list( $key, $value ) = explode( '=', $argumentPair, 2 );
if (!array_key_exists($key, self::$validArguments)) {
continue;
}
$args[$key] = $value;
}
$args = array_merge( self::$validArguments, $args );
return self::parseEV(
$parser,
$args['service'],
$args['id'],
$args['dimensions'],
$args['alignment'],
$args['description'],
$args['container'],
$args['urlargs'],
$args['autoresize'],
$args['valignment']
);
}
/**
* Adapter to call the parser hook.
*
* @access public
* @param string Raw User Input
* @param array Arguments on the tag.
* @param object Parser object.
* @param object PPFrame object.
* @return string Error Message
*/
static public function parseEVTag( $input, array $args, Parser $parser, PPFrame $frame ) {
$args = array_merge( self::$validArguments, $args );
return self::parseEV(
$parser,
$args['service'],
$input,
$args['dimensions'],
$args['alignment'],
$args['description'],
$args['container'],
$args['urlargs'],
$args['autoresize'],
$args['valignment']
);
}
/**
* Embeds a video of the chosen service.
*
* @access public
* @param object Parser
* @param string [Optional] Which online service has the video.
* @param string [Optional] Identifier Code or URL for the video on the service.
* @param string [Optional] Dimensions of video
* @param string [Optional] Description to show
* @param string [Optional] Horizontal Alignment of the embed container.
* @param string [Optional] Container to use.(Frame is currently the only option.)
* @param string [Optional] Extra URL Arguments
* @param string [Optional] Automatically Resize video that will break its parent container.
* @param string [Optional] Vertical Alignment of the embed container.
* @return string Encoded representation of input params (to be processed later)
*/
static public function parseEV( $parser, $service = null, $id = null, $dimensions = null, $alignment = null, $description = null, $container = null, $urlArgs = null, $autoResize = null, $vAlignment = null ) {
self::resetParameters();
$service = trim( $service );
$id = trim( $id );
$alignment = trim( $alignment );
$description = trim( $description );
$dimensions = trim( $dimensions );
$urlArgs = trim( $urlArgs );
$width = null;
$height = null;
$autoResize = ( isset( $autoResize ) && strtolower( trim( $autoResize ) ) == "false" ) ? false : true;
$vAlignment = trim( $vAlignment );
// I am not using $parser->parseWidthParam() since it can not handle height only. Example: x100
if ( stristr( $dimensions, 'x' ) ) {
$dimensions = strtolower( $dimensions );
list( $width, $height ) = explode( 'x', $dimensions );
} elseif ( is_numeric( $dimensions ) ) {
$width = $dimensions;
}
/************************************/
/* Error Checking */
/************************************/
if ( !$service || !$id ) {
return self::error( 'missingparams', $service, $id );
}
self::$service = \EmbedVideo\VideoService::newFromName( $service );
if ( !self::$service ) {
return self::error( 'service', $service );
}
// Let the service automatically handle bad dimensional values.
self::$service->setWidth( $width );
self::$service->setHeight( $height );
// If the service has an ID pattern specified, verify the id number.
if ( !self::$service->setVideoID( $id ) ) {
return self::error( 'id', $service, $id );
}
if ( !self::$service->setUrlArgs( $urlArgs ) ) {
return self::error( 'urlargs', $service, $urlArgs );
}
if (!is_null($parser)) {
self::setDescription( $description, $parser );
} else {
self::setDescriptionNoParse( $description );
}
if ( !self::setContainer( $container ) ) {
return self::error( 'container', $container );
}
if ( !self::setAlignment( $alignment ) ) {
return self::error( 'alignment', $alignment );
}
if ( !self::setVerticalAlignment( $vAlignment ) ) {
return self::error( 'valignment', $vAlignment );
}
/************************************/
/* HMTL Generation */
/************************************/
$html = self::$service->getHtml();
if ( !$html ) {
return self::error( 'unknown', $service );
}
if ($autoResize) {
$html = self::generateWrapperHTML( $html, null, "autoResize" );
} else {
$html = self::generateWrapperHTML( $html );
}
if ($parser) {
// dont call this if parser is null (such as in API usage).
$out = $parser->getOutput();
$out->addModules( 'ext.embedVideo' );
$out->addModuleStyles( 'ext.embedVideo.styles' );
}
return [
$html,
'noparse' => true,
'isHTML' => true
];
}
/**
* Generate the HTML necessary to embed the video with the given alignment
* and text description
*
* @access private
* @param string [Optional] Horizontal Alignment
* @param string [Optional] Description
* @param string [Optional] Additional Classes to add to the wrapper
* @return string
*/
static private function generateWrapperHTML( $html, $description = null, $addClass = null ) {
$classString = "embedvideo";
$styleString = "";
$innerClassString = "embedvideowrap";
if ( self::getContainer() == 'frame' ) {
$classString .= " thumb";
$innerClassString .= " thumbinner";
}
if (self::getAlignment() !== false) {
$classString .= " ev_" . self::getAlignment();
$styleString .= " width: " . ( self::$service->getWidth() + 6 ) . "px;";
}
if (self::getVerticalAlignment() !== false) {
$classString .= " ev_" . self::getVerticalAlignment();
}
if ($addClass) {
$classString .= " " . $addClass;
}
$html = "<div class='" . $classString . "' style='" . $styleString . "'><div class='" . $innerClassString . "' style='width: " . self::$service->getWidth() . "px;'>{$html}" . ( self::getDescription() !== false ? "<div class='thumbcaption'>" . self::getDescription() . "</div>" : null ) . "</div></div>";
return $html;
}
/**
* Return the alignment parameter.
*
* @access public
* @return mixed Alignment or false for not set.
*/
static private function getAlignment() {
return self::$alignment;
}
/**
* Set the align parameter.
*
* @access private
* @param string Alignment Parameter
* @return boolean Valid
*/
static private function setAlignment( $alignment ) {
if ( !empty( $alignment ) && ( $alignment == 'left' || $alignment == 'right' || $alignment == 'center' || $alignment == 'inline' ) ) {
self::$alignment = $alignment;
} elseif ( !empty( $alignment ) ) {
return false;
}
return true;
}
/**
* Return the valignment parameter.
*
* @access public
* @return mixed Vertical Alignment or false for not set.
*/
static private function getVerticalAlignment() {
return self::$vAlignment;
}
/**
* Set the align parameter.
*
* @access private
* @param string Alignment Parameter
* @return boolean Valid
*/
static private function setVerticalAlignment( $vAlignment ) {
if ( !empty( $vAlignment ) && ( $vAlignment == 'top' || $vAlignment == 'middle' || $vAlignment == 'bottom' || $vAlignment == 'baseline' ) ) {
if ($vAlignment != 'baseline') {
self::$alignment = 'inline';
}
self::$vAlignment = $vAlignment;
} elseif ( !empty( $vAlignment ) ) {
return false;
}
return true;
}
/**
* Return description text.
*
* @access private
* @return mixed String description or false for not set.
*/
static private function getDescription() {
return self::$description;
}
/**
* Set the description.
*
* @access private
* @param string Description
* @param object Mediawiki Parser object
* @return void
*/
static private function setDescription( $description, \Parser $parser ) {
self::$description = ( !$description ? false : $parser->recursiveTagParse( $description ) );
}
/**
* Set the description without using the parser
* @param string Description
*/
static private function setDescriptionNoParse( $description ) {
self::$description = ( !$description ? false : $description );
}
/**
* Return container type.
*
* @access private
* @return mixed String container type or false for not set.
*/
static private function getContainer() {
return self::$container;
}
/**
* Set the container type.
*
* @access private
* @param string Container
* @return boolean Success
*/
static private function setContainer( $container ) {
if ( !empty( $container ) && ( $container == 'frame' ) ) {
self::$container = $container;
} elseif ( !empty( $container ) ) {
return false;
}
return true;
}
/**
* Reset parameters between parses.
*
* @access private
* @return void
*/
static private function resetParameters() {
self::$description = false;
self::$alignment = false;
self::$container = false;
}
/**
* Error Handler
*
* @access private
* @param string [Optional] Error Type
* @param mixed [...] Multiple arguments to be retrieved with func_get_args().
* @return string Printable Error Message
*/
static private function error( $type = 'unknown' ) {
$arguments = func_get_args();
array_shift( $arguments );
$message = wfMessage( 'error_embedvideo_' . $type, $arguments )->escaped();
return [
"<div class='errorbox'>{$message}</div>",
'noparse' => true,
'isHTML' => true
];
}
}