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 |
1 | 680 | + 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 |
1 | 35 | + 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 |
1 | 80 | + 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 |
1 | 504 | + 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 |
1 | 280 | + 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 |
1 | 111 | + 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 |
1 | 123 | + 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§ion=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 |
1 | 26 | + 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 & 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 |
1 | 330 | + 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 |
1 | 27 | + 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 |
1 | 169 | + 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 |
1 | 160 | + 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 |
1 | 97 | + 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 |
1 | 331 | + 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 |
1 | 52 | + 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 |
1 | 29 | + 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 |
1 | 54 | + 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 |
1 | 14 | + 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 |
1 | 66 | + 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 |
1 | 38 | + 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 |
1 | 65 | + 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 |
1 | 129 | + 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 ? '&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 | + '&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1' . $auto . '" />'; |
| 32 | + $output .= '<embed src="http://vimeo.com/moogaloop.swf?clip_id=' . $this->id . '&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&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 |
1 | 70 | + 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 |
1 | 69 | + 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 | + '&locale=en_US&autoplay=0&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 |
1 | 80 | + 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&fullscreen=1&autoplay=0&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 |
1 | 62 | + 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 |
1 | 28 | + 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 |
1 | 116 | + 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 |
1 | 54 | + 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 |
1 | 67 | + 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 |
1 | 39 | + 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 |
1 | 31 | + 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 |
1 | 128 | + 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 |
1 | 32 | + native |