MediaWiki REL1_39
SpecialDeletedContributions.php
Go to the documentation of this file.
1<?php
32use Wikimedia\IPUtils;
34
41 protected $mOpts;
42
44 private $permissionManager;
45
47 private $loadBalancer;
48
50 private $commentStore;
51
53 private $revisionFactory;
54
56 private $namespaceInfo;
57
59 private $userFactory;
60
62 private $userNameUtils;
63
65 private $userNamePrefixSearch;
66
77 public function __construct(
78 PermissionManager $permissionManager,
79 ILoadBalancer $loadBalancer,
80 CommentStore $commentStore,
81 RevisionFactory $revisionFactory,
82 NamespaceInfo $namespaceInfo,
83 UserFactory $userFactory,
84 UserNameUtils $userNameUtils,
85 UserNamePrefixSearch $userNamePrefixSearch
86 ) {
87 parent::__construct( 'DeletedContributions', 'deletedhistory' );
88 $this->permissionManager = $permissionManager;
89 $this->loadBalancer = $loadBalancer;
90 $this->commentStore = $commentStore;
91 $this->revisionFactory = $revisionFactory;
92 $this->namespaceInfo = $namespaceInfo;
93 $this->userFactory = $userFactory;
94 $this->userNameUtils = $userNameUtils;
95 $this->userNamePrefixSearch = $userNamePrefixSearch;
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,
123 $this->getConfig()->get( MainConfigNames::QueryPageDefaultLimit ) );
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 $this->getSkin()->setRelevantUser( $userObj );
152
153 $target = $userObj->getName();
154
155 $out->addSubtitle( $this->getSubTitle( $userObj ) );
156 $out->setPageTitle( $this->msg( 'deletedcontributions-title', $target ) );
157
158 $this->getForm();
159
160 $pager = new DeletedContribsPager(
161 $this->getContext(),
162 $this->commentStore,
163 $this->getHookContainer(),
164 $this->getLinkRenderer(),
165 $this->loadBalancer,
166 $this->revisionFactory,
167 $target,
168 $opts->getValue( 'namespace' )
169 );
170 if ( !$pager->getNumRows() ) {
171 $out->addWikiMsg( 'nocontribs' );
172
173 return;
174 }
175
176 # Show a message about replica DB lag, if applicable
177 $lag = $pager->getDatabase()->getSessionLagStatus()['lag'];
178 if ( $lag > 0 ) {
179 $out->showLagWarning( $lag );
180 }
181
182 $out->addHTML(
183 '<p>' . $pager->getNavigationBar() . '</p>' .
184 $pager->getBody() .
185 '<p>' . $pager->getNavigationBar() . '</p>' );
186
187 # If there were contributions, and it was a valid user or IP, show
188 # the appropriate "footer" message - WHOIS tools, etc.
189 $message = IPUtils::isIPAddress( $target ) ?
190 'sp-contributions-footer-anon' :
191 'sp-contributions-footer';
192
193 if ( !$this->msg( $message )->isDisabled() ) {
194 $out->wrapWikiMsg(
195 "<div class='mw-contributions-footer'>\n$1\n</div>",
196 [ $message, $target ]
197 );
198 }
199 }
200
206 private function getSubTitle( $userObj ) {
207 $linkRenderer = $this->getLinkRenderer();
208 if ( $userObj->isAnon() ) {
209 $user = htmlspecialchars( $userObj->getName() );
210 } else {
211 $user = $linkRenderer->makeLink( $userObj->getUserPage(), $userObj->getName() );
212 }
213 $links = '';
214 $nt = $userObj->getUserPage();
215 $talk = $nt->getTalkPage();
216 if ( $talk ) {
218 $this,
219 $userObj,
220 $this->permissionManager,
221 $this->getHookRunner()
222 );
223
224 $contributionsLink = $linkRenderer->makeKnownLink(
225 SpecialPage::getTitleFor( 'Contributions', $nt->getDBkey() ),
226 $this->msg( 'sp-deletedcontributions-contribs' )->text()
227 );
228 if ( isset( $tools['deletedcontribs'] ) ) {
229 // Swap out the deletedcontribs link for our contribs one
230 $tools = wfArrayInsertAfter(
231 $tools, [ 'contribs' => $contributionsLink ], 'deletedcontribs' );
232 unset( $tools['deletedcontribs'] );
233 } else {
234 $tools['contribs'] = $contributionsLink;
235 }
236
237 $links = $this->getLanguage()->pipeList( $tools );
238
239 // Show a note if the user is blocked and display the last block log entry.
240 $block = DatabaseBlock::newFromTarget( $userObj, $userObj );
241 if ( $block !== null && $block->getType() != DatabaseBlock::TYPE_AUTO ) {
242 if ( $block->getType() == DatabaseBlock::TYPE_RANGE ) {
243 $nt = $this->namespaceInfo->getCanonicalName( NS_USER )
244 . ':' . $block->getTargetName();
245 }
246
247 // LogEventsList::showLogExtract() wants the first parameter by ref
248 $out = $this->getOutput();
250 $out,
251 'block',
252 $nt,
253 '',
254 [
255 'lim' => 1,
256 'showIfEmpty' => false,
257 'msgKey' => [
258 'sp-contributions-blocked-notice',
259 $userObj->getName() # Support GENDER in 'sp-contributions-blocked-notice'
260 ],
261 'offset' => '' # don't use $this->getRequest() parameter offset
262 ]
263 );
264 }
265 }
266
267 return $this->msg( 'contribsub2' )->rawParams( $user, $links )->params( $userObj->getName() );
268 }
269
273 private function getForm() {
274 $opts = $this->mOpts;
275
276 $formDescriptor = [
277 'target' => [
278 'type' => 'user',
279 'name' => 'target',
280 'label-message' => 'sp-contributions-username',
281 'default' => $opts->getValue( 'target' ),
282 'ipallowed' => true,
283 ],
284
285 'namespace' => [
286 'type' => 'namespaceselect',
287 'name' => 'namespace',
288 'label-message' => 'namespace',
289 'all' => '',
290 ],
291 ];
292
293 HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
294 ->setWrapperLegendMsg( 'sp-contributions-search' )
295 ->setSubmitTextMsg( 'sp-contributions-submit' )
296 // prevent setting subpage and 'target' parameter at the same time
297 ->setTitle( $this->getPageTitle() )
298 ->setMethod( 'get' )
299 ->prepareForm()
300 ->displayForm( false );
301 }
302
311 public function prefixSearchSubpages( $search, $limit, $offset ) {
312 $search = $this->userNameUtils->getCanonical( $search );
313 if ( !$search ) {
314 // No prefix suggestion for invalid user
315 return [];
316 }
317 // Autocomplete subpage as user list - public to allow caching
318 return $this->userNamePrefixSearch
319 ->search( UserNamePrefixSearch::AUDIENCE_PUBLIC, $search, $limit, $offset );
320 }
321
322 protected function getGroupName() {
323 return 'users';
324 }
325}
const NS_USER
Definition Defines.php:66
wfArrayInsertAfter(array $array, array $insert, $after)
Insert an array into another array after the specified key.
Handle database storage of comments such as edit summaries and log reasons.
Helper class to keep track of options when mixing links and form elements.
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...
A class containing constants representing the names of configuration variables.
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
Creates User objects.
Handles searching prefixes of user names.
UserNameUtils service.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
static getUserLinks(SpecialPage $sp, User $target, PermissionManager $permissionManager=null, HookRunner $hookRunner=null)
Links to different places.
Implements Special:DeletedContributions to display archived revisions.
execute( $par)
Special page "deleted user contributions".
__construct(PermissionManager $permissionManager, ILoadBalancer $loadBalancer, CommentStore $commentStore, RevisionFactory $revisionFactory, NamespaceInfo $namespaceInfo, UserFactory $userFactory, UserNameUtils $userNameUtils, UserNamePrefixSearch $userNamePrefixSearch)
Parent class for all special pages.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
getSkin()
Shortcut to get the skin being used for this instance.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
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,...
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
getLanguage()
Shortcut to get user's language.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Service for constructing RevisionRecord objects.
Shared interface for rigor levels when dealing with User methods.
Create and track the database connections and transactions for a given database cluster.