r60517 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r60516‎ | r60517 | r60518 >
Date:22:24, 30 December 2009
Author:pdhanda
Status:deferred
Tags:
Comment:
Switched to using request params. Cleaned up some code style.
Modified paths:
  • /trunk/extensions/GNSM/SpecialGNSM_body.php (modified) (history)

Diff [purge]

Index: trunk/extensions/GNSM/SpecialGNSM_body.php
@@ -6,7 +6,7 @@
77 **
88 * Simple feed using Atom/RSS coupled to DynamicPageList category searching.
99 *
10 - * To use: http://wiki.url/Special:GNSM/[paramter=value][...]
 10+ * To use: http://wiki.url/Special:GNSM/<feedType>?[paramter=value][...]
1111 *
1212 * Implemented parameters are marked with an @
1313 **
@@ -28,502 +28,490 @@
2929
3030 class GNSM extends IncludableSpecialPage {
3131
32 -
33 - /**
34 - * FIXME: Some of this might need a config eventually
35 - * @var string
36 - **/
37 - var $Title = '';
38 - var $Description = '';
39 - var $Url = '';
40 - var $Date = '';
41 - var $Author = '';
42 - var $pubDate = '';
43 - var $keywords = '';
44 - var $lastMod = '';
45 - var $priority = '';
46 -
47 - /**
48 - * Script default values - correctly spelt, naming standard.
49 - **/
50 - var $wgDPlminCategories = 1; // Minimum number of categories to look for
51 - var $wgDPlmaxCategories = 6; // Maximum number of categories to look for
52 - var $wgDPLminResultCount = 1; // Minimum number of results to allow
53 - var $wgDPLmaxResultCount = 50; // Maximum number of results to allow
54 - var $wgDPLallowUnlimitedResults = true; // Allow unlimited results
55 - var $wgDPLallowUnlimitedCategories = false; // Allow unlimited categories
5632
57 -
58 - /**
59 - * @var array Parameters array
60 - **/
61 - var $params = array();
62 - var $categories = array();
63 - var $notCategories = array();
64 -
65 - /**
66 - * Constructor
67 - **/
68 - public function __construct() {
69 - parent::__construct( 'GNSM' );
70 - }
71 -
72 - /**
73 - * main()
74 - **/
75 - public function execute( $par ) {
76 - global $wgUser;
77 - global $wgLang;
78 - global $wgContLang;
79 - global $wgRequest, $wgOut;
80 - global $wgSitename, $wgServer, $wgScriptPath;
81 -// global $wfTimeStamp;
82 - wfLoadExtensionMessages( 'GNSM' );
83 - global $wgFeedClasses, $wgLocaltimezone;
84 -
85 - // Not sure how clean $wgLocaltimezone is
86 - // In fact, it's default setting is null...
87 - if ( null == $wgLocaltimezone )
88 - $wgLocaltimezone = date_default_timezone_get();
89 - date_default_timezone_set( $wgLocaltimezone );
90 - //$url = __FILE__;
 33+ /**
 34+ * FIXME: Some of this might need a config eventually
 35+ * @var string
 36+ **/
 37+ var $Title = '';
 38+ var $Description = '';
 39+ var $Url = '';
 40+ var $Date = '';
 41+ var $Author = '';
 42+ var $pubDate = '';
 43+ var $keywords = '';
 44+ var $lastMod = '';
 45+ var $priority = '';
9146
92 - $this->dpl_parm( $par );
93 -
94 -
95 - $wgFeedClasses[] = array( 'sitemap' => 'SitemapFeed' );
96 -
97 - if ( 'sitemap' == $this->params['feed'] ){
98 - $feed = new SitemapFeed(
99 - $wgServer.$wgScriptPath,
100 - date( DATE_ATOM )
101 - );
102 - }else{
103 - // FIXME: These should be configurable at some point
104 - $feed = new $wgFeedClasses[ $this->params['feed'] ](
105 - $wgSitename,
106 - $wgSitename . ' ' . $this->params['feed'] . ' feed',
107 - $wgServer.$wgScriptPath,
108 - date( DATE_ATOM ),
109 - $wgSitename
110 - );
 47+ /**
 48+ * Script default values - correctly spelt, naming standard.
 49+ **/
 50+ var $wgDPlminCategories = 1; // Minimum number of categories to look for
 51+ var $wgDPlmaxCategories = 6; // Maximum number of categories to look for
 52+ var $wgDPLminResultCount = 1; // Minimum number of results to allow
 53+ var $wgDPLmaxResultCount = 50; // Maximum number of results to allow
 54+ var $wgDPLallowUnlimitedResults = true; // Allow unlimited results
 55+ var $wgDPLallowUnlimitedCategories = false; // Allow unlimited categories
 56+
 57+
 58+ /**
 59+ * @var array Parameters array
 60+ **/
 61+ var $params = array();
 62+ var $categories = array();
 63+ var $notCategories = array();
 64+
 65+ /**
 66+ * Constructor
 67+ **/
 68+ public function __construct() {
 69+ parent::__construct( 'GNSM' );
11170 }
11271
113 - $feed->outHeader();
114 -
115 - // main routine to output items
116 - if ( isset( $this->param['error'] ) ){
117 - echo $this->param['error'];
118 - }else{
119 - $dbr =& wfGetDB( DB_SLAVE );
120 - $sql = $this->dpl_buildSQL();
121 - //Debug line
122 - //echo "\n<p>$sql</p>\n";
123 - $res = $dbr->query ( $sql );
124 -
125 - // FIXME: figure out how to fail with no results gracefully
126 - if ( $dbr->numRows( $res ) == 0 ){
127 - $feed->outFooter();
128 - if ( false == $this->params['suppressErrors'] )
129 - return htmlspecialchars( wfMsg( 'gnsm_noresults' ) );
130 - else
131 - return '';
132 - }
133 -
134 - while ($row = $dbr->fetchObject( $res ) ) {
135 - $title = Title::makeTitle( $row->page_namespace, $row->page_title);
136 -
137 - if ( $title ){
 72+ /**
 73+ * main()
 74+ **/
 75+ public function execute( $par ) {
 76+ global $wgUser;
 77+ global $wgLang;
 78+ global $wgContLang;
 79+ global $wgRequest, $wgOut;
 80+ global $wgSitename, $wgServer, $wgScriptPath;
 81+ // global $wfTimeStamp;
 82+ wfLoadExtensionMessages( 'GNSM' );
 83+ global $wgFeedClasses, $wgLocaltimezone;
 84+
 85+ // Not sure how clean $wgLocaltimezone is
 86+ // In fact, it's default setting is null...
 87+ if ( null == $wgLocaltimezone )
 88+ $wgLocaltimezone = date_default_timezone_get();
 89+ date_default_timezone_set( $wgLocaltimezone );
 90+ //$url = __FILE__;
 91+
 92+ $this->dpl_parm( $par );
 93+
 94+
 95+ $wgFeedClasses[] = array( 'sitemap' => 'SitemapFeed' );
 96+
 97+ if ( 'sitemap' == $this->params['feed'] ){
 98+ $feed = new SitemapFeed(
 99+ $wgServer.$wgScriptPath,
 100+ date( DATE_ATOM )
 101+ );
 102+ }else{
 103+ // FIXME: These should be configurable at some point
 104+ $feed = new $wgFeedClasses[ $this->params['feed'] ](
 105+ $wgSitename,
 106+ $wgSitename . ' ' . $this->params['feed'] . ' feed',
 107+ $wgServer.$wgScriptPath,
 108+ date( DATE_ATOM ),
 109+ $wgSitename
 110+ );
 111+ }
 112+
 113+ $feed->outHeader();
 114+
 115+ // main routine to output items
 116+ if ( isset( $this->param['error'] ) ){
 117+ echo $this->param['error'];
 118+ }else{
 119+ $dbr =& wfGetDB( DB_SLAVE );
 120+ $sql = $this->dpl_buildSQL();
 121+ //Debug line
 122+ //echo "\n<p>$sql</p>\n";
 123+ $res = $dbr->query ( $sql );
 124+
 125+ // FIXME: figure out how to fail with no results gracefully
 126+ if ( $dbr->numRows( $res ) == 0 ){
 127+ $feed->outFooter();
 128+ if ( false == $this->params['suppressErrors'] )
 129+ return htmlspecialchars( wfMsg( 'gnsm_noresults' ) );
 130+ else
 131+ return '';
 132+ }
 133+
 134+ while ($row = $dbr->fetchObject( $res ) ) {
 135+ $title = Title::makeTitle( $row->page_namespace, $row->page_title);
 136+
 137+ if ( $title ){
138138 //This is printing things in places it shouldn't
139 - // print $this->params['nameSpace'];
140 -
141 - $titleText = ( true == $this->params['nameSpace'] ) ? $title->getPrefixedText() : $title->getText();
142 -
143 - if ( 'sitemap' == $this->params['feed'] ){
144 -
145 - $this->pubDate = isset( $row->cl_timestamp ) ? $row->cl_timestamp : date( DATE_ATOM );
146 - $feedArticle = new Article( $title );
 139+ // print $this->params['nameSpace'];
147140
148 - $feedItem = new feedSMItem(
149 - trim( $title->getFullURL() ),
150 - wfTimeStamp( TS_ISO_8601, $this->pubDate ),
151 - $this->getKeywords( $title ),
152 - wfTimeStamp( TS_ISO_8601, $feedArticle->getTouched() ),
153 - $feed->getPriority( $this->priority )
154 - );
155 -
156 - }elseif ( ('atom' == $this->params['feed'] ) || ( 'rss' == $this->params['feed'] ) ){
157 -
158 - $this->Date = isset( $row->cl_timestamp ) ? $row->cl_timestamp : date( DATE_ATOM );
159 - if ( isset( $row->comment ) ){
 141+ $titleText = ( true == $this->params['nameSpace'] ) ? $title->getPrefixedText() : $title->getText();
 142+
 143+ if ( 'sitemap' == $this->params['feed'] ){
 144+
 145+ $this->pubDate = isset( $row->cl_timestamp ) ? $row->cl_timestamp : date( DATE_ATOM );
 146+ $feedArticle = new Article( $title );
 147+
 148+ $feedItem = new feedSMItem(
 149+ trim( $title->getFullURL() ),
 150+ wfTimeStamp( TS_ISO_8601, $this->pubDate ),
 151+ $this->getKeywords( $title ),
 152+ wfTimeStamp( TS_ISO_8601, $feedArticle->getTouched() ),
 153+ $feed->getPriority( $this->priority )
 154+ );
 155+
 156+ }elseif ( ('atom' == $this->params['feed'] ) || ( 'rss' == $this->params['feed'] ) ){
 157+
 158+ $this->Date = isset( $row->cl_timestamp ) ? $row->cl_timestamp : date( DATE_ATOM );
 159+ if ( isset( $row->comment ) ){
160160 $comments = htmlspecialchars( $row->comment );
161 - }else{
 161+ }else{
162162 $talkpage = $title->getTalkPage();
163163 $comments = $talkpage->getFullURL();
 164+ }
 165+ $titleText = (true === $this->params['nameSpace'] ) ? $title->getPrefixedText() : $title->getText();
 166+ $feedItem = new FeedItem(
 167+ $titleText,
 168+ $this->feedItemDesc( $row ),
 169+ $title->getFullURL(),
 170+ $this->Date,
 171+ $this->feedItemAuthor( $row ),
 172+ $comments);
 173+ }
 174+ $feed->outItem( $feedItem );
 175+ }
164176 }
165 - $titleText = (true === $this->params['nameSpace'] ) ? $title->getPrefixedText() : $title->getText();
166 - $feedItem = new FeedItem(
167 - $titleText,
168 - $this->feedItemDesc( $row ),
169 - $title->getFullURL(),
170 - $this->Date,
171 - $this->feedItemAuthor( $row ),
172 - $comments);
173 - }
174 - $feed->outItem( $feedItem );
175177 }
176 - }
177 - }
178 - $feed->outFooter();
179 - }
180 -
181 - /**
182 - * Build sql
183 - **/
184 - public function dpl_buildSQL(){
185 -
186 - $sqlSelectFrom = 'SELECT page_namespace, page_title, page_id, c1.cl_timestamp FROM ' . $this->params['dbr']->tableName( 'page' );
187 -
188 - if ( $this->params['nameSpace'] ){
189 - $sqlWhere = ' WHERE page_namespace=' . $this->params['iNameSpace'] . ' ';
190 - }else{
191 - $sqlWhere = ' WHERE 1=1 ';
192 - }
193 -
194 - // If flagged revisions is in use, check which options selected.
195 - // FIXME: double check the default options in function::dpl_parm; what should it default to?
196 - if( function_exists('efLoadFlaggedRevs') ) {
197 - $flaggedPages = $this->params['dbr']->tableName( 'flaggedpages' );
198 - $filterSet = array( 'only', 'exclude' );
199 - # Either involves the same JOIN here...
200 - if( in_array( $this->params['stable'], $filterSet ) || in_array( $this->params['quality'], $filterSet ) ) {
201 - $sqlSelectFrom .= " LEFT JOIN $flaggedPages ON page_id = fp_page_id";
202 - }
203 - switch( $this->params['stable'] ){
204 - case 'only':
205 - $sqlWhere .= ' AND fp_stable IS NOT NULL ';
206 - break;
207 - case 'exclude':
208 - $sqlWhere .= ' AND fp_stable IS NULL ';
209 - break;
210 - }
211 - switch( $this->params['quality'] ){
212 - case 'only':
213 - $sqlWhere .= ' AND fp_quality >= 1';
214 - break;
215 - case 'exclude':
216 - $sqlWhere .= ' AND fp_quality = 0';
217 - break;
218 - }
 178+ $feed->outFooter();
219179 }
220 -
221 - switch ( $this->params['redirects'] )
222 - {
223 - case 'only':
224 - $sqlWhere .= ' AND page_is_redirect = 1 ';
225 - break;
226 - case 'exclude':
227 - $sqlWhere .= ' AND page_is_redirect = 0 ';
228 - break;
229 - }
230 -
231 - $currentTableNumber = 0;
232 -
233 - for ( $i = 0; $i < $this->params['catCount']; $i++ ){
234180
235 - $sqlSelectFrom .= ' INNER JOIN ' . $this->params['dbr']->tableName( 'categorylinks' );
236 - $sqlSelectFrom .= ' AS c' . ( $currentTableNumber + 1 ) . ' ON page_id = c';
237 - $sqlSelectFrom .= ( $currentTableNumber + 1 ) . '.cl_from AND c' . ( $currentTableNumber + 1 );
 181+ /**
 182+ * Build sql
 183+ **/
 184+ public function dpl_buildSQL(){
 185+
 186+ $sqlSelectFrom = 'SELECT page_namespace, page_title, page_id, c1.cl_timestamp FROM ' . $this->params['dbr']->tableName( 'page' );
238187
239 - $sqlSelectFrom .= '.cl_to=' . $this->params['dbr']->addQuotes( $this->categories[$i]->getDBkey() );
240 -
241 - $currentTableNumber++;
242 - }
 188+ if ( $this->params['nameSpace'] ){
 189+ $sqlWhere = ' WHERE page_namespace=' . $this->params['iNameSpace'] . ' ';
 190+ }else{
 191+ $sqlWhere = ' WHERE 1=1 ';
 192+ }
243193
244 - for ( $i = 0; $i < $this->params['notCatCount']; $i++ ){
245 - //echo "notCategory parameter $i<br />\n";
246 - $sqlSelectFrom .= ' LEFT OUTER JOIN ' . $this->params['dbr']->tableName( 'categorylinks' );
247 - $sqlSelectFrom .= ' AS c' . ( $currentTableNumber + 1 ) . ' ON page_id = c' . ( $currentTableNumber + 1 );
248 - $sqlSelectFrom .= '.cl_from AND c' . ( $currentTableNumber + 1 );
249 - $sqlSelectFrom .= '.cl_to=' . $this->params['dbr']->addQuotes( $this->notCategories[$i]->getDBkey() );
250 -
251 - $sqlWhere .= ' AND c' . ( $currentTableNumber + 1 ) . '.cl_to IS NULL';
252 -
253 - $currentTableNumber++;
254 - }
255 -
256 - if ('lastedit' == $this->params['orderMethod'] )
257 - $sqlWhere .= ' ORDER BY page_touched ';
258 - else
259 - $sqlWhere .= ' ORDER BY c1.cl_timestamp ';
260 -
261 - if ( 'descending' == $this->params['order'] )
262 - $sqlWhere .= 'DESC';
263 - else
264 - $sqlWhere .= 'ASC';
265 -
266 - // FIXME: Note: this is not a boolean type check - will also trap count = 0 which may
267 - // accidentally give unlimited returns
268 - if ( 0 < $this->params['count'] ){
269 - $sqlWhere .= ' LIMIT ' . $this->params['count'];
270 - }
271 -
272 - //debug line
273 - //echo "<p>$sqlSelectFrom$sqlWhere;</p>\n";
274 -
275 - return $sqlSelectFrom . $sqlWhere;
276 - }
277 -
278 - /**
279 - * Parse parameters
280 - **
281 - * FIXME this includes a lot of DynamicPageList cruft in need of thinning.
282 - **/
283 - public function dpl_parm( $par ){
284 - global $wgContLang;
285 -
286 - $params = array();
287 - // FIXME: note: if ( false === $count ) then no count has ever been set
288 - // however, there's still no guarantee $count <> zero || NULL
289 - $this->params['count'] = $this->wgDPLmaxResultCount;
290 -
291 - $this->params['orderMethod'] = 'categoryadd';
292 - $this->params['order'] = 'descending';
293 - $this->params['redirects'] = 'exclude';
294 - $this->params['stable'] = $this->params['quality'] = 'only';
295 -
296 - $this->params['nameSpace'] = false;
297 - $this->params['iNameSpace'] = 0;
298 -
299 - $this->params['useNameSpace'] = false;
300 - $this->params['useCurId'] = false;
301 -
302 - $this->params['suppressErrors'] = false;
303 -
304 - $this->params['feed'] = 'atom';
305 -
306 - $params = explode( '&', $par );
307 -
308 - $parser = new Parser;
309 - $poptions = new ParserOptions;
310 -
311 - foreach ( $params AS $paramString ){
312 - $param = explode( '=', $paramString );
313 -
314 - if ( count( $param ) < 2 ) continue;
315 -
316 - // not sure this is necessary, or even would work
317 - $param[0] = trim( $param[0] );
318 - $param[1] = trim( $param[1] );
319 -
320 - switch ( $param[0] ){
321 - case 'category':
322 - $title = Title::newFromText( $parser->transformMsg( $param[1], $poptions ) );
323 -
324 - if ( is_object( $title ) ){
325 - $this->categories[] = $title;
326 - }else{
327 - echo "Explode on category.\n";
328 - continue;
329 - }
330 - break;
331 - case 'notcategory':
332 - //echo "Got notcategory $param[1]\n";
333 - $title = Title::newFromText( $parser->transformMsg( $param[1], $poptions ) );
334 - if ( is_object( $title ) )
335 - $this->notCategories[] = $title;
336 - else{
337 - echo 'Explode on notCategory.';
338 - continue;
339 - }
340 - break;
341 - case 'namespace':
342 - if ( $param[1] == intval( $param[1] ) ){
343 - $this->params['iNameSpace'] = intval( $param[1] );
344 - if ( 0 <= $this->params['iNameSpace'] ){
345 - $this->params['nameSpace'] = true;
346 - }else{
347 - $this->params['nameSpace'] = false;
 194+ // If flagged revisions is in use, check which options selected.
 195+ // FIXME: double check the default options in function::dpl_parm; what should it default to?
 196+ if( function_exists('efLoadFlaggedRevs') ) {
 197+ $flaggedPages = $this->params['dbr']->tableName( 'flaggedpages' );
 198+ $filterSet = array( 'only', 'exclude' );
 199+ # Either involves the same JOIN here...
 200+ if( in_array( $this->params['stable'], $filterSet ) || in_array( $this->params['quality'], $filterSet ) ) {
 201+ $sqlSelectFrom .= " LEFT JOIN $flaggedPages ON page_id = fp_page_id";
348202 }
349 - }else{
350 - $ns = $wgContLang->getNsIndex( $param[1] );
351 - if ( null !== $ns ){
352 - $this->params['iNameSpace'] = $ns;
353 - $this->params['nameSpace'] = true;
 203+ switch( $this->params['stable'] ){
 204+ case 'only':
 205+ $sqlWhere .= ' AND fp_stable IS NOT NULL ';
 206+ break;
 207+ case 'exclude':
 208+ $sqlWhere .= ' AND fp_stable IS NULL ';
 209+ break;
354210 }
355 - }
356 - break;
357 - case 'count':
358 - if ( ( $this->wgDPLminResultCount < $param[1] ) && ( $param[1] < $this->wgDPLmaxResultCount ) ){
359 - $this->params['count'] = intval( $param[1] );
360 - }
361 - break;
362 - case 'order';
363 - switch ( $param[1] ){
364 - case 'ascending':
365 - $this->params['order'] = 'ascending';
366 - break;
367 - case 'descending':
368 - default:
369 - $this->params['order'] = 'descending';
370 - break;
371 - }
372 - break;
373 - case 'ordermethod';
374 - switch ( $param[1] ){
375 - case 'lastedit':
376 - $this->params['orderMethod'] = 'lastedit';
377 - break;
378 - case 'categoryadd':
379 - default:
380 - $this->params['orderMethod'] = 'categoryadd';
381 - break;
382 - }
383 - break;
384 - case 'redirects';
385 - switch ( $param[1] ){
386 - case 'include':
387 - $this->params['redirects'] = 'include';
388 - break;
389 - case 'only':
390 - $this->params['redirects'] = 'only';
391 - break;
392 - case 'exclude':
393 - default:
394 - $this->params['redirects'] = 'exclude';
395 - break;
396 - }
397 - break;
398 - case 'stablepages':
399 - switch ( $param[1] ){
400 - case 'include':
401 - $this->params['stable'] = 'include';
402 - break;
403 - case 'exclude':
404 - $this->params['stable'] = 'exclude';
405 - break;
406 - case 'only':
407 - default:
408 - $this->params['stable'] = 'only';
409 - break;
410 - }
411 - break;
412 - case 'qualitypages':
413 - switch ( $param[1] ){
414 - case 'include':
415 - $this->params['quality'] = 'include';
416 - break;
 211+ switch( $this->params['quality'] ){
 212+ case 'only':
 213+ $sqlWhere .= ' AND fp_quality >= 1';
 214+ break;
 215+ case 'exclude':
 216+ $sqlWhere .= ' AND fp_quality = 0';
 217+ break;
 218+ }
 219+ }
 220+
 221+ switch ( $this->params['redirects'] )
 222+ {
417223 case 'only':
418 - $this->params['quality'] = 'only';
 224+ $sqlWhere .= ' AND page_is_redirect = 1 ';
419225 break;
420226 case 'exclude':
421 - default:
422 - $this->params['quality'] = 'exclude';
 227+ $sqlWhere .= ' AND page_is_redirect = 0 ';
423228 break;
424 - }
425 - break;
426 - case 'suppresserrors':
427 - // note: if previously set to true, remains true. malformed does not reset to false.
428 - if ( 'true' == $param[1] ) $this->params['suppressErrors'] = true;
429 - break;
430 - case 'usenamespace':
431 - // note: if previously set to false, remains false. Malformed does not reset to true.
432 - if ( 'false' == $param[1] ) $this->params['useNameSpace'] = false;
433 - break;
434 - case 'usecurid':
435 - // note: if previously set to true, remains true. Malformed does not reset to false.
436 - if ( 'true' == $param[1] ) $this->params['useCurId'] = true;
437 - break;
438 - case 'feed':
439 - $param[1] = strtolower( $param[1] );
440 - switch( $param[1] ){
 229+ }
 230+
 231+ $currentTableNumber = 0;
 232+
 233+ for ( $i = 0; $i < $this->params['catCount']; $i++ ){
 234+
 235+ $sqlSelectFrom .= ' INNER JOIN ' . $this->params['dbr']->tableName( 'categorylinks' );
 236+ $sqlSelectFrom .= ' AS c' . ( $currentTableNumber + 1 ) . ' ON page_id = c';
 237+ $sqlSelectFrom .= ( $currentTableNumber + 1 ) . '.cl_from AND c' . ( $currentTableNumber + 1 );
 238+
 239+ $sqlSelectFrom .= '.cl_to=' . $this->params['dbr']->addQuotes( $this->categories[$i]->getDBkey() );
 240+
 241+ $currentTableNumber++;
 242+ }
 243+
 244+ for ( $i = 0; $i < $this->params['notCatCount']; $i++ ){
 245+ //echo "notCategory parameter $i<br />\n";
 246+ $sqlSelectFrom .= ' LEFT OUTER JOIN ' . $this->params['dbr']->tableName( 'categorylinks' );
 247+ $sqlSelectFrom .= ' AS c' . ( $currentTableNumber + 1 ) . ' ON page_id = c' . ( $currentTableNumber + 1 );
 248+ $sqlSelectFrom .= '.cl_from AND c' . ( $currentTableNumber + 1 );
 249+ $sqlSelectFrom .= '.cl_to=' . $this->params['dbr']->addQuotes( $this->notCategories[$i]->getDBkey() );
 250+
 251+ $sqlWhere .= ' AND c' . ( $currentTableNumber + 1 ) . '.cl_to IS NULL';
 252+
 253+ $currentTableNumber++;
 254+ }
 255+
 256+ if ('lastedit' == $this->params['orderMethod'] )
 257+ $sqlWhere .= ' ORDER BY page_touched ';
 258+ else
 259+ $sqlWhere .= ' ORDER BY c1.cl_timestamp ';
 260+
 261+ if ( 'descending' == $this->params['order'] )
 262+ $sqlWhere .= 'DESC';
 263+ else
 264+ $sqlWhere .= 'ASC';
 265+
 266+ // FIXME: Note: this is not a boolean type check - will also trap count = 0 which may
 267+ // accidentally give unlimited returns
 268+ if ( 0 < $this->params['count'] ){
 269+ $sqlWhere .= ' LIMIT ' . $this->params['count'];
 270+ }
 271+
 272+ //debug line
 273+ //echo "<p>$sqlSelectFrom$sqlWhere;</p>\n";
 274+
 275+ return $sqlSelectFrom . $sqlWhere;
 276+ }
 277+
 278+ /**
 279+ * Parse parameters
 280+ **
 281+ * FIXME this includes a lot of DynamicPageList cruft in need of thinning.
 282+ **/
 283+ public function dpl_parm( $par ){
 284+ global $wgContLang;
 285+ global $wgRequest;
 286+
 287+ $params = $wgRequest->getValues();
 288+ // FIXME: note: if ( false === $count ) then no count has ever been set
 289+ // however, there's still no guarantee $count <> zero || NULL
 290+ $this->params['count'] = $this->wgDPLmaxResultCount;
 291+
 292+ $this->params['orderMethod'] = 'categoryadd';
 293+ $this->params['order'] = 'descending';
 294+ $this->params['redirects'] = 'exclude';
 295+ $this->params['stable'] = $this->params['quality'] = 'only';
 296+
 297+ $this->params['nameSpace'] = false;
 298+ $this->params['iNameSpace'] = 0;
 299+
 300+ $this->params['useNameSpace'] = false;
 301+ $this->params['useCurId'] = false;
 302+
 303+ $this->params['suppressErrors'] = false;
 304+
 305+ $this->params['feed'] = 'atom';
 306+ $feedType = explode( '/', $par, 2);
 307+ switch( strtolower($feedType[0])){
441308 case 'rss':
442 - $this->params['feed'] = 'rss';
443 - break;
 309+ $this->params['feed'] = 'rss';
 310+ break;
444311 case 'sitemap':
445 - $this->params['feed'] = 'sitemap';
446 - break;
 312+ $this->params['feed'] = 'sitemap';
 313+ break;
447314 default:
448 - $this->params['feed'] = 'atom';
449 - break;
450 - }
451 - break;
452 - default:
453 -
454 - }
455 - }
456 -
457 - $this->params['catCount'] = count( $this->categories );
458 - $this->params['notCatCount'] = count( $this->notCategories );
459 - $totalCatCount = $this->params['catCount'] + $this->params['notCatCount'];
460 -
461 - if (( $this->params['catCount'] < 1 && false == $this->params['nameSpace'] ) || ( $totalCatCount < $this->wgDPlminCategories )){
462 - //echo "Boom on catCount\n";
463 - $parser = new Parser;
464 - $poptions = new ParserOptions;
465 - $feed = Title::newFromText( $parser->transformMsg( 'Published', $poptions ) );
466 - if ( is_object( $feed ) ){
467 - $this->categories[] = $feed;
468 - $this->params['catCount'] = count( $this->categories );
469 - }else{
470 - echo "\$feed is not an object.\n";
471 - continue;
472 - }
473 - }
474 -
475 - if ( ( $totalCatCount > $this->wgDPlmaxCategories ) && ( !$this->wgDPLallowUnlimitedCategories ) ){
476 - $this->params['error'] = htmlspecialchars( wfMsg( 'intersection_toomanycats' ) ); // "!!too many categories!!";
 315+ $this->params['feed'] = 'atom';
 316+ break;
 317+ }
 318+
 319+ $parser = new Parser;
 320+ $poptions = new ParserOptions;
 321+
 322+ foreach ( $params as $key=>$value ){
 323+ switch ( $key ){
 324+ case 'category':
 325+ $title = Title::newFromText( $parser->transformMsg( $value, $poptions ) );
 326+
 327+ if ( is_object( $title ) ){
 328+ $this->categories[] = $title;
 329+ }else{
 330+ echo "Explode on category.\n";
 331+ continue;
 332+ }
 333+ break;
 334+ case 'notcategory':
 335+ //echo "Got notcategory $value\n";
 336+ $title = Title::newFromText( $parser->transformMsg( $value, $poptions ) );
 337+ if ( is_object( $title ) )
 338+ $this->notCategories[] = $title;
 339+ else{
 340+ echo 'Explode on notCategory.';
 341+ continue;
 342+ }
 343+ break;
 344+ case 'namespace':
 345+ if ( $value == intval( $value ) ){
 346+ $this->params['iNameSpace'] = intval( $value );
 347+ if ( 0 <= $this->params['iNameSpace'] ){
 348+ $this->params['nameSpace'] = true;
 349+ }else{
 350+ $this->params['nameSpace'] = false;
 351+ }
 352+ }else{
 353+ $ns = $wgContLang->getNsIndex( $value );
 354+ if ( null !== $ns ){
 355+ $this->params['iNameSpace'] = $ns;
 356+ $this->params['nameSpace'] = true;
 357+ }
 358+ }
 359+ break;
 360+ case 'count':
 361+ if ( ( $this->wgDPLminResultCount < $value ) && ( $value < $this->wgDPLmaxResultCount ) ){
 362+ $this->params['count'] = intval( $value );
 363+ }
 364+ break;
 365+ case 'order';
 366+ switch ( $value ){
 367+ case 'ascending':
 368+ $this->params['order'] = 'ascending';
 369+ break;
 370+ case 'descending':
 371+ default:
 372+ $this->params['order'] = 'descending';
 373+ break;
 374+ }
 375+ break;
 376+ case 'ordermethod';
 377+ switch ( $value ){
 378+ case 'lastedit':
 379+ $this->params['orderMethod'] = 'lastedit';
 380+ break;
 381+ case 'categoryadd':
 382+ default:
 383+ $this->params['orderMethod'] = 'categoryadd';
 384+ break;
 385+ }
 386+ break;
 387+ case 'redirects';
 388+ switch ( $value ){
 389+ case 'include':
 390+ $this->params['redirects'] = 'include';
 391+ break;
 392+ case 'only':
 393+ $this->params['redirects'] = 'only';
 394+ break;
 395+ case 'exclude':
 396+ default:
 397+ $this->params['redirects'] = 'exclude';
 398+ break;
 399+ }
 400+ break;
 401+ case 'stablepages':
 402+ switch ( $value ){
 403+ case 'include':
 404+ $this->params['stable'] = 'include';
 405+ break;
 406+ case 'exclude':
 407+ $this->params['stable'] = 'exclude';
 408+ break;
 409+ case 'only':
 410+ default:
 411+ $this->params['stable'] = 'only';
 412+ break;
 413+ }
 414+ break;
 415+ case 'qualitypages':
 416+ switch ( $value ){
 417+ case 'include':
 418+ $this->params['quality'] = 'include';
 419+ break;
 420+ case 'only':
 421+ $this->params['quality'] = 'only';
 422+ break;
 423+ case 'exclude':
 424+ default:
 425+ $this->params['quality'] = 'exclude';
 426+ break;
 427+ }
 428+ break;
 429+ case 'suppresserrors':
 430+ // note: if previously set to true, remains true. malformed does not reset to false.
 431+ if ( 'true' == $value ) $this->params['suppressErrors'] = true;
 432+ break;
 433+ case 'usenamespace':
 434+ // note: if previously set to false, remains false. Malformed does not reset to true.
 435+ if ( 'false' == $value ) $this->params['useNameSpace'] = false;
 436+ break;
 437+ case 'usecurid':
 438+ // note: if previously set to true, remains true. Malformed does not reset to false.
 439+ if ( 'true' == $value ) $this->params['useCurId'] = true;
 440+ break;
 441+ default:
 442+ }
 443+ }
 444+
 445+ $this->params['catCount'] = count( $this->categories );
 446+ $this->params['notCatCount'] = count( $this->notCategories );
 447+ $totalCatCount = $this->params['catCount'] + $this->params['notCatCount'];
 448+
 449+ if (( $this->params['catCount'] < 1 && false == $this->params['nameSpace'] ) || ( $totalCatCount < $this->wgDPlminCategories )){
 450+ //echo "Boom on catCount\n";
 451+ $parser = new Parser;
 452+ $poptions = new ParserOptions;
 453+ $feed = Title::newFromText( $parser->transformMsg( 'Published', $poptions ) );
 454+ if ( is_object( $feed ) ){
 455+ $this->categories[] = $feed;
 456+ $this->params['catCount'] = count( $this->categories );
 457+ }else{
 458+ echo "\$feed is not an object.\n";
 459+ continue;
 460+ }
 461+ }
 462+
 463+ if ( ( $totalCatCount > $this->wgDPlmaxCategories ) && ( !$this->wgDPLallowUnlimitedCategories ) ){
 464+ $this->params['error'] = htmlspecialchars( wfMsg( 'intersection_toomanycats' ) ); // "!!too many categories!!";
 465+ }
 466+
 467+ //disallow showing date if the query doesn't have an inclusion category parameter
 468+ if ( $this->params['count'] < 1 )
 469+ $this->params['addFirstCategoryDate'] = false;
 470+
 471+ $this->params['dbr'] =& wfGetDB( DB_SLAVE );
 472+ return;
477473 }
478 -
479 - //disallow showing date if the query doesn't have an inclusion category parameter
480 - if ( $this->params['count'] < 1 )
481 - $this->params['addFirstCategoryDate'] = false;
482 -
483 - $this->params['dbr'] =& wfGetDB( DB_SLAVE );
484 - return;
485 - }
486 -
487 - function feedItemAuthor( $row ) {
488 - return isset( $row->user_text ) ? $row->user_text : 'Wikinews';
489 - }
490474
491 - function feedItemDesc( $row ) {
492 - return isset( $row->comment ) ? htmlspecialchars( $row->comment ) : '';
493 - }
494 -
495 - function getKeywords ( $title ){
496 - $cats = $title->getParentCategories();
497 - $str = '';
498 - #the following code is based (stolen) from r56954 of flagged revs.
499 - $catMap = Array();
500 - $catMask = Array();
501 - $msg = wfMsg( 'gnsm_categorymap' );
502 - if ( !wfEmptyMsg( 'gnsm_categorymap', $msg ) ) {
503 - $list = explode( "\n*", "\n$msg");
504 - foreach($list as $item) {
505 - $mapping = explode('|', $item, 2);
506 - if ( count( $mapping ) == 2 ) {
507 - if ( trim( $mapping[1] ) == '__MASK__') {
508 - $catMask[trim($mapping[0])] = true;
 475+ function feedItemAuthor( $row ) {
 476+ return isset( $row->user_text ) ? $row->user_text : 'Wikinews';
 477+ }
 478+
 479+ function feedItemDesc( $row ) {
 480+ return isset( $row->comment ) ? htmlspecialchars( $row->comment ) : '';
 481+ }
 482+
 483+ function getKeywords ( $title ){
 484+ $cats = $title->getParentCategories();
 485+ $str = '';
 486+ #the following code is based (stolen) from r56954 of flagged revs.
 487+ $catMap = Array();
 488+ $catMask = Array();
 489+ $msg = wfMsg( 'gnsm_categorymap' );
 490+ if ( !wfEmptyMsg( 'gnsm_categorymap', $msg ) ) {
 491+ $list = explode( "\n*", "\n$msg");
 492+ foreach($list as $item) {
 493+ $mapping = explode('|', $item, 2);
 494+ if ( count( $mapping ) == 2 ) {
 495+ if ( trim( $mapping[1] ) == '__MASK__') {
 496+ $catMask[trim($mapping[0])] = true;
 497+ } else {
 498+ $catMap[trim($mapping[0])] = trim($mapping[1]);
 499+ }
 500+ }
 501+ }
 502+ }
 503+ foreach ( $cats as $key => $val ){
 504+ $cat = str_replace( '_', ' ', trim( substr( $key, strpos( $key, ':' ) + 1 ) ) );
 505+ if (!isset($catMask[$cat])) {
 506+ if (isset($catMap[$cat])) {
 507+ $str .= ', ' . str_replace( '_', ' ', trim ( $catMap[$cat] ) );
509508 } else {
510 - $catMap[trim($mapping[0])] = trim($mapping[1]);
 509+ $str .= ', ' . $cat;
511510 }
512511 }
513512 }
 513+ $str = substr( $str, 2 ); #to remove leading ', '
 514+ return $str;
514515 }
515 - foreach ( $cats as $key => $val ){
516 - $cat = str_replace( '_', ' ', trim( substr( $key, strpos( $key, ':' ) + 1 ) ) );
517 - if (!isset($catMask[$cat])) {
518 - if (isset($catMap[$cat])) {
519 - $str .= ', ' . str_replace( '_', ' ', trim ( $catMap[$cat] ) );
520 - } else {
521 - $str .= ', ' . $cat;
522 - }
523 - }
524 - }
525 - $str = substr( $str, 2 ); #to remove leading ', '
526 - return $str;
527 - }
528516
529517 }
530518
@@ -533,131 +521,145 @@
534522 * Base class for basic SiteMap support, for building url containers.
535523 **/
536524 class feedSMItem{
537 - /**
538 - * Var string
539 - **/
540 - var $url = '';
541 - var $pubDate = '';
542 - var $keywords = '';
543 - var $lastMod = '';
544 - var $priority = '';
545 -
546 - function __construct( $url, $pubDate, $keywords = '', $lastMod = '', $priority = ''){
547 - $this->url = $url;
548 - $this->pubDate = $pubDate;
549 - $this->keywords = $keywords;
550 - $this->lastMod = $lastMod;
551 - $this->priority = $priority;
552 - }
553 -
554 - public function xmlEncode( $string ){
555 - $string = str_replace( "\r\n", "\n", $string );
556 - $string = preg_replace( '/[\x00-\x08\x0b\x0c\x0e-\x1f]/', '', $string );
557 - return htmlspecialchars( $string );
558 - }
559 -
560 - public function getUrl(){
561 - return $this->url;
562 - }
563 -
564 - public function getPriority(){
565 - return $this->priority;
566 - }
567 -
568 - public function getLastMod(){
569 - return $this->lastMod;
570 - }
 525+ /**
 526+ * Var string
 527+ **/
 528+ var $url = '';
 529+ var $pubDate = '';
 530+ var $keywords = '';
 531+ var $lastMod = '';
 532+ var $priority = '';
571533
572 - public function getKeywords (){
573 - return $this->xmlEncode( $this->keywords );
574 - }
575 -
576 - public function getPubDate(){
577 - return $this->pubDate;
578 - }
579 -
580 - function formatTime( $ts ) {
581 - // need to use RFC 822 time format at least for rss2.0
582 - return gmdate( 'Y-m-d\TH:i:s', wfTimestamp( TS_UNIX, $ts ) );
583 - }
584 -
585 - /**
586 - * Setup and send HTTP headers. Don't send any content;
587 - * content might end up being cached and re-sent with
588 - * these same headers later.
589 - *
590 - * This should be called from the outHeader() method,
591 - * but can also be called separately.
592 - *
593 - * @public
594 - **/
595 - function httpHeaders() {
596 - global $wgOut;
597 - # We take over from $wgOut, excepting its cache header info
598 - $wgOut->disable();
599 - $mimetype = $this->contentType();
600 - header( "Content-type: $mimetype; charset=UTF-8" );
601 - $wgOut->sendCacheControl();
 534+ function __construct( $url, $pubDate, $keywords = '', $lastMod = '', $priority = ''){
 535+ $this->url = $url;
 536+ $this->pubDate = $pubDate;
 537+ $this->keywords = $keywords;
 538+ $this->lastMod = $lastMod;
 539+ $this->priority = $priority;
 540+ }
602541
603 - }
604 -
605 - function outXmlHeader(){
606 - global $wgStylePath, $wgStyleVersion;
 542+ public function xmlEncode( $string ){
 543+ $string = str_replace( "\r\n", "\n", $string );
 544+ $string = preg_replace( '/[\x00-\x08\x0b\x0c\x0e-\x1f]/', '', $string );
 545+ return htmlspecialchars( $string );
 546+ }
607547
608 - $this->httpHeaders();
609 - echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
610 - }
 548+ public function getUrl(){
 549+ return $this->url;
 550+ }
611551
612 - /**
613 - * Return an internet media type to be sent in the headers.
614 - *
615 - * @return string
616 - * @private
617 - **/
618 - function contentType() {
619 - global $wgRequest;
620 - $ctype = $wgRequest->getVal('ctype','application/xml');
621 - $allowedctypes = array('application/xml','text/xml','application/rss+xml','application/atom+xml');
622 - return (in_array($ctype, $allowedctypes) ? $ctype : 'application/xml');
623 - }
 552+ public function getPriority(){
 553+ return $this->priority;
 554+ }
624555
 556+ public function getLastMod(){
 557+ return $this->lastMod;
 558+ }
 559+
 560+ public function getKeywords (){
 561+ return $this->xmlEncode( $this->keywords );
 562+ }
 563+
 564+ public function getPubDate(){
 565+ return $this->pubDate;
 566+ }
 567+
 568+ function formatTime( $ts ) {
 569+ // need to use RFC 822 time format at least for rss2.0
 570+ return gmdate( 'Y-m-d\TH:i:s', wfTimestamp( TS_UNIX, $ts ) );
 571+ }
 572+
 573+ /**
 574+ * Setup and send HTTP headers. Don't send any content;
 575+ * content might end up being cached and re-sent with
 576+ * these same headers later.
 577+ *
 578+ * This should be called from the outHeader() method,
 579+ * but can also be called separately.
 580+ *
 581+ * @public
 582+ **/
 583+ function httpHeaders() {
 584+ global $wgOut;
 585+ # We take over from $wgOut, excepting its cache header info
 586+ $wgOut->disable();
 587+ $mimetype = $this->contentType();
 588+ header( "Content-type: $mimetype; charset=UTF-8" );
 589+ $wgOut->sendCacheControl();
 590+
 591+ }
 592+
 593+ function outXmlHeader(){
 594+ global $wgStylePath, $wgStyleVersion;
 595+
 596+ $this->httpHeaders();
 597+ echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
 598+ }
 599+
 600+ /**
 601+ * Return an internet media type to be sent in the headers.
 602+ *
 603+ * @return string
 604+ * @private
 605+ **/
 606+ function contentType() {
 607+ global $wgRequest;
 608+ $ctype = $wgRequest->getVal('ctype','application/xml');
 609+ $allowedctypes = array('application/xml','text/xml','application/rss+xml','application/atom+xml');
 610+ return (in_array($ctype, $allowedctypes) ? $ctype : 'application/xml');
 611+ }
 612+
625613 }
626614
627615 class SitemapFeed extends feedSMItem{
628 - /**
629 - * Output feed headers
630 - **/
631 - function outHeader(){
632 - $this->outXmlHeader();
633 - ?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
634 -<?php
635 - }
636 - /**
637 - * Output a SiteMap 0.9 item
638 - * @param feedSMItem item to be output
639 - **/
640 - function outItem( $item ) {
 616+ /**
 617+ * Output feed headers
 618+ **/
 619+ function outHeader(){
 620+ $this->outXmlHeader();
 621+ ?>
 622+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
 623+ xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
 624+ <?php
 625+ }
 626+ /**
 627+ * Output a SiteMap 0.9 item
 628+ * @param feedSMItem item to be output
 629+ **/
 630+ function outItem( $item ) {
 631+ ?>
 632+<url>
 633+<loc>
 634+ <?php print $item->getUrl() ?>
 635+</loc>
 636+<news:news>
 637+ <news:publication_date>
 638+ <?php print $item->getPubDate() ?>
 639+ </news:publication_date>
 640+ <?php if( $item->getKeywords() ){
 641+ echo '<news:keywords>' . $item->getKeywords() . "</news:keywords>\n";
 642+ }
641643 ?>
642 - <url>
643 - <loc><?php print $item->getUrl() ?></loc>
644 - <news:news>
645 - <news:publication_date><?php print $item->getPubDate() ?></news:publication_date>
646 - <?php if( $item->getKeywords() ){
647 - echo '<news:keywords>' . $item->getKeywords() . "</news:keywords>\n";
648 - }
649 -?> </news:news>
650 -<?php if( $item->getLastMod() ){ ?> <lastmod><?php print $item->getLastMod(); ?></lastmod>
651 -<?php }?>
652 -<?php if( $item->getPriority() ){ ?> <priority><? print $item->getPriority(); ?></priority><?php }?>
653 - </url>
654 -<?php
655 - }
656 -
657 - /**
658 - * Output SiteMap 0.9 footer
659 - **/
660 - function outFooter(){
661 - echo '</urlset>';
662 - }
 644+</news:news>
 645+ <?php if( $item->getLastMod() ){ ?>
 646+<lastmod>
 647+ <?php print $item->getLastMod(); ?>
 648+</lastmod>
 649+ <?php }?>
 650+ <?php if( $item->getPriority() ){ ?>
 651+<priority>
 652+ <? print $item->getPriority(); ?>
 653+</priority>
 654+ <?php }?>
 655+</url>
 656+ <?php
 657+ }
663658
 659+ /**
 660+ * Output SiteMap 0.9 footer
 661+ **/
 662+ function outFooter(){
 663+ echo '</urlset>';
 664+ }
 665+
664666 }

Status & tagging log