r99245 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r99244‎ | r99245 | r99246 >
Date:20:06, 7 October 2011
Author:ashley
Status:deferred (Comments)
Tags:
Comment:
Video, *the* Video extension. Some things haven't yet been implemented, see my wikitech-l post for details.
Modified paths:
  • /trunk/extensions/Video (added) (history)
  • /trunk/extensions/Video/ReadMe (added) (history)
  • /trunk/extensions/Video/SpecialAddVideo.php (added) (history)
  • /trunk/extensions/Video/SpecialNewVideos.php (added) (history)
  • /trunk/extensions/Video/Video.alias.php (added) (history)
  • /trunk/extensions/Video/Video.css (added) (history)
  • /trunk/extensions/Video/Video.i18n.php (added) (history)
  • /trunk/extensions/Video/Video.namespaces.php (added) (history)
  • /trunk/extensions/Video/Video.php (added) (history)
  • /trunk/extensions/Video/VideoClass.php (added) (history)
  • /trunk/extensions/Video/VideoGallery.php (added) (history)
  • /trunk/extensions/Video/VideoGalleryPopulate.php (added) (history)
  • /trunk/extensions/Video/VideoHooks.php (added) (history)
  • /trunk/extensions/Video/VideoPage.php (added) (history)
  • /trunk/extensions/Video/VideoPageArchive.php (added) (history)
  • /trunk/extensions/Video/providers (added) (history)
  • /trunk/extensions/Video/providers/ArchiveOrgVideo.php (added) (history)
  • /trunk/extensions/Video/providers/BlipTVVideo.php (added) (history)
  • /trunk/extensions/Video/providers/DailyMotionVideo.php (added) (history)
  • /trunk/extensions/Video/providers/FlashVideo.php (added) (history)
  • /trunk/extensions/Video/providers/GametrailersVideo.php (added) (history)
  • /trunk/extensions/Video/providers/GamevideosVideo.php (added) (history)
  • /trunk/extensions/Video/providers/GoGreenTubeVideo.php (added) (history)
  • /trunk/extensions/Video/providers/GoogleVideo.php (added) (history)
  • /trunk/extensions/Video/providers/HuluVideo.php (added) (history)
  • /trunk/extensions/Video/providers/MetaCafeVideo.php (added) (history)
  • /trunk/extensions/Video/providers/MovieClipsVideo.php (added) (history)
  • /trunk/extensions/Video/providers/MySpaceVideo.php (added) (history)
  • /trunk/extensions/Video/providers/MyVideoVideo.php (added) (history)
  • /trunk/extensions/Video/providers/NewsRoomVideo.php (added) (history)
  • /trunk/extensions/Video/providers/SevenloadVideo.php (added) (history)
  • /trunk/extensions/Video/providers/SouthParkStudiosVideo.php (added) (history)
  • /trunk/extensions/Video/providers/ViddlerVideo.php (added) (history)
  • /trunk/extensions/Video/providers/VimeoVideo.php (added) (history)
  • /trunk/extensions/Video/providers/WeGameVideo.php (added) (history)
  • /trunk/extensions/Video/providers/YouTubeVideo.php (added) (history)
  • /trunk/extensions/Video/video.sql (added) (history)

Diff [purge]

