wiki.techinc.nl/includes/changes/ChangesList.php

788 lines
22 KiB
PHP
Raw Normal View History

<?php
/**
* Base class for all changes lists.
*
* The class is used for formatting recent changes, related changes and watchlist.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
use MediaWiki\Linker\LinkRenderer;
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ResultWrapper;
class ChangesList extends ContextSource {
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
const CSS_CLASS_PREFIX = 'mw-changeslist-';
/**
* @var Skin
*/
public $skin;
protected $watchlist = false;
protected $lastdate;
protected $message;
protected $rc_cache;
protected $rcCacheIndex;
protected $rclistOpen;
protected $rcMoveIndex;
/** @var callable */
protected $changeLinePrefixer;
/** @var BagOStuff */
protected $watchMsgCache;
/**
* @var LinkRenderer
*/
protected $linkRenderer;
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
/**
* @var array
*/
protected $filterGroups;
/**
* Changeslist constructor
*
* @param Skin|IContextSource $obj
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
* @param array $filterGroups Array of ChangesListFilterGroup objects (currently optional)
*/
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
public function __construct( $obj, array $filterGroups = [] ) {
if ( $obj instanceof IContextSource ) {
$this->setContext( $obj );
$this->skin = $obj->getSkin();
} else {
$this->setContext( $obj->getContext() );
$this->skin = $obj;
}
$this->preCacheMessages();
$this->watchMsgCache = new HashBagOStuff( [ 'maxKeys' => 50 ] );
$this->linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
$this->filterGroups = $filterGroups;
}
/**
* Fetch an appropriate changes list class for the specified context
* Some users might want to use an enhanced list format, for instance
*
* @param IContextSource $context
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
* @param array $groups Array of ChangesListFilterGroup objects (currently optional)
* @return ChangesList
*/
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
public static function newFromContext( IContextSource $context, array $groups = [] ) {
$user = $context->getUser();
$sk = $context->getSkin();
$list = null;
if ( Hooks::run( 'FetchChangesList', [ $user, &$sk, &$list ] ) ) {
$new = $context->getRequest()->getBool( 'enhanced', $user->getOption( 'usenewrc' ) );
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
return $new ?
new EnhancedChangesList( $context, $groups ) :
new OldChangesList( $context, $groups );
} else {
return $list;
}
}
/**
* Format a line
*
* @since 1.27
*
* @param RecentChange &$rc Passed by reference
* @param bool $watched (default false)
* @param int $linenumber (default null)
*
* @return string|bool
*/
public function recentChangesLine( &$rc, $watched = false, $linenumber = null ) {
throw new RuntimeException( 'recentChangesLine should be implemented' );
}
/**
* Sets the list to use a "<li class='watchlist-(namespace)-(page)'>" tag
* @param bool $value
*/
public function setWatchlistDivs( $value = true ) {
$this->watchlist = $value;
}
/**
* @return bool True when setWatchlistDivs has been called
* @since 1.23
*/
public function isWatchlist() {
return (bool)$this->watchlist;
}
/**
* As we use the same small set of messages in various methods and that
* they are called often, we call them once and save them in $this->message
*/
private function preCacheMessages() {
if ( !isset( $this->message ) ) {
foreach ( [
'cur', 'diff', 'hist', 'enhancedrc-history', 'last', 'blocklink', 'history',
'semicolon-separator', 'pipe-separator' ] as $msg
) {
$this->message[$msg] = $this->msg( $msg )->escaped();
}
}
}
/**
* Returns the appropriate flags for new page, minor change and patrolling
* @param array $flags Associative array of 'flag' => Bool
* @param string $nothing To use for empty space
* @return string
*/
public function recentChangesFlags( $flags, $nothing = '&#160;' ) {
$f = '';
foreach ( array_keys( $this->getConfig()->get( 'RecentChangesFlags' ) ) as $flag ) {
$f .= isset( $flags[$flag] ) && $flags[$flag]
? self::flag( $flag, $this->getContext() )
: $nothing;
}
return $f;
}
/**
* Get an array of default HTML class attributes for the change.
*
* @param RecentChange|RCCacheEntry $rc
* @param string|bool $watched Optionally timestamp for adding watched class
*
* @return array of classes
*/
protected function getHTMLClasses( $rc, $watched ) {
$classes = [ self::CSS_CLASS_PREFIX . 'line' ];
$logType = $rc->mAttribs['rc_log_type'];
if ( $logType ) {
$classes[] = self::CSS_CLASS_PREFIX . 'log';
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
$classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'log-' . $logType );
} else {
$classes[] = self::CSS_CLASS_PREFIX . 'edit';
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
$classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'ns' .
$rc->mAttribs['rc_namespace'] . '-' . $rc->mAttribs['rc_title'] );
}
$classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'ns-' .
$rc->mAttribs['rc_namespace'] );
// Indicate watched status on the line to allow for more
// comprehensive styling.
$classes[] = $watched && $rc->mAttribs['rc_timestamp'] >= $watched
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
? self::CSS_CLASS_PREFIX . 'line-watched'
: self::CSS_CLASS_PREFIX . 'line-not-watched';
$classes = array_merge( $classes, $this->getHTMLClassesForFilters( $rc ) );
return $classes;
}
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
/**
* Get an array of CSS classes attributed to filters for this row
*
* @param RecentChange $rc
* @return array Array of CSS classes
*/
protected function getHTMLClassesForFilters( $rc ) {
$classes = [];
Back-end of new RecentChanges page, refactoring Generate old RC, Related changes (it was already displayed and working on 'Related changes' before this change), and Watchlist/etc. and data for new UI from back-end. This moves everything used for defining the old (unstructured) and new (structured) filters into unified objects, ChangesListFilter and ChangesListFilterGroup (and sub-classes). This includes the query logic (see below) and logic for adding CSS attribution classes. This is a breaking change (for subclasses of ChangesListSpecialpage) due to the signature (and name) change of buildMainQueryConds and doMainQuery. An alternative that I don't think is a breaking change would be to put the filter->DB logic in runMainQueryHook, but then it's doing more than just running a hook. This is because it used to only build $conds here, but it's clear from filterOnUserExperienceLevel filters need more than this. I added all the DB parameters from the hook, but this could be debated. I have an checked and fixed the WMF-deployed extensions affected by this. Other than that, there should be full back-compat (including legacy filters not using the new system). * add hidepatrolled/hideunpatrolled to new UI. * Move userExpLevel from RC to ChangesListSpecialPage. Although for now the structured UI only displays on RC anyway, when it displays on watchlist, it seems we'll want userExpLevel there. Change this to make 'all' exclude unregistered users. * Don't have front-end convert none-selected to 'all' on string_options. * Needs the hideanons/hideliu special redirect to be done before this is merged (T151873) Bug: T152754 Bug: T152797 Change-Id: Iec2d82f6a830403d1c948a280efa58992e0cdee7
2017-02-14 07:55:37 +00:00
if ( $this->filterGroups !== null ) {
foreach ( $this->filterGroups as $filterGroup ) {
foreach ( $filterGroup->getFilters() as $filter ) {
$filter->applyCssClassIfNeeded( $this, $rc, $classes );
}
}
}
return $classes;
}
/**
* Make an "<abbr>" element for a given change flag. The flag indicating a new page, minor edit,
* bot edit, or unpatrolled edit. In English it typically contains "N", "m", "b", or "!".
*
* @param string $flag One key of $wgRecentChangesFlags
* @param IContextSource $context
* @return string HTML
*/
public static function flag( $flag, IContextSource $context = null ) {
static $map = [ 'minoredit' => 'minor', 'botedit' => 'bot' ];
static $flagInfos = null;
if ( is_null( $flagInfos ) ) {
global $wgRecentChangesFlags;
$flagInfos = [];
foreach ( $wgRecentChangesFlags as $key => $value ) {
$flagInfos[$key]['letter'] = $value['letter'];
$flagInfos[$key]['title'] = $value['title'];
// Allow customized class name, fall back to flag name
$flagInfos[$key]['class'] = isset( $value['class'] ) ? $value['class'] : $key;
}
}
$context = $context ?: RequestContext::getMain();
// Inconsistent naming, kepted for b/c
if ( isset( $map[$flag] ) ) {
$flag = $map[$flag];
}
$info = $flagInfos[$flag];
return Html::element( 'abbr', [
'class' => $info['class'],
'title' => wfMessage( $info['title'] )->setContext( $context )->text(),
], wfMessage( $info['letter'] )->setContext( $context )->text() );
}
/**
* Returns text for the start of the tabular part of RC
* @return string
*/
public function beginRecentChangesList() {
$this->rc_cache = [];
$this->rcMoveIndex = 0;
$this->rcCacheIndex = 0;
$this->lastdate = '';
$this->rclistOpen = false;
$this->getOutput()->addModuleStyles( 'mediawiki.special.changeslist' );
return '<div class="mw-changeslist">';
}
/**
* @param ResultWrapper|array $rows
*/
public function initChangesListRows( $rows ) {
Hooks::run( 'ChangesListInitRows', [ $this, $rows ] );
}
/**
* Show formatted char difference
*
* Needs the css module 'mediawiki.special.changeslist' to style output
*
* @param int $old Number of bytes
* @param int $new Number of bytes
* @param IContextSource $context
* @return string
*/
public static function showCharacterDifference( $old, $new, IContextSource $context = null ) {
if ( !$context ) {
$context = RequestContext::getMain();
}
$new = (int)$new;
$old = (int)$old;
$szdiff = $new - $old;
$lang = $context->getLanguage();
$config = $context->getConfig();
$code = $lang->getCode();
static $fastCharDiff = [];
if ( !isset( $fastCharDiff[$code] ) ) {
$fastCharDiff[$code] = $config->get( 'MiserMode' )
|| $context->msg( 'rc-change-size' )->plain() === '$1';
}
$formattedSize = $lang->formatNum( $szdiff );
if ( !$fastCharDiff[$code] ) {
$formattedSize = $context->msg( 'rc-change-size', $formattedSize )->text();
}
if ( abs( $szdiff ) > abs( $config->get( 'RCChangedSizeThreshold' ) ) ) {
$tag = 'strong';
} else {
$tag = 'span';
}
if ( $szdiff === 0 ) {
$formattedSizeClass = 'mw-plusminus-null';
} elseif ( $szdiff > 0 ) {
$formattedSize = '+' . $formattedSize;
$formattedSizeClass = 'mw-plusminus-pos';
} else {
$formattedSizeClass = 'mw-plusminus-neg';
}
$formattedTotalSize = $context->msg( 'rc-change-size-new' )->numParams( $new )->text();
return Html::element( $tag,
[ 'dir' => 'ltr', 'class' => $formattedSizeClass, 'title' => $formattedTotalSize ],
$context->msg( 'parentheses', $formattedSize )->plain() ) . $lang->getDirMark();
}
/**
* Format the character difference of one or several changes.
*
* @param RecentChange $old
* @param RecentChange $new Last change to use, if not provided, $old will be used
* @return string HTML fragment
*/
public function formatCharacterDifference( RecentChange $old, RecentChange $new = null ) {
$oldlen = $old->mAttribs['rc_old_len'];
if ( $new ) {
$newlen = $new->mAttribs['rc_new_len'];
} else {
$newlen = $old->mAttribs['rc_new_len'];
}
if ( $oldlen === null || $newlen === null ) {
return '';
}
return self::showCharacterDifference( $oldlen, $newlen, $this->getContext() );
}
/**
* Returns text for the end of RC
* @return string
*/
public function endRecentChangesList() {
$out = $this->rclistOpen ? "</ul>\n" : '';
$out .= '</div>';
return $out;
}
/**
* @param string &$s HTML to update
* @param mixed $rc_timestamp
*/
public function insertDateHeader( &$s, $rc_timestamp ) {
# Make date header if necessary
$date = $this->getLanguage()->userDate( $rc_timestamp, $this->getUser() );
if ( $date != $this->lastdate ) {
if ( $this->lastdate != '' ) {
$s .= "</ul>\n";
}
$s .= Xml::element( 'h4', null, $date ) . "\n<ul class=\"special\">";
$this->lastdate = $date;
$this->rclistOpen = true;
}
}
/**
* @param string &$s HTML to update
* @param Title $title
* @param string $logtype
*/
public function insertLog( &$s, $title, $logtype ) {
$page = new LogPage( $logtype );
$logname = $page->getName()->setContext( $this->getContext() )->text();
$s .= $this->msg( 'parentheses' )->rawParams(
$this->linkRenderer->makeKnownLink( $title, $logname )
)->escaped();
}
/**
* @param string &$s HTML to update
* @param RecentChange &$rc
* @param bool|null $unpatrolled Unused variable, since 1.27.
*/
public function insertDiffHist( &$s, &$rc, $unpatrolled = null ) {
# Diff link
Enable users to watch category membership changes #2 This is part of a chain that reverts: e412ff5ecc900991cce4f99b7a069f625a5694b3. NOTE: - The feature is disabled by default - User settings default to hiding changes - T109707 Touching a file on wikisource adds and removes it from a category... Even when page has no changes.... WTF? See linked issue, marked as stalled with a possible way forward for this patch. @see https://gerrit.wikimedia.org/r/#/c/235467/ Changes since version 1: - T109604 - Page names in comment are no longer url encoded / have _'s - T109638 & T110338 - Reserved username now used when we can't determine a username for the change (we could perhaps set the user and id to be blank in the RC table, but who knows what this might do) - T109688 - History links are now disabled in RC.... (could be fine for the introduction and worked on more in the future) - Categorization changes are now always patrolled - Touching on T109672 in this change emails will never be sent regarding categorization changes. (this can of course be changed in a followup) - Added $wgRCWatchCategoryMembership defaulting to true for enabling / disabling the feature - T109700 - for cases when no revision was retrieved for a category change set the bot flag to true. This means all changes caused by parser functions & Lua will be marked as bot, as will changes that cant find their revision due to slave lag.. Bug: T9148 Bug: T109604 Bug: T109638 Bug: T109688 Bug: T109700 Bug: T110338 Bug: T110340 Change-Id: I51c2c1254de862f24a26ef9dbbf027c6c83e9063
2015-08-24 17:40:06 +00:00
if (
$rc->mAttribs['rc_type'] == RC_NEW ||
$rc->mAttribs['rc_type'] == RC_LOG ||
$rc->mAttribs['rc_type'] == RC_CATEGORIZE
) {
$diffLink = $this->message['diff'];
} elseif ( !self::userCan( $rc, Revision::DELETED_TEXT, $this->getUser() ) ) {
$diffLink = $this->message['diff'];
} else {
$query = [
'curid' => $rc->mAttribs['rc_cur_id'],
'diff' => $rc->mAttribs['rc_this_oldid'],
'oldid' => $rc->mAttribs['rc_last_oldid']
];
$diffLink = $this->linkRenderer->makeKnownLink(
$rc->getTitle(),
new HtmlArmor( $this->message['diff'] ),
[ 'class' => 'mw-changeslist-diff' ],
$query
);
}
Enable users to watch category membership changes #2 This is part of a chain that reverts: e412ff5ecc900991cce4f99b7a069f625a5694b3. NOTE: - The feature is disabled by default - User settings default to hiding changes - T109707 Touching a file on wikisource adds and removes it from a category... Even when page has no changes.... WTF? See linked issue, marked as stalled with a possible way forward for this patch. @see https://gerrit.wikimedia.org/r/#/c/235467/ Changes since version 1: - T109604 - Page names in comment are no longer url encoded / have _'s - T109638 & T110338 - Reserved username now used when we can't determine a username for the change (we could perhaps set the user and id to be blank in the RC table, but who knows what this might do) - T109688 - History links are now disabled in RC.... (could be fine for the introduction and worked on more in the future) - Categorization changes are now always patrolled - Touching on T109672 in this change emails will never be sent regarding categorization changes. (this can of course be changed in a followup) - Added $wgRCWatchCategoryMembership defaulting to true for enabling / disabling the feature - T109700 - for cases when no revision was retrieved for a category change set the bot flag to true. This means all changes caused by parser functions & Lua will be marked as bot, as will changes that cant find their revision due to slave lag.. Bug: T9148 Bug: T109604 Bug: T109638 Bug: T109688 Bug: T109700 Bug: T110338 Bug: T110340 Change-Id: I51c2c1254de862f24a26ef9dbbf027c6c83e9063
2015-08-24 17:40:06 +00:00
if ( $rc->mAttribs['rc_type'] == RC_CATEGORIZE ) {
$diffhist = $diffLink . $this->message['pipe-separator'] . $this->message['hist'];
} else {
$diffhist = $diffLink . $this->message['pipe-separator'];
# History link
$diffhist .= $this->linkRenderer->makeKnownLink(
Enable users to watch category membership changes #2 This is part of a chain that reverts: e412ff5ecc900991cce4f99b7a069f625a5694b3. NOTE: - The feature is disabled by default - User settings default to hiding changes - T109707 Touching a file on wikisource adds and removes it from a category... Even when page has no changes.... WTF? See linked issue, marked as stalled with a possible way forward for this patch. @see https://gerrit.wikimedia.org/r/#/c/235467/ Changes since version 1: - T109604 - Page names in comment are no longer url encoded / have _'s - T109638 & T110338 - Reserved username now used when we can't determine a username for the change (we could perhaps set the user and id to be blank in the RC table, but who knows what this might do) - T109688 - History links are now disabled in RC.... (could be fine for the introduction and worked on more in the future) - Categorization changes are now always patrolled - Touching on T109672 in this change emails will never be sent regarding categorization changes. (this can of course be changed in a followup) - Added $wgRCWatchCategoryMembership defaulting to true for enabling / disabling the feature - T109700 - for cases when no revision was retrieved for a category change set the bot flag to true. This means all changes caused by parser functions & Lua will be marked as bot, as will changes that cant find their revision due to slave lag.. Bug: T9148 Bug: T109604 Bug: T109638 Bug: T109688 Bug: T109700 Bug: T110338 Bug: T110340 Change-Id: I51c2c1254de862f24a26ef9dbbf027c6c83e9063
2015-08-24 17:40:06 +00:00
$rc->getTitle(),
new HtmlArmor( $this->message['hist'] ),
[ 'class' => 'mw-changeslist-history' ],
[
Enable users to watch category membership changes #2 This is part of a chain that reverts: e412ff5ecc900991cce4f99b7a069f625a5694b3. NOTE: - The feature is disabled by default - User settings default to hiding changes - T109707 Touching a file on wikisource adds and removes it from a category... Even when page has no changes.... WTF? See linked issue, marked as stalled with a possible way forward for this patch. @see https://gerrit.wikimedia.org/r/#/c/235467/ Changes since version 1: - T109604 - Page names in comment are no longer url encoded / have _'s - T109638 & T110338 - Reserved username now used when we can't determine a username for the change (we could perhaps set the user and id to be blank in the RC table, but who knows what this might do) - T109688 - History links are now disabled in RC.... (could be fine for the introduction and worked on more in the future) - Categorization changes are now always patrolled - Touching on T109672 in this change emails will never be sent regarding categorization changes. (this can of course be changed in a followup) - Added $wgRCWatchCategoryMembership defaulting to true for enabling / disabling the feature - T109700 - for cases when no revision was retrieved for a category change set the bot flag to true. This means all changes caused by parser functions & Lua will be marked as bot, as will changes that cant find their revision due to slave lag.. Bug: T9148 Bug: T109604 Bug: T109638 Bug: T109688 Bug: T109700 Bug: T110338 Bug: T110340 Change-Id: I51c2c1254de862f24a26ef9dbbf027c6c83e9063
2015-08-24 17:40:06 +00:00
'curid' => $rc->mAttribs['rc_cur_id'],
'action' => 'history'
]
Enable users to watch category membership changes #2 This is part of a chain that reverts: e412ff5ecc900991cce4f99b7a069f625a5694b3. NOTE: - The feature is disabled by default - User settings default to hiding changes - T109707 Touching a file on wikisource adds and removes it from a category... Even when page has no changes.... WTF? See linked issue, marked as stalled with a possible way forward for this patch. @see https://gerrit.wikimedia.org/r/#/c/235467/ Changes since version 1: - T109604 - Page names in comment are no longer url encoded / have _'s - T109638 & T110338 - Reserved username now used when we can't determine a username for the change (we could perhaps set the user and id to be blank in the RC table, but who knows what this might do) - T109688 - History links are now disabled in RC.... (could be fine for the introduction and worked on more in the future) - Categorization changes are now always patrolled - Touching on T109672 in this change emails will never be sent regarding categorization changes. (this can of course be changed in a followup) - Added $wgRCWatchCategoryMembership defaulting to true for enabling / disabling the feature - T109700 - for cases when no revision was retrieved for a category change set the bot flag to true. This means all changes caused by parser functions & Lua will be marked as bot, as will changes that cant find their revision due to slave lag.. Bug: T9148 Bug: T109604 Bug: T109638 Bug: T109688 Bug: T109700 Bug: T110338 Bug: T110340 Change-Id: I51c2c1254de862f24a26ef9dbbf027c6c83e9063
2015-08-24 17:40:06 +00:00
);
}
// @todo FIXME: Hard coded ". .". Is there a message for this? Should there be?
$s .= $this->msg( 'parentheses' )->rawParams( $diffhist )->escaped() .
' <span class="mw-changeslist-separator">. .</span> ';
}
/**
* @param string &$s Article link will be appended to this string, in place.
* @param RecentChange $rc
* @param bool $unpatrolled
* @param bool $watched
* @deprecated since 1.27, use getArticleLink instead.
*/
public function insertArticleLink( &$s, RecentChange $rc, $unpatrolled, $watched ) {
$s .= $this->getArticleLink( $rc, $unpatrolled, $watched );
}
/**
* @param RecentChange &$rc
* @param bool $unpatrolled
* @param bool $watched
* @return string HTML
* @since 1.26
*/
public function getArticleLink( &$rc, $unpatrolled, $watched ) {
$params = [];
if ( $rc->getTitle()->isRedirect() ) {
$params = [ 'redirect' => 'no' ];
}
$articlelink = $this->linkRenderer->makeLink(
$rc->getTitle(),
null,
[ 'class' => 'mw-changeslist-title' ],
$params
);
if ( $this->isDeleted( $rc, Revision::DELETED_TEXT ) ) {
$articlelink = '<span class="history-deleted">' . $articlelink . '</span>';
}
# To allow for boldening pages watched by this user
$articlelink = "<span class=\"mw-title\">{$articlelink}</span>";
# RTL/LTR marker
$articlelink .= $this->getLanguage()->getDirMark();
# TODO: Deprecate the $s argument, it seems happily unused.
$s = '';
# Avoid PHP 7.1 warning from passing $this by reference
$changesList = $this;
Hooks::run( 'ChangesListInsertArticleLink',
[ &$changesList, &$articlelink, &$s, &$rc, $unpatrolled, $watched ] );
return "{$s} {$articlelink}";
}
/**
* Get the timestamp from $rc formatted with current user's settings
* and a separator
*
* @param RecentChange $rc
* @return string HTML fragment
*/
public function getTimestamp( $rc ) {
// @todo FIXME: Hard coded ". .". Is there a message for this? Should there be?
return $this->message['semicolon-separator'] . '<span class="mw-changeslist-date">' .
$this->getLanguage()->userTime(
$rc->mAttribs['rc_timestamp'],
$this->getUser()
) . '</span> <span class="mw-changeslist-separator">. .</span> ';
}
/**
* Insert time timestamp string from $rc into $s
*
* @param string &$s HTML to update
* @param RecentChange $rc
*/
public function insertTimestamp( &$s, $rc ) {
$s .= $this->getTimestamp( $rc );
}
/**
* Insert links to user page, user talk page and eventually a blocking link
*
* @param string &$s HTML to update
* @param RecentChange &$rc
*/
public function insertUserRelatedLinks( &$s, &$rc ) {
if ( $this->isDeleted( $rc, Revision::DELETED_USER ) ) {
$s .= ' <span class="history-deleted">' .
$this->msg( 'rev-deleted-user' )->escaped() . '</span>';
} else {
$s .= $this->getLanguage()->getDirMark() . Linker::userLink( $rc->mAttribs['rc_user'],
$rc->mAttribs['rc_user_text'] );
$s .= Linker::userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
}
}
/**
* Insert a formatted action
*
* @param RecentChange $rc
* @return string
*/
public function insertLogEntry( $rc ) {
$formatter = LogFormatter::newFromRow( $rc->mAttribs );
$formatter->setContext( $this->getContext() );
$formatter->setShowUserToolLinks( true );
$mark = $this->getLanguage()->getDirMark();
return $formatter->getActionText() . " $mark" . $formatter->getComment();
}
/**
* Insert a formatted comment
* @param RecentChange $rc
* @return string
*/
public function insertComment( $rc ) {
if ( $this->isDeleted( $rc, Revision::DELETED_COMMENT ) ) {
return ' <span class="history-deleted">' .
$this->msg( 'rev-deleted-comment' )->escaped() . '</span>';
} else {
return Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() );
}
}
/**
* Returns the string which indicates the number of watching users
* @param int $count Number of user watching a page
* @return string
*/
protected function numberofWatchingusers( $count ) {
if ( $count <= 0 ) {
return '';
}
$cache = $this->watchMsgCache;
return $cache->getWithSetCallback(
$cache->makeKey( 'watching-users-msg', $count ),
$cache::TTL_INDEFINITE,
function () use ( $count ) {
return $this->msg( 'number_of_watching_users_RCview' )
->numParams( $count )->escaped();
}
);
}
/**
* Determine if said field of a revision is hidden
* @param RCCacheEntry|RecentChange $rc
* @param int $field One of DELETED_* bitfield constants
* @return bool
*/
public static function isDeleted( $rc, $field ) {
return ( $rc->mAttribs['rc_deleted'] & $field ) == $field;
}
/**
* Determine if the current user is allowed to view a particular
* field of this revision, if it's marked as deleted.
* @param RCCacheEntry|RecentChange $rc
* @param int $field
* @param User $user User object to check, or null to use $wgUser
* @return bool
*/
public static function userCan( $rc, $field, User $user = null ) {
if ( $rc->mAttribs['rc_type'] == RC_LOG ) {
return LogEventsList::userCanBitfield( $rc->mAttribs['rc_deleted'], $field, $user );
} else {
return Revision::userCanBitfield( $rc->mAttribs['rc_deleted'], $field, $user );
}
}
/**
* @param string $link
* @param bool $watched
* @return string
*/
protected function maybeWatchedLink( $link, $watched = false ) {
if ( $watched ) {
return '<strong class="mw-watched">' . $link . '</strong>';
} else {
return '<span class="mw-rc-unwatched">' . $link . '</span>';
}
}
/** Inserts a rollback link
*
* @param string &$s
* @param RecentChange &$rc
*/
public function insertRollback( &$s, &$rc ) {
if ( $rc->mAttribs['rc_type'] == RC_EDIT
&& $rc->mAttribs['rc_this_oldid']
&& $rc->mAttribs['rc_cur_id']
) {
$page = $rc->getTitle();
/** Check for rollback and edit permissions, disallow special pages, and only
* show a link on the top-most revision */
if ( $this->getUser()->isAllowed( 'rollback' )
&& $rc->mAttribs['page_latest'] == $rc->mAttribs['rc_this_oldid']
) {
$rev = new Revision( [
'title' => $page,
'id' => $rc->mAttribs['rc_this_oldid'],
'user' => $rc->mAttribs['rc_user'],
'user_text' => $rc->mAttribs['rc_user_text'],
'deleted' => $rc->mAttribs['rc_deleted']
] );
$s .= ' ' . Linker::generateRollback( $rev, $this->getContext() );
}
}
}
/**
* @param RecentChange $rc
* @return string
* @since 1.26
*/
public function getRollback( RecentChange $rc ) {
$s = '';
$this->insertRollback( $s, $rc );
return $s;
}
/**
* @param string &$s
* @param RecentChange &$rc
* @param array &$classes
*/
public function insertTags( &$s, &$rc, &$classes ) {
if ( empty( $rc->mAttribs['ts_tags'] ) ) {
return;
}
list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow(
$rc->mAttribs['ts_tags'],
'changeslist',
$this->getContext()
);
$classes = array_merge( $classes, $newClasses );
$s .= ' ' . $tagSummary;
}
/**
* @param RecentChange $rc
* @param array &$classes
* @return string
* @since 1.26
*/
public function getTags( RecentChange $rc, array &$classes ) {
$s = '';
$this->insertTags( $s, $rc, $classes );
return $s;
}
public function insertExtra( &$s, &$rc, &$classes ) {
// Empty, used for subclasses to add anything special.
}
protected function showAsUnpatrolled( RecentChange $rc ) {
return self::isUnpatrolled( $rc, $this->getUser() );
}
/**
* @param object|RecentChange $rc Database row from recentchanges or a RecentChange object
* @param User $user
* @return bool
*/
public static function isUnpatrolled( $rc, User $user ) {
if ( $rc instanceof RecentChange ) {
$isPatrolled = $rc->mAttribs['rc_patrolled'];
$rcType = $rc->mAttribs['rc_type'];
$rcLogType = $rc->mAttribs['rc_log_type'];
} else {
$isPatrolled = $rc->rc_patrolled;
$rcType = $rc->rc_type;
$rcLogType = $rc->rc_log_type;
}
if ( !$isPatrolled ) {
if ( $user->useRCPatrol() ) {
return true;
}
if ( $user->useNPPatrol() && $rcType == RC_NEW ) {
return true;
}
if ( $user->useFilePatrol() && $rcLogType == 'upload' ) {
return true;
}
}
return false;
}
Enable users to watch category membership changes #2 This is part of a chain that reverts: e412ff5ecc900991cce4f99b7a069f625a5694b3. NOTE: - The feature is disabled by default - User settings default to hiding changes - T109707 Touching a file on wikisource adds and removes it from a category... Even when page has no changes.... WTF? See linked issue, marked as stalled with a possible way forward for this patch. @see https://gerrit.wikimedia.org/r/#/c/235467/ Changes since version 1: - T109604 - Page names in comment are no longer url encoded / have _'s - T109638 & T110338 - Reserved username now used when we can't determine a username for the change (we could perhaps set the user and id to be blank in the RC table, but who knows what this might do) - T109688 - History links are now disabled in RC.... (could be fine for the introduction and worked on more in the future) - Categorization changes are now always patrolled - Touching on T109672 in this change emails will never be sent regarding categorization changes. (this can of course be changed in a followup) - Added $wgRCWatchCategoryMembership defaulting to true for enabling / disabling the feature - T109700 - for cases when no revision was retrieved for a category change set the bot flag to true. This means all changes caused by parser functions & Lua will be marked as bot, as will changes that cant find their revision due to slave lag.. Bug: T9148 Bug: T109604 Bug: T109638 Bug: T109688 Bug: T109700 Bug: T110338 Bug: T110340 Change-Id: I51c2c1254de862f24a26ef9dbbf027c6c83e9063
2015-08-24 17:40:06 +00:00
/**
* Determines whether a revision is linked to this change; this may not be the case
* when the categorization wasn't done by an edit but a conditional parser function
*
* @since 1.27
*
* @param RecentChange|RCCacheEntry $rcObj
* @return bool
*/
protected function isCategorizationWithoutRevision( $rcObj ) {
return intval( $rcObj->getAttribute( 'rc_type' ) ) === RC_CATEGORIZE
&& intval( $rcObj->getAttribute( 'rc_this_oldid' ) ) === 0;
}
/**
* Get recommended data attributes for a change line.
* @param RecentChange $rc
* @return string[] attribute name => value
*/
protected function getDataAttributes( RecentChange $rc ) {
$attrs = [];
$type = $rc->getAttribute( 'rc_source' );
switch ( $type ) {
case RecentChange::SRC_EDIT:
case RecentChange::SRC_NEW:
$attrs['data-mw-revid'] = $rc->mAttribs['rc_this_oldid'];
break;
case RecentChange::SRC_LOG:
$attrs['data-mw-logid'] = $rc->mAttribs['rc_logid'];
$attrs['data-mw-logaction'] =
$rc->mAttribs['rc_log_type'] . '/' . $rc->mAttribs['rc_log_action'];
break;
}
$attrs[ 'data-mw-ts' ] = $rc->getAttribute( 'rc_timestamp' );
return $attrs;
}
/**
* Sets the callable that generates a change line prefix added to the beginning of each line.
*
* @param callable $prefixer Callable to run that generates the change line prefix.
* Takes three parameters: a RecentChange object, a ChangesList object,
* and whether the current entry is a grouped entry.
*/
public function setChangeLinePrefixer( callable $prefixer ) {
$this->changeLinePrefixer = $prefixer;
}
}