MediaWiki  REL1_24
SpecialAllPages.php
Go to the documentation of this file.
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 }