Index: trunk/extensions/Video/VideoClass.php
@@ -0,0 +1,678 @@
 2+<?php
 3+
 4+class Video {
 5+
 6+ /**
 7+ * @var String: database key of the video
 8+ */
 9+ var $name;
 10+
 11+ /**
 12+ * @var Title: Title object associated with the current Video
 13+ */
 14+ var $title;
 15+
 16+ /**
 17+ * @var Boolean: does this video exist? True = exists, false = doesn't.
 18+ */
 19+ var $exists;
 20+
 21+ /**
 22+ * @var Integer: height of the video, is set to 400 in this class'
 23+ * constructor
 24+ */
 25+ var $height;
 26+
 27+ /**
 28+ * @var Integer: width of the video, is set to 400 in this class'
 29+ * constructor
 30+ */
 31+ var $width;
 32+
 33+ /**
 34+ * @var Integer: is set to 1 in this class' constructor. Provider classes
 35+ * should calculate this by diving width by height.
 36+ */
 37+ var $ratio;
 38+
 39+ /**
 40+ * @var String: URL to the video on the provider service
 41+ */
 42+ var $url;
 43+
 44+ /**
 45+ * @var String: username of the person who added the current video to the
 46+ * wiki
 47+ */
 48+ var $submitter_user_name;
 49+
 50+ /**
 51+ * @var Integer: user ID number of the person who added the current video
 52+ * to the wiki
 53+ */
 54+ var $submitter_user_id;
 55+
 56+ /**
 57+ * @var Integer: timestamp when this video was added to the wiki
 58+ */
 59+ var $create_date;
 60+
 61+ /**
 62+ * @var String: lowercase/internal name of the video provider service, such
 63+ * as 'youtube' or 'archiveorg'
 64+ */
 65+ var $type;
 66+
 67+ /**
 68+ * @var Boolean: has all the metadata been loaded into the cache?
 69+ */
 70+ var $dataLoaded;
 71+
 72+ /**
 73+ * Constructor -- create a new Video object from the given Title and set
 74+ * some member variables
 75+ *
 76+ * @param $title Object: Title object associated with the Video
 77+ */
 78+ public function __construct( $title ) {
 79+ if( !is_object( $title ) ) {
 80+ throw new MWException( 'Video constructor given bogus title.' );
 81+ }
 82+ $this->title =& $title;
 83+ $this->name = $title->getDBkey();
 84+ $this->height = 400;
 85+ $this->width = 400;
 86+ $this->ratio = 1;
 87+ $this->dataLoaded = false;
 88+ }
 89+
 90+ /**
 91+ * Create a Video object from a video name
 92+ *
 93+ * @param $name Mixed: name of the video, used to create a title object using Title::makeTitleSafe
 94+ */
 95+ public static function newFromName( $name ) {
 96+ $title = Title::makeTitleSafe( NS_VIDEO, $name );
 97+ if ( is_object( $title ) ) {
 98+ return new Video( $title );
 99+ } else {
 100+ return null;
 101+ }
 102+ }
 103+
 104+ /**
 105+ * Add the video into the database
 106+ *
 107+ * @param $url String: URL to the video on the provider service
 108+ * @param $type String: (internal) provider name in lowercase
 109+ * @param $categories String: pipe-separated list of categories
 110+ * @param $watch Boolean: add the new video page to the user's watchlist?
 111+ */
 112+ public function addVideo( $url, $type, $categories, $watch = '' ) {
 113+ global $wgUser, $wgContLang;
 114+
 115+ $dbw = wfGetDB( DB_MASTER );
 116+
 117+ $now = $dbw->timestamp();
 118+
 119+ $desc = wfMsgForContent(
 120+ 'video-log-added-entry',
 121+ Title::makeTitle( NS_VIDEO, $this->getName() )->getPrefixedText()
 122+ );
 123+ // Test to see if the row exists using INSERT IGNORE
 124+ // This avoids race conditions by locking the row until the commit, and also
 125+ // doesn't deadlock. SELECT FOR UPDATE causes a deadlock for every race condition.
 126+ $dbw->insert(
 127+ 'video',
 128+ array(
 129+ 'video_name' => $this->getName(),
 130+ 'video_url' => $url,
 131+ 'video_type' => $type,
 132+ 'video_user_id' => $wgUser->getID(),
 133+ 'video_user_name' => $wgUser->getName(),
 134+ 'video_timestamp' => $now
 135+ ),
 136+ __METHOD__,
 137+ 'IGNORE'
 138+ );
 139+
 140+ $categoryWikiText = '';
 141+
 142+ if( $dbw->affectedRows() == 0 ) {
 143+ $desc = wfMsgForContent(
 144+ 'video-log-updated-entry',
 145+ Title::makeTitle( NS_VIDEO, $this->getName() )->getPrefixedText()
 146+ );
 147+
 148+ // Clear cache
 149+ global $wgMemc;
 150+ $key = $this->getCacheKey();
 151+ $wgMemc->delete( $key );
 152+
 153+ // Collision, this is an update of a video
 154+ // Insert previous contents into oldvideo
 155+ $dbw->insertSelect(
 156+ 'oldvideo', 'video',
 157+ array(
 158+ 'ov_name' => 'video_name',
 159+ 'ov_archive_name' => $dbw->addQuotes( gmdate( 'YmdHis' ) . "!{$this->getName()}" ),
 160+ 'ov_url' => 'video_url',
 161+ 'ov_type' => 'video_type',
 162+ 'ov_user_id' => 'video_user_id',
 163+ 'ov_user_name' => 'video_user_name',
 164+ 'ov_timestamp' => 'video_timestamp'
 165+ ),
 166+ array( 'video_name' => $this->getName() ),
 167+ __METHOD__
 168+ );
 169+
 170+ // Update the current video row
 171+ $dbw->update(
 172+ 'video',
 173+ array( /* SET */
 174+ 'video_url'=> $url,
 175+ 'video_type' => $type,
 176+ 'video_user_id' => $wgUser->getID(),
 177+ 'video_user_name' => $wgUser->getName(),
 178+ 'video_timestamp' => $now
 179+ ),
 180+ array( /* WHERE */
 181+ 'video_name' => $this->getName()
 182+ ),
 183+ __METHOD__
 184+ );
 185+ }
 186+
 187+ $descTitle = $this->getTitle();
 188+ $article = new Article( $descTitle );
 189+ $watch = $watch || $wgUser->isWatched( $descTitle );
 190+
 191+ // Get the localized category name
 192+ $videoCategoryName = wfMsgForContent( 'video-category-name' );
 193+
 194+ if( $categories ) {
 195+ $categories .= "|$videoCategoryName";
 196+ } else {
 197+ $categories = "$videoCategoryName";
 198+ }
 199+
 200+ // Loop through category variable and individually build Category Tab for Wiki text
 201+ if( $categories ) {
 202+ $categories_array = explode( '|', $categories );
 203+ foreach( $categories_array as $ctg ) {
 204+ $ctg = trim( $ctg );
 205+ if( $ctg ) {
 206+ $catName = $wgContLang->getNsText( NS_CATEGORY );
 207+ $tag = "[[{$catName}:{$ctg}]]";
 208+ if( strpos( $categoryWikiText, $tag ) === false ) {
 209+ $categoryWikiText .= "\n{$tag}";
 210+ }
 211+ }
 212+ }
 213+ }
 214+
 215+ if( $descTitle->exists() ) {
 216+ # Invalidate the cache for the description page
 217+ $descTitle->invalidateCache();
 218+ $descTitle->purgeSquid();
 219+ } else {
 220+ // New video; create the description page.
 221+ // Supress the recent changes bc it will appear in the log/video
 222+ $article->doEdit( $categoryWikiText, $desc, EDIT_SUPPRESS_RC );
 223+ }
 224+
 225+ if( $watch ) {
 226+ $wgUser->addWatch( $descTitle );
 227+ }
 228+
 229+ // Add the log entry
 230+ $log = new LogPage( 'video' );
 231+ $log->addEntry( 'video', $descTitle, $desc );
 232+
 233+ // Commit the transaction now, in case something goes wrong later
 234+ // The most important thing is that videos don't get lost, especially archives
 235+ $dbw->commit();
 236+ }
 237+
 238+ /**
 239+ * Try to load video metadata from memcached.
 240+ * @return Boolean: true on success.
 241+ */
 242+ private function loadFromCache() {
 243+ global $wgMemc;
 244+
 245+ wfProfileIn( __METHOD__ );
 246+ $this->dataLoaded = false;
 247+
 248+ $key = $this->getCacheKey();
 249+ $data = $wgMemc->get( $key );
 250+
 251+ if( !empty( $data ) && is_array( $data ) ) {
 252+ $this->url = $data['url'];
 253+ $this->type = $data['type'];
 254+ $this->submitter_user_id = $data['user_id'];
 255+ $this->submitter_user_name = $data['user_name'];
 256+ $this->create_date = $data['create_date'];
 257+ $this->dataLoaded = true;
 258+ $this->exists = true;
 259+ }
 260+
 261+ if ( $this->dataLoaded ) {
 262+ wfDebug( "Loaded Video:{$this->name} from cache\n" );
 263+ wfIncrStats( 'video_cache_hit' );
 264+ } else {
 265+ wfIncrStats( 'video_cache_miss' );
 266+ }
 267+
 268+ wfProfileOut( __METHOD__ );
 269+ return $this->dataLoaded;
 270+ }
 271+
 272+ /**
 273+ * Save the video data to memcached
 274+ */
 275+ private function saveToCache() {
 276+ global $wgMemc;
 277+ $key = $this->getCacheKey();
 278+ if ( $this->exists() ) {
 279+ $cachedValues = array(
 280+ 'url' => $this->url,
 281+ 'type' => $this->type,
 282+ 'user_id' => $this->submitter_user_id,
 283+ 'user_name' => $this->submitter_user_name,
 284+ 'create_date' => $this->create_date
 285+ );
 286+ $wgMemc->set( $key, $cachedValues, 60 * 60 * 24 * 7 ); // A week
 287+ } else {
 288+ // However we should clear them, so they aren't leftover
 289+ // if we've deleted the file.
 290+ $wgMemc->delete( $key );
 291+ }
 292+ }
 293+
 294+ /**
 295+ * Get the memcached key for the current video.
 296+ */
 297+ public function getCacheKey() {
 298+ global $wgMemc;
 299+ // memcached does not like spaces, so replace 'em with an underscore
 300+ $safeVideoName = str_replace( ' ', '_', $this->getName() );
 301+ $key = wfMemcKey( 'video', 'page', $safeVideoName );
 302+ return $key;
 303+ }
 304+
 305+ /**
 306+ * Load video from the database
 307+ */
 308+ function loadFromDB() {
 309+ wfProfileIn( __METHOD__ );
 310+
 311+ $dbr = wfGetDB( DB_MASTER );
 312+
 313+ $row = $dbr->selectRow(
 314+ 'video',
 315+ array(
 316+ 'video_url', 'video_type', 'video_user_name', 'video_user_id',
 317+ 'video_timestamp'
 318+ ),
 319+ array( 'video_name' => $this->name ),
 320+ __METHOD__
 321+ );
 322+
 323+ if ( $row ) {
 324+ $this->url = $row->video_url;
 325+ $this->exists = true;
 326+ $this->type = $row->video_type;
 327+ $this->submitter_user_name = $row->video_user_name;
 328+ $this->submitter_user_id = $row->video_user_id;
 329+ $this->create_date = $row->video_timestamp;
 330+ }
 331+
 332+ # Unconditionally set loaded=true, we don't want the accessors constantly rechecking
 333+ $this->dataLoaded = true;
 334+ wfProfileOut( __METHOD__ );
 335+ }
 336+
 337+ /**
 338+ * Load video metadata from cache or database, unless it's already loaded.
 339+ */
 340+ function load() {
 341+ if ( !$this->dataLoaded ) {
 342+ if ( !$this->loadFromCache() ) {
 343+ $this->loadFromDB();
 344+ $this->saveToCache();
 345+ }
 346+ $this->dataLoaded = true;
 347+ }
 348+ }
 349+
 350+ /**
 351+ * Return the name of this video
 352+ */
 353+ public function getName() {
 354+ return $this->name;
 355+ }
 356+
 357+ /**
 358+ * Return the associated Title object
 359+ */
 360+ public function getTitle() {
 361+ return $this->title;
 362+ }
 363+
 364+ /**
 365+ * Return the URL of this video
 366+ */
 367+ public function getURL() {
 368+ $this->load();
 369+ return strip_tags( $this->url );
 370+ }
 371+
 372+ /**
 373+ * Return the type of this video
 374+ */
 375+ public function getType() {
 376+ $this->load();
 377+ return $this->type;
 378+ }
 379+
 380+ /**
 381+ * @return Boolean: true if the Video exists
 382+ */
 383+ public function exists() {
 384+ $this->load();
 385+ return $this->exists;
 386+ }
 387+
 388+ /**
 389+ * Get the embed code for this Video
 390+ *
 391+ * @return String: video embed code
 392+ */
 393+ public function getEmbedCode() {
 394+ switch( $this->getType() ) {
 395+ case 'youtube':
 396+ $provider = new YouTubeVideo( $this );
 397+ break;
 398+ case 'google':
 399+ $provider = new GoogleVideo( $this );
 400+ break;
 401+ case 'metacafe':
 402+ $provider = new MetaCafeVideo( $this );
 403+ break;
 404+ case 'myspace':
 405+ $provider = new MySpaceVideo( $this );
 406+ break;
 407+ case 'dailymotion':
 408+ $provider = new DailyMotionVideo( $this );
 409+ break;
 410+ case 'thenewsroom':
 411+ $provider = new NewsRoomVideo( $this );
 412+ break;
 413+ case 'archiveorg':
 414+ $provider = new ArchiveOrgVideo( $this );
 415+ break;
 416+ case 'bliptv':
 417+ $provider = new BlipTVVideo( $this );
 418+ break;
 419+ case 'hulu':
 420+ $provider = new HuluVideo( $this );
 421+ break;
 422+ case 'gametrailers':
 423+ $provider = new GametrailersVideo( $this );
 424+ break;
 425+ case 'gamevideos':
 426+ $provider = new GamevideosVideo( $this );
 427+ break;
 428+ case 'gogreentube':
 429+ $provider = new GoGreenTubeVideo( $this );
 430+ break;
 431+ case 'movieclips':
 432+ $provider = new MovieClipsVideo( $this );
 433+ break;
 434+ case 'myvideo':
 435+ $provider = new MyVideoVideo( $this );
 436+ break;
 437+ case 'sevenload':
 438+ $provider = new SevenloadVideo( $this );
 439+ break;
 440+ case 'southparkstudios':
 441+ $provider = new SouthParkStudiosVideo( $this );
 442+ break;
 443+ case 'viddler':
 444+ $provider = new ViddlerVideo( $this );
 445+ break;
 446+ case 'vimeo':
 447+ $provider = new VimeoVideo( $this );
 448+ break;
 449+ case 'wegame':
 450+ $provider = new WeGameVideo( $this );
 451+ break;
 452+ default:
 453+ $provider = new FlashVideo( $this );
 454+ break;
 455+ }
 456+
 457+ return $provider->getEmbedCode();
 458+ }
 459+
 460+ /**
 461+ * Is the supplied value a URL?
 462+ *
 463+ * @return Boolean: true if it is, otherwise false
 464+ */
 465+ public static function isURL( $code ) {
 466+ return preg_match( '%^(?:http|https|ftp)://(?:www\.)?.*$%i', $code ) ? true : false;
 467+ }
 468+
 469+ /**
 470+ * Try to figure out the video's URL from the embed code that the provider
 471+ * allows users to copy & paste on their own sites.
 472+ *
 473+ * @param $code String: the video's HTML embedding code
 474+ * @return String: URL of the video
 475+ */
 476+ public static function getURLfromEmbedCode( $code ) {
 477+ preg_match(
 478+ "/embed .*src=(\"([^<\"].*?)\"|\'([^<\"].*?)\'|[^<\"].*?)(.*flashvars=(\"([^<\"].*?)\"|\'([^<\"].*?)\'|[^<\"].*?\s))?/i",
 479+ $code,
 480+ $matches
 481+ );
 482+
 483+ $embedCode = '';
 484+ if( $matches[2] ) {
 485+ $embedCode = $matches[2];
 486+ }
 487+
 488+ // Some providers (such as MySpace) have flashvars='' in the embed
 489+ // code, and the base URL in the src='' so we need to grab the
 490+ // flashvars and append it to get the real URL
 491+ $flash_vars = $matches[6];
 492+ if( $flash_vars ) {
 493+ if( strpos( '?', $flash_vars ) !== false ) {
 494+ $embedCode .= '&';
 495+ } else {
 496+ $embedCode .= '?';
 497+ }
 498+ $embedCode .= $flash_vars;
 499+ }
 500+
 501+ return $embedCode;
 502+ }
 503+
 504+ /**
 505+ * Figure out the provider's name (lowercased) from a given URL.
 506+ *
 507+ * @param $url String: URL to check
 508+ * @return String: provider name or 'unknown' if we were unable to figure
 509+ * it out
 510+ */
 511+ public static function getProviderByURL( $url ) {
 512+ $text = preg_match( '/youtube\.com/i', $url );
 513+ if( $text ) {
 514+ return 'youtube';
 515+ }
 516+ $text = preg_match( '/metacafe\.com/i', $url );
 517+ if( $text ) {
 518+ return 'metacafe';
 519+ }
 520+ $text = preg_match( '/google\.com/i', $url );
 521+ if( $text ) {
 522+ return 'google';
 523+ }
 524+ $text = preg_match( '/myspace(tv)?\.com/i', $url );
 525+ if( $text ) {
 526+ return 'myspace';
 527+ }
 528+ $text = preg_match( '/dailymotion\.com/i', $url );
 529+ if( $text ) {
 530+ return 'dailymotion';
 531+ }
 532+ $text = preg_match( '/thenewsroom\.com/i', $url );
 533+ if( $text ) {
 534+ return 'thenewsroom';
 535+ }
 536+ $text = preg_match( '/archive\.org/i', $url );
 537+ if( $text ) {
 538+ return 'archiveorg';
 539+ }
 540+ $text = preg_match( '/blip\.tv/i', $url );
 541+ if( $text ) {
 542+ return 'bliptv';
 543+ }
 544+ $text = preg_match( '/gametrailers\.com/i', $url );
 545+ if( $text ) {
 546+ return 'gametrailers';
 547+ }
 548+ $text = preg_match( '/gamevideos\.1up\.com/i', $url );
 549+ if( $text ) {
 550+ return 'gamevideos';
 551+ }
 552+ $text = preg_match( '/gogreentube\.com/i', $url );
 553+ if( $text ) {
 554+ return 'gogreentube';
 555+ }
 556+ $text = preg_match( '/hulu\.com/i', $url );
 557+ if( $text ) {
 558+ return 'hulu';
 559+ }
 560+ $text = preg_match( '/movieclips\.com/i', $url );
 561+ if( $text ) {
 562+ return 'movieclips';
 563+ }
 564+ $text = preg_match( '/myvideo\.de/i', $url );
 565+ if( $text ) {
 566+ return 'myvideo';
 567+ }
 568+ $text = preg_match( '/sevenload\.com/i', $url );
 569+ if( $text ) {
 570+ return 'sevenload';
 571+ }
 572+ $text = preg_match( '/southparkstudios\.com/i', $url );
 573+ if( $text ) {
 574+ return 'southparkstudios';
 575+ }
 576+ $text = preg_match( '/viddler\.com/i', $url );
 577+ if( $text ) {
 578+ return 'viddler';
 579+ }
 580+ $text = preg_match( '/vimeo\.com/i', $url );
 581+ if( $text ) {
 582+ return 'vimeo';
 583+ }
 584+ $text = preg_match( '/wegame\.com/i', $url );
 585+ if( $text ) {
 586+ return 'wegame';
 587+ }
 588+ if( !$text ) {
 589+ return 'unknown';
 590+ }
 591+ }
 592+
 593+ public function setWidth( $width ) {
 594+ if( is_numeric( $width ) ) {
 595+ $this->width = $width;
 596+ }
 597+ }
 598+
 599+ public function setHeight( $height ) {
 600+ if( is_numeric( $height ) ) {
 601+ $this->height = $height;
 602+ }
 603+ }
 604+
 605+ public function getWidth() {
 606+ return $this->width;
 607+ }
 608+
 609+ public function getHeight() {
 610+ return floor( $this->getWidth() / $this->ratio );
 611+ //return $this->height;
 612+ }
 613+
 614+ /**
 615+ * Get the code for embedding the current video on a wiki page.
 616+ *
 617+ * @return String: wikitext to insert on a wiki page
 618+ */
 619+ public function getEmbedThisCode() {
 620+ $videoName = htmlspecialchars( $this->getName(), ENT_QUOTES );
 621+ return "[[Video:{$videoName}|{$this->getWidth()}px]]";
 622+ //return "<video name=\"{$this->getName()}\" width=\"{$this->getWidth()}\" height=\"{$this->getHeight()}\"></video>";
 623+ }
 624+
 625+ /**
 626+ * Return the image history of this video, line by line.
 627+ * starts with current version, then old versions.
 628+ * uses $this->historyLine to check which line to return:
 629+ * 0 return line for current version
 630+ * 1 query for old versions, return first one
 631+ * 2, ... return next old version from above query
 632+ */
 633+ public function nextHistoryLine() {
 634+ $dbr = wfGetDB( DB_SLAVE );
 635+
 636+ if ( empty( $this->historyLine ) ) { // called for the first time, return line from cur
 637+ $this->historyRes = $dbr->select( 'video',
 638+ array(
 639+ 'video_url',
 640+ 'video_type',
 641+ 'video_user_id','video_user_name',
 642+ 'video_timestamp',
 643+ "'' AS ov_archive_name"
 644+ ),
 645+ array( 'video_name' => $this->title->getDBkey() ),
 646+ __METHOD__
 647+ );
 648+ if ( $dbr->numRows( $this->historyRes ) == 0 ) {
 649+ return false;
 650+ }
 651+ } elseif ( $this->historyLine == 1 ) {
 652+ $this->historyRes = $dbr->select(
 653+ 'oldvideo',
 654+ array(
 655+ 'ov_url AS video_url',
 656+ 'ov_type AS video_type',
 657+ 'ov_user_id AS video_user_id',
 658+ 'ov_user_name AS video_user_name',
 659+ 'ov_timestamp AS video_timestamp',
 660+ 'ov_archive_name'
 661+ ),
 662+ array( 'ov_name' => $this->title->getDBkey() ),
 663+ __METHOD__,
 664+ array( 'ORDER BY' => 'ov_timestamp DESC' )
 665+ );
 666+ }
 667+ $this->historyLine++;
 668+
 669+ return $dbr->fetchObject( $this->historyRes );
 670+ }
 671+
 672+ /**
 673+ * Reset the history pointer to the first element of the history
 674+ */
 675+ public function resetHistory() {
 676+ $this->historyLine = 0;
 677+ }
 678+
 679+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/VideoClass.php
___________________________________________________________________
Added: svn:eol-style
1680 + native
Index: trunk/extensions/Video/Video.alias.php
@@ -0,0 +1,33 @@
 2+<?php
 3+/**
 4+ * Aliases for the Video extension.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$aliases = array();
 11+
 12+/** English */
 13+$aliases['en'] = array(
 14+ 'AddVideo' => array( 'AddVideo' ),
 15+ 'NewVideos' => array( 'NewVideos' ),
 16+);
 17+
 18+/** Finnish (Suomi) */
 19+$aliases['fi'] = array(
 20+ 'AddVideo' => array( 'Lisää video' ),
 21+ 'NewVideos' => array( 'Uudet videot' ),
 22+);
 23+
 24+/** French (Français) */
 25+$aliases['fr'] = array(
 26+ 'AddVideo' => array( 'Ajouter vidéo', 'Ajouter video', 'AjouterVidéo', 'AjouterVideo' ),
 27+ 'NewVideos' => array( 'Nouvelles vidéos', 'Nouvelles videos', 'NouvellesVidéos', 'NouvellesVideos' ),
 28+);
 29+
 30+/** Dutch (Nederlands) */
 31+$aliases['nl'] = array(
 32+ 'AddVideo' => array( 'VideoToevoegen', 'Video toevoegen' ),
 33+ 'NewVideos' => array( "NieuweVideos", "NieuweVideo's", 'NieuweVideo’s', "Nieuwe video's", 'Nieuwe video’s' ),
 34+);
\ No newline at end of file
Property changes on: trunk/extensions/Video/Video.alias.php
___________________________________________________________________
Added: svn:eol-style
135 + native
Index: trunk/extensions/Video/VideoGalleryPopulate.php
@@ -0,0 +1,78 @@
 2+<?php
 3+/**
 4+ * <videogallerypopulate> parser hook extension -- display a gallery of all
 5+ * videos in a specific category
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
 11+if ( !defined( 'MEDIAWIKI' ) ) {
 12+ die( "This is not a valid entry point.\n" );
 13+}
 14+
 15+$wgHooks['ParserFirstCallInit'][] = 'wfVideoGalleryPopulate';
 16+
 17+function wfVideoGalleryPopulate( &$parser ) {
 18+ $parser->setHook( 'videogallerypopulate', 'VideoGalleryPopulate' );
 19+ return true;
 20+}
 21+
 22+function VideoGalleryPopulate( $input, $args, $parser ) {
 23+ global $wgOut;
 24+
 25+ $parser->disableCache();
 26+
 27+ $category = ( isset( $args['category'] ) ) ? $args['category'] : '';
 28+ $limit = ( isset( $args['limit'] ) ) ? intval( $args['limit'] ) : 10;
 29+
 30+ if( empty( $category ) ) {
 31+ return '';
 32+ }
 33+
 34+ // Why do we initialize a new instance of Parser here, I wonder?
 35+ $parser = new Parser();
 36+ $category = $parser->transformMsg( $category, $wgOut->parserOptions() );
 37+ $category_title = Title::newFromText( $category );
 38+ if( !( $category_title instanceof Title ) ) {
 39+ return '';
 40+ }
 41+
 42+ // @todo FIXME: not overly i18n-friendly here...
 43+ $category_title_secondary = Title::newFromText( $category . ' Videos' );
 44+ if( !( $category_title_secondary instanceof Title ) ) {
 45+ return '';
 46+ }
 47+
 48+ $params['ORDER BY'] = 'page_id';
 49+ if( $limit ) {
 50+ $params['LIMIT'] = $limit;
 51+ }
 52+
 53+ $dbr = wfGetDB( DB_SLAVE );
 54+ $res = $dbr->select(
 55+ array( 'page', 'categorylinks' ),
 56+ 'page_title',
 57+ array(
 58+ 'cl_to' => array(
 59+ $category_title->getDBkey(),
 60+ $category_title_secondary->getDBkey()
 61+ ),
 62+ 'page_namespace' => NS_VIDEO
 63+ ),
 64+ __METHOD__,
 65+ $params,
 66+ array( 'categorylinks' => array( 'INNER JOIN', 'cl_from = page_id' ) )
 67+ );
 68+
 69+ $gallery = new VideoGallery();
 70+ $gallery->setParsing( true );
 71+ $gallery->setShowFilename( true );
 72+
 73+ foreach ( $res as $row ) {
 74+ $video = Video::newFromName( $row->page_title );
 75+ $gallery->add( $video );
 76+ }
 77+
 78+ return $gallery->toHtml();
 79+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/VideoGalleryPopulate.php
___________________________________________________________________
Added: svn:eol-style
180 + native
Index: trunk/extensions/Video/VideoPage.php
@@ -0,0 +1,502 @@
 2+<?php
 3+
 4+class VideoPage extends Article {
 5+
 6+ var $title = null;
 7+
 8+ /**
 9+ * Constructor and clear the article
 10+ * @param $title Object: reference to a Title object.
 11+ */
 12+ public function __construct( $title ) {
 13+ parent::__construct( $title );
 14+ }
 15+
 16+ /**
 17+ * Called on every video page view.
 18+ */
 19+ public function view() {
 20+ global $wgOut, $wgUser, $wgRequest;
 21+
 22+ $this->video = new Video( $this->getTitle() );
 23+
 24+ $videoLinksHTML = '<br />' . Xml::element( 'h2',
 25+ array( 'id' => 'filelinks' ), wfMsg( 'video-links' ) ) . "\n";
 26+ $sk = $wgUser->getSkin();
 27+
 28+ // No need to display noarticletext, we use our own message
 29+ if ( $this->getID() ) {
 30+ parent::view();
 31+ } else {
 32+ // Just need to set the right headers
 33+ $wgOut->setArticleFlag( true );
 34+ $wgOut->setRobotPolicy( 'index,follow' );
 35+ $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
 36+ }
 37+
 38+ if( $this->video->exists() ) {
 39+ // Display flash video
 40+ $wgOut->addHTML( $this->video->getEmbedCode() );
 41+
 42+ // Force embed this code to have width of 300
 43+ $this->video->setWidth( 300 );
 44+ $wgOut->addHTML( $this->getEmbedThisTag() );
 45+
 46+ $this->videoHistory();
 47+
 48+ //$wgOut->addHTML( $videoLinksHTML );
 49+ //$this->videoLinks();
 50+ } else {
 51+ // Video doesn't exist, so give a link allowing user to add one with this name
 52+ $title = SpecialPage::getTitleFor( 'AddVideo' );
 53+ $link = $sk->linkKnown(
 54+ $title,
 55+ wfMsgHtml( 'video-novideo-linktext' ),
 56+ array(),
 57+ array( 'wpDestName' => $this->video->getName() )
 58+ );
 59+ $wgOut->addHTML( wfMsgWikiHtml( 'video-novideo', $link ) );
 60+
 61+ //$wgOut->addHTML( $videoLinksHTML );
 62+ //$this->videoLinks();
 63+ $this->viewUpdates();
 64+ }
 65+ }
 66+
 67+ /**
 68+ * Display pages linking to that video on the video page.
 69+ *
 70+ * @todo FIXME: this does not work at the moment; there are no NS_VIDEO
 71+ * entries in the pagelinks table. I think it is because the
 72+ * [[Video:Foo]] links are not links per se, but they just
 73+ * look like links to the end-user; to MediaWiki, they are
 74+ * parser hooks, like <video name="Foo" />...how to fix this?
 75+ */
 76+ function videoLinks() {
 77+ global $wgOut, $wgUser;
 78+
 79+ $limit = 100;
 80+
 81+ $dbr = wfGetDB( DB_SLAVE );
 82+
 83+ // WikiaVideo used the imagelinks table here because that extension
 84+ // adds everything into core (archive, filearchive, imagelinks, etc.)
 85+ // tables instead of using its own tables
 86+ $res = $dbr->select(
 87+ array( 'pagelinks', 'page' ),
 88+ array( 'page_namespace', 'page_title' ),
 89+ array(
 90+ 'pl_namespace' => NS_VIDEO,
 91+ 'pl_title' => $this->getTitle()->getDBkey(),
 92+ 'pl_from = page_id',
 93+ ),
 94+ __METHOD__,
 95+ array( 'LIMIT' => $limit + 1 )
 96+ );
 97+
 98+ $count = $dbr->numRows( $res );
 99+
 100+ if ( $count == 0 ) {
 101+ $wgOut->addHTML( '<div id="mw-imagepage-nolinkstoimage">' . "\n" );
 102+ $wgOut->addWikiMsg( 'video-no-links-to-video' );
 103+ $wgOut->addHTML( "</div>\n" );
 104+ return;
 105+ }
 106+
 107+ $wgOut->addHTML( '<div id="mw-imagepage-section-linkstoimage">' . "\n" );
 108+ $wgOut->addWikiMsg( 'video-links-to-video', $count );
 109+ $wgOut->addHTML( '<ul class="mw-imagepage-linktoimage">' . "\n" );
 110+
 111+ $sk = $wgUser->getSkin();
 112+ $count = 0;
 113+ while ( $s = $res->fetchObject() ) {
 114+ $count++;
 115+ if ( $count <= $limit ) {
 116+ // We have not yet reached the extra one that tells us there is
 117+ // more to fetch
 118+ $name = Title::makeTitle( $s->page_namespace, $s->page_title );
 119+ $link = $sk->makeKnownLinkObj( $name, '' );
 120+ $wgOut->addHTML( "<li>{$link}</li>\n" );
 121+ }
 122+ }
 123+ $wgOut->addHTML( "</ul></div>\n" );
 124+ $res->free();
 125+
 126+ // Add a link to [[Special:WhatLinksHere]]
 127+ if ( $count > $limit ) {
 128+ $wgOut->addWikiMsg(
 129+ 'video-more-links-to-video',
 130+ $this->mTitle->getPrefixedDBkey()
 131+ );
 132+ }
 133+ }
 134+
 135+ /** @todo FIXME: is this needed? If not, remove! */
 136+ function getContent() {
 137+ return Article::getContent();
 138+ }
 139+
 140+ /**
 141+ * Get the HTML table that contains the code for embedding the current
 142+ * video on a wiki page.
 143+ *
 144+ * @return String: HTML
 145+ */
 146+ public function getEmbedThisTag() {
 147+ $code = $this->video->getEmbedThisCode();
 148+ $code = preg_replace( '/[\n\r\t]/', '', $code ); // replace any non-space whitespace with a space
 149+ $code = str_replace( '_', ' ', $code ); // replace underscores with spaces
 150+ return '<br /><br />
 151+ <table cellpadding="0" cellspacing="2" border="0">
 152+ <tr>
 153+ <td>
 154+ <b>' . wfMsg( 'video-embed' ) . '</b>
 155+ </td>
 156+ <td>
 157+ <form name="embed_video" action="">
 158+ <input name="embed_code" style="width: 300px; font-size: 10px;" type="text" value="' . $code . '" onclick="javascript:document.embed_video.embed_code.focus();document.embed_video.embed_code.select();" readonly="readonly" />
 159+ </form>
 160+ </td>
 161+ </tr>
 162+ </table>';
 163+ }
 164+
 165+ /**
 166+ * If the page we've just displayed is in the "Video" namespace,
 167+ * we follow it with an upload history of the video and its usage.
 168+ */
 169+ function videoHistory() {
 170+ global $wgUser, $wgOut;
 171+
 172+ $sk = $wgUser->getSkin();
 173+
 174+ $line = $this->video->nextHistoryLine();
 175+
 176+ if ( $line ) {
 177+ $list = new VideoHistoryList( $sk );
 178+ $s = $list->beginVideoHistoryList() .
 179+ $list->videoHistoryLine(
 180+ true,
 181+ wfTimestamp( TS_MW, $line->video_timestamp ),
 182+ $this->mTitle->getDBkey(),
 183+ $line->video_user_id,
 184+ $line->video_user_name,
 185+ strip_tags( $line->video_url ),
 186+ $line->video_type
 187+ );
 188+
 189+ while ( $line = $this->video->nextHistoryLine() ) {
 190+ $s .= $list->videoHistoryLine( false, $line->video_timestamp,
 191+ $line->ov_archive_name, $line->video_user_id,
 192+ $line->video_user_name, strip_tags( $line->video_url ), $line->video_type
 193+ );
 194+ }
 195+ $s .= $list->endVideoHistoryList();
 196+ } else {
 197+ $s = '';
 198+ }
 199+ $wgOut->addHTML( $s );
 200+
 201+ // Exist check because we don't want to show this on pages where a video
 202+ // doesn't exist along with the novideo message, that would suck.
 203+ if( $this->video->exists() ) {
 204+ $this->uploadLinksBox();
 205+ }
 206+ }
 207+
 208+ /**
 209+ * Print out the reupload link at the bottom of a video page for privileged
 210+ * users.
 211+ */
 212+ function uploadLinksBox() {
 213+ global $wgUser, $wgOut;
 214+
 215+ $sk = $wgUser->getSkin();
 216+
 217+ $wgOut->addHTML( '<br /><ul>' );
 218+
 219+ // "Upload a new version of this video" link
 220+ if( $wgUser->isAllowed( 'reupload' ) ) {
 221+ $ulink = $sk->link(
 222+ SpecialPage::getTitleFor( 'AddVideo' ),
 223+ wfMsg( 'uploadnewversion-linktext' ),
 224+ array(),
 225+ array( 'wpDestName' => $this->video->getName() )
 226+ );
 227+ $wgOut->addHTML( "<li>{$ulink}</li>" );
 228+ }
 229+
 230+ $wgOut->addHTML( '</ul>' );
 231+ }
 232+
 233+ /**
 234+ * Reverts a video to its earlier state
 235+ */
 236+ function revert() {
 237+ global $wgOut, $wgRequest, $wgUser;
 238+
 239+ $oldvideo = $wgRequest->getText( 'oldvideo' );
 240+ if ( strlen( $oldvideo ) < 16 ) {
 241+ $wgOut->showUnexpectedValueError( 'oldvideo', htmlspecialchars( $oldvideo ) );
 242+ return;
 243+ }
 244+
 245+ // Can't do anything during DB locks
 246+ if ( wfReadOnly() ) {
 247+ $wgOut->readOnlyPage();
 248+ return;
 249+ }
 250+
 251+ // Must be logged in to revert videos
 252+ if( $wgUser->isAnon() ) {
 253+ $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
 254+ return;
 255+ }
 256+
 257+ // Must be able to edit in order to revert
 258+ if ( !$this->mTitle->userCan( 'edit' ) ) {
 259+ $wgOut->readOnlyPage( $this->getContent(), true );
 260+ return;
 261+ }
 262+
 263+ // Must not be blocked
 264+ if ( $wgUser->isBlocked() ) {
 265+ return $this->blockedIPpage();
 266+ }
 267+
 268+ // And finally edit tokens must match in order to prevent cross-site request forgery
 269+ if( !$wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $oldvideo ) ) {
 270+ $wgOut->showErrorPage( 'internalerror', 'sessionfailure' );
 271+ return;
 272+ }
 273+
 274+ $dbr = wfGetDB( DB_MASTER );
 275+ $s = $dbr->selectRow(
 276+ 'oldvideo',
 277+ array( 'ov_url', 'ov_type' ),
 278+ array( 'ov_archive_name' => urldecode( $oldvideo ) ),
 279+ __METHOD__
 280+ );
 281+ if ( $s !== false ) {
 282+ $url = $s->ov_url;
 283+ $type = $s->ov_type;
 284+ } else {
 285+ $wgOut->showUnexpectedValueError( 'oldvideo', htmlspecialchars( $oldvideo ) );
 286+ return;
 287+ }
 288+
 289+ $name = substr( $oldvideo, 15 );
 290+
 291+ //$oldver = wfTimestampNow() . "!{$name}";
 292+
 293+ // Record upload and update metadata cache
 294+ $video = Video::newFromName( $name );
 295+ $video->addVideo( $url, $type, '' );
 296+
 297+ $wgOut->setPageTitle( wfMsgHtml( 'actioncomplete' ) );
 298+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
 299+ $wgOut->addHTML( wfMsg( 'video-revert-success' ) );
 300+
 301+ $descTitle = $video->getTitle();
 302+ $wgOut->returnToMain( false, $descTitle->getPrefixedText() );
 303+ }
 304+
 305+}
 306+
 307+/**
 308+ * @todo document
 309+ */
 310+class VideoHistoryList {
 311+
 312+ function __construct( &$skin ) {
 313+ $this->skin =& $skin;
 314+ }
 315+
 316+ function beginVideoHistoryList() {
 317+ $s = "\n" .
 318+ Xml::element( 'h2', array( 'id' => 'filehistory' ), wfMsgHtml( 'video-history' ) ) .
 319+ "\n<p>" . wfMsg( 'video-histlegend' ) . "</p>\n" . '<ul class="special">';
 320+ return $s;
 321+ }
 322+
 323+ function endVideoHistoryList() {
 324+ $s = "</ul>\n";
 325+ return $s;
 326+ }
 327+
 328+ function videoHistoryLine( $iscur, $timestamp, $video, $user_id, $user_name, $url, $type ) {
 329+ global $wgUser, $wgLang, $wgTitle, $wgContLang;
 330+
 331+ $datetime = $wgLang->timeanddate( $timestamp, true );
 332+ $cur = wfMsgHtml( 'cur' );
 333+
 334+ if ( $iscur ) {
 335+ $rlink = $cur;
 336+ } else {
 337+ if( $wgUser->getID() != 0 && $wgTitle->userCan( 'edit' ) ) {
 338+ $token = urlencode( $wgUser->editToken( $video ) );
 339+ $rlink = $this->skin->makeKnownLinkObj(
 340+ $wgTitle,
 341+ wfMsgHtml( 'video-revert' ),
 342+ 'action=revert&oldvideo=' . urlencode( $video ) .
 343+ "&wpEditToken=$token"
 344+ );
 345+ } else {
 346+ # Having live active links for non-logged in users
 347+ # means that bots and spiders crawling our site can
 348+ # inadvertently change content. Baaaad idea.
 349+ $rlink = wfMsgHtml( 'video-revert' );
 350+ $dlink = $del;
 351+ }
 352+ }
 353+
 354+ $userlink = $this->skin->userLink( $user_id, $user_name ) .
 355+ $this->skin->userToolLinks( $user_id, $user_name );
 356+
 357+ $style = $this->skin->getInternalLinkAttributes( $url, $datetime );
 358+
 359+ $s = "<li>({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a> . . ({$type}) . . {$userlink}";
 360+
 361+ $s .= $this->skin->commentBlock( /*$description*/'', $wgTitle );
 362+ $s .= "</li>\n";
 363+ return $s;
 364+ }
 365+
 366+}
 367+
 368+/**
 369+ * This is like a normal CategoryViewer, except that it supports videos.
 370+ * This is initialized for every category page by
 371+ * VideoHooks::categoryPageWithVideo function in VideoHooks.php.
 372+ */
 373+class CategoryWithVideoViewer extends CategoryViewer {
 374+
 375+ function clearCategoryState() {
 376+ $this->articles = array();
 377+ $this->articles_start_char = array();
 378+ $this->children = array();
 379+ $this->children_start_char = array();
 380+ if( $this->showGallery ) {
 381+ $this->gallery = new ImageGallery();
 382+ }
 383+ #if( $this->showVideoGallery ) {
 384+ $this->videogallery = new VideoGallery();
 385+ $this->videogallery->setParsing();
 386+ #}
 387+ }
 388+
 389+ /**
 390+ * Format the category data list.
 391+ *
 392+ * @param $from String: return only sort keys from this item on
 393+ * @param $until String: don't return keys after this point.
 394+ * @return String: HTML output
 395+ * @private
 396+ */
 397+ function getHTML() {
 398+ global $wgOut, $wgCategoryMagicGallery;
 399+ wfProfileIn( __METHOD__ );
 400+
 401+ $this->showGallery = $wgCategoryMagicGallery && !$wgOut->mNoGallery;
 402+
 403+ $this->clearCategoryState();
 404+ $this->doCategoryQuery();
 405+ $this->finaliseCategoryState();
 406+
 407+ $r = $this->getCategoryTop() .
 408+ $this->getSubcategorySection() .
 409+ $this->getPagesSection() .
 410+ $this->getImageSection() .
 411+ $this->getVideoSection() .
 412+ $this->getCategoryBottom();
 413+
 414+ wfProfileOut( __METHOD__ );
 415+ return $r;
 416+ }
 417+
 418+ /**
 419+ * If there are videos on the category, display a message indicating how
 420+ * many videos are in the category and render the gallery of videos.
 421+ *
 422+ * @return String: HTML when there are videos on the category
 423+ */
 424+ function getVideoSection() {
 425+ if( !$this->videogallery->isEmpty() ) {
 426+ return "<div id=\"mw-category-media\">\n" . '<h2>' .
 427+ wfMsg(
 428+ 'category-video-header',
 429+ htmlspecialchars( $this->title->getText() )
 430+ ) . "</h2>\n" .
 431+ wfMsgExt(
 432+ 'category-video-count',
 433+ 'parsemag',
 434+ $this->videogallery->count()
 435+ ) . $this->videogallery->toHTML() . "\n</div>";
 436+ } else {
 437+ return '';
 438+ }
 439+ }
 440+
 441+ /**
 442+ * Add a page in the video namespace
 443+ */
 444+ function addVideo( $title, $sortkey, $pageLength ) {
 445+ $video = new Video( $title );
 446+ if( $this->flip ) {
 447+ $this->videogallery->insert( $video );
 448+ } else {
 449+ $this->videogallery->add( $video );
 450+ }
 451+ }
 452+
 453+ function doCategoryQuery() {
 454+ $dbr = wfGetDB( DB_SLAVE );
 455+ if( $this->from != '' ) {
 456+ $pageCondition = 'cl_sortkey >= ' . $dbr->addQuotes( $this->from );
 457+ $this->flip = false;
 458+ } elseif( $this->until != '' ) {
 459+ $pageCondition = 'cl_sortkey < ' . $dbr->addQuotes( $this->until );
 460+ $this->flip = true;
 461+ } else {
 462+ $pageCondition = '1 = 1';
 463+ $this->flip = false;
 464+ }
 465+ $res = $dbr->select(
 466+ array( 'page', 'categorylinks' ),
 467+ array( 'page_title', 'page_namespace', 'page_len', 'cl_sortkey' ),
 468+ array(
 469+ $pageCondition,
 470+ 'cl_from = page_id',
 471+ 'cl_to' => $this->title->getDBKey()
 472+ ),
 473+ __METHOD__,
 474+ array(
 475+ 'ORDER BY' => $this->flip ? 'cl_sortkey DESC' : 'cl_sortkey',
 476+ 'LIMIT' => $this->limit + 1
 477+ )
 478+ );
 479+
 480+ $count = 0;
 481+ $this->nextPage = null;
 482+ foreach( $res as $x ) {
 483+ if( ++$count > $this->limit ) {
 484+ // We've reached the one extra which shows that there are
 485+ // additional pages to be had. Stop here...
 486+ $this->nextPage = $x->cl_sortkey;
 487+ break;
 488+ }
 489+
 490+ $title = Title::makeTitle( $x->page_namespace, $x->page_title );
 491+
 492+ if( $title->getNamespace() == NS_CATEGORY ) {
 493+ $this->addSubcategory( $title, $x->cl_sortkey, $x->page_len );
 494+ } elseif( $title->getNamespace() == NS_FILE ) {
 495+ $this->addImage( $title, $x->cl_sortkey, $x->page_len );
 496+ } elseif( $title->getNamespace() == NS_VIDEO ) {
 497+ $this->addVideo( $title, $x->cl_sortkey, $x->page_len );
 498+ } else {
 499+ $this->addPage( $title, $x->cl_sortkey, $x->page_len );
 500+ }
 501+ }
 502+ }
 503+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/VideoPage.php
___________________________________________________________________
Added: svn:eol-style
1504 + native
Index: trunk/extensions/Video/SpecialNewVideos.php
@@ -0,0 +1,278 @@
 2+<?php
 3+/**
 4+ * Special:NewVideos - a special page for showing recently added videos
 5+ * Reuses various bits and pieces from SpecialNewimages.php
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
 11+class NewVideos extends IncludableSpecialPage {
 12+
 13+ /**
 14+ * Constructor
 15+ */
 16+ public function __construct() {
 17+ parent::__construct( 'NewVideos' );
 18+ }
 19+
 20+ /**
 21+ * Show the special page
 22+ *
 23+ * @param $par Mixed: parameter passed to the page or null
 24+ */
 25+ public function execute( $par ) {
 26+ global $wgUser, $wgOut, $wgLang, $wgRequest, $wgGroupPermissions;
 27+
 28+ $wgOut->setPageTitle( wfMsgHtml( 'newvideos' ) );
 29+
 30+ $wpIlMatch = $wgRequest->getText( 'wpIlMatch' );
 31+ $dbr = wfGetDB( DB_SLAVE );
 32+ $sk = $wgUser->getSkin();
 33+ $shownav = !$this->including();
 34+ $hidebots = $wgRequest->getBool( 'hidebots', 1 );
 35+
 36+ $hidebotsql = '';
 37+ if( $hidebots ) {
 38+ /**
 39+ * Make a list of group names which have the 'bot' flag
 40+ * set.
 41+ */
 42+ $botconds = array();
 43+ foreach( $wgGroupPermissions as $groupname => $perms ) {
 44+ if( array_key_exists( 'bot', $perms ) && $perms['bot'] ) {
 45+ $botconds[] = "ug_group='$groupname'";
 46+ }
 47+ }
 48+
 49+ /* If not bot groups, do not set $hidebotsql */
 50+ if( $botconds ) {
 51+ $isbotmember = $dbr->makeList( $botconds, LIST_OR );
 52+
 53+ /**
 54+ * This join, in conjunction with WHERE ug_group
 55+ * IS NULL, returns only those rows from IMAGE
 56+ * where the uploading user is not a member of
 57+ * a group which has the 'bot' permission set.
 58+ */
 59+ $ug = $dbr->tableName( 'user_groups' );
 60+ $hidebotsql = " LEFT OUTER JOIN $ug ON video_user_name=ug_user AND ($isbotmember)";
 61+ }
 62+ }
 63+
 64+ $video = $dbr->tableName( 'video' );
 65+
 66+ $sql = "SELECT video_timestamp FROM $video";
 67+ if( $hidebotsql ) {
 68+ $sql .= "$hidebotsql WHERE ug_group IS NULL";
 69+ }
 70+ $sql.= ' ORDER BY video_timestamp DESC LIMIT 1';
 71+ $res = $dbr->query( $sql, __METHOD__ );
 72+ $row = $dbr->fetchRow( $res );
 73+ if( $row !== false ) {
 74+ $ts = $row[0];
 75+ } else {
 76+ $ts = false;
 77+ }
 78+ $sql = '';
 79+
 80+ /** If we were clever, we'd use this to cache. */
 81+ $latestTimestamp = wfTimestamp( TS_MW, $ts );
 82+
 83+ /** Hardcode this for now. */
 84+ $limit = 48;
 85+
 86+ if ( $parval = intval( $par ) ) {
 87+ if ( $parval <= $limit && $parval > 0 ) {
 88+ $limit = $parval;
 89+ }
 90+ }
 91+
 92+ $where = array();
 93+ $searchpar = array();
 94+ if ( $wpIlMatch != '' ) {
 95+ $nt = Title::newFromUrl( $wpIlMatch );
 96+ if( $nt ) {
 97+ $m = $dbr->strencode( strtolower( $nt->getDBkey() ) );
 98+ $m = str_replace( '%', "\\%", $m );
 99+ $m = str_replace( '_', "\\_", $m );
 100+ $where[] = "LCASE(video_name) LIKE '%{$m}%'";
 101+ $searchpar['wpIlMatch'] = $wpIlMatch;
 102+ }
 103+ }
 104+
 105+ $invertSort = false;
 106+ if( $until = $wgRequest->getVal( 'until' ) ) {
 107+ $where[] = 'video_timestamp < ' . $dbr->timestamp( $until );
 108+ }
 109+ if( $from = $wgRequest->getVal( 'from' ) ) {
 110+ $where[] = 'video_timestamp >= ' . $dbr->timestamp( $from );
 111+ $invertSort = true;
 112+ }
 113+ $sql = 'SELECT video_name, video_url, video_user_name, video_user_id, '.
 114+ " video_timestamp FROM $video";
 115+
 116+ if( $hidebotsql ) {
 117+ $sql .= $hidebotsql;
 118+ $where[] = 'ug_group IS NULL';
 119+ }
 120+ if( count( $where ) ) {
 121+ $sql.= ' WHERE ' . $dbr->makeList( $where, LIST_AND );
 122+ }
 123+ $sql.= ' ORDER BY video_timestamp '. ( $invertSort ? '' : ' DESC' );
 124+ $sql.= ' LIMIT ' . ( $limit + 1 );
 125+ $res = $dbr->query( $sql, __METHOD__ );
 126+
 127+ /**
 128+ * We have to flip things around to get the last N after a certain date
 129+ */
 130+ $videos = array();
 131+ foreach( $res as $s ) {
 132+ if( $invertSort ) {
 133+ array_unshift( $videos, $s );
 134+ } else {
 135+ array_push( $videos, $s );
 136+ }
 137+ }
 138+
 139+ $gallery = new VideoGallery();
 140+ $firstTimestamp = null;
 141+ $lastTimestamp = null;
 142+ $shownVideos = 0;
 143+ foreach( $videos as $s ) {
 144+ if( ++$shownVideos > $limit ) {
 145+ // One extra just to test for whether to show a page link;
 146+ // don't actually show it.
 147+ break;
 148+ }
 149+
 150+ $name = $s->video_name;
 151+ $ut = $s->video_user_name;
 152+
 153+ $nt = Title::newFromText( $name, NS_VIDEO );
 154+ $vid = new Video( $nt );
 155+ $ul = $sk->makeLinkObj( Title::makeTitle( NS_USER, $ut ), $ut );
 156+
 157+ $gallery->add(
 158+ $vid,
 159+ "$ul<br />\n<i>" .
 160+ $wgLang->timeanddate( $s->video_timestamp, true ) .
 161+ "</i><br />\n"
 162+ );
 163+
 164+ $timestamp = wfTimestamp( TS_MW, $s->video_timestamp );
 165+ if( empty( $firstTimestamp ) ) {
 166+ $firstTimestamp = $timestamp;
 167+ }
 168+ $lastTimestamp = $timestamp;
 169+ }
 170+
 171+ $bydate = wfMsg( 'bydate' );
 172+ $lt = $wgLang->formatNum( min( $shownVideos, $limit ) );
 173+ if( $shownav ) {
 174+ $text = wfMsgExt( 'imagelisttext', 'parse', $lt, $bydate );
 175+ $wgOut->addHTML( $text . "\n" );
 176+ }
 177+
 178+ $sub = wfMsg( 'ilsubmit' );
 179+ $titleObj = SpecialPage::getTitleFor( 'NewVideos' );
 180+ $action = $titleObj->escapeLocalURL( $hidebots ? '' : 'hidebots=0' );
 181+ if( $shownav ) {
 182+ $wgOut->addHTML(
 183+ "<form id=\"imagesearch\" method=\"post\" action=\"{$action}\">" .
 184+ Xml::input( 'wpIlMatch', 20, $wpIlMatch ) . ' ' .
 185+ Xml::submitButton( $sub, array( 'name' => 'wpIlSubmit' ) ) .
 186+ '</form>'
 187+ );
 188+ }
 189+
 190+ /**
 191+ * Paging controls...
 192+ */
 193+
 194+ # If we change bot visibility, this needs to be carried along.
 195+ if( !$hidebots ) {
 196+ $botpar = array( 'hidebots' => 0 );
 197+ } else {
 198+ $botpar = array();
 199+ }
 200+ $now = wfTimestampNow();
 201+ $date = $wgLang->date( $now, true );
 202+ $time = $wgLang->time( $now, true );
 203+ $query = array_merge(
 204+ array( 'from' => $now ),
 205+ $botpar,
 206+ $searchpar
 207+ );
 208+
 209+ $dateLink = $sk->linkKnown(
 210+ $titleObj,
 211+ htmlspecialchars( wfMsgHtml( 'sp-newimages-showfrom', $date, $time ) ),
 212+ array(),
 213+ $query
 214+ );
 215+
 216+ $query = array_merge(
 217+ array( 'hidebots' => ( $hidebots ? 0 : 1 ) ),
 218+ $searchpar
 219+ );
 220+
 221+ $showhide = $hidebots ? wfMsg( 'show' ) : wfMsg( 'hide' );
 222+
 223+ $botLink = $sk->linkKnown(
 224+ $titleObj,
 225+ htmlspecialchars( wfMsg( 'showhidebots', $showhide ) ),
 226+ array(),
 227+ $query
 228+ );
 229+
 230+ $opts = array( 'parsemag', 'escapenoentities' );
 231+ $prevLink = wfMsgExt( 'pager-newer-n', $opts, $wgLang->formatNum( $limit ) );
 232+ if( $firstTimestamp && $firstTimestamp != $latestTimestamp ) {
 233+ $query = array_merge(
 234+ array( 'from' => $firstTimestamp ),
 235+ $botpar,
 236+ $searchpar
 237+ );
 238+ $prevLink = $sk->linkKnown(
 239+ $titleObj,
 240+ $prevLink,
 241+ array(),
 242+ $query
 243+ );
 244+ }
 245+
 246+ $nextLink = wfMsgExt( 'pager-older-n', $opts, $wgLang->formatNum( $limit ) );
 247+ if( $shownVideos > $limit && $lastTimestamp ) {
 248+ $query = array_merge(
 249+ array( 'until' => $lastTimestamp ),
 250+ $botpar,
 251+ $searchpar
 252+ );
 253+
 254+ $nextLink = $sk->linkKnown(
 255+ $titleObj,
 256+ $nextLink,
 257+ array(),
 258+ $query
 259+ );
 260+ }
 261+
 262+ $prevnext = '<p>' . $botLink . ' ' .
 263+ wfMsgHtml( 'viewprevnext', $prevLink, $nextLink, $dateLink ) .
 264+ '</p>';
 265+
 266+ if( $shownav ) {
 267+ $wgOut->addHTML( $prevnext );
 268+ }
 269+
 270+ if( count( $videos ) ) {
 271+ $wgOut->addHTML( $gallery->toHTML() );
 272+ if( $shownav ) {
 273+ $wgOut->addHTML( $prevnext );
 274+ }
 275+ } else {
 276+ $wgOut->addWikiMsg( 'video-no-videos' );
 277+ }
 278+ }
 279+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/SpecialNewVideos.php
___________________________________________________________________
Added: svn:eol-style
1280 + native
Index: trunk/extensions/Video/VideoPageArchive.php
@@ -0,0 +1,109 @@
 2+<?php
 3+/**
 4+ * A subclass of PageArchive for restoring deleted videos.
 5+ * Based on Bartek Łapiński's code.
 6+ *
 7+ * @file
 8+ */
 9+
 10+class VideoPageArchive extends PageArchive {
 11+
 12+ /**
 13+ * List the deleted file revisions for this video page.
 14+ * Returns a result wrapper with various oldvideo fields.
 15+ *
 16+ * @return ResultWrapper
 17+ */
 18+ function listFiles() {
 19+ $dbr = wfGetDB( DB_SLAVE );
 20+ $res = $dbr->select(
 21+ 'oldvideo',
 22+ array(
 23+ 'ov_name', 'ov_archive_name', 'ov_url', 'ov_type',
 24+ 'ov_user_id', 'ov_user_name', 'ov_timestamp'
 25+ ),
 26+ array( 'ov_name' => $this->title->getDBkey() ),
 27+ __METHOD__,
 28+ array( 'ORDER BY' => 'ov_timestamp DESC' )
 29+ );
 30+ $ret = $dbr->resultObject( $res );
 31+ return $ret;
 32+ }
 33+
 34+ /**
 35+ * Restore the given (or all) text and video revisions for the page.
 36+ * Once restored, the items will be removed from the archive tables.
 37+ * The deletion log will be updated with an undeletion notice.
 38+ *
 39+ * @param $timestamps Array: pass an empty array to restore all revisions,
 40+ * otherwise list the ones to undelete.
 41+ * @param $comment String: reason for undeleting
 42+ * @param $fileVersions Array
 43+ * @param $unsuppress Boolean: false by default
 44+ *
 45+ * @return array(number of file revisions restored, number of video revisions restored, log message)
 46+ * on success, false on failure
 47+ */
 48+ function undelete( $timestamps, $comment = '', $fileVersions = array(), $unsuppress = false ) {
 49+ // We currently restore only whole deleted videos, a restore link from
 50+ // log could take us here...
 51+ if ( $this->title->exists() ) {
 52+ return;
 53+ }
 54+
 55+ $dbw = wfGetDB( DB_MASTER );
 56+
 57+ $result = $dbw->select(
 58+ 'oldvideo',
 59+ '*',
 60+ array( 'ov_name' => $this->title->getDBkey() ),
 61+ __METHOD__,
 62+ array( 'ORDER BY' => 'ov_timestamp DESC' )
 63+ );
 64+
 65+ $insertBatch = array();
 66+ $insertCurrent = false;
 67+ $archiveName = '';
 68+ $first = true;
 69+
 70+ foreach ( $result as $row ) {
 71+ if( $first ) { // this is our new current revision
 72+ $insertCurrent = array(
 73+ 'video_name' => $row->ov_name,
 74+ 'video_url' => $row->ov_url,
 75+ 'video_type' => $row->ov_type,
 76+ 'video_user_id' => $row->ov_user_id,
 77+ 'video_user_name' => $row->ov_user_name,
 78+ 'video_timestamp' => $row->ov_timestamp
 79+ );
 80+ } else { // older revisions, they could be even elder current ones from ancient deletions
 81+ $insertBatch = array(
 82+ 'ov_name' => $row->ov_name,
 83+ 'ov_archive_name' => $archiveName,
 84+ 'ov_url' => $row->ov_url,
 85+ 'ov_type' => $row->ov_type,
 86+ 'ov_user_id' => $row->ov_user_id,
 87+ 'ov_user_name' => $row->ov_user_name,
 88+ 'ov_timestamp' => $row->ov_timestamp
 89+ );
 90+ }
 91+ $first = false;
 92+ }
 93+
 94+ unset( $result );
 95+
 96+ if ( $insertCurrent ) {
 97+ $dbw->insert( 'video', $insertCurrent, __METHOD__ );
 98+ }
 99+ if ( $insertBatch ) {
 100+ $dbw->insert( 'oldvideo', $insertBatch, __METHOD__ );
 101+ }
 102+
 103+ // run parent version, because it uses a private function inside
 104+ // files will not be touched anyway here, because it's not NS_FILE
 105+ parent::undelete( $timestamps, $comment, $fileVersions, $unsuppress );
 106+
 107+ return array( '', '', '' );
 108+ }
 109+
 110+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/VideoPageArchive.php
___________________________________________________________________
Added: svn:eol-style
1111 + native
Index: trunk/extensions/Video/Video.php
@@ -0,0 +1,121 @@
 2+<?php
 3+/**
 4+ * Wiki Video Namespace
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ * @version 1.3
 9+ * @author David Pean <david.pean@gmail.com> - original code/ideas
 10+ * @author Jack Phoenix <jack@countervandalism.net>
 11+ * @copyright Copyright © 2007 David Pean, Wikia Inc.
 12+ * @copyright Copyright © 2008-2011 Jack Phoenix
 13+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
 14+ * @link http://www.mediawiki.org/wiki/Extension:Video Documentation
 15+ */
 16+
 17+// Bail out if we're not inside MediaWiki
 18+if ( !defined( 'MEDIAWIKI' ) ) {
 19+ die( "This is not a valid entry point.\n" );
 20+}
 21+
 22+// Extension credits that show up on Special:Version
 23+$wgExtensionCredits['other'][] = array(
 24+ 'name' => 'Video',
 25+ 'version' => '1.3',
 26+ 'author' => array( 'David Pean', 'Jack Phoenix' ),
 27+ 'description' => 'Allows new Video namespace for embeddable media on supported sites',
 28+ 'url' => 'http://www.mediawiki.org/wiki/Extension:Video',
 29+);
 30+
 31+// ResourceLoader support for MediaWiki 1.17+
 32+$wgResourceModules['ext.video'] = array(
 33+ 'styles' => 'Video.css',
 34+ 'localBasePath' => dirname( __FILE__ ),
 35+ 'remoteExtPath' => 'Video'
 36+);
 37+
 38+// Global video namespace reference
 39+if( !defined( 'NS_VIDEO' ) ) {
 40+ define( 'NS_VIDEO', 400 );
 41+}
 42+
 43+if( !defined( 'NS_VIDEO_TALK' ) ) {
 44+ define( 'NS_VIDEO_TALK', 401 );
 45+}
 46+
 47+// Define permissions
 48+$wgAvailableRights[] = 'addvideo';
 49+$wgGroupPermissions['*']['addvideo'] = false;
 50+$wgGroupPermissions['user']['addvideo'] = true;
 51+
 52+// Set up i18n and autoload the gazillion different classes we have
 53+$dir = dirname( __FILE__ ) . '/';
 54+$wgExtensionMessagesFiles['Video'] = $dir . 'Video.i18n.php';
 55+$wgExtensionAliasesFiles['Video'] = $dir . 'Video.alias.php';
 56+// Namespace translations
 57+$wgExtensionMessagesFiles['VideoNamespaces'] = $dir . 'Video.namespaces.php';
 58+
 59+// Base Video class
 60+$wgAutoloadClasses['Video'] = $dir . 'VideoClass.php';
 61+
 62+// ...and the dozen different provider classes
 63+$wgAutoloadClasses['ArchiveOrgVideo'] = $dir . 'providers/ArchiveOrgVideo.php';
 64+$wgAutoloadClasses['BlipTVVideo'] = $dir . 'providers/BlipTVVideo.php';
 65+$wgAutoloadClasses['DailyMotionVideo'] = $dir . 'providers/DailyMotionVideo.php';
 66+$wgAutoloadClasses['FlashVideo'] = $dir . 'providers/FlashVideo.php';
 67+$wgAutoloadClasses['GametrailersVideo'] = $dir . 'providers/GametrailersVideo.php';
 68+$wgAutoloadClasses['GamevideosVideo'] = $dir . 'providers/GamevideosVideo.php';
 69+$wgAutoloadClasses['GoGreenTubeVideo'] = $dir . 'providers/GoGreenTubeVideo.php';
 70+$wgAutoloadClasses['GoogleVideo'] = $dir . 'providers/GoogleVideo.php';
 71+$wgAutoloadClasses['HuluVideo'] = $dir . 'providers/HuluVideo.php';
 72+$wgAutoloadClasses['MetaCafeVideo'] = $dir . 'providers/MetaCafeVideo.php';
 73+$wgAutoloadClasses['MySpaceVideo'] = $dir . 'providers/MySpaceVideo.php';
 74+$wgAutoloadClasses['MovieClipsVideo'] = $dir . 'providers/MovieClipsVideo.php';
 75+$wgAutoloadClasses['MyVideoVideo'] = $dir . 'providers/MyVideoVideo.php';
 76+$wgAutoloadClasses['NewsRoomVideo'] = $dir . 'providers/NewsRoomVideo.php';
 77+$wgAutoloadClasses['SevenloadVideo'] = $dir . 'providers/SevenloadVideo.php';
 78+$wgAutoloadClasses['SouthParkStudiosVideo'] = $dir . 'providers/SouthParkStudiosVideo.php';
 79+$wgAutoloadClasses['ViddlerVideo'] = $dir . 'providers/ViddlerVideo.php';
 80+$wgAutoloadClasses['VimeoVideo'] = $dir . 'providers/VimeoVideo.php';
 81+$wgAutoloadClasses['WeGameVideo'] = $dir . 'providers/WeGameVideo.php';
 82+$wgAutoloadClasses['YouTubeVideo'] = $dir . 'providers/YouTubeVideo.php';
 83+
 84+// User Interface stuff
 85+$wgAutoloadClasses['VideoPage'] = $dir . 'VideoPage.php';
 86+$wgAutoloadClasses['VideoHistoryList'] = $dir . 'VideoPage.php';
 87+$wgAutoloadClasses['CategoryWithVideoViewer'] = $dir . 'VideoPage.php';
 88+
 89+$wgAutoloadClasses['VideoGallery'] = $dir . 'VideoGallery.php';
 90+
 91+// Class for undeleting previously deleted videos
 92+$wgAutoloadClasses['VideoPageArchive'] = $dir . 'VideoPageArchive.php';
 93+
 94+// New special pages
 95+$wgAutoloadClasses['AddVideo'] = $dir . 'SpecialAddVideo.php';
 96+$wgAutoloadClasses['NewVideos'] = $dir . 'SpecialNewVideos.php';
 97+$wgSpecialPages['AddVideo'] = 'AddVideo';
 98+$wgSpecialPages['NewVideos'] = 'NewVideos';
 99+// Special page groups for MW 1.13+
 100+$wgSpecialPageGroups['AddVideo'] = 'media';
 101+$wgSpecialPageGroups['NewVideos'] = 'changes';
 102+
 103+// Hook things up
 104+$wgAutoloadClasses['VideoHooks'] = $dir . 'VideoHooks.php';
 105+
 106+$wgHooks['ArticleFromTitle'][] = 'VideoHooks::videoFromTitle';
 107+$wgHooks['CategoryPageView'][] = 'VideoHooks::categoryPageWithVideo';
 108+$wgHooks['ParserBeforeStrip'][] = 'VideoHooks::videoTag';
 109+$wgHooks['ParserFirstCallInit'][] = 'VideoHooks::registerVideoHook';
 110+$wgHooks['ArticleDelete'][] = 'VideoHooks::onVideoDelete';
 111+$wgHooks['UndeleteForm::showRevision'][] = 'VideoHooks::specialUndeleteSwitchArchive';
 112+$wgHooks['UndeleteForm::showHistory'][] = 'VideoHooks::specialUndeleteSwitchArchive';
 113+$wgHooks['UndeleteForm::undelete'][] = 'VideoHooks::specialUndeleteSwitchArchive';
 114+$wgHooks['LoadExtensionSchemaUpdates'][] = 'VideoHooks::addTables';
 115+$wgHooks['RenameUserSQL'][] = 'VideoHooks::onUserRename'; // For the Renameuser extension
 116+$wgHooks['CanonicalNamespaces'][] = 'VideoHooks::onCanonicalNamespaces';
 117+
 118+// Set up logging
 119+$wgLogTypes[] = 'video';
 120+$wgLogNames['video'] = 'video-log-page';
 121+$wgLogHeaders['video'] = 'video-log-page-text';
 122+$wgLogActions['video/video'] = 'video-log-entry';
\ No newline at end of file
Property changes on: trunk/extensions/Video/Video.php
___________________________________________________________________
Added: svn:eol-style
1123 + native
Index: trunk/extensions/Video/ReadMe
@@ -0,0 +1,88 @@
 2+VIDEO NAMESPACE FOR MEDIAWIKI
 3+
 4+1. Overview
 5+2. Requirements
 6+3. Installing Video Extension
 7+4. New Special Pages
 8+5. New User Rights
 9+6. Bug Reports and More
 10+7. Credits
 11+
 12+==1. Overview==
 13+The video namespace facilitates creation and displaying of new video
 14+description pages that contain embeddable flash videos.
 15+
 16+It introduces the [[Video:Name]] MediaWiki markup (and <video name="Name"/>)
 17+
 18+Also allows functionality for Video Galleries (similar to <gallery>) and
 19+showing Videos in category pages.
 20+
 21+==2. Requirements==
 22+The '''Video Namespace''' extension requires MediaWiki 1.16.0 or greater.
 23+
 24+r88235 (or greater) is required for proper undeletion support. Without that
 25+revision, videos cannot be undeleted properly; only the video page is
 26+undeleted, the actual video will be gone forever without that patch.
 27+
 28+==3. Installing Video Extension==
 29+Installing the Video extension is very easy if you have shell (SSH) access to
 30+your server.
 31+
 32+You should run video.sql against the database with a command like
 33+mysql -u DATABASE_USER -p DATABASE_NAME < video.sql
 34+in your terminal window to generate the two necessary tables, oldvideo and video.
 35+Alternatively, you can add the require_once() line below into the wiki's
 36+LocalSettings.php and then run maintenance/update.php to create the two tables.
 37+
 38+If you don't have shell access, you should copy the contents of video.sql and
 39+paste them into phpMyAdmin's SQL prompt to create the tables.
 40+
 41+Then add the following into your wiki's LocalSettings.php:
 42+
 43+require_once("$IP/extensions/Video/Video.php");
 44+
 45+==4. New Special Pages==
 46+Video extension introduces two new special pages, Special:AddVideo and Special:NewVideos.
 47+
 48+Special:AddVideo is used to add a video and Special:NewVideos displays a list
 49+of newly added videos à la Special:NewFiles.
 50+
 51+==5. New User Rights==
 52+Video extension introduces one new user right, 'addvideo'.
 53+Users with the addvideo right can upload videos through Special:AddVideo.
 54+By default, all registered users are given this right.
 55+
 56+The 'reupload' user right is required to upload new videos of pre-existing
 57+videos.
 58+
 59+In addition, everyone is able to view Special:NewVideos special page.
 60+
 61+==6. Bug Reports and More==
 62+You can report software bugs on this extension's talk page at MediaWiki.org:
 63+
 64+http://www.mediawiki.org/w/index.php?title=Extension_talk:Video&action=edit&section=new
 65+
 66+The most up-to-date Video extension documentation can always be found at MediaWiki.org:
 67+
 68+http://www.mediawiki.org/wiki/Extension:Video
 69+
 70+==7. Credits==
 71+The initial idea and coding was done by David Pean <david.pean@gmail.com>.
 72+
 73+Łukasz 'TOR' Garczewski <tor@wikia-inc.com> rewrote Special:AddVideo.
 74+
 75+Bartek Łapiński <bartek@wikia-inc.com> made a couple small bugfixes and
 76+participated in the development of WikiaVideo extension, which was forked from
 77+this extension.
 78+
 79+Przemek Piotrowski <ppiotr@wikia-inc.com> wrote the YouTube extension, from
 80+which a lot of code for various different video providers was extracted. Thanks
 81+to him, we can embed media from Archive.org, Gametrailers.com, GoGreenTube.com
 82+and WeGame.com.
 83+
 84+Jack Phoenix <jack@countervandalism.net> performed code cleanup and wrote the
 85+code for deleting videos and improved the undeletion code, ported a bunch of
 86+providers from the YouTube extension and tweaked internationalization messages.
 87+
 88+William Lee <wlee@wikia-inc.com> wrote some code for the WikiaVideo extension,
 89+which was used to build providers/HuluVideo.php.
\ No newline at end of file
Index: trunk/extensions/Video/Video.css
@@ -0,0 +1,24 @@
 2+/* CSS for Video extension */
 3+.video-error {
 4+ color: #ff0000;
 5+ font-size: 16px;
 6+ font-weight: bold;
 7+}
 8+
 9+.page-nav a {
 10+ font-weight: bold;
 11+}
 12+
 13+.page-nav {
 14+ margin-top: 10px;
 15+ margin-bottom: 10px;
 16+}
 17+
 18+#categorysearch {
 19+ margin-top: 5px;
 20+ margin-bottom: 5px;
 21+}
 22+
 23+#wpVideo {
 24+ width: 500px;
 25+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/Video.css
___________________________________________________________________
Added: svn:eol-style
126 + native
Index: trunk/extensions/Video/VideoHooks.php
@@ -0,0 +1,328 @@
 2+<?php
 3+/**
 4+ * Class that contains all Video extension's hooked functions.
 5+ * All functions are naturally public and static (what were you expecting?).
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+class VideoHooks {
 11+
 12+ /**
 13+ * Convert [[Video:Video Name]] tags to <video/> hook; calls
 14+ * VideoHooks::renderVideo to do that.
 15+ *
 16+ * @param $parser Object: instance of Parser
 17+ * @param $text String: input text to search for [[Video:]] tags
 18+ * @param $strip_state [unused]
 19+ * @return Boolean: true
 20+ */
 21+ public static function videoTag( &$parser, &$text, &$strip_state ) {
 22+ global $wgContLang;
 23+ $localizedVideoName = $wgContLang->getNsText( NS_VIDEO );
 24+ // Fallback code...is this needed?
 25+ if ( $localizedVideoName === false ) {
 26+ $localizedVideoName = 'Video';
 27+ }
 28+ $pattern = '@(\[\[' . $localizedVideoName . ':)([^\]]*?)].*?\]@si';
 29+ $text = preg_replace_callback( $pattern, 'VideoHooks::renderVideo', $text );
 30+ return true;
 31+ }
 32+
 33+ /**
 34+ * Callback function for the preg_replace_callback call in
 35+ * VideoHooks::videoTag.
 36+ * Converts [[Video:]] links to <video> parser hooks.
 37+ */
 38+ public static function renderVideo( $matches ) {
 39+ $name = $matches[2];
 40+ $params = explode( '|', $name );
 41+ $video_name = $params[0];
 42+ $video = Video::newFromName( $video_name );
 43+ $x = 1;
 44+
 45+ foreach( $params as $param ) {
 46+ if( $x > 1 ) {
 47+ $width_check = preg_match( '/px/i', $param );
 48+
 49+ if( $width_check ) {
 50+ $width = preg_replace( '/px/i', '', $param );
 51+ } else {
 52+ $align = $param;
 53+ }
 54+ }
 55+ $x++;
 56+ }
 57+
 58+ if ( is_object( $video ) ) {
 59+ if( $video->exists() ) {
 60+ $widthTag = $alignTag = '';
 61+ if ( !empty( $width ) ) {
 62+ $widthTag = " width=\"{$width}\"";
 63+ }
 64+ if ( !empty( $align ) ) {
 65+ $alignTag = " align=\"{$align}\"";
 66+ }
 67+ $output = "<video name=\"{$video->getName()}\"{$widthTag}{$alignTag} />";
 68+ return $output;
 69+ }
 70+ return $matches[0];
 71+ }
 72+ }
 73+
 74+ /**
 75+ * Calls VideoPage instead of standard Article for pages in the NS_VIDEO
 76+ * namespace.
 77+ *
 78+ * @param $title Object: Title object for the current page
 79+ * @param $article Object: Article object for the current page
 80+ * @return Boolean: true
 81+ */
 82+ function videoFromTitle( &$title, &$article ) {
 83+ global $wgRequest;
 84+
 85+ if ( $title->getNamespace() == NS_VIDEO ) {
 86+ if( $wgRequest->getVal( 'action' ) == 'edit' ) {
 87+ $addTitle = SpecialPage::getTitleFor( 'AddVideo' );
 88+ $video = Video::newFromName( $title->getText() );
 89+ if( !$video->exists() ) {
 90+ global $wgOut;
 91+ $wgOut->redirect(
 92+ // escapeFullURL() converts & to &amp; which causes the
 93+ // destName parameter not to work correctly
 94+ $addTitle->getFullURL( 'destName=' . $video->getName() )
 95+ );
 96+ }
 97+ }
 98+ $article = new VideoPage( $title );
 99+ }
 100+
 101+ return true;
 102+ }
 103+
 104+ /**
 105+ * Register the new <video> hook with MediaWiki's parser.
 106+ *
 107+ * @param $parser Object: instance of Parser
 108+ * @return Boolean: true
 109+ */
 110+ public static function registerVideoHook( &$parser ) {
 111+ $parser->setHook( 'video', 'VideoHooks::videoEmbed' );
 112+ return true;
 113+ }
 114+
 115+ /**
 116+ * Callback function for VideoHooks::registerVideoHook.
 117+ *
 118+ * @param $input [unused]
 119+ * @param $argv Array: array or user-supplied arguments; name must be present.
 120+ * Optional args include width, height and align.
 121+ * @param $parser Object: instance of parser
 122+ * @return String
 123+ */
 124+ public static function videoEmbed( $input, $argv, $parser ) {
 125+ $video_name = $argv['name'];
 126+ if( !$video_name ) {
 127+ return '';
 128+ }
 129+
 130+ $width = $width_max = 425;
 131+ $height = $height_max = 350;
 132+ $validAlign = array( 'LEFT', 'CENTER', 'RIGHT' );
 133+
 134+ if( !empty( $argv['width'] ) && ( $width_max >= $argv['width'] ) ) {
 135+ $width = $argv['width'];
 136+ }
 137+
 138+ if( !empty( $argv['height'] ) && ( $height_max >= $argv['height'] ) ) {
 139+ $height = $argv['height'];
 140+ }
 141+
 142+ $align = isset( $argv['align'] ) ? $argv['align'] : 'left';
 143+ $alignTag = '';
 144+
 145+ if( in_array( strtoupper( $align ), $validAlign ) ) {
 146+ $alignTag = " class=\"float{$align}\" ";
 147+ }
 148+
 149+ $output = '';
 150+ $video = Video::newFromName( $video_name );
 151+ if( $video->exists() ) {
 152+ $video->setWidth( $width );
 153+ $video->setHeight( $height );
 154+
 155+ $output .= "<div{$alignTag}>";
 156+ $output .= $video->getEmbedCode();
 157+ $output .= '</div>';
 158+ }
 159+
 160+ return $output;
 161+ }
 162+
 163+ /**
 164+ * Injects Video Gallery into Category pages
 165+ *
 166+ * @param $cat Object: CategoryPage object
 167+ * @return Boolean: false
 168+ */
 169+ public static function categoryPageWithVideo( &$cat ) {
 170+ $article = new Article( $cat->mTitle );
 171+ $article->view();
 172+
 173+ if ( $cat->mTitle->getNamespace() == NS_CATEGORY ) {
 174+ global $wgOut, $wgRequest;
 175+ $from = $wgRequest->getVal( 'from' );
 176+ // @todo CHECKME/FIXME: is this correct? I just added something
 177+ // here to prevent an E_NOTICE about an undefined variable...
 178+ $until = $wgRequest->getVal( 'until' );
 179+
 180+ $viewer = new CategoryWithVideoViewer( $cat->mTitle, $from, $until );
 181+ $wgOut->addHTML( $viewer->getHTML() );
 182+ }
 183+
 184+ return false;
 185+ }
 186+
 187+ /**
 188+ * Called on video deletion; this is the main logic for deleting videos.
 189+ * There is no logic related to video deletion on the VideoPage class.
 190+ *
 191+ * @param $articleObj Object: instance of Article or its subclass
 192+ * @param $user Object: current User object ($wgUser)
 193+ * @param $reason String: reason for the deletion [unused]
 194+ * @param $error String: error message, if any [unused]
 195+ * @return Boolean: true
 196+ */
 197+ public static function onVideoDelete( &$articleObj, &$user, &$reason, &$error ) {
 198+ if ( $articleObj->getTitle()->getNamespace() == NS_VIDEO ) {
 199+ global $wgRequest;
 200+
 201+ $videoObj = new Video( $articleObj->getTitle() );
 202+ $videoName = $videoObj->getName();
 203+ $oldVideo = $wgRequest->getVal( 'wpOldVideo', false );
 204+ $where = array(
 205+ 'video_name' => $videoName
 206+ );
 207+ /*
 208+ BEWARE! THIS DOES NOT WORK HOW YOU WOULD THINK IT DOES...
 209+ IT GENERATES INVALID SQL LIKE video_name = \'(Ayumi_Hamasaki_-_Ladies_Night) OR (Video:Ayumi Hamasaki - Ladies Night)\'
 210+ AND GENERALLY CAUSES THINGS TO EXPLODE!
 211+ $where = array(
 212+ 'video_name' => $dbw->makeList( array(
 213+ $articleObj->getTitle()->getDBkey(),
 214+ $articleObj->getTitle()->getPrefixedText()
 215+ ), LIST_OR )
 216+ );
 217+ */
 218+ if ( !empty( $oldVideo ) ) {
 219+ $where['video_timestamp'] = $oldVideo;
 220+ }
 221+
 222+ $dbw = wfGetDB( DB_MASTER );
 223+ // Delicious copypasta from Article.php, function doDeleteArticle()
 224+ // with some modifications
 225+ $archiveName = gmdate( 'YmdHis' ) . "!{$videoName}";
 226+ $dbw->begin();
 227+ $dbw->insertSelect(
 228+ 'oldvideo',
 229+ 'video',
 230+ array(
 231+ 'ov_name' => 'video_name',
 232+ 'ov_archive_name' => $dbw->addQuotes( $archiveName ),
 233+ 'ov_url' => 'video_url',
 234+ 'ov_type' => 'video_type',
 235+ 'ov_user_id' => 'video_user_id',
 236+ 'ov_user_name' => 'video_user_name',
 237+ 'ov_timestamp' => 'video_timestamp'
 238+ ),
 239+ $where,
 240+ __METHOD__
 241+ );
 242+
 243+ // Now that it's safely backed up, delete it
 244+ $dbw->delete(
 245+ 'video',
 246+ $where,
 247+ __METHOD__
 248+ );
 249+
 250+ $dbw->commit();
 251+
 252+ // Purge caches
 253+ // None of these help, the video is still displayed on pages where
 254+ // it was used until someone edits or does ?action=purge :-(
 255+ /*
 256+ $articleObj->getTitle()->invalidateCache();
 257+ $articleObj->getTitle()->purgeSquid();
 258+ $articleObj->doPurge();
 259+ global $wgMemc;
 260+ $wgMemc->delete( $videoObj->getCacheKey() );
 261+ */
 262+ }
 263+
 264+ // Continue deleting stuff
 265+ return true;
 266+ }
 267+
 268+ /**
 269+ * Use VideoPageArchive class to properly restore deleted Video pages.
 270+ * Standard PageArchive allows only to restore the wiki page, not the
 271+ * associated video.
 272+ *
 273+ * @param $archive Object: PageArchive object or a child class
 274+ * @param $title Object: Title object for the current page that we're about
 275+ * to undelete or view
 276+ * @return Boolean: true
 277+ */
 278+ public static function specialUndeleteSwitchArchive( $archive, $title ) {
 279+ if ( $title->getNamespace() == NS_VIDEO ) {
 280+ $archive = new VideoPageArchive( $title );
 281+ }
 282+ return true;
 283+ }
 284+
 285+ /**
 286+ * Applies the schema changes when the user runs maintenance/update.php.
 287+ *
 288+ * @param $updater
 289+ * @return Boolean: true
 290+ */
 291+ public static function addTables( $updater = null ) {
 292+ $dir = dirname( __FILE__ );
 293+ $file = "$dir/video.sql";
 294+ if ( $updater === null ) {
 295+ global $wgExtNewTables;
 296+ $wgExtNewTables[] = array( 'video', $file );
 297+ $wgExtNewTables[] = array( 'oldvideo', $file );
 298+ } else {
 299+ $updater->addExtensionUpdate( array( 'addTable', 'video', $file, true ) );
 300+ $updater->addExtensionUpdate( array( 'addTable', 'oldvideo', $file, true ) );
 301+ }
 302+ return true;
 303+ }
 304+
 305+ /**
 306+ * For the Renameuser extension.
 307+ *
 308+ * @param $renameUserSQL
 309+ * @return Boolean: true
 310+ */
 311+ public static function onUserRename( $renameUserSQL ) {
 312+ $renameUserSQL->tables['oldvideo'] = array( 'ov_user_name', 'ov_user_id' );
 313+ $renameUserSQL->tables['video'] = array( 'video_user_name', 'video_user_id' );
 314+ return true;
 315+ }
 316+
 317+ /**
 318+ * Register the canonical names for our namespace and its talkspace.
 319+ *
 320+ * @param $list Array: array of namespace numbers with corresponding
 321+ * canonical names
 322+ * @return Boolean: true
 323+ */
 324+ public static function onCanonicalNamespaces( &$list ) {
 325+ $list[NS_VIDEO] = 'Video';
 326+ $list[NS_VIDEO_TALK] = 'Video_talk';
 327+ return true;
 328+ }
 329+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/VideoHooks.php
___________________________________________________________________
Added: svn:eol-style
1330 + native
Index: trunk/extensions/Video/video.sql
@@ -0,0 +1,25 @@
 2+-- Table that contains information about the deleted videos
 3+CREATE TABLE /*_*/oldvideo (
 4+ `ov_name` varchar(255) NOT NULL default '',
 5+ `ov_archive_name` varchar(255) NOT NULL default '',
 6+ `ov_url` varchar(255) NOT NULL default '',
 7+ `ov_type` varchar(255) default 'unknown',
 8+ `ov_user_id` int(11) NOT NULL default '0',
 9+ `ov_user_name` varchar(255) NOT NULL default '',
 10+ `ov_timestamp` varchar(14) NOT NULL default ''
 11+)/*$wgDBTableOptions*/;
 12+
 13+CREATE INDEX /*i*/ov_name ON /*_*/oldvideo (ov_name);
 14+CREATE INDEX /*i*/ov_timestamp ON /*_*/oldvideo (ov_timestamp);
 15+
 16+-- Table that contains information about all the active videos
 17+CREATE TABLE /*_*/video (
 18+ `video_name` varchar(255) NOT NULL PRIMARY KEY default '',
 19+ `video_url` varchar(255) NOT NULL default '',
 20+ `video_type` varchar(255) default 'unknown',
 21+ `video_user_id` int(11) NOT NULL default '0',
 22+ `video_user_name` varchar(255) NOT NULL default '',
 23+ `video_timestamp` varchar(14) NOT NULL default ''
 24+)/*$wgDBTableOptions*/;
 25+
 26+CREATE INDEX /*i*/video_timestamp ON /*_*/video (video_timestamp);
\ No newline at end of file
Property changes on: trunk/extensions/Video/video.sql
___________________________________________________________________
Added: svn:eol-style
127 + native
Index: trunk/extensions/Video/SpecialAddVideo.php
@@ -0,0 +1,167 @@
 2+<?php
 3+
 4+class AddVideo extends SpecialPage {
 5+
 6+ /**
 7+ * Constructor -- set up the new special page
 8+ */
 9+ public function __construct() {
 10+ parent::__construct( 'AddVideo' /*class*/, 'addvideo' /*restriction*/);
 11+ }
 12+
 13+ /**
 14+ * Show the special page
 15+ *
 16+ * @param $par Mixed: parameter passed to the page or null
 17+ */
 18+ public function execute( $par ) {
 19+ global $wgRequest, $wgOut, $wgUser, $wgScriptPath;
 20+
 21+ // Add CSS
 22+ if ( defined( 'MW_SUPPORTS_RESOURCE_MODULES' ) ) {
 23+ $wgOut->addModuleStyles( 'ext.video' );
 24+ } else {
 25+ $wgOut->addExtensionStyle( $wgScriptPath . '/extensions/Video/Video.css' );
 26+ }
 27+
 28+ // If the user doesn't have the required 'addvideo' permission, display an error
 29+ if( !$wgUser->isAllowed( 'addvideo' ) ) {
 30+ $wgOut->permissionRequired( 'addvideo' );
 31+ return;
 32+ }
 33+
 34+ // Show a message if the database is in read-only mode
 35+ if ( wfReadOnly() ) {
 36+ $wgOut->readOnlyPage();
 37+ return;
 38+ }
 39+
 40+ // If user is blocked, s/he doesn't need to access this page
 41+ if( $wgUser->isBlocked() ) {
 42+ $wgOut->blockedPage( false );
 43+ return false;
 44+ }
 45+
 46+ $categories = $wgRequest->getVal( 'wpCategories' );
 47+
 48+ // wpDestName URL parameter is set in VideoPage.php; when viewing a
 49+ // video page of a video that does not yet exist, there is a link to
 50+ // Special:AddVideo and the wpDestName parameter will be set to the
 51+ // name of the video
 52+ $destination = $wgRequest->getVal( 'destName' );
 53+ if( !$destination ) {
 54+ $destination = $wgRequest->getVal( 'wpDestName' );
 55+ }
 56+
 57+ // Posted items
 58+ $video_code = $wgRequest->getVal( 'wpVideo' );
 59+ $title = str_replace( '#', '', $wgRequest->getVal( 'wpTitle' ) );
 60+
 61+ $pageTitle = wfMsg( 'video-addvideo-title' );
 62+ if( $destination ) {
 63+ $pageTitle = wfMsg( 'video-addvideo-dest', str_replace( '_', ' ', $destination ) );
 64+ }
 65+
 66+ $wgOut->setPageTitle( $pageTitle );
 67+
 68+ if( $destination ) {
 69+ $title = $destination;
 70+ }
 71+
 72+ $output = '<div class="add-video-container">
 73+ <form name="videoadd" action="" method="post">';
 74+
 75+ $output .= '<p class="addvideo-subtitle">' .
 76+ wfMsgExt( 'video-addvideo-instructions', 'parse' ) . '</p>';
 77+ $output .= '<table border="0" cellpadding="3" cellspacing="5">';
 78+ $output .= '<tr>';
 79+
 80+ // If we're not adding a new version of a pre-existing video, allow the
 81+ // user to supply the video's title, obviously...
 82+ if( !$destination ) {
 83+ $output .= '<td><label for="wpTitle">' .
 84+ wfMsgHtml( 'video-addvideo-title-label' ) .
 85+ '</label></td><td>';
 86+
 87+ $output .= Xml::element( 'input',
 88+ array(
 89+ 'type' => 'text',
 90+ 'name' => 'wpTitle',
 91+ 'size' => '30',
 92+ 'value' => $wgRequest->getVal( 'wpTitle' ),
 93+ )
 94+ );
 95+ $output .= '</td></tr>';
 96+ }
 97+
 98+ $watchChecked = $wgUser->getOption( 'watchdefault' )
 99+ ? ' checked="checked"'
 100+ : '';
 101+
 102+ $output .= '<tr>
 103+ <td valign="top">' . wfMsg( 'video-addvideo-embed-label' ) . '</td>
 104+ <td><textarea rows="5" cols="65" name="wpVideo" id="wpVideo">' .
 105+ $wgRequest->getVal( 'wpVideo' ) .
 106+ '</textarea></td>
 107+ </tr>
 108+ <tr>
 109+ <td></td>
 110+ <td>
 111+ <input type="checkbox" name="wpWatchthis" id="wpWatchthis"' . $watchChecked . ' value="true" />
 112+ <label for="wpWatchthis">' . wfMsgHtml( 'watchthisupload' ) . '</label>
 113+
 114+ </td>
 115+ </tr>';
 116+
 117+ $output .= '<tr>
 118+ <td></td>
 119+ <td>';
 120+ $output .= Xml::element( 'input',
 121+ array(
 122+ 'type' => 'button',
 123+ 'value' => wfMsg( 'video-addvideo-button' ),
 124+ 'onclick' => 'document.videoadd.submit();',
 125+ )
 126+ );
 127+ $output .= '</td>
 128+ </tr>
 129+ </table>
 130+ </form>
 131+ </div>';
 132+
 133+ if( $wgRequest->wasPosted() ) {
 134+ $video = Video::newFromName( $title );
 135+
 136+ // Page title for Video has already been taken
 137+ if( $video->exists() && !$destination ) {
 138+ $error = '<div class="video-error">' .
 139+ wfMsgHtml( 'video-addvideo-exists' ) . '</div>';
 140+ $wgOut->addHTML( $error );
 141+ } else {
 142+ // Get URL based on user input
 143+ // It could be a straight URL to the page or the embed code
 144+ if ( $video->isURL( $video_code ) ) {
 145+ $url = $video_code;
 146+ } else {
 147+ $urlFromEmbed = $video->getURLfromEmbedCode( $video_code );
 148+ if ( $video->isURL( $urlFromEmbed ) ) {
 149+ $url = $urlFromEmbed;
 150+ }
 151+ }
 152+ $provider = $video->getProviderByURL( $url );
 153+ if( !$url || $provider == 'unknown' ) {
 154+ $error = '<div class="video-error">' .
 155+ wfMsg( 'video-addvideo-invalidcode' ) . '</div>';
 156+ $wgOut->addHTML( $error );
 157+ } else {
 158+ $video->addVideo(
 159+ $url, $provider, $categories,
 160+ $wgRequest->getVal( 'wpWatchthis' )
 161+ );
 162+ $wgOut->redirect( $video->title->getFullURL() );
 163+ }
 164+ }
 165+ }
 166+ $wgOut->addHTML( $output );
 167+ }
 168+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/SpecialAddVideo.php
___________________________________________________________________
Added: svn:eol-style
1169 + native
Index: trunk/extensions/Video/Video.i18n.php
@@ -0,0 +1,158 @@
 2+<?php
 3+/**
 4+ * Internationalization file for the Video extension.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author David Pean <david.pean@gmail.com>
 14+ */
 15+$messages['en'] = array(
 16+ // Special page titles, as seen on Special:SpecialPages
 17+ 'addvideo' => 'Add Video',
 18+ 'newvideos' => 'New Videos',
 19+
 20+ // Various Special:AddVideo UI messages
 21+ 'video-addvideo-title' => 'Add Video',
 22+ 'video-addvideo-dest' => 'Add Video for $1',
 23+ 'video-addvideo-button' => 'Add Video',
 24+ 'video-provider-list' => '*[http://www.youtube.com/ YouTube]
 25+*[http://vids.myspace.com/ MySpaceTV]
 26+*[http://video.google.com/ Google Video]
 27+*[http://www.metacafe.com/ Metacafe]
 28+*[http://archive.org/ Archive.org]
 29+*[http://blip.tv/ Blip.tv]
 30+*[http://www.dailymotion.com/ Dailymotion]
 31+*[http://www.gametrailers.com Gametrailers]
 32+*[http://gamevideos.1up.com/ Gamevideos]
 33+*[http://www.gogreentube.com/ GoGreenTube]
 34+*[http://www.hulu.com/ Hulu]
 35+*[http://www.myvideo.de/ MyVideo]
 36+*[http://movieclips.com/ MovieClips]
 37+*[http://www.sevenload.com/ Sevenload]
 38+*[http://www.southparkstudios.com/ South Park Studios]
 39+*[http://www.viddler.com/ Viddler]
 40+*[http://www.vimeo.com/ Vimeo]
 41+*[http://www.wegame.com/ WeGame]', // list of all available video providers; used in the msg below; do not translate!
 42+ 'video-addvideo-instructions' => "Adding a video to {{SITENAME}} is easy.
 43+Just paste the video embed code ''or'' the video's URL into the following form, add a name for the video, and press the \"{{int:video-addvideo-button}}\" button.
 44+If you want to embed the video on a page use the following format: '''<nowiki>[[Video:Video Title]]</nowiki>'''.
 45+You can add a video from the following providers:
 46+{{int:video-provider-list}}
 47+===Example of a Video Embed Code===
 48+This is an example video embed code from YouTube:
 49+
 50+<pre style=\"background-color: #F9F9F9; border: 1px dashed #2F6FAB; color: black; line-height: 1.1em; padding: 1em;\">
 51+<nowiki><object width=\"425\" height=\"355\">
 52+<param name=\"movie\" value=\"http://www.youtube.com/v/hUcFWPgB8oY\"></param>
 53+<param name=\"wmode\" value=\"transparent\"></param>
 54+<embed src=\"http://www.youtube.com/v/hUcFWPgB8oY\" type=\"application/x-shockwave-flash\"
 55+wmode=\"transparent\" width=\"425\" height=\"355\"></embed>
 56+</object></nowiki>
 57+</pre>
 58+
 59+===Example of a Video URL===
 60+Below is an example of a video's URL from YouTube:
 61+<pre style=\"background-color: #F9F9F9; border: 1px dashed #2F6FAB; color: black; line-height: 1.1em; padding: 1em;\">http://www.youtube.com/watch?v=hUcFWPgB8oY</pre>",
 62+ 'video-addvideo-invalidcode' => 'The code or URL you pasted is invalid. Please try again.',
 63+ 'video-addvideo-exists' => 'The title for your video already exists. Please choose another title for the video.',
 64+ 'video-addvideo-title-label' => 'Video Title:',
 65+ 'video-addvideo-embed-label' => 'Embed Code or URL:',
 66+
 67+ // Shown on Special:NewVideos when it's empty
 68+ 'video-no-videos' => 'No new videos.',
 69+
 70+ // Log of added videos at Special:Log/video
 71+ 'video-log-page' => 'Video log',
 72+ 'video-log-page-text' => 'This is a log of added videos and updates to existing videos.',
 73+ 'video-log-entry' => '', # do not translate this into other languages!
 74+ 'video-log-added-entry' => 'added video [[$1]]',
 75+ 'video-log-updated-entry' => 'updated video [[$1]]',
 76+
 77+ // Shown on category pages
 78+ 'category-video-header' => 'Videos in category "$1"',
 79+ #'category-video-count' => '{{PLURAL:$2|This category contains only the following video.|The following {{PLURAL:$1|video is|$1 videos are}} in this category, out of $2 total.}}',
 80+ 'category-video-count' => 'There {{PLURAL:$1|is one video|are $1 videos}} in this category.',
 81+
 82+ 'video-novideo-linktext' => 'add it',
 83+ 'video-novideo' => 'No video by this name exists, you can $1.', // $1 is novideo-linktext
 84+ 'video-embed' => 'Embed',
 85+ 'video-history' => 'Video History',
 86+ 'video-revert' => 'rev',
 87+ 'video-histlegend' => 'Legend: ({{int:cur}}) = this is the current video, ({{int:video-revert}}) = revert to this old version.
 88+<br /><i>Click on date to see the video URL on that date</i>.',
 89+ 'video-revert-success' => 'Revert to earlier version was successful.',
 90+
 91+ 'video-category-name' => 'Videos', // name of the category where videos will be stored
 92+
 93+ // Pages linking to the current video -- this feature does not work (yet), see
 94+ // VideoPage::videoLinks() for details
 95+ 'video-links' => 'Video links',
 96+ 'video-links-to-video' => 'The following {{PLURAL:$1|page links|$1 pages link}} to this video:',
 97+ 'video-no-links-to-video' => 'There are no pages that link to this video.',
 98+ 'video-more-links-to-video' => 'View [[Special:WhatLinksHere/$1|more links]] to this video.',
 99+
 100+ // For Special:ListGroupRights
 101+ 'right-addvideo' => 'Add videos from external services into the site',
 102+);
 103+
 104+/** Finnish (Suomi)
 105+ * @author Jack Phoenix <jack@countervandalism.net>
 106+ */
 107+$messages['fi'] = array(
 108+ 'addvideo' => 'Lisää video',
 109+ 'newvideos' => 'Uudet videot',
 110+ 'video-no-videos' => 'Ei uusia videoja.',
 111+ 'video-log-page' => 'Videoloki',
 112+ 'video-log-page-text' => 'Tämä on loki lisätyistä videoista ja päivityksistä olemassaoleviin videoihin.',
 113+ 'video-log-added-entry' => 'lisäsi videon [[$1]]',
 114+ 'video-log-updated-entry' => 'päivitti videon [[$1]]',
 115+ 'category-video-header' => 'Videot luokassa "$1"',
 116+ 'category-video-count' => 'Tässä luokassa on {{PLURAL:$1|yksi video|$1 videoa}}.',
 117+ #'category-video-count' => '{{PLURAL:$2|Tässä luokassa on vain seuraava video.|{{PLURAL:$1|Seuraava video kuuluu|Seuraavat $1 videoa kuuluvat}} tähän luokkaan. Sivujen kokonaismäärä luokassa on $2.}}',
 118+ 'video-novideo' => 'Tämännimistä videoa ei ole olemassa, voit $1.',
 119+ 'video-novideo-linktext' => 'lisätä sen',
 120+ 'video-embed' => 'Upota',
 121+ 'video-addvideo-title' => 'Lisää video',
 122+ 'video-addvideo-dest' => 'Lisää uusi versio videosta $1', // "Add a new version of video $1"
 123+ 'video-addvideo-button' => 'Lisää video',
 124+ 'video-addvideo-instructions' => "Videon lisääminen {{GRAMMAR:illative|{{SITENAME}}}} on helppoa.
 125+Liitä vain videon upotuskoodi ''tai'' videon URL seuraavaan lomakkeeseen, lisää nimi videolle ja paina \"{{int:video-addvideo-button}}\" -painiketta.
 126+Jos haluat upottaa videon sivulle, käytä seuraavaa muotoa: '''<nowiki>[[Video:Videon otsikko]]</nowiki>'''.
 127+Voit lisätä videoita seuraavista palveluista:
 128+{{int:video-provider-list}}
 129+===Esimerkki videon upotuskoodista===
 130+Tämä on esimerkki videon upotuskoodista YouTubesta:
 131+
 132+<pre style=\"background-color: #F9F9F9; border: 1px dashed #2F6FAB; color: black; line-height: 1.1em; padding: 1em;\">
 133+<nowiki><object width=\"425\" height=\"355\">
 134+<param name=\"movie\" value=\"http://www.youtube.com/v/hUcFWPgB8oY\"></param>
 135+<param name=\"wmode\" value=\"transparent\"></param>
 136+<embed src=\"http://www.youtube.com/v/hUcFWPgB8oY\" type=\"application/x-shockwave-flash\"
 137+wmode=\"transparent\" width=\"425\" height=\"355\"></embed>
 138+</object></nowiki>
 139+</pre>
 140+
 141+===Esimerkki videon URL:ista===
 142+Alapuolella on esimerkki YouTube-videon URL:ista:
 143+<pre style=\"background-color: #F9F9F9; border: 1px dashed #2F6FAB; color: black; line-height: 1.1em; padding: 1em;\">http://www.youtube.com/watch?v=hUcFWPgB8oY</pre>",
 144+ 'video-addvideo-invalidcode' => 'Liittämäsi koodi tai URL on kelvoton. Ole hyvä ja kokeile uudestaan.',
 145+ 'video-addvideo-exists' => 'Videosi otsikko on jo olemassa. Ole hyvä ja valitse toinen otsikko videollesi.',
 146+ 'video-addvideo-title-label' => 'Videon otsikko:',
 147+ 'video-addvideo-embed-label' => 'Upotuskoodi tai URL:',
 148+ 'video-history' => 'Videon historia',
 149+ 'video-revert' => 'pal',
 150+ 'video-histlegend' => 'Merkinnät: ({{int:cur}}) = tämä on nykyinen video, ({{int:video-revert}}) = palauta tähän vanhaan versioon.
 151+<br /><i>Napsauta päivämäärää nähdäksesi videon URL kyseisenä päivänä</i>.',
 152+ 'video-revert-success' => 'Palauttaminen aiempaan versioon onnistui.',
 153+ 'video-category-name' => 'Videot',
 154+ 'video-links' => 'Linkit videoon',
 155+ 'video-links-to-video' => '{{PLURAL:$1|Seuraava sivu linkittää|Seuraavat $1 sivua linkittävät}} tähän videoon:',
 156+ 'video-no-links-to-video' => 'Mikään sivu ei linkitä tähän videoon.',
 157+ 'video-more-links-to-video' => 'Katso [[Special:WhatLinksHere/$1|lisää linkkejä]] tähän videoon.',
 158+ 'right-addvideo' => 'Lisätä videoita ulkoisista palveluista sivustolle',
 159+);
\ No newline at end of file
Property changes on: trunk/extensions/Video/Video.i18n.php
___________________________________________________________________
Added: svn:eol-style
1160 + native
Index: trunk/extensions/Video/Video.namespaces.php
@@ -0,0 +1,95 @@
 2+<?php
 3+/**
 4+ * Translations of the Video namespace.
 5+ *
 6+ * @file
 7+ */
 8+
 9+$namespaceNames = array();
 10+
 11+// For wikis where the Video extension is not installed.
 12+if( !defined( 'NS_VIDEO' ) ) {
 13+ define( 'NS_VIDEO', 400 );
 14+}
 15+
 16+if( !defined( 'NS_VIDEO_TALK' ) ) {
 17+ define( 'NS_VIDEO_TALK', 401 );
 18+}
 19+
 20+/** English */
 21+$namespaceNames['en'] = array(
 22+ NS_VIDEO => 'Video',
 23+ NS_VIDEO_TALK => 'Video_talk',
 24+);
 25+
 26+/** German (Deutsch) */
 27+$namespaceNames['de'] = array(
 28+ NS_VIDEO => 'Video',
 29+ NS_VIDEO_TALK => 'Video_Diskussion',
 30+);
 31+
 32+/** Spanish (Español) */
 33+$namespaceNames['es'] = array(
 34+ NS_VIDEO => 'Video',
 35+ NS_VIDEO_TALK => 'Video_Discusión',
 36+);
 37+
 38+/** Estonian (Eesti) */
 39+$namespaceNames['et'] = array(
 40+ NS_VIDEO => 'Video',
 41+ NS_VIDEO_TALK => 'Video_arutelu',
 42+);
 43+
 44+/** Finnish (Suomi) */
 45+$namespaceNames['fi'] = array(
 46+ NS_VIDEO => 'Video',
 47+ NS_VIDEO_TALK => 'Keskustelu_videosta',
 48+);
 49+
 50+/** French (Français) */
 51+$namespaceNames['fr'] = array(
 52+ NS_VIDEO => 'Vidéo',
 53+ NS_VIDEO_TALK => 'Discussion_vidéo',
 54+);
 55+
 56+/** Italian (Italiano) */
 57+$namespaceNames['it'] = array(
 58+ NS_VIDEO => 'Video',
 59+ NS_VIDEO_TALK => 'Discussioni_video',
 60+);
 61+
 62+/** Korean (한국어) */
 63+$namespaceNames['ko'] = array(
 64+ NS_VIDEO => '동영상',
 65+ NS_VIDEO_TALK => '동영상토론',
 66+);
 67+
 68+/** Dutch (Nederlands) */
 69+$namespaceNames['nl'] = array(
 70+ NS_VIDEO => 'Video',
 71+ NS_VIDEO_TALK => 'Overleg_video',
 72+);
 73+
 74+/** Polish (Polski) */
 75+$namespaceNames['pl'] = array(
 76+ NS_VIDEO => 'Video',
 77+ NS_VIDEO_TALK => 'Dyskusja_Video',
 78+);
 79+
 80+/** Portuguese (Português) */
 81+$namespaceNames['pt'] = array(
 82+ NS_VIDEO => 'Vídeo',
 83+ NS_VIDEO_TALK => 'Vídeo_Discussão',
 84+);
 85+
 86+/** Russian (Русский) */
 87+$namespaceNames['ru'] = array(
 88+ NS_VIDEO => 'Видео',
 89+ NS_VIDEO_TALK => 'Обсуждение_видео'
 90+);
 91+
 92+/** Swedish (Svenska) */
 93+$namespaceNames['sv'] = array(
 94+ NS_VIDEO => 'Video',
 95+ NS_VIDEO_TALK => 'Videodiskussion',
 96+);
\ No newline at end of file
Property changes on: trunk/extensions/Video/Video.namespaces.php
___________________________________________________________________
Added: svn:eol-style
197 + native
Index: trunk/extensions/Video/VideoGallery.php
@@ -0,0 +1,329 @@
 2+<?php
 3+/**
 4+ * <videogallery> parser hook tag
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+if ( !defined( 'MEDIAWIKI' ) ) {
 11+ die( 1 );
 12+}
 13+
 14+$wgHooks['ParserFirstCallInit'][] = 'wfVideoGallery';
 15+
 16+function wfVideoGallery( &$parser ) {
 17+ $parser->setHook( 'videogallery', 'wfRenderVideoGallery' );
 18+ return true;
 19+}
 20+
 21+function wfRenderVideoGallery( $input, $argv, $parser ) {
 22+ global $wgTitle;
 23+
 24+ $vg = new VideoGallery();
 25+ $vg->setContextTitle( $wgTitle->getText() );
 26+ $vg->setShowFilename( true );
 27+ $vg->setParsing();
 28+
 29+ if( isset( $argv['perrow'] ) ) {
 30+ $vg->setPerRow( $argv['perrow'] );
 31+ }
 32+ if( isset( $params['widths'] ) ) {
 33+ $vg->setWidths( $argv['widths'] );
 34+ }
 35+ if( isset( $params['heights'] ) ) {
 36+ $vg->setHeights( $argv['heights'] );
 37+ }
 38+
 39+ $lines = explode( "\n", $input );
 40+
 41+ foreach ( $lines as $line ) {
 42+ // match lines like these:
 43+ // Video:Some video name|This is some video
 44+ $matches = array();
 45+ preg_match( "/^([^|]+)(\\|(.*))?$/", $line, $matches );
 46+ // Skip empty lines
 47+ if ( count( $matches ) == 0 ) {
 48+ continue;
 49+ }
 50+
 51+ $tp = Title::newFromText( $matches[1] );
 52+ $nt =& $tp;
 53+ if( is_null( $nt ) ) {
 54+ // Bogus title. Ignore these so we don't bomb out later.
 55+ continue;
 56+ }
 57+ if ( isset( $matches[3] ) ) {
 58+ $label = $matches[3];
 59+ } else {
 60+ $label = '';
 61+ }
 62+
 63+ $html = '';
 64+ /*
 65+ $pout = $this->parse( $label,
 66+ $this->mTitle,
 67+ $this->mOptions,
 68+ false, // Strip whitespace...?
 69+ false // Don't clear state!
 70+ );
 71+ $html = $pout->getText();
 72+ */
 73+
 74+ $vg->add( new Video( $nt ), $html );
 75+
 76+ }
 77+ return $vg->toHTML();
 78+}
 79+
 80+/**
 81+ * Video gallery
 82+ *
 83+ * Add videos to the gallery using add(), then render that list to HTML using toHTML().
 84+ */
 85+class VideoGallery {
 86+ var $mVideos, $mShowFilename;
 87+ var $mSkin = false;
 88+
 89+ /**
 90+ * Is the gallery on a wiki page (i.e. not a special page)
 91+ */
 92+ var $mParsing;
 93+
 94+ private $mPerRow = 3; // How many videos wide should the gallery be?
 95+ private $mWidths = 200, $mHeights = 200; // How wide/tall each thumbnail should be
 96+
 97+ /**
 98+ * Create a new image gallery object.
 99+ */
 100+ function __construct() {
 101+ $this->mVideos = array();
 102+ $this->mShowFilename = true;
 103+ $this->mParsing = false;
 104+ }
 105+
 106+ /**
 107+ * Set the "parse" bit so we know to hide "bad" videos
 108+ */
 109+ function setParsing( $val = true ) {
 110+ $this->mParsing = $val;
 111+ }
 112+
 113+ /**
 114+ * Get the caption (as plain text)
 115+ */
 116+ function getCaption() {
 117+ return ( isset( $this->mCaption ) ) ? $this->mCaption : '';
 118+ }
 119+
 120+ /**
 121+ * Set the caption (as plain text)
 122+ *
 123+ * @param $caption Caption
 124+ */
 125+ function setCaption( $caption ) {
 126+ $this->mCaption = htmlspecialchars( $caption );
 127+ }
 128+
 129+ /**
 130+ * Set the caption (as HTML)
 131+ *
 132+ * @param $caption Caption
 133+ */
 134+ public function setCaptionHtml( $caption ) {
 135+ $this->mCaption = $caption;
 136+ }
 137+
 138+ /**
 139+ * Set how many images will be displayed per row.
 140+ *
 141+ * @param int $num > 0; invalid numbers will be rejected
 142+ */
 143+ public function setPerRow( $num ) {
 144+ if( $num > 0 ) {
 145+ $this->mPerRow = (int)$num;
 146+ }
 147+ }
 148+
 149+ /**
 150+ * Set how wide each image will be, in pixels.
 151+ *
 152+ * @param int $num > 0; invalid numbers will be ignored
 153+ */
 154+ public function setWidths( $num ) {
 155+ if( $num > 0 ) {
 156+ $this->mWidths = (int)$num;
 157+ }
 158+ }
 159+
 160+ /**
 161+ * Set how high each image will be, in pixels.
 162+ *
 163+ * @param int $num > 0; invalid numbers will be ignored
 164+ */
 165+ public function setHeights( $num ) {
 166+ if( $num > 0 ) {
 167+ $this->mHeights = (int)$num;
 168+ }
 169+ }
 170+
 171+ /**
 172+ * Instruct the class to use a specific skin for rendering
 173+ *
 174+ * @param $skin Skin object
 175+ */
 176+ function useSkin( $skin ) {
 177+ $this->mSkin = $skin;
 178+ }
 179+
 180+ /**
 181+ * Return the skin that should be used
 182+ *
 183+ * @return Skin object
 184+ */
 185+ function getSkin() {
 186+ if( !$this->mSkin ) {
 187+ global $wgUser;
 188+ $skin = $wgUser->getSkin();
 189+ } else {
 190+ $skin = $this->mSkin;
 191+ }
 192+ return $skin;
 193+ }
 194+
 195+ /**
 196+ * Add a video to the gallery.
 197+ *
 198+ * @param $video Video object that is added to the gallery
 199+ * @param $html String: additional HTML text to be shown. The name and size of the image are always shown.
 200+ */
 201+ function add( $video, $html = '' ) {
 202+ $this->mVideos[] = array( &$video, $html );
 203+ wfDebug( __METHOD__ . ':' . $video->getName() . "\n" );
 204+ }
 205+
 206+ /**
 207+ * Add an image at the beginning of the gallery.
 208+ *
 209+ * @param $image Image object that is added to the gallery
 210+ * @param $html String: Additional HTML text to be shown. The name and size of the image are always shown.
 211+ */
 212+ function insert( $video, $html = '' ) {
 213+ array_unshift( $this->mVideos, array( &$video, $html ) );
 214+ }
 215+
 216+ /**
 217+ * @return true if the gallery contains no videos
 218+ */
 219+ function isEmpty() {
 220+ return empty( $this->mVideos );
 221+ }
 222+
 223+ /**
 224+ * Enable/Disable showing of the filename of an image in the gallery.
 225+ * Enabled by default.
 226+ *
 227+ * @param $f Boolean: set to false to disable.
 228+ */
 229+ function setShowFilename( $f ) {
 230+ $this->mShowFilename = ( $f == true );
 231+ }
 232+
 233+ /**
 234+ * Return a HTML representation of the video gallery
 235+ *
 236+ * For each video in the gallery, display
 237+ * - a thumbnail
 238+ * - the video name
 239+ * - the additional text provided when adding the video
 240+ * - the size of the video
 241+ */
 242+ function toHTML() {
 243+ global $wgLang;
 244+
 245+ $sk = $this->getSkin();
 246+
 247+ $s = '<table class="gallery" cellspacing="0" cellpadding="0">';
 248+ if( $this->getCaption() )
 249+ $s .= "\n\t<caption>{$this->mCaption}</caption>";
 250+
 251+ $i = 0;
 252+ foreach ( $this->mVideos as $pair ) {
 253+ $video =& $pair[0];
 254+ $text = $pair[1];
 255+
 256+ $nt = $video->getTitle();
 257+
 258+ if( $nt->getNamespace() != NS_VIDEO ) {
 259+ # We're dealing with a non-video, spit out the name and be done with it.
 260+ $thumbhtml = "\n\t\t\t" . '<div style="height: ' . ( $this->mHeights * 1.25 + 2 ) . 'px;">'
 261+ . htmlspecialchars( $nt->getText() ) . '</div>';
 262+ } else {
 263+ $video->setWidth( $this->mWidths );
 264+ $video->setHeight( $this->mHeights );
 265+ $vpad = floor( ( 1.25* $this->mHeights - $this->mWidths ) / 2 ) - 2;
 266+ $thumbhtml = "\n\t\t\t" . '<div class="thumb" style="padding: ' . $vpad . 'px 0; width: ' . ( $this->mWidths + 30 ) . 'px;">'
 267+ . $video->getEmbedCode() . '</div>';
 268+ }
 269+
 270+ $nb = '';
 271+
 272+ $textlink = $this->mShowFilename ?
 273+ $sk->makeKnownLinkObj( $nt, htmlspecialchars( $wgLang->truncate( $nt->getText(), 30, '...' ) ) ) . "<br />\n" :
 274+ '';
 275+
 276+ # ATTENTION: The newline after <div class="gallerytext"> is needed to accommodate htmltidy which
 277+ # in version 4.8.6 generated crackpot html in its absence, see:
 278+ # http://bugzilla.wikimedia.org/show_bug.cgi?id=1765 -Ævar
 279+
 280+ if ( $i % $this->mPerRow == 0 ) {
 281+ $s .= "\n\t<tr>";
 282+ }
 283+ $s .=
 284+ "\n\t\t" . '<td><div class="gallerybox" style="width: ' . ( $this->mWidths * 1.25 ) . 'px;">'
 285+ . $thumbhtml
 286+ . "\n\t\t\t" . '<div class="gallerytext">' . "\n"
 287+ . $textlink . $text . $nb
 288+ . "\n\t\t\t</div>"
 289+ . "\n\t\t</div></td>";
 290+ if ( $i % $this->mPerRow == $this->mPerRow - 1 ) {
 291+ $s .= "\n\t</tr>";
 292+ }
 293+ ++$i;
 294+ }
 295+ if( $i % $this->mPerRow != 0 ) {
 296+ $s .= "\n\t</tr>";
 297+ }
 298+ $s .= "\n</table>";
 299+
 300+ return $s;
 301+ }
 302+
 303+ /**
 304+ * @return int Number of videos in the gallery
 305+ */
 306+ public function count() {
 307+ return count( $this->mVideos );
 308+ }
 309+
 310+ /**
 311+ * Set the contextual title
 312+ *
 313+ * @param Title $title Contextual title
 314+ */
 315+ public function setContextTitle( $title ) {
 316+ $this->contextTitle = $title;
 317+ }
 318+
 319+ /**
 320+ * Get the contextual title, if applicable
 321+ *
 322+ * @return mixed Title or false
 323+ */
 324+ public function getContextTitle() {
 325+ return is_object( $this->contextTitle ) && $this->contextTitle instanceof Title
 326+ ? $this->contextTitle
 327+ : false;
 328+ }
 329+
 330+} //class
\ No newline at end of file
Property changes on: trunk/extensions/Video/VideoGallery.php
___________________________________________________________________
Added: svn:eol-style
1331 + native
Index: trunk/extensions/Video/providers/WeGameVideo.php
@@ -0,0 +1,50 @@
 2+<?php
 3+
 4+class WeGameVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'WeGameVideo constructor given bogus video object.' );
 13+ }
 14+
 15+ $this->video =& $video;
 16+ $this->video->ratio = 488 / 387; // or the other way around...
 17+ $this->id = $this->extractID( $this->video->getURL() );
 18+ $this->url = 'http://www.wegame.com/watch/' . $this->id;
 19+ return $this;
 20+ }
 21+
 22+ public function getEmbedCode() {
 23+ $height = $this->video->getHeight();
 24+ $width = $this->video->getWidth();
 25+ $weid = $this->extractID();
 26+ $output = "<object type=\"application/x-shockwave-flash\" data=\"http://www.wegame.com/static/flash/player2.swf\" width=\"{$width}\" height=\"{$height}\">";
 27+ $output .= "<param name=\"flashvars\" value=\"tag={$weid}\"/></object>";
 28+ return $output;
 29+ }
 30+
 31+ /**
 32+ * Extract the video ID from its URL.
 33+ *
 34+ * @return Integer: video ID
 35+ */
 36+ private function extractID() {
 37+ $url = $this->video->getURL();
 38+
 39+ $id = $url;
 40+
 41+ if ( preg_match( '/^http:\/\/www\.wegame\.com\/watch\/(.+)\/$/', $url, $preg ) ) {
 42+ $id = $preg[1];
 43+ }
 44+
 45+ preg_match( '/([0-9A-Za-z_-]+)/', $id, $preg );
 46+ $id = $preg[1];
 47+
 48+ return $id;
 49+ }
 50+
 51+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/WeGameVideo.php
___________________________________________________________________
Added: svn:eol-style
152 + native
Index: trunk/extensions/Video/providers/MetaCafeVideo.php
@@ -0,0 +1,27 @@
 2+<?php
 3+
 4+class MetaCafeVideo extends FlashVideo {
 5+
 6+ public function __construct( &$video ) {
 7+ parent::__construct( $video );
 8+ $this->video->ratio = 400/345;
 9+ $this->url = $this->video->getURL();
 10+ $this->extractID( $this->video->getURL() );
 11+ }
 12+
 13+ private function extractID() {
 14+ // Standard Metacafe browser URL
 15+ $url = $this->video->getURL();
 16+ $standard_inurl = strpos( strtoupper( $url ), 'HTTP://WWW.METACAFE.COM/WATCH/' );
 17+
 18+ if( $standard_inurl !== false ) {
 19+ $id = substr( $url, $standard_inurl + strlen( 'HTTP://WWW.METACAFE.COM/WATCH/' ), strlen( $url ) );
 20+ $last_char = substr( $id, -1 ,1 );
 21+
 22+ if( $last_char == '/' ) {
 23+ $id = substr( $id, 0, strlen( $id )-1 );
 24+ }
 25+ $this->url = "http://www.metacafe.com/fplayer/{$id}.swf";
 26+ }
 27+ }
 28+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/MetaCafeVideo.php
___________________________________________________________________
Added: svn:eol-style
129 + native
Index: trunk/extensions/Video/providers/GoGreenTubeVideo.php
@@ -0,0 +1,52 @@
 2+<?php
 3+
 4+class GoGreenTubeVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'GoGreenTubeVideo constructor given bogus video object.' );
 13+ }
 14+
 15+ $this->video =& $video;
 16+ $this->video->ratio = 432 / 394; // or the other way around...
 17+ $this->id = $this->extractID( $this->video->getURL() );
 18+ $this->url = 'http://www.gogreentube.com/embed/' . $this->id;
 19+ return $this;
 20+ }
 21+
 22+ public function getEmbedCode() {
 23+ $height = $this->video->getHeight();
 24+ $width = $this->video->getWidth();
 25+ $ggid = $this->extractID();
 26+ $url = "http://www.gogreentube.com/embed/{$ggid}";
 27+ $output = "<script type=\"text/javascript\" src=\"{$url}\"></script>";
 28+ return $output;
 29+ }
 30+
 31+ /**
 32+ * Extract the video ID from its URL.
 33+ *
 34+ * @return Integer: video ID
 35+ */
 36+ private function extractID() {
 37+ $url = $this->video->getURL();
 38+
 39+ $id = $url;
 40+
 41+ if( preg_match( '/^http:\/\/www\.gogreentube\.com\/watch\.php\?v=(.+)$/', $url, $preg ) ) {
 42+ $id = $preg[1];
 43+ } elseif( preg_match( '/^http:\/\/www\.gogreentube\.com\/embed\/(.+)$/', $url, $preg ) ) {
 44+ $id = $preg[1];
 45+ }
 46+
 47+ preg_match( '/([0-9A-Za-z]+)/', $id, $preg );
 48+ $id = $preg[1];
 49+
 50+ return $id;
 51+ }
 52+
 53+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/GoGreenTubeVideo.php
___________________________________________________________________
Added: svn:eol-style
154 + native
Index: trunk/extensions/Video/providers/NewsRoomVideo.php
@@ -0,0 +1,12 @@
 2+<?php
 3+
 4+class NewsRoomVideo extends FlashVideo {
 5+
 6+ public function __construct( &$video ) {
 7+ parent::__construct( $video );
 8+ $this->video->width = 300;
 9+ $this->video->height = 325;
 10+ $this->video->ratio = 300 / 325;
 11+ }
 12+
 13+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/NewsRoomVideo.php
___________________________________________________________________
Added: svn:eol-style
114 + native
Index: trunk/extensions/Video/providers/MovieClipsVideo.php
@@ -0,0 +1,64 @@
 2+<?php
 3+/**
 4+ * @file
 5+ * @author William Lee <wlee@wikia-inc.com>
 6+ * @see http://trac.wikia-code.com/changeset/39940
 7+ */
 8+class MovieClipsVideo extends FlashVideo {
 9+
 10+ var $video,
 11+ $id,
 12+ $url;
 13+
 14+ public function __construct( $video ) {
 15+ if( !is_object( $video ) ) {
 16+ throw new MWException( 'MovieClipsVideo constructor given bogus video object.' );
 17+ }
 18+
 19+ $this->video =& $video;
 20+ $this->video->ratio = 560 / 304;
 21+ $this->id = $this->extractID( $this->video->getURL() );
 22+ $this->url = $url = 'http://movieclips.com/' . $this->id;
 23+ return $this;
 24+ }
 25+
 26+ public function getEmbedCode() {
 27+ $height = $this->video->getHeight();
 28+ $width = $this->video->getWidth();
 29+ $url = 'http://movieclips.com/e/' . $this->id . '/';
 30+ $output = "<embed src=\"{$url}\" width=\"{$width}\" height=\"{$height}\" wmode=\"transparent\" allowScriptAccess=\"always\" allowfullscreen=\"true\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\"> </embed>";
 31+ return $output;
 32+ }
 33+
 34+ /**
 35+ * Extract the video ID from its URL.
 36+ *
 37+ * @return Mixed: video ID (integer) on success, boolean false on failure
 38+ */
 39+ private function extractID() {
 40+ $url = $this->video->getURL();
 41+ $url = trim( $url );
 42+
 43+ $fixed_url = strtoupper( $url );
 44+ $test = strpos( $fixed_url, 'HTTP://' );
 45+ if( !false === $test ) {
 46+ return false;
 47+ }
 48+
 49+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 50+ $fixed_parts = explode( '/', $fixed_url );
 51+ $fixed_url = $fixed_parts[0];
 52+
 53+ $id = '';
 54+ $text = strpos( $fixed_url, 'MOVIECLIPS.COM' );
 55+ if( $text !== false ) {
 56+ $url = trim( $url, '/' );
 57+ $parsed = explode( '/', $url );
 58+ if( is_array( $parsed ) ) {
 59+ $id = array_pop( $parsed );
 60+ }
 61+ }
 62+
 63+ return $id;
 64+ }
 65+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/MovieClipsVideo.php
___________________________________________________________________
Added: svn:eol-style
166 + native
Index: trunk/extensions/Video/providers/GoogleVideo.php
@@ -0,0 +1,36 @@
 2+<?php
 3+
 4+class GoogleVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'GoogleVideo constructor given bogus video object.' );
 13+ }
 14+ $this->video =& $video;
 15+ $this->video->ratio = 425/355;
 16+ $this->id = $this->extractID( $this->video->getURL() );
 17+ $this->url = "http://video.google.com/googleplayer.swf?docId={$this->id}";
 18+ return $this;
 19+ }
 20+
 21+ private function extractID() {
 22+ // Standard Google browser URL
 23+ $url = $this->video->getURL();
 24+ $standard_inurl = strpos( strtoupper( $url ), 'VIDEOPLAY?DOCID=' );
 25+
 26+ if( $standard_inurl !== false ) {
 27+ $id = substr( $url, $standard_inurl + strlen( 'VIDEOPLAY?DOCID=' ), strlen( $url ) );
 28+ }
 29+ if( !$id ) {
 30+ $id_test = preg_replace( "%http\:\/\/video\.google\.com\/googleplayer\.swf\?docId=%i", '', $url );
 31+ if( $id_test != $url ) {
 32+ $id = $id_test;
 33+ }
 34+ }
 35+ return $id;
 36+ }
 37+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/GoogleVideo.php
___________________________________________________________________
Added: svn:eol-style
138 + native
Index: trunk/extensions/Video/providers/MyVideoVideo.php
@@ -0,0 +1,63 @@
 2+<?php
 3+
 4+class MyVideoVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'MyVideoVideo constructor given bogus video object.' );
 13+ }
 14+
 15+ $this->video =& $video;
 16+ $this->video->ratio = 470 / 406;
 17+ $this->id = $this->extractID( $this->video->getURL() );
 18+ $this->url = 'http://www.myvideo.de/watch/' . $this->id;
 19+ return $this;
 20+ }
 21+
 22+ public function getEmbedCode() {
 23+ $height = $this->video->getHeight();
 24+ $width = $this->video->getWidth();
 25+ $output = "<object style=\"width:{$width}px;height:{$height}px;\" type=\"application/x-shockwave-flash\" data=\"http://www.myvideo.de/movie/{$this->id}\">";
 26+ $output .= '<param name="wmode" value="transparent">';
 27+ $output .= '<param name="movie" value="http://www.myvideo.de/movie/' . $this->id . '" />';
 28+ $output .= '<param name="AllowFullscreen?" value="true" /> </object>';
 29+ return $output;
 30+ }
 31+
 32+ /**
 33+ * Extract the video ID from its URL.
 34+ * Copypasted from WikiaVideo's VideoPage.php's parseUrl().
 35+ *
 36+ * @return Integer: video ID
 37+ */
 38+ private function extractID() {
 39+ $url = $this->video->getURL();
 40+ $url = trim( $url );
 41+
 42+ $fixed_url = strtoupper( $url );
 43+ $test = strpos( $fixed_url, 'HTTP://' );
 44+ if( !false === $test ) {
 45+ return false;
 46+ }
 47+
 48+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 49+ $fixed_parts = explode( '/', $fixed_url );
 50+ $fixed_url = $fixed_parts[0];
 51+
 52+ $id = '';
 53+ $text = strpos( $fixed_url, 'MYVIDEO.DE' );
 54+ if( $text !== false ) {
 55+ $parsed = explode( '/', $url );
 56+ if( is_array( $parsed ) ) {
 57+ $id = array_pop( $parsed );
 58+ }
 59+ }
 60+
 61+ return $id;
 62+ }
 63+
 64+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/MyVideoVideo.php
___________________________________________________________________
Added: svn:eol-style
165 + native
Index: trunk/extensions/Video/providers/HuluVideo.php
@@ -0,0 +1,127 @@
 2+<?php
 3+/**
 4+ * @file
 5+ * @author William Lee <wlee@wikia-inc.com>
 6+ * @see http://trac.wikia-code.com/changeset/38530
 7+ */
 8+class HuluVideo extends FlashVideo {
 9+
 10+ var $video,
 11+ $id,
 12+ $url;
 13+
 14+ public function __construct( $video ) {
 15+ if( !is_object( $video ) ) {
 16+ throw new MWException( 'HuluVideo constructor given bogus video object.' );
 17+ }
 18+
 19+ $this->video =& $video;
 20+ $this->video->ratio = 512 / 296;
 21+ $this->id = $this->extractID( $this->video->getURL() );
 22+ $this->url = 'http://www.hulu.com/watch/' . $this->id;
 23+ return $this;
 24+ }
 25+
 26+ public function getEmbedCode() {
 27+ $height = $this->video->getHeight();
 28+ $width = $this->video->getWidth();
 29+ $data = $this->getData();
 30+ $url = 'http://www.hulu.com/embed/' . $data['embedId'];
 31+ $output = "<embed src=\"{$url}\" width=\"{$width}\" height=\"{$height}\" wmode=\"transparent\" allowScriptAccess=\"always\" allowfullscreen=\"true\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\"> </embed>";
 32+ return $output;
 33+ }
 34+
 35+ /**
 36+ * Extract the video ID from its URL.
 37+ *
 38+ * @return Mixed: video ID (integer) on success, boolean false on failure
 39+ */
 40+ private function extractID() {
 41+ $url = $this->video->getURL();
 42+ $url = trim( $url );
 43+
 44+ $fixed_url = strtoupper( $url );
 45+ $test = strpos( $fixed_url, 'HTTP://' );
 46+ if( !false === $test ) {
 47+ return false;
 48+ }
 49+
 50+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 51+ $fixed_parts = explode( '/', $fixed_url );
 52+ $fixed_url = $fixed_parts[0];
 53+
 54+ $id = '';
 55+ $text = strpos( $fixed_url, 'HULU.COM' );
 56+ if( $text !== false ) {
 57+ // Hulu goes like
 58+ // http://www.hulu.com/watch/252775/[seo terms]
 59+ $url = trim( $url, '/' );
 60+ $parsed = explode( '/', $url );
 61+ if( is_array( $parsed ) ) {
 62+ // $id is a number, and it is either last or second to last element of $parsed
 63+ $last = explode( '?', array_pop( $parsed ) );
 64+ $last = $last[0];
 65+ if ( is_numeric( $last ) ) {
 66+ $id = $last;
 67+ } else {
 68+ $id = array_pop( $parsed );
 69+ //$seo = $last;
 70+ }
 71+ /*
 72+ $this->mData = null; // getData() works only if mData is null
 73+ $huluData = $this->getData();
 74+ $this->mData = array();
 75+ if ( is_array( $huluData ) ) {
 76+ foreach ( $huluData as $key => $value ) {
 77+ $this->mData[] = $value;
 78+ }
 79+ }
 80+ if ( !empty( $seo ) ) {
 81+ $this->mData[] = $seo;
 82+ }
 83+ */
 84+ }
 85+ }
 86+
 87+ return $id;
 88+ }
 89+
 90+ private function getData() {
 91+ $data = array();
 92+
 93+ /*
 94+ if ( !empty( $this->mData ) ) {
 95+ // metadata could be a one-element array, expressed in serialized form.
 96+ // If so, deserialize
 97+ if ( sizeof( $this->mData ) == 1 ) {
 98+ $this->mData = explode( ',', $this->mData[0] );
 99+ }
 100+
 101+ $data['embedId'] = $this->mData[0];
 102+ $data['thumbnailUrl'] = $this->mData[1];
 103+ $data['videoName'] = $this->mData[2];
 104+ if ( sizeof( $this->mData ) > 3 ) {
 105+ $data['seo'] = $this->mData[3];
 106+ }
 107+ } else {*/
 108+ wfSuppressWarnings();
 109+ $file = Http::get(
 110+ 'http://www.hulu.com/api/oembed.xml?url=' .
 111+ urlencode( 'http://www.hulu.com/watch/' . $this->id ), false );
 112+ wfRestoreWarnings();
 113+
 114+ if ( $file ) {
 115+ $doc = new DOMDocument( '1.0', 'UTF-8' );
 116+ wfSuppressWarnings();
 117+ $doc->loadXML( $file );
 118+ wfRestoreWarnings();
 119+ $embedUrl = trim( $doc->getElementsByTagName( 'embed_url' )->item( 0 )->textContent );
 120+ $embedUrlParts = explode( '/', $embedUrl );
 121+ $data['embedId'] = array_pop( $embedUrlParts );
 122+ $data['thumbnailUrl'] = trim( $doc->getElementsByTagName( 'thumbnail_url' )->item( 0 )->textContent );
 123+ $data['videoName'] = trim( $doc->getElementsByTagName( 'title' )->item( 0 )->textContent );
 124+ }
 125+ /*}*/
 126+ return $huluData;
 127+ }
 128+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/HuluVideo.php
___________________________________________________________________
Added: svn:eol-style
1129 + native
Index: trunk/extensions/Video/providers/VimeoVideo.php
@@ -0,0 +1,68 @@
 2+<?php
 3+
 4+class VimeoVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'VimeoVideo constructor given bogus video object.' );
 13+ }
 14+
 15+ $this->video =& $video;
 16+ $this->video->ratio = 400 / 225;
 17+ $this->id = $this->extractID( $this->video->getURL() );
 18+ $this->url = 'http://www.vimeo.com/' . $this->id;
 19+ return $this;
 20+ }
 21+
 22+ public function getEmbedCode() {
 23+ $height = $this->video->getHeight();
 24+ $width = $this->video->getWidth();
 25+ $auto = '';#$autoplay ? '&amp;autoplay=1' : '';
 26+ $output = '<object width="' . $width . '" height="' . $height . '">';
 27+ $output .= '<param name="allowfullscreen" value="true" />';
 28+ $output .= '<param name="wmode" value="transparent">';
 29+ $output .= '<param name="allowscriptaccess" value="always" />';
 30+ $output .= '<param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=' . $this->id .
 31+ '&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1' . $auto . '" />';
 32+ $output .= '<embed src="http://vimeo.com/moogaloop.swf?clip_id=' . $this->id . '&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1' . $auto . '" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="' . $width . '" height="' . $height . '">';
 33+ $output .= '</embed></object>';
 34+ return $output;
 35+ }
 36+
 37+ /**
 38+ * Extract the video ID from its URL.
 39+ * Copypasted from WikiaVideo's VideoPage.php's parseUrl().
 40+ *
 41+ * @return Integer: video ID
 42+ */
 43+ private function extractID() {
 44+ $url = $this->video->getURL();
 45+ $url = trim( $url );
 46+
 47+ $fixed_url = strtoupper( $url );
 48+ $test = strpos( $fixed_url, 'HTTP://' );
 49+ if( !false === $test ) {
 50+ return false;
 51+ }
 52+
 53+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 54+ $fixed_parts = explode( '/', $fixed_url );
 55+ $fixed_url = $fixed_parts[0];
 56+
 57+ $id = '';
 58+ $text = strpos( $fixed_url, 'VIMEO.COM' );
 59+ if( $text !=== false ) {
 60+ $parsed = explode( '/', $url );
 61+ if( is_array( $parsed ) ) {
 62+ $id = array_pop( $parsed );
 63+ }
 64+ }
 65+
 66+ return $id;
 67+ }
 68+
 69+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/VimeoVideo.php
___________________________________________________________________
Added: svn:eol-style
170 + native
Index: trunk/extensions/Video/providers/GametrailersVideo.php
@@ -0,0 +1,67 @@
 2+<?php
 3+
 4+class GametrailersVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'GametrailersVideo constructor given bogus video object.' );
 13+ }
 14+
 15+ $this->video =& $video;
 16+ $this->video->ratio = 480 / 392;
 17+ $this->id = $this->extractID( $this->video->getURL() );
 18+ $this->url = 'http://www.gametrailers.com/video/play/' . $this->id;
 19+ return $this;
 20+ }
 21+
 22+ public function getEmbedCode() {
 23+ $height = $this->video->getHeight();
 24+ $width = $this->video->getWidth();
 25+ $output = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" id="gtembed" width="' . $width . '" height="' . $height . '">
 26+ <param name="allowScriptAccess" value="sameDomain" />
 27+ <param name="allowFullScreen" value="true" />
 28+ <param name="movie" value="http://www.gametrailers.com/remote_wrap.php?mid=' . $this->id . '"/>
 29+ <param name="quality" value="high" />
 30+ <embed src="http://www.gametrailers.com/remote_wrap.php?mid=' . $this->id . '" swLiveConnect="true" name="gtembed" align="middle" allowScriptAccess="sameDomain" allowFullScreen="true" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="' . $width . '" height="' . $height . '"></embed>
 31+ </object>';
 32+ return $output;
 33+ }
 34+
 35+ /**
 36+ * Extract the video ID from its URL.
 37+ * Copypasted from WikiaVideo's VideoPage.php's parseUrl().
 38+ *
 39+ * @return Integer: video ID
 40+ */
 41+ private function extractID() {
 42+ $url = $this->video->getURL();
 43+ $url = trim( $url );
 44+
 45+ $fixed_url = strtoupper( $url );
 46+ $test = strpos( $fixed_url, 'HTTP://' );
 47+ if( !false === $test ) {
 48+ return false;
 49+ }
 50+
 51+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 52+ $fixed_parts = explode( '/', $fixed_url );
 53+ $fixed_url = $fixed_parts[0];
 54+
 55+ $id = '';
 56+ $text = strpos( $fixed_url, 'GAMETRAILERS' );
 57+ if( $text !== false ) {
 58+ $parsed = explode( '/', $url );
 59+ if( is_array( $parsed ) ) {
 60+ $id = explode( '?', array_pop( $parsed ) );
 61+ $id = $id[0];
 62+ }
 63+ }
 64+
 65+ return $id;
 66+ }
 67+
 68+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/GametrailersVideo.php
___________________________________________________________________
Added: svn:eol-style
169 + native
Index: trunk/extensions/Video/providers/SevenloadVideo.php
@@ -0,0 +1,78 @@
 2+<?php
 3+/**
 4+ * Bartek Łapiński's notes from WikiaVideo extension:
 5+ * needs an API key - to be done last
 6+ * 1. create a token
 7+ * http://api.sevenload.com/rest/1.0/tokens/create with user and password
 8+ *
 9+ * 2. load the data using the token
 10+ * http://api.sevenload.com/rest/1.0/items/A2C4E6G \
 11+ * ?username=XYZ&token-id=8b8453ca4b79f500e94aac1fc7025b0704f3f2c7
 12+ */
 13+
 14+class SevenloadVideo extends FlashVideo {
 15+
 16+ var $video,
 17+ $id,
 18+ $url;
 19+
 20+ public function __construct( $video ) {
 21+ if( !is_object( $video ) ) {
 22+ throw new MWException( 'SevenloadVideo constructor given bogus video object.' );
 23+ }
 24+
 25+ $this->video =& $video;
 26+ $this->video->ratio = 500 / 408;
 27+ $this->id = $this->extractID( $this->video->getURL() );
 28+ $this->url = 'http://www.sevenload.com/videos/' . $this->id;
 29+ return $this;
 30+ }
 31+
 32+ public function getEmbedCode() {
 33+ $output = '<object style="visibility: visible;" id="sevenloadPlayer_' . $this->id .
 34+ '" data="http://static.sevenload.com/swf/player/player.swf" type="application/x-shockwave-flash" height="' .
 35+ $this->video->getHeight() .
 36+ '" width="' . $this->video->getWidth() . '">';
 37+ $output .= '<param name="wmode" value="transparent">';
 38+ $output .= '<param value="always" name="allowScriptAccess">';
 39+ $output .= '<param value="true" name="allowFullscreen">';
 40+ $output .= '<param value="configPath=http%3A%2F%2Fflash.sevenload.com%2Fplayer%3FportalId%3Den%26autoplay%3D0%26itemId%3D' . $this->id .
 41+ '&amp;locale=en_US&amp;autoplay=0&amp;environment=" name="flashvars">';
 42+ $output .= '</object>';
 43+ return $output;
 44+ }
 45+
 46+ /**
 47+ * Extract the video ID from its URL.
 48+ * Copypasted from WikiaVideo's VideoPage.php's parseUrl().
 49+ *
 50+ * @return Integer: video ID
 51+ */
 52+ private function extractID() {
 53+ $url = $this->video->getURL();
 54+ $url = trim( $url );
 55+
 56+ $fixed_url = strtoupper( $url );
 57+ $test = strpos( $fixed_url, 'HTTP://' );
 58+ if( !false === $test ) {
 59+ return false;
 60+ }
 61+
 62+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 63+ $fixed_parts = explode( '/', $fixed_url );
 64+ $fixed_url = $fixed_parts[0];
 65+
 66+ $id = '';
 67+ $text = strpos( $fixed_url, 'SEVENLOAD.COM' );
 68+ if( $text !== false ) {
 69+ $parsed = explode( '/', $url );
 70+ $id = array_pop( $parsed );
 71+ $parsed_id = explode( '-', $id );
 72+ if( is_array( $parsed_id ) ) {
 73+ $id = $parsed_id[0];
 74+ }
 75+ }
 76+ return $id;
 77+ }
 78+
 79+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/SevenloadVideo.php
___________________________________________________________________
Added: svn:eol-style
180 + native
Index: trunk/extensions/Video/providers/GamevideosVideo.php
@@ -0,0 +1,60 @@
 2+<?php
 3+
 4+class GamevideosVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'GamevideosVideo constructor given bogus video object.' );
 13+ }
 14+
 15+ $this->video =& $video;
 16+ $this->video->ratio = 500 / 319;
 17+ $this->id = $this->extractID( $this->video->getURL() );
 18+ $this->url = 'http://gamevideos.1up.com/video/id/' . $this->id;
 19+ return $this;
 20+ }
 21+
 22+ public function getEmbedCode() {
 23+ $height = $this->video->getHeight();
 24+ $width = $this->video->getWidth();
 25+ $output = '<embed wmode="transparent" type="application/x-shockwave-flash" width="' . $width . '" height="' . $height . '" src="http://gamevideos.1up.com/swf/gamevideos12.swf?embedded=1&amp;fullscreen=1&amp;autoplay=0&amp;src=http://gamevideos.1up.com/do/videoListXML%3Fid%3D' . $this->id . '%26adPlay%3Dtrue" align="middle"></embed>';
 26+ return $output;
 27+ }
 28+
 29+ /**
 30+ * Extract the video ID from its URL.
 31+ * Copypasted from WikiaVideo's VideoPage.php's parseUrl().
 32+ *
 33+ * @return Integer: video ID
 34+ */
 35+ private function extractID() {
 36+ $url = $this->video->getURL();
 37+ $url = trim( $url );
 38+
 39+ $fixed_url = strtoupper( $url );
 40+ $test = strpos( $fixed_url, 'HTTP://' );
 41+ if( !false === $test ) {
 42+ return false;
 43+ }
 44+
 45+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 46+ $fixed_parts = explode( '/', $fixed_url );
 47+ $fixed_url = $fixed_parts[0];
 48+
 49+ $id = '';
 50+ $text = strpos( $fixed_url, 'GAMEVIDEOS.1UP.COM' );
 51+ if( $text !== false ) {
 52+ $parsed = explode( '/', $url );
 53+ if( is_array( $parsed ) ) {
 54+ $id = array_pop( $parsed );
 55+ }
 56+ }
 57+
 58+ return $id;
 59+ }
 60+
 61+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/GamevideosVideo.php
___________________________________________________________________
Added: svn:eol-style
162 + native
Index: trunk/extensions/Video/providers/DailyMotionVideo.php
@@ -0,0 +1,26 @@
 2+<?php
 3+
 4+class DailyMotionVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'DailyMotionVideo constructor given bogus video object.' );
 13+ }
 14+ $this->video =& $video;
 15+ $this->video->ratio = 425/335;
 16+ $this->id = $this->extractID( $this->video->getURL() );
 17+ $this->url = "http://www.dailymotion.com/swf/{$this->id}";
 18+ return $this;
 19+ }
 20+
 21+ private function extractID() {
 22+ $url = $this->video->getURL();
 23+ $id = preg_replace( '%http\:\/\/www\.dailymotion\.com\/(swf|video)\/%i', '', $url );
 24+ return $id;
 25+ }
 26+
 27+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/DailyMotionVideo.php
