210 $id = $title->getArticleID();
211 $config = $this->context->getConfig();
212 $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
214 $pageCounts = $this->
pageCounts( $this->page );
216 $pageProperties = [];
218 if ( isset( $props[$id] ) ) {
219 $pageProperties = $props[$id];
224 $pageInfo[
'header-basic'] = [];
227 $displayTitle = $title->getPrefixedText();
228 if ( isset( $pageProperties[
'displaytitle'] ) ) {
229 $displayTitle = $pageProperties[
'displaytitle'];
232 $pageInfo[
'header-basic'][] = [
233 $this->
msg(
'pageinfo-display-title' ), $displayTitle
237 if ( $title->isRedirect() ) {
238 $pageInfo[
'header-basic'][] = [
239 $this->
msg(
'pageinfo-redirectsto' ),
240 $linkRenderer->makeLink( $this->page->getRedirectTarget() ) .
241 $this->
msg(
'word-separator' )->escaped() .
243 $this->page->getRedirectTarget(),
244 $this->msg(
'pageinfo-redirectsto-info' )->text(),
246 [
'action' =>
'info' ]
252 $sortKey = $title->getCategorySortkey();
253 if ( isset( $pageProperties[
'defaultsort'] ) ) {
254 $sortKey = $pageProperties[
'defaultsort'];
257 $sortKey = htmlspecialchars( $sortKey );
258 $pageInfo[
'header-basic'][] = [ $this->
msg(
'pageinfo-default-sort' ), $sortKey ];
261 $pageInfo[
'header-basic'][] = [
262 $this->
msg(
'pageinfo-length' ),
$lang->formatNum( $title->getLength() )
266 $pageInfo[
'header-basic'][] = [ $this->
msg(
'pageinfo-article-id' ), $id ];
269 $pageLang = $title->getPageLanguage()->getCode();
271 $pageLangHtml = $pageLang .
' - ' .
272 Language::fetchLanguageName( $pageLang,
$lang->getCode() );
274 if ( $config->get(
'PageLanguageUseDB' )
275 && $title->userCan(
'pagelang', $user )
277 $pageLangHtml .=
' ' . $this->
msg(
'parentheses' )->rawParams(
$linkRenderer->makeLink(
279 $this->msg(
'pageinfo-language-change' )->text()
283 $pageInfo[
'header-basic'][] = [
284 $this->
msg(
'pageinfo-language' )->escaped(),
291 if ( $config->get(
'ContentHandlerUseDB' )
292 && $title->userCan(
'editcontentmodel', $user )
294 $modelHtml .=
' ' . $this->
msg(
'parentheses' )->rawParams(
$linkRenderer->makeLink(
296 $this->msg(
'pageinfo-content-model-change' )->text()
300 $pageInfo[
'header-basic'][] = [
301 $this->
msg(
'pageinfo-content-model' ),
305 if ( $title->inNamespace( NS_USER ) ) {
306 $pageUser = User::newFromName( $title->getRootText() );
307 if ( $pageUser && $pageUser->getId() && !$pageUser->isHidden() ) {
308 $pageInfo[
'header-basic'][] = [
309 $this->
msg(
'pageinfo-user-id' ),
317 if ( isset( $pageProperties[
'noindex'] ) ) {
318 $pOutput->setIndexPolicy(
'noindex' );
320 if ( isset( $pageProperties[
'index'] ) ) {
321 $pOutput->setIndexPolicy(
'index' );
325 $policy = $this->page->getRobotPolicy(
'view', $pOutput );
326 $pageInfo[
'header-basic'][] = [
328 $this->
msg(
'pageinfo-robot-policy' ),
329 $this->
msg(
"pageinfo-robot-${policy['index']}" )
332 $unwatchedPageThreshold = $config->get(
'UnwatchedPageThreshold' );
334 $user->isAllowed(
'unwatchedpages' ) ||
335 ( $unwatchedPageThreshold !==
false &&
336 $pageCounts[
'watchers'] >= $unwatchedPageThreshold )
339 $pageInfo[
'header-basic'][] = [
340 $this->
msg(
'pageinfo-watchers' ),
341 $lang->formatNum( $pageCounts[
'watchers'] )
344 $config->get(
'ShowUpdatedMarker' ) &&
345 isset( $pageCounts[
'visitingWatchers'] )
347 $minToDisclose = $config->get(
'UnwatchedPageSecret' );
348 if ( $pageCounts[
'visitingWatchers'] > $minToDisclose ||
349 $user->isAllowed(
'unwatchedpages' ) ) {
350 $pageInfo[
'header-basic'][] = [
351 $this->
msg(
'pageinfo-visiting-watchers' ),
352 $lang->formatNum( $pageCounts[
'visitingWatchers'] )
355 $pageInfo[
'header-basic'][] = [
356 $this->
msg(
'pageinfo-visiting-watchers' ),
357 $this->
msg(
'pageinfo-few-visiting-watchers' )
361 } elseif ( $unwatchedPageThreshold !==
false ) {
362 $pageInfo[
'header-basic'][] = [
363 $this->
msg(
'pageinfo-watchers' ),
364 $this->
msg(
'pageinfo-few-watchers' )->numParams( $unwatchedPageThreshold )
370 $pageInfo[
'header-basic'][] = [
373 $this->
msg(
'pageinfo-redirects-name' )->
text(),
378 'hideimages' => $title->getNamespace() ==
NS_FILE
381 $this->
msg(
'pageinfo-redirects-value' )
382 ->numParams( count( $title->getRedirectsHere() ) )
386 if ( $this->page->isCountable() ) {
387 $pageInfo[
'header-basic'][] = [
388 $this->
msg(
'pageinfo-contentpage' ),
389 $this->
msg(
'pageinfo-contentpage-yes' )
394 if ( MWNamespace::hasSubpages( $title->getNamespace() ) ) {
396 'Prefixindex', $title->getPrefixedText() .
'/' );
397 $pageInfo[
'header-basic'][] = [
400 $this->
msg(
'pageinfo-subpages-name' )->
text()
402 $this->
msg(
'pageinfo-subpages-value' )
404 $pageCounts[
'subpages'][
'total'],
405 $pageCounts[
'subpages'][
'redirects'],
406 $pageCounts[
'subpages'][
'nonredirects'] )
411 $category = Category::newFromTitle( $title );
415 $allCount = (int)$category->getPageCount();
416 $subcatCount = (int)$category->getSubcatCount();
417 $fileCount = (int)$category->getFileCount();
418 $pagesCount = $allCount - $subcatCount - $fileCount;
420 $pageInfo[
'category-info'] = [
422 $this->
msg(
'pageinfo-category-total' ),
423 $lang->formatNum( $allCount )
426 $this->
msg(
'pageinfo-category-pages' ),
427 $lang->formatNum( $pagesCount )
430 $this->
msg(
'pageinfo-category-subcats' ),
431 $lang->formatNum( $subcatCount )
434 $this->
msg(
'pageinfo-category-files' ),
435 $lang->formatNum( $fileCount )
441 $pageInfo[
'header-restrictions'] = [];
444 if ( $title->isCascadeProtected() ) {
446 $sources = $title->getCascadeProtectionSources()[0];
448 foreach ( $sources as $sourceTitle ) {
449 $cascadingFrom .= Html::rawElement(
453 $cascadingFrom = Html::rawElement(
'ul', [], $cascadingFrom );
454 $pageInfo[
'header-restrictions'][] = [
455 $this->
msg(
'pageinfo-protect-cascading-from' ),
461 if ( $title->areRestrictionsCascading() ) {
462 $pageInfo[
'header-restrictions'][] = [
463 $this->
msg(
'pageinfo-protect-cascading' ),
464 $this->
msg(
'pageinfo-protect-cascading-yes' )
469 foreach ( $title->getRestrictionTypes() as $restrictionType ) {
470 $protectionLevel = implode(
', ', $title->getRestrictions( $restrictionType ) );
472 if ( $protectionLevel ==
'' ) {
474 $message = $this->
msg(
'protect-default' )->escaped();
478 $message = $this->
msg(
"protect-level-$protectionLevel" );
479 if ( $message->isDisabled() ) {
481 $message = $this->
msg(
"protect-fallback", $protectionLevel )->parse();
483 $message = $message->escaped();
486 $expiry = $title->getRestrictionExpiry( $restrictionType );
487 $formattedexpiry = $this->
msg(
'parentheses',
488 $lang->formatExpiry( $expiry ) )->escaped();
489 $message .= $this->
msg(
'word-separator' )->escaped() . $formattedexpiry;
493 $pageInfo[
'header-restrictions'][] = [
494 $this->
msg(
"restriction-$restrictionType" ), $message
498 if ( !$this->page->exists() ) {
503 $pageInfo[
'header-edits'] = [];
505 $firstRev = $this->page->getOldestRevision();
506 $lastRev = $this->page->getRevision();
511 if ( $firstRevUser !==
'' ) {
512 $firstRevUserTitle = Title::makeTitle( NS_USER, $firstRevUser );
513 $batch->addObj( $firstRevUserTitle );
514 $batch->addObj( $firstRevUserTitle->getTalkPage() );
520 if ( $lastRevUser !==
'' ) {
521 $lastRevUserTitle = Title::makeTitle( NS_USER, $lastRevUser );
522 $batch->addObj( $lastRevUserTitle );
523 $batch->addObj( $lastRevUserTitle->getTalkPage() );
531 $pageInfo[
'header-edits'][] = [
532 $this->
msg(
'pageinfo-firstuser' ),
537 $pageInfo[
'header-edits'][] = [
538 $this->
msg(
'pageinfo-firsttime' ),
541 $lang->userTimeAndDate( $firstRev->getTimestamp(), $user ),
543 [
'oldid' => $firstRev->getId() ]
550 $pageInfo[
'header-edits'][] = [
551 $this->
msg(
'pageinfo-lastuser' ),
556 $pageInfo[
'header-edits'][] = [
557 $this->
msg(
'pageinfo-lasttime' ),
560 $lang->userTimeAndDate( $this->page->getTimestamp(), $user ),
562 [
'oldid' => $this->page->getLatest() ]
568 $pageInfo[
'header-edits'][] = [
569 $this->
msg(
'pageinfo-edits' ),
$lang->formatNum( $pageCounts[
'edits'] )
573 if ( $pageCounts[
'authors'] > 0 ) {
574 $pageInfo[
'header-edits'][] = [
575 $this->
msg(
'pageinfo-authors' ),
$lang->formatNum( $pageCounts[
'authors'] )
580 $pageInfo[
'header-edits'][] = [
581 $this->
msg(
'pageinfo-recent-edits',
582 $lang->formatDuration( $config->get(
'RCMaxAge' ) ) ),
583 $lang->formatNum( $pageCounts[
'recent_edits'] )
587 $pageInfo[
'header-edits'][] = [
588 $this->
msg(
'pageinfo-recent-authors' ),
589 $lang->formatNum( $pageCounts[
'recent_authors'] )
604 $listItems[] = Html::element(
'li', [], $localizedWords[
$property][1] );
608 $localizedList = Html::rawElement(
'ul', [], implode(
'', $listItems ) );
609 $hiddenCategories = $this->page->getHiddenCategories();
612 count( $listItems ) > 0 ||
613 count( $hiddenCategories ) > 0 ||
614 $pageCounts[
'transclusion'][
'from'] > 0 ||
615 $pageCounts[
'transclusion'][
'to'] > 0
617 $options = [
'LIMIT' => $config->get(
'PageInfoTransclusionLimit' ) ];
618 $transcludedTemplates = $title->getTemplateLinksFrom(
$options );
619 if ( $config->get(
'MiserMode' ) ) {
620 $transcludedTargets = [];
622 $transcludedTargets = $title->getTemplateLinksTo(
$options );
626 $pageInfo[
'header-properties'] = [];
629 if ( count( $listItems ) > 0 ) {
630 $pageInfo[
'header-properties'][] = [
631 $this->
msg(
'pageinfo-magic-words' )->numParams( count( $listItems ) ),
637 if ( count( $hiddenCategories ) > 0 ) {
638 $pageInfo[
'header-properties'][] = [
639 $this->
msg(
'pageinfo-hidden-categories' )
640 ->numParams( count( $hiddenCategories ) ),
646 if ( $pageCounts[
'transclusion'][
'from'] > 0 ) {
647 if ( $pageCounts[
'transclusion'][
'from'] > count( $transcludedTemplates ) ) {
648 $more = $this->
msg(
'morenotlisted' )->escaped();
658 $pageInfo[
'header-properties'][] = [
659 $this->
msg(
'pageinfo-templates' )
660 ->numParams( $pageCounts[
'transclusion'][
'from'] ),
661 $templateListFormatter->format( $transcludedTemplates,
false, $more )
665 if ( !$config->get(
'MiserMode' ) && $pageCounts[
'transclusion'][
'to'] > 0 ) {
666 if ( $pageCounts[
'transclusion'][
'to'] > count( $transcludedTargets ) ) {
669 $this->
msg(
'moredotdotdot' )->
text(),
671 [
'hidelinks' => 1,
'hideredirs' => 1 ]
682 $pageInfo[
'header-properties'][] = [
683 $this->
msg(
'pageinfo-transclusions' )
684 ->numParams( $pageCounts[
'transclusion'][
'to'] ),
685 $templateListFormatter->format( $transcludedTargets,
false, $more )