Index: trunk/extensions/Wikilog/WikilogFeed.php |
— | — | @@ -65,7 +65,7 @@ |
66 | 66 | * to this list means that feed caching should be revisited. Parameters |
67 | 67 | * must be listed as keys. |
68 | 68 | */ |
69 | | - public static $paramWhitelist = array( 'show' => true ); |
| 69 | + public static $paramWhitelist = array( 'wikilog' => true, 'show' => true ); |
70 | 70 | |
71 | 71 | /** |
72 | 72 | * WikilogFeed constructor. |
— | — | @@ -362,7 +362,6 @@ |
363 | 363 | if ( !$limit ) $limit = $wgWikilogNumArticles; |
364 | 364 | parent::__construct( $title, $format, $query, $limit ); |
365 | 365 | $this->mSiteFeed = $this->mQuery->getWikilogTitle() === null; |
366 | | - |
367 | 366 | } |
368 | 367 | |
369 | 368 | public function getIndexField() { |
— | — | @@ -375,10 +374,12 @@ |
376 | 375 | } |
377 | 376 | |
378 | 377 | public function getFeedObject() { |
379 | | - if ( $this->mSiteFeed ) { |
| 378 | + if ( $this->mQuery->getWikilogTitle() ) { |
| 379 | + return $this->getWikilogFeedObject( $this->mQuery->getWikilogTitle() ); |
| 380 | + } elseif ( $this->mQuery->getNamespace() !== false ) { |
| 381 | + return $this->getNamespaceFeedObject( $this->mQuery->getNamespace() ); |
| 382 | + } else { |
380 | 383 | return $this->getSiteFeedObject(); |
381 | | - } else { |
382 | | - return $this->getWikilogFeedObject( $this->mQuery->getWikilogTitle() ); |
383 | 384 | } |
384 | 385 | } |
385 | 386 | |
— | — | @@ -414,6 +415,47 @@ |
415 | 416 | } |
416 | 417 | |
417 | 418 | /** |
| 419 | + * Generates and populates a WlSyndicationFeed object for a given namespace. |
| 420 | + * |
| 421 | + * @param $ns Namespace. |
| 422 | + * @return Feed object. |
| 423 | + */ |
| 424 | + protected function getNamespaceFeedObject( $ns ) { |
| 425 | + global $wgWikilogFeedClasses, $wgFavicon, $wgLogo; |
| 426 | + global $wgContLang, $wgContLanguageCode; |
| 427 | + |
| 428 | + $title = wfMsgForContent( 'wikilog-feed-ns-title', $wgContLang->getFormattedNsText( $ns ) ); |
| 429 | + $subtitle = wfMsgExt( 'wikilog-feed-description', array( 'parse', 'content' ) ); |
| 430 | + |
| 431 | + $updated = $this->mDb->selectField( |
| 432 | + array( 'wikilog_wikilogs', 'page' ), |
| 433 | + 'MAX(wlw_updated)', |
| 434 | + array( |
| 435 | + 'wlw_page = page_id', |
| 436 | + 'page_namespace' => $ns |
| 437 | + ), |
| 438 | + __METHOD__ |
| 439 | + ); |
| 440 | + if ( !$updated ) $updated = wfTimestampNow(); |
| 441 | + |
| 442 | + $feed = new $wgWikilogFeedClasses[$this->mFormat]( |
| 443 | + $this->mTitle->getFullUrl(), |
| 444 | + wfMsgForContent( 'wikilog-feed-title', $title, $wgContLanguageCode ), |
| 445 | + $updated, |
| 446 | + $this->mTitle->getFullUrl() |
| 447 | + ); |
| 448 | + $feed->setSubtitle( new WlTextConstruct( 'html', $subtitle ) ); |
| 449 | + $feed->setLogo( wfExpandUrl( $wgLogo ) ); |
| 450 | + if ( $wgFavicon !== false ) { |
| 451 | + $feed->setIcon( wfExpandUrl( $wgFavicon ) ); |
| 452 | + } |
| 453 | + if ( $this->mCopyright ) { |
| 454 | + $feed->setRights( new WlTextConstruct( 'html', $this->mCopyright ) ); |
| 455 | + } |
| 456 | + return $feed; |
| 457 | + } |
| 458 | + |
| 459 | + /** |
418 | 460 | * Generates and populates a WlSyndicationFeed object for the given |
419 | 461 | * wikilog. Caches objects whenever possible. |
420 | 462 | * |
— | — | @@ -574,8 +616,13 @@ |
575 | 617 | * Returns the keys for the timestamp and feed output in the object cache. |
576 | 618 | */ |
577 | 619 | public function getCacheKeys() { |
578 | | - $title = $this->mQuery->getWikilogTitle(); |
579 | | - $id = $title ? 'id:' . $title->getArticleId() : 'site'; |
| 620 | + if ( ( $title = $this->mQuery->getWikilogTitle() ) ) { |
| 621 | + $id = 'id:' . $title->getArticleId(); |
| 622 | + } elseif ( ( $ns = $this->mQuery->getNamespace() ) ) { |
| 623 | + $id = 'ns:' . $ns; |
| 624 | + } else { |
| 625 | + $id = 'site'; |
| 626 | + } |
580 | 627 | $ft = 'show:' . $this->mQuery->getPubStatus() . |
581 | 628 | ':limit:' . $this->mLimit; |
582 | 629 | return array( |
Index: trunk/extensions/Wikilog/SpecialWikilog.php |
— | — | @@ -119,7 +119,7 @@ |
120 | 120 | global $wgRequest, $wgFeedLimit; |
121 | 121 | |
122 | 122 | $opts = $this->getDefaultOptions(); |
123 | | - $opts->fetchValuesFromRequest( $wgRequest, array( 'show', 'limit' ) ); |
| 123 | + $opts->fetchValuesFromRequest( $wgRequest, array( 'wikilog', 'show', 'limit' ) ); |
124 | 124 | $opts->validateIntBounds( 'limit', 0, $wgFeedLimit ); |
125 | 125 | return $opts; |
126 | 126 | } |
— | — | @@ -191,8 +191,8 @@ |
192 | 192 | |
193 | 193 | # Add feed links. |
194 | 194 | $wgOut->setSyndicated(); |
195 | | - if ( isset( $qarr['show'] ) ) { |
196 | | - $altquery = wfArrayToCGI( array_intersect_key( $qarr, WikilogItemFeed::$paramWhitelist ) ); |
| 195 | + $altquery = wfArrayToCGI( array_intersect_key( $qarr, WikilogItemFeed::$paramWhitelist ) ); |
| 196 | + if ( $altquery ) { |
197 | 197 | $wgOut->setFeedAppendQuery( $altquery ); |
198 | 198 | } |
199 | 199 | |
— | — | @@ -400,13 +400,20 @@ |
401 | 401 | * @return Wikilog query object. |
402 | 402 | */ |
403 | 403 | public static function getQuery( $opts ) { |
| 404 | + global $wgWikilogNamespaces; |
| 405 | + |
404 | 406 | $query = new WikilogItemQuery(); |
405 | 407 | $query->setPubStatus( $opts['show'] ); |
406 | | - if ( $opts['wikilog'] && ( $t = Title::newFromText( $opts['wikilog'] ) ) ) { |
407 | | - if ( $t->getText() == '*' ) { |
408 | | - $query->setNamespace( $t->getNamespace() ); |
| 408 | + if ( $opts['wikilog'] ) { |
| 409 | + $t = Title::newFromText( $opts['wikilog'] ); |
| 410 | + if ( $t && in_array( $t->getNamespace(), $wgWikilogNamespaces ) ) { |
| 411 | + if ( $t->getText() == '*' ) { |
| 412 | + $query->setNamespace( $t->getNamespace() ); |
| 413 | + } else { |
| 414 | + $query->setWikilogTitle( $t ); |
| 415 | + } |
409 | 416 | } else { |
410 | | - $query->setWikilogTitle( $t ); |
| 417 | + $query->setEmpty(); |
411 | 418 | } |
412 | 419 | } |
413 | 420 | if ( ( $t = $opts['category'] ) ) { |
Index: trunk/extensions/Wikilog/WikilogQuery.php |
— | — | @@ -46,6 +46,12 @@ |
47 | 47 | protected $mDefaultOptions = array(); |
48 | 48 | |
49 | 49 | /** |
| 50 | + * Whether the query should always return nothing (when invalid options |
| 51 | + * are provided, for example). |
| 52 | + */ |
| 53 | + protected $mEmpty = false; |
| 54 | + |
| 55 | + /** |
50 | 56 | * Constructor. |
51 | 57 | */ |
52 | 58 | public function __construct() { |
— | — | @@ -86,6 +92,12 @@ |
87 | 93 | } |
88 | 94 | |
89 | 95 | /** |
| 96 | + * Filter is always returns empty. |
| 97 | + */ |
| 98 | + public function setEmpty( $empty = true ) { $this->mEmpty = $empty; } |
| 99 | + public function getEmpty() { return $this->mEmpty; } |
| 100 | + |
| 101 | + /** |
90 | 102 | * Generate and return query information. |
91 | 103 | * @param $db Database Database object used to encode table names, etc. |
92 | 104 | * @param $opts mixed Misc query options. |
— | — | @@ -312,10 +324,15 @@ |
313 | 325 | $q_options = array(); |
314 | 326 | $q_joins = $wlp_tables['join_conds']; |
315 | 327 | |
| 328 | + # Invalid filter. |
| 329 | + if ( $this->mEmpty ) { |
| 330 | + $q_conds[] = '0=1'; |
| 331 | + } |
| 332 | + |
316 | 333 | # Filter by wikilog name. |
317 | 334 | if ( $this->mWikilogTitle !== null ) { |
318 | 335 | $q_conds['wlp_parent'] = $this->mWikilogTitle->getArticleId(); |
319 | | - } elseif ( $this->mNamespace ) { |
| 336 | + } elseif ( $this->mNamespace !== false ) { |
320 | 337 | $q_conds['p.page_namespace'] = $this->mNamespace; |
321 | 338 | } |
322 | 339 | |
— | — | @@ -380,7 +397,7 @@ |
381 | 398 | |
382 | 399 | if ( $this->mNeedWikilogParam && $this->mWikilogTitle ) { |
383 | 400 | $query['wikilog'] = $this->mWikilogTitle->getPrefixedDBKey(); |
384 | | - } elseif ( $this->mNamespace ) { |
| 401 | + } elseif ( $this->mNamespace !== false ) { |
385 | 402 | $query['wikilog'] = Title::makeTitle( $this->mNamespace, "*" )->getPrefixedDBKey(); |
386 | 403 | } |
387 | 404 | |
— | — | @@ -525,7 +542,7 @@ |
526 | 543 | * precedence over this filter. |
527 | 544 | * @param $ns Namespace to query for. |
528 | 545 | */ |
529 | | - public function setNamespace ( $ns ) { |
| 546 | + public function setNamespace( $ns ) { |
530 | 547 | $this->mNamespace = $ns; |
531 | 548 | } |
532 | 549 | |
— | — | @@ -637,6 +654,11 @@ |
638 | 655 | $q_options = array(); |
639 | 656 | $q_joins = $wlc_tables['join_conds']; |
640 | 657 | |
| 658 | + # Invalid filter. |
| 659 | + if ( $this->mEmpty ) { |
| 660 | + $q_conds[] = '0=1'; |
| 661 | + } |
| 662 | + |
641 | 663 | # Filter by moderation status. |
642 | 664 | if ( $this->mModStatus == self::MS_ACCEPTED ) { |
643 | 665 | $q_conds['wlc_status'] = 'OK'; |
— | — | @@ -658,7 +680,7 @@ |
659 | 681 | } elseif ( $this->mWikilog !== null ) { |
660 | 682 | $join_wlp = true; |
661 | 683 | $q_conds['wlp_parent'] = $this->mWikilog->getArticleId(); |
662 | | - } elseif ( $this->mNamespace ) { |
| 684 | + } elseif ( $this->mNamespace !== false ) { |
663 | 685 | $q_conds['c.page_namespace'] = $this->mNamespace; |
664 | 686 | } |
665 | 687 | |
— | — | @@ -706,7 +728,7 @@ |
707 | 729 | $query['item'] = $this->mItem->mTitle->getPrefixedDBKey(); |
708 | 730 | } elseif ( $this->mWikilog ) { |
709 | 731 | $query['wikilog'] = $this->mWikilog->getPrefixedDBKey(); |
710 | | - } elseif ( $this->mNamespace ) { |
| 732 | + } elseif ( $this->mNamespace !== false ) { |
711 | 733 | $query['wikilog'] = Title::makeTitle( $this->mNamespace, "*" )->getPrefixedDBKey(); |
712 | 734 | } |
713 | 735 | |
Index: trunk/extensions/Wikilog/Wikilog.i18n.php |
— | — | @@ -119,6 +119,7 @@ |
120 | 120 | |
121 | 121 | # Atom and RSS feeds |
122 | 122 | 'wikilog-feed-title' => '{{SITENAME}} - $1 [$2]', # $1 = title, $2 = content language |
| 123 | + 'wikilog-feed-ns-title' => '$1 wikilog articles', # $1 = namespace name |
123 | 124 | 'wikilog-feed-description' => 'Read the most recent posts in this feed.', |
124 | 125 | 'wikilog-comment-feed-title1' => 'Comment by $2 (#$1)', |
125 | 126 | 'wikilog-comment-feed-title2' => 'Comment by $2 to $3 (#$1)', |