MediaWiki
REL1_24
|
00001 <?php 00029 class SpecialAllPages extends IncludableSpecialPage { 00030 00036 protected $maxPerPage = 345; 00037 00043 protected $nsfromMsg = 'allpagesfrom'; 00044 00050 function __construct( $name = 'Allpages' ) { 00051 parent::__construct( $name ); 00052 } 00053 00059 function execute( $par ) { 00060 $request = $this->getRequest(); 00061 $out = $this->getOutput(); 00062 00063 $this->setHeaders(); 00064 $this->outputHeader(); 00065 $out->allowClickjacking(); 00066 00067 # GET values 00068 $from = $request->getVal( 'from', null ); 00069 $to = $request->getVal( 'to', null ); 00070 $namespace = $request->getInt( 'namespace' ); 00071 $hideredirects = $request->getBool( 'hideredirects', false ); 00072 00073 $namespaces = $this->getContext()->getLanguage()->getNamespaces(); 00074 00075 $out->setPageTitle( 00076 ( $namespace > 0 && array_key_exists( $namespace, $namespaces ) ) ? 00077 $this->msg( 'allinnamespace', str_replace( '_', ' ', $namespaces[$namespace] ) ) : 00078 $this->msg( 'allarticles' ) 00079 ); 00080 $out->addModuleStyles( 'mediawiki.special' ); 00081 00082 if ( $par !== null ) { 00083 $this->showChunk( $namespace, $par, $to, $hideredirects ); 00084 } elseif ( $from !== null && $to === null ) { 00085 $this->showChunk( $namespace, $from, $to, $hideredirects ); 00086 } else { 00087 $this->showToplevel( $namespace, $from, $to, $hideredirects ); 00088 } 00089 } 00090 00100 function namespaceForm( $namespace = NS_MAIN, $from = '', $to = '', $hideredirects = false ) { 00101 $t = $this->getPageTitle(); 00102 00103 $out = Xml::openElement( 'div', array( 'class' => 'namespaceoptions' ) ); 00104 $out .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $this->getConfig()->get( 'Script' ) ) ); 00105 $out .= Html::hidden( 'title', $t->getPrefixedText() ); 00106 $out .= Xml::openElement( 'fieldset' ); 00107 $out .= Xml::element( 'legend', null, $this->msg( 'allpages' )->text() ); 00108 $out .= Xml::openElement( 'table', array( 'id' => 'nsselect', 'class' => 'allpages' ) ); 00109 $out .= "<tr> 00110 <td class='mw-label'>" . 00111 Xml::label( $this->msg( 'allpagesfrom' )->text(), 'nsfrom' ) . 00112 " </td> 00113 <td class='mw-input'>" . 00114 Xml::input( 'from', 30, str_replace( '_', ' ', $from ), array( 'id' => 'nsfrom' ) ) . 00115 " </td> 00116 </tr> 00117 <tr> 00118 <td class='mw-label'>" . 00119 Xml::label( $this->msg( 'allpagesto' )->text(), 'nsto' ) . 00120 " </td> 00121 <td class='mw-input'>" . 00122 Xml::input( 'to', 30, str_replace( '_', ' ', $to ), array( 'id' => 'nsto' ) ) . 00123 " </td> 00124 </tr> 00125 <tr> 00126 <td class='mw-label'>" . 00127 Xml::label( $this->msg( 'namespace' )->text(), 'namespace' ) . 00128 " </td> 00129 <td class='mw-input'>" . 00130 Html::namespaceSelector( 00131 array( 'selected' => $namespace ), 00132 array( 'name' => 'namespace', 'id' => 'namespace' ) 00133 ) . ' ' . 00134 Xml::checkLabel( 00135 $this->msg( 'allpages-hide-redirects' )->text(), 00136 'hideredirects', 00137 'hideredirects', 00138 $hideredirects 00139 ) . ' ' . 00140 Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . 00141 " </td> 00142 </tr>"; 00143 $out .= Xml::closeElement( 'table' ); 00144 $out .= Xml::closeElement( 'fieldset' ); 00145 $out .= Xml::closeElement( 'form' ); 00146 $out .= Xml::closeElement( 'div' ); 00147 00148 return $out; 00149 } 00150 00157 function showToplevel( $namespace = NS_MAIN, $from = '', $to = '', $hideredirects = false ) { 00158 $from = Title::makeTitleSafe( $namespace, $from ); 00159 $to = Title::makeTitleSafe( $namespace, $to ); 00160 $from = ( $from && $from->isLocal() ) ? $from->getDBkey() : null; 00161 $to = ( $to && $to->isLocal() ) ? $to->getDBkey() : null; 00162 00163 $this->showChunk( $namespace, $from, $to, $hideredirects ); 00164 } 00165 00172 function showChunk( $namespace = NS_MAIN, $from = false, $to = false, $hideredirects = false ) { 00173 $output = $this->getOutput(); 00174 00175 $fromList = $this->getNamespaceKeyAndText( $namespace, $from ); 00176 $toList = $this->getNamespaceKeyAndText( $namespace, $to ); 00177 $namespaces = $this->getContext()->getLanguage()->getNamespaces(); 00178 $n = 0; 00179 00180 if ( !$fromList || !$toList ) { 00181 $out = $this->msg( 'allpagesbadtitle' )->parseAsBlock(); 00182 } elseif ( !array_key_exists( $namespace, $namespaces ) ) { 00183 // Show errormessage and reset to NS_MAIN 00184 $out = $this->msg( 'allpages-bad-ns', $namespace )->parse(); 00185 $namespace = NS_MAIN; 00186 } else { 00187 list( $namespace, $fromKey, $from ) = $fromList; 00188 list( , $toKey, $to ) = $toList; 00189 00190 $dbr = wfGetDB( DB_SLAVE ); 00191 $conds = array( 00192 'page_namespace' => $namespace, 00193 'page_title >= ' . $dbr->addQuotes( $fromKey ) 00194 ); 00195 00196 if ( $hideredirects ) { 00197 $conds['page_is_redirect'] = 0; 00198 } 00199 00200 if ( $toKey !== "" ) { 00201 $conds[] = 'page_title <= ' . $dbr->addQuotes( $toKey ); 00202 } 00203 00204 $res = $dbr->select( 'page', 00205 array( 'page_namespace', 'page_title', 'page_is_redirect', 'page_id' ), 00206 $conds, 00207 __METHOD__, 00208 array( 00209 'ORDER BY' => 'page_title', 00210 'LIMIT' => $this->maxPerPage + 1, 00211 'USE INDEX' => 'name_title', 00212 ) 00213 ); 00214 00215 if ( $res->numRows() > 0 ) { 00216 $out = Xml::openElement( 'ul', array( 'class' => 'mw-allpages-chunk' ) ); 00217 while ( ( $n < $this->maxPerPage ) && ( $s = $res->fetchObject() ) ) { 00218 $t = Title::newFromRow( $s ); 00219 if ( $t ) { 00220 $out .= '<li' . 00221 ( $s->page_is_redirect ? ' class="allpagesredirect"' : '' ) . 00222 '>' . 00223 Linker::link( $t ) . 00224 "</li>\n"; 00225 } else { 00226 $out .= '<li>[[' . htmlspecialchars( $s->page_title ) . "]]</li>\n"; 00227 } 00228 } 00229 $out .= Xml::closeElement( 'ul' ); 00230 } else { 00231 $out = ''; 00232 } 00233 } 00234 00235 if ( $this->including() ) { 00236 $output->addHTML( $out ); 00237 return; 00238 } 00239 00240 if ( $from == '' ) { 00241 // First chunk; no previous link. 00242 $prevTitle = null; 00243 } else { 00244 # Get the last title from previous chunk 00245 $dbr = wfGetDB( DB_SLAVE ); 00246 $res_prev = $dbr->select( 00247 'page', 00248 'page_title', 00249 array( 'page_namespace' => $namespace, 'page_title < ' . $dbr->addQuotes( $from ) ), 00250 __METHOD__, 00251 array( 'ORDER BY' => 'page_title DESC', 00252 'LIMIT' => $this->maxPerPage, 'OFFSET' => ( $this->maxPerPage - 1 ) 00253 ) 00254 ); 00255 00256 # Get first title of previous complete chunk 00257 if ( $dbr->numrows( $res_prev ) >= $this->maxPerPage ) { 00258 $pt = $dbr->fetchObject( $res_prev ); 00259 $prevTitle = Title::makeTitle( $namespace, $pt->page_title ); 00260 } else { 00261 # The previous chunk is not complete, need to link to the very first title 00262 # available in the database 00263 $options = array( 'LIMIT' => 1 ); 00264 if ( !$dbr->implicitOrderby() ) { 00265 $options['ORDER BY'] = 'page_title'; 00266 } 00267 $reallyFirstPage_title = $dbr->selectField( 'page', 'page_title', 00268 array( 'page_namespace' => $namespace ), __METHOD__, $options ); 00269 # Show the previous link if it s not the current requested chunk 00270 if ( $from != $reallyFirstPage_title ) { 00271 $prevTitle = Title::makeTitle( $namespace, $reallyFirstPage_title ); 00272 } else { 00273 $prevTitle = null; 00274 } 00275 } 00276 } 00277 00278 $self = $this->getPageTitle(); 00279 00280 $topLinks = array( 00281 Linker::link( $self, $this->msg( 'allpages' )->escaped() ) 00282 ); 00283 $bottomLinks = array(); 00284 00285 # Do we put a previous link ? 00286 if ( $prevTitle && $pt = $prevTitle->getText() ) { 00287 $query = array( 'from' => $prevTitle->getText() ); 00288 00289 if ( $namespace ) { 00290 $query['namespace'] = $namespace; 00291 } 00292 00293 if ( $hideredirects ) { 00294 $query['hideredirects'] = $hideredirects; 00295 } 00296 00297 $prevLink = Linker::linkKnown( 00298 $self, 00299 $this->msg( 'prevpage', $pt )->escaped(), 00300 array(), 00301 $query 00302 ); 00303 $topLinks[] = $prevLink; 00304 $bottomLinks[] = $prevLink; 00305 } 00306 00307 if ( $n == $this->maxPerPage && $s = $res->fetchObject() ) { 00308 # $s is the first link of the next chunk 00309 $t = Title::makeTitle( $namespace, $s->page_title ); 00310 $query = array( 'from' => $t->getText() ); 00311 00312 if ( $namespace ) { 00313 $query['namespace'] = $namespace; 00314 } 00315 00316 if ( $hideredirects ) { 00317 $query['hideredirects'] = $hideredirects; 00318 } 00319 00320 $nextLink = Linker::linkKnown( 00321 $self, 00322 $this->msg( 'nextpage', $t->getText() )->escaped(), 00323 array(), 00324 $query 00325 ); 00326 $topLinks[] = $nextLink; 00327 $bottomLinks[] = $nextLink; 00328 } 00329 00330 $nsForm = $this->namespaceForm( $namespace, $from, $to, $hideredirects ); 00331 $out2 = Xml::openElement( 'table', array( 'class' => 'mw-allpages-table-form' ) ) . 00332 '<tr> 00333 <td>' . 00334 $nsForm . 00335 '</td> 00336 <td class="mw-allpages-nav">' . 00337 $this->getLanguage()->pipeList( $topLinks ) . 00338 '</td></tr></table>'; 00339 00340 $output->addHTML( $out2 . $out ); 00341 00342 if ( count( $bottomLinks ) ) { 00343 $output->addHTML( 00344 Html::element( 'hr' ) . 00345 Html::rawElement( 'div', array( 'class' => 'mw-allpages-nav' ), 00346 $this->getLanguage()->pipeList( $bottomLinks ) 00347 ) 00348 ); 00349 } 00350 } 00351 00357 protected function getNamespaceKeyAndText( $ns, $text ) { 00358 if ( $text == '' ) { 00359 # shortcut for common case 00360 return array( $ns, '', '' ); 00361 } 00362 00363 $t = Title::makeTitleSafe( $ns, $text ); 00364 if ( $t && $t->isLocal() ) { 00365 return array( $t->getNamespace(), $t->getDBkey(), $t->getText() ); 00366 } elseif ( $t ) { 00367 return null; 00368 } 00369 00370 # try again, in case the problem was an empty pagename 00371 $text = preg_replace( '/(#|$)/', 'X$1', $text ); 00372 $t = Title::makeTitleSafe( $ns, $text ); 00373 if ( $t && $t->isLocal() ) { 00374 return array( $t->getNamespace(), '', '' ); 00375 } else { 00376 return null; 00377 } 00378 } 00379 00380 protected function getGroupName() { 00381 return 'pages'; 00382 } 00383 }