MediaWiki  master
HistoryPager.php
Go to the documentation of this file.
1 <?php
25 
34  public $lastRow = false;
35 
37 
38  protected $oldIdChecked;
39 
40  protected $preventClickjacking = false;
44  protected $parentLens;
45 
47  protected $showTagEditUI;
48 
50  private $tagFilter;
51 
60  public function __construct(
61  HistoryAction $historyPage,
62  $year = '',
63  $month = '',
64  $tagFilter = '',
65  array $conds = [],
66  $day = ''
67  ) {
68  parent::__construct( $historyPage->getContext() );
69  $this->historyPage = $historyPage;
70  $this->tagFilter = $tagFilter;
71  $this->getDateCond( $year, $month, $day );
72  $this->conds = $conds;
73  $this->showTagEditUI = ChangeTags::showTagEditingUI( $this->getUser() );
74  }
75 
76  // For hook compatibility...
77  function getArticle() {
78  return $this->historyPage->getArticle();
79  }
80 
81  function getSqlComment() {
82  if ( $this->conds ) {
83  return 'history page filtered'; // potentially slow, see CR r58153
84  } else {
85  return 'history page unfiltered';
86  }
87  }
88 
89  function getQueryInfo() {
90  $revQuery = Revision::getQueryInfo( [ 'user' ] );
91  $queryInfo = [
92  'tables' => $revQuery['tables'],
93  'fields' => $revQuery['fields'],
94  'conds' => array_merge(
95  [ 'rev_page' => $this->getWikiPage()->getId() ],
96  $this->conds ),
97  'options' => [ 'USE INDEX' => [ 'revision' => 'page_timestamp' ] ],
98  'join_conds' => $revQuery['joins'],
99  ];
101  $queryInfo['tables'],
102  $queryInfo['fields'],
103  $queryInfo['conds'],
104  $queryInfo['join_conds'],
105  $queryInfo['options'],
106  $this->tagFilter
107  );
108 
109  // Avoid PHP 7.1 warning of passing $this by reference
110  $historyPager = $this;
111  Hooks::run( 'PageHistoryPager::getQueryInfo', [ &$historyPager, &$queryInfo ] );
112 
113  return $queryInfo;
114  }
115 
116  function getIndexField() {
117  return 'rev_timestamp';
118  }
119 
124  function formatRow( $row ) {
125  if ( $this->lastRow ) {
126  $latest = ( $this->counter == 1 && $this->mIsFirst );
127  $firstInList = $this->counter == 1;
128  $this->counter++;
129 
130  $notifTimestamp = $this->getConfig()->get( 'ShowUpdatedMarker' )
131  ? $this->getTitle()->getNotificationTimestamp( $this->getUser() )
132  : false;
133 
134  $s = $this->historyLine(
135  $this->lastRow, $row, $notifTimestamp, $latest, $firstInList );
136  } else {
137  $s = '';
138  }
139  $this->lastRow = $row;
140 
141  return $s;
142  }
143 
144  protected function doBatchLookups() {
145  if ( !Hooks::run( 'PageHistoryPager::doBatchLookups', [ $this, $this->mResult ] ) ) {
146  return;
147  }
148 
149  # Do a link batch query
150  $this->mResult->seek( 0 );
151  $batch = new LinkBatch();
152  $revIds = [];
153  foreach ( $this->mResult as $row ) {
154  if ( $row->rev_parent_id ) {
155  $revIds[] = $row->rev_parent_id;
156  }
157  if ( $row->user_name !== null ) {
158  $batch->add( NS_USER, $row->user_name );
159  $batch->add( NS_USER_TALK, $row->user_name );
160  } else { # for anons or usernames of imported revisions
161  $batch->add( NS_USER, $row->rev_user_text );
162  $batch->add( NS_USER_TALK, $row->rev_user_text );
163  }
164  }
165  $this->parentLens = Revision::getParentLengths( $this->mDb, $revIds );
166  $batch->execute();
167  $this->mResult->seek( 0 );
168  }
169 
175  protected function getStartBody() {
176  $this->lastRow = false;
177  $this->counter = 1;
178  $this->oldIdChecked = 0;
179 
180  $this->getOutput()->wrapWikiMsg( "<div class='mw-history-legend'>\n$1\n</div>", 'histlegend' );
181  $s = Html::openElement( 'form', [ 'action' => wfScript(),
182  'id' => 'mw-history-compare' ] ) . "\n";
183  $s .= Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . "\n";
184  $s .= Html::hidden( 'action', 'historysubmit' ) . "\n";
185  $s .= Html::hidden( 'type', 'revision' ) . "\n";
186 
187  // Button container stored in $this->buttons for re-use in getEndBody()
188  $this->buttons = Html::openElement( 'div', [ 'class' => 'mw-history-compareselectedversions' ] );
189  $className = 'historysubmit mw-history-compareselectedversions-button';
190  $attrs = [ 'class' => $className ]
191  + Linker::tooltipAndAccesskeyAttribs( 'compareselectedversions' );
192  $this->buttons .= $this->submitButton( $this->msg( 'compareselectedversions' )->text(),
193  $attrs
194  ) . "\n";
195 
196  $user = $this->getUser();
197  $actionButtons = '';
198  if ( $user->isAllowed( 'deleterevision' ) ) {
199  $actionButtons .= $this->getRevisionButton( 'revisiondelete', 'showhideselectedversions' );
200  }
201  if ( $this->showTagEditUI ) {
202  $actionButtons .= $this->getRevisionButton( 'editchangetags', 'history-edit-tags' );
203  }
204  if ( $actionButtons ) {
205  $this->buttons .= Xml::tags( 'div', [ 'class' =>
206  'mw-history-revisionactions' ], $actionButtons );
207  }
208 
209  if ( $user->isAllowed( 'deleterevision' ) || $this->showTagEditUI ) {
210  $this->buttons .= ( new ListToggle( $this->getOutput() ) )->getHTML();
211  }
212 
213  $this->buttons .= '</div>';
214 
215  $s .= $this->buttons;
216  $s .= '<ul id="pagehistory">' . "\n";
217 
218  return $s;
219  }
220 
221  private function getRevisionButton( $name, $msg ) {
222  $this->preventClickjacking();
223  # Note T22966, <button> is non-standard in IE<8
224  $element = Html::element(
225  'button',
226  [
227  'type' => 'submit',
228  'name' => $name,
229  'value' => '1',
230  'class' => "historysubmit mw-history-$name-button",
231  ],
232  $this->msg( $msg )->text()
233  ) . "\n";
234  return $element;
235  }
236 
237  protected function getEndBody() {
238  if ( $this->lastRow ) {
239  $latest = $this->counter == 1 && $this->mIsFirst;
240  $firstInList = $this->counter == 1;
241  if ( $this->mIsBackwards ) {
242  # Next row is unknown, but for UI reasons, probably exists if an offset has been specified
243  if ( $this->mOffset == '' ) {
244  $next = null;
245  } else {
246  $next = 'unknown';
247  }
248  } else {
249  # The next row is the past-the-end row
250  $next = $this->mPastTheEndRow;
251  }
252  $this->counter++;
253 
254  $notifTimestamp = $this->getConfig()->get( 'ShowUpdatedMarker' )
255  ? $this->getTitle()->getNotificationTimestamp( $this->getUser() )
256  : false;
257 
258  $s = $this->historyLine(
259  $this->lastRow, $next, $notifTimestamp, $latest, $firstInList );
260  } else {
261  $s = '';
262  }
263  $s .= "</ul>\n";
264  # Add second buttons only if there is more than one rev
265  if ( $this->getNumRows() > 2 ) {
266  $s .= $this->buttons;
267  }
268  $s .= '</form>';
269 
270  return $s;
271  }
272 
280  function submitButton( $message, $attributes = [] ) {
281  # Disable submit button if history has 1 revision only
282  if ( $this->getNumRows() > 1 ) {
283  return Html::submitButton( $message, $attributes );
284  } else {
285  return '';
286  }
287  }
288 
303  function historyLine( $row, $next, $notificationtimestamp = false,
304  $latest = false, $firstInList = false ) {
305  $rev = new Revision( $row, 0, $this->getTitle() );
306 
307  if ( is_object( $next ) ) {
308  $prevRev = new Revision( $next, 0, $this->getTitle() );
309  } else {
310  $prevRev = null;
311  }
312 
313  $curlink = $this->curLink( $rev, $latest );
314  $lastlink = $this->lastLink( $rev, $next );
315  $curLastlinks = Html::rawElement( 'span', [], $curlink ) .
316  Html::rawElement( 'span', [], $lastlink );
317  $histLinks = Html::rawElement(
318  'span',
319  [ 'class' => 'mw-history-histlinks mw-changeslist-links' ],
320  $curLastlinks
321  );
322 
323  $diffButtons = $this->diffButtons( $rev, $firstInList );
324  $s = $histLinks . $diffButtons;
325 
326  $link = $this->revLink( $rev );
327  $classes = [];
328 
329  $del = '';
330  $user = $this->getUser();
331  $canRevDelete = $user->isAllowed( 'deleterevision' );
332  // Show checkboxes for each revision, to allow for revision deletion and
333  // change tags
334  if ( $canRevDelete || $this->showTagEditUI ) {
335  $this->preventClickjacking();
336  // If revision was hidden from sysops and we don't need the checkbox
337  // for anything else, disable it
338  if ( !$this->showTagEditUI && !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
339  $del = Xml::check( 'deleterevisions', false, [ 'disabled' => 'disabled' ] );
340  // Otherwise, enable the checkbox...
341  } else {
342  $del = Xml::check( 'showhiderevisions', false,
343  [ 'name' => 'ids[' . $rev->getId() . ']' ] );
344  }
345  // User can only view deleted revisions...
346  } elseif ( $rev->getVisibility() && $user->isAllowed( 'deletedhistory' ) ) {
347  // If revision was hidden from sysops, disable the link
348  if ( !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
349  $del = Linker::revDeleteLinkDisabled( false );
350  // Otherwise, show the link...
351  } else {
352  $query = [ 'type' => 'revision',
353  'target' => $this->getTitle()->getPrefixedDBkey(), 'ids' => $rev->getId() ];
354  $del .= Linker::revDeleteLink( $query,
355  $rev->isDeleted( Revision::DELETED_RESTRICTED ), false );
356  }
357  }
358  if ( $del ) {
359  $s .= " $del ";
360  }
361 
362  $lang = $this->getLanguage();
363  $dirmark = $lang->getDirMark();
364 
365  $s .= " $link";
366  $s .= $dirmark;
367  $s .= " <span class='history-user'>" .
368  Linker::revUserTools( $rev, true, false ) . "</span>";
369  $s .= $dirmark;
370 
371  if ( $rev->isMinor() ) {
372  $s .= ' ' . ChangesList::flag( 'minor', $this->getContext() );
373  }
374 
375  # Sometimes rev_len isn't populated
376  if ( $rev->getSize() !== null ) {
377  # Size is always public data
378  $prevSize = $this->parentLens[$row->rev_parent_id] ?? 0;
379  $sDiff = ChangesList::showCharacterDifference( $prevSize, $rev->getSize() );
380  $fSize = Linker::formatRevisionSize( $rev->getSize(), false );
381  $s .= ' <span class="mw-changeslist-separator"></span> ' . "$fSize $sDiff";
382  }
383 
384  # Text following the character difference is added just before running hooks
385  $s2 = Linker::revComment( $rev, false, true, false );
386 
387  if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) {
388  $s2 .= ' <span class="updatedmarker">' . $this->msg( 'updatedmarker' )->escaped() . '</span>';
389  $classes[] = 'mw-history-line-updated';
390  }
391 
392  $tools = [];
393 
394  # Rollback and undo links
395  if ( $prevRev && $this->getTitle()->quickUserCan( 'edit', $user ) ) {
396  if ( $latest && $this->getTitle()->quickUserCan( 'rollback', $user ) ) {
397  // Get a rollback link without the brackets
398  $rollbackLink = Linker::generateRollback(
399  $rev,
400  $this->getContext(),
401  [ 'verify', 'noBrackets' ]
402  );
403  if ( $rollbackLink ) {
404  $this->preventClickjacking();
405  $tools[] = $rollbackLink;
406  }
407  }
408 
409  if ( !$rev->isDeleted( Revision::DELETED_TEXT )
410  && !$prevRev->isDeleted( Revision::DELETED_TEXT )
411  ) {
412  # Create undo tooltip for the first (=latest) line only
413  $undoTooltip = $latest
414  ? [ 'title' => $this->msg( 'tooltip-undo' )->text() ]
415  : [];
416  $undolink = MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
417  $this->getTitle(),
418  $this->msg( 'editundo' )->text(),
419  $undoTooltip,
420  [
421  'action' => 'edit',
422  'undoafter' => $prevRev->getId(),
423  'undo' => $rev->getId()
424  ]
425  );
426  $tools[] = "<span class=\"mw-history-undo\">{$undolink}</span>";
427  }
428  }
429  // Allow extension to add their own links here
430  Hooks::run( 'HistoryRevisionTools', [ $rev, &$tools, $prevRev, $user ] );
431 
432  if ( $tools ) {
433  $s2 .= ' ' . Html::openElement( 'span', [ 'class' => 'mw-changeslist-links' ] );
434  foreach ( $tools as $tool ) {
435  $s2 .= Html::rawElement( 'span', [], $tool );
436  }
437  $s2 .= Html::closeElement( 'span' );
438  }
439 
440  # Tags
441  list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow(
442  $row->ts_tags,
443  'history',
444  $this->getContext()
445  );
446  $classes = array_merge( $classes, $newClasses );
447  if ( $tagSummary !== '' ) {
448  $s2 .= " $tagSummary";
449  }
450 
451  # Include separator between character difference and following text
452  if ( $s2 !== '' ) {
453  $s .= ' <span class="mw-changeslist-separator"></span> ' . $s2;
454  }
455 
456  $attribs = [ 'data-mw-revid' => $rev->getId() ];
457 
458  Hooks::run( 'PageHistoryLineEnding', [ $this, &$row, &$s, &$classes, &$attribs ] );
459  $attribs = array_filter( $attribs,
460  [ Sanitizer::class, 'isReservedDataAttribute' ],
461  ARRAY_FILTER_USE_KEY
462  );
463 
464  if ( $classes ) {
465  $attribs['class'] = implode( ' ', $classes );
466  }
467 
468  return Xml::tags( 'li', $attribs, $s ) . "\n";
469  }
470 
477  function revLink( $rev ) {
478  return ChangesList::revDateLink( $rev, $this->getUser(), $this->getLanguage(),
479  $this->getTitle() );
480  }
481 
489  function curLink( $rev, $latest ) {
490  $cur = $this->historyPage->message['cur'];
491  if ( $latest || !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
492  return $cur;
493  } else {
494  return MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
495  $this->getTitle(),
496  new HtmlArmor( $cur ),
497  [],
498  [
499  'diff' => $this->getWikiPage()->getLatest(),
500  'oldid' => $rev->getId()
501  ]
502  );
503  }
504  }
505 
515  function lastLink( $prevRev, $next ) {
516  $last = $this->historyPage->message['last'];
517 
518  if ( $next === null ) {
519  # Probably no next row
520  return $last;
521  }
522 
523  $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
524  if ( $next === 'unknown' ) {
525  # Next row probably exists but is unknown, use an oldid=prev link
526  return $linkRenderer->makeKnownLink(
527  $this->getTitle(),
528  new HtmlArmor( $last ),
529  [],
530  [
531  'diff' => $prevRev->getId(),
532  'oldid' => 'prev'
533  ]
534  );
535  }
536 
537  $nextRev = new Revision( $next, 0, $this->getTitle() );
538 
539  if ( !$prevRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
540  || !$nextRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
541  ) {
542  return $last;
543  }
544 
545  return $linkRenderer->makeKnownLink(
546  $this->getTitle(),
547  new HtmlArmor( $last ),
548  [],
549  [
550  'diff' => $prevRev->getId(),
551  'oldid' => $next->rev_id
552  ]
553  );
554  }
555 
564  function diffButtons( $rev, $firstInList ) {
565  if ( $this->getNumRows() > 1 ) {
566  $id = $rev->getId();
567  $radio = [ 'type' => 'radio', 'value' => $id ];
569  if ( $firstInList ) {
570  $first = Xml::element( 'input',
571  array_merge( $radio, [
572  'style' => 'visibility:hidden',
573  'name' => 'oldid',
574  'id' => 'mw-oldid-null' ] )
575  );
576  $checkmark = [ 'checked' => 'checked' ];
577  } else {
578  # Check visibility of old revisions
579  if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
580  $radio['disabled'] = 'disabled';
581  $checkmark = []; // We will check the next possible one
582  } elseif ( !$this->oldIdChecked ) {
583  $checkmark = [ 'checked' => 'checked' ];
584  $this->oldIdChecked = $id;
585  } else {
586  $checkmark = [];
587  }
588  $first = Xml::element( 'input',
589  array_merge( $radio, $checkmark, [
590  'name' => 'oldid',
591  'id' => "mw-oldid-$id" ] ) );
592  $checkmark = [];
593  }
594  $second = Xml::element( 'input',
595  array_merge( $radio, $checkmark, [
596  'name' => 'diff',
597  'id' => "mw-diff-$id" ] ) );
598 
599  return $first . $second;
600  } else {
601  return '';
602  }
603  }
604 
608  function getDefaultQuery() {
609  parent::getDefaultQuery();
610  unset( $this->mDefaultQuery['date-range-to'] );
611  return $this->mDefaultQuery;
612  }
613 
618  function preventClickjacking( $enable = true ) {
619  $this->preventClickjacking = $enable;
620  }
621 
628  }
629 
630 }
Class for generating clickable toggle links for a list of checkboxes.
Definition: ListToggle.php:31
getRevisionButton( $name, $msg)
static modifyDisplayQuery(&$tables, &$fields, &$conds, &$join_conds, &$options, $filter_tag='')
Applies all tags-related changes to a query.
Definition: ChangeTags.php:732
formatRow( $row)
lastLink( $prevRev, $next)
Create a diff-to-previous link for this revision for this page.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1585
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:232
getStartBody()
Creates begin of history list with a submit button.
static formatRevisionSize( $size)
Definition: Linker.php:1597
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing after in associative array form before processing starts Return false to skip default processing and return $ret $linkRenderer
Definition: hooks.txt:1982
globals txt Globals are evil The original MediaWiki code relied on globals for processing context far too often MediaWiki development since then has been a story of slowly moving context out of global variables and into objects Storing processing context in object member variables allows those objects to be reused in a much more flexible way Consider the elegance of
database rows
Definition: globals.txt:10
if(!isset( $args[0])) $lang
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing &#39;/&#39;...
Definition: Html.php:252
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:210
Efficient paging for SQL queries.
bool stdClass $lastRow
static getParentLengths( $db, array $revIds)
Do a batched query to get the parent revision lengths.
Definition: Revision.php:538
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
msg( $key)
Get a Message object with context set Parameters are the same as wfMessage()
static generateRollback( $rev, IContextSource $context=null, $options=[ 'verify'])
Generate a rollback link for a given revision.
Definition: Linker.php:1812
This list may contain false positives That usually means there is additional text with links below the first Each row contains links to the first and second as well as the first line of the second redirect text
$batch
Definition: linkcache.txt:23
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition: hooks.txt:3051
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
static submitButton( $contents, array $attrs, array $modifiers=[])
Returns an HTML link element in a string styled as a button (when $wgUseMediaWikiUIEverywhere is enab...
Definition: Html.php:186
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:34
$last
static flag( $flag, IContextSource $context=null)
Make an "<abbr>" element for a given change flag.
In both all secondary updates will be triggered handle like object that caches derived data representing a and can trigger updates of cached copies of that e g in the links the and the CDN layer DerivedPageDataUpdater is used by PageUpdater when creating new revisions
Definition: pageupdater.txt:78
bool $showTagEditUI
Whether to show the tag editing UI.
preventClickjacking( $enable=true)
This is called if a write operation is possible from the generated HTML.
getContext()
Get the base IContextSource object.
static revDateLink(Revision $rev, User $user, Language $lang, $title=null)
Render the date and time of a revision in the current user language based on whether the user is able...
static tags( $element, $attribs, $contents)
Same as Xml::element(), but does not escape contents.
Definition: Xml.php:130
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:316
static showTagEditingUI(User $user)
Indicate whether change tag editing UI is relevant.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing & $attribs
Definition: hooks.txt:1982
const DELETED_RESTRICTED
Definition: Revision.php:49
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:780
static getQueryInfo( $options=[])
Return the tables, fields, and join conditions to be selected to create a new revision object...
Definition: Revision.php:511
getContext()
Get the IContextSource in use here.
Definition: Action.php:179
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
Definition: hooks.txt:1766
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
static showCharacterDifference( $old, $new, IContextSource $context=null)
Show formatted char difference.
getPreventClickjacking()
Get the "prevent clickjacking" flag.
const DELETED_TEXT
Definition: Revision.php:46
stdClass bool null $mPastTheEndRow
Extra row fetched at the end to see if the end was reached.
Definition: IndexPager.php:97
This class handles printing the history page for an article.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
historyLine( $row, $next, $notificationtimestamp=false, $latest=false, $firstInList=false)
Returns a row from the history printout.
getDateCond( $year, $month, $day=-1)
Set and return the mOffset timestamp such that we can get all revisions with a timestamp up to the sp...
submitButton( $message, $attributes=[])
Creates a submit button.
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
string $tagFilter
__construct(HistoryAction $historyPage, $year='', $month='', $tagFilter='', array $conds=[], $day='')
static hidden( $name, $value, array $attribs=[])
Convenience function to produce an input element with type=hidden.
Definition: Html.php:797
static revDeleteLink( $query=[], $restricted=false, $delete=true)
Creates a (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2153
$revQuery
revLink( $rev)
Create a link to view this revision of the page.
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:41
diffButtons( $rev, $firstInList)
Create radio buttons for page history.
array $parentLens
static formatSummaryRow( $tags, $page, IContextSource $context=null)
Creates HTML for the given tags.
Definition: ChangeTags.php:93
static revComment(Revision $rev, $local=false, $isPublic=false, $useParentheses=true)
Wrap and format the given revision&#39;s comment block, if the current user is allowed to view it...
Definition: Linker.php:1572
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:271
bool $mIsFirst
True if the current result set is the first one.
Definition: IndexPager.php:132
static tooltipAndAccesskeyAttribs( $name, array $msgParams=[], $options=null)
Returns the attributes for the tooltip and access key.
Definition: Linker.php:2194
const NS_USER_TALK
Definition: Defines.php:63
getWikiPage()
Get the WikiPage object.
curLink( $rev, $latest)
Create a diff-to-current link for this revision for this page.
static check( $name, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox.
Definition: Xml.php:323
return true to allow those checks to and false if checking is done & $user
Definition: hooks.txt:1473
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
static revDeleteLinkDisabled( $delete=true)
Creates a dead (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2175
array $mDefaultQuery
Definition: IndexPager.php:143
getNumRows()
Get the number of rows in the result set.
Definition: IndexPager.php:602
static revUserTools( $rev, $isPublic=false, $useParentheses=true)
Generate a user tool link cluster if the current user is allowed to view it.
Definition: Linker.php:1124