4 * @addtogroup SpecialPage
11 function wfSpecialNewPages( $par ) {
12 $page = new NewPagesForm();
14 $page->showList( $par );
18 * implements Special:Newpages
19 * @addtogroup SpecialPage
23 * Show a form for filtering namespace and username
27 public function showList() {
28 global $wgScript, $wgContLang, $wgGroupPermissions, $wgRequest, $wgUser, $wgOut;
29 $sk = $wgUser->getSkin();
30 $align = $wgContLang->isRTL() ?
'left' : 'right';
31 $self = SpecialPage
::getTitleFor( 'NewPages' );
34 $showhide = array( wfMsgHtml( 'show' ), wfMsgHtml( 'hide' ));
38 if ( $wgGroupPermissions['*']['createpage'] === true ) {
39 $hidelinks['hideliu'] = 'rcshowhideliu';
41 if ( $wgUser->useNPPatrol() ) {
42 $hidelinks['hidepatrolled'] = 'rcshowhidepatr';
44 $hidelinks['hidebots'] = 'rcshowhidebots';
47 /* bool */ 'hideliu' => false,
48 /* bool */ 'hidepatrolled' => false,
49 /* bool */ 'hidebots' => false,
50 /* text */ 'namespace' => "0",
51 /* text */ 'username' => '',
52 /* int */ 'offset' => 0,
53 /* int */ 'limit' => 50,
57 // Override all values from requests, if specified
58 foreach ( $defaults as $v => $t ) {
60 $options[$v] = $wgRequest->getBool( $v, $options[$v] );
61 } elseif( is_int($t) ) {
62 $options[$v] = $wgRequest->getInt( $v, $options[$v] );
63 } elseif( is_string($t) ) {
64 $options[$v] = $wgRequest->getText( $v, $options[$v] );
68 $wgOut->setSyndicated( true );
69 $wgOut->setFeedAppendQuery( "namespace={$options['namespace']}&username={$options['username']}" );
71 $feedType = $wgRequest->getVal( 'feed' );
73 wfProfileOut( __METHOD__
);
74 return $this->feed( $feedType, $options );
77 $nondefaults = array();
78 foreach ( $options as $v => $t ) {
79 if ( $v === 'offset' ) continue; # Reset offset if parameters change
80 wfAppendToArrayIfNotDefault( $v, $t, $defaults, $nondefaults );
84 foreach ( $hidelinks as $key => $msg ) {
85 $reversed = 1 - $options[$key];
86 $link = $sk->makeKnownLinkObj( $self, $showhide[$reversed],
87 wfArrayToCGI( array( $key => $reversed ), $nondefaults )
89 $links[$key] = wfMsgHtml( $msg, $link );
92 $hl = implode( ' | ', $links );
94 // Store query values in hidden fields so that form submission doesn't lose them
96 foreach ( $nondefaults as $key => $value ) {
97 if ( $key === 'namespace' ) continue;
98 if ( $key === 'username' ) continue;
99 $hidden[] = Xml
::hidden( $key, $value );
101 $hidden = implode( "\n", $hidden );
103 $form = Xml
::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) .
104 Xml
::hidden( 'title', $self->getPrefixedDBkey() ) .
105 Xml
::openElement( 'fieldset' ) .
106 Xml
::element( 'legend', null, wfMsg( 'newpages' ) ) .
107 Xml
::openElement( 'table', array( 'id' => 'mw-newpages-table' ) ) .
109 <td align=\"$align\">" .
110 Xml
::label( wfMsg( 'namespace' ), 'namespace' ) .
113 Xml
::namespaceSelector( $options['namespace'], 'all' ) .
117 <td align=\"$align\">" .
118 Xml
::label( wfMsg( 'newpages-username' ), 'mw-np-username' ) .
121 Xml
::input( 'username', 30, $options['username'], array( 'id' => 'mw-np-username' ) ) .
126 Xml
::submitButton( wfMsg( 'allpagessubmit' ) ) .
135 Xml
::closeElement( 'table' ) .
136 Xml
::closeElement( 'fieldset' ) .
138 Xml
::closeElement( 'form' );
140 $wgOut->addHTML( $form );
142 $pager = new NewPagesPager( $this, array(), $options['namespace'], $options['hideliu'],
143 $options['hidepatrolled'], $options['hidebots'], $options['username'] );
145 if( $pager->getNumRows() ) {
146 $wgOut->addHTML( $pager->getNavigationBar() .
147 $pager->getStartBody() .
149 $pager->getEndBody() .
150 $pager->getNavigationBar() );
152 $wgOut->addHTML( '<p>' . wfMsgHtml( 'specialpage-empty' ) . '</p>' );
157 * Format a row, providing the timestamp, links to the page/history, size, user links, and a comment
159 * @param $skin Skin to use
160 * @param $result Result row
163 public function formatRow( $result ) {
164 global $wgLang, $wgContLang, $wgUser;
165 $dm = $wgContLang->getDirMark();
169 if( is_null( $skin ) )
170 $skin = $wgUser->getSkin();
172 $title = Title
::makeTitleSafe( $result->rc_namespace
, $result->rc_title
);
173 $time = $wgLang->timeAndDate( $result->rc_timestamp
, true );
174 $plink = $skin->makeKnownLinkObj( $title, '', $this->patrollable( $result ) ?
'rcid=' . $result->rc_id
: '' );
175 $hist = $skin->makeKnownLinkObj( $title, wfMsgHtml( 'hist' ), 'action=history' );
176 $length = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ),
177 $wgLang->formatNum( htmlspecialchars( $result->length
) ) );
178 $ulink = $skin->userLink( $result->rc_user
, $result->rc_user_text
) . ' ' .
179 $skin->userToolLinks( $result->rc_user
, $result->rc_user_text
);
180 $comment = $skin->commentBlock( $result->rc_comment
);
181 $css = $this->patrollable( $result ) ?
'not-patrolled' : '';
183 return "<li class='$css'>{$time} {$dm}{$plink} ({$hist}) {$dm}[{$length}] {$dm}{$ulink} {$comment}</li>";
187 * Should a specific result row provide "patrollable" links?
189 * @param $result Result row
192 protected function patrollable( $result ) {
194 return ( $wgUser->useNPPatrol() && !$result->rc_patrolled
);
198 * Output a subscription feed listing recent edits to this page.
199 * @param string $type
201 protected function feed( $type, $options ) {
202 require_once 'SpecialRecentchanges.php';
204 global $wgFeed, $wgFeedClasses;
208 $wgOut->addWikiMsg( 'feed-unavailable' );
212 if( !isset( $wgFeedClasses[$type] ) ) {
214 $wgOut->addWikiMsg( 'feed-invalid' );
218 $self = SpecialPage
::getTitleFor( 'NewPages' );
219 $feed = new $wgFeedClasses[$type](
222 $self->getFullUrl() );
224 $pager = new NewPagesPager( $this, array(), $options['namespace'], $options['hideliu'],
225 $options['hidepatrolled'], $options['hidebots'], $options['username'] );
228 if( $pager->getNumRows() > 0 ) {
229 while( $row = $pager->mResult
->fetchObject() ) {
230 $feed->outItem( $this->feedItem( $row ) );
236 protected function feedTitle() {
237 global $wgContLanguageCode, $wgSitename;
238 $page = SpecialPage
::getPage( 'Newpages' );
239 $desc = $page->getDescription();
240 return "$wgSitename - $desc [$wgContLanguageCode]";
243 protected function feedItem( $row ) {
244 $title = Title
::MakeTitle( intval( $row->rc_namespace
), $row->rc_title
);
246 $date = $row->rc_timestamp
;
247 $comments = $this->stripComment( $row->rc_comment
);
250 $title->getPrefixedText(),
251 $this->feedItemDesc( $row ),
252 $title->getFullURL(),
254 $this->feedItemAuthor( $row ),
262 * Quickie hack... strip out wikilinks to more legible form from the comment.
264 function stripComment( $text ) {
265 return preg_replace( '/\[\[([^]]*\|)?([^]]+)\]\]/', '\2', $text );
268 function feedItemAuthor( $row ) {
269 return isset( $row->rc_user_text
) ?
$row->rc_user_text
: '';
272 protected function feedItemDesc( $row ) {
273 $revision = Revision
::newFromId( $row->rev_id
);
275 return '<p>' . htmlspecialchars( wfMsg( 'summary' ) ) . ': ' .
276 htmlspecialchars( $revision->getComment() ) . "</p>\n<hr />\n<div>" .
277 nl2br( htmlspecialchars( $revision->getText() ) ) . "</div>";
286 class NewPagesPager
extends ReverseChronologicalPager
{
287 private $hideliu, $hidepatrolled, $hidebots, $namespace, $user;
289 function __construct( $form, $conds=array(), $namespace, $hliu=false, $hpatrolled=false, $hbots=1, $user='' ) {
290 parent
::__construct();
291 $this->mForm
= $form;
292 $this->mConds
= $conds;
294 $this->namespace = ($namespace === "all") ?
false : intval($namespace);
297 $this->hideliu
= (bool)$hliu;
298 $this->hidepatrolled
= (bool)$hpatrolled;
299 $this->hidebots
= (bool)$hbots;
302 function getQueryInfo() {
303 $conds = $this->mConds
;
304 $conds['rc_new'] = 1;
305 if( $this->namespace !== false ) {
306 $conds['rc_namespace'] = $this->namespace;
307 $rcIndexes = array( 'new_name_timestamp', 'rc_timestamp', 'rc_user_text' );
309 $rcIndexes = array( 'rc_timestamp', 'rc_user_text' );
311 $conds[] = 'page_id = rc_cur_id';
312 $conds['page_is_redirect'] = 0;
314 global $wgGroupPermissions, $wgUser;
315 # If anons cannot make new pages, don't query for it!
316 if( $wgGroupPermissions['*']['createpage'] && $this->hideliu
) {
317 $conds['rc_user'] = 0;
319 $title = Title
::makeTitleSafe( NS_USER
, $this->user
);
321 $conds['rc_user_text'] = $title->getText();
324 # If this user cannot see patrolled edits or they are off, don't do dumb queries!
325 if( $this->hidepatrolled
&& $wgUser->useNPPatrol() ) {
326 $conds['rc_patrolled'] = 0;
328 if( $this->hidebots
) {
329 $conds['rc_bot'] = 0;
333 $conds['rc_user_text'] = $this->user
;
337 'tables' => array( 'recentchanges', 'page' ),
338 'fields' => 'rc_namespace,rc_title, rc_cur_id, rc_user,rc_user_text,rc_comment,
339 rc_timestamp,rc_patrolled,rc_id,page_len as length, page_latest as rev_id',
341 'options' => array( 'USE INDEX' => array('recentchanges' => $rcIndexes) )
345 function getIndexField() {
346 return 'rc_timestamp';
349 function formatRow( $row ) {
350 return $this->mForm
->formatRow( $row );
353 function getStartBody() {
354 # Do a batch existence check on pages
355 $linkBatch = new LinkBatch();
356 while( $row = $this->mResult
->fetchObject() ) {
357 $linkBatch->add( NS_USER
, $row->rc_user_text
);
358 $linkBatch->add( NS_USER_TALK
, $row->rc_user_text
);
359 $linkBatch->add( $row->rc_namespace
, $row->rc_title
);
361 $linkBatch->execute();
365 function getEndBody() {