Go to the documentation of this file.
33 parent::__construct(
'Contributions' );
40 $out->addModuleStyles(
'mediawiki.special' );
42 $this->opts =
array();
45 if ( $par !==
null ) {
48 $target = $request->getVal(
'target' );
52 if ( $request->getVal(
'contribs' ) ==
'newbie' ) {
54 $this->opts[
'contribs'] =
'newbie';
55 } elseif ( $par ===
'newbies' ) {
57 $this->opts[
'contribs'] =
'newbie';
59 $this->opts[
'contribs'] =
'user';
62 $this->opts[
'deletedOnly'] = $request->getBool(
'deletedOnly' );
64 if ( !strlen( $target ) ) {
74 $this->opts[
'limit'] = $request->getInt(
'limit',
$user->getOption(
'rclimit' ) );
75 $this->opts[
'target'] = $target;
76 $this->opts[
'topOnly'] = $request->getBool(
'topOnly' );
77 $this->opts[
'newOnly'] = $request->getBool(
'newOnly' );
91 $id = $userObj->getID();
93 if ( $this->opts[
'contribs'] !=
'newbie' ) {
94 $target = $nt->getText();
98 $this->
msg(
'contributions-title', $target )->plain()
99 )->inContentLanguage() );
100 $this->
getSkin()->setRelevantUser( $userObj );
102 $out->addSubtitle( $this->
msg(
'sp-contributions-newbies-sub' ) );
103 $out->setHTMLTitle( $this->
msg(
105 $this->
msg(
'sp-contributions-newbies-title' )->plain()
106 )->inContentLanguage() );
109 if ( ( $ns = $request->getVal(
'namespace',
null ) ) !==
null && $ns !==
'' ) {
110 $this->opts[
'namespace'] = intval( $ns );
112 $this->opts[
'namespace'] =
'';
115 $this->opts[
'associated'] = $request->getBool(
'associated' );
116 $this->opts[
'nsInvert'] = (bool)$request->getVal(
'nsInvert' );
117 $this->opts[
'tagfilter'] = (string)$request->getVal(
'tagfilter' );
121 if (
$user->isAllowed(
'markbotedits' ) && $request->getBool(
'bot' ) ) {
122 $this->opts[
'bot'] =
'1';
125 $skip = $request->getText(
'offset' ) || $request->getText(
'dir' ) ==
'prev';
126 # Offset overrides year/month selection
128 $this->opts[
'year'] =
'';
129 $this->opts[
'month'] =
'';
131 $this->opts[
'year'] = $request->getIntOrNull(
'year' );
132 $this->opts[
'month'] = $request->getIntOrNull(
'month' );
135 $feedType = $request->getVal(
'feed' );
138 'action' =>
'feedcontributions',
141 if ( $this->opts[
'topOnly'] ) {
142 $feedParams[
'toponly'] =
true;
144 if ( $this->opts[
'newOnly'] ) {
145 $feedParams[
'newonly'] =
true;
147 if ( $this->opts[
'deletedOnly'] ) {
148 $feedParams[
'deletedonly'] =
true;
150 if ( $this->opts[
'tagfilter'] !==
'' ) {
151 $feedParams[
'tagfilter'] = $this->opts[
'tagfilter'];
153 if ( $this->opts[
'namespace'] !==
'' ) {
154 $feedParams[
'namespace'] = $this->opts[
'namespace'];
158 if ( $feedType && $this->opts[
'year'] !==
null ) {
159 $feedParams[
'year'] = $this->opts[
'year'];
161 if ( $feedType && $this->opts[
'month'] !==
null ) {
162 $feedParams[
'month'] = $this->opts[
'month'];
168 $feedParams[
'feedformat'] = $feedType;
171 $out->redirect( $url,
'301' );
179 if (
wfRunHooks(
'SpecialContributionsBeforeMainOutput',
array( $id, $userObj, $this ) ) ) {
185 'contribs' => $this->opts[
'contribs'],
186 'namespace' => $this->opts[
'namespace'],
187 'tagfilter' => $this->opts[
'tagfilter'],
188 'year' => $this->opts[
'year'],
189 'month' => $this->opts[
'month'],
190 'deletedOnly' => $this->opts[
'deletedOnly'],
191 'topOnly' => $this->opts[
'topOnly'],
192 'newOnly' => $this->opts[
'newOnly'],
193 'nsInvert' => $this->opts[
'nsInvert'],
194 'associated' => $this->opts[
'associated'],
197 if ( !$pager->getNumRows() ) {
198 $out->addWikiMsg(
'nocontribs', $target );
200 # Show a message about slave lag, if applicable
201 $lag =
wfGetLB()->safeGetLag( $pager->getDatabase() );
203 $out->showLagWarning( $lag );
207 '<p>' . $pager->getNavigationBar() .
'</p>' .
209 '<p>' . $pager->getNavigationBar() .
'</p>'
212 $out->preventClickjacking( $pager->getPreventClickjacking() );
214 # Show the appropriate "footer" message - WHOIS tools, etc.
215 if ( $this->opts[
'contribs'] ==
'newbie' ) {
216 $message =
'sp-contributions-footer-newbies';
218 $message =
'sp-contributions-footer-anon';
219 } elseif ( $userObj->isAnon() ) {
223 $message =
'sp-contributions-footer';
228 if ( !$this->
msg( $message, $target )->isDisabled() ) {
230 "<div class='mw-contributions-footer'>\n$1\n</div>",
231 array( $message, $target ) );
246 if ( $userObj->isAnon() ) {
250 "<div class=\"mw-userpage-userdoesnotexist error\">\n\$1\n</div>",
252 'contributions-userdoesnotexist',
257 $user = htmlspecialchars( $userObj->getName() );
259 $user =
Linker::link( $userObj->getUserPage(), htmlspecialchars( $userObj->getName() ) );
261 $nt = $userObj->getUserPage();
262 $talk = $userObj->getTalkPage();
271 if ( $userObj->isBlocked() && $userObj->getBlock()->getType() !=
Block::TYPE_AUTO ) {
280 'showIfEmpty' =>
false,
283 'sp-contributions-blocked-notice-anon' :
284 'sp-contributions-blocked-notice',
285 $userObj->getName() # Support GENDER
in 'sp-contributions-blocked-notice'
287 'offset' =>
'' # don
't use WebRequest parameter offset
293 return $this->msg( 'contribsub2
' )->rawParams( $user, $links )->params( $userObj->getName() );
303 public function getUserLinks( Title $userpage, Title $talkpage, User $target ) {
305 $id = $target->getId();
306 $username = $target->getName();
308 $tools[] = Linker::link( $talkpage, $this->msg( 'sp-contributions-talk
' )->escaped() );
310 if ( ( $id !== null ) || ( $id === null && IP::isIPAddress( $username ) ) ) {
311 if ( $this->getUser()->isAllowed( 'block' ) ) { # Block / Change block / Unblock links
312 if ( $target->isBlocked() && $target->getBlock()->getType() != Block::TYPE_AUTO ) {
313 $tools[] = Linker::linkKnown( # Change block link
314 SpecialPage::getTitleFor( 'Block', $username ),
315 $this->msg( 'change-blocklink
' )->escaped()
317 $tools[] = Linker::linkKnown( # Unblock link
318 SpecialPage::getTitleFor( 'Unblock
', $username ),
319 $this->msg( 'unblocklink
' )->escaped()
321 } else { # User is not blocked
322 $tools[] = Linker::linkKnown( # Block link
323 SpecialPage::getTitleFor( 'Block', $username ),
324 $this->msg( 'blocklink
' )->escaped()
330 $tools[] = Linker::linkKnown(
331 SpecialPage::getTitleFor( 'Log
', 'block' ),
332 $this->msg( 'sp-contributions-blocklog
' )->escaped(),
334 array( 'page' => $userpage->getPrefixedText() )
337 # Suppression log link (bug 59120)
338 if ( $this->getUser()->isAllowed( 'suppressionlog
' ) ) {
339 $tools[] = Linker::linkKnown(
340 SpecialPage::getTitleFor( 'Log
', 'suppress
' ),
341 $this->msg( 'sp-contributions-suppresslog
' )->escaped(),
343 array( 'offender
' => $username )
348 $tools[] = Linker::linkKnown(
349 SpecialPage::getTitleFor( 'Listfiles
', $username ),
350 $this->msg( 'sp-contributions-uploads
' )->escaped()
354 $tools[] = Linker::linkKnown(
355 SpecialPage::getTitleFor( 'Log
', $username ),
356 $this->msg( 'sp-contributions-logs
' )->escaped()
359 # Add link to deleted user contributions for priviledged users
360 if ( $this->getUser()->isAllowed( 'deletedhistory
' ) ) {
361 $tools[] = Linker::linkKnown(
362 SpecialPage::getTitleFor( 'DeletedContributions
', $username ),
363 $this->msg( 'sp-contributions-deleted
' )->escaped()
367 # Add a link to change user rights for privileged users
368 $userrightsPage = new UserrightsPage();
369 $userrightsPage->setContext( $this->getContext() );
370 if ( $userrightsPage->userCanChangeRights( $target ) ) {
371 $tools[] = Linker::linkKnown(
372 SpecialPage::getTitleFor( 'Userrights
', $username ),
373 $this->msg( 'sp-contributions-userrights
' )->escaped()
377 wfRunHooks( 'ContributionsToolLinks
', array( $id, $userpage, &$tools ) );
386 protected function getForm() {
389 $this->opts['title'] = $this->getPageTitle()->getPrefixedText();
390 if ( !isset( $this->opts['target
'] ) ) {
391 $this->opts['target
'] = '';
393 $this->opts['target
'] = str_replace( '_
', ' ', $this->opts['target
'] );
396 if ( !isset( $this->opts['namespace'] ) ) {
397 $this->opts['namespace'] = '';
400 if ( !isset( $this->opts['nsInvert
'] ) ) {
401 $this->opts['nsInvert
'] = '';
404 if ( !isset( $this->opts['associated
'] ) ) {
405 $this->opts['associated
'] = false;
408 if ( !isset( $this->opts['contribs
'] ) ) {
409 $this->opts['contribs
'] = 'user';
412 if ( !isset( $this->opts['year
'] ) ) {
413 $this->opts['year
'] = '';
416 if ( !isset( $this->opts['month
'] ) ) {
417 $this->opts['month
'] = '';
420 if ( $this->opts['contribs
'] == 'newbie
' ) {
421 $this->opts['target
'] = '';
424 if ( !isset( $this->opts['tagfilter
'] ) ) {
425 $this->opts['tagfilter
'] = '';
428 if ( !isset( $this->opts['topOnly
'] ) ) {
429 $this->opts['topOnly
'] = false;
432 if ( !isset( $this->opts['newOnly
'] ) ) {
433 $this->opts['newOnly
'] = false;
436 $form = Html::openElement(
441 'class' => 'mw-contributions-
form'
445 # Add hidden params for tracking except for parameters in $skipParameters
446 $skipParameters = array(
459 foreach ( $this->opts as $name => $value ) {
460 if ( in_array( $name, $skipParameters ) ) {
463 $form .= "\t" . Html::hidden( $name, $value ) . "\n";
466 $tagFilter = ChangeTags::buildTagFilterSelector( $this->opts['tagfilter
'] );
469 $filterSelection = Html::rawElement(
471 array( 'class' => 'mw-label
' ),
472 array_shift( $tagFilter )
474 $filterSelection .= Html::rawElement(
476 array( 'class' => 'mw-input
' ),
477 implode( ' 
', $tagFilter )
480 $filterSelection = Html::rawElement( 'td
', array( 'colspan
' => 2 ), '' );
483 $labelNewbies = Xml::radioLabel(
484 $this->msg( 'sp-contributions-newbies
' )->text(),
488 $this->opts['contribs
'] == 'newbie
',
489 array( 'class' => 'mw-input
' )
491 $labelUsername = Xml::radioLabel(
492 $this->msg( 'sp-contributions-username
' )->text(),
496 $this->opts['contribs
'] == 'user',
497 array( 'class' => 'mw-input
' )
499 $input = Html::input(
501 $this->opts['target
'],
503 array( 'size
' => '40
', 'required
' => '', 'class' => 'mw-input
' ) +
504 ( $this->opts['target
'] ? array() : array( 'autofocus
' )
507 $targetSelection = Html::rawElement(
509 array( 'colspan
' => 2 ),
510 $labelNewbies . '<br />
' . $labelUsername . ' ' . $input . ' '
513 $namespaceSelection = Xml::tags(
515 array( 'class' => 'mw-label
' ),
517 $this->msg( 'namespace' )->text(),
522 $namespaceSelection .= Html::rawElement(
525 Html::namespaceSelector(
526 array( 'selected
' => $this->opts['namespace'], 'all
' => '' ),
528 'name' => 'namespace',
530 'class' => 'namespaceselector
',
535 array( 'style
' => 'white-space: nowrap
' ),
537 $this->msg( 'invert
' )->text(),
540 $this->opts['nsInvert
'],
542 'title' => $this->msg( 'tooltip-invert
' )->text(),
543 'class' => 'mw-input
'
547 Html::rawElement( 'span
', array( 'style
' => 'white-space: nowrap
' ),
549 $this->msg( 'namespace_association
' )->text(),
552 $this->opts['associated
'],
554 'title' => $this->msg( 'tooltip-namespace_association
' )->text(),
555 'class' => 'mw-input
'
561 if ( $this->getUser()->isAllowed( 'deletedhistory
' ) ) {
562 $deletedOnlyCheck = Html::rawElement(
564 array( 'style
' => 'white-space: nowrap
' ),
566 $this->msg( 'history-show-deleted
' )->text(),
568 'mw-show-deleted-
only',
569 $this->opts['deletedOnly
'],
570 array( 'class' => 'mw-input
' )
574 $deletedOnlyCheck = '';
577 $checkLabelTopOnly = Html::rawElement(
579 array( 'style
' => 'white-space: nowrap
' ),
581 $this->msg( 'sp-contributions-toponly
' )->text(),
584 $this->opts['topOnly
'],
585 array( 'class' => 'mw-input
' )
588 $checkLabelNewOnly = Html::rawElement(
590 array( 'style
' => 'white-space: nowrap
' ),
592 $this->msg( 'sp-contributions-newonly
' )->text(),
595 $this->opts['newOnly
'],
596 array( 'class' => 'mw-input
' )
599 $extraOptions = Html::rawElement(
601 array( 'colspan
' => 2 ),
602 $deletedOnlyCheck . $checkLabelTopOnly . $checkLabelNewOnly
605 $dateSelectionAndSubmit = Xml::tags( 'td
', array( 'colspan
' => 2 ),
607 $this->opts['year
'] === '' ? MWTimestamp::getInstance()->format( 'Y
' ) : $this->opts['year
'],
611 $this->msg( 'sp-contributions-submit
' )->text(),
612 array( 'class' => 'mw-submit
' )
616 $form .= Xml::fieldset( $this->msg( 'sp-contributions-search
' )->text() );
617 $form .= Html::rawElement( 'table', array( 'class' => 'mw-contributions-
table' ), "\n" .
618 Html::rawElement( 'tr
', array(), $targetSelection ) . "\n" .
619 Html::rawElement( 'tr
', array(), $namespaceSelection ) . "\n" .
620 Html::rawElement( 'tr
', array(), $filterSelection ) . "\n" .
621 Html::rawElement( 'tr
', array(), $extraOptions ) . "\n" .
622 Html::rawElement( 'tr
', array(), $dateSelectionAndSubmit ) . "\n"
625 $explain = $this->msg( 'sp-contributions-explain
' );
626 if ( !$explain->isBlank() ) {
627 $form .= "<p id='mw-sp-contributions-explain
'>{$explain->parse()}</p>";
630 $form .= Xml::closeElement( 'fieldset
' ) . Xml::closeElement( 'form' );
635 protected function getGroupName() {
644 class ContribsPager extends ReverseChronologicalPager {
645 public $mDefaultDirection = true;
648 public $namespace = '';
650 public $preventClickjacking = false;
653 public $mDbSecondary;
658 protected $mParentLens;
660 function __construct( IContextSource $context, array $options ) {
661 parent::__construct( $context );
673 foreach ( $msgs as $msg ) {
674 $this->messages[$msg] = $this->msg( $msg )->escaped();
677 $this->target = isset( $options['target
'] ) ? $options['target
'] : '';
678 $this->contribs = isset( $options['contribs
'] ) ? $options['contribs
'] : 'users
';
679 $this->namespace = isset( $options['namespace'] ) ? $options['namespace'] : '';
680 $this->tagFilter = isset( $options['tagfilter
'] ) ? $options['tagfilter
'] : false;
681 $this->nsInvert = isset( $options['nsInvert
'] ) ? $options['nsInvert
'] : false;
682 $this->associated = isset( $options['associated
'] ) ? $options['associated
'] : false;
684 $this->deletedOnly = !empty( $options['deletedOnly
'] );
685 $this->topOnly = !empty( $options['topOnly
'] );
686 $this->newOnly = !empty( $options['newOnly
'] );
688 $year = isset( $options['year
'] ) ? $options['year
'] : false;
689 $month = isset( $options['month
'] ) ? $options['month
'] : false;
690 $this->getDateCond( $year, $month );
692 // Most of this code will use the 'contributions
' group DB, which can map to slaves
693 // with extra user based indexes or partioning by user. The additional metadata
694 // queries should use a regular slave since the lookup pattern is not all by user.
695 $this->mDbSecondary = wfGetDB( DB_SLAVE ); // any random slave
696 $this->mDb = wfGetDB( DB_SLAVE, 'contributions
' );
699 function getDefaultQuery() {
700 $query = parent::getDefaultQuery();
701 $query['target
'] = $this->target;
715 function reallyDoQuery( $offset, $limit, $descending ) {
716 list( $tables, $fields, $conds, $fname, $options, $join_conds ) = $this->buildQueryInfo(
724 * This hook will allow extensions to add in additional queries, so they can get their data
725 * in My Contributions as well. Extensions should append their results to the $data array.
727 * Extension queries have to implement the navbar requirement as well. They should
728 * - have a column aliased as $pager->getIndexField()
730 * - have a WHERE-clause that compares the $pager->getIndexField()-equivalent column to the offset
731 * - have the ORDER BY specified based upon the details provided by the navbar
733 * See includes/Pager.php buildQueryInfo() method on how to build LIMIT, WHERE & ORDER BY
735 * &$data: an array of results of all contribs queries
736 * $pager: the ContribsPager object hooked into
737 * $offset: see phpdoc above
738 * $limit: see phpdoc above
739 * $descending: see phpdoc above
741 $data = array( $this->mDb->select(
742 $tables, $fields, $conds, $fname, $options, $join_conds
746 array( &$data, $pager, $offset, $limit, $descending )
751 // loop all results and collect them in an array
752 foreach ( $data as $query ) {
753 foreach ( $query as $i => $row ) {
754 // use index column as key, allowing us to easily sort in PHP
755 $result[$row->{$this->getIndexField()} . "-$i"] = $row;
767 $result = array_slice( $result, 0, $limit );
769 // get rid of array keys
770 $result = array_values( $result );
772 return new FakeResultWrapper( $result );
775 function getQueryInfo() {
776 list( $tables, $index, $userCond, $join_cond ) = $this->getUserCond();
778 $user = $this->getUser();
779 $conds = array_merge( $userCond, $this->getNamespaceCond() );
781 // Paranoia: avoid brute force searches (bug 17342)
782 if ( !$user->isAllowed( 'deletedhistory
' ) ) {
783 $conds[] = $this->mDb->bitAnd( 'rev_deleted
', Revision::DELETED_USER ) . ' = 0
';
784 } elseif ( !$user->isAllowed( 'suppressrevision
' ) ) {
785 $conds[] = $this->mDb->bitAnd( 'rev_deleted
', Revision::SUPPRESSED_USER ) .
786 ' !=
' . Revision::SUPPRESSED_USER;
789 # Don't include orphaned revisions
791 # Get the current user name for accounts
801 'fields' => array_merge(
804 array(
'page_namespace',
'page_title',
'page_is_new',
805 'page_latest',
'page_is_redirect',
'page_len' )
809 'join_conds' => $join_cond
813 $queryInfo[
'tables'],
814 $queryInfo[
'fields'],
816 $queryInfo[
'join_conds'],
817 $queryInfo[
'options'],
821 wfRunHooks(
'ContribsPager::getQueryInfo',
array( &$this, &$queryInfo ) );
826 function getUserCond() {
827 $condition =
array();
828 $join_conds =
array();
831 if ( $this->contribs ==
'newbie' ) {
832 $max = $this->mDb->selectField(
'user',
'max(user_id)',
false, __METHOD__ );
833 $condition[] =
'rev_user >' . (int)( $max - $max / 100 );
834 # ignore local groups with the bot right
835 # @todo FIXME: Global groups may have 'bot' rights
837 if ( count( $groupsWithBotPermission ) ) {
839 $condition[] =
'ug_group IS NULL';
840 $join_conds[
'user_groups'] =
array(
842 'ug_user = rev_user',
843 'ug_group' => $groupsWithBotPermission
850 $condition[
'rev_user'] = $uid;
851 $index =
'user_timestamp';
853 $condition[
'rev_user_text'] = $this->target;
854 $index =
'usertext_timestamp';
858 if ( $this->deletedOnly ) {
859 $condition[] =
'rev_deleted != 0';
862 if ( $this->topOnly ) {
863 $condition[] =
'rev_id = page_latest';
866 if ( $this->newOnly ) {
867 $condition[] =
'rev_parent_id = 0';
870 return array(
$tables, $index, $condition, $join_conds );
873 function getNamespaceCond() {
874 if ( $this->
namespace !==
'' ) {
875 $selectedNS = $this->mDb->addQuotes( $this->
namespace );
876 $eq_op = $this->nsInvert ?
'!=' :
'=';
877 $bool_op = $this->nsInvert ?
'AND' :
'OR';
879 if ( !$this->associated ) {
880 return array(
"page_namespace $eq_op $selectedNS" );
883 $associatedNS = $this->mDb->addQuotes(
888 "page_namespace $eq_op $selectedNS " .
890 " page_namespace $eq_op $associatedNS"
897 function getIndexField() {
898 return 'rev_timestamp';
901 function doBatchLookups() {
902 # Do a link batch query
903 $this->mResult->seek( 0 );
906 # Give some pointers to make (last) links
907 foreach ( $this->mResult
as $row ) {
908 if ( isset( $row->rev_parent_id ) && $row->rev_parent_id ) {
909 $revIds[] = $row->rev_parent_id;
911 if ( isset( $row->rev_id ) ) {
912 if ( $this->contribs ===
'newbie' ) {
916 $batch->add( $row->page_namespace, $row->page_title );
921 $this->mResult->seek( 0 );
927 function getStartBody() {
934 function getEndBody() {
950 function formatRow( $row ) {
966 $validRevision = (bool)
$rev->getId();
968 $validRevision =
false;
972 if ( $validRevision ) {
978 htmlspecialchars( $page->getPrefixedText() ),
979 array(
'class' =>
'mw-contributions-title' ),
980 $page->isRedirect() ?
array(
'redirect' =>
'no' ) :
array()
982 # Mark current revisions
985 if ( $row->rev_id == $row->page_latest ) {
986 $topmarktext .=
'<span class="mw-uctop">' . $this->
messages[
'uctop'] .
'</span>';
988 if ( !$row->page_is_new && $page->quickUserCan(
'rollback',
$user )
989 && $page->quickUserCan(
'edit',
$user )
991 $this->preventClickjacking();
995 # Is there a visible previous revision?
1003 'oldid' => $row->rev_id
1007 $difftext = $this->
messages[
'diff'];
1013 array(
'action' =>
'history' )
1016 if ( $row->rev_parent_id ===
null ) {
1020 $chardiff =
' <span class="mw-changeslist-separator">. .</span> ';
1022 $chardiff .=
' <span class="mw-changeslist-separator">. .</span> ';
1025 if ( isset( $this->mParentLens[$row->rev_parent_id] ) ) {
1026 $parentLen = $this->mParentLens[$row->rev_parent_id];
1029 $chardiff =
' <span class="mw-changeslist-separator">. .</span> ';
1035 $chardiff .=
' <span class="mw-changeslist-separator">. .</span> ';
1040 $date = $lang->userTimeAndDate( $row->rev_timestamp,
$user );
1044 htmlspecialchars( $date ),
1045 array(
'class' =>
'mw-changeslist-date' ),
1046 array(
'oldid' => intval( $row->rev_id ) )
1049 $d = htmlspecialchars( $date );
1052 $d =
'<span class="history-deleted">' . $d .
'</span>';
1055 # Show user names for /newbies as there may be different users.
1056 # Note that we already excluded rows with hidden user names.
1057 if ( $this->contribs ==
'newbie' ) {
1059 $userlink .=
' ' . $this->
msg(
'parentheses' )->rawParams(
1065 if (
$rev->getParentId() === 0 ) {
1071 if (
$rev->isMinor() ) {
1078 if ( $del !==
'' ) {
1082 $diffHistLinks = $this->
msg(
'parentheses' )
1083 ->rawParams( $difftext . $this->
messages[
'pipe-separator'] . $histlink )
1085 $ret =
"{$del}{$d} {$diffHistLinks}{$chardiff}{$nflag}{$mflag} ";
1086 $ret .=
"{$link}{$userlink} {$comment} {$topmarktext}";
1088 # Denote if username is redacted for this edit
1090 $ret .=
" <strong>" .
1091 $this->
msg(
'rev-deleted-user-contribs' )->escaped() .
1100 $classes = array_merge( $classes, $newClasses );
1101 $ret .=
" $tagSummary";
1107 if ( $classes ===
array() &&
$ret ===
'' ) {
1108 wfDebug(
"Dropping Special:Contribution row that could not be formatted\n" );
1109 $ret =
"<!-- Could not format Special:Contribution row. -->\n";
1123 function getSqlComment() {
1124 if ( $this->
namespace || $this->deletedOnly ) {
1126 return 'contributions page filtered for namespace or RevisionDeleted edits';
1128 return 'contributions page unfiltered';
1132 protected function preventClickjacking() {
1133 $this->preventClickjacking =
true;
1139 public function getPreventClickjacking() {
1140 return $this->preventClickjacking;
static generateRollback( $rev, IContextSource $context=null, $options=array( 'verify'))
Generate a rollback link for a given revision.
static userTalkLink( $userId, $userText)
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
static pageJoinCond()
Return the value of a select() page conds array for the page table.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
namespace and then decline to actually register it RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist & $tables
static userLink( $userId, $userName, $altUserName=false)
Make user link (or user contributions for unregistered users)
getOutput()
Get the OutputPage being used for this instance.
getForm()
Generates the namespace selector form with hidden attributes.
wfGetLB( $wiki=false)
Get a load balancer object.
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
wfProfileIn( $functionname)
Begin profiling of a function.
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 & $ret
wfSuppressWarnings( $end=false)
Reference-counted warning suppression.
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
getSkin()
Shortcut to get the skin being used for this instance.
Shortcut to construct an includable special page.
getLanguage()
Shortcut to get user's language.
namespace and then decline to actually register it RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist but no entry for that model exists in $wgContentHandlers if desired whether it is OK to use $contentModel on $title Handler functions that modify $ok should generally return false to prevent further hooks from further modifying $ok in case the handler function wants to provide a converted Content object Note that $result getContentModel() must return $toModel. Handler functions that modify $result should generally return false to further attempts at conversion. 'ContribsPager you ll need to handle error messages
set to $title object and return false for a match for latest after cache objects are set use the ContentHandler facility to handle CSS and JavaScript for highlighting & $link
static linkKnown( $target, $html=null, $customAttribs=array(), $query=array(), $options=array( 'known', 'noclasses'))
Identical to link(), except $options defaults to 'known'.
static flag( $flag)
Provide the "<abbr>" element appropriate to a given abbreviated flag, namely the flag indicating a ne...
static link( $target, $html=null, $customAttribs=array(), $query=array(), $options=array())
This function returns an HTML link to the given target.
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
to move a page</td >< td > &*You are moving the page across *A non empty talk page already exists under the new or *You uncheck the box below In those you will have to move or merge the page manually if desired</td >< td > be sure to &You are responsible for making sure that links continue to point where they are supposed to go Note that the page will &a page at the new title
execute( $par)
Default execute method Checks user permissions, calls the function given in mFunction.
addFeedLinks( $params)
Adds RSS/atom links.
wfRestoreWarnings()
Restore error level to previous value.
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
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 then executing the whole list after the page is displayed We don t do anything smart like collating updates to the same table or such because the list is almost always going to have just one item on if so it s not worth the trouble Since there is a job queue in the jobs table
static newFromRow( $row)
Make a Title object from a DB row.
wfProfileOut( $functionname='missing')
Stop profiling of a function.
wfRunHooks( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in $wgHooks.
static isIP( $name)
Does the string match an anonymous IPv4 address?
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getUser()
Shortcut to get the User executing this instance.
null means default in associative array form
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
processing should stop and the error should be shown to the user * false
getContext()
Gets the context this SpecialPage is executed in.
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 & $options
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
static revComment(Revision $rev, $local=false, $isPublic=false)
Wrap and format the given revision's comment block, if the current user is allowed to view it.
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 and we might be restricted by PHP settings such as safe mode or open_basedir We cannot assume that the software even has read access anywhere useful Many shared hosts run all users web applications under the same user
msg()
Wrapper around wfMessage that sets the current context.
static getParentLengths( $db, array $revIds)
Do a batched query to get the parent revision lengths.
static getRevDeleteLink(User $user, Revision $rev, Title $title)
Get a revision-deletion link, or disabled link, or nothing, depending on user permissions & the setti...
static configuration should be added through ResourceLoaderGetConfigVars instead can be used to get the real title after the basic globals have been set but before ordinary actions take place change it to the message you want to define which works for all SkinTemplate type skins $tools
getRequest()
Get the WebRequest being used for this instance.
static formatRevisionSize( $size)
static showCharacterDifference( $old, $new, IContextSource $context=null)
Show formatted char difference.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LoginAuthenticateAudit' this hook is for auditing only etc block
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
getUserLinks(Title $userpage, Title $talkpage, User $target)
Links to different places.
published in in Madrid In the first edition of the Vocabolario for was published In in Rotterdam was the Dictionnaire Universel ! html< p > The first monolingual dictionary written in a Romance language was< i > Sebastián Covarrubias</i >< i > Tesoro de la lengua castellana o published in in Madrid In the first edition of the< i > Vocabolario dell< a href="/index.php?title=Accademia_della_Crusca&action=edit&redlink=1" class="new" title="Accademia della Crusca (page does not exist)"> Accademia della Crusca</a ></i > for was published In in Rotterdam was the< i > Dictionnaire Universel</i ></p > ! end ! test Italics and ! wikitext foo ! html< p >< i > foo</i ></p > !end ! test Italics and ! wikitext foo ! html< p >< i > foo</i ></p > !end ! test Italics and ! wikitext foo ! html< p >< i > foo</i ></p > !end ! test Italics and ! wikitext foo ! html php< p >< i > foo</i ></p > ! html parsoid< p >< i > foo</i >< b ></b ></p > !end ! test Italics and ! wikitext foo ! html< p >< i > foo</i ></p > !end ! test Italics and ! wikitext foo ! html< p >< b > foo</b ></p > !end ! test Italics and ! wikitext foo ! html< p >< b > foo</b ></p > !end ! test Italics and ! wikitext foo ! html php< p >< b > foo</b ></p > ! html parsoid< p >< b > foo</b >< i ></i ></p > !end ! test Italics and ! wikitext foo ! html< p >< i > foo</i ></p > !end ! test Italics and ! wikitext foo ! html< p >< b > foo</b ></p > !end ! test Italics and ! wikitext foo ! html< p >< b > foo</b ></p > !end ! test Italics and ! wikitext foo ! html php< p >< b > foo</b ></p > ! html parsoid< p >< b > foo</b >< i ></i ></p > !end ! test Italics and ! options ! wikitext foo ! html< p >< b >< i > foo</i ></b ></p > !end ! test Italics and ! wikitext foo ! html< p >< i >< b > foo</b ></i ></p > !end ! test Italics and ! wikitext foo ! html< p >< i >< b > foo</b ></i ></p > !end ! test Italics and ! wikitext foo ! html< p >< i >< b > foo</b ></i ></p > !end ! test Italics and ! wikitext foo bar ! html< p >< i > foo< b > bar</b ></i ></p > !end ! test Italics and ! wikitext foo bar ! html< p >< i > foo< b > bar</b ></i ></p > !end ! test Italics and ! wikitext foo bar ! html< p >< i > foo< b > bar</b ></i ></p > !end ! test Italics and ! wikitext foo bar ! html php< p >< b > foo</b > bar</p > ! html parsoid< p >< b > foo</b > bar< i ></i ></p > !end ! test Italics and ! wikitext foo bar ! html php< p >< b > foo</b > bar</p > ! html parsoid< p >< b > foo</b > bar< b ></b ></p > !end ! test Italics and ! wikitext this is about foo s family ! html< p >< i > this is about< b > foo s family</b ></i ></p > !end ! test Italics and ! wikitext this is about foo s family ! html< p >< i > this is about< b > foo s</b > family</i ></p > !end ! test Italics and ! wikitext this is about foo s family ! html< p >< b > this is about< i > foo</i ></b >< i > s family</i ></p > !end ! test Italics and ! options ! wikitext this is about foo s family ! html< p >< i > this is about</i > foo< b > s family</b ></p > !end ! test Italics and ! wikitext this is about foo s family ! html< p >< b > this is about< i > foo s</i > family</b ></p > !end ! test Italicized possessive ! wikitext The s talk page ! html< p > The< i >< a href="/wiki/Main_Page" title="Main Page"> Main Page</a ></i > s talk page</p > ! end ! test Parsoid only
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
static idFromName( $name)
Get database id given a user name.
Prior to maintenance scripts were a hodgepodge of code that had no cohesion or formal method of action Beginning in
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
static userJoinCond()
Return the value of a select() JOIN conds array for the user table.
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at name
static selectUserFields()
Return the list of user fields that should be selected from user table.
contributionsSub( $userObj)
Generates the subheading with links.
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 change
static rawElement( $element, $attribs=array(), $contents='')
Returns an HTML element in a string.
static selectFields()
Return the list of revision fields that should be selected to create a new revision.
static getAssociated( $index)
Get the associated namespace.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
including( $x=null)
Whether the special page is being evaluated via transclusion.
Special:Contributions, show user contributions in a paged list.
static isIPAddress( $ip)
Determine if a string is as valid IP address or network (CIDR prefix).
static getGroupsWithPermission( $role)
Get all the groups who have a given permission.
static showLogExtract(&$out, $types=array(), $page='', $user='', $param=array())
Show log extract.
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values my talk page