[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Implements Special:Allpages 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * http://www.gnu.org/copyleft/gpl.html 19 * 20 * @file 21 * @ingroup SpecialPage 22 */ 23 24 /** 25 * Implements Special:Allpages 26 * 27 * @ingroup SpecialPage 28 */ 29 class SpecialAllPages extends IncludableSpecialPage { 30 31 /** 32 * Maximum number of pages to show on single subpage. 33 * 34 * @var int $maxPerPage 35 */ 36 protected $maxPerPage = 345; 37 38 /** 39 * Determines, which message describes the input field 'nsfrom'. 40 * 41 * @var string $nsfromMsg 42 */ 43 protected $nsfromMsg = 'allpagesfrom'; 44 45 /** 46 * Constructor 47 * 48 * @param string $name Name of the special page, as seen in links and URLs (default: 'Allpages') 49 */ 50 function __construct( $name = 'Allpages' ) { 51 parent::__construct( $name ); 52 } 53 54 /** 55 * Entry point : initialise variables and call subfunctions. 56 * 57 * @param string $par Becomes "FOO" when called like Special:Allpages/FOO (default null) 58 */ 59 function execute( $par ) { 60 $request = $this->getRequest(); 61 $out = $this->getOutput(); 62 63 $this->setHeaders(); 64 $this->outputHeader(); 65 $out->allowClickjacking(); 66 67 # GET values 68 $from = $request->getVal( 'from', null ); 69 $to = $request->getVal( 'to', null ); 70 $namespace = $request->getInt( 'namespace' ); 71 $hideredirects = $request->getBool( 'hideredirects', false ); 72 73 $namespaces = $this->getContext()->getLanguage()->getNamespaces(); 74 75 $out->setPageTitle( 76 ( $namespace > 0 && array_key_exists( $namespace, $namespaces ) ) ? 77 $this->msg( 'allinnamespace', str_replace( '_', ' ', $namespaces[$namespace] ) ) : 78 $this->msg( 'allarticles' ) 79 ); 80 $out->addModuleStyles( 'mediawiki.special' ); 81 82 if ( $par !== null ) { 83 $this->showChunk( $namespace, $par, $to, $hideredirects ); 84 } elseif ( $from !== null && $to === null ) { 85 $this->showChunk( $namespace, $from, $to, $hideredirects ); 86 } else { 87 $this->showToplevel( $namespace, $from, $to, $hideredirects ); 88 } 89 } 90 91 /** 92 * HTML for the top form 93 * 94 * @param int $namespace A namespace constant (default NS_MAIN). 95 * @param string $from DbKey we are starting listing at. 96 * @param string $to DbKey we are ending listing at. 97 * @param bool $hideredirects Dont show redirects (default false) 98 * @return string 99 */ 100 function namespaceForm( $namespace = NS_MAIN, $from = '', $to = '', $hideredirects = false ) { 101 $t = $this->getPageTitle(); 102 103 $out = Xml::openElement( 'div', array( 'class' => 'namespaceoptions' ) ); 104 $out .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $this->getConfig()->get( 'Script' ) ) ); 105 $out .= Html::hidden( 'title', $t->getPrefixedText() ); 106 $out .= Xml::openElement( 'fieldset' ); 107 $out .= Xml::element( 'legend', null, $this->msg( 'allpages' )->text() ); 108 $out .= Xml::openElement( 'table', array( 'id' => 'nsselect', 'class' => 'allpages' ) ); 109 $out .= "<tr> 110 <td class='mw-label'>" . 111 Xml::label( $this->msg( 'allpagesfrom' )->text(), 'nsfrom' ) . 112 " </td> 113 <td class='mw-input'>" . 114 Xml::input( 'from', 30, str_replace( '_', ' ', $from ), array( 'id' => 'nsfrom' ) ) . 115 " </td> 116 </tr> 117 <tr> 118 <td class='mw-label'>" . 119 Xml::label( $this->msg( 'allpagesto' )->text(), 'nsto' ) . 120 " </td> 121 <td class='mw-input'>" . 122 Xml::input( 'to', 30, str_replace( '_', ' ', $to ), array( 'id' => 'nsto' ) ) . 123 " </td> 124 </tr> 125 <tr> 126 <td class='mw-label'>" . 127 Xml::label( $this->msg( 'namespace' )->text(), 'namespace' ) . 128 " </td> 129 <td class='mw-input'>" . 130 Html::namespaceSelector( 131 array( 'selected' => $namespace ), 132 array( 'name' => 'namespace', 'id' => 'namespace' ) 133 ) . ' ' . 134 Xml::checkLabel( 135 $this->msg( 'allpages-hide-redirects' )->text(), 136 'hideredirects', 137 'hideredirects', 138 $hideredirects 139 ) . ' ' . 140 Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . 141 " </td> 142 </tr>"; 143 $out .= Xml::closeElement( 'table' ); 144 $out .= Xml::closeElement( 'fieldset' ); 145 $out .= Xml::closeElement( 'form' ); 146 $out .= Xml::closeElement( 'div' ); 147 148 return $out; 149 } 150 151 /** 152 * @param int $namespace (default NS_MAIN) 153 * @param string $from List all pages from this name 154 * @param string $to List all pages to this name 155 * @param bool $hideredirects Dont show redirects (default false) 156 */ 157 function showToplevel( $namespace = NS_MAIN, $from = '', $to = '', $hideredirects = false ) { 158 $from = Title::makeTitleSafe( $namespace, $from ); 159 $to = Title::makeTitleSafe( $namespace, $to ); 160 $from = ( $from && $from->isLocal() ) ? $from->getDBkey() : null; 161 $to = ( $to && $to->isLocal() ) ? $to->getDBkey() : null; 162 163 $this->showChunk( $namespace, $from, $to, $hideredirects ); 164 } 165 166 /** 167 * @param int $namespace Namespace (Default NS_MAIN) 168 * @param string $from List all pages from this name (default false) 169 * @param string $to List all pages to this name (default false) 170 * @param bool $hideredirects Dont show redirects (default false) 171 */ 172 function showChunk( $namespace = NS_MAIN, $from = false, $to = false, $hideredirects = false ) { 173 $output = $this->getOutput(); 174 175 $fromList = $this->getNamespaceKeyAndText( $namespace, $from ); 176 $toList = $this->getNamespaceKeyAndText( $namespace, $to ); 177 $namespaces = $this->getContext()->getLanguage()->getNamespaces(); 178 $n = 0; 179 180 if ( !$fromList || !$toList ) { 181 $out = $this->msg( 'allpagesbadtitle' )->parseAsBlock(); 182 } elseif ( !array_key_exists( $namespace, $namespaces ) ) { 183 // Show errormessage and reset to NS_MAIN 184 $out = $this->msg( 'allpages-bad-ns', $namespace )->parse(); 185 $namespace = NS_MAIN; 186 } else { 187 list( $namespace, $fromKey, $from ) = $fromList; 188 list( , $toKey, $to ) = $toList; 189 190 $dbr = wfGetDB( DB_SLAVE ); 191 $conds = array( 192 'page_namespace' => $namespace, 193 'page_title >= ' . $dbr->addQuotes( $fromKey ) 194 ); 195 196 if ( $hideredirects ) { 197 $conds['page_is_redirect'] = 0; 198 } 199 200 if ( $toKey !== "" ) { 201 $conds[] = 'page_title <= ' . $dbr->addQuotes( $toKey ); 202 } 203 204 $res = $dbr->select( 'page', 205 array( 'page_namespace', 'page_title', 'page_is_redirect', 'page_id' ), 206 $conds, 207 __METHOD__, 208 array( 209 'ORDER BY' => 'page_title', 210 'LIMIT' => $this->maxPerPage + 1, 211 'USE INDEX' => 'name_title', 212 ) 213 ); 214 215 if ( $res->numRows() > 0 ) { 216 $out = Xml::openElement( 'ul', array( 'class' => 'mw-allpages-chunk' ) ); 217 while ( ( $n < $this->maxPerPage ) && ( $s = $res->fetchObject() ) ) { 218 $t = Title::newFromRow( $s ); 219 if ( $t ) { 220 $out .= '<li' . 221 ( $s->page_is_redirect ? ' class="allpagesredirect"' : '' ) . 222 '>' . 223 Linker::link( $t ) . 224 "</li>\n"; 225 } else { 226 $out .= '<li>[[' . htmlspecialchars( $s->page_title ) . "]]</li>\n"; 227 } 228 $n++; 229 } 230 $out .= Xml::closeElement( 'ul' ); 231 } else { 232 $out = ''; 233 } 234 } 235 236 if ( $this->including() ) { 237 $output->addHTML( $out ); 238 return; 239 } 240 241 if ( $from == '' ) { 242 // First chunk; no previous link. 243 $prevTitle = null; 244 } else { 245 # Get the last title from previous chunk 246 $dbr = wfGetDB( DB_SLAVE ); 247 $res_prev = $dbr->select( 248 'page', 249 'page_title', 250 array( 'page_namespace' => $namespace, 'page_title < ' . $dbr->addQuotes( $from ) ), 251 __METHOD__, 252 array( 'ORDER BY' => 'page_title DESC', 253 'LIMIT' => $this->maxPerPage, 'OFFSET' => ( $this->maxPerPage - 1 ) 254 ) 255 ); 256 257 # Get first title of previous complete chunk 258 if ( $dbr->numrows( $res_prev ) >= $this->maxPerPage ) { 259 $pt = $dbr->fetchObject( $res_prev ); 260 $prevTitle = Title::makeTitle( $namespace, $pt->page_title ); 261 } else { 262 # The previous chunk is not complete, need to link to the very first title 263 # available in the database 264 $options = array( 'LIMIT' => 1 ); 265 if ( !$dbr->implicitOrderby() ) { 266 $options['ORDER BY'] = 'page_title'; 267 } 268 $reallyFirstPage_title = $dbr->selectField( 'page', 'page_title', 269 array( 'page_namespace' => $namespace ), __METHOD__, $options ); 270 # Show the previous link if it s not the current requested chunk 271 if ( $from != $reallyFirstPage_title ) { 272 $prevTitle = Title::makeTitle( $namespace, $reallyFirstPage_title ); 273 } else { 274 $prevTitle = null; 275 } 276 } 277 } 278 279 $self = $this->getPageTitle(); 280 281 $topLinks = array( 282 Linker::link( $self, $this->msg( 'allpages' )->escaped() ) 283 ); 284 $bottomLinks = array(); 285 286 # Do we put a previous link ? 287 if ( $prevTitle && $pt = $prevTitle->getText() ) { 288 $query = array( 'from' => $prevTitle->getText() ); 289 290 if ( $namespace ) { 291 $query['namespace'] = $namespace; 292 } 293 294 if ( $hideredirects ) { 295 $query['hideredirects'] = $hideredirects; 296 } 297 298 $prevLink = Linker::linkKnown( 299 $self, 300 $this->msg( 'prevpage', $pt )->escaped(), 301 array(), 302 $query 303 ); 304 $topLinks[] = $prevLink; 305 $bottomLinks[] = $prevLink; 306 } 307 308 if ( $n == $this->maxPerPage && $s = $res->fetchObject() ) { 309 # $s is the first link of the next chunk 310 $t = Title::makeTitle( $namespace, $s->page_title ); 311 $query = array( 'from' => $t->getText() ); 312 313 if ( $namespace ) { 314 $query['namespace'] = $namespace; 315 } 316 317 if ( $hideredirects ) { 318 $query['hideredirects'] = $hideredirects; 319 } 320 321 $nextLink = Linker::linkKnown( 322 $self, 323 $this->msg( 'nextpage', $t->getText() )->escaped(), 324 array(), 325 $query 326 ); 327 $topLinks[] = $nextLink; 328 $bottomLinks[] = $nextLink; 329 } 330 331 $nsForm = $this->namespaceForm( $namespace, $from, $to, $hideredirects ); 332 $out2 = Xml::openElement( 'table', array( 'class' => 'mw-allpages-table-form' ) ) . 333 '<tr> 334 <td>' . 335 $nsForm . 336 '</td> 337 <td class="mw-allpages-nav">' . 338 $this->getLanguage()->pipeList( $topLinks ) . 339 '</td></tr></table>'; 340 341 $output->addHTML( $out2 . $out ); 342 343 if ( count( $bottomLinks ) ) { 344 $output->addHTML( 345 Html::element( 'hr' ) . 346 Html::rawElement( 'div', array( 'class' => 'mw-allpages-nav' ), 347 $this->getLanguage()->pipeList( $bottomLinks ) 348 ) 349 ); 350 } 351 } 352 353 /** 354 * @param int $ns The namespace of the article 355 * @param string $text The name of the article 356 * @return array( int namespace, string dbkey, string pagename ) or null on error 357 */ 358 protected function getNamespaceKeyAndText( $ns, $text ) { 359 if ( $text == '' ) { 360 # shortcut for common case 361 return array( $ns, '', '' ); 362 } 363 364 $t = Title::makeTitleSafe( $ns, $text ); 365 if ( $t && $t->isLocal() ) { 366 return array( $t->getNamespace(), $t->getDBkey(), $t->getText() ); 367 } elseif ( $t ) { 368 return null; 369 } 370 371 # try again, in case the problem was an empty pagename 372 $text = preg_replace( '/(#|$)/', 'X$1', $text ); 373 $t = Title::makeTitleSafe( $ns, $text ); 374 if ( $t && $t->isLocal() ) { 375 return array( $t->getNamespace(), '', '' ); 376 } else { 377 return null; 378 } 379 } 380 381 protected function getGroupName() { 382 return 'pages'; 383 } 384 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |