Index: trunk/phase3/CREDITS |
— | — | @@ -74,7 +74,6 @@ |
75 | 75 | * Brianna Laugher |
76 | 76 | * Carlin |
77 | 77 | * Conrad Irwin |
78 | | -* Crb |
79 | 78 | * Dan Nessett |
80 | 79 | * Daniel Arnold |
81 | 80 | * Denny Vrandecic |
Index: trunk/phase3/includes/ChangesFeed.php |
— | — | @@ -40,14 +40,11 @@ |
41 | 41 | * |
42 | 42 | * @param $feed ChannelFeed subclass object (generally the one returned by getFeedObject()) |
43 | 43 | * @param $rows ResultWrapper object with rows in recentchanges table |
44 | | - * @param $limit Integer: number of rows in $rows (only used for the cache key) |
45 | | - * @param $hideminor Boolean: whether to hide minor edits (only used for the cache key) |
46 | 44 | * @param $lastmod Integer: timestamp of the last item in the recentchanges table (only used for the cache key) |
47 | | - * @param $target String: target's name; for Special:RecentChangesLinked (only used for the cache key) |
48 | | - * @param $namespace Integer: namespace id (only used for the cache key) |
| 45 | + * @param $opts FormOptions as in SpecialRecentChanges::getDefaultOptions() |
49 | 46 | * @return null or true |
50 | 47 | */ |
51 | | - public function execute( $feed, $rows, $limit=0, $hideminor=false, $lastmod=false, $target='', $namespace='' ) { |
| 48 | + public function execute( $feed, $rows, $lastmod, $opts ) { |
52 | 49 | global $messageMemc, $wgFeedCacheTimeout; |
53 | 50 | global $wgSitename, $wgLang; |
54 | 51 | |
— | — | @@ -56,7 +53,8 @@ |
57 | 54 | } |
58 | 55 | |
59 | 56 | $timekey = wfMemcKey( $this->type, $this->format, 'timestamp' ); |
60 | | - $key = wfMemcKey( $this->type, $this->format, $limit, $hideminor, $target, $wgLang->getCode(), $namespace ); |
| 57 | + $optionsHash = md5( serialize( $opts->getAllValues() ) ); |
| 58 | + $key = wfMemcKey( $this->type, $this->format, $wgLang->getCode(), $optionsHash ); |
61 | 59 | |
62 | 60 | FeedUtils::checkPurge($timekey, $key); |
63 | 61 | |
— | — | @@ -173,4 +171,4 @@ |
174 | 172 | wfProfileOut( __METHOD__ ); |
175 | 173 | } |
176 | 174 | |
177 | | -} |
\ No newline at end of file |
| 175 | +} |
Index: trunk/phase3/includes/specials/SpecialRecentchangeslinked.php |
— | — | @@ -5,6 +5,7 @@ |
6 | 6 | * @ingroup SpecialPage |
7 | 7 | */ |
8 | 8 | class SpecialRecentchangeslinked extends SpecialRecentchanges { |
| 9 | + var $rclTargetTitle; |
9 | 10 | |
10 | 11 | function __construct(){ |
11 | 12 | SpecialPage::SpecialPage( 'Recentchangeslinked' ); |
— | — | @@ -26,7 +27,6 @@ |
27 | 28 | public function feedSetup() { |
28 | 29 | global $wgRequest; |
29 | 30 | $opts = parent::feedSetup(); |
30 | | - # Feed is cached on limit,hideminor,target; other params would randomly not work |
31 | 31 | $opts['target'] = $wgRequest->getVal( 'target' ); |
32 | 32 | return $opts; |
33 | 33 | } |
— | — | @@ -34,7 +34,7 @@ |
35 | 35 | public function getFeedObject( $feedFormat ){ |
36 | 36 | $feed = new ChangesFeed( $feedFormat, false ); |
37 | 37 | $feedObj = $feed->getFeedObject( |
38 | | - wfMsgForContent( 'recentchangeslinked-title', $this->mTargetTitle->getPrefixedText() ), |
| 38 | + wfMsgForContent( 'recentchangeslinked-title', $this->getTargetTitle()->getPrefixedText() ), |
39 | 39 | wfMsgForContent( 'recentchangeslinked-feed' ) |
40 | 40 | ); |
41 | 41 | return array( $feed, $feedObj ); |
— | — | @@ -55,7 +55,6 @@ |
56 | 56 | $wgOut->wrapWikiMsg( "<div class=\"errorbox\">\n$1</div><br style=\"clear: both\" />", 'allpagesbadtitle' ); |
57 | 57 | return false; |
58 | 58 | } |
59 | | - $this->mTargetTitle = $title; |
60 | 59 | |
61 | 60 | $wgOut->setPageTitle( wfMsg( 'recentchangeslinked-title', $title->getPrefixedText() ) ); |
62 | 61 | |
— | — | @@ -197,18 +196,37 @@ |
198 | 197 | return $extraOpts; |
199 | 198 | } |
200 | 199 | |
| 200 | + function getTargetTitle() { |
| 201 | + if ( $this->rclTargetTitle === null ) { |
| 202 | + $opts = $this->getOptions(); |
| 203 | + if ( isset( $opts['target'] ) && $opts['target'] !== '' ) { |
| 204 | + $this->rclTargetTitle = Title::newFromText( $opts['target'] ); |
| 205 | + } else { |
| 206 | + $this->rclTargetTitle = false; |
| 207 | + } |
| 208 | + } |
| 209 | + return $this->rclTargetTitle; |
| 210 | + } |
| 211 | + |
201 | 212 | function setTopText( OutputPage $out, FormOptions $opts ) { |
202 | 213 | global $wgUser; |
203 | 214 | $skin = $wgUser->getSkin(); |
204 | | - if( isset( $this->mTargetTitle ) && is_object( $this->mTargetTitle ) ) |
205 | | - $out->setSubtitle( wfMsg( 'recentchangeslinked-backlink', $skin->link( $this->mTargetTitle, |
206 | | - $this->mTargetTitle->getPrefixedText(), array(), array( 'redirect' => 'no' ) ) ) ); |
| 215 | + $target = $this->getTargetTitle(); |
| 216 | + if( $target ) |
| 217 | + $out->setSubtitle( wfMsg( 'recentchangeslinked-backlink', $skin->link( $target, |
| 218 | + $target->getPrefixedText(), array(), array( 'redirect' => 'no' ) ) ) ); |
207 | 219 | } |
208 | 220 | |
209 | | - function setBottomText( OutputPage $out, FormOptions $opts ){ |
210 | | - if( isset( $this->mTargetTitle ) && is_object( $this->mTargetTitle ) ){ |
211 | | - $out->setFeedAppendQuery( "target=" . urlencode( $this->mTargetTitle->getPrefixedDBkey() ) ); |
| 221 | + public function getFeedQuery() { |
| 222 | + $target = $this->getTargetTitle(); |
| 223 | + if( $target ) { |
| 224 | + return "target=" . urlencode( $target->getPrefixedDBkey() ); |
| 225 | + } else { |
| 226 | + return false; |
212 | 227 | } |
| 228 | + } |
| 229 | + |
| 230 | + function setBottomText( OutputPage $out, FormOptions $opts ) { |
213 | 231 | if( isset( $this->mResultEmpty ) && $this->mResultEmpty ){ |
214 | 232 | $out->addWikiMsg( 'recentchangeslinked-noresult' ); |
215 | 233 | } |
Index: trunk/phase3/includes/specials/SpecialRecentchanges.php |
— | — | @@ -5,6 +5,8 @@ |
6 | 6 | * @ingroup SpecialPage |
7 | 7 | */ |
8 | 8 | class SpecialRecentChanges extends SpecialPage { |
| 9 | + var $rcOptions, $rcSubpage; |
| 10 | + |
9 | 11 | public function __construct() { |
10 | 12 | parent::__construct( 'Recentchanges' ); |
11 | 13 | $this->includable( true ); |
— | — | @@ -40,7 +42,7 @@ |
41 | 43 | } |
42 | 44 | |
43 | 45 | /** |
44 | | - * Get a FormOptions object with options as specified by the user |
| 46 | + * Create a FormOptions object with options as specified by the user |
45 | 47 | * |
46 | 48 | * @return FormOptions |
47 | 49 | */ |
— | — | @@ -60,7 +62,7 @@ |
61 | 63 | } |
62 | 64 | |
63 | 65 | /** |
64 | | - * Get a FormOptions object sepcific for feed requests |
| 66 | + * Create a FormOptions object specific for feed requests and return it |
65 | 67 | * |
66 | 68 | * @return FormOptions |
67 | 69 | */ |
— | — | @@ -74,12 +76,26 @@ |
75 | 77 | } |
76 | 78 | |
77 | 79 | /** |
| 80 | + * Get the current FormOptions for this request |
| 81 | + */ |
| 82 | + public function getOptions() { |
| 83 | + if ( $this->rcOptions === null ) { |
| 84 | + global $wgRequest; |
| 85 | + $feedFormat = $wgRequest->getVal( 'feed' ); |
| 86 | + $this->rcOptions = $feedFormat ? $this->feedSetup() : $this->setup( $this->rcSubpage ); |
| 87 | + } |
| 88 | + return $this->rcOptions; |
| 89 | + } |
| 90 | + |
| 91 | + |
| 92 | + /** |
78 | 93 | * Main execution point |
79 | 94 | * |
80 | | - * @param $parameters string |
| 95 | + * @param $subpage string |
81 | 96 | */ |
82 | | - public function execute( $parameters ) { |
| 97 | + public function execute( $subpage ) { |
83 | 98 | global $wgRequest, $wgOut; |
| 99 | + $this->rcSubpage = $subpage; |
84 | 100 | $feedFormat = $wgRequest->getVal( 'feed' ); |
85 | 101 | |
86 | 102 | # 10 seconds server-side caching max |
— | — | @@ -90,12 +106,11 @@ |
91 | 107 | return; |
92 | 108 | } |
93 | 109 | |
94 | | - $opts = $feedFormat ? $this->feedSetup() : $this->setup( $parameters ); |
| 110 | + $opts = $this->getOptions(); |
95 | 111 | $this->setHeaders(); |
96 | 112 | $this->outputHeader(); |
97 | 113 | |
98 | 114 | // Fetch results, prepare a batch link existence check query |
99 | | - $rows = array(); |
100 | 115 | $conds = $this->buildMainQueryConds( $opts ); |
101 | 116 | $rows = $this->doMainQuery( $conds, $opts ); |
102 | 117 | if( $rows === false ){ |
— | — | @@ -114,10 +129,9 @@ |
115 | 130 | } |
116 | 131 | $batch->execute(); |
117 | 132 | } |
118 | | - $target = isset($opts['target']) ? $opts['target'] : ''; // RCL has targets |
119 | 133 | if( $feedFormat ) { |
120 | | - list( $feed, $feedObj ) = $this->getFeedObject( $feedFormat ); |
121 | | - $feed->execute( $feedObj, $rows, $opts['limit'], $opts['hideminor'], $lastmod, $target, $opts['namespace'] ); |
| 134 | + list( $changesFeed, $formatter ) = $this->getFeedObject( $feedFormat ); |
| 135 | + $changesFeed->execute( $formatter, $rows, $lastmod, $opts ); |
122 | 136 | } else { |
123 | 137 | $this->webOutput( $rows, $opts ); |
124 | 138 | } |
— | — | @@ -131,12 +145,12 @@ |
132 | 146 | * @return array |
133 | 147 | */ |
134 | 148 | public function getFeedObject( $feedFormat ){ |
135 | | - $feed = new ChangesFeed( $feedFormat, 'rcfeed' ); |
136 | | - $feedObj = $feed->getFeedObject( |
| 149 | + $changesFeed = new ChangesFeed( $feedFormat, 'rcfeed' ); |
| 150 | + $formatter = $changesFeed->getFeedObject( |
137 | 151 | wfMsgForContent( 'recentchanges' ), |
138 | 152 | wfMsgForContent( 'recentchanges-feed-description' ) |
139 | 153 | ); |
140 | | - return array( $feed, $feedObj ); |
| 154 | + return array( $changesFeed, $formatter ); |
141 | 155 | } |
142 | 156 | |
143 | 157 | /** |
— | — | @@ -355,7 +369,7 @@ |
356 | 370 | } |
357 | 371 | |
358 | 372 | // And now for the content |
359 | | - $wgOut->setSyndicated( true ); |
| 373 | + $wgOut->setFeedAppendQuery( $this->getFeedQuery() ); |
360 | 374 | |
361 | 375 | if( $wgAllowCategorizedRecentChanges ) { |
362 | 376 | $this->filterByCategories( $rows, $opts ); |
— | — | @@ -403,6 +417,14 @@ |
404 | 418 | } |
405 | 419 | |
406 | 420 | /** |
| 421 | + * Get the query string to append to feed link URLs. |
| 422 | + * This is overridden by RCL to add the target parameter |
| 423 | + */ |
| 424 | + public function getFeedQuery() { |
| 425 | + return false; |
| 426 | + } |
| 427 | + |
| 428 | + /** |
407 | 429 | * Return the text to be displayed above the changes |
408 | 430 | * |
409 | 431 | * @param $opts FormOptions |