r52235 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r52234‎ | r52235 | r52236 >
Date:11:16, 21 June 2009
Author:ialex
Status:ok
Tags:
Comment:
svn:eol-style
Modified paths:
  • /trunk/extensions/FlaggedRevs/specialpages/ProblemChanges_body.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialActiveusers.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/specials/SpecialActiveusers.php
@@ -1,143 +1,143 @@
2 -<?php
3 -
4 -# Copyright (C) 2008 Aaron Schulz
5 -#
6 -# http://www.mediawiki.org/
7 -#
8 -# This program is free software; you can redistribute it and/or modify
9 -# it under the terms of the GNU General Public License as published by
10 -# the Free Software Foundation; either version 2 of the License, or
11 -# (at your option) any later version.
12 -#
13 -# This program is distributed in the hope that it will be useful,
14 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
15 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 -# GNU General Public License for more details.
17 -#
18 -# You should have received a copy of the GNU General Public License along
19 -# with this program; if not, write to the Free Software Foundation, Inc.,
20 -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 -# http://www.gnu.org/copyleft/gpl.html
22 -/**
23 - *
24 - * @addtogroup SpecialPage
25 - */
26 -
27 -/**
28 - * This class is used to get a list of user. The ones with specials
29 - * rights (sysop, bureaucrat, developer) will have them displayed
30 - * next to their names.
31 - *
32 - * @addtogroup SpecialPage
33 - */
34 -
35 -class ActiveUsersPager extends UsersPager {
36 -
37 - function __construct($group=null) {
38 - global $wgRequest;
39 - $un = $wgRequest->getText( 'username' );
40 - $this->requestedUser = '';
41 - if ( $un != '' ) {
42 - $username = Title::makeTitleSafe( NS_USER, $un );
43 - if( ! is_null( $username ) ) {
44 - $this->requestedUser = $username->getText();
45 - }
46 - }
47 - parent::__construct();
48 - }
49 -
50 -
51 - function getIndexField() {
52 - return 'rc_user_text';
53 - }
54 -
55 - function getQueryInfo() {
56 - $dbr = wfGetDB( DB_SLAVE );
57 - $conds = array();
58 - // don't show hidden names
59 - $conds[] = 'ipb_deleted IS NULL';
60 - $useIndex = $dbr->useIndexClause('rc_user_text');
61 - if( $this->requestedUser != "" ) {
62 - $conds[] = 'rc_user_text >= ' . $dbr->addQuotes( $this->requestedUser );
63 - }
64 - $conds[] = 'rc_user > 0'; // Users - no anons
65 -
66 - list ($recentchanges,$ipblocks) = $dbr->tableNamesN('recentchanges','ipblocks');
67 -
68 - $query = array(
69 - 'tables' => " $recentchanges $useIndex
70 - LEFT JOIN $ipblocks ON rc_user=ipb_user AND ipb_auto=0 AND ipb_deleted=1 ",
71 - 'fields' => array('rc_user_text AS user_name', // inheritance
72 - 'rc_user_text', // for Pager
73 - 'MAX(rc_user) AS user_id',
74 - 'COUNT(*) AS recentedits',
75 - 'MAX(ipb_user) AS blocked'),
76 - 'options' => array('GROUP BY' => 'user_name'),
77 - 'conds' => $conds
78 - );
79 - return $query;
80 - }
81 -
82 - function formatRow( $row ) {
83 - $userPage = Title::makeTitle( NS_USER, $row->rc_user_text );
84 - $name = $this->getSkin()->makeLinkObj( $userPage, htmlspecialchars( $userPage->getText() ) );
85 -
86 - $list = array();
87 - foreach( self::getGroups( $row->user_id ) as $group )
88 - $list[] = self::buildGroupLink( $group );
89 - $groups = implode( ', ', $list );
90 -
91 - $item = wfSpecialList( $name, $groups );
92 - $count = wfMsgExt( 'activeusers-count', array('parsemag'), $row->recentedits );
93 - $blocked = $row->blocked ? ' '.wfMsg('listusers-blocked') : '';
94 -
95 - return "<li>{$item} [{$count}]{$blocked}</li>";
96 - }
97 -
98 - function getPageHeader() {
99 - global $wgScript, $wgRequest;
100 - $self = $this->getTitle();
101 -
102 - # Form tag
103 - $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) .
104 - '<fieldset>' .
105 - Xml::element( 'legend', array(), wfMsg( 'activeusers' ) );
106 - $out .= Xml::hidden( 'title', $self->getPrefixedDbKey() );
107 -
108 - # Username field
109 - $out .= Xml::label( wfMsg( 'activeusers-from' ), 'offset' ) . ' ' .
110 - Xml::input( 'username', 20, $this->requestedUser, array( 'id' => 'offset' ) ) . ' ';
111 -
112 - # Submit button and form bottom
113 - if( $this->mLimit )
114 - $out .= Xml::hidden( 'limit', $this->mLimit );
115 - $out .= Xml::submitButton( wfMsg( 'allpagessubmit' ) );
116 -
117 - $out .= '</fieldset>' . Xml::closeElement( 'form' );
118 -
119 - return $out;
120 - }
121 -}
122 -
123 -/**
124 - * constructor
125 - * $par string (optional) A group to list users from
126 - */
127 -function wfSpecialActiveusers( $par = null ) {
128 - global $wgRequest, $wgOut;
129 -
130 - $up = new ActiveUsersPager();
131 -
132 - # getBody() first to check, if empty
133 - $usersbody = $up->getBody();
134 - $s = $up->getPageHeader();
135 - if( $usersbody ) {
136 - $s .= $up->getNavigationBar();
137 - $s .= '<ul>' . $usersbody . '</ul>';
138 - $s .= $up->getNavigationBar() ;
139 - } else {
140 - $s .= '<p>' . wfMsgHTML('activeusers-noresult') . '</p>';
141 - };
142 -
143 - $wgOut->addHTML( $s );
144 -}
 2+<?php
 3+
 4+# Copyright (C) 2008 Aaron Schulz
 5+#
 6+# http://www.mediawiki.org/
 7+#
 8+# This program is free software; you can redistribute it and/or modify
 9+# it under the terms of the GNU General Public License as published by
 10+# the Free Software Foundation; either version 2 of the License, or
 11+# (at your option) any later version.
 12+#
 13+# This program is distributed in the hope that it will be useful,
 14+# but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+# GNU General Public License for more details.
 17+#
 18+# You should have received a copy of the GNU General Public License along
 19+# with this program; if not, write to the Free Software Foundation, Inc.,
 20+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 21+# http://www.gnu.org/copyleft/gpl.html
 22+/**
 23+ *
 24+ * @addtogroup SpecialPage
 25+ */
 26+
 27+/**
 28+ * This class is used to get a list of user. The ones with specials
 29+ * rights (sysop, bureaucrat, developer) will have them displayed
 30+ * next to their names.
 31+ *
 32+ * @addtogroup SpecialPage
 33+ */
 34+
 35+class ActiveUsersPager extends UsersPager {
 36+
 37+ function __construct($group=null) {
 38+ global $wgRequest;
 39+ $un = $wgRequest->getText( 'username' );
 40+ $this->requestedUser = '';
 41+ if ( $un != '' ) {
 42+ $username = Title::makeTitleSafe( NS_USER, $un );
 43+ if( ! is_null( $username ) ) {
 44+ $this->requestedUser = $username->getText();
 45+ }
 46+ }
 47+ parent::__construct();
 48+ }
 49+
 50+
 51+ function getIndexField() {
 52+ return 'rc_user_text';
 53+ }
 54+
 55+ function getQueryInfo() {
 56+ $dbr = wfGetDB( DB_SLAVE );
 57+ $conds = array();
 58+ // don't show hidden names
 59+ $conds[] = 'ipb_deleted IS NULL';
 60+ $useIndex = $dbr->useIndexClause('rc_user_text');
 61+ if( $this->requestedUser != "" ) {
 62+ $conds[] = 'rc_user_text >= ' . $dbr->addQuotes( $this->requestedUser );
 63+ }
 64+ $conds[] = 'rc_user > 0'; // Users - no anons
 65+
 66+ list ($recentchanges,$ipblocks) = $dbr->tableNamesN('recentchanges','ipblocks');
 67+
 68+ $query = array(
 69+ 'tables' => " $recentchanges $useIndex
 70+ LEFT JOIN $ipblocks ON rc_user=ipb_user AND ipb_auto=0 AND ipb_deleted=1 ",
 71+ 'fields' => array('rc_user_text AS user_name', // inheritance
 72+ 'rc_user_text', // for Pager
 73+ 'MAX(rc_user) AS user_id',
 74+ 'COUNT(*) AS recentedits',
 75+ 'MAX(ipb_user) AS blocked'),
 76+ 'options' => array('GROUP BY' => 'user_name'),
 77+ 'conds' => $conds
 78+ );
 79+ return $query;
 80+ }
 81+
 82+ function formatRow( $row ) {
 83+ $userPage = Title::makeTitle( NS_USER, $row->rc_user_text );
 84+ $name = $this->getSkin()->makeLinkObj( $userPage, htmlspecialchars( $userPage->getText() ) );
 85+
 86+ $list = array();
 87+ foreach( self::getGroups( $row->user_id ) as $group )
 88+ $list[] = self::buildGroupLink( $group );
 89+ $groups = implode( ', ', $list );
 90+
 91+ $item = wfSpecialList( $name, $groups );
 92+ $count = wfMsgExt( 'activeusers-count', array('parsemag'), $row->recentedits );
 93+ $blocked = $row->blocked ? ' '.wfMsg('listusers-blocked') : '';
 94+
 95+ return "<li>{$item} [{$count}]{$blocked}</li>";
 96+ }
 97+
 98+ function getPageHeader() {
 99+ global $wgScript, $wgRequest;
 100+ $self = $this->getTitle();
 101+
 102+ # Form tag
 103+ $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) .
 104+ '<fieldset>' .
 105+ Xml::element( 'legend', array(), wfMsg( 'activeusers' ) );
 106+ $out .= Xml::hidden( 'title', $self->getPrefixedDbKey() );
 107+
 108+ # Username field
 109+ $out .= Xml::label( wfMsg( 'activeusers-from' ), 'offset' ) . ' ' .
 110+ Xml::input( 'username', 20, $this->requestedUser, array( 'id' => 'offset' ) ) . ' ';
 111+
 112+ # Submit button and form bottom
 113+ if( $this->mLimit )
 114+ $out .= Xml::hidden( 'limit', $this->mLimit );
 115+ $out .= Xml::submitButton( wfMsg( 'allpagessubmit' ) );
 116+
 117+ $out .= '</fieldset>' . Xml::closeElement( 'form' );
 118+
 119+ return $out;
 120+ }
 121+}
 122+
 123+/**
 124+ * constructor
 125+ * $par string (optional) A group to list users from
 126+ */
 127+function wfSpecialActiveusers( $par = null ) {
 128+ global $wgRequest, $wgOut;
 129+
 130+ $up = new ActiveUsersPager();
 131+
 132+ # getBody() first to check, if empty
 133+ $usersbody = $up->getBody();
 134+ $s = $up->getPageHeader();
 135+ if( $usersbody ) {
 136+ $s .= $up->getNavigationBar();
 137+ $s .= '<ul>' . $usersbody . '</ul>';
 138+ $s .= $up->getNavigationBar() ;
 139+ } else {
 140+ $s .= '<p>' . wfMsgHTML('activeusers-noresult') . '</p>';
 141+ };
 142+
 143+ $wgOut->addHTML( $s );
 144+}
