* @ingroup Actions
*/
class InfoAction extends FormlessAction {
- const CACHE_VERSION = '2013-03-17';
+ const VERSION = 1;
/**
* Returns the name of the action this object responds to.
* @param int|null $revid Revision id to clear
*/
public static function invalidateCache( Title $title, $revid = null ) {
- $cache = ObjectCache::getMainWANInstance();
-
if ( !$revid ) {
$revision = Revision::newFromTitle( $title, 0, Revision::READ_LATEST );
$revid = $revision ? $revision->getId() : null;
}
if ( $revid !== null ) {
- $key = wfMemcKey( 'infoaction', sha1( $title->getPrefixedText() ), $revid );
- $cache->delete( $key );
+ $key = self::getCacheKey( $title, $revid );
+ ObjectCache::getMainWANInstance()->delete( $key );
}
}
$content .= $this->msg( 'pageinfo-footer' )->parse();
}
- // Page credits
- /*if ( $this->page->exists() ) {
- $content .= Html::rawElement( 'div', array( 'id' => 'mw-credits' ), $this->getContributors() );
- }*/
-
return $content;
}
* @return string The table with the row added
*/
protected function addRow( $table, $name, $value, $id ) {
- return $table . Html::rawElement( 'tr', $id === null ? array() : array( 'id' => 'mw-' . $id ),
- Html::rawElement( 'td', array( 'style' => 'vertical-align: top;' ), $name ) .
- Html::rawElement( 'td', array(), $value )
- );
+ return $table .
+ Html::rawElement(
+ 'tr',
+ $id === null ? array() : array( 'id' => 'mw-' . $id ),
+ Html::rawElement( 'td', array( 'style' => 'vertical-align: top;' ), $name ) .
+ Html::rawElement( 'td', array(), $value )
+ );
}
/**
$id = $title->getArticleID();
$config = $this->context->getConfig();
- $cache = ObjectCache::getMainWANInstance();
- $memcKey = wfMemcKey( 'infoaction',
- sha1( $title->getPrefixedText() ), $this->page->getLatest() );
- $pageCounts = $cache->get( $memcKey );
- $version = isset( $pageCounts['cacheversion'] ) ? $pageCounts['cacheversion'] : false;
- if ( $pageCounts === false || $version !== self::CACHE_VERSION ) {
- // Get page information that would be too "expensive" to retrieve by normal means
- $pageCounts = $this->pageCounts( $title );
- $pageCounts['cacheversion'] = self::CACHE_VERSION;
-
- $cache->set( $memcKey, $pageCounts );
- }
-
- // Get page properties
- $dbr = wfGetDB( DB_SLAVE );
- $result = $dbr->select(
- 'page_props',
- array( 'pp_propname', 'pp_value' ),
- array( 'pp_page' => $id ),
- __METHOD__
- );
+ $pageCounts = $this->pageCounts( $this->page );
$pageProperties = array();
- foreach ( $result as $row ) {
- $pageProperties[$row->pp_propname] = $row->pp_value;
+ $props = PageProps::getInstance()->getProperties( $title );
+ if ( isset( $props[$id] ) ) {
+ $pageProperties = $props[$id];
}
// Basic information
$policy = $this->page->getRobotPolicy( 'view', $pOutput );
$pageInfo['header-basic'][] = array(
// Messages: pageinfo-robot-index, pageinfo-robot-noindex
- $this->msg( 'pageinfo-robot-policy' ), $this->msg( "pageinfo-robot-${policy['index']}" )
+ $this->msg( 'pageinfo-robot-policy' ),
+ $this->msg( "pageinfo-robot-${policy['index']}" )
);
$unwatchedPageThreshold = $config->get( 'UnwatchedPageThreshold' );
// Subpages of this page, if subpages are enabled for the current NS
if ( MWNamespace::hasSubpages( $title->getNamespace() ) ) {
- $prefixIndex = SpecialPage::getTitleFor( 'Prefixindex', $title->getPrefixedText() . '/' );
+ $prefixIndex = SpecialPage::getTitleFor(
+ 'Prefixindex', $title->getPrefixedText() . '/' );
$pageInfo['header-basic'][] = array(
Linker::link( $prefixIndex, $this->msg( 'pageinfo-subpages-name' )->escaped() ),
$this->msg( 'pageinfo-subpages-value' )
$sources = $title->getCascadeProtectionSources(); // Array deferencing is in PHP 5.4 :(
foreach ( $sources[0] as $sourceTitle ) {
- $cascadingFrom .= Html::rawElement( 'li', array(), Linker::linkKnown( $sourceTitle ) );
+ $cascadingFrom .= Html::rawElement(
+ 'li', array(), Linker::linkKnown( $sourceTitle ) );
}
$cascadingFrom = Html::rawElement( 'ul', array(), $cascadingFrom );
$this->msg( 'pageinfo-lasttime' ),
Linker::linkKnown(
$title,
- htmlspecialchars( $lang->userTimeAndDate( $this->page->getTimestamp(), $user ) ),
+ htmlspecialchars(
+ $lang->userTimeAndDate( $this->page->getTimestamp(), $user )
+ ),
array(),
array( 'oldid' => $this->page->getLatest() )
)
// Recent number of edits (within past 30 days)
$pageInfo['header-edits'][] = array(
- $this->msg( 'pageinfo-recent-edits', $lang->formatDuration( $config->get( 'RCMaxAge' ) ) ),
+ $this->msg( 'pageinfo-recent-edits',
+ $lang->formatDuration( $config->get( 'RCMaxAge' ) ) ),
$lang->formatNum( $pageCounts['recent_edits'] )
);
// Recent number of distinct authors
$pageInfo['header-edits'][] = array(
- $this->msg( 'pageinfo-recent-authors' ), $lang->formatNum( $pageCounts['recent_authors'] )
+ $this->msg( 'pageinfo-recent-authors' ),
+ $lang->formatNum( $pageCounts['recent_authors'] )
);
// Array of MagicWord objects
/**
* Returns page counts that would be too "expensive" to retrieve by normal means.
*
- * @param Title $title Title to get counts for
+ * @param WikiPage|Article|Page $page
* @return array
*/
- protected function pageCounts( Title $title ) {
- $id = $title->getArticleID();
+ protected function pageCounts( Page $page ) {
+ $fname = __METHOD__;
$config = $this->context->getConfig();
- $dbrWatchlist = wfGetDB( DB_SLAVE, 'watchlist' );
- $result = array();
-
- // Number of page watchers
- $watchers = (int)$dbrWatchlist->selectField(
- 'watchlist',
- 'COUNT(*)',
- array(
- 'wl_namespace' => $title->getNamespace(),
- 'wl_title' => $title->getDBkey(),
- ),
- __METHOD__
- );
- $result['watchers'] = $watchers;
-
- if ( $config->get( 'ShowUpdatedMarker' ) ) {
- // Threshold: last visited about 26 weeks before latest edit
- $updated = wfTimestamp( TS_UNIX, $this->page->getTimestamp() );
- $age = $config->get( 'WatchersMaxAge' );
- $threshold = $dbrWatchlist->timestamp( $updated - $age );
- // Number of page watchers who also visited a "recent" edit
- $visitingWatchers = (int)$dbrWatchlist->selectField(
- 'watchlist',
- 'COUNT(*)',
- array(
- 'wl_namespace' => $title->getNamespace(),
- 'wl_title' => $title->getDBkey(),
- 'wl_notificationtimestamp >= ' . $dbrWatchlist->addQuotes( $threshold ) .
- ' OR wl_notificationtimestamp IS NULL'
- ),
- __METHOD__
- );
- $result['visitingWatchers'] = $visitingWatchers;
- }
+ return ObjectCache::getMainWANInstance()->getWithSetCallback(
+ self::getCacheKey( $page->getTitle(), $page->getLatest() ),
+ 86400 * 7,
+ function ( $oldValue, &$ttl, &$setOpts ) use ( $page, $config, $fname ) {
+ $title = $page->getTitle();
+ $id = $title->getArticleID();
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $dbrWatchlist = wfGetDB( DB_SLAVE, 'watchlist' );
+
+ $setOpts += Database::getCacheSetOptions( $dbr, $dbrWatchlist );
+
+ $result = array();
+
+ // Number of page watchers
+ $watchers = (int)$dbrWatchlist->selectField(
+ 'watchlist',
+ 'COUNT(*)',
+ array(
+ 'wl_namespace' => $title->getNamespace(),
+ 'wl_title' => $title->getDBkey(),
+ ),
+ $fname
+ );
+ $result['watchers'] = $watchers;
+
+ if ( $config->get( 'ShowUpdatedMarker' ) ) {
+ // Threshold: last visited about 26 weeks before latest edit
+ $updated = wfTimestamp( TS_UNIX, $page->getTimestamp() );
+ $age = $config->get( 'WatchersMaxAge' );
+ $threshold = $dbrWatchlist->timestamp( $updated - $age );
+ // Number of page watchers who also visited a "recent" edit
+ $visitingWatchers = (int)$dbrWatchlist->selectField(
+ 'watchlist',
+ 'COUNT(*)',
+ array(
+ 'wl_namespace' => $title->getNamespace(),
+ 'wl_title' => $title->getDBkey(),
+ 'wl_notificationtimestamp >= ' .
+ $dbrWatchlist->addQuotes( $threshold ) .
+ ' OR wl_notificationtimestamp IS NULL'
+ ),
+ $fname
+ );
+ $result['visitingWatchers'] = $visitingWatchers;
+ }
- $dbr = wfGetDB( DB_SLAVE );
- // Total number of edits
- $edits = (int)$dbr->selectField(
- 'revision',
- 'COUNT(*)',
- array( 'rev_page' => $id ),
- __METHOD__
- );
- $result['edits'] = $edits;
+ // Total number of edits
+ $edits = (int)$dbr->selectField(
+ 'revision',
+ 'COUNT(*)',
+ array( 'rev_page' => $id ),
+ $fname
+ );
+ $result['edits'] = $edits;
- // Total number of distinct authors
- if ( $config->get( 'MiserMode' ) ) {
- $result['authors'] = 0;
- } else {
- $result['authors'] = (int)$dbr->selectField(
- 'revision',
- 'COUNT(DISTINCT rev_user_text)',
- array( 'rev_page' => $id ),
- __METHOD__
- );
- }
+ // Total number of distinct authors
+ if ( $config->get( 'MiserMode' ) ) {
+ $result['authors'] = 0;
+ } else {
+ $result['authors'] = (int)$dbr->selectField(
+ 'revision',
+ 'COUNT(DISTINCT rev_user_text)',
+ array( 'rev_page' => $id ),
+ $fname
+ );
+ }
- // "Recent" threshold defined by RCMaxAge setting
- $threshold = $dbr->timestamp( time() - $config->get( 'RCMaxAge' ) );
+ // "Recent" threshold defined by RCMaxAge setting
+ $threshold = $dbr->timestamp( time() - $config->get( 'RCMaxAge' ) );
+
+ // Recent number of edits
+ $edits = (int)$dbr->selectField(
+ 'revision',
+ 'COUNT(rev_page)',
+ array(
+ 'rev_page' => $id,
+ "rev_timestamp >= " . $dbr->addQuotes( $threshold )
+ ),
+ $fname
+ );
+ $result['recent_edits'] = $edits;
+
+ // Recent number of distinct authors
+ $result['recent_authors'] = (int)$dbr->selectField(
+ 'revision',
+ 'COUNT(DISTINCT rev_user_text)',
+ array(
+ 'rev_page' => $id,
+ "rev_timestamp >= " . $dbr->addQuotes( $threshold )
+ ),
+ $fname
+ );
- // Recent number of edits
- $edits = (int)$dbr->selectField(
- 'revision',
- 'COUNT(rev_page)',
- array(
- 'rev_page' => $id,
- "rev_timestamp >= " . $dbr->addQuotes( $threshold )
- ),
- __METHOD__
- );
- $result['recent_edits'] = $edits;
+ // Subpages (if enabled)
+ if ( MWNamespace::hasSubpages( $title->getNamespace() ) ) {
+ $conds = array( 'page_namespace' => $title->getNamespace() );
+ $conds[] = 'page_title ' .
+ $dbr->buildLike( $title->getDBkey() . '/', $dbr->anyString() );
+
+ // Subpages of this page (redirects)
+ $conds['page_is_redirect'] = 1;
+ $result['subpages']['redirects'] = (int)$dbr->selectField(
+ 'page',
+ 'COUNT(page_id)',
+ $conds,
+ $fname
+ );
- // Recent number of distinct authors
- $result['recent_authors'] = (int)$dbr->selectField(
- 'revision',
- 'COUNT(DISTINCT rev_user_text)',
- array(
- 'rev_page' => $id,
- "rev_timestamp >= " . $dbr->addQuotes( $threshold )
- ),
- __METHOD__
- );
+ // Subpages of this page (non-redirects)
+ $conds['page_is_redirect'] = 0;
+ $result['subpages']['nonredirects'] = (int)$dbr->selectField(
+ 'page',
+ 'COUNT(page_id)',
+ $conds,
+ $fname
+ );
- // Subpages (if enabled)
- if ( MWNamespace::hasSubpages( $title->getNamespace() ) ) {
- $conds = array( 'page_namespace' => $title->getNamespace() );
- $conds[] = 'page_title ' . $dbr->buildLike( $title->getDBkey() . '/', $dbr->anyString() );
-
- // Subpages of this page (redirects)
- $conds['page_is_redirect'] = 1;
- $result['subpages']['redirects'] = (int)$dbr->selectField(
- 'page',
- 'COUNT(page_id)',
- $conds,
- __METHOD__ );
-
- // Subpages of this page (non-redirects)
- $conds['page_is_redirect'] = 0;
- $result['subpages']['nonredirects'] = (int)$dbr->selectField(
- 'page',
- 'COUNT(page_id)',
- $conds,
- __METHOD__
- );
+ // Subpages of this page (total)
+ $result['subpages']['total'] = $result['subpages']['redirects']
+ + $result['subpages']['nonredirects'];
+ }
- // Subpages of this page (total)
- $result['subpages']['total'] = $result['subpages']['redirects']
- + $result['subpages']['nonredirects'];
- }
+ // Counts for the number of transclusion links (to/from)
+ if ( $config->get( 'MiserMode' ) ) {
+ $result['transclusion']['to'] = 0;
+ } else {
+ $result['transclusion']['to'] = (int)$dbr->selectField(
+ 'templatelinks',
+ 'COUNT(tl_from)',
+ array(
+ 'tl_namespace' => $title->getNamespace(),
+ 'tl_title' => $title->getDBkey()
+ ),
+ $fname
+ );
+ }
- // Counts for the number of transclusion links (to/from)
- if ( $config->get( 'MiserMode' ) ) {
- $result['transclusion']['to'] = 0;
- } else {
- $result['transclusion']['to'] = (int)$dbr->selectField(
- 'templatelinks',
- 'COUNT(tl_from)',
- array(
- 'tl_namespace' => $title->getNamespace(),
- 'tl_title' => $title->getDBkey()
- ),
- __METHOD__
- );
- }
+ $result['transclusion']['from'] = (int)$dbr->selectField(
+ 'templatelinks',
+ 'COUNT(*)',
+ array( 'tl_from' => $title->getArticleID() ),
+ $fname
+ );
- $result['transclusion']['from'] = (int)$dbr->selectField(
- 'templatelinks',
- 'COUNT(*)',
- array( 'tl_from' => $title->getArticleID() ),
- __METHOD__
+ return $result;
+ }
);
-
- return $result;
}
/**
# "ThisSite user(s) A, B and C"
if ( count( $user_names ) ) {
- $user = $this->msg( 'siteusers' )->rawParams( $lang->listToText( $user_names ) )->params(
- count( $user_names ) )->escaped();
+ $user = $this->msg( 'siteusers' )
+ ->rawParams( $lang->listToText( $user_names ) )
+ ->params( count( $user_names ) )->escaped();
} else {
$user = false;
}
if ( count( $anon_ips ) ) {
- $anon = $this->msg( 'anonusers' )->rawParams( $lang->listToText( $anon_ips ) )->params(
- count( $anon_ips ) )->escaped();
+ $anon = $this->msg( 'anonusers' )
+ ->rawParams( $lang->listToText( $anon_ips ) )
+ ->params( count( $anon_ips ) )->escaped();
} else {
$anon = false;
}
protected function getDescription() {
return '';
}
+
+ /**
+ * @param Title $title
+ * @param int $revId
+ * @return string
+ */
+ protected static function getCacheKey( Title $title, $revId ) {
+ return wfMemcKey( 'infoaction', md5( $title->getPrefixedText() ), $revId, self::VERSION );
+ }
}