MediaWiki  REL1_21
InfoAction.php
Go to the documentation of this file.
00001 <?php
00030 class InfoAction extends FormlessAction {
00036         public function getName() {
00037                 return 'info';
00038         }
00039 
00045         public function requiresUnblock() {
00046                 return false;
00047         }
00048 
00054         public function requiresWrite() {
00055                 return false;
00056         }
00057 
00063         public function onView() {
00064                 $content = '';
00065 
00066                 // Validate revision
00067                 $oldid = $this->page->getOldID();
00068                 if ( $oldid ) {
00069                         $revision = $this->page->getRevisionFetched();
00070 
00071                         // Revision is missing
00072                         if ( $revision === null ) {
00073                                 return $this->msg( 'missing-revision', $oldid )->parse();
00074                         }
00075 
00076                         // Revision is not current
00077                         if ( !$revision->isCurrent() ) {
00078                                 return $this->msg( 'pageinfo-not-current' )->plain();
00079                         }
00080                 }
00081 
00082                 // Page header
00083                 if ( !$this->msg( 'pageinfo-header' )->isDisabled() ) {
00084                         $content .= $this->msg( 'pageinfo-header' )->parse();
00085                 }
00086 
00087                 // Hide "This page is a member of # hidden categories" explanation
00088                 $content .= Html::element( 'style', array(),
00089                         '.mw-hiddenCategoriesExplanation { display: none; }' ) . "\n";
00090 
00091                 // Hide "Templates used on this page" explanation
00092                 $content .= Html::element( 'style', array(),
00093                         '.mw-templatesUsedExplanation { display: none; }' ) . "\n";
00094 
00095                 // Get page information
00096                 $pageInfo = $this->pageInfo();
00097 
00098                 // Allow extensions to add additional information
00099                 wfRunHooks( 'InfoAction', array( $this->getContext(), &$pageInfo ) );
00100 
00101                 // Render page information
00102                 foreach ( $pageInfo as $header => $infoTable ) {
00103                         $content .= $this->makeHeader( $this->msg( "pageinfo-${header}" )->escaped() ) . "\n";
00104                         $table = "\n";
00105                         foreach ( $infoTable as $infoRow ) {
00106                                 $name = ( $infoRow[0] instanceof Message ) ? $infoRow[0]->escaped() : $infoRow[0];
00107                                 $value = ( $infoRow[1] instanceof Message ) ? $infoRow[1]->escaped() : $infoRow[1];
00108                                 $table = $this->addRow( $table, $name, $value ) . "\n";
00109                         }
00110                         $content = $this->addTable( $content, $table ) . "\n";
00111                 }
00112 
00113                 // Page footer
00114                 if ( !$this->msg( 'pageinfo-footer' )->isDisabled() ) {
00115                         $content .= $this->msg( 'pageinfo-footer' )->parse();
00116                 }
00117 
00118                 // Page credits
00119                 /*if ( $this->page->exists() ) {
00120                         $content .= Html::rawElement( 'div', array( 'id' => 'mw-credits' ), $this->getContributors() );
00121                 }*/
00122 
00123                 return $content;
00124         }
00125 
00132         protected function makeHeader( $header ) {
00133                 $spanAttribs = array( 'class' => 'mw-headline', 'id' => Sanitizer::escapeId( $header ) );
00134                 return Html::rawElement( 'h2', array(), Html::element( 'span', $spanAttribs, $header ) );
00135         }
00136 
00145         protected function addRow( $table, $name, $value ) {
00146                 return $table . Html::rawElement( 'tr', array(),
00147                         Html::rawElement( 'td', array( 'style' => 'vertical-align: top;' ), $name ) .
00148                         Html::rawElement( 'td', array(), $value )
00149                 );
00150         }
00151 
00159         protected function addTable( $content, $table ) {
00160                 return $content . Html::rawElement( 'table', array( 'class' => 'wikitable mw-page-info' ),
00161                         $table );
00162         }
00163 
00171         protected function pageInfo() {
00172                 global $wgContLang, $wgRCMaxAge, $wgMemc, $wgUnwatchedPageThreshold, $wgPageInfoTransclusionLimit;
00173 
00174                 $user = $this->getUser();
00175                 $lang = $this->getLanguage();
00176                 $title = $this->getTitle();
00177                 $id = $title->getArticleID();
00178 
00179                 $memcKey = wfMemcKey( 'infoaction', sha1( $title->getPrefixedText() ), $this->page->getLatest() );
00180                 $pageCounts = $wgMemc->get( $memcKey );
00181                 if ( $pageCounts === false ) {
00182                         // Get page information that would be too "expensive" to retrieve by normal means
00183                         $pageCounts = self::pageCounts( $title );
00184 
00185                         $wgMemc->set( $memcKey, $pageCounts );
00186                 }
00187 
00188                 // Get page properties
00189                 $dbr = wfGetDB( DB_SLAVE );
00190                 $result = $dbr->select(
00191                         'page_props',
00192                         array( 'pp_propname', 'pp_value' ),
00193                         array( 'pp_page' => $id ),
00194                         __METHOD__
00195                 );
00196 
00197                 $pageProperties = array();
00198                 foreach ( $result as $row ) {
00199                         $pageProperties[$row->pp_propname] = $row->pp_value;
00200                 }
00201 
00202                 // Basic information
00203                 $pageInfo = array();
00204                 $pageInfo['header-basic'] = array();
00205 
00206                 // Display title
00207                 $displayTitle = $title->getPrefixedText();
00208                 if ( !empty( $pageProperties['displaytitle'] ) ) {
00209                         $displayTitle = $pageProperties['displaytitle'];
00210                 }
00211 
00212                 $pageInfo['header-basic'][] = array(
00213                         $this->msg( 'pageinfo-display-title' ), $displayTitle
00214                 );
00215 
00216                 // Is it a redirect? If so, where to?
00217                 if ( $title->isRedirect() ) {
00218                         $pageInfo['header-basic'][] = array(
00219                                 $this->msg( 'pageinfo-redirectsto' ),
00220                                 Linker::link( $this->page->getRedirectTarget() ) .
00221                                 $this->msg( 'word-separator' )->text() .
00222                                 $this->msg( 'parentheses', Linker::link(
00223                                         $this->page->getRedirectTarget(),
00224                                         $this->msg( 'pageinfo-redirectsto-info' )->escaped(),
00225                                         array(),
00226                                         array( 'action' => 'info' )
00227                                 ) )->text()
00228                         );
00229                 }
00230 
00231                 // Default sort key
00232                 $sortKey = $title->getCategorySortKey();
00233                 if ( !empty( $pageProperties['defaultsort'] ) ) {
00234                         $sortKey = $pageProperties['defaultsort'];
00235                 }
00236 
00237                 $sortKey = htmlspecialchars( $sortKey );
00238                 $pageInfo['header-basic'][] = array( $this->msg( 'pageinfo-default-sort' ), $sortKey );
00239 
00240                 // Page length (in bytes)
00241                 $pageInfo['header-basic'][] = array(
00242                         $this->msg( 'pageinfo-length' ), $lang->formatNum( $title->getLength() )
00243                 );
00244 
00245                 // Page ID (number not localised, as it's a database ID)
00246                 $pageInfo['header-basic'][] = array( $this->msg( 'pageinfo-article-id' ), $id );
00247 
00248                 // Language in which the page content is (supposed to be) written
00249                 $pageLang = $title->getPageLanguage()->getCode();
00250                 $pageInfo['header-basic'][] = array( $this->msg( 'pageinfo-language' ),
00251                         Language::fetchLanguageName( $pageLang, $lang->getCode() )
00252                         . ' ' . $this->msg( 'parentheses', $pageLang ) );
00253 
00254                 // Search engine status
00255                 $pOutput = new ParserOutput();
00256                 if ( isset( $pageProperties['noindex'] ) ) {
00257                         $pOutput->setIndexPolicy( 'noindex' );
00258                 }
00259 
00260                 // Use robot policy logic
00261                 $policy = $this->page->getRobotPolicy( 'view', $pOutput );
00262                 $pageInfo['header-basic'][] = array(
00263                         $this->msg( 'pageinfo-robot-policy' ), $this->msg( "pageinfo-robot-${policy['index']}" )
00264                 );
00265 
00266                 if ( isset( $pageCounts['views'] ) ) {
00267                         // Number of views
00268                         $pageInfo['header-basic'][] = array(
00269                                 $this->msg( 'pageinfo-views' ), $lang->formatNum( $pageCounts['views'] )
00270                         );
00271                 }
00272 
00273                 if (
00274                         $user->isAllowed( 'unwatchedpages' ) ||
00275                         ( $wgUnwatchedPageThreshold !== false &&
00276                           $pageCounts['watchers'] >= $wgUnwatchedPageThreshold )
00277                 ) {
00278                         // Number of page watchers
00279                         $pageInfo['header-basic'][] = array(
00280                                 $this->msg( 'pageinfo-watchers' ), $lang->formatNum( $pageCounts['watchers'] )
00281                         );
00282                 } elseif ( $wgUnwatchedPageThreshold !== false ) {
00283                         $pageInfo['header-basic'][] = array(
00284                                 $this->msg( 'pageinfo-watchers' ),
00285                                 $this->msg( 'pageinfo-few-watchers' )->numParams( $wgUnwatchedPageThreshold )
00286                         );
00287                 }
00288 
00289                 // Redirects to this page
00290                 $whatLinksHere = SpecialPage::getTitleFor( 'Whatlinkshere', $title->getPrefixedText() );
00291                 $pageInfo['header-basic'][] = array(
00292                         Linker::link(
00293                                 $whatLinksHere,
00294                                 $this->msg( 'pageinfo-redirects-name' )->escaped(),
00295                                 array(),
00296                                 array( 'hidelinks' => 1, 'hidetrans' => 1 )
00297                         ),
00298                         $this->msg( 'pageinfo-redirects-value' )
00299                                 ->numParams( count( $title->getRedirectsHere() ) )
00300                 );
00301 
00302                 // Is it counted as a content page?
00303                 if ( $this->page->isCountable() ) {
00304                         $pageInfo['header-basic'][] = array(
00305                                 $this->msg( 'pageinfo-contentpage' ),
00306                                 $this->msg( 'pageinfo-contentpage-yes' )
00307                         );
00308                 }
00309 
00310                 // Subpages of this page, if subpages are enabled for the current NS
00311                 if ( MWNamespace::hasSubpages( $title->getNamespace() ) ) {
00312                         $prefixIndex = SpecialPage::getTitleFor( 'Prefixindex', $title->getPrefixedText() . '/' );
00313                         $pageInfo['header-basic'][] = array(
00314                                 Linker::link( $prefixIndex, $this->msg( 'pageinfo-subpages-name' )->escaped() ),
00315                                 $this->msg( 'pageinfo-subpages-value' )
00316                                         ->numParams(
00317                                                 $pageCounts['subpages']['total'],
00318                                                 $pageCounts['subpages']['redirects'],
00319                                                 $pageCounts['subpages']['nonredirects'] )
00320                         );
00321                 }
00322 
00323                 if ( $title->inNamespace( NS_CATEGORY ) ) {
00324                         $category = Category::newFromTitle( $title );
00325                         $pageInfo['category-info'] = array(
00326                                 array(
00327                                         $this->msg( 'pageinfo-category-pages' ),
00328                                         $lang->formatNum( $category->getPageCount() )
00329                                 ),
00330                                 array(
00331                                         $this->msg( 'pageinfo-category-subcats' ),
00332                                         $lang->formatNum( $category->getSubcatCount() )
00333                                 ),
00334                                 array(
00335                                         $this->msg( 'pageinfo-category-files' ),
00336                                         $lang->formatNum( $category->getFileCount() )
00337                                 )
00338                         );
00339                 }
00340 
00341                 // Page protection
00342                 $pageInfo['header-restrictions'] = array();
00343 
00344                 // Is this page effected by the cascading protection of something which includes it?
00345                 if ( $title->isCascadeProtected() ) {
00346                         $cascadingFrom = '';
00347                         $sources = $title->getCascadeProtectionSources(); // Array deferencing is in PHP 5.4 :(
00348 
00349                         foreach ( $sources[0] as $sourceTitle ) {
00350                                 $cascadingFrom .= Html::rawElement( 'li', array(), Linker::linkKnown( $sourceTitle ) );
00351                         }
00352 
00353                         $cascadingFrom = Html::rawElement( 'ul', array(), $cascadingFrom );
00354                         $pageInfo['header-restrictions'][] = array(
00355                                 $this->msg( 'pageinfo-protect-cascading-from' ),
00356                                 $cascadingFrom
00357                         );
00358                 }
00359 
00360                 // Is out protection set to cascade to other pages?
00361                 if ( $title->areRestrictionsCascading() ) {
00362                         $pageInfo['header-restrictions'][] = array(
00363                                 $this->msg( 'pageinfo-protect-cascading' ),
00364                                 $this->msg( 'pageinfo-protect-cascading-yes' )
00365                         );
00366                 }
00367 
00368                 // Page protection
00369                 foreach ( $title->getRestrictionTypes() as $restrictionType ) {
00370                         $protectionLevel = implode( ', ', $title->getRestrictions( $restrictionType ) );
00371 
00372                         if ( $protectionLevel == '' ) {
00373                                 // Allow all users
00374                                 $message = $this->msg( 'protect-default' )->escaped();
00375                         } else {
00376                                 // Administrators only
00377                                 $message = $this->msg( "protect-level-$protectionLevel" );
00378                                 if ( $message->isDisabled() ) {
00379                                         // Require "$1" permission
00380                                         $message = $this->msg( "protect-fallback", $protectionLevel )->parse();
00381                                 } else {
00382                                         $message = $message->escaped();
00383                                 }
00384                         }
00385 
00386                         $pageInfo['header-restrictions'][] = array(
00387                                 $this->msg( "restriction-$restrictionType" ), $message
00388                         );
00389                 }
00390 
00391                 if ( !$this->page->exists() ) {
00392                         return $pageInfo;
00393                 }
00394 
00395                 // Edit history
00396                 $pageInfo['header-edits'] = array();
00397 
00398                 $firstRev = $this->page->getOldestRevision();
00399                 $lastRev = $this->page->getRevision();
00400                 $batch = new LinkBatch;
00401 
00402                 if ( $firstRev ) {
00403                         $firstRevUser = $firstRev->getUserText( Revision::FOR_THIS_USER );
00404                         if ( $firstRevUser !== '' ) {
00405                                 $batch->add( NS_USER, $firstRevUser );
00406                                 $batch->add( NS_USER_TALK, $firstRevUser );
00407                         }
00408                 }
00409 
00410                 if ( $lastRev ) {
00411                         $lastRevUser = $lastRev->getUserText( Revision::FOR_THIS_USER );
00412                         if ( $lastRevUser !== '' ) {
00413                                 $batch->add( NS_USER, $lastRevUser );
00414                                 $batch->add( NS_USER_TALK, $lastRevUser );
00415                         }
00416                 }
00417 
00418                 $batch->execute();
00419 
00420                 if ( $firstRev ) {
00421                         // Page creator
00422                         $pageInfo['header-edits'][] = array(
00423                                 $this->msg( 'pageinfo-firstuser' ),
00424                                 Linker::revUserTools( $firstRev )
00425                         );
00426 
00427                         // Date of page creation
00428                         $pageInfo['header-edits'][] = array(
00429                                 $this->msg( 'pageinfo-firsttime' ),
00430                                 Linker::linkKnown(
00431                                         $title,
00432                                         $lang->userTimeAndDate( $firstRev->getTimestamp(), $user ),
00433                                         array(),
00434                                         array( 'oldid' => $firstRev->getId() )
00435                                 )
00436                         );
00437                 }
00438 
00439                 if ( $lastRev ) {
00440                         // Latest editor
00441                         $pageInfo['header-edits'][] = array(
00442                                 $this->msg( 'pageinfo-lastuser' ),
00443                                 Linker::revUserTools( $lastRev )
00444                         );
00445 
00446                         // Date of latest edit
00447                         $pageInfo['header-edits'][] = array(
00448                                 $this->msg( 'pageinfo-lasttime' ),
00449                                 Linker::linkKnown(
00450                                         $title,
00451                                         $lang->userTimeAndDate( $this->page->getTimestamp(), $user ),
00452                                         array(),
00453                                         array( 'oldid' => $this->page->getLatest() )
00454                                 )
00455                         );
00456                 }
00457 
00458                 // Total number of edits
00459                 $pageInfo['header-edits'][] = array(
00460                         $this->msg( 'pageinfo-edits' ), $lang->formatNum( $pageCounts['edits'] )
00461                 );
00462 
00463                 // Total number of distinct authors
00464                 $pageInfo['header-edits'][] = array(
00465                         $this->msg( 'pageinfo-authors' ), $lang->formatNum( $pageCounts['authors'] )
00466                 );
00467 
00468                 // Recent number of edits (within past 30 days)
00469                 $pageInfo['header-edits'][] = array(
00470                         $this->msg( 'pageinfo-recent-edits', $lang->formatDuration( $wgRCMaxAge ) ),
00471                         $lang->formatNum( $pageCounts['recent_edits'] )
00472                 );
00473 
00474                 // Recent number of distinct authors
00475                 $pageInfo['header-edits'][] = array(
00476                         $this->msg( 'pageinfo-recent-authors' ), $lang->formatNum( $pageCounts['recent_authors'] )
00477                 );
00478 
00479                 // Array of MagicWord objects
00480                 $magicWords = MagicWord::getDoubleUnderscoreArray();
00481 
00482                 // Array of magic word IDs
00483                 $wordIDs = $magicWords->names;
00484 
00485                 // Array of IDs => localized magic words
00486                 $localizedWords = $wgContLang->getMagicWords();
00487 
00488                 $listItems = array();
00489                 foreach ( $pageProperties as $property => $value ) {
00490                         if ( in_array( $property, $wordIDs ) ) {
00491                                 $listItems[] = Html::element( 'li', array(), $localizedWords[$property][1] );
00492                         }
00493                 }
00494 
00495                 $localizedList = Html::rawElement( 'ul', array(), implode( '', $listItems ) );
00496                 $hiddenCategories = $this->page->getHiddenCategories();
00497 
00498                 if (
00499                         count( $listItems ) > 0 ||
00500                         count( $hiddenCategories ) > 0 ||
00501                         $pageCounts['transclusion']['from'] > 0 ||
00502                         $pageCounts['transclusion']['to'] > 0
00503                 ) {
00504                         $options = array( 'LIMIT' => $wgPageInfoTransclusionLimit );
00505                         $transcludedTemplates = $title->getTemplateLinksFrom( $options );
00506                         $transcludedTargets = $title->getTemplateLinksTo( $options );
00507 
00508                         // Page properties
00509                         $pageInfo['header-properties'] = array();
00510 
00511                         // Magic words
00512                         if ( count( $listItems ) > 0 ) {
00513                                 $pageInfo['header-properties'][] = array(
00514                                         $this->msg( 'pageinfo-magic-words' )->numParams( count( $listItems ) ),
00515                                         $localizedList
00516                                 );
00517                         }
00518 
00519                         // Hidden categories
00520                         if ( count( $hiddenCategories ) > 0 ) {
00521                                 $pageInfo['header-properties'][] = array(
00522                                         $this->msg( 'pageinfo-hidden-categories' )
00523                                                 ->numParams( count( $hiddenCategories ) ),
00524                                         Linker::formatHiddenCategories( $hiddenCategories )
00525                                 );
00526                         }
00527 
00528                         // Transcluded templates
00529                         if ( $pageCounts['transclusion']['from'] > 0 ) {
00530                                 if ( $pageCounts['transclusion']['from'] > count( $transcludedTemplates ) ) {
00531                                         $more = $this->msg( 'morenotlisted' )->escaped();
00532                                 } else {
00533                                         $more = null;
00534                                 }
00535 
00536                                 $pageInfo['header-properties'][] = array(
00537                                         $this->msg( 'pageinfo-templates' )
00538                                                 ->numParams( $pageCounts['transclusion']['from'] ),
00539                                         Linker::formatTemplates(
00540                                                 $transcludedTemplates,
00541                                                 false,
00542                                                 false,
00543                                                 $more )
00544                                 );
00545                         }
00546 
00547                         if ( $pageCounts['transclusion']['to'] > 0 ) {
00548                                 if ( $pageCounts['transclusion']['to'] > count( $transcludedTargets ) ) {
00549                                         $more = Linker::link(
00550                                                 $whatLinksHere,
00551                                                 $this->msg( 'moredotdotdot' )->escaped(),
00552                                                 array(),
00553                                                 array( 'hidelinks' => 1, 'hideredirs' => 1 )
00554                                         );
00555                                 } else {
00556                                         $more = null;
00557                                 }
00558 
00559                                 $pageInfo['header-properties'][] = array(
00560                                         $this->msg( 'pageinfo-transclusions' )
00561                                                 ->numParams( $pageCounts['transclusion']['to'] ),
00562                                         Linker::formatTemplates(
00563                                                 $transcludedTargets,
00564                                                 false,
00565                                                 false,
00566                                                 $more )
00567                                 );
00568                         }
00569                 }
00570 
00571                 return $pageInfo;
00572         }
00573 
00580         protected static function pageCounts( Title $title ) {
00581                 global $wgRCMaxAge, $wgDisableCounters;
00582 
00583                 wfProfileIn( __METHOD__ );
00584                 $id = $title->getArticleID();
00585 
00586                 $dbr = wfGetDB( DB_SLAVE );
00587                 $result = array();
00588 
00589                 if ( !$wgDisableCounters ) {
00590                         // Number of views
00591                         $views = (int) $dbr->selectField(
00592                                 'page',
00593                                 'page_counter',
00594                                 array( 'page_id' => $id ),
00595                                 __METHOD__
00596                         );
00597                         $result['views'] = $views;
00598                 }
00599 
00600                 // Number of page watchers
00601                 $watchers = (int) $dbr->selectField(
00602                         'watchlist',
00603                         'COUNT(*)',
00604                         array(
00605                                 'wl_namespace' => $title->getNamespace(),
00606                                 'wl_title'     => $title->getDBkey(),
00607                         ),
00608                         __METHOD__
00609                 );
00610                 $result['watchers'] = $watchers;
00611 
00612                 // Total number of edits
00613                 $edits = (int) $dbr->selectField(
00614                         'revision',
00615                         'COUNT(rev_page)',
00616                         array( 'rev_page' => $id ),
00617                         __METHOD__
00618                 );
00619                 $result['edits'] = $edits;
00620 
00621                 // Total number of distinct authors
00622                 $authors = (int) $dbr->selectField(
00623                         'revision',
00624                         'COUNT(DISTINCT rev_user_text)',
00625                         array( 'rev_page' => $id ),
00626                         __METHOD__
00627                 );
00628                 $result['authors'] = $authors;
00629 
00630                 // "Recent" threshold defined by $wgRCMaxAge
00631                 $threshold = $dbr->timestamp( time() - $wgRCMaxAge );
00632 
00633                 // Recent number of edits
00634                 $edits = (int) $dbr->selectField(
00635                         'revision',
00636                         'COUNT(rev_page)',
00637                         array(
00638                                 'rev_page' => $id,
00639                                 "rev_timestamp >= " . $dbr->addQuotes( $threshold )
00640                         ),
00641                         __METHOD__
00642                 );
00643                 $result['recent_edits'] = $edits;
00644 
00645                 // Recent number of distinct authors
00646                 $authors = (int) $dbr->selectField(
00647                         'revision',
00648                         'COUNT(DISTINCT rev_user_text)',
00649                         array(
00650                                 'rev_page' => $id,
00651                                 "rev_timestamp >= " . $dbr->addQuotes( $threshold )
00652                         ),
00653                         __METHOD__
00654                 );
00655                 $result['recent_authors'] = $authors;
00656 
00657                 // Subpages (if enabled)
00658                 if ( MWNamespace::hasSubpages( $title->getNamespace() ) ) {
00659                         $conds = array( 'page_namespace' => $title->getNamespace() );
00660                         $conds[] = 'page_title ' . $dbr->buildLike( $title->getDBkey() . '/', $dbr->anyString() );
00661 
00662                         // Subpages of this page (redirects)
00663                         $conds['page_is_redirect'] = 1;
00664                         $result['subpages']['redirects'] = (int) $dbr->selectField(
00665                                 'page',
00666                                 'COUNT(page_id)',
00667                                 $conds,
00668                                 __METHOD__ );
00669 
00670                         // Subpages of this page (non-redirects)
00671                         $conds['page_is_redirect'] = 0;
00672                         $result['subpages']['nonredirects'] = (int) $dbr->selectField(
00673                                 'page',
00674                                 'COUNT(page_id)',
00675                                 $conds,
00676                                 __METHOD__
00677                         );
00678 
00679                         // Subpages of this page (total)
00680                         $result['subpages']['total'] = $result['subpages']['redirects']
00681                                 + $result['subpages']['nonredirects'];
00682                 }
00683 
00684                 // Counts for the number of transclusion links (to/from)
00685                 $result['transclusion']['to'] = (int) $dbr->selectField(
00686                         'templatelinks',
00687                         'COUNT(tl_from)',
00688                         array(
00689                                 'tl_namespace' => $title->getNamespace(),
00690                                 'tl_title' => $title->getDBkey()
00691                         ),
00692                         __METHOD__
00693                 );
00694 
00695                 $result['transclusion']['from'] = (int) $dbr->selectField(
00696                         'templatelinks',
00697                         'COUNT(*)',
00698                         array( 'tl_from' => $title->getArticleID() ),
00699                         __METHOD__
00700                 );
00701 
00702                 wfProfileOut( __METHOD__ );
00703                 return $result;
00704         }
00705 
00711         protected function getPageTitle() {
00712                 return $this->msg( 'pageinfo-title', $this->getTitle()->getPrefixedText() )->text();
00713         }
00714 
00719         protected function getContributors() {
00720                 global $wgHiddenPrefs;
00721 
00722                 $contributors = $this->page->getContributors();
00723                 $real_names = array();
00724                 $user_names = array();
00725                 $anon_ips = array();
00726 
00727                 # Sift for real versus user names
00728                 foreach ( $contributors as $user ) {
00729                         $page = $user->isAnon()
00730                                 ? SpecialPage::getTitleFor( 'Contributions', $user->getName() )
00731                                 : $user->getUserPage();
00732 
00733                         if ( $user->getID() == 0 ) {
00734                                 $anon_ips[] = Linker::link( $page, htmlspecialchars( $user->getName() ) );
00735                         } elseif ( !in_array( 'realname', $wgHiddenPrefs ) && $user->getRealName() ) {
00736                                 $real_names[] = Linker::link( $page, htmlspecialchars( $user->getRealName() ) );
00737                         } else {
00738                                 $user_names[] = Linker::link( $page, htmlspecialchars( $user->getName() ) );
00739                         }
00740                 }
00741 
00742                 $lang = $this->getLanguage();
00743 
00744                 $real = $lang->listToText( $real_names );
00745 
00746                 # "ThisSite user(s) A, B and C"
00747                 if ( count( $user_names ) ) {
00748                         $user = $this->msg( 'siteusers' )->rawParams( $lang->listToText( $user_names ) )->params(
00749                                 count( $user_names ) )->escaped();
00750                 } else {
00751                         $user = false;
00752                 }
00753 
00754                 if ( count( $anon_ips ) ) {
00755                         $anon = $this->msg( 'anonusers' )->rawParams( $lang->listToText( $anon_ips ) )->params(
00756                                 count( $anon_ips ) )->escaped();
00757                 } else {
00758                         $anon = false;
00759                 }
00760 
00761                 # This is the big list, all mooshed together. We sift for blank strings
00762                 $fulllist = array();
00763                 foreach ( array( $real, $user, $anon ) as $s ) {
00764                         if ( $s !== '' ) {
00765                                 array_push( $fulllist, $s );
00766                         }
00767                 }
00768 
00769                 $count = count( $fulllist );
00770                 # "Based on work by ..."
00771                 return $count
00772                         ? $this->msg( 'othercontribs' )->rawParams(
00773                                 $lang->listToText( $fulllist ) )->params( $count )->escaped()
00774                         : '';
00775         }
00776 
00782         protected function getDescription() {
00783                 return '';
00784         }
00785 }