Property changes on: trunk/phase3/includes/specials/SpecialActiveusers.php
___________________________________________________________________
Name: svn:eol-style
145145 + native
Index: trunk/extensions/FlaggedRevs/specialpages/ProblemChanges_body.php
@@ -1,373 +1,373 @@
2 -<?php
3 -if ( !defined( 'MEDIAWIKI' ) ) {
4 - echo "FlaggedRevs extension\n";
5 - exit( 1 );
6 -}
7 -
8 -class ProblemChanges extends SpecialPage
9 -{
10 - public function __construct() {
11 - parent::__construct( 'ProblemChanges' );
12 - $this->includable( true );
13 - wfLoadExtensionMessages( 'ProblemChanges' );
14 - wfLoadExtensionMessages( 'OldReviewedPages' );
15 - wfLoadExtensionMessages( 'FlaggedRevs' );
16 - }
17 -
18 - public function execute( $par ) {
19 - global $wgRequest, $wgUser, $wgOut;
20 - $this->setHeaders();
21 - $this->skin = $wgUser->getSkin();
22 - $this->level = $wgRequest->getInt( 'level', -1 );
23 - $this->tag = trim( $wgRequest->getVal( 'tagfilter' ) );
24 - $this->category = trim( $wgRequest->getVal( 'category' ) );
25 - $feedType = $wgRequest->getVal( 'feed' );
26 - if( $feedType ) {
27 - return $this->feed( $feedType );
28 - }
29 - $this->setSyndicated();
30 - $this->showList( $par );
31 - }
32 -
33 - protected function setSyndicated() {
34 - global $wgOut, $wgRequest;
35 - $queryParams = array(
36 - 'level' => $wgRequest->getIntOrNull( 'level' ),
37 - 'tag' => $wgRequest->getVal( 'tag' ),
38 - 'category' => $wgRequest->getVal( 'category' ),
39 - );
40 - $wgOut->setSyndicated( true );
41 - $wgOut->setFeedAppendQuery( wfArrayToCGI( $queryParams ) );
42 - }
43 -
44 - public function showList( $par ) {
45 - global $wgOut, $wgScript, $wgUser, $wgFlaggedRevsNamespaces;
46 - $limit = $this->parseParams( $par );
47 - $pager = new ProblemChangesPager( $this, $this->level, $this->category, $this->tag );
48 - // Apply limit if transcluded
49 - $pager->mLimit = $limit ? $limit : $pager->mLimit;
50 - // Viewing the page normally...
51 - if( !$this->including() ) {
52 - $action = htmlspecialchars( $wgScript );
53 - $tagForm = ChangeTags::buildTagFilterSelector( $this->tag );
54 - $wgOut->addHTML(
55 - "<form action=\"$action\" method=\"get\">\n" .
56 - '<fieldset><legend>' . wfMsg('problemchanges-legend') . '</legend>' .
57 - Xml::hidden( 'title', $this->getTitle()->getPrefixedDBKey() )
58 - );
59 - $form =
60 - ( FlaggedRevs::qualityVersions() ?
61 - "<span style='white-space: nowrap;'>" .
62 - FlaggedRevsXML::getLevelMenu( $this->level, 'revreview-filter-stable' ) . '</span> '
63 - : ""
64 - );
65 - if( count($tagForm) ) {
66 - $form .= Xml::tags( 'td', array( 'class' => 'mw-label' ), $tagForm[0] );
67 - $form .= Xml::tags( 'td', array( 'class' => 'mw-input' ), $tagForm[1] );
68 - }
69 - $form .= '<br/>' .
70 - Xml::label( wfMsg("problemchanges-category"), 'wpCategory' ) . '&nbsp;' .
71 - Xml::input( 'category', 30, $this->category, array('id' => 'wpCategory') ) . ' ';
72 - $form .= Xml::submitButton( wfMsg( 'allpagessubmit' ) ) . "\n" .
73 - "</fieldset></form>";
74 - # Add filter options
75 - $wgOut->addHTML( $form );
76 - # Add list output (skip if no tag given)
77 - $num = strlen($this->tag) && $pager->getNumRows();
78 - if( $num ) {
79 - $wgOut->addHTML( $pager->getNavigationBar() );
80 - $wgOut->addHTML( $pager->getBody() );
81 - $wgOut->addHTML( $pager->getNavigationBar() );
82 - } else if( strlen($this->tag) ) {
83 - $wgOut->addHTML( wfMsgExt('problemchanges-none', array('parse') ) );
84 - }
85 - // If this page is transcluded...
86 - } else {
87 - if( strlen($this->tag) && $pager->getNumRows() ) {
88 - $wgOut->addHTML( $pager->getBody() );
89 - } else if( strlen($this->tag) ) {
90 - $wgOut->addHTML( wfMsgExt('problemchanges-none', array('parse') ) );
91 - }
92 - }
93 - }
94 -
95 - protected function parseParams( $par ) {
96 - global $wgLang;
97 - $bits = preg_split( '/\s*,\s*/', trim( $par ) );
98 - $limit = false;
99 - foreach( $bits as $bit ) {
100 - if( is_numeric( $bit ) )
101 - $limit = intval( $bit );
102 - $m = array();
103 - if( preg_match( '/^limit=(\d+)$/', $bit, $m ) )
104 - $limit = intval($m[1]);
105 - if( preg_match( '/^category=(.+)$/', $bit, $m ) )
106 - $this->category = $m[1];
107 - if( preg_match( '/^tagfilter=(.+)$/', $bit, $m ) )
108 - $this->tag = $m[1];
109 - }
110 - return $limit;
111 - }
112 -
113 - /**
114 - * Output a subscription feed listing recent edits to this page.
115 - * @param string $type
116 - */
117 - protected function feed( $type ) {
118 - global $wgFeed, $wgFeedClasses, $wgRequest;
119 - if( !$wgFeed ) {
120 - global $wgOut;
121 - $wgOut->addWikiMsg( 'feed-unavailable' );
122 - return;
123 - }
124 - if( !isset( $wgFeedClasses[$type] ) ) {
125 - global $wgOut;
126 - $wgOut->addWikiMsg( 'feed-invalid' );
127 - return;
128 - }
129 - $feed = new $wgFeedClasses[$type](
130 - $this->feedTitle(),
131 - wfMsg( 'tagline' ),
132 - $this->getTitle()->getFullUrl() );
133 -
134 - $pager = new ProblemChangesPager( $this, $this->category );
135 - $limit = $wgRequest->getInt( 'limit', 50 );
136 - global $wgFeedLimit;
137 - $pager->mLimit = min( $wgFeedLimit, $limit );
138 -
139 - $feed->outHeader();
140 - if( $pager->getNumRows() > 0 ) {
141 - while( $row = $pager->mResult->fetchObject() ) {
142 - $feed->outItem( $this->feedItem( $row ) );
143 - }
144 - }
145 - $feed->outFooter();
146 - }
147 -
148 - protected function feedTitle() {
149 - global $wgContLanguageCode, $wgSitename;
150 - $page = SpecialPage::getPage( 'problemchanges' );
151 - $desc = $page->getDescription();
152 - return "$wgSitename - $desc [$wgContLanguageCode]";
153 - }
154 -
155 - protected function feedItem( $row ) {
156 - $title = Title::MakeTitle( $row->page_namespace, $row->page_title );
157 - if( $title ) {
158 - $date = $row->pending_since;
159 - $comments = $title->getTalkPage()->getFullURL();
160 - $curRev = Revision::newFromTitle( $title );
161 - return new FeedItem(
162 - $title->getPrefixedText(),
163 - FeedUtils::formatDiffRow( $title, $row->stable, $curRev->getId(),
164 - $row->pending_since, $curRev->getComment() ),
165 - $title->getFullURL(),
166 - $date,
167 - $curRev->getUserText(),
168 - $comments
169 - );
170 - } else {
171 - return NULL;
172 - }
173 - }
174 -
175 - public function formatRow( $row ) {
176 - global $wgLang, $wgUser, $wgMemc;
177 -
178 - $title = Title::makeTitle( $row->page_namespace, $row->page_title );
179 - $link = $this->skin->makeKnownLinkObj( $title );
180 - $css = $stxt = $review = $quality = $underReview = '';
181 - $review = $this->skin->makeKnownLinkObj( $title, wfMsg('oldreviewed-diff'),
182 - "diff=cur&oldid={$row->stable}&reviewform=1&diffonly=0" );
183 - # Show quality level if there are several
184 - if( FlaggedRevs::qualityVersions() ) {
185 - $quality = $row->quality ?
186 - wfMsgHtml('revreview-lev-quality') : wfMsgHtml('revreview-lev-sighted');
187 - $quality = " <b>[{$quality}]</b>";
188 - }
189 - # Is anybody watching?
190 - if( !$this->including() && $wgUser->isAllowed( 'unreviewedpages' ) ) {
191 - $uw = UnreviewedPages::usersWatching( $title );
192 - $watching = $uw
193 - ? wfMsgExt('oldreviewedpages-watched','parsemag',$uw,$uw)
194 - : wfMsgHtml('oldreviewedpages-unwatched');
195 - $watching = " {$watching}";
196 - } else {
197 - $uw = -1;
198 - $watching = ''; // leave out data
199 - }
200 - # Get how long the first unreviewed edit has been waiting...
201 - if( $row->pending_since ) {
202 - static $currentTime;
203 - $currentTime = wfTimestamp( TS_UNIX ); // now
204 - $firstPendingTime = wfTimestamp( TS_UNIX, $row->pending_since );
205 - $hours = ($currentTime - $firstPendingTime)/3600;
206 - // After three days, just use days
207 - if( $hours > (3*24) ) {
208 - $days = round($hours/24,0);
209 - $age = wfMsgExt('oldreviewedpages-days',array('parsemag'),$days);
210 - // If one or more hours, use hours
211 - } elseif( $hours >= 1 ) {
212 - $hours = round($hours,0);
213 - $age = wfMsgExt('oldreviewedpages-hours',array('parsemag'),$hours);
214 - } else {
215 - $age = wfMsg('oldreviewedpages-recent'); // hot off the press :)
216 - }
217 - // Oh-noes!
218 - $css = self::getLineClass( $hours, $uw );
219 - $css = $css ? " class='$css'" : "";
220 - } else {
221 - $age = ""; // wtf?
222 - }
223 - $key = wfMemcKey( 'stableDiffs', 'underReview', $row->stable, $row->page_latest );
224 - # Show if a user is looking at this page
225 - if( ($val = $wgMemc->get($key)) ) {
226 - $underReview = " <b class='fr-under-review'>".wfMsgHtml('oldreviewedpages-viewing').'</b>';
227 - }
228 -
229 - return( "<li{$css}>{$link} {$stxt} ({$review}) <i>{$age}</i>{$quality}{$watching}{$underReview}</li>" );
230 - }
231 -
232 - /**
233 - * Get the timestamp of the next revision
234 - *
235 - * @param integer $revision Revision ID. Get the revision that was after this one.
236 - * @param integer $page, page ID
237 - */
238 - protected function getNextRevisionTimestamp( $revision, $page ) {
239 - $dbr = wfGetDB( DB_SLAVE );
240 - return $dbr->selectField( 'revision', 'rev_timestamp',
241 - array(
242 - 'rev_page' => $page,
243 - 'rev_id > ' . intval( $revision )
244 - ),
245 - __METHOD__,
246 - array( 'ORDER BY' => 'rev_id' )
247 - );
248 - }
249 -
250 - protected static function getLineClass( $hours, $uw ) {
251 - if( $uw == 0 )
252 - return 'fr-unreviewed-unwatched';
253 - else
254 - return "";
255 - }
256 -}
257 -
258 -/**
259 - * Query to list out outdated reviewed pages
260 - */
261 -class ProblemChangesPager extends AlphabeticPager {
262 - public $mForm, $mConds;
263 - private $category, $namespace, $tag;
264 -
265 - function __construct( $form, $level=-1, $category='', $tag='' )
266 - {
267 - $this->mForm = $form;
268 - # Must be a content page...
269 - global $wgFlaggedRevsNamespaces;
270 - $this->namespace = $wgFlaggedRevsNamespaces;
271 - # Sanity check level: 0 = sighted; 1 = quality; 2 = pristine
272 - $this->level = ($level >= 0 && $level <= 2) ? $level : -1;
273 - $this->tag = $tag;
274 - $this->category = $category ? str_replace(' ','_',$category) : NULL;
275 - parent::__construct();
276 - // Don't get to expensive
277 - $this->mLimitsShown = array( 20, 50, 100 );
278 - $this->mLimit = min( $this->mLimit, 100 );
279 - }
280 -
281 - function formatRow( $row ) {
282 - return $this->mForm->formatRow( $row );
283 - }
284 -
285 - function getDefaultDirections() {
286 - return false;
287 - }
288 -
289 - function getQueryInfo() {
290 - global $wgUser;
291 - $conds = $this->mConds;
292 - $tables = array( 'page', 'revision', 'change_tag' );
293 - $fields = array('page_namespace','page_title','page_latest');
294 - # Show outdated "stable" versions
295 - if( $this->level < 0 ) {
296 - $fields[] = 'fp_stable AS stable';
297 - $fields[] = 'fp_quality AS quality';
298 - $fields[] = 'fp_pending_since AS pending_since';
299 - $conds[] = 'fp_pending_since IS NOT NULL';
300 - $conds[] = 'page_id = fp_page_id';
301 - # Find revisions that are tagged as such
302 - $conds[] = 'rev_page = page_id';
303 - $conds[] = 'rev_id > fp_stable';
304 - $conds[] = 'ct_rev_id = rev_id';
305 - $conds['ct_tag'] = $this->tag;
306 - $useIndex = array('flaggedpages' => 'fp_pending_since',
307 - 'change_tag' => 'change_tag_rev_tag ');
308 - # Filter by category
309 - if( $this->category ) {
310 - array_unshift($tables,'categorylinks'); // order matters
311 - $conds[] = 'cl_from = fp_page_id';
312 - $conds['cl_to'] = $this->category;
313 - $useIndex['categorylinks'] = 'cl_from';
314 - }
315 - array_unshift($tables,'flaggedpages'); // order matters
316 - $this->mIndexField = 'fp_pending_since';
317 - $groupBy = 'fp_pending_since,fp_page_id';
318 - # Show outdated version for a specific review level
319 - } else {
320 - $fields[] = 'fpp_rev_id AS stable';
321 - $fields[] = 'fpp_quality AS quality';
322 - $fields[] = 'fpp_pending_since AS pending_since';
323 - $conds[] = 'fpp_pending_since IS NOT NULL';
324 - $conds[] = 'page_id = fpp_page_id';
325 - # Find revisions that are tagged as such
326 - $conds[] = 'rev_page = page_id';
327 - $conds[] = 'rev_id > fpp_rev_id';
328 - $conds[] = 'rev_id = ct_rev_id';
329 - $conds['ct_tag'] = $this->tag;
330 - $useIndex = array('flaggedpage_pending' => 'fpp_quality_pending',
331 - 'change_tag' => 'change_tag_rev_tag ');
332 - # Filter by review level
333 - $conds['fpp_quality'] = $this->level;
334 - # Filter by category
335 - if( $this->category ) {
336 - array_unshift($tables,'categorylinks'); // order matters
337 - $conds[] = 'cl_from = fpp_page_id';
338 - $conds['cl_to'] = $this->category;
339 - $useIndex['categorylinks'] = 'cl_from';
340 - }
341 - array_unshift($tables,'flaggedpage_pending'); // order matters
342 - $this->mIndexField = 'fpp_pending_since';
343 - $groupBy = 'fpp_pending_since,fpp_page_id';
344 - }
345 - $fields[] = $this->mIndexField; // Pager needs this
346 - $conds['page_namespace'] = $this->namespace; // sanity check NS
347 - return array(
348 - 'tables' => $tables,
349 - 'fields' => $fields,
350 - 'conds' => $conds,
351 - 'options' => array( 'USE INDEX' => $useIndex, 'GROUP BY' => $groupBy, 'STRAIGHT_JOIN' )
352 - );
353 - }
354 -
355 - function getIndexField() {
356 - return $this->mIndexField;
357 - }
358 -
359 - function getStartBody() {
360 - wfProfileIn( __METHOD__ );
361 - # Do a link batch query
362 - $lb = new LinkBatch();
363 - while( $row = $this->mResult->fetchObject() ) {
364 - $lb->add( $row->page_namespace, $row->page_title );
365 - }
366 - $lb->execute();
367 - wfProfileOut( __METHOD__ );
368 - return '<ul>';
369 - }
370 -
371 - function getEndBody() {
372 - return '</ul>';
373 - }
374 -}
 2+<?php
 3+if ( !defined( 'MEDIAWIKI' ) ) {
 4+ echo "FlaggedRevs extension\n";
 5+ exit( 1 );
 6+}
 7+
 8+class ProblemChanges extends SpecialPage
 9+{
 10+ public function __construct() {
 11+ parent::__construct( 'ProblemChanges' );
 12+ $this->includable( true );
 13+ wfLoadExtensionMessages( 'ProblemChanges' );
 14+ wfLoadExtensionMessages( 'OldReviewedPages' );
 15+ wfLoadExtensionMessages( 'FlaggedRevs' );
 16+ }
 17+
 18+ public function execute( $par ) {
 19+ global $wgRequest, $wgUser, $wgOut;
 20+ $this->setHeaders();
 21+ $this->skin = $wgUser->getSkin();
 22+ $this->level = $wgRequest->getInt( 'level', -1 );
 23+ $this->tag = trim( $wgRequest->getVal( 'tagfilter' ) );
 24+ $this->category = trim( $wgRequest->getVal( 'category' ) );
 25+ $feedType = $wgRequest->getVal( 'feed' );
 26+ if( $feedType ) {
 27+ return $this->feed( $feedType );
 28+ }
 29+ $this->setSyndicated();
 30+ $this->showList( $par );
 31+ }
 32+
 33+ protected function setSyndicated() {
 34+ global $wgOut, $wgRequest;
 35+ $queryParams = array(
 36+ 'level' => $wgRequest->getIntOrNull( 'level' ),
 37+ 'tag' => $wgRequest->getVal( 'tag' ),
 38+ 'category' => $wgRequest->getVal( 'category' ),
 39+ );
 40+ $wgOut->setSyndicated( true );
 41+ $wgOut->setFeedAppendQuery( wfArrayToCGI( $queryParams ) );
 42+ }
 43+
 44+ public function showList( $par ) {
 45+ global $wgOut, $wgScript, $wgUser, $wgFlaggedRevsNamespaces;
 46+ $limit = $this->parseParams( $par );
 47+ $pager = new ProblemChangesPager( $this, $this->level, $this->category, $this->tag );
 48+ // Apply limit if transcluded
 49+ $pager->mLimit = $limit ? $limit : $pager->mLimit;
 50+ // Viewing the page normally...
 51+ if( !$this->including() ) {
 52+ $action = htmlspecialchars( $wgScript );
 53+ $tagForm = ChangeTags::buildTagFilterSelector( $this->tag );
 54+ $wgOut->addHTML(
 55+ "<form action=\"$action\" method=\"get\">\n" .
 56+ '<fieldset><legend>' . wfMsg('problemchanges-legend') . '</legend>' .
 57+ Xml::hidden( 'title', $this->getTitle()->getPrefixedDBKey() )
 58+ );
 59+ $form =
 60+ ( FlaggedRevs::qualityVersions() ?
 61+ "<span style='white-space: nowrap;'>" .
 62+ FlaggedRevsXML::getLevelMenu( $this->level, 'revreview-filter-stable' ) . '</span> '
 63+ : ""
 64+ );
 65+ if( count($tagForm) ) {
 66+ $form .= Xml::tags( 'td', array( 'class' => 'mw-label' ), $tagForm[0] );
 67+ $form .= Xml::tags( 'td', array( 'class' => 'mw-input' ), $tagForm[1] );
 68+ }
 69+ $form .= '<br/>' .
 70+ Xml::label( wfMsg("problemchanges-category"), 'wpCategory' ) . '&nbsp;' .
 71+ Xml::input( 'category', 30, $this->category, array('id' => 'wpCategory') ) . ' ';
 72+ $form .= Xml::submitButton( wfMsg( 'allpagessubmit' ) ) . "\n" .
 73+ "</fieldset></form>";
 74+ # Add filter options
 75+ $wgOut->addHTML( $form );
 76+ # Add list output (skip if no tag given)
 77+ $num = strlen($this->tag) && $pager->getNumRows();
 78+ if( $num ) {
 79+ $wgOut->addHTML( $pager->getNavigationBar() );
 80+ $wgOut->addHTML( $pager->getBody() );
 81+ $wgOut->addHTML( $pager->getNavigationBar() );
 82+ } else if( strlen($this->tag) ) {
 83+ $wgOut->addHTML( wfMsgExt('problemchanges-none', array('parse') ) );
 84+ }
 85+ // If this page is transcluded...
 86+ } else {
 87+ if( strlen($this->tag) && $pager->getNumRows() ) {
 88+ $wgOut->addHTML( $pager->getBody() );
 89+ } else if( strlen($this->tag) ) {
 90+ $wgOut->addHTML( wfMsgExt('problemchanges-none', array('parse') ) );
 91+ }
 92+ }
 93+ }
 94+
 95+ protected function parseParams( $par ) {
 96+ global $wgLang;
 97+ $bits = preg_split( '/\s*,\s*/', trim( $par ) );
 98+ $limit = false;
 99+ foreach( $bits as $bit ) {
 100+ if( is_numeric( $bit ) )
 101+ $limit = intval( $bit );
 102+ $m = array();
 103+ if( preg_match( '/^limit=(\d+)$/', $bit, $m ) )
 104+ $limit = intval($m[1]);
 105+ if( preg_match( '/^category=(.+)$/', $bit, $m ) )
 106+ $this->category = $m[1];
 107+ if( preg_match( '/^tagfilter=(.+)$/', $bit, $m ) )
 108+ $this->tag = $m[1];
 109+ }
 110+ return $limit;
 111+ }
 112+
 113+ /**
 114+ * Output a subscription feed listing recent edits to this page.
 115+ * @param string $type
 116+ */
 117+ protected function feed( $type ) {
 118+ global $wgFeed, $wgFeedClasses, $wgRequest;
 119+ if( !$wgFeed ) {
 120+ global $wgOut;
 121+ $wgOut->addWikiMsg( 'feed-unavailable' );
 122+ return;
 123+ }
 124+ if( !isset( $wgFeedClasses[$type] ) ) {
 125+ global $wgOut;
 126+ $wgOut->addWikiMsg( 'feed-invalid' );
 127+ return;
 128+ }
 129+ $feed = new $wgFeedClasses[$type](
 130+ $this->feedTitle(),
 131+ wfMsg( 'tagline' ),
 132+ $this->getTitle()->getFullUrl() );
 133+
 134+ $pager = new ProblemChangesPager( $this, $this->category );
 135+ $limit = $wgRequest->getInt( 'limit', 50 );
 136+ global $wgFeedLimit;
 137+ $pager->mLimit = min( $wgFeedLimit, $limit );
 138+
 139+ $feed->outHeader();
 140+ if( $pager->getNumRows() > 0 ) {
 141+ while( $row = $pager->mResult->fetchObject() ) {
 142+ $feed->outItem( $this->feedItem( $row ) );
 143+ }
 144+ }
 145+ $feed->outFooter();
 146+ }
 147+
 148+ protected function feedTitle() {
 149+ global $wgContLanguageCode, $wgSitename;
 150+ $page = SpecialPage::getPage( 'problemchanges' );
 151+ $desc = $page->getDescription();
 152+ return "$wgSitename - $desc [$wgContLanguageCode]";
 153+ }
 154+
 155+ protected function feedItem( $row ) {
 156+ $title = Title::MakeTitle( $row->page_namespace, $row->page_title );
 157+ if( $title ) {
 158+ $date = $row->pending_since;
 159+ $comments = $title->getTalkPage()->getFullURL();
 160+ $curRev = Revision::newFromTitle( $title );
 161+ return new FeedItem(
 162+ $title->getPrefixedText(),
 163+ FeedUtils::formatDiffRow( $title, $row->stable, $curRev->getId(),
 164+ $row->pending_since, $curRev->getComment() ),
 165+ $title->getFullURL(),
 166+ $date,
 167+ $curRev->getUserText(),
 168+ $comments
 169+ );
 170+ } else {
 171+ return NULL;
 172+ }
 173+ }
 174+
 175+ public function formatRow( $row ) {
 176+ global $wgLang, $wgUser, $wgMemc;
 177+
 178+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
 179+ $link = $this->skin->makeKnownLinkObj( $title );
 180+ $css = $stxt = $review = $quality = $underReview = '';
 181+ $review = $this->skin->makeKnownLinkObj( $title, wfMsg('oldreviewed-diff'),
 182+ "diff=cur&oldid={$row->stable}&reviewform=1&diffonly=0" );
 183+ # Show quality level if there are several
 184+ if( FlaggedRevs::qualityVersions() ) {
 185+ $quality = $row->quality ?
 186+ wfMsgHtml('revreview-lev-quality') : wfMsgHtml('revreview-lev-sighted');
 187+ $quality = " <b>[{$quality}]</b>";
 188+ }
 189+ # Is anybody watching?
 190+ if( !$this->including() && $wgUser->isAllowed( 'unreviewedpages' ) ) {
 191+ $uw = UnreviewedPages::usersWatching( $title );
 192+ $watching = $uw
 193+ ? wfMsgExt('oldreviewedpages-watched','parsemag',$uw,$uw)
 194+ : wfMsgHtml('oldreviewedpages-unwatched');
 195+ $watching = " {$watching}";
 196+ } else {
 197+ $uw = -1;
 198+ $watching = ''; // leave out data
 199+ }
 200+ # Get how long the first unreviewed edit has been waiting...
 201+ if( $row->pending_since ) {
 202+ static $currentTime;
 203+ $currentTime = wfTimestamp( TS_UNIX ); // now
 204+ $firstPendingTime = wfTimestamp( TS_UNIX, $row->pending_since );
 205+ $hours = ($currentTime - $firstPendingTime)/3600;
 206+ // After three days, just use days
 207+ if( $hours > (3*24) ) {
 208+ $days = round($hours/24,0);
 209+ $age = wfMsgExt('oldreviewedpages-days',array('parsemag'),$days);
 210+ // If one or more hours, use hours
 211+ } elseif( $hours >= 1 ) {
 212+ $hours = round($hours,0);
 213+ $age = wfMsgExt('oldreviewedpages-hours',array('parsemag'),$hours);
 214+ } else {
 215+ $age = wfMsg('oldreviewedpages-recent'); // hot off the press :)
 216+ }
 217+ // Oh-noes!
 218+ $css = self::getLineClass( $hours, $uw );
 219+ $css = $css ? " class='$css'" : "";
 220+ } else {
 221+ $age = ""; // wtf?
 222+ }
 223+ $key = wfMemcKey( 'stableDiffs', 'underReview', $row->stable, $row->page_latest );
 224+ # Show if a user is looking at this page
 225+ if( ($val = $wgMemc->get($key)) ) {
 226+ $underReview = " <b class='fr-under-review'>".wfMsgHtml('oldreviewedpages-viewing').'</b>';
 227+ }
 228+
 229+ return( "<li{$css}>{$link} {$stxt} ({$review}) <i>{$age}</i>{$quality}{$watching}{$underReview}</li>" );
 230+ }
 231+
 232+ /**
 233+ * Get the timestamp of the next revision
 234+ *
 235+ * @param integer $revision Revision ID. Get the revision that was after this one.
 236+ * @param integer $page, page ID
 237+ */
 238+ protected function getNextRevisionTimestamp( $revision, $page ) {
 239+ $dbr = wfGetDB( DB_SLAVE );
 240+ return $dbr->selectField( 'revision', 'rev_timestamp',
 241+ array(
 242+ 'rev_page' => $page,
 243+ 'rev_id > ' . intval( $revision )
 244+ ),
 245+ __METHOD__,
 246+ array( 'ORDER BY' => 'rev_id' )
 247+ );
 248+ }
 249+
 250+ protected static function getLineClass( $hours, $uw ) {
 251+ if( $uw == 0 )
 252+ return 'fr-unreviewed-unwatched';
 253+ else
 254+ return "";
 255+ }
 256+}
 257+
 258+/**
 259+ * Query to list out outdated reviewed pages
 260+ */
 261+class ProblemChangesPager extends AlphabeticPager {
 262+ public $mForm, $mConds;
 263+ private $category, $namespace, $tag;
 264+
 265+ function __construct( $form, $level=-1, $category='', $tag='' )
 266+ {
 267+ $this->mForm = $form;
 268+ # Must be a content page...
 269+ global $wgFlaggedRevsNamespaces;
 270+ $this->namespace = $wgFlaggedRevsNamespaces;
 271+ # Sanity check level: 0 = sighted; 1 = quality; 2 = pristine
 272+ $this->level = ($level >= 0 && $level <= 2) ? $level : -1;
 273+ $this->tag = $tag;
 274+ $this->category = $category ? str_replace(' ','_',$category) : NULL;
 275+ parent::__construct();
 276+ // Don't get to expensive
 277+ $this->mLimitsShown = array( 20, 50, 100 );
 278+ $this->mLimit = min( $this->mLimit, 100 );
 279+ }
 280+
 281+ function formatRow( $row ) {
 282+ return $this->mForm->formatRow( $row );
 283+ }
 284+
 285+ function getDefaultDirections() {
 286+ return false;
 287+ }
 288+
 289+ function getQueryInfo() {
 290+ global $wgUser;
 291+ $conds = $this->mConds;
 292+ $tables = array( 'page', 'revision', 'change_tag' );
 293+ $fields = array('page_namespace','page_title','page_latest');
 294+ # Show outdated "stable" versions
 295+ if( $this->level < 0 ) {
 296+ $fields[] = 'fp_stable AS stable';
 297+ $fields[] = 'fp_quality AS quality';
 298+ $fields[] = 'fp_pending_since AS pending_since';
 299+ $conds[] = 'fp_pending_since IS NOT NULL';
 300+ $conds[] = 'page_id = fp_page_id';
 301+ # Find revisions that are tagged as such
 302+ $conds[] = 'rev_page = page_id';
 303+ $conds[] = 'rev_id > fp_stable';
 304+ $conds[] = 'ct_rev_id = rev_id';
 305+ $conds['ct_tag'] = $this->tag;
 306+ $useIndex = array('flaggedpages' => 'fp_pending_since',
 307+ 'change_tag' => 'change_tag_rev_tag ');
 308+ # Filter by category
 309+ if( $this->category ) {
 310+ array_unshift($tables,'categorylinks'); // order matters
 311+ $conds[] = 'cl_from = fp_page_id';
 312+ $conds['cl_to'] = $this->category;
 313+ $useIndex['categorylinks'] = 'cl_from';
 314+ }
 315+ array_unshift($tables,'flaggedpages'); // order matters
 316+ $this->mIndexField = 'fp_pending_since';
 317+ $groupBy = 'fp_pending_since,fp_page_id';
 318+ # Show outdated version for a specific review level
 319+ } else {
 320+ $fields[] = 'fpp_rev_id AS stable';
 321+ $fields[] = 'fpp_quality AS quality';
 322+ $fields[] = 'fpp_pending_since AS pending_since';
 323+ $conds[] = 'fpp_pending_since IS NOT NULL';
 324+ $conds[] = 'page_id = fpp_page_id';
 325+ # Find revisions that are tagged as such
 326+ $conds[] = 'rev_page = page_id';
 327+ $conds[] = 'rev_id > fpp_rev_id';
 328+ $conds[] = 'rev_id = ct_rev_id';
 329+ $conds['ct_tag'] = $this->tag;
 330+ $useIndex = array('flaggedpage_pending' => 'fpp_quality_pending',
 331+ 'change_tag' => 'change_tag_rev_tag ');
 332+ # Filter by review level
 333+ $conds['fpp_quality'] = $this->level;
 334+ # Filter by category
 335+ if( $this->category ) {
 336+ array_unshift($tables,'categorylinks'); // order matters
 337+ $conds[] = 'cl_from = fpp_page_id';
 338+ $conds['cl_to'] = $this->category;
 339+ $useIndex['categorylinks'] = 'cl_from';
 340+ }
 341+ array_unshift($tables,'flaggedpage_pending'); // order matters
 342+ $this->mIndexField = 'fpp_pending_since';
 343+ $groupBy = 'fpp_pending_since,fpp_page_id';
 344+ }
 345+ $fields[] = $this->mIndexField; // Pager needs this
 346+ $conds['page_namespace'] = $this->namespace; // sanity check NS
 347+ return array(
 348+ 'tables' => $tables,
 349+ 'fields' => $fields,
 350+ 'conds' => $conds,
 351+ 'options' => array( 'USE INDEX' => $useIndex, 'GROUP BY' => $groupBy, 'STRAIGHT_JOIN' )
 352+ );
 353+ }
 354+
 355+ function getIndexField() {
 356+ return $this->mIndexField;
 357+ }
 358+
 359+ function getStartBody() {
 360+ wfProfileIn( __METHOD__ );
 361+ # Do a link batch query
 362+ $lb = new LinkBatch();
 363+ while( $row = $this->mResult->fetchObject() ) {
 364+ $lb->add( $row->page_namespace, $row->page_title );
 365+ }
 366+ $lb->execute();
 367+ wfProfileOut( __METHOD__ );
 368+ return '<ul>';
 369+ }
 370+
 371+ function getEndBody() {
 372+ return '</ul>';
 373+ }
 374+}
Property changes on: trunk/extensions/FlaggedRevs/specialpages/ProblemChanges_body.php
___________________________________________________________________
Name: svn:eol-style
375375 + native

Status & tagging log