diff --git a/includes/Article.php b/includes/Article.php
index 0d2d7a6a7ed..ea677385dcc 100644
--- a/includes/Article.php
+++ b/includes/Article.php
@@ -1829,6 +1829,14 @@ class Article {
$this->protect();
}
+ /**
+ * Info about this page
+ * Called for ?action=info when $wgAllowPageInfo is on.
+ */
+ public function info() {
+ Action::factory( 'info', $this )->show();
+ }
+
/**
* Insert a new empty page record for this article.
* This *must* be followed up by creating a revision
@@ -4000,95 +4008,6 @@ class Article {
$wgOut->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
}
- /**
- * Info about this page
- * Called for ?action=info when $wgAllowPageInfo is on.
- */
- public function info() {
- global $wgLang, $wgOut, $wgAllowPageInfo, $wgUser;
-
- if ( !$wgAllowPageInfo ) {
- $wgOut->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
- return;
- }
-
- $page = $this->mTitle->getSubjectPage();
-
- $wgOut->setPagetitle( $page->getPrefixedText() );
- $wgOut->setPageTitleActionText( wfMsg( 'info_short' ) );
- $wgOut->setSubtitle( wfMsgHtml( 'infosubtitle' ) );
-
- if ( !$this->mTitle->exists() ) {
- $wgOut->addHTML( '
' );
- $msg = $wgUser->isLoggedIn()
- ? 'noarticletext'
- : 'noarticletextanon';
- $wgOut->addWikiMsg( $msg );
- $wgOut->addHTML( '
' );
- } else {
- $dbr = wfGetDB( DB_SLAVE );
- $wl_clause = array(
- 'wl_title' => $page->getDBkey(),
- 'wl_namespace' => $page->getNamespace() );
- $numwatchers = $dbr->selectField(
- 'watchlist',
- 'COUNT(*)',
- $wl_clause,
- __METHOD__ );
-
- $pageInfo = $this->pageCountInfo( $page );
- $talkInfo = $this->pageCountInfo( $page->getTalkPage() );
-
- // @todo FIXME: unescaped messages
- $wgOut->addHTML( "- " . wfMsg( "numwatchers", $wgLang->formatNum( $numwatchers ) ) . '
' );
- $wgOut->addHTML( "- " . wfMsg( 'numedits', $wgLang->formatNum( $pageInfo['edits'] ) ) . '
' );
-
- if ( $talkInfo ) {
- $wgOut->addHTML( '- ' . wfMsg( "numtalkedits", $wgLang->formatNum( $talkInfo['edits'] ) ) . '
' );
- }
-
- $wgOut->addHTML( '- ' . wfMsg( "numauthors", $wgLang->formatNum( $pageInfo['authors'] ) ) . '
' );
-
- if ( $talkInfo ) {
- $wgOut->addHTML( '- ' . wfMsg( 'numtalkauthors', $wgLang->formatNum( $talkInfo['authors'] ) ) . '
' );
- }
-
- $wgOut->addHTML( '
' );
- }
- }
-
- /**
- * Return the total number of edits and number of unique editors
- * on a given page. If page does not exist, returns false.
- *
- * @param $title Title object
- * @return mixed array or boolean false
- */
- public function pageCountInfo( $title ) {
- $id = $title->getArticleId();
-
- if ( $id == 0 ) {
- return false;
- }
-
- $dbr = wfGetDB( DB_SLAVE );
- $rev_clause = array( 'rev_page' => $id );
- $edits = $dbr->selectField(
- 'revision',
- 'COUNT(rev_page)',
- $rev_clause,
- __METHOD__
- );
- $authors = $dbr->selectField(
- 'revision',
- 'COUNT(DISTINCT rev_user_text)',
- $rev_clause,
- __METHOD__
- );
-
- return array( 'edits' => $edits, 'authors' => $authors );
- }
-
/**
* Return a list of templates used by this article.
* Uses the templatelinks table
diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php
index ab863710220..64ad88552ed 100644
--- a/includes/AutoLoader.php
+++ b/includes/AutoLoader.php
@@ -249,6 +249,7 @@ $wgAutoloadLocalClasses = array(
# includes/actions
'CreditsAction' => 'includes/actions/CreditsAction.php',
'DeletetrackbackAction' => 'includes/actions/DeletetrackbackAction.php',
+ 'InfoAction' => 'includes/actions/InfoAction.php',
'MarkpatrolledAction' => 'includes/actions/MarkpatrolledAction.php',
'PurgeAction' => 'includes/actions/PurgeAction.php',
'RevisiondeleteAction' => 'includes/actions/RevisiondeleteAction.php',
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index b41a7f55f11..a4c7cb22819 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -5020,6 +5020,7 @@ $wgMaxRedirectLinksRetrieved = 500;
$wgActions = array(
'credits' => true,
'deletetrackback' => true,
+ 'info' => true,
'markpatrolled' => true,
'purge' => true,
'revisiondelete' => true,
diff --git a/includes/Wiki.php b/includes/Wiki.php
index f3d1c6d6dbf..3a18061458f 100644
--- a/includes/Wiki.php
+++ b/includes/Wiki.php
@@ -444,7 +444,6 @@ class MediaWiki {
case 'rollback':
case 'protect':
case 'unprotect':
- case 'info':
case 'render':
$article->$act();
break;
diff --git a/includes/actions/InfoAction.php b/includes/actions/InfoAction.php
new file mode 100644
index 00000000000..82b5211e69b
--- /dev/null
+++ b/includes/actions/InfoAction.php
@@ -0,0 +1,149 @@
+getTitle()->getSubjectPage();
+
+ $this->getOutput()->setPagetitle( wfMsg( 'pageinfo-title', $title->getPrefixedText() ) );
+
+ $pageInfo = self::pageCountInfo( $title );
+ $talkInfo = self::pageCountInfo( $title->getTalkPage() );
+
+ return Html::rawElement( 'table', array( 'class' => 'wikitable mw-page-info' ),
+ Html::rawElement( 'tr', array(),
+ Html::element( 'th', array(), '' ) .
+ Html::element( 'th', array(), wfMsg( 'pageinfo-subjectpage' ) ) .
+ Html::element( 'th', array(), wfMsg( 'pageinfo-talkpage' ) )
+ ) .
+ Html::rawElement( 'tr', array(),
+ Html::element( 'th', array( 'colspan' => 3 ), wfMsg( 'pageinfo-header-edits' ) )
+ ) .
+ Html::rawElement( 'tr', array(),
+ Html::element( 'td', array(), wfMsg( 'pageinfo-edits' ) ) .
+ Html::element( 'td', array(), $this->getLang()->formatNum( $pageInfo['edits'] ) ) .
+ Html::element( 'td', array(), $this->getLang()->formatNum( $talkInfo['edits'] ) )
+ ) .
+ Html::rawElement( 'tr', array(),
+ Html::element( 'td', array(), wfMsg( 'pageinfo-authors' ) ) .
+ Html::element( 'td', array(), $this->getLang()->formatNum( $pageInfo['authors'] ) ) .
+ Html::element( 'td', array(), $this->getLang()->formatNum( $talkInfo['authors'] ) )
+ ) .
+ ( !$this->getUser()->isAllowed( 'unwatchedpages' ) ? '' :
+ Html::rawElement( 'tr', array(),
+ Html::element( 'th', array( 'colspan' => 3 ), wfMsg( 'pageinfo-header-watchlist' ) )
+ ) .
+ Html::rawElement( 'tr', array(),
+ Html::element( 'td', array(), wfMsg( 'pageinfo-watchers' ) ) .
+ Html::element( 'td', array( 'colspan' => 2 ), $this->getLang()->formatNum( $pageInfo['watchers'] ) )
+ )
+ ).
+ ( $wgDisableCounters ? '' :
+ Html::rawElement( 'tr', array(),
+ Html::element( 'th', array( 'colspan' => 3 ), wfMsg( 'pageinfo-header-views' ) )
+ ) .
+ Html::rawElement( 'tr', array(),
+ Html::element( 'td', array(), wfMsg( 'pageinfo-views' ) ) .
+ Html::element( 'td', array(), $this->getLang()->formatNum( $pageInfo['views'] ) ) .
+ Html::element( 'td', array(), $this->getLang()->formatNum( $talkInfo['views'] ) )
+ ) .
+ Html::rawElement( 'tr', array(),
+ Html::element( 'td', array(), wfMsg( 'pageinfo-viewsperedit' ) ) .
+ Html::element( 'td', array(), $this->getLang()->formatNum( sprintf( '%.2f', $pageInfo['edits'] ? $pageInfo['views'] / $pageInfo['edits'] : 0 ) ) ) .
+ Html::element( 'td', array(), $this->getLang()->formatNum( sprintf( '%.2f', $talkInfo['edits'] ? $talkInfo['views'] / $talkInfo['edits'] : 0 ) ) )
+ )
+ )
+ );
+ }
+
+ /**
+ * Return the total number of edits and number of unique editors
+ * on a given page. If page does not exist, returns false.
+ *
+ * @param $title Title object
+ * @return mixed array or boolean false
+ */
+ public static function pageCountInfo( $title ) {
+ $id = $title->getArticleId();
+ $dbr = wfGetDB( DB_SLAVE );
+
+ $watchers = (int)$dbr->selectField(
+ 'watchlist',
+ 'COUNT(*)',
+ array(
+ 'wl_title' => $title->getDBkey(),
+ 'wl_namespace' => $title->getNamespace()
+ ),
+ __METHOD__
+ );
+
+ $edits = (int)$dbr->selectField(
+ 'revision',
+ 'COUNT(rev_page)',
+ array( 'rev_page' => $id ),
+ __METHOD__
+ );
+
+ $authors = (int)$dbr->selectField(
+ 'revision',
+ 'COUNT(DISTINCT rev_user_text)',
+ array( 'rev_page' => $id ),
+ __METHOD__
+ );
+
+ $views = (int)$dbr->selectField(
+ 'page',
+ 'page_counter',
+ array( 'page_id' => $id ),
+ __METHOD__
+ );
+
+ return array( 'watchers' => $watchers, 'edits' => $edits,
+ 'authors' => $authors, 'views' => $views );
+ }
+}
diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php
index d83749988ff..7fe1fc73fd7 100644
--- a/languages/messages/MessagesEn.php
+++ b/languages/messages/MessagesEn.php
@@ -812,7 +812,6 @@ XHTML id names.
'history' => 'Page history',
'history_short' => 'History',
'updatedmarker' => 'updated since my last visit',
-'info_short' => 'Information',
'printableversion' => 'Printable version',
'permalink' => 'Permanent link',
'print' => 'Print',
@@ -3566,12 +3565,17 @@ This is probably caused by a link to a blacklisted external site.',
'spam_blanking' => 'All revisions contained links to $1, blanking',
# Info page
-'infosubtitle' => 'Information for page',
-'numedits' => 'Number of edits (page): $1',
-'numtalkedits' => 'Number of edits (discussion page): $1',
-'numwatchers' => 'Number of watchers: $1',
-'numauthors' => 'Number of distinct authors (page): $1',
-'numtalkauthors' => 'Number of distinct authors (discussion page): $1',
+'pageinfo-title' => 'Information for "$1"',
+'pageinfo-header-edits' => 'Edits',
+'pageinfo-header-watchlist' => 'Watchlist',
+'pageinfo-header-views' => 'Views',
+'pageinfo-subjectpage' => 'Page',
+'pageinfo-talkpage' => 'Talk page',
+'pageinfo-watchers' => 'Number of watchers',
+'pageinfo-edits' => 'Number of edits',
+'pageinfo-authors' => 'Number of distinct authors',
+'pageinfo-views' => 'Number of views',
+'pageinfo-viewsperedit' => 'Views per edit',
# Skin names
'skinname-standard' => 'Classic', # only translate this message to other languages if you have to change it
diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc
index 805a2eee729..7bd4b38ea16 100644
--- a/maintenance/language/messages.inc
+++ b/maintenance/language/messages.inc
@@ -218,7 +218,6 @@ $wgMessageStructure = array(
'history',
'history_short',
'updatedmarker',
- 'info_short',
'printableversion',
'permalink',
'print',
@@ -2513,12 +2512,17 @@ $wgMessageStructure = array(
'spam_blanking',
),
'info' => array(
- 'infosubtitle',
- 'numedits',
- 'numtalkedits',
- 'numwatchers',
- 'numauthors',
- 'numtalkauthors',
+ 'pageinfo-title',
+ 'pageinfo-header-edits',
+ 'pageinfo-header-watchlist',
+ 'pageinfo-header-views',
+ 'pageinfo-subjectpage',
+ 'pageinfo-talkpage',
+ 'pageinfo-watchers',
+ 'pageinfo-edits',
+ 'pageinfo-authors',
+ 'pageinfo-views',
+ 'pageinfo-viewsperedit',
),
'skin' => array(
'skinname-standard',