MediaWiki 1.41.2
SpecialDeletedContributions.php
Go to the documentation of this file.
1<?php
24namespace MediaWiki\Specials;
25
26use HTMLForm;
43use Wikimedia\IPUtils;
45
52 protected $mOpts;
53
54 private PermissionManager $permissionManager;
55 private IConnectionProvider $dbProvider;
56 private RevisionFactory $revisionFactory;
57 private NamespaceInfo $namespaceInfo;
58 private UserFactory $userFactory;
59 private UserNameUtils $userNameUtils;
60 private UserNamePrefixSearch $userNamePrefixSearch;
61 private CommentFormatter $commentFormatter;
62 private LinkBatchFactory $linkBatchFactory;
63
75 public function __construct(
76 PermissionManager $permissionManager,
77 IConnectionProvider $dbProvider,
78 RevisionFactory $revisionFactory,
79 NamespaceInfo $namespaceInfo,
80 UserFactory $userFactory,
81 UserNameUtils $userNameUtils,
82 UserNamePrefixSearch $userNamePrefixSearch,
83 CommentFormatter $commentFormatter,
84 LinkBatchFactory $linkBatchFactory
85 ) {
86 parent::__construct( 'DeletedContributions', 'deletedhistory' );
87 $this->permissionManager = $permissionManager;
88 $this->dbProvider = $dbProvider;
89 $this->revisionFactory = $revisionFactory;
90 $this->namespaceInfo = $namespaceInfo;
91 $this->userFactory = $userFactory;
92 $this->userNameUtils = $userNameUtils;
93 $this->userNamePrefixSearch = $userNamePrefixSearch;
94 $this->commentFormatter = $commentFormatter;
95 $this->linkBatchFactory = $linkBatchFactory;
96 }
97
104 public function execute( $par ) {
105 $this->setHeaders();
106 $this->outputHeader();
107 $this->checkPermissions();
108 $out = $this->getOutput();
109 $out->addModuleStyles( [
110 'mediawiki.interface.helpers.styles',
111 'mediawiki.special.changeslist',
112 ] );
113 $this->addHelpLink( 'Help:User contributions' );
114
115 $opts = new FormOptions();
116
117 $opts->add( 'target', '' );
118 $opts->add( 'namespace', '' );
119 $opts->add( 'limit', 20 );
120
121 $opts->fetchValuesFromRequest( $this->getRequest() );
122 $opts->validateIntBounds( 'limit', 0,
124
125 if ( $par !== null ) {
126 // Beautify the username
127 $par = $this->userNameUtils->getCanonical( $par, UserRigorOptions::RIGOR_NONE );
128 $opts->setValue( 'target', (string)$par );
129 }
130
131 $ns = $opts->getValue( 'namespace' );
132 if ( $ns !== null && $ns !== '' ) {
133 $opts->setValue( 'namespace', intval( $ns ) );
134 }
135
136 $this->mOpts = $opts;
137
138 $target = trim( $opts->getValue( 'target' ) );
139 if ( !strlen( $target ) ) {
140 $this->getForm();
141
142 return;
143 }
144
145 $userObj = $this->userFactory->newFromName( $target, UserRigorOptions::RIGOR_NONE );
146 if ( !$userObj ) {
147 $this->getForm();
148
149 return;
150 }
151 // Only set valid local user as the relevant user (T344886)
152 // Uses the same condition as the SpecialContributions class did
153 if ( !IPUtils::isValidRange( $target ) &&
154 ( $this->userNameUtils->isIP( $target ) || $userObj->isRegistered() )
155 ) {
156 $this->getSkin()->setRelevantUser( $userObj );
157 }
158
159 $target = $userObj->getName();
160
161 $out->addSubtitle( $this->getSubTitle( $userObj ) );
162 $out->setPageTitleMsg( $this->msg( 'deletedcontributions-title' )->plaintextParams( $target ) );
163
164 $this->getForm();
165
166 $pager = new DeletedContribsPager(
167 $this->getContext(),
168 $this->getHookContainer(),
169 $this->getLinkRenderer(),
170 $this->dbProvider,
171 $this->revisionFactory,
172 $this->commentFormatter,
173 $this->linkBatchFactory,
174 $target,
175 $opts->getValue( 'namespace' )
176 );
177 if ( !$pager->getNumRows() ) {
178 $out->addWikiMsg( 'nocontribs' );
179
180 return;
181 }
182
183 # Show a message about replica DB lag, if applicable
184 $lag = $pager->getDatabase()->getSessionLagStatus()['lag'];
185 if ( $lag > 0 ) {
186 $out->showLagWarning( $lag );
187 }
188
189 $out->addHTML(
190 '<p>' . $pager->getNavigationBar() . '</p>' .
191 $pager->getBody() .
192 '<p>' . $pager->getNavigationBar() . '</p>' );
193
194 # If there were contributions, and it was a valid user or IP, show
195 # the appropriate "footer" message - WHOIS tools, etc.
196 $message = IPUtils::isIPAddress( $target ) ?
197 'sp-contributions-footer-anon' :
198 'sp-contributions-footer';
199
200 if ( !$this->msg( $message )->isDisabled() ) {
201 $out->wrapWikiMsg(
202 "<div class='mw-contributions-footer'>\n$1\n</div>",
203 [ $message, $target ]
204 );
205 }
206 }
207
213 private function getSubTitle( $userObj ) {
214 $linkRenderer = $this->getLinkRenderer();
215 if ( $userObj->isAnon() ) {
216 $user = htmlspecialchars( $userObj->getName() );
217 } else {
218 $user = $linkRenderer->makeLink( $userObj->getUserPage(), $userObj->getName() );
219 }
220 $links = '';
221 $nt = $userObj->getUserPage();
222 $talk = $nt->getTalkPage();
223 if ( $talk ) {
225 $this,
226 $userObj,
227 $this->permissionManager,
228 $this->getHookRunner()
229 );
230
231 $contributionsLink = $linkRenderer->makeKnownLink(
232 SpecialPage::getTitleFor( 'Contributions', $nt->getDBkey() ),
233 $this->msg( 'sp-deletedcontributions-contribs' )->text()
234 );
235 if ( isset( $tools['deletedcontribs'] ) ) {
236 // Swap out the deletedcontribs link for our contribs one
237 $tools = wfArrayInsertAfter(
238 $tools, [ 'contribs' => $contributionsLink ], 'deletedcontribs' );
239 unset( $tools['deletedcontribs'] );
240 } else {
241 $tools['contribs'] = $contributionsLink;
242 }
243
244 $links = $this->getLanguage()->pipeList( $tools );
245
246 // Show a note if the user is blocked and display the last block log entry.
247 $block = DatabaseBlock::newFromTarget( $userObj, $userObj );
248 if ( $block !== null && $block->getType() != DatabaseBlock::TYPE_AUTO ) {
249 if ( $block->getType() == DatabaseBlock::TYPE_RANGE ) {
250 $nt = $this->namespaceInfo->getCanonicalName( NS_USER )
251 . ':' . $block->getTargetName();
252 }
253
254 // LogEventsList::showLogExtract() wants the first parameter by ref
255 $out = $this->getOutput();
257 $out,
258 'block',
259 $nt,
260 '',
261 [
262 'lim' => 1,
263 'showIfEmpty' => false,
264 'msgKey' => [
265 'sp-contributions-blocked-notice',
266 $userObj->getName() # Support GENDER in 'sp-contributions-blocked-notice'
267 ],
268 'offset' => '' # don't use $this->getRequest() parameter offset
269 ]
270 );
271 }
272 }
273
274 return $this->msg( 'contribsub2' )->rawParams( $user, $links )->params( $userObj->getName() );
275 }
276
280 private function getForm() {
281 $opts = $this->mOpts;
282
283 $formDescriptor = [
284 'target' => [
285 'type' => 'user',
286 'name' => 'target',
287 'label-message' => 'sp-contributions-username',
288 'default' => $opts->getValue( 'target' ),
289 'ipallowed' => true,
290 ],
291
292 'namespace' => [
293 'type' => 'namespaceselect',
294 'name' => 'namespace',
295 'label-message' => 'namespace',
296 'all' => '',
297 ],
298 ];
299
300 HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
301 ->setWrapperLegendMsg( 'sp-contributions-search' )
302 ->setSubmitTextMsg( 'sp-contributions-submit' )
303 // prevent setting subpage and 'target' parameter at the same time
304 ->setTitle( $this->getPageTitle() )
305 ->setMethod( 'get' )
306 ->prepareForm()
307 ->displayForm( false );
308 }
309
318 public function prefixSearchSubpages( $search, $limit, $offset ) {
319 $search = $this->userNameUtils->getCanonical( $search );
320 if ( !$search ) {
321 // No prefix suggestion for invalid user
322 return [];
323 }
324 // Autocomplete subpage as user list - public to allow caching
325 return $this->userNamePrefixSearch
326 ->search( UserNamePrefixSearch::AUDIENCE_PUBLIC, $search, $limit, $offset );
327 }
328
329 protected function getGroupName() {
330 return 'users';
331 }
332}
333
337class_alias( SpecialDeletedContributions::class, 'SpecialDeletedContributions' );
const NS_USER
Definition Defines.php:66
wfArrayInsertAfter(array $array, array $insert, $after)
Insert an array into another array after the specified key.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:158
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
This is the main service interface for converting single-line comments from various DB comment fields...
Helper class to keep track of options when mixing links and form elements.
A class containing constants representing the names of configuration variables.
const QueryPageDefaultLimit
Name constant for the QueryPageDefaultLimit setting, for use with Config::get()
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
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,...
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
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.
getLanguage()
Shortcut to get user's language.
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.
static getUserLinks(SpecialPage $sp, User $target, PermissionManager $permissionManager=null, HookRunner $hookRunner=null)
Links to different places.
Implements Special:DeletedContributions to display archived revisions.
__construct(PermissionManager $permissionManager, IConnectionProvider $dbProvider, RevisionFactory $revisionFactory, NamespaceInfo $namespaceInfo, UserFactory $userFactory, UserNameUtils $userNameUtils, UserNamePrefixSearch $userNamePrefixSearch, CommentFormatter $commentFormatter, LinkBatchFactory $linkBatchFactory)
execute( $par)
Special page "deleted user contributions".
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Creates User objects.
Handles searching prefixes of user names.
UserNameUtils service.
internal since 1.36
Definition User.php:98
Service for constructing RevisionRecord objects.
Shared interface for rigor levels when dealing with User methods.
Provide primary and replica IDatabase connections.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...