___________________________________________________________________
Added: svn:eol-style
128 + native
Index: trunk/extensions/Video/providers/ViddlerVideo.php
@@ -0,0 +1,114 @@
 2+<?php
 3+
 4+class ViddlerVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ /**
 11+ * @var String: Viddler API key -- this is Wikia's :)
 12+ */
 13+ const API_KEY = 'hacouneo6n6o3nysn0em';
 14+
 15+ public function __construct( $video ) {
 16+ if( !is_object( $video ) ) {
 17+ throw new MWException( 'ViddlerVideo constructor given bogus video object.' );
 18+ }
 19+
 20+ $this->video =& $video;
 21+ $this->video->ratio = 437 / 288;
 22+ $this->id = $this->extractID( $this->video->getURL() );
 23+ // This needs to take from their API, since they're doing some conversion on their side
 24+ // URL ID -> embedding ID
 25+ // The above is what Bartek once wrote on the WikiaVideo extension.
 26+ // I'm not sure if my code is correct, but if it's not, feel free to
 27+ // correct me...
 28+ //$this->url = $this->getURLToEmbed();
 29+ $this->url = 'http://www.viddler.com/explore/' . $this->id;
 30+ return $this;
 31+ }
 32+
 33+ /**
 34+ * This function is a combination of WikiaVideo's getUrlToEmbed() and
 35+ * getViddlerTrueID() functions.
 36+ * I removed memcached support -- if it ever worked that must've
 37+ * been good luck, because the code was just...well, wtf: it used
 38+ * uninitialized $url variable in the memcached key.
 39+ *
 40+ * @return Mixed: false in case of failure or video URL in case of success
 41+ */
 42+ private function getURLToEmbed() {
 43+ //global $wgMemc;
 44+
 45+ //$cacheKey = wfMemcKey( 'wvi', 'viddlerid', $this->id, $url );
 46+ //$obj = $wgMemc->get( $cacheKey );
 47+
 48+ //if ( isset( $obj ) ) {
 49+ // return $obj;
 50+ //}
 51+
 52+ $url = 'http://api.viddler.com/rest/v1/?method=viddler.videos.getDetailsByUrl&api_key=' .
 53+ self::API_KEY . '&url=http://www.viddler.com/explore/' . $this->id;
 54+ wfSuppressWarnings();
 55+ $file = Http::get( $url );
 56+ $doc = new DOMDocument( '1.0', 'UTF-8' );
 57+ $doc->loadXML( $file );
 58+ wfRestoreWarnings();
 59+ $trueID = trim( $doc->getElementsByTagName( 'id' )->item( 0 )->textContent );
 60+ if ( empty( $trueID ) ) {
 61+ return false;
 62+ }
 63+
 64+ //$wgMemc->set( $cacheKey, $trueID, 60 * 60 * 24 );
 65+
 66+ return 'http://www.viddler.com/player/' . $trueID . '/';
 67+ }
 68+
 69+ public function getEmbedCode() {
 70+ $height = $this->video->getHeight();
 71+ $width = $this->video->getWidth();
 72+ $url = $this->getURLToEmbed();
 73+ $output = "<embed src=\"{$url}\" width=\"{$width}\" height=\"{$height}\" wmode=\"transparent\" allowScriptAccess=\"always\" allowfullscreen=\"true\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\"> </embed>";
 74+ return $output;
 75+ }
 76+
 77+ /**
 78+ * Extract the video ID from its URL.
 79+ * Copypasted from WikiaVideo's VideoPage.php's parseUrl().
 80+ *
 81+ * @return Integer: video ID
 82+ */
 83+ private function extractID() {
 84+ $url = $this->video->getURL();
 85+ $url = trim( $url );
 86+
 87+ $fixed_url = strtoupper( $url );
 88+ $test = strpos( $fixed_url, 'HTTP://' );
 89+ if( !false === $test ) {
 90+ return false;
 91+ }
 92+
 93+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 94+ $fixed_parts = explode( '/', $fixed_url );
 95+ $fixed_url = $fixed_parts[0];
 96+
 97+ $id = '';
 98+ $text = strpos( $fixed_url, 'VIDDLER.COM' );
 99+ if( $text !== false ) {
 100+ $parsed = explode( '/explore/', strtolower( $url ) );
 101+ if( is_array( $parsed ) ) {
 102+ $mdata = array_pop( $parsed );
 103+ if ( ( $mdata != '' ) && ( strpos( $mdata, '?' ) === false ) ) {
 104+ $id = $mdata;
 105+ } else {
 106+ $id = array_pop( $parsed );
 107+ }
 108+ if ( substr( $id, -1, 1 ) != '/' ) {
 109+ $id .= '/';
 110+ }
 111+ }
 112+ }
 113+
 114+ return $id;
 115+ }
