MediaWiki  master
SpecialDeletedContributions.php
Go to the documentation of this file.
1 <?php
26 
33  protected $mOpts;
34 
35  function __construct() {
36  parent::__construct( 'DeletedContributions', 'deletedhistory' );
37  }
38 
45  function execute( $par ) {
46  $this->setHeaders();
47  $this->outputHeader();
48  $this->checkPermissions();
49  $this->addHelpLink( 'Help:User contributions' );
50 
51  $out = $this->getOutput();
52  $out->setPageTitle( $this->msg( 'deletedcontributions-title' ) );
53 
54  $opts = new FormOptions();
55 
56  $opts->add( 'target', '' );
57  $opts->add( 'namespace', '' );
58  $opts->add( 'limit', 20 );
59 
60  $opts->fetchValuesFromRequest( $this->getRequest() );
61  $opts->validateIntBounds( 'limit', 0, $this->getConfig()->get( 'QueryPageDefaultLimit' ) );
62 
63  if ( $par !== null ) {
64  // Beautify the username
65  $par = User::getCanonicalName( $par, false );
66  $opts->setValue( 'target', (string)$par );
67  }
68 
69  $ns = $opts->getValue( 'namespace' );
70  if ( $ns !== null && $ns !== '' ) {
71  $opts->setValue( 'namespace', intval( $ns ) );
72  }
73 
74  $this->mOpts = $opts;
75 
76  $target = trim( $opts->getValue( 'target' ) );
77  if ( !strlen( $target ) ) {
78  $this->getForm();
79 
80  return;
81  }
82 
83  $userObj = User::newFromName( $target, false );
84  if ( !$userObj ) {
85  $this->getForm();
86 
87  return;
88  }
89  $this->getSkin()->setRelevantUser( $userObj );
90 
91  $target = $userObj->getName();
92  $out->addSubtitle( $this->getSubTitle( $userObj ) );
93 
94  $this->getForm();
95 
96  $pager = new DeletedContribsPager( $this->getContext(), $target, $opts->getValue( 'namespace' ),
97  $this->getLinkRenderer() );
98  if ( !$pager->getNumRows() ) {
99  $out->addWikiMsg( 'nocontribs' );
100 
101  return;
102  }
103 
104  # Show a message about replica DB lag, if applicable
105  $lag = $pager->getDatabase()->getSessionLagStatus()['lag'];
106  if ( $lag > 0 ) {
107  $out->showLagWarning( $lag );
108  }
109 
110  $out->addHTML(
111  '<p>' . $pager->getNavigationBar() . '</p>' .
112  $pager->getBody() .
113  '<p>' . $pager->getNavigationBar() . '</p>' );
114 
115  # If there were contributions, and it was a valid user or IP, show
116  # the appropriate "footer" message - WHOIS tools, etc.
117  $message = IP::isIPAddress( $target ) ?
118  'sp-contributions-footer-anon' :
119  'sp-contributions-footer';
120 
121  if ( !$this->msg( $message )->isDisabled() ) {
122  $out->wrapWikiMsg(
123  "<div class='mw-contributions-footer'>\n$1\n</div>",
124  [ $message, $target ]
125  );
126  }
127  }
128 
134  function getSubTitle( $userObj ) {
135  $linkRenderer = $this->getLinkRenderer();
136  if ( $userObj->isAnon() ) {
137  $user = htmlspecialchars( $userObj->getName() );
138  } else {
139  $user = $linkRenderer->makeLink( $userObj->getUserPage(), $userObj->getName() );
140  }
141  $links = '';
142  $nt = $userObj->getUserPage();
143  $talk = $nt->getTalkPage();
144  if ( $talk ) {
145  $tools = SpecialContributions::getUserLinks( $this, $userObj );
146 
147  $contributionsLink = $linkRenderer->makeKnownLink(
148  SpecialPage::getTitleFor( 'Contributions', $nt->getDBkey() ),
149  $this->msg( 'sp-deletedcontributions-contribs' )->text()
150  );
151  if ( isset( $tools['deletedcontribs'] ) ) {
152  // Swap out the deletedcontribs link for our contribs one
153  $tools = wfArrayInsertAfter(
154  $tools, [ 'contribs' => $contributionsLink ], 'deletedcontribs' );
155  unset( $tools['deletedcontribs'] );
156  } else {
157  $tools['contribs'] = $contributionsLink;
158  }
159 
160  $links = $this->getLanguage()->pipeList( $tools );
161 
162  // Show a note if the user is blocked and display the last block log entry.
163  $block = DatabaseBlock::newFromTarget( $userObj, $userObj );
164  if ( !is_null( $block ) && $block->getType() != DatabaseBlock::TYPE_AUTO ) {
165  if ( $block->getType() == DatabaseBlock::TYPE_RANGE ) {
166  $nt = MediaWikiServices::getInstance()->getNamespaceInfo()->
167  getCanonicalName( NS_USER ) . ':' . $block->getTarget();
168  }
169 
170  // LogEventsList::showLogExtract() wants the first parameter by ref
171  $out = $this->getOutput();
173  $out,
174  'block',
175  $nt,
176  '',
177  [
178  'lim' => 1,
179  'showIfEmpty' => false,
180  'msgKey' => [
181  'sp-contributions-blocked-notice',
182  $userObj->getName() # Support GENDER in 'sp-contributions-blocked-notice'
183  ],
184  'offset' => '' # don't use $this->getRequest() parameter offset
185  ]
186  );
187  }
188  }
189 
190  return $this->msg( 'contribsub2' )->rawParams( $user, $links )->params( $userObj->getName() );
191  }
192 
196  function getForm() {
197  $opts = $this->mOpts;
198 
199  $formDescriptor = [
200  'target' => [
201  'type' => 'user',
202  'name' => 'target',
203  'label-message' => 'sp-contributions-username',
204  'default' => $opts->getValue( 'target' ),
205  'ipallowed' => true,
206  ],
207 
208  'namespace' => [
209  'type' => 'namespaceselect',
210  'name' => 'namespace',
211  'label-message' => 'namespace',
212  'all' => '',
213  ],
214  ];
215 
216  HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
217  ->setWrapperLegendMsg( 'sp-contributions-search' )
218  ->setSubmitTextMsg( 'sp-contributions-submit' )
219  // prevent setting subpage and 'target' parameter at the same time
220  ->setAction( $this->getPageTitle()->getLocalURL() )
221  ->setMethod( 'get' )
222  ->prepareForm()
223  ->displayForm( false );
224  }
225 
234  public function prefixSearchSubpages( $search, $limit, $offset ) {
235  $user = User::newFromName( $search );
236  if ( !$user ) {
237  // No prefix suggestion for invalid user
238  return [];
239  }
240  // Autocomplete subpage as user list - public to allow caching
241  return UserNamePrefixSearch::search( 'public', $search, $limit, $offset );
242  }
243 
244  protected function getGroupName() {
245  return 'users';
246  }
247 }
Helper class to keep track of options when mixing links and form elements.
Definition: FormOptions.php:35
static isIPAddress( $ip)
Determine if a string is as valid IP address or network (CIDR prefix).
Definition: IP.php:77
getContext()
Gets the context this SpecialPage is executed in.
execute( $par)
Special page "deleted user contributions".
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
getOutput()
Get the OutputPage being used for this instance.
getDatabase()
Get the Database object in use.
static getCanonicalName( $name, $validate='valid')
Given unvalidated user input, return a canonical username, or false if the username is invalid...
Definition: User.php:1139
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getForm()
Generates the namespace selector form with hidden attributes.
getSkin()
Shortcut to get the skin being used for this instance.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes! ...
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don&#39;t need a full Title object...
Definition: SpecialPage.php:83
wfArrayInsertAfter(array $array, array $insert, $after)
Insert array into another array after the specified KEY
Implements Special:DeletedContributions to display archived revisions.
getConfig()
Shortcut to get main config object.
getLanguage()
Shortcut to get user&#39;s language.
getSubTitle( $userObj)
Generates the subheading with links.
static getUserLinks(SpecialPage $sp, User $target)
Links to different places.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
getRequest()
Get the WebRequest being used for this instance.
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:515
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
MediaWiki Linker LinkRenderer null $linkRenderer
Definition: SpecialPage.php:67