46use Wikimedia\Timestamp\TimestampException;
79 parent::__construct(
'Log' );
80 $this->linkBatchFactory = $linkBatchFactory;
81 $this->dbProvider = $dbProvider;
82 $this->actorNormalization = $actorNormalization;
83 $this->userIdentityLookup = $userIdentityLookup;
84 $this->userNameUtils = $userNameUtils;
91 $out->addModules(
'mediawiki.userSuggest' );
92 $out->addModuleStyles(
'mediawiki.interface.helpers.styles' );
96 $opts->
add(
'type',
'' );
97 $opts->add(
'user',
'' );
98 $opts->add(
'page',
'' );
99 $opts->add(
'pattern',
false );
100 $opts->add(
'year',
null, FormOptions::INTNULL );
101 $opts->add(
'month',
null, FormOptions::INTNULL );
102 $opts->add(
'day',
null, FormOptions::INTNULL );
103 $opts->add(
'tagfilter',
'' );
104 $opts->add(
'tagInvert',
false );
105 $opts->add(
'offset',
'' );
106 $opts->add(
'dir',
'' );
107 $opts->add(
'offender',
'' );
108 $opts->add(
'subtype',
'' );
109 $opts->add(
'logid',
'' );
112 if ( $par !==
null ) {
113 $this->parseParams( (
string)$par );
115 $opts->fetchValuesFromRequest( $this->
getRequest() );
118 $dateString = $this->
getRequest()->getVal(
'wpdate' );
121 $dateStamp = MWTimestamp::getInstance( $dateString .
' 00:00:00' );
122 }
catch ( TimestampException $e ) {
128 $opts->setValue(
'year', (
int)$dateStamp->format(
'Y' ) );
129 $opts->setValue(
'month', (
int)$dateStamp->format(
'm' ) );
130 $opts->setValue(
'day', (
int)$dateStamp->format(
'd' ) );
137 $type = $opts->getValue(
'type' );
138 if ( isset( $logRestrictions[$type] )
139 && !$this->
getAuthority()->isAllowed( $logRestrictions[$type] )
144 # TODO: Move this into LogPager like other query conditions.
145 # Handle type-specific inputs
147 $offenderName = $opts->getValue(
'offender' );
148 if ( $opts->getValue(
'type' ) ==
'suppress' && $offenderName !==
'' ) {
149 $dbr = $this->dbProvider->getReplicaDatabase();
150 $offenderId = $this->actorNormalization->findActorIdByName( $offenderName, $dbr );
152 $qc = [
'ls_field' =>
'target_author_actor',
'ls_value' => strval( $offenderId ) ];
160 $opts->getValue(
'type' ), $this->getRequest(), $qc );
163 # TODO: Move this into LogEventList and use it as filter-callback in the field descriptor.
164 # Some log types are only for a 'User:' title but we might have been given
165 # only the username instead of the full title 'User:username'. This part try
166 # to lookup for a user by that name and eventually fix user input. See T3697.
167 if ( in_array( $opts->getValue(
'type' ), self::getLogTypesOnUser( $this->getHookRunner() ) ) ) {
168 # ok we have a type of log which expect a user title.
169 $page = $opts->getValue(
'page' );
170 $target = Title::newFromText( $page );
171 if ( $target && $target->getNamespace() ===
NS_MAIN ) {
172 if ( IPUtils::isValidRange( $target->getText() ) ) {
173 $page = IPUtils::sanitizeRange( $target->getText() );
175 # User forgot to add 'User:', we are adding it for him
176 $target = Title::makeTitleSafe(
NS_USER, $page );
177 } elseif ( $target && $target->getNamespace() ===
NS_USER
178 && IPUtils::isValidRange( $target->getText() )
180 $ipOrRange = IPUtils::sanitizeRange( $target->getText() );
181 if ( $ipOrRange !== $target->getText() ) {
182 $target = Title::makeTitleSafe(
NS_USER, $ipOrRange );
185 if ( $target !==
null ) {
186 $page = $target->getPrefixedText();
187 $opts->setValue(
'page', $page );
192 $this->show( $opts, $qc );
207 static $types =
null;
208 if ( $types !==
null ) {
219 ->onGetLogTypesOnUser( $types );
229 $subpages = LogPage::validTypes();
243 private function parseParams(
string $par ) {
245 $parms = explode(
'/', $par, 2 );
246 $symsForAll = [
'*',
'all' ];
247 if ( $parms[0] !==
'' &&
248 ( in_array( $parms[0], LogPage::validTypes() ) || in_array( $parms[0], $symsForAll ) )
250 $this->
getRequest()->setVal(
'type', $parms[0] );
251 if ( count( $parms ) === 2 ) {
252 $this->
getRequest()->setVal(
'user', $parms[1] );
254 } elseif ( $par !==
'' ) {
259 private function show( FormOptions $opts, array $extraConds ) {
260 # Create a LogPager item to get the results and a LogEventsList item to format them...
264 LogEventsList::USE_CHECKBOXES
266 $pager =
new LogPager(
268 $opts->getValue(
'type' ),
269 $opts->getValue(
'user' ),
270 $opts->getValue(
'page' ),
271 $opts->getValue(
'pattern' ),
273 $opts->getValue(
'year' ),
274 $opts->getValue(
'month' ),
275 $opts->getValue(
'day' ),
276 $opts->getValue(
'tagfilter' ),
277 $opts->getValue(
'subtype' ),
278 $opts->getValue(
'logid' ),
279 $this->linkBatchFactory,
280 $this->actorNormalization,
281 $opts->getValue(
'tagInvert' )
285 $performer = $pager->getPerformer();
287 $performerUser = $this->userIdentityLookup->getUserIdentityByName( $performer );
290 if ( $performerUser && !IPUtils::isValidRange( $performer ) &&
291 ( $this->userNameUtils->isIP( $performer ) || $performerUser->isRegistered() )
293 $this->
getSkin()->setRelevantUser( $performerUser );
298 $succeed = $loglist->showOptions(
299 $opts->getValue(
'type' ),
300 $opts->getValue(
'year' ),
301 $opts->getValue(
'month' ),
302 $opts->getValue(
'day' )
309 (
new LogPage( $opts->getValue(
'type' ) ) )->getName()
313 $logBody = $pager->getBody();
316 $pager->getNavigationBar() .
317 $this->getActionButtons(
318 $loglist->beginLogEventsList() .
320 $loglist->endLogEventsList()
322 $pager->getNavigationBar()
325 $this->
getOutput()->addWikiMsg(
'logempty' );
329 private function getActionButtons( $formcontents ) {
331 ->isAllowedAll(
'deletedhistory',
'deletelogentry' );
333 # If the user doesn't have the ability to delete log entries nor edit tags,
334 # don't bother showing them the button(s).
335 if ( !$canRevDelete && !$showTagEditUI ) {
336 return $formcontents;
339 # Show button to hide log entries and/or edit change tags
340 $s = Html::openElement(
342 [
'action' =>
wfScript(),
'id' =>
'mw-log-deleterevision-submit' ]
344 $s .= Html::hidden(
'type',
'logging' ) .
"\n";
347 if ( $canRevDelete ) {
354 'class' =>
"deleterevision-log-submit mw-log-deleterevision-button mw-ui-button"
356 $this->
msg(
'showhideselectedlogentries' )->text()
359 if ( $showTagEditUI ) {
366 'class' =>
"editchangetags-log-submit mw-log-editchangetags-button mw-ui-button"
368 $this->
msg(
'log-edit-tags' )->text()
372 $buttons .= (
new ListToggle( $this->
getOutput() ) )->getHTML();
374 $s .= $buttons . $formcontents . $buttons;
375 $s .= Html::closeElement(
'form' );
386class_alias( SpecialLog::class,
'SpecialLog' );
wfScript( $script='index')
Get the URL path to a MediaWiki entry point.
Class to simplify the use of log pages.
A class containing constants representing the names of configuration variables.
const LogRestrictions
Name constant for the LogRestrictions setting, for use with Config::get()
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getSkin()
Shortcut to get the skin being used for this instance.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
getConfig()
Shortcut to get main config object.
getContext()
Gets the context this SpecialPage is executed in.
getRequest()
Get the WebRequest being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
getAuthority()
Shortcut to get the Authority executing this instance.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Show an error when a user tries to do something they do not have the necessary permissions for.