Property changes on: trunk/extensions/Video/providers/ViddlerVideo.php
___________________________________________________________________
Added: svn:eol-style
1116 + native
Index: trunk/extensions/Video/providers/ArchiveOrgVideo.php
@@ -0,0 +1,52 @@
 2+<?php
 3+
 4+class ArchiveOrgVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'ArchiveOrgVideo constructor given bogus video object.' );
 13+ }
 14+
 15+ $this->video =& $video;
 16+ $this->video->ratio = 320 / 263; // or the other way around :) --Jack
 17+ $this->id = $this->extractID( $this->video->getURL() );
 18+ $this->url = "http://www.archive.org/download/{$this->id}.flv";
 19+ return $this;
 20+ }
 21+
 22+ public function getEmbedCode() {
 23+ $height = $this->video->getHeight();
 24+ $width = $this->video->getWidth();
 25+ $aovid = $this->extractID();
 26+ $url = "http://www.archive.org/download/{$aovid}.flv";
 27+ $output = "<object type=\"application/x-shockwave-flash\" data=\"http://www.archive.org/flv/FlowPlayerWhite.swf\" width=\"{$width}\" height=\"{$height}\">
 28+ <param name=\"movie\" value=\"http://www.archive.org/flv/FlowPlayerWhite.swf\"/><param name=\"flashvars\" value=\"config={loop: false, videoFile: '{$url}', autoPlay: false}\"/>
 29+ </object>";
 30+ return $output;
 31+ }
 32+
 33+ /**
 34+ * Extract the video ID from its URL.
 35+ *
 36+ * @return Integer: video ID
 37+ */
 38+ private function extractID() {
 39+ $url = $this->video->getURL();
 40+
 41+ $id = $url;
 42+
 43+ if ( preg_match( '/http:\/\/www\.archive\.org\/download\/(.+)\.flv$/', $url, $preg ) ) {
 44+ $id = $preg[1];
 45+ }
 46+
 47+ preg_match( '/([0-9A-Za-z_\/.]+)/', $id, $preg );
 48+ $id = $preg[1];
 49+
 50+ return $id;
 51+ }
 52+
 53+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/ArchiveOrgVideo.php
___________________________________________________________________
Added: svn:eol-style
154 + native
Index: trunk/extensions/Video/providers/SouthParkStudiosVideo.php
@@ -0,0 +1,65 @@
 2+<?php
 3+
 4+class SouthParkStudiosVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'SouthParkStudiosVideo constructor given bogus video object.' );
 13+ }
 14+
 15+ $this->video =& $video;
 16+ $this->video->ratio = 480 / 400;
 17+ $this->id = $this->extractID( $this->video->getURL() );
 18+ $this->url = 'http://www.southparkstudios.com/clips/' . $this->id;
 19+ return $this;
 20+ }
 21+
 22+ public function getEmbedCode() {
 23+ $height = $this->video->getHeight();
 24+ $width = $this->video->getWidth();
 25+ $output = '<embed src="http://media.mtvnservices.com/mgid:cms:item:southparkstudios.com:' . $this->id . '" width="' . $width . '" height="' . $height . '" type="application/x-shockwave-flash" wmode="window" flashVars="autoPlay=false&dist=http://www.southparkstudios.com&orig=" allowFullScreen="true" allowScriptAccess="always" allownetworking="all" bgcolor="#000000"></embed>';
 26+ return $output;
 27+ }
 28+
 29+ /**
 30+ * Extract the video ID from its URL.
 31+ * Copypasted from WikiaVideo's VideoPage.php's parseUrl().
 32+ *
 33+ * @return Integer: video ID
 34+ */
 35+ private function extractID() {
 36+ $url = $this->video->getURL();
 37+ $url = trim( $url );
 38+
 39+ $fixed_url = strtoupper( $url );
 40+ $test = strpos( $fixed_url, 'HTTP://' );
 41+ if( !false === $test ) {
 42+ return false;
 43+ }
 44+
 45+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 46+ $fixed_parts = explode( '/', $fixed_url );
 47+ $fixed_url = $fixed_parts[0];
 48+
 49+ $id = '';
 50+ $text = strpos( $fixed_url, 'SOUTHPARKSTUDIOS.COM' );
 51+ if( $text !== false ) {
 52+ $parsed = explode( '/', $url );
 53+ if( is_array( $parsed ) ) {
 54+ $mdata = array_pop( $parsed );
 55+ if ( ( $mdata != '' ) && ( strpos( $mdata, '?' ) === false ) ) {
 56+ $id = $mdata;
 57+ } else {
 58+ $id = array_pop( $parsed );
 59+ }
 60+ }
 61+ }
 62+
 63+ return $id;
 64+ }
 65+
 66+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/SouthParkStudiosVideo.php
___________________________________________________________________
Added: svn:eol-style
167 + native
Index: trunk/extensions/Video/providers/YouTubeVideo.php
@@ -0,0 +1,37 @@
 2+<?php
 3+
 4+class YouTubeVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'YouTube constructor given bogus video object.' );
 13+ }
 14+ $this->video =& $video;
 15+ $this->video->ratio = 425/355;
 16+ $this->id = $this->extractYouTubeID( $this->video->getURL() );
 17+ $this->url = "http://www.youtube.com/v/{$this->id}";
 18+ return $this;
 19+ }
 20+
 21+ private function extractYouTubeID() {
 22+ // Standard YouTube URL
 23+ $url = $this->video->getURL();
 24+ $standard_youtube_inurl = strpos( strtoupper( $url ), 'WATCH?V=' );
 25+
 26+ $id = '';
 27+ if( $standard_youtube_inurl !== false ) {
 28+ $id = substr( $url, $standard_youtube_inurl + 8, strlen( $url ) );
 29+ }
 30+ if( empty( $id ) ) {
 31+ $id_test = str_replace( 'http://www.youtube.com/v/', '', $url );
 32+ if( $id_test != $url ) {
 33+ $id = $id_test;
 34+ }
 35+ }
 36+ return $id;
 37+ }
 38+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/YouTubeVideo.php
___________________________________________________________________
Added: svn:eol-style
139 + native
Index: trunk/extensions/Video/providers/FlashVideo.php
@@ -0,0 +1,29 @@
 2+<?php
 3+
 4+class FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'FlashVideo constructor given bogus video object.' );
 13+ }
 14+
 15+ $this->video =& $video;
 16+ $this->url = $this->video->getURL();
 17+ return $this;
 18+ }
 19+
 20+ public function getEmbedCode() {
 21+ $output = "<object width=\"{$this->video->getWidth()}px\" height=\"{$this->video->getHeight()}px\">";
 22+ $output .= "<param name=\"movie\" value=\"{$this->url}\"></param>";
 23+ $output .= '<param name="wmode" value="transparent"></param>';
 24+ $output .= "<embed wmode=\"transparent\" base=\".\" allowScriptAccess=\"always\" src=\"{$this->url}\" type=\"application/x-shockwave-flash\" width=\"{$this->video->getWidth()}px\" height=\"{$this->video->getHeight()}px\">";
 25+ $output .= '</embed>';
 26+ $output .= '</object>';
 27+ return $output;
 28+ }
 29+
 30+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/FlashVideo.php
___________________________________________________________________
Added: svn:eol-style
131 + native
Index: trunk/extensions/Video/providers/BlipTVVideo.php
@@ -0,0 +1,126 @@
 2+<?php
 3+/**
 4+ * @file
 5+ */
 6+class BlipTVVideo extends FlashVideo {
 7+
 8+ var $video,
 9+ $id,
 10+ $url;
 11+
 12+ public function __construct( $video ) {
 13+ if( !is_object( $video ) ) {
 14+ throw new MWException( 'BlipTVVideo constructor given bogus video object.' );
 15+ }
 16+
 17+ $this->video =& $video;
 18+ $this->video->ratio = 480 / 350;
 19+ $this->id = $this->extractID( $this->video->getURL() );
 20+ $this->url = 'http://blip.tv/file/' . $this->id;
 21+ return $this;
 22+ }
 23+
 24+ public function getEmbedCode() {
 25+ $height = $this->video->getHeight();
 26+ $width = $this->video->getWidth();
 27+ $result = $this->getData();
 28+ $url = 'http://blip.tv/play/' . $result['mTrueID'];
 29+ $output = "<embed src=\"{$url}\" width=\"{$width}\" height=\"{$height}\" wmode=\"transparent\" allowScriptAccess=\"always\" allowfullscreen=\"true\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\"> </embed>";
 30+ return $output;
 31+ }
 32+
 33+ /**
 34+ * Extract the video ID from its URL.
 35+ *
 36+ * @return Integer: video ID
 37+ */
 38+ private function extractID() {
 39+ $url = $this->video->getURL();
 40+ $url = trim( $url );
 41+
 42+ $fixed_url = strtoupper( $url );
 43+ $test = strpos( $fixed_url, 'HTTP://' );
 44+ if( !false === $test ) {
 45+ return false;
 46+ }
 47+
 48+ $fixed_url = str_replace( 'HTTP://', '', $fixed_url );
 49+ $fixed_parts = explode( '/', $fixed_url );
 50+ $fixed_url = $fixed_parts[0];
 51+
 52+ $id = '';
 53+ $text = strpos( $fixed_url, 'BLIP.TV' );
 54+ if( $text !== false ) {
 55+ $blip = '';
 56+ $parsed = explode( '/', $url );
 57+ if( is_array( $parsed ) ) {
 58+ $mdata = array_pop( $parsed );
 59+ if ( $mdata != '' ) {
 60+ $blip = $mdata;
 61+ } else {
 62+ $blip = array_pop( $parsed );
 63+ }
 64+ $last = explode( '?', $blip );
 65+ $id = $last[0];
 66+ }
 67+ }
 68+
 69+ return $id;
 70+ }
 71+
 72+ /**
 73+ * Get BlipTV data (true ID and thumbnail URL) via their API and hold in
 74+ * memcached.
 75+ * Thumbnail URL isn't used anywhere at the moment
 76+ *
 77+ * @return Mixed: array containing the true ID number and thumbnail URL on
 78+ * sucess, boolean false on failure
 79+ */
 80+ private function getData() {
 81+ global $wgMemc;
 82+
 83+ // Try memcached first
 84+ $cacheKey = wfMemcKey( 'video', 'bliptv', $this->id, $url );
 85+ $obj = $wgMemc->get( $cacheKey );
 86+
 87+ // Got something? Super! We can return here and give the cached data to
 88+ // the user instead of having to make a HTTP request to Blip.tv API.
 89+ if ( isset( $obj ) ) {
 90+ return $obj;
 91+ }
 92+
 93+ $url = 'http://blip.tv/file/' . $this->id . '?skin=rss&version=3';
 94+
 95+ wfSuppressWarnings();
 96+ $file = Http::get( $url );
 97+ wfRestoreWarnings();
 98+ if ( empty( $file ) ) {
 99+ return false;
 100+ }
 101+ $doc = new DOMDocument( '1.0', 'UTF-8' );
 102+ wfSuppressWarnings();
 103+ $doc->loadXML( $file );
 104+ wfRestoreWarnings();
 105+
 106+ $mTrueID = trim( $doc->getElementsByTagNameNS( 'http://blip.tv/dtd/blip/1.0', 'embedLookup' )->item( 0 )->textContent );
 107+ $thumbnailUrl = trim( $doc->getElementsByTagNameNS( 'http://search.yahoo.com/mrss/', 'thumbnail' )->item( 0 )->getAttribute( 'url' ) );
 108+ $mType = trim( $doc->getElementsByTagNameNS( 'http://blip.tv/dtd/blip/1.0', 'embedUrl' )->item( 0 )->getAttribute( 'type' ) );
 109+
 110+ if (
 111+ ( $mType !== 'application/x-shockwave-flash' ) ||
 112+ ( empty( $mTrueID ) ) || ( empty( $thumbnailUrl ) )
 113+ )
 114+ {
 115+ return false;
 116+ }
 117+
 118+ $obj = array(
 119+ 'mTrueID' => $mTrueID,
 120+ 'thumbnailUrl' => $thumbnailUrl
 121+ );
 122+
 123+ $wgMemc->set( $cacheKey, $obj, 60 * 60 * 24 );
 124+
 125+ return $obj;
 126+ }
 127+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/BlipTVVideo.php
___________________________________________________________________
Added: svn:eol-style
1128 + native
Index: trunk/extensions/Video/providers/MySpaceVideo.php
@@ -0,0 +1,30 @@
 2+<?php
 3+
 4+class MySpaceVideo extends FlashVideo {
 5+
 6+ var $video,
 7+ $id,
 8+ $url;
 9+
 10+ public function __construct( $video ) {
 11+ if( !is_object( $video ) ) {
 12+ throw new MWException( 'MySpace constructor given bogus video object.' );
 13+ }
 14+ $this->video =& $video;
 15+ $this->video->ratio = 430/346;
 16+ $this->id = $this->extractID( $this->video->getURL() );
 17+ $this->url = "http://lads.myspace.com/videos/vplayer.swf?m={$this->id}&v=2&type=video";
 18+ return $this;
 19+ }
 20+
 21+ private function extractID() {
 22+ $url = $this->video->getURL();
 23+ //http://myspacetv.com/index.cfm?fuseaction=vids.individual&videoid=1388509
 24+ //http://lads.myspace.com/videos/vplayer.swf?m=1505336&v=2&type=video
 25+ $id = preg_replace( "%http\:\/\/(vids\.|www\.)?myspace(tv)?\.com/index\.cfm\?fuseaction=vids\.individual&VideoID=%i", '', $url );
 26+ $id = preg_replace( "%http\:\/\/(vids\.|www\.|lads\.)?myspace(tv)?\.com\/videos\/vplayer\.swf\?m=%i", '', $id );
 27+ //$id = preg_replace( "%&v=2&type=video%i", '', $id );
 28+ return $id;
 29+ }
 30+
 31+}
\ No newline at end of file
Property changes on: trunk/extensions/Video/providers/MySpaceVideo.php
___________________________________________________________________
Added: svn:eol-style
132 + native

Comments

#Comment by Jack Phoenix (talk | contribs)   20:10, 7 October 2011

The mailing list post in question can be found here: http://lists.wikimedia.org/pipermail/wikitech-l/2011-October/055602.html

I also sent it to MediaWiki-l, but it's not yet showing up in the archives, most probably caused by the fact that I'm not a member of MediaWiki-l and thus it got queued.

#Comment by Siebrand (talk | contribs)   20:26, 7 October 2011

Please add message documentation for the newly added messages. Thanks.

Status & tagging log