MediaWiki  1.34.0
SpecialEditWatchlist.php
Go to the documentation of this file.
1 <?php
32 
46  const EDIT_CLEAR = 1;
47  const EDIT_RAW = 2;
48  const EDIT_NORMAL = 3;
49 
50  protected $successMessage;
51 
52  protected $toc;
53 
54  private $badItems = [];
55 
59  private $titleParser;
60 
61  public function __construct() {
62  parent::__construct( 'EditWatchlist', 'editmywatchlist' );
63  }
64 
69  private function initServices() {
70  if ( !$this->titleParser ) {
71  $this->titleParser = MediaWikiServices::getInstance()->getTitleParser();
72  }
73  }
74 
75  public function doesWrites() {
76  return true;
77  }
78 
84  public function execute( $mode ) {
85  $this->initServices();
86  $this->setHeaders();
87 
88  # Anons don't get a watchlist
89  $this->requireLogin( 'watchlistanontext' );
90 
91  $out = $this->getOutput();
92 
93  $this->checkPermissions();
94  $this->checkReadOnly();
95 
96  $this->outputHeader();
97  $this->outputSubtitle();
98  $out->addModuleStyles( 'mediawiki.special' );
99 
100  # B/C: $mode used to be waaay down the parameter list, and the first parameter
101  # was $wgUser
102  if ( $mode instanceof User ) {
103  $args = func_get_args();
104  if ( count( $args ) >= 4 ) {
105  $mode = $args[3];
106  }
107  }
108  $mode = self::getMode( $this->getRequest(), $mode );
109 
110  switch ( $mode ) {
111  case self::EDIT_RAW:
112  $out->setPageTitle( $this->msg( 'watchlistedit-raw-title' ) );
113  $form = $this->getRawForm();
114  if ( $form->show() ) {
115  $out->addHTML( $this->successMessage );
116  $out->addReturnTo( SpecialPage::getTitleFor( 'Watchlist' ) );
117  }
118  break;
119  case self::EDIT_CLEAR:
120  $out->setPageTitle( $this->msg( 'watchlistedit-clear-title' ) );
121  $form = $this->getClearForm();
122  if ( $form->show() ) {
123  $out->addHTML( $this->successMessage );
124  $out->addReturnTo( SpecialPage::getTitleFor( 'Watchlist' ) );
125  }
126  break;
127 
128  case self::EDIT_NORMAL:
129  default:
130  $this->executeViewEditWatchlist();
131  break;
132  }
133  }
134 
138  protected function outputSubtitle() {
139  $out = $this->getOutput();
140  $out->addSubtitle( $this->msg( 'watchlistfor2', $this->getUser()->getName() )
141  ->rawParams(
142  self::buildTools(
143  $this->getLanguage(),
144  $this->getLinkRenderer()
145  )
146  )
147  );
148  }
149 
153  protected function executeViewEditWatchlist() {
154  $out = $this->getOutput();
155  $out->setPageTitle( $this->msg( 'watchlistedit-normal-title' ) );
156  $form = $this->getNormalForm();
157  if ( $form->show() ) {
158  $out->addHTML( $this->successMessage );
159  $out->addReturnTo( SpecialPage::getTitleFor( 'Watchlist' ) );
160  } elseif ( $this->toc !== false ) {
161  $out->prependHTML( $this->toc );
162  $out->addModuleStyles( 'mediawiki.toc.styles' );
163  }
164  }
165 
172  public function getSubpagesForPrefixSearch() {
173  // SpecialWatchlist uses SpecialEditWatchlist::getMode, so new types should be added
174  // here and there - no 'edit' here, because that the default for this page
175  return [
176  'clear',
177  'raw',
178  ];
179  }
180 
188  private function extractTitles( $list ) {
189  $list = explode( "\n", trim( $list ) );
190  if ( !is_array( $list ) ) {
191  return [];
192  }
193 
194  $titles = [];
195 
196  foreach ( $list as $text ) {
197  $text = trim( $text );
198  if ( strlen( $text ) > 0 ) {
199  $title = Title::newFromText( $text );
200  if ( $title instanceof Title && $title->isWatchable() ) {
201  $titles[] = $title;
202  }
203  }
204  }
205 
206  MediaWikiServices::getInstance()->getGenderCache()->doTitlesArray( $titles );
207 
208  $list = [];
210  foreach ( $titles as $title ) {
211  $list[] = $title->getPrefixedText();
212  }
213 
214  return array_unique( $list );
215  }
216 
217  public function submitRaw( $data ) {
218  $wanted = $this->extractTitles( $data['Titles'] );
219  $current = $this->getWatchlist();
220 
221  if ( count( $wanted ) > 0 ) {
222  $toWatch = array_diff( $wanted, $current );
223  $toUnwatch = array_diff( $current, $wanted );
224  $this->watchTitles( $toWatch );
225  $this->unwatchTitles( $toUnwatch );
226  $this->getUser()->invalidateCache();
227 
228  if ( count( $toWatch ) > 0 || count( $toUnwatch ) > 0 ) {
229  $this->successMessage = $this->msg( 'watchlistedit-raw-done' )->parse();
230  } else {
231  return false;
232  }
233 
234  if ( count( $toWatch ) > 0 ) {
235  $this->successMessage .= ' ' . $this->msg( 'watchlistedit-raw-added' )
236  ->numParams( count( $toWatch ) )->parse();
237  $this->showTitles( $toWatch, $this->successMessage );
238  }
239 
240  if ( count( $toUnwatch ) > 0 ) {
241  $this->successMessage .= ' ' . $this->msg( 'watchlistedit-raw-removed' )
242  ->numParams( count( $toUnwatch ) )->parse();
243  $this->showTitles( $toUnwatch, $this->successMessage );
244  }
245  } else {
246 
247  if ( count( $current ) === 0 ) {
248  return false;
249  }
250 
251  $this->clearUserWatchedItems( $current, 'raw' );
252  $this->showTitles( $current, $this->successMessage );
253  }
254 
255  return true;
256  }
257 
258  public function submitClear( $data ) {
259  $current = $this->getWatchlist();
260  $this->clearUserWatchedItems( $current, 'clear' );
261  $this->showTitles( $current, $this->successMessage );
262  return true;
263  }
264 
269  private function clearUserWatchedItems( $current, $messageFor ) {
270  $watchedItemStore = MediaWikiServices::getInstance()->getWatchedItemStore();
271  if ( $watchedItemStore->clearUserWatchedItems( $this->getUser() ) ) {
272  $this->successMessage = $this->msg( 'watchlistedit-' . $messageFor . '-done' )->parse();
273  $this->successMessage .= ' ' . $this->msg( 'watchlistedit-' . $messageFor . '-removed' )
274  ->numParams( count( $current ) )->parse();
275  $this->getUser()->invalidateCache();
276  } else {
277  $watchedItemStore->clearUserWatchedItemsUsingJobQueue( $this->getUser() );
278  $this->successMessage = $this->msg( 'watchlistedit-clear-jobqueue' )->parse();
279  }
280  }
281 
291  private function showTitles( $titles, &$output ) {
292  $talk = $this->msg( 'talkpagelinktext' )->text();
293  // Do a batch existence check
294  $batch = new LinkBatch();
295  if ( count( $titles ) >= 100 ) {
296  $output = $this->msg( 'watchlistedit-too-many' )->parse();
297  return;
298  }
299  foreach ( $titles as $title ) {
300  if ( !$title instanceof Title ) {
302  }
303 
304  if ( $title instanceof Title ) {
305  $batch->addObj( $title );
306  $batch->addObj( $title->getTalkPage() );
307  }
308  }
309 
310  $batch->execute();
311 
312  // Print out the list
313  $output .= "<ul>\n";
314 
315  $linkRenderer = $this->getLinkRenderer();
316  foreach ( $titles as $title ) {
317  if ( !$title instanceof Title ) {
319  }
320 
321  if ( $title instanceof Title ) {
322  $output .= '<li>' .
323  $linkRenderer->makeLink( $title ) . ' ' .
324  $this->msg( 'parentheses' )->rawParams(
325  $linkRenderer->makeLink( $title->getTalkPage(), $talk )
326  )->escaped() .
327  "</li>\n";
328  }
329  }
330 
331  $output .= "</ul>\n";
332  }
333 
340  private function getWatchlist() {
341  $list = [];
342 
343  $watchedItems = MediaWikiServices::getInstance()->getWatchedItemStore()->getWatchedItemsForUser(
344  $this->getUser(),
345  [ 'forWrite' => $this->getRequest()->wasPosted() ]
346  );
347 
348  if ( $watchedItems ) {
350  $titles = [];
351  foreach ( $watchedItems as $watchedItem ) {
352  $namespace = $watchedItem->getLinkTarget()->getNamespace();
353  $dbKey = $watchedItem->getLinkTarget()->getDBkey();
354  $title = Title::makeTitleSafe( $namespace, $dbKey );
355 
356  if ( $this->checkTitle( $title, $namespace, $dbKey )
357  && !$title->isTalkPage()
358  ) {
359  $titles[] = $title;
360  }
361  }
362 
363  MediaWikiServices::getInstance()->getGenderCache()->doTitlesArray( $titles );
364 
365  foreach ( $titles as $title ) {
366  $list[] = $title->getPrefixedText();
367  }
368  }
369 
370  $this->cleanupWatchlist();
371 
372  return $list;
373  }
374 
381  protected function getWatchlistInfo() {
382  $titles = [];
383  $services = MediaWikiServices::getInstance();
384 
385  $watchedItems = $services->getWatchedItemStore()
386  ->getWatchedItemsForUser( $this->getUser(), [ 'sort' => WatchedItemStore::SORT_ASC ] );
387 
388  $lb = new LinkBatch();
389 
390  foreach ( $watchedItems as $watchedItem ) {
391  $namespace = $watchedItem->getLinkTarget()->getNamespace();
392  $dbKey = $watchedItem->getLinkTarget()->getDBkey();
393  $lb->add( $namespace, $dbKey );
394  if ( !$services->getNamespaceInfo()->isTalk( $namespace ) ) {
395  $titles[$namespace][$dbKey] = 1;
396  }
397  }
398 
399  $lb->execute();
400 
401  return $titles;
402  }
403 
412  private function checkTitle( $title, $namespace, $dbKey ) {
413  if ( $title
414  && ( $title->isExternal()
415  || $title->getNamespace() < 0
416  )
417  ) {
418  $title = false; // unrecoverable
419  }
420 
421  if ( !$title
422  || $title->getNamespace() != $namespace
423  || $title->getDBkey() != $dbKey
424  ) {
425  $this->badItems[] = [ $title, $namespace, $dbKey ];
426  }
427 
428  return (bool)$title;
429  }
430 
434  private function cleanupWatchlist() {
435  if ( $this->badItems === [] ) {
436  return; // nothing to do
437  }
438 
439  $user = $this->getUser();
441  DeferredUpdates::addCallableUpdate( function () use ( $user, $badItems ) {
442  $store = MediaWikiServices::getInstance()->getWatchedItemStore();
443  foreach ( $badItems as $row ) {
444  list( $title, $namespace, $dbKey ) = $row;
445  $action = $title ? 'cleaning up' : 'deleting';
446  wfDebug( "User {$user->getName()} has broken watchlist item " .
447  "ns($namespace):$dbKey, $action.\n" );
448 
449  $store->removeWatch( $user, new TitleValue( (int)$namespace, $dbKey ) );
450  // Can't just do an UPDATE instead of DELETE/INSERT due to unique index
451  if ( $title ) {
452  $user->addWatch( $title );
453  }
454  }
455  } );
456  }
457 
466  private function watchTitles( array $targets ) {
467  return MediaWikiServices::getInstance()->getWatchedItemStore()
468  ->addWatchBatchForUser( $this->getUser(), $this->getExpandedTargets( $targets ) )
469  && $this->runWatchUnwatchCompleteHook( 'Watch', $targets );
470  }
471 
484  private function unwatchTitles( array $targets ) {
485  return MediaWikiServices::getInstance()->getWatchedItemStore()
486  ->removeWatchBatchForUser( $this->getUser(), $this->getExpandedTargets( $targets ) )
487  && $this->runWatchUnwatchCompleteHook( 'Unwatch', $targets );
488  }
489 
498  private function runWatchUnwatchCompleteHook( $action, $targets ) {
499  foreach ( $targets as $target ) {
500  $title = $target instanceof TitleValue ?
501  Title::newFromTitleValue( $target ) :
502  Title::newFromText( $target );
503  $page = WikiPage::factory( $title );
504  Hooks::run( $action . 'ArticleComplete', [ $this->getUser(), &$page ] );
505  }
506  return true;
507  }
508 
513  private function getExpandedTargets( array $targets ) {
514  $expandedTargets = [];
515  $services = MediaWikiServices::getInstance();
516  foreach ( $targets as $target ) {
517  if ( !$target instanceof LinkTarget ) {
518  try {
519  $target = $this->titleParser->parseTitle( $target, NS_MAIN );
520  }
521  catch ( MalformedTitleException $e ) {
522  continue;
523  }
524  }
525 
526  $ns = $target->getNamespace();
527  $dbKey = $target->getDBkey();
528  $expandedTargets[] =
529  new TitleValue( $services->getNamespaceInfo()->getSubject( $ns ), $dbKey );
530  $expandedTargets[] =
531  new TitleValue( $services->getNamespaceInfo()->getTalk( $ns ), $dbKey );
532  }
533  return $expandedTargets;
534  }
535 
536  public function submitNormal( $data ) {
537  $removed = [];
538 
539  foreach ( $data as $titles ) {
540  $this->unwatchTitles( $titles );
541  $removed = array_merge( $removed, $titles );
542  }
543 
544  if ( count( $removed ) > 0 ) {
545  $this->successMessage = $this->msg( 'watchlistedit-normal-done'
546  )->numParams( count( $removed ) )->parse();
547  $this->showTitles( $removed, $this->successMessage );
548 
549  return true;
550  } else {
551  return false;
552  }
553  }
554 
560  protected function getNormalForm() {
561  $fields = [];
562  $count = 0;
563 
564  // Allow subscribers to manipulate the list of watched pages (or use it
565  // to preload lots of details at once)
566  $watchlistInfo = $this->getWatchlistInfo();
567  Hooks::run(
568  'WatchlistEditorBeforeFormRender',
569  [ &$watchlistInfo ]
570  );
571 
572  foreach ( $watchlistInfo as $namespace => $pages ) {
573  $options = [];
574 
575  foreach ( array_keys( $pages ) as $dbkey ) {
576  $title = Title::makeTitleSafe( $namespace, $dbkey );
577 
578  if ( $this->checkTitle( $title, $namespace, $dbkey ) ) {
579  $text = $this->buildRemoveLine( $title );
580  $options[$text] = $title->getPrefixedText();
581  $count++;
582  }
583  }
584 
585  // checkTitle can filter some options out, avoid empty sections
586  if ( count( $options ) > 0 ) {
587  $fields['TitlesNs' . $namespace] = [
588  'class' => EditWatchlistCheckboxSeriesField::class,
589  'options' => $options,
590  'section' => "ns$namespace",
591  ];
592  }
593  }
594  $this->cleanupWatchlist();
595 
596  if ( count( $fields ) > 1 && $count > 30 ) {
597  $this->toc = Linker::tocIndent();
598  $tocLength = 0;
599  $contLang = MediaWikiServices::getInstance()->getContentLanguage();
600 
601  foreach ( $fields as $data ) {
602  # strip out the 'ns' prefix from the section name:
603  $ns = substr( $data['section'], 2 );
604 
605  $nsText = ( $ns == NS_MAIN )
606  ? $this->msg( 'blanknamespace' )->escaped()
607  : htmlspecialchars( $contLang->getFormattedNsText( $ns ) );
608  $this->toc .= Linker::tocLine( "editwatchlist-{$data['section']}", $nsText,
609  $this->getLanguage()->formatNum( ++$tocLength ), 1 ) . Linker::tocLineEnd();
610  }
611 
612  $this->toc = Linker::tocList( $this->toc );
613  } else {
614  $this->toc = false;
615  }
616 
617  $context = new DerivativeContext( $this->getContext() );
618  $context->setTitle( $this->getPageTitle() ); // Remove subpage
619  $form = new EditWatchlistNormalHTMLForm( $fields, $context );
620  $form->setSubmitTextMsg( 'watchlistedit-normal-submit' );
621  $form->setSubmitDestructive();
622  # Used message keys:
623  # 'accesskey-watchlistedit-normal-submit', 'tooltip-watchlistedit-normal-submit'
624  $form->setSubmitTooltip( 'watchlistedit-normal-submit' );
625  $form->setWrapperLegendMsg( 'watchlistedit-normal-legend' );
626  $form->addHeaderText( $this->msg( 'watchlistedit-normal-explain' )->parse() );
627  $form->setSubmitCallback( [ $this, 'submitNormal' ] );
628 
629  return $form;
630  }
631 
638  private function buildRemoveLine( $title ) {
639  $linkRenderer = $this->getLinkRenderer();
640  $link = $linkRenderer->makeLink( $title );
641 
642  $tools = [];
643  $tools['talk'] = $linkRenderer->makeLink(
644  $title->getTalkPage(),
645  $this->msg( 'talkpagelinktext' )->text()
646  );
647 
648  if ( $title->exists() ) {
649  $tools['history'] = $linkRenderer->makeKnownLink(
650  $title,
651  $this->msg( 'history_small' )->text(),
652  [],
653  [ 'action' => 'history' ]
654  );
655  }
656 
657  if ( $title->getNamespace() == NS_USER && !$title->isSubpage() ) {
658  $tools['contributions'] = $linkRenderer->makeKnownLink(
659  SpecialPage::getTitleFor( 'Contributions', $title->getText() ),
660  $this->msg( 'contribslink' )->text()
661  );
662  }
663 
664  Hooks::run(
665  'WatchlistEditorBuildRemoveLine',
666  [ &$tools, $title, $title->isRedirect(), $this->getSkin(), &$link ]
667  );
668 
669  if ( $title->isRedirect() ) {
670  // Linker already makes class mw-redirect, so this is redundant
671  $link = '<span class="watchlistredir">' . $link . '</span>';
672  }
673 
674  return $link . ' ' .
675  $this->msg( 'parentheses' )->rawParams( $this->getLanguage()->pipeList( $tools ) )->escaped();
676  }
677 
683  protected function getRawForm() {
684  $titles = implode( "\n", $this->getWatchlist() );
685  $fields = [
686  'Titles' => [
687  'type' => 'textarea',
688  'label-message' => 'watchlistedit-raw-titles',
689  'default' => $titles,
690  ],
691  ];
692  $context = new DerivativeContext( $this->getContext() );
693  $context->setTitle( $this->getPageTitle( 'raw' ) ); // Reset subpage
694  $form = new OOUIHTMLForm( $fields, $context );
695  $form->setSubmitTextMsg( 'watchlistedit-raw-submit' );
696  # Used message keys: 'accesskey-watchlistedit-raw-submit', 'tooltip-watchlistedit-raw-submit'
697  $form->setSubmitTooltip( 'watchlistedit-raw-submit' );
698  $form->setWrapperLegendMsg( 'watchlistedit-raw-legend' );
699  $form->addHeaderText( $this->msg( 'watchlistedit-raw-explain' )->parse() );
700  $form->setSubmitCallback( [ $this, 'submitRaw' ] );
701 
702  return $form;
703  }
704 
710  protected function getClearForm() {
711  $context = new DerivativeContext( $this->getContext() );
712  $context->setTitle( $this->getPageTitle( 'clear' ) ); // Reset subpage
713  $form = new OOUIHTMLForm( [], $context );
714  $form->setSubmitTextMsg( 'watchlistedit-clear-submit' );
715  # Used message keys: 'accesskey-watchlistedit-clear-submit', 'tooltip-watchlistedit-clear-submit'
716  $form->setSubmitTooltip( 'watchlistedit-clear-submit' );
717  $form->setWrapperLegendMsg( 'watchlistedit-clear-legend' );
718  $form->addHeaderText( $this->msg( 'watchlistedit-clear-explain' )->parse() );
719  $form->setSubmitCallback( [ $this, 'submitClear' ] );
720  $form->setSubmitDestructive();
721 
722  return $form;
723  }
724 
733  public static function getMode( $request, $par ) {
734  $mode = strtolower( $request->getVal( 'action', $par ) );
735 
736  switch ( $mode ) {
737  case 'clear':
738  case self::EDIT_CLEAR:
739  return self::EDIT_CLEAR;
740  case 'raw':
741  case self::EDIT_RAW:
742  return self::EDIT_RAW;
743  case 'edit':
744  case self::EDIT_NORMAL:
745  return self::EDIT_NORMAL;
746  default:
747  return false;
748  }
749  }
750 
759  public static function buildTools( $lang, LinkRenderer $linkRenderer = null ) {
760  if ( !$lang instanceof Language ) {
761  // back-compat where the first parameter was $unused
762  global $wgLang;
763  $lang = $wgLang;
764  }
765  if ( !$linkRenderer ) {
766  $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
767  }
768 
769  $tools = [];
770  $modes = [
771  'view' => [ 'Watchlist', false ],
772  'edit' => [ 'EditWatchlist', false ],
773  'raw' => [ 'EditWatchlist', 'raw' ],
774  'clear' => [ 'EditWatchlist', 'clear' ],
775  ];
776 
777  foreach ( $modes as $mode => $arr ) {
778  // can use messages 'watchlisttools-view', 'watchlisttools-edit', 'watchlisttools-raw'
779  $tools[] = $linkRenderer->makeKnownLink(
780  SpecialPage::getTitleFor( $arr[0], $arr[1] ),
781  wfMessage( "watchlisttools-{$mode}" )->text()
782  );
783  }
784 
785  return Html::rawElement(
786  'span',
787  [ 'class' => 'mw-watchlist-toollinks' ],
788  wfMessage( 'parentheses' )->rawParams( $lang->pipeList( $tools ) )->escaped()
789  );
790  }
791 }
SpecialPage\getPageTitle
getPageTitle( $subpage=false)
Get a self-referential title object.
Definition: SpecialPage.php:672
SpecialEditWatchlist\submitNormal
submitNormal( $data)
Definition: SpecialEditWatchlist.php:536
SpecialEditWatchlist\EDIT_CLEAR
const EDIT_CLEAR
Editing modes.
Definition: SpecialEditWatchlist.php:46
SpecialEditWatchlist\unwatchTitles
unwatchTitles(array $targets)
Remove a list of titles from a user's watchlist.
Definition: SpecialEditWatchlist.php:484
SpecialEditWatchlist\getWatchlist
getWatchlist()
Prepare a list of titles on a user's watchlist (excluding talk pages) and return an array of (prefixe...
Definition: SpecialEditWatchlist.php:340
SpecialPage\msg
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:792
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:316
SpecialEditWatchlist\EDIT_RAW
const EDIT_RAW
Definition: SpecialEditWatchlist.php:47
SpecialEditWatchlist\checkTitle
checkTitle( $title, $namespace, $dbKey)
Validates watchlist entry.
Definition: SpecialEditWatchlist.php:412
SpecialEditWatchlist\initServices
initServices()
Initialize any services we'll need (unless it has already been provided via a setter).
Definition: SpecialEditWatchlist.php:69
LinkBatch
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:34
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:719
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:117
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
UnlistedSpecialPage
Shortcut to construct a special page which is unlisted by default.
Definition: UnlistedSpecialPage.php:29
Linker\tocIndent
static tocIndent()
Add another level to the Table of Contents.
Definition: Linker.php:1617
MediaWiki\Linker\LinkRenderer
Class that generates HTML links for pages.
Definition: LinkRenderer.php:41
SpecialEditWatchlist\__construct
__construct()
Definition: SpecialEditWatchlist.php:61
SpecialEditWatchlist\submitRaw
submitRaw( $data)
Definition: SpecialEditWatchlist.php:217
SpecialPage\checkPermissions
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
Definition: SpecialPage.php:315
SpecialEditWatchlist\buildRemoveLine
buildRemoveLine( $title)
Build the label for a checkbox, with a link to the title, and various additional bits.
Definition: SpecialEditWatchlist.php:638
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1264
SpecialPage\getTitleFor
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,...
Definition: SpecialPage.php:83
SpecialEditWatchlist\watchTitles
watchTitles(array $targets)
Add a list of targets to a user's watchlist.
Definition: SpecialEditWatchlist.php:466
SpecialPage\getSkin
getSkin()
Shortcut to get the skin being used for this instance.
Definition: SpecialPage.php:739
SpecialEditWatchlist\getExpandedTargets
getExpandedTargets(array $targets)
Definition: SpecialEditWatchlist.php:513
SpecialPage\getLanguage
getLanguage()
Shortcut to get user's language.
Definition: SpecialPage.php:749
SpecialPage\getName
getName()
Get the name of this Special Page.
Definition: SpecialPage.php:153
SpecialEditWatchlist\clearUserWatchedItems
clearUserWatchedItems( $current, $messageFor)
Definition: SpecialEditWatchlist.php:269
Linker\tocLine
static tocLine( $anchor, $tocline, $tocnumber, $level, $sectionIndex=false)
parameter level defines if we are on an indentation level
Definition: Linker.php:1643
SpecialEditWatchlist\$badItems
$badItems
Definition: SpecialEditWatchlist.php:54
Linker\tocList
static tocList( $toc, Language $lang=null)
Wraps the TOC in a table and provides the hide/collapse javascript.
Definition: Linker.php:1679
SpecialEditWatchlist\$titleParser
TitleParser $titleParser
Definition: SpecialEditWatchlist.php:59
SpecialEditWatchlist\runWatchUnwatchCompleteHook
runWatchUnwatchCompleteHook( $action, $targets)
Definition: SpecialEditWatchlist.php:498
OOUIHTMLForm
Compact stacked vertical format for forms, implemented using OOUI widgets.
Definition: OOUIHTMLForm.php:27
SpecialEditWatchlist\execute
execute( $mode)
Main execution point.
Definition: SpecialEditWatchlist.php:84
NS_MAIN
const NS_MAIN
Definition: Defines.php:60
EditWatchlistNormalHTMLForm
Extend OOUIHTMLForm purely so we can have a more sane way of getting the section headers.
Definition: EditWatchlistNormalHTMLForm.php:24
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:30
SpecialEditWatchlist\EDIT_NORMAL
const EDIT_NORMAL
Definition: SpecialEditWatchlist.php:48
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:142
SpecialEditWatchlist\getRawForm
getRawForm()
Get a form for editing the watchlist in "raw" mode.
Definition: SpecialEditWatchlist.php:683
SpecialEditWatchlist\executeViewEditWatchlist
executeViewEditWatchlist()
Executes an edit mode for the watchlist view, from which you can manage your watchlist.
Definition: SpecialEditWatchlist.php:153
SpecialEditWatchlist\extractTitles
extractTitles( $list)
Extract a list of titles from a blob of text, returning (prefixed) strings; unwatchable titles are ig...
Definition: SpecialEditWatchlist.php:188
$wgLang
$wgLang
Definition: Setup.php:881
Linker\tocLineEnd
static tocLineEnd()
End a Table Of Contents line.
Definition: Linker.php:1667
SpecialEditWatchlist
Provides the UI through which users can perform editing operations on their watchlist.
Definition: SpecialEditWatchlist.php:41
$title
$title
Definition: testCompression.php:34
SpecialPage\setHeaders
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
Definition: SpecialPage.php:537
SpecialPage\getUser
getUser()
Shortcut to get the User executing this instance.
Definition: SpecialPage.php:729
SpecialEditWatchlist\showTitles
showTitles( $titles, &$output)
Print out a list of linked titles.
Definition: SpecialEditWatchlist.php:291
TitleParser
A title parser service for MediaWiki.
Definition: TitleParser.php:33
$output
$output
Definition: SyntaxHighlight.php:335
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:913
SpecialPage\getContext
getContext()
Gets the context this SpecialPage is executed in.
Definition: SpecialPage.php:692
SpecialPage\requireLogin
requireLogin( $reasonMsg='exception-nologin-text', $titleMsg='exception-nologin')
If the user is not logged in, throws UserNotLoggedIn error.
Definition: SpecialPage.php:345
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:613
SpecialEditWatchlist\getMode
static getMode( $request, $par)
Determine whether we are editing the watchlist, and if so, what kind of editing operation.
Definition: SpecialEditWatchlist.php:733
SpecialEditWatchlist\getSubpagesForPrefixSearch
getSubpagesForPrefixSearch()
Return an array of subpages that this special page will accept.
Definition: SpecialEditWatchlist.php:172
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:709
SpecialEditWatchlist\cleanupWatchlist
cleanupWatchlist()
Attempts to clean up broken items.
Definition: SpecialEditWatchlist.php:434
SpecialEditWatchlist\doesWrites
doesWrites()
Indicates whether this special page may perform database writes.
Definition: SpecialEditWatchlist.php:75
WatchedItemStoreInterface\SORT_ASC
const SORT_ASC
Definition: WatchedItemStoreInterface.php:35
$context
$context
Definition: load.php:45
SpecialEditWatchlist\outputSubtitle
outputSubtitle()
Renders a subheader on the watchlist page.
Definition: SpecialEditWatchlist.php:138
SpecialEditWatchlist\$toc
$toc
Definition: SpecialEditWatchlist.php:52
SpecialPage\getLinkRenderer
getLinkRenderer()
Definition: SpecialPage.php:904
SpecialEditWatchlist\buildTools
static buildTools( $lang, LinkRenderer $linkRenderer=null)
Build a set of links for convenient navigation between watchlist viewing and editing modes.
Definition: SpecialEditWatchlist.php:759
$args
if( $line===false) $args
Definition: cdb.php:64
Title
Represents a title within MediaWiki.
Definition: Title.php:42
SpecialEditWatchlist\getClearForm
getClearForm()
Get a form for clearing the watchlist.
Definition: SpecialEditWatchlist.php:710
MalformedTitleException
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
Definition: MalformedTitleException.php:25
NS_USER
const NS_USER
Definition: Defines.php:62
SpecialEditWatchlist\getNormalForm
getNormalForm()
Get the standard watchlist editing form.
Definition: SpecialEditWatchlist.php:560
SpecialPage\checkReadOnly
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
Definition: SpecialPage.php:328
SpecialPage\$linkRenderer
MediaWiki Linker LinkRenderer null $linkRenderer
Definition: SpecialPage.php:67
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
SpecialEditWatchlist\getWatchlistInfo
getWatchlistInfo()
Get a list of titles on a user's watchlist, excluding talk pages, and return as a two-dimensional arr...
Definition: SpecialEditWatchlist.php:381
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:51
DeferredUpdates\addCallableUpdate
static addCallableUpdate( $callable, $stage=self::POSTSEND, $dbw=null)
Add a callable update.
Definition: DeferredUpdates.php:124
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
SpecialEditWatchlist\submitClear
submitClear( $data)
Definition: SpecialEditWatchlist.php:258
SpecialPage\outputHeader
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
Definition: SpecialPage.php:639
Language
Internationalisation code.
Definition: Language.php:37
SpecialEditWatchlist\$successMessage
$successMessage
Definition: SpecialEditWatchlist.php:50
TitleValue
Represents a page (or page fragment) title within MediaWiki.
Definition: TitleValue.php:36
Title\newFromTitleValue
static newFromTitleValue(TitleValue $titleValue, $forceClone='')
Returns a Title given a TitleValue.
Definition: Title.php:253