Page MenuHomeWickedGov Phorge

TimelinePager.php
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

TimelinePager.php

<?php
namespace MediaWiki\CheckUser\Investigate\Pagers;
use MediaWiki\Cache\LinkBatchFactory;
use MediaWiki\CheckUser\Hook\CheckUserFormatRowHook;
use MediaWiki\CheckUser\Investigate\Services\TimelineService;
use MediaWiki\CheckUser\Investigate\Utilities\DurationManager;
use MediaWiki\CheckUser\Services\TokenQueryManager;
use MediaWiki\Context\IContextSource;
use MediaWiki\Html\Html;
use MediaWiki\Linker\LinkRenderer;
use MediaWiki\Pager\ReverseChronologicalPager;
use MediaWiki\Parser\ParserOutput;
use MediaWiki\User\UserIdentityValue;
use Psr\Log\LoggerInterface;
use Wikimedia\Rdbms\FakeResultWrapper;
class TimelinePager extends ReverseChronologicalPager {
private CheckUserFormatRowHook $formatRowHookRunner;
private TimelineService $timelineService;
private TimelineRowFormatter $timelineRowFormatter;
private TokenQueryManager $tokenQueryManager;
private LinkBatchFactory $linkBatchFactory;
/** @var string */
private $start;
/** @var string|null */
private $lastDateHeader;
/**
* Targets whose results should not be included in the investigation.
* Targets in this list may or may not also be in the $targets list.
* Either way, no activity related to these targets will appear in the
* results.
*
* @var string[]
*/
private $excludeTargets;
/**
* If set, makes the pager to not show temporary accounts in the results.
*/
private bool $excludeTempAccounts;
/**
* Targets that have been added to the investigation but that are not
* present in $excludeTargets. These are the targets that will actually
* be investigated.
*
* @var string[]
*/
private $filteredTargets;
private LoggerInterface $logger;
public function __construct(
IContextSource $context,
LinkRenderer $linkRenderer,
CheckUserFormatRowHook $formatRowHookRunner,
TokenQueryManager $tokenQueryManager,
DurationManager $durationManager,
TimelineService $timelineService,
TimelineRowFormatter $timelineRowFormatter,
LinkBatchFactory $linkBatchFactory,
LoggerInterface $logger
) {
parent::__construct( $context, $linkRenderer );
$this->formatRowHookRunner = $formatRowHookRunner;
$this->timelineService = $timelineService;
$this->timelineRowFormatter = $timelineRowFormatter;
$this->tokenQueryManager = $tokenQueryManager;
$this->linkBatchFactory = $linkBatchFactory;
$this->logger = $logger;
$tokenData = $tokenQueryManager->getDataFromRequest( $context->getRequest() );
$this->mOffset = $tokenData['offset'] ?? '';
$this->excludeTempAccounts = $tokenData['FilterTempAccounts'] ?? false;
$this->excludeTargets = $tokenData['exclude-targets'] ?? [];
$this->filteredTargets = array_diff(
$tokenData['targets'] ?? [],
$this->excludeTargets
);
$this->start = $durationManager->getTimestampFromRequest( $context->getRequest() );
}
/**
* @inheritDoc
*
* Handle special case where all targets are filtered.
*/
public function reallyDoQuery( $offset, $limit, $order ) {
// If there are no targets, there is no need to run the query and an empty result can be used.
if ( $this->filteredTargets === [] ) {
return new FakeResultWrapper( [] );
}
return parent::reallyDoQuery( $offset, $limit, $order );
}
/**
* @inheritDoc
*/
public function getQueryInfo() {
return $this->timelineService->getQueryInfo(
$this->filteredTargets,
$this->excludeTargets,
$this->excludeTempAccounts,
$this->start,
$this->mLimit
);
}
/**
* @inheritDoc
*/
protected function doBatchLookups() {
$lb = $this->linkBatchFactory->newLinkBatch();
$lb->setCaller( __METHOD__ );
foreach ( $this->mResult as $row ) {
$lb->addUser( new UserIdentityValue( $row->user ?? 0, $row->user_text ?? $row->ip ) );
}
}
/**
* @inheritDoc
*/
public function getIndexField() {
return [ [ 'timestamp', 'id' ] ];
}
/**
* @inheritDoc
*/
public function formatRow( $row ) {
$line = '';
$dateHeader = $this->getLanguage()->userDate( wfTimestamp( TS_MW, $row->timestamp ), $this->getUser() );
if ( $this->lastDateHeader === null ) {
$this->lastDateHeader = $dateHeader;
$line .= Html::element( 'h4', [], $dateHeader );
$line .= Html::openElement( 'ul' );
} elseif ( $this->lastDateHeader !== $dateHeader ) {
$this->lastDateHeader = $dateHeader;
// Start a new list with a new date header
$line .= Html::closeElement( 'ul' );
$line .= Html::element( 'h4', [], $dateHeader );
$line .= Html::openElement( 'ul' );
}
$rowItems = $this->timelineRowFormatter->getFormattedRowItems( $row );
$this->formatRowHookRunner->onCheckUserFormatRow( $this->getContext(), $row, $rowItems );
if ( !is_array( $rowItems ) || !isset( $rowItems['links'] ) || !isset( $rowItems['info'] ) ) {
$this->logger->warning(
__METHOD__ . ': Expected array with keys \'links\' and \'info\''
. ' from CheckUserFormatRow $rowItems param'
);
return '';
}
$formattedLinks = implode( ' ', array_filter(
$rowItems['links'],
static function ( $item ) {
return $item !== '';
} )
);
$formatted = implode( ' . . ', array_filter(
array_merge(
[ $formattedLinks ],
$rowItems['info']
), static function ( $item ) {
return $item !== '';
} )
);
$line .= Html::rawElement(
'li',
[],
$formatted
);
return $line;
}
/**
* @inheritDoc
*
* Conceal the offset which may reveal private data.
*/
public function getPagingQueries() {
return $this->tokenQueryManager->getPagingQueries(
$this->getRequest(), parent::getPagingQueries()
);
}
/**
* Get the formatted result list, with navigation bars.
*
* @return ParserOutput
*/
public function getFullOutput(): ParserOutput {
return new ParserOutput(
$this->getNavigationBar() . $this->getBody() . $this->getNavigationBar()
);
}
/**
* @inheritDoc
*/
public function getEndBody() {
return $this->getNumRows() ? Html::closeElement( 'ul' ) : '';
}
}

File Metadata

Mime Type
text/x-php
Expires
Sat, May 16, 19:24 (4 h, 59 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
79/b0/dafde9a5c9a9b340c0cce52d54ad
Default Alt Text
TimelinePager.php (5 KB)

Event Timeline