Go to the documentation of this file.
70 parent::__construct(
'MergeHistory',
'mergehistory' );
82 $this->mAction = $request->getVal(
'action' );
83 $this->mTarget = $request->getVal(
'target' );
84 $this->mDest = $request->getVal(
'dest' );
85 $this->mSubmitted = $request->getBool(
'submitted' );
87 $this->mTargetID = intval( $request->getVal(
'targetID' ) );
88 $this->mDestID = intval( $request->getVal(
'destID' ) );
89 $this->mTimestamp = $request->getVal(
'mergepoint' );
90 if ( !preg_match(
'/[0-9]{14}/', $this->mTimestamp ) ) {
91 $this->mTimestamp =
'';
93 $this->mComment = $request->getText(
'wpComment' );
95 $this->mMerge = $request->wasPosted()
96 && $this->
getUser()->matchEditToken( $request->getVal(
'wpEditToken' ) );
99 if ( $this->mSubmitted ) {
103 $this->mTargetObj =
null;
104 $this->mDestObj =
null;
119 if ( $this->mTargetID && $this->mDestID && $this->mAction ==
'submit' && $this->mMerge ) {
125 if ( !$this->mSubmitted ) {
132 if ( !$this->mTargetObj instanceof
Title ) {
133 $errors[] = $this->
msg(
'mergehistory-invalid-source' )->parseAsBlock();
134 } elseif ( !$this->mTargetObj->exists() ) {
135 $errors[] = $this->
msg(
'mergehistory-no-source',
140 if ( !$this->mDestObj instanceof
Title ) {
141 $errors[] = $this->
msg(
'mergehistory-invalid-destination' )->parseAsBlock();
142 } elseif ( !$this->mDestObj->exists() ) {
143 $errors[] = $this->
msg(
'mergehistory-no-destination',
148 if ( $this->mTargetObj && $this->mDestObj && $this->mTargetObj->equals( $this->mDestObj ) ) {
149 $errors[] = $this->
msg(
'mergehistory-same-destination' )->parseAsBlock();
152 if ( count( $errors ) ) {
154 $this->
getOutput()->addHTML( implode(
"\n", $errors ) );
162 $out->addWikiMsg(
'mergehistory-header' );
170 $this->
msg(
'mergehistory-box' )->text() ) .
171 Html::hidden(
'title', $this->
getPageTitle()->getPrefixedDBkey() ) .
172 Html::hidden(
'submitted',
'1' ) .
173 Html::hidden(
'mergepoint', $this->mTimestamp ) .
176 <td>' .
Xml::label( $this->
msg(
'mergehistory-from' )->text(),
'target' ) .
'</td>
177 <td>' .
Xml::input(
'target', 30, $this->mTarget, [
'id' =>
'target' ] ) .
'</td>
179 <td>' .
Xml::label( $this->
msg(
'mergehistory-into' )->text(),
'dest' ) .
'</td>
180 <td>' .
Xml::input(
'dest', 30, $this->mDest, [
'id' =>
'dest' ] ) .
'</td>
195 # List all stored revisions
197 $this, [], $this->mTargetObj, $this->mDestObj
199 $haveRevisions = $revisions && $revisions->getNumRows() > 0;
203 $action = $titleObj->getLocalURL( [
'action' =>
'submit' ] );
204 # Start the form here
213 $out->addHTML( $top );
215 if ( $haveRevisions ) {
216 # Format the user-visible controls (comment field, submission button)
217 # in a nice little table
220 $this->
msg(
'mergehistory-merge', $this->mTargetObj->getPrefixedText(),
221 $this->mDestObj->getPrefixedText() )->parse() .
224 <td class="mw-label">' .
225 Xml::label( $this->
msg(
'mergehistory-reason' )->text(),
'wpComment' ) .
227 <td class="mw-input">' .
228 Xml::input(
'wpComment', 50, $this->mComment, [
'id' =>
'wpComment' ] ) .
233 <td class=\"mw-submit\">" .
235 $this->
msg(
'mergehistory-submit' )->text(),
236 [
'name' =>
'merge',
'id' =>
'mw-merge-submit' ]
243 $out->addHTML( $table );
247 '<h2 id="mw-mergehistory">' .
248 $this->
msg(
'mergehistory-list' )->escaped() .
"</h2>\n"
251 if ( $haveRevisions ) {
252 $out->addHTML( $revisions->getNavigationBar() );
253 $out->addHTML(
'<ul>' );
254 $out->addHTML( $revisions->getBody() );
255 $out->addHTML(
'</ul>' );
256 $out->addHTML( $revisions->getNavigationBar() );
258 $out->addWikiMsg(
'mergehistory-empty' );
261 # Show relevant lines from the merge log:
262 $mergeLogPage =
new LogPage(
'merge' );
263 $out->addHTML(
'<h2>' . $mergeLogPage->getName()->escaped() .
"</h2>\n" );
266 # When we submit, go by page ID to avoid some nasty but unlikely collisions.
267 # Such would happen if a page was renamed after the form loaded, but before submit
268 $misc = Html::hidden(
'targetID', $this->mTargetObj->getArticleID() );
269 $misc .= Html::hidden(
'destID', $this->mDestObj->getArticleID() );
270 $misc .= Html::hidden(
'target', $this->mTarget );
271 $misc .= Html::hidden(
'dest', $this->mDest );
272 $misc .= Html::hidden(
'wpEditToken', $this->
getUser()->getEditToken() );
274 $out->addHTML( $misc );
285 $last = $this->
msg(
'last' )->escaped();
288 $checkBox =
Xml::radio(
'mergepoint', $ts, ( $this->mTimestamp === $ts ) );
294 $this->
getLanguage()->userTimeAndDate( $ts, $user ),
296 [
'oldid' => $rev->getId() ]
298 if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
299 $pageLink =
'<span class="history-deleted">' . $pageLink .
'</span>';
303 if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
304 $last = $this->
msg(
'last' )->escaped();
305 } elseif ( isset( $this->prevId[$row->rev_id] ) ) {
308 $this->
msg(
'last' )->text(),
311 'diff' => $row->rev_id,
312 'oldid' => $this->prevId[$row->rev_id]
319 $size = $row->rev_len;
320 if ( !is_null( $size ) ) {
325 return Html::rawElement(
'li', [],
326 $this->
msg(
'mergehistory-revisionrow' )
327 ->rawParams( $checkBox,
$last, $pageLink, $userLink, $stxt, $comment )->escaped() );
343 # Get the titles directly from the IDs, in case the target page params
344 # were spoofed. The queries are done based on the IDs, so it's best to
345 # keep it consistent...
348 if ( is_null( $targetTitle ) || is_null( $destTitle ) ) {
351 if ( $targetTitle->getArticleID() == $destTitle->getArticleID() ) {
356 $mh =
new MergeHistory( $targetTitle, $destTitle, $this->mTimestamp );
359 $mergeStatus = $mh->merge( $this->
getUser(), $this->mComment );
360 if ( !$mergeStatus->isOK() ) {
362 $this->
getOutput()->addWikiMsg( $mergeStatus->getMessage() );
372 [
'redirect' =>
'no' ]
375 $this->
getOutput()->addWikiMsg( $this->
msg(
'mergehistory-done' )
376 ->rawParams( $targetLink )
377 ->params( $destTitle->getPrefixedText() )
378 ->numParams( $mh->getMergedRevisionCount() )
getPageTitle( $subpage=false)
Get a self-referential title object.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
merge()
Actually attempt the history move.
getOutput()
Get the OutputPage being used for this instance.
static label( $label, $id, $attribs=[])
Convenience function to build an HTML form label.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
static radio( $name, $value, $checked=false, $attribs=[])
Convenience function to build an HTML radio button.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
static revComment(Revision $rev, $local=false, $isPublic=false, $useParentheses=true)
Wrap and format the given revision's comment block, if the current user is allowed to view it.
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
getLanguage()
Shortcut to get user's language.
static openElement( $element, $attribs=null)
This opens an XML element.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
Class to simplify the use of log pages.
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getUser()
Shortcut to get the User executing this instance.
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
static revUserTools( $rev, $isPublic=false, $useParentheses=true)
Generate a user tool link cluster if the current user is allowed to view it.
Parent class for all special pages.
bool $mSubmitted
Was submitted?
getRequest()
Get the WebRequest being used for this instance.
static formatRevisionSize( $size)
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Handles the backend logic of merging the histories of two pages.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Represents a title within MediaWiki.
static closeElement( $element)
Shortcut to close an XML element.
static input( $name, $size=false, $value=false, $attribs=[])
Convenience function to build an HTML text input field.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
MediaWiki Linker LinkRenderer null $linkRenderer
static newFromID( $id, $flags=0)
Create a new Title from an article ID.
Special page allowing users with the appropriate permissions to merge article histories,...
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
doesWrites()
Indicates whether this special page may perform database writes.
static submitButton( $value, $attribs=[])
Convenience function to build an HTML submit button When $wgUseMediaWikiUIEverywhere is true it will ...
execute( $par)
Default execute method Checks user permissions.