2004-02-18 02:15:00 +00:00
|
|
|
<?php
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2007-04-04 05:22:37 +00:00
|
|
|
* Contains the EditPage class
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @file
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2007-04-04 05:22:37 +00:00
|
|
|
* The edit page/HTML interface (split from Article)
|
2004-09-02 23:28:24 +00:00
|
|
|
* The actual database and text munging is still in Article,
|
|
|
|
|
* but it should get easier to call those from alternate
|
|
|
|
|
* interfaces.
|
2007-11-03 03:20:12 +00:00
|
|
|
*
|
|
|
|
|
* EditPage cares about two distinct titles:
|
|
|
|
|
* $wgTitle is the page that forms submit to, links point to,
|
|
|
|
|
* redirects go to, etc. $this->mTitle (as well as $mArticle) is the
|
|
|
|
|
* page in the database that is actually being edited. These are
|
|
|
|
|
* usually the same, but they are now allowed to be different.
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2003-08-02 20:43:11 +00:00
|
|
|
class EditPage {
|
2008-01-25 10:34:43 +00:00
|
|
|
const AS_SUCCESS_UPDATE = 200;
|
2007-10-30 05:42:19 +00:00
|
|
|
const AS_SUCCESS_NEW_ARTICLE = 201;
|
2008-01-25 10:34:43 +00:00
|
|
|
const AS_HOOK_ERROR = 210;
|
|
|
|
|
const AS_FILTERING = 211;
|
2007-10-30 05:42:19 +00:00
|
|
|
const AS_HOOK_ERROR_EXPECTED = 212;
|
|
|
|
|
const AS_BLOCKED_PAGE_FOR_USER = 215;
|
2008-01-25 10:34:43 +00:00
|
|
|
const AS_CONTENT_TOO_BIG = 216;
|
|
|
|
|
const AS_USER_CANNOT_EDIT = 217;
|
2007-10-30 05:42:19 +00:00
|
|
|
const AS_READ_ONLY_PAGE_ANON = 218;
|
|
|
|
|
const AS_READ_ONLY_PAGE_LOGGED = 219;
|
2008-01-25 10:34:43 +00:00
|
|
|
const AS_READ_ONLY_PAGE = 220;
|
|
|
|
|
const AS_RATE_LIMITED = 221;
|
2007-10-30 05:42:19 +00:00
|
|
|
const AS_ARTICLE_WAS_DELETED = 222;
|
|
|
|
|
const AS_NO_CREATE_PERMISSION = 223;
|
2008-01-25 10:34:43 +00:00
|
|
|
const AS_BLANK_ARTICLE = 224;
|
|
|
|
|
const AS_CONFLICT_DETECTED = 225;
|
|
|
|
|
const AS_SUMMARY_NEEDED = 226;
|
|
|
|
|
const AS_TEXTBOX_EMPTY = 228;
|
|
|
|
|
const AS_MAX_ARTICLE_SIZE_EXCEEDED = 229;
|
|
|
|
|
const AS_OK = 230;
|
|
|
|
|
const AS_END = 231;
|
|
|
|
|
const AS_SPAM_ERROR = 232;
|
|
|
|
|
const AS_IMAGE_REDIRECT_ANON = 233;
|
|
|
|
|
const AS_IMAGE_REDIRECT_LOGGED = 234;
|
2007-10-30 05:42:19 +00:00
|
|
|
|
2006-05-11 22:40:38 +00:00
|
|
|
var $mArticle;
|
2007-11-01 17:56:19 +00:00
|
|
|
var $mTitle;
|
2008-08-27 05:56:34 +00:00
|
|
|
var $action;
|
2006-05-11 22:40:38 +00:00
|
|
|
var $mMetaData = '';
|
|
|
|
|
var $isConflict = false;
|
|
|
|
|
var $isCssJsSubpage = false;
|
|
|
|
|
var $deletedSinceEdit = false;
|
|
|
|
|
var $formtype;
|
|
|
|
|
var $firsttime;
|
|
|
|
|
var $lastDelete;
|
2006-06-06 06:21:50 +00:00
|
|
|
var $mTokenOk = false;
|
2007-07-01 22:22:16 +00:00
|
|
|
var $mTokenOkExceptSuffix = false;
|
2006-06-07 08:28:43 +00:00
|
|
|
var $mTriedSave = false;
|
2006-05-11 22:40:38 +00:00
|
|
|
var $tooBig = false;
|
|
|
|
|
var $kblength = false;
|
|
|
|
|
var $missingComment = false;
|
|
|
|
|
var $missingSummary = false;
|
|
|
|
|
var $allowBlankSummary = false;
|
|
|
|
|
var $autoSumm = '';
|
|
|
|
|
var $hookError = '';
|
2008-08-27 05:56:34 +00:00
|
|
|
#var $mPreviewTemplates;
|
|
|
|
|
var $mParserOutput;
|
2008-07-15 08:43:40 +00:00
|
|
|
var $mBaseRevision = false;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-03-08 09:09:35 +00:00
|
|
|
# Form values
|
2006-05-11 22:40:38 +00:00
|
|
|
var $save = false, $preview = false, $diff = false;
|
|
|
|
|
var $minoredit = false, $watchthis = false, $recreate = false;
|
|
|
|
|
var $textbox1 = '', $textbox2 = '', $summary = '';
|
|
|
|
|
var $edittime = '', $section = '', $starttime = '';
|
|
|
|
|
var $oldid = 0, $editintro = '', $scrolltop = null;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-11-22 20:53:11 +00:00
|
|
|
# Placeholders for text injection by hooks (must be HTML)
|
|
|
|
|
# extensions should take care to _append_ to the present value
|
2006-11-26 13:58:40 +00:00
|
|
|
public $editFormPageTop; // Before even the preview
|
|
|
|
|
public $editFormTextTop;
|
2007-11-03 03:20:12 +00:00
|
|
|
public $editFormTextBeforeContent;
|
2006-11-26 13:58:40 +00:00
|
|
|
public $editFormTextAfterWarn;
|
|
|
|
|
public $editFormTextAfterTools;
|
|
|
|
|
public $editFormTextBottom;
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-11-03 03:20:12 +00:00
|
|
|
/* $didSave should be set to true whenever an article was succesfully altered. */
|
|
|
|
|
public $didSave = false;
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-11-03 03:20:12 +00:00
|
|
|
public $suppressIntro = false;
|
2006-11-22 20:53:11 +00:00
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
|
|
|
|
* @todo document
|
|
|
|
|
* @param $article
|
|
|
|
|
*/
|
2003-08-02 20:43:11 +00:00
|
|
|
function EditPage( $article ) {
|
2007-11-03 03:20:12 +00:00
|
|
|
$this->mArticle =& $article;
|
|
|
|
|
$this->mTitle = $article->getTitle();
|
2008-08-27 05:56:34 +00:00
|
|
|
$this->action = 'submit';
|
2006-11-22 20:53:11 +00:00
|
|
|
|
|
|
|
|
# Placeholders for text injection by hooks (empty per default)
|
2006-11-26 13:58:40 +00:00
|
|
|
$this->editFormPageTop =
|
|
|
|
|
$this->editFormTextTop =
|
2007-11-03 03:20:12 +00:00
|
|
|
$this->editFormTextBeforeContent =
|
2006-11-26 13:58:40 +00:00
|
|
|
$this->editFormTextAfterWarn =
|
|
|
|
|
$this->editFormTextAfterTools =
|
2006-11-22 20:53:11 +00:00
|
|
|
$this->editFormTextBottom = "";
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-07-05 22:45:41 +00:00
|
|
|
/**
|
|
|
|
|
* Fetch initial editing page content.
|
2008-01-24 04:33:21 +00:00
|
|
|
* @private
|
2006-07-05 22:45:41 +00:00
|
|
|
*/
|
2008-01-24 04:33:21 +00:00
|
|
|
function getContent( $def_text = '' ) {
|
2008-03-04 17:36:44 +00:00
|
|
|
global $wgOut, $wgRequest, $wgParser, $wgMessageCache;
|
2006-07-05 22:45:41 +00:00
|
|
|
|
|
|
|
|
# Get variables from query string :P
|
|
|
|
|
$section = $wgRequest->getVal( 'section' );
|
|
|
|
|
$preload = $wgRequest->getVal( 'preload' );
|
2007-03-28 19:41:53 +00:00
|
|
|
$undoafter = $wgRequest->getVal( 'undoafter' );
|
2007-03-27 21:30:39 +00:00
|
|
|
$undo = $wgRequest->getVal( 'undo' );
|
2006-07-05 22:45:41 +00:00
|
|
|
|
|
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
|
|
|
|
|
$text = '';
|
2007-11-01 17:56:19 +00:00
|
|
|
if( !$this->mTitle->exists() ) {
|
|
|
|
|
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
|
2008-03-04 17:36:44 +00:00
|
|
|
$wgMessageCache->loadAllMessages();
|
2008-04-14 07:45:50 +00:00
|
|
|
# If this is a system message, get the default text.
|
2008-08-20 21:27:12 +00:00
|
|
|
$text = wfMsgWeirdKey( $this->mTitle->getText() ) ;
|
2007-01-11 04:13:11 +00:00
|
|
|
} else {
|
|
|
|
|
# If requested, preload some text.
|
|
|
|
|
$text = $this->getPreloadedText( $preload );
|
|
|
|
|
}
|
2006-07-05 22:45:41 +00:00
|
|
|
# We used to put MediaWiki:Newarticletext here if
|
|
|
|
|
# $text was empty at this point.
|
|
|
|
|
# This is now shown above the edit box instead.
|
|
|
|
|
} else {
|
|
|
|
|
// FIXME: may be better to use Revision class directly
|
|
|
|
|
// But don't mess with it just yet. Article knows how to
|
|
|
|
|
// fetch the page record from the high-priority server,
|
|
|
|
|
// which is needed to guarantee we don't pick up lagged
|
|
|
|
|
// information.
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2006-07-05 22:45:41 +00:00
|
|
|
$text = $this->mArticle->getContent();
|
2006-11-26 10:54:01 +00:00
|
|
|
|
2007-07-06 06:52:52 +00:00
|
|
|
if ($undo > 0 && $undoafter > 0 && $undo < $undoafter) {
|
|
|
|
|
# If they got undoafter and undo round the wrong way, switch them
|
2007-07-06 07:11:58 +00:00
|
|
|
list( $undo, $undoafter ) = array( $undoafter, $undo );
|
2007-07-06 06:52:52 +00:00
|
|
|
}
|
|
|
|
|
|
2007-03-28 19:41:53 +00:00
|
|
|
if ( $undo > 0 && $undo > $undoafter ) {
|
|
|
|
|
# Undoing a specific edit overrides section editing; section-editing
|
2006-11-26 10:54:01 +00:00
|
|
|
# doesn't work with undoing.
|
2007-03-28 19:41:53 +00:00
|
|
|
if ( $undoafter ) {
|
|
|
|
|
$undorev = Revision::newFromId($undo);
|
|
|
|
|
$oldrev = Revision::newFromId($undoafter);
|
|
|
|
|
} else {
|
|
|
|
|
$undorev = Revision::newFromId($undo);
|
|
|
|
|
$oldrev = $undorev ? $undorev->getPrevious() : null;
|
|
|
|
|
}
|
2007-04-21 14:44:56 +00:00
|
|
|
|
2008-04-23 16:08:16 +00:00
|
|
|
# Sanity check, make sure it's the right page,
|
|
|
|
|
# the revisions exist and they were not deleted.
|
2006-11-26 10:54:01 +00:00
|
|
|
# Otherwise, $text will be left as-is.
|
2008-04-23 16:08:16 +00:00
|
|
|
if( !is_null( $undorev ) && !is_null( $oldrev ) &&
|
|
|
|
|
$undorev->getPage() == $oldrev->getPage() &&
|
|
|
|
|
$undorev->getPage() == $this->mArticle->getID() &&
|
|
|
|
|
!$undorev->isDeleted( Revision::DELETED_TEXT ) &&
|
|
|
|
|
!$oldrev->isDeleted( Revision::DELETED_TEXT ) ) {
|
2006-11-26 10:54:01 +00:00
|
|
|
$undorev_text = $undorev->getText();
|
2007-04-21 14:44:56 +00:00
|
|
|
$oldrev_text = $oldrev->getText();
|
|
|
|
|
$currev_text = $text;
|
2006-12-11 09:39:39 +00:00
|
|
|
|
2007-03-28 19:41:53 +00:00
|
|
|
if ( $currev_text != $undorev_text ) {
|
2008-04-23 16:08:16 +00:00
|
|
|
$result = wfMerge( $undorev_text, $oldrev_text, $currev_text, $text );
|
2006-12-11 09:39:39 +00:00
|
|
|
} else {
|
2008-04-23 16:08:16 +00:00
|
|
|
# No use doing a merge if it's just a straight revert.
|
2006-12-24 02:04:13 +00:00
|
|
|
$text = $oldrev_text;
|
2006-12-11 09:39:39 +00:00
|
|
|
$result = true;
|
|
|
|
|
}
|
2008-04-23 16:08:16 +00:00
|
|
|
if( $result ) {
|
|
|
|
|
# Inform the user of our success and set an automatic edit summary
|
|
|
|
|
$this->editFormPageTop .= $wgOut->parse( wfMsgNoTrans( 'undo-success' ) );
|
|
|
|
|
$firstrev = $oldrev->getNext();
|
|
|
|
|
# If we just undid one rev, use an autosummary
|
|
|
|
|
if( $firstrev->mId == $undo ) {
|
|
|
|
|
$this->summary = wfMsgForContent('undo-summary', $undo, $undorev->getUserText());
|
|
|
|
|
}
|
|
|
|
|
$this->formtype = 'diff';
|
|
|
|
|
} else {
|
|
|
|
|
# Warn the user that something went wrong
|
|
|
|
|
$this->editFormPageTop .= $wgOut->parse( wfMsgNoTrans( 'undo-failure' ) );
|
|
|
|
|
}
|
2007-03-05 20:58:17 +00:00
|
|
|
} else {
|
|
|
|
|
// Failed basic sanity checks.
|
|
|
|
|
// Older revisions may have been removed since the link
|
|
|
|
|
// was created, or we may simply have got bogus input.
|
2008-04-23 16:08:16 +00:00
|
|
|
$this->editFormPageTop .= $wgOut->parse( wfMsgNoTrans( 'undo-norev' ) );
|
2006-11-26 10:54:01 +00:00
|
|
|
}
|
2007-03-10 23:14:55 +00:00
|
|
|
} else if( $section != '' ) {
|
|
|
|
|
if( $section == 'new' ) {
|
|
|
|
|
$text = $this->getPreloadedText( $preload );
|
|
|
|
|
} else {
|
2007-03-14 18:20:21 +00:00
|
|
|
$text = $wgParser->getSection( $text, $section, $def_text );
|
2007-03-10 23:14:55 +00:00
|
|
|
}
|
2006-07-05 22:45:41 +00:00
|
|
|
}
|
|
|
|
|
}
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2006-07-05 22:45:41 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the contents of a page from its title and remove includeonly tags
|
|
|
|
|
*
|
|
|
|
|
* @param $preload String: the title of the page.
|
|
|
|
|
* @return string The contents of the page.
|
|
|
|
|
*/
|
2008-07-17 04:37:59 +00:00
|
|
|
protected function getPreloadedText($preload) {
|
2006-07-05 22:45:41 +00:00
|
|
|
if ( $preload === '' )
|
|
|
|
|
return '';
|
|
|
|
|
else {
|
|
|
|
|
$preloadTitle = Title::newFromText( $preload );
|
|
|
|
|
if ( isset( $preloadTitle ) && $preloadTitle->userCanRead() ) {
|
|
|
|
|
$rev=Revision::newFromTitle($preloadTitle);
|
|
|
|
|
if ( is_object( $rev ) ) {
|
|
|
|
|
$text = $rev->getText();
|
|
|
|
|
// TODO FIXME: AAAAAAAAAAA, this shouldn't be implementing
|
|
|
|
|
// its own mini-parser! -ævar
|
|
|
|
|
$text = preg_replace( '~</?includeonly>~', '', $text );
|
|
|
|
|
return $text;
|
|
|
|
|
} else
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-12-29 13:46:10 +00:00
|
|
|
/**
|
|
|
|
|
* This is the function that extracts metadata from the article body on the first view.
|
|
|
|
|
* To turn the feature on, set $wgUseMetadataEdit = true ; in LocalSettings
|
2004-12-29 14:39:43 +00:00
|
|
|
* and set $wgMetadataWhitelist to the *full* title of the template whitelist
|
2004-12-29 13:46:10 +00:00
|
|
|
*/
|
2005-06-26 23:15:39 +00:00
|
|
|
function extractMetaDataFromArticle () {
|
2004-12-29 14:39:43 +00:00
|
|
|
global $wgUseMetadataEdit , $wgMetadataWhitelist , $wgLang ;
|
2005-03-30 09:26:48 +00:00
|
|
|
$this->mMetaData = '' ;
|
2004-12-29 13:46:10 +00:00
|
|
|
if ( !$wgUseMetadataEdit ) return ;
|
2005-06-26 23:15:39 +00:00
|
|
|
if ( $wgMetadataWhitelist == '' ) return ;
|
2005-03-30 09:26:48 +00:00
|
|
|
$s = '' ;
|
2006-07-05 22:45:41 +00:00
|
|
|
$t = $this->getContent();
|
2004-12-29 13:46:10 +00:00
|
|
|
|
|
|
|
|
# MISSING : <nowiki> filtering
|
|
|
|
|
|
|
|
|
|
# Categories and language links
|
|
|
|
|
$t = explode ( "\n" , $t ) ;
|
|
|
|
|
$catlow = strtolower ( $wgLang->getNsText ( NS_CATEGORY ) ) ;
|
|
|
|
|
$cat = $ll = array() ;
|
|
|
|
|
foreach ( $t AS $key => $x )
|
|
|
|
|
{
|
|
|
|
|
$y = trim ( strtolower ( $x ) ) ;
|
2005-06-26 23:15:39 +00:00
|
|
|
while ( substr ( $y , 0 , 2 ) == '[[' )
|
2004-12-29 13:46:10 +00:00
|
|
|
{
|
2005-06-26 23:15:39 +00:00
|
|
|
$y = explode ( ']]' , trim ( $x ) ) ;
|
2004-12-29 13:46:10 +00:00
|
|
|
$first = array_shift ( $y ) ;
|
2005-06-26 23:15:39 +00:00
|
|
|
$first = explode ( ':' , $first ) ;
|
2004-12-29 13:46:10 +00:00
|
|
|
$ns = array_shift ( $first ) ;
|
2005-03-30 09:26:48 +00:00
|
|
|
$ns = trim ( str_replace ( '[' , '' , $ns ) ) ;
|
2004-12-29 13:46:10 +00:00
|
|
|
if ( strlen ( $ns ) == 2 OR strtolower ( $ns ) == $catlow )
|
|
|
|
|
{
|
2005-03-30 09:26:48 +00:00
|
|
|
$add = '[[' . $ns . ':' . implode ( ':' , $first ) . ']]' ;
|
2004-12-29 13:46:10 +00:00
|
|
|
if ( strtolower ( $ns ) == $catlow ) $cat[] = $add ;
|
|
|
|
|
else $ll[] = $add ;
|
2005-03-30 09:26:48 +00:00
|
|
|
$x = implode ( ']]' , $y ) ;
|
2004-12-29 13:46:10 +00:00
|
|
|
$t[$key] = $x ;
|
|
|
|
|
$y = trim ( strtolower ( $x ) ) ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-03-30 09:26:48 +00:00
|
|
|
if ( count ( $cat ) ) $s .= implode ( ' ' , $cat ) . "\n" ;
|
|
|
|
|
if ( count ( $ll ) ) $s .= implode ( ' ' , $ll ) . "\n" ;
|
2004-12-29 13:46:10 +00:00
|
|
|
$t = implode ( "\n" , $t ) ;
|
|
|
|
|
|
2004-12-29 14:39:43 +00:00
|
|
|
# Load whitelist
|
|
|
|
|
$sat = array () ; # stand-alone-templates; must be lowercase
|
|
|
|
|
$wl_title = Title::newFromText ( $wgMetadataWhitelist ) ;
|
|
|
|
|
$wl_article = new Article ( $wl_title ) ;
|
2006-01-13 00:29:20 +00:00
|
|
|
$wl = explode ( "\n" , $wl_article->getContent() ) ;
|
2004-12-29 14:39:43 +00:00
|
|
|
foreach ( $wl AS $x )
|
|
|
|
|
{
|
|
|
|
|
$isentry = false ;
|
|
|
|
|
$x = trim ( $x ) ;
|
2005-03-30 09:26:48 +00:00
|
|
|
while ( substr ( $x , 0 , 1 ) == '*' )
|
2004-12-29 14:39:43 +00:00
|
|
|
{
|
|
|
|
|
$isentry = true ;
|
|
|
|
|
$x = trim ( substr ( $x , 1 ) ) ;
|
|
|
|
|
}
|
|
|
|
|
if ( $isentry )
|
|
|
|
|
{
|
|
|
|
|
$sat[] = strtolower ( $x ) ;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-29 14:39:43 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-29 13:46:10 +00:00
|
|
|
# Templates, but only some
|
2005-03-30 09:26:48 +00:00
|
|
|
$t = explode ( '{{' , $t ) ;
|
2004-12-29 13:46:10 +00:00
|
|
|
$tl = array () ;
|
|
|
|
|
foreach ( $t AS $key => $x )
|
|
|
|
|
{
|
2005-03-30 09:26:48 +00:00
|
|
|
$y = explode ( '}}' , $x , 2 ) ;
|
2004-12-29 13:46:10 +00:00
|
|
|
if ( count ( $y ) == 2 )
|
|
|
|
|
{
|
|
|
|
|
$z = $y[0] ;
|
2005-03-30 09:26:48 +00:00
|
|
|
$z = explode ( '|' , $z ) ;
|
2004-12-29 13:46:10 +00:00
|
|
|
$tn = array_shift ( $z ) ;
|
|
|
|
|
if ( in_array ( strtolower ( $tn ) , $sat ) )
|
|
|
|
|
{
|
2005-03-30 09:26:48 +00:00
|
|
|
$tl[] = '{{' . $y[0] . '}}' ;
|
2004-12-29 13:46:10 +00:00
|
|
|
$t[$key] = $y[1] ;
|
2005-03-30 09:26:48 +00:00
|
|
|
$y = explode ( '}}' , $y[1] , 2 ) ;
|
2004-12-29 13:46:10 +00:00
|
|
|
}
|
2005-03-30 09:26:48 +00:00
|
|
|
else $t[$key] = '{{' . $x ;
|
2004-12-29 13:46:10 +00:00
|
|
|
}
|
2005-03-30 09:26:48 +00:00
|
|
|
else if ( $key != 0 ) $t[$key] = '{{' . $x ;
|
2004-12-29 13:46:10 +00:00
|
|
|
else $t[$key] = $x ;
|
|
|
|
|
}
|
2005-03-30 09:26:48 +00:00
|
|
|
if ( count ( $tl ) ) $s .= implode ( ' ' , $tl ) ;
|
|
|
|
|
$t = implode ( '' , $t ) ;
|
2004-12-29 13:46:10 +00:00
|
|
|
|
|
|
|
|
$t = str_replace ( "\n\n\n" , "\n" , $t ) ;
|
|
|
|
|
$this->mArticle->mContent = $t ;
|
|
|
|
|
$this->mMetaData = $s ;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-03-03 16:40:42 +00:00
|
|
|
protected function wasDeletedSinceLastEdit() {
|
|
|
|
|
/* Note that we rely on the logging table, which hasn't been always there,
|
|
|
|
|
* but that doesn't matter, because this only applies to brand new
|
2008-04-14 07:45:50 +00:00
|
|
|
* deletes.
|
2008-03-03 16:40:42 +00:00
|
|
|
*/
|
|
|
|
|
if ( $this->deletedSinceEdit )
|
|
|
|
|
return true;
|
|
|
|
|
if ( $this->mTitle->isDeleted() ) {
|
|
|
|
|
$this->lastDelete = $this->getLastDelete();
|
|
|
|
|
if ( !is_null($this->lastDelete) ) {
|
|
|
|
|
$deletetime = $this->lastDelete->log_timestamp;
|
|
|
|
|
if ( ($deletetime - $this->starttime) > 0 ) {
|
|
|
|
|
$this->deletedSinceEdit = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $this->deletedSinceEdit;
|
|
|
|
|
}
|
2004-12-29 13:46:10 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
function submit() {
|
|
|
|
|
$this->edit();
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
2006-01-07 13:09:30 +00:00
|
|
|
* This is the function that gets called for "action=edit". It
|
|
|
|
|
* sets up various member variables, then passes execution to
|
2005-08-20 06:57:21 +00:00
|
|
|
* another function, usually showEditForm()
|
2006-01-07 13:09:30 +00:00
|
|
|
*
|
2005-08-20 06:57:21 +00:00
|
|
|
* The edit form is self-submitting, so that when things like
|
|
|
|
|
* preview and edit conflicts occur, we get the same form back
|
|
|
|
|
* with the extra stuff added. Only when the final submission
|
|
|
|
|
* is made and all is well do we actually save and redirect to
|
|
|
|
|
* the newly-edited page.
|
2004-09-03 16:51:45 +00:00
|
|
|
*/
|
|
|
|
|
function edit() {
|
2008-01-25 10:34:43 +00:00
|
|
|
global $wgOut, $wgUser, $wgRequest;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-01-11 20:51:53 +00:00
|
|
|
if ( !wfRunHooks( 'AlternateEdit', array( &$this ) ) )
|
2005-11-10 10:30:25 +00:00
|
|
|
return;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-01-11 20:51:53 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
wfDebug( __METHOD__.": enter\n" );
|
2005-08-21 04:45:28 +00:00
|
|
|
|
2004-01-29 22:36:02 +00:00
|
|
|
// this is not an article
|
2008-08-20 21:27:12 +00:00
|
|
|
$wgOut->setArticleFlag( false );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-03-08 09:09:35 +00:00
|
|
|
$this->importFormData( $wgRequest );
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->firsttime = false;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 02:36:04 +00:00
|
|
|
if( $this->live ) {
|
|
|
|
|
$this->livePreview();
|
2008-01-11 20:51:53 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2004-12-19 02:36:04 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-01-15 01:55:48 +00:00
|
|
|
if( wfReadOnly() ) {
|
2008-08-20 21:27:12 +00:00
|
|
|
if( $this->save ){
|
|
|
|
|
// Force preview
|
|
|
|
|
$this->save = false;
|
|
|
|
|
$this->preview = true;
|
|
|
|
|
} elseif( $this->preview || $this->diff ){
|
|
|
|
|
// A warning will be displayed instead
|
|
|
|
|
} else {
|
|
|
|
|
$this->readOnlyPage( $this->getContent() );
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2008-01-15 01:55:48 +00:00
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2008-08-20 21:27:12 +00:00
|
|
|
$wgOut->addScriptFile( 'edit.js' );
|
|
|
|
|
|
|
|
|
|
$permErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $wgUser );
|
2008-05-23 10:34:11 +00:00
|
|
|
|
2008-01-02 01:39:05 +00:00
|
|
|
if( !$this->mTitle->exists() ) {
|
2008-04-14 07:45:50 +00:00
|
|
|
$permErrors = array_merge( $permErrors,
|
2008-08-20 21:27:12 +00:00
|
|
|
wfArrayDiff2( $this->mTitle->getUserPermissionsErrors( 'create', $wgUser ), $permErrors ) );
|
2008-01-02 01:39:05 +00:00
|
|
|
}
|
2007-08-03 09:27:28 +00:00
|
|
|
|
|
|
|
|
# Ignore some permissions errors.
|
|
|
|
|
$remove = array();
|
|
|
|
|
foreach( $permErrors as $error ) {
|
2008-02-21 09:32:59 +00:00
|
|
|
if ( ( $this->preview || $this->diff ) &&
|
2007-08-03 09:27:28 +00:00
|
|
|
($error[0] == 'blockedtext' || $error[0] == 'autoblockedtext'))
|
|
|
|
|
{
|
|
|
|
|
// Don't worry about blocks when previewing/diffing
|
|
|
|
|
$remove[] = $error;
|
|
|
|
|
}
|
2003-08-05 11:04:02 +00:00
|
|
|
}
|
2008-02-21 09:32:59 +00:00
|
|
|
$permErrors = wfArrayDiff2( $permErrors, $remove );
|
2008-05-23 10:34:11 +00:00
|
|
|
|
2008-02-21 09:32:59 +00:00
|
|
|
if ( $permErrors ) {
|
2008-01-11 20:51:53 +00:00
|
|
|
wfDebug( __METHOD__.": User can't edit\n" );
|
2008-05-23 10:34:11 +00:00
|
|
|
$this->readOnlyPage( $this->getContent(), true, $permErrors, 'edit' );
|
2008-01-11 20:51:53 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-12-05 05:37:10 +00:00
|
|
|
return;
|
2005-08-20 06:57:21 +00:00
|
|
|
} else {
|
|
|
|
|
if ( $this->save ) {
|
|
|
|
|
$this->formtype = 'save';
|
2008-08-20 21:27:12 +00:00
|
|
|
} else if( $this->preview ) {
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->formtype = 'preview';
|
|
|
|
|
} else if ( $this->diff ) {
|
|
|
|
|
$this->formtype = 'diff';
|
|
|
|
|
} else { # First time through
|
|
|
|
|
$this->firsttime = true;
|
|
|
|
|
if( $this->previewOnOpen() ) {
|
|
|
|
|
$this->formtype = 'preview';
|
|
|
|
|
} else {
|
|
|
|
|
$this->extractMetaDataFromArticle () ;
|
|
|
|
|
$this->formtype = 'initial';
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
2005-08-21 04:45:28 +00:00
|
|
|
|
2008-01-11 20:51:53 +00:00
|
|
|
wfProfileIn( __METHOD__."-business-end" );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->isConflict = false;
|
|
|
|
|
// css / js subpages of user pages get a special treatment
|
2007-11-03 03:20:12 +00:00
|
|
|
$this->isCssJsSubpage = $this->mTitle->isCssJsSubpage();
|
|
|
|
|
$this->isValidCssJsSubpage = $this->mTitle->isValidCssJsSubpage();
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2007-06-11 11:57:20 +00:00
|
|
|
# Show applicable editing introductions
|
|
|
|
|
if( $this->formtype == 'initial' || $this->firsttime )
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->showIntro();
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-11-01 17:56:19 +00:00
|
|
|
if( $this->mTitle->isTalkPage() ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'talkpagetext' );
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
|
|
|
|
|
2008-08-11 08:30:29 +00:00
|
|
|
# Optional notices on a per-namespace and per-page basis
|
|
|
|
|
$editnotice_ns = 'editnotice-'.$this->mTitle->getNamespace();
|
|
|
|
|
$editnotice_page = $editnotice_ns.'-'.$this->mTitle->getDBkey();
|
|
|
|
|
if ( !wfEmptyMsg( $editnotice_ns, wfMsgForContent( $editnotice_ns ) ) ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsgForContent( $editnotice_ns ) );
|
|
|
|
|
}
|
|
|
|
|
if ( MWNamespace::hasSubpages( $this->mTitle->getNamespace() ) ) {
|
|
|
|
|
$parts = explode( '/', $this->mTitle->getDBkey() );
|
|
|
|
|
$editnotice_base = $editnotice_ns;
|
|
|
|
|
while ( count( $parts ) > 0 ) {
|
|
|
|
|
$editnotice_base .= '-'.array_shift( $parts );
|
|
|
|
|
if ( !wfEmptyMsg( $editnotice_base, wfMsgForContent( $editnotice_base ) ) ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsgForContent( $editnotice_base ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if ( !wfEmptyMsg( $editnotice_page, wfMsgForContent( $editnotice_page ) ) ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsgForContent( $editnotice_page ) );
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# Attempt submission here. This will check for edit conflicts,
|
|
|
|
|
# and redundantly check for locked database, blocked IPs, etc.
|
|
|
|
|
# that edit() already checked just in case someone tries to sneak
|
|
|
|
|
# in the back door with a hand-edited submission URL.
|
|
|
|
|
|
|
|
|
|
if ( 'save' == $this->formtype ) {
|
|
|
|
|
if ( !$this->attemptSave() ) {
|
2008-01-11 20:51:53 +00:00
|
|
|
wfProfileOut( __METHOD__."-business-end" );
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
2005-08-20 06:57:21 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# First time through: get contents, set time for conflict
|
|
|
|
|
# checking, etc.
|
|
|
|
|
if ( 'initial' == $this->formtype || $this->firsttime ) {
|
2007-03-14 18:20:21 +00:00
|
|
|
if ($this->initialiseForm() === false) {
|
|
|
|
|
$this->noSuchSectionPage();
|
2008-01-11 20:51:53 +00:00
|
|
|
wfProfileOut( __METHOD__."-business-end" );
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
2007-03-14 18:20:21 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
if( !$this->mTitle->getArticleId() )
|
2007-11-01 17:56:19 +00:00
|
|
|
wfRunHooks( 'EditFormPreloadText', array( &$this->textbox1, &$this->mTitle ) );
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->showEditForm();
|
2008-01-11 20:51:53 +00:00
|
|
|
wfProfileOut( __METHOD__."-business-end" );
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-02-21 09:32:59 +00:00
|
|
|
/**
|
|
|
|
|
* Show a read-only error
|
|
|
|
|
* Parameters are the same as OutputPage:readOnlyPage()
|
2008-02-26 06:10:24 +00:00
|
|
|
* Redirect to the article page if redlink=1
|
2008-02-21 09:32:59 +00:00
|
|
|
*/
|
2008-05-23 10:34:11 +00:00
|
|
|
function readOnlyPage( $source = null, $protected = false, $reasons = array(), $action = null ) {
|
2008-02-21 09:32:59 +00:00
|
|
|
global $wgRequest, $wgOut;
|
2008-02-26 06:10:24 +00:00
|
|
|
if ( $wgRequest->getBool( 'redlink' ) ) {
|
2008-02-21 09:32:59 +00:00
|
|
|
// The edit page was reached via a red link.
|
2008-04-14 07:45:50 +00:00
|
|
|
// Redirect to the article page and let them click the edit tab if
|
2008-02-21 09:32:59 +00:00
|
|
|
// they really want a permission error.
|
|
|
|
|
$wgOut->redirect( $this->mTitle->getFullUrl() );
|
|
|
|
|
} else {
|
2008-05-23 10:34:11 +00:00
|
|
|
$wgOut->readOnlyPage( $source, $protected, $reasons, $action );
|
2008-02-21 09:32:59 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-06-30 06:51:43 +00:00
|
|
|
/**
|
2007-07-10 19:23:01 +00:00
|
|
|
* Should we show a preview when the edit form is first shown?
|
|
|
|
|
*
|
2005-06-30 06:51:43 +00:00
|
|
|
* @return bool
|
|
|
|
|
*/
|
2008-07-17 04:37:59 +00:00
|
|
|
protected function previewOnOpen() {
|
2007-07-10 19:23:01 +00:00
|
|
|
global $wgRequest, $wgUser;
|
|
|
|
|
if( $wgRequest->getVal( 'preview' ) == 'yes' ) {
|
|
|
|
|
// Explicit override from request
|
|
|
|
|
return true;
|
|
|
|
|
} elseif( $wgRequest->getVal( 'preview' ) == 'no' ) {
|
|
|
|
|
// Explicit override from request
|
|
|
|
|
return false;
|
|
|
|
|
} elseif( $this->section == 'new' ) {
|
|
|
|
|
// Nothing *to* preview for new sections
|
|
|
|
|
return false;
|
2007-11-01 17:56:19 +00:00
|
|
|
} elseif( ( $wgRequest->getVal( 'preload' ) !== '' || $this->mTitle->exists() ) && $wgUser->getOption( 'previewonfirst' ) ) {
|
2007-07-10 19:23:01 +00:00
|
|
|
// Standard preference behaviour
|
|
|
|
|
return true;
|
2007-11-01 17:56:19 +00:00
|
|
|
} elseif( !$this->mTitle->exists() && $this->mTitle->getNamespace() == NS_CATEGORY ) {
|
2007-07-10 19:23:01 +00:00
|
|
|
// Categories are special
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2005-06-30 06:51:43 +00:00
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
|
|
|
|
* @todo document
|
2006-04-19 15:46:24 +00:00
|
|
|
* @param $request
|
2004-09-03 16:51:45 +00:00
|
|
|
*/
|
2004-03-08 09:09:35 +00:00
|
|
|
function importFormData( &$request ) {
|
2006-04-12 02:49:14 +00:00
|
|
|
global $wgLang, $wgUser;
|
2005-08-21 04:45:28 +00:00
|
|
|
$fname = 'EditPage::importFormData';
|
|
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
2008-02-26 22:40:59 +00:00
|
|
|
# Section edit can come from either the form or a link
|
|
|
|
|
$this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
|
|
|
|
|
|
2005-02-15 00:24:49 +00:00
|
|
|
if( $request->wasPosted() ) {
|
|
|
|
|
# These fields need to be checked for encoding.
|
|
|
|
|
# Also remove trailing whitespace, but don't remove _initial_
|
|
|
|
|
# whitespace from the text boxes. This may be significant formatting.
|
2005-07-29 10:08:41 +00:00
|
|
|
$this->textbox1 = $this->safeUnicodeInput( $request, 'wpTextbox1' );
|
|
|
|
|
$this->textbox2 = $this->safeUnicodeInput( $request, 'wpTextbox2' );
|
2008-04-06 17:52:55 +00:00
|
|
|
$this->mMetaData = rtrim( $request->getText( 'metadata' ) );
|
2005-10-08 22:33:46 +00:00
|
|
|
# Truncate for whole multibyte characters. +5 bytes for ellipsis
|
2008-04-06 17:52:55 +00:00
|
|
|
$this->summary = $wgLang->truncate( $request->getText( 'wpSummary' ), 250 );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-04-06 17:58:21 +00:00
|
|
|
# Remove extra headings from summaries and new sections.
|
2008-04-08 18:04:55 +00:00
|
|
|
$this->summary = preg_replace('/^\s*=+\s*(.*?)\s*=+\s*$/', '$1', $this->summary);
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-02-15 00:24:49 +00:00
|
|
|
$this->edittime = $request->getVal( 'wpEdittime' );
|
2005-08-02 20:17:23 +00:00
|
|
|
$this->starttime = $request->getVal( 'wpStarttime' );
|
2005-10-26 10:59:44 +00:00
|
|
|
|
2005-10-26 20:37:10 +00:00
|
|
|
$this->scrolltop = $request->getIntOrNull( 'wpScrolltop' );
|
2005-10-26 10:59:44 +00:00
|
|
|
|
2005-02-15 00:24:49 +00:00
|
|
|
if( is_null( $this->edittime ) ) {
|
|
|
|
|
# If the form is incomplete, force to preview.
|
2005-10-22 20:52:30 +00:00
|
|
|
wfDebug( "$fname: Form data appears to be incomplete\n" );
|
|
|
|
|
wfDebug( "POST DATA: " . var_export( $_POST, true ) . "\n" );
|
2005-02-15 00:24:49 +00:00
|
|
|
$this->preview = true;
|
|
|
|
|
} else {
|
2006-02-20 21:18:11 +00:00
|
|
|
/* Fallback for live preview */
|
|
|
|
|
$this->preview = $request->getCheck( 'wpPreview' ) || $request->getCheck( 'wpLivePreview' );
|
2005-10-31 22:36:35 +00:00
|
|
|
$this->diff = $request->getCheck( 'wpDiff' );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2006-06-07 08:28:43 +00:00
|
|
|
// Remember whether a save was requested, so we can indicate
|
|
|
|
|
// if we forced preview due to session failure.
|
|
|
|
|
$this->mTriedSave = !$this->preview;
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2006-06-06 06:21:50 +00:00
|
|
|
if ( $this->tokenOk( $request ) ) {
|
|
|
|
|
# Some browsers will not report any submit button
|
|
|
|
|
# if the user hits enter in the comment box.
|
|
|
|
|
# The unmarked state will be assumed to be a save,
|
|
|
|
|
# if the form seems otherwise complete.
|
|
|
|
|
wfDebug( "$fname: Passed token check.\n" );
|
2006-10-25 08:31:44 +00:00
|
|
|
} else if ( $this->diff ) {
|
|
|
|
|
# Failed token check, but only requested "Show Changes".
|
|
|
|
|
wfDebug( "$fname: Failed token check; Show Changes requested.\n" );
|
2006-06-06 06:21:50 +00:00
|
|
|
} else {
|
|
|
|
|
# Page might be a hack attempt posted from
|
|
|
|
|
# an external site. Preview instead of saving.
|
|
|
|
|
wfDebug( "$fname: Failed token check; forcing preview\n" );
|
|
|
|
|
$this->preview = true;
|
2005-02-15 00:24:49 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-04-06 17:52:55 +00:00
|
|
|
$this->save = !$this->preview && !$this->diff;
|
2005-02-15 00:24:49 +00:00
|
|
|
if( !preg_match( '/^\d{14}$/', $this->edittime )) {
|
|
|
|
|
$this->edittime = null;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-08-02 20:17:23 +00:00
|
|
|
if( !preg_match( '/^\d{14}$/', $this->starttime )) {
|
|
|
|
|
$this->starttime = null;
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-02 20:17:23 +00:00
|
|
|
$this->recreate = $request->getCheck( 'wpRecreate' );
|
|
|
|
|
|
2005-02-15 00:24:49 +00:00
|
|
|
$this->minoredit = $request->getCheck( 'wpMinoredit' );
|
|
|
|
|
$this->watchthis = $request->getCheck( 'wpWatchthis' );
|
2006-04-12 02:49:14 +00:00
|
|
|
|
|
|
|
|
# Don't force edit summaries when a user is editing their own user or talk page
|
2007-11-01 17:56:19 +00:00
|
|
|
if( ( $this->mTitle->mNamespace == NS_USER || $this->mTitle->mNamespace == NS_USER_TALK ) && $this->mTitle->getText() == $wgUser->getName() ) {
|
2006-04-12 02:49:14 +00:00
|
|
|
$this->allowBlankSummary = true;
|
|
|
|
|
} else {
|
|
|
|
|
$this->allowBlankSummary = $request->getBool( 'wpIgnoreBlankSummary' );
|
|
|
|
|
}
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2008-04-14 07:45:50 +00:00
|
|
|
$this->autoSumm = $request->getText( 'wpAutoSummary' );
|
2005-02-15 00:24:49 +00:00
|
|
|
} else {
|
|
|
|
|
# Not a posted form? Start with nothing.
|
2005-10-22 20:52:30 +00:00
|
|
|
wfDebug( "$fname: Not a posted form.\n" );
|
2005-02-15 00:24:49 +00:00
|
|
|
$this->textbox1 = '';
|
|
|
|
|
$this->textbox2 = '';
|
|
|
|
|
$this->mMetaData = '';
|
|
|
|
|
$this->summary = '';
|
|
|
|
|
$this->edittime = '';
|
2005-08-02 20:17:23 +00:00
|
|
|
$this->starttime = wfTimestampNow();
|
2007-08-29 18:11:17 +00:00
|
|
|
$this->edit = false;
|
2005-02-15 00:24:49 +00:00
|
|
|
$this->preview = false;
|
|
|
|
|
$this->save = false;
|
2007-08-29 18:11:17 +00:00
|
|
|
$this->diff = false;
|
2005-02-15 00:24:49 +00:00
|
|
|
$this->minoredit = false;
|
|
|
|
|
$this->watchthis = false;
|
2005-08-02 20:17:23 +00:00
|
|
|
$this->recreate = false;
|
2008-02-26 22:40:59 +00:00
|
|
|
|
|
|
|
|
if ( $this->section == 'new' && $request->getVal( 'preloadtitle' ) ) {
|
|
|
|
|
$this->summary = $request->getVal( 'preloadtitle' );
|
|
|
|
|
}
|
2005-02-15 00:24:49 +00:00
|
|
|
}
|
2004-03-18 06:56:14 +00:00
|
|
|
|
2004-03-08 09:09:35 +00:00
|
|
|
$this->oldid = $request->getInt( 'oldid' );
|
2004-03-18 06:56:14 +00:00
|
|
|
|
2004-12-19 02:36:04 +00:00
|
|
|
$this->live = $request->getCheck( 'live' );
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->editintro = $request->getText( 'editintro' );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2004-03-08 09:09:35 +00:00
|
|
|
}
|
2004-03-18 06:56:14 +00:00
|
|
|
|
2005-02-04 06:19:37 +00:00
|
|
|
/**
|
2005-02-15 00:24:49 +00:00
|
|
|
* Make sure the form isn't faking a user's credentials.
|
|
|
|
|
*
|
2006-04-19 15:46:24 +00:00
|
|
|
* @param $request WebRequest
|
2005-02-15 00:24:49 +00:00
|
|
|
* @return bool
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-02-04 06:19:37 +00:00
|
|
|
*/
|
2005-02-15 00:24:49 +00:00
|
|
|
function tokenOk( &$request ) {
|
|
|
|
|
global $wgUser;
|
2007-07-01 22:22:16 +00:00
|
|
|
$token = $request->getVal( 'wpEditToken' );
|
|
|
|
|
$this->mTokenOk = $wgUser->matchEditToken( $token );
|
|
|
|
|
$this->mTokenOkExceptSuffix = $wgUser->matchEditTokenNoSuffix( $token );
|
2005-10-31 22:36:35 +00:00
|
|
|
return $this->mTokenOk;
|
2005-02-15 00:24:49 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2007-06-11 11:57:20 +00:00
|
|
|
/**
|
|
|
|
|
* Show all applicable editing introductions
|
|
|
|
|
*/
|
2008-07-17 04:37:59 +00:00
|
|
|
protected function showIntro() {
|
2005-10-06 01:07:25 +00:00
|
|
|
global $wgOut, $wgUser;
|
2007-11-27 18:04:24 +00:00
|
|
|
if( $this->suppressIntro )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
# Show a warning message when someone creates/edits a user (talk) page but the user does not exists
|
|
|
|
|
if( $this->mTitle->getNamespace() == NS_USER || $this->mTitle->getNamespace() == NS_USER_TALK ) {
|
2007-11-29 07:01:30 +00:00
|
|
|
$parts = explode( '/', $this->mTitle->getText(), 2 );
|
|
|
|
|
$username = $parts[0];
|
|
|
|
|
$id = User::idFromName( $username );
|
|
|
|
|
$ip = User::isIP( $username );
|
2007-11-27 18:04:24 +00:00
|
|
|
|
|
|
|
|
if ( $id == 0 && !$ip ) {
|
2008-04-14 07:45:50 +00:00
|
|
|
$wgOut->wrapWikiMsg( '<div class="mw-userpage-userdoesnotexist error">$1</div>',
|
2008-02-18 07:25:35 +00:00
|
|
|
array( 'userpage-userdoesnotexist', $username ) );
|
2007-11-27 18:04:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-30 00:29:46 +00:00
|
|
|
if( !$this->mTitle->exists() && !$this->showCustomIntro() ) {
|
2007-06-11 11:57:20 +00:00
|
|
|
if( $wgUser->isLoggedIn() ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->wrapWikiMsg( '<div class="mw-newarticletext">$1</div>', 'newarticletext' );
|
2007-06-11 11:57:20 +00:00
|
|
|
} else {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->wrapWikiMsg( '<div class="mw-newarticletextanon">$1</div>', 'newarticletextanon' );
|
2007-06-11 11:57:20 +00:00
|
|
|
}
|
2007-06-12 20:18:13 +00:00
|
|
|
$this->showDeletionLog( $wgOut );
|
2007-06-11 11:57:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
2007-11-27 18:04:24 +00:00
|
|
|
|
2007-06-11 11:57:20 +00:00
|
|
|
/**
|
|
|
|
|
* Attempt to show a custom editing introduction, if supplied
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2008-07-17 04:37:59 +00:00
|
|
|
protected function showCustomIntro() {
|
2007-06-11 11:57:20 +00:00
|
|
|
if( $this->editintro ) {
|
|
|
|
|
$title = Title::newFromText( $this->editintro );
|
|
|
|
|
if( $title instanceof Title && $title->exists() && $title->userCanRead() ) {
|
2007-06-12 19:49:38 +00:00
|
|
|
global $wgOut;
|
2007-06-11 11:57:20 +00:00
|
|
|
$revision = Revision::newFromTitle( $title );
|
2008-03-24 15:04:55 +00:00
|
|
|
$wgOut->addWikiTextTitleTidy( $revision->getText(), $this->mTitle );
|
2007-06-11 11:57:20 +00:00
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
2007-10-30 05:42:19 +00:00
|
|
|
* Attempt submission (no UI)
|
|
|
|
|
* @return one of the constants describing the result
|
2004-09-03 16:51:45 +00:00
|
|
|
*/
|
2008-01-10 13:33:23 +00:00
|
|
|
function internalAttemptSave( &$result, $bot = false ) {
|
2008-08-19 20:32:30 +00:00
|
|
|
global $wgFilterCallback, $wgUser, $wgOut, $wgParser;
|
2008-01-25 10:34:43 +00:00
|
|
|
global $wgMaxArticleSize;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-21 04:45:28 +00:00
|
|
|
$fname = 'EditPage::attemptSave';
|
|
|
|
|
wfProfileIn( $fname );
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileIn( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
|
2006-12-01 21:18:40 +00:00
|
|
|
if( !wfRunHooks( 'EditPage::attemptSave', array( &$this ) ) )
|
|
|
|
|
{
|
|
|
|
|
wfDebug( "Hook 'EditPage::attemptSave' aborted article saving" );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_HOOK_ERROR;
|
2006-12-01 21:18:40 +00:00
|
|
|
}
|
|
|
|
|
|
2008-01-20 07:05:59 +00:00
|
|
|
# Check image redirect
|
2008-01-25 10:34:43 +00:00
|
|
|
if ( $this->mTitle->getNamespace() == NS_IMAGE &&
|
2008-01-20 07:05:59 +00:00
|
|
|
Title::newFromRedirect( $this->textbox1 ) instanceof Title &&
|
|
|
|
|
!$wgUser->isAllowed( 'upload' ) ) {
|
|
|
|
|
if( $wgUser->isAnon() ) {
|
|
|
|
|
return self::AS_IMAGE_REDIRECT_ANON;
|
|
|
|
|
} else {
|
|
|
|
|
return self::AS_IMAGE_REDIRECT_LOGGED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# Reintegrate metadata
|
|
|
|
|
if ( $this->mMetaData != '' ) $this->textbox1 .= "\n" . $this->mMetaData ;
|
|
|
|
|
$this->mMetaData = '' ;
|
2005-08-02 20:17:23 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# Check for spam
|
2008-08-19 20:32:30 +00:00
|
|
|
$match = self::matchSpamRegex( $this->summary );
|
|
|
|
|
if( $match === false ) {
|
|
|
|
|
$match = self::matchSpamRegex( $this->textbox1 );
|
|
|
|
|
}
|
|
|
|
|
if( $match !== false ) {
|
|
|
|
|
$result['spam'] = $match;
|
2008-06-19 23:33:45 +00:00
|
|
|
$ip = wfGetIP();
|
|
|
|
|
$pdbk = $this->mTitle->getPrefixedDBkey();
|
2008-08-19 20:32:30 +00:00
|
|
|
$match = str_replace( "\n", '', $match );
|
2008-06-19 23:33:45 +00:00
|
|
|
wfDebugLog( 'SpamRegex', "$ip spam regex hit [[$pdbk]]: \"$match\"" );
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_SPAM_ERROR;
|
2005-08-02 20:17:23 +00:00
|
|
|
}
|
2008-06-21 03:21:02 +00:00
|
|
|
if ( $wgFilterCallback && $wgFilterCallback( $this->mTitle, $this->textbox1, $this->section, $this->hookError, $this->summary ) ) {
|
2005-08-20 06:57:21 +00:00
|
|
|
# Error messages or other handling should be performed by the filter function
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2007-10-31 11:30:15 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_FILTERING;
|
2004-03-05 21:44:38 +00:00
|
|
|
}
|
2008-06-19 03:14:05 +00:00
|
|
|
if ( !wfRunHooks( 'EditFilter', array( $this, $this->textbox1, $this->section, &$this->hookError, $this->summary ) ) ) {
|
2006-05-06 21:41:53 +00:00
|
|
|
# Error messages etc. could be handled within the hook...
|
2005-09-29 23:35:31 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2007-10-31 11:30:15 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_HOOK_ERROR;
|
2006-05-06 21:41:53 +00:00
|
|
|
} elseif( $this->hookError != '' ) {
|
|
|
|
|
# ...or the hook could be expecting us to produce an error
|
2007-10-31 11:30:15 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2006-05-06 21:41:53 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_HOOK_ERROR_EXPECTED;
|
2005-09-29 23:35:31 +00:00
|
|
|
}
|
2008-01-25 10:34:43 +00:00
|
|
|
if ( $wgUser->isBlockedFrom( $this->mTitle, false ) ) {
|
2005-08-20 06:57:21 +00:00
|
|
|
# Check block state against master, thus 'false'.
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_BLOCKED_PAGE_FOR_USER;
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2006-02-22 00:55:25 +00:00
|
|
|
$this->kblength = (int)(strlen( $this->textbox1 ) / 1024);
|
|
|
|
|
if ( $this->kblength > $wgMaxArticleSize ) {
|
|
|
|
|
// Error will be displayed by showEditForm()
|
|
|
|
|
$this->tooBig = true;
|
|
|
|
|
wfProfileOut( "$fname-checks" );
|
|
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_CONTENT_TOO_BIG;
|
2006-02-22 00:55:25 +00:00
|
|
|
}
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( !$wgUser->isAllowed('edit') ) {
|
|
|
|
|
if ( $wgUser->isAnon() ) {
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_READ_ONLY_PAGE_ANON;
|
2003-08-05 11:04:02 +00:00
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
else {
|
2005-09-11 11:25:55 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_READ_ONLY_PAGE_LOGGED;
|
2005-05-27 11:03:37 +00:00
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
New edit toolbar for bold, italic, links, headlines, math, images, media,
sigs, horizontal lines (more can be added easily). Select text and click
to apply, or just click to see an example. Mouseover should show speedtips.
Also, access keys for the edit window (ALT+P=Preview, ALT+S=Save) -> Moz+IE
2004-01-11 04:11:43 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( wfReadOnly() ) {
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_READ_ONLY_PAGE;
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
|
|
|
|
if ( $wgUser->pingLimiter() ) {
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_RATE_LIMITED;
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# If the article has been deleted while editing, don't save it without
|
|
|
|
|
# confirmation
|
2008-03-03 16:40:42 +00:00
|
|
|
if ( $this->wasDeletedSinceLastEdit() && !$this->recreate ) {
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_ARTICLE_WAS_DELETED;
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# If article is new, insert it.
|
2007-11-01 17:56:19 +00:00
|
|
|
$aid = $this->mTitle->getArticleID( GAID_FOR_UPDATE );
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( 0 == $aid ) {
|
2006-12-01 21:18:40 +00:00
|
|
|
|
2005-12-05 05:37:10 +00:00
|
|
|
// Late check for create permission, just in case *PARANOIA*
|
2007-11-01 17:56:19 +00:00
|
|
|
if ( !$this->mTitle->userCan( 'create' ) ) {
|
2005-12-05 05:37:10 +00:00
|
|
|
wfDebug( "$fname: no create permission\n" );
|
|
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_NO_CREATE_PERMISSION;
|
2005-12-05 05:37:10 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# Don't save a new article if it's blank.
|
2008-01-24 01:59:35 +00:00
|
|
|
if ( '' == $this->textbox1 ) {
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_BLANK_ARTICLE;
|
2005-09-04 17:41:44 +00:00
|
|
|
}
|
2005-08-23 08:15:14 +00:00
|
|
|
|
2007-11-12 07:30:40 +00:00
|
|
|
// Run post-section-merge edit filter
|
2008-06-19 03:14:05 +00:00
|
|
|
if ( !wfRunHooks( 'EditFilterMerged', array( $this, $this->textbox1, &$this->hookError, $this->summary ) ) ) {
|
2007-11-12 07:30:40 +00:00
|
|
|
# Error messages etc. could be handled within the hook...
|
|
|
|
|
wfProfileOut( $fname );
|
2008-01-25 16:07:45 +00:00
|
|
|
return self::AS_HOOK_ERROR;
|
2007-11-12 07:30:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$isComment = ( $this->section == 'new' );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2005-08-23 08:15:14 +00:00
|
|
|
$this->mArticle->insertNewArticle( $this->textbox1, $this->summary,
|
2008-01-10 13:33:23 +00:00
|
|
|
$this->minoredit, $this->watchthis, false, $isComment, $bot);
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_SUCCESS_NEW_ARTICLE;
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2004-03-18 15:02:56 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# Article exists. Check for edit conflict.
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->mArticle->clear(); # Force reload of dates, etc.
|
|
|
|
|
$this->mArticle->forUpdate( true ); # Lock the article
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2007-03-11 03:59:37 +00:00
|
|
|
wfDebug("timestamp: {$this->mArticle->getTimestamp()}, edittime: {$this->edittime}\n");
|
|
|
|
|
|
2005-12-11 12:07:18 +00:00
|
|
|
if( $this->mArticle->getTimestamp() != $this->edittime ) {
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->isConflict = true;
|
2005-12-11 15:09:44 +00:00
|
|
|
if( $this->section == 'new' ) {
|
2005-12-11 12:07:18 +00:00
|
|
|
if( $this->mArticle->getUserText() == $wgUser->getName() &&
|
|
|
|
|
$this->mArticle->getComment() == $this->summary ) {
|
|
|
|
|
// Probably a duplicate submission of a new comment.
|
|
|
|
|
// This can happen when squid resends a request after
|
|
|
|
|
// a timeout but the first one actually went through.
|
|
|
|
|
wfDebug( "EditPage::editForm duplicate new section submission; trigger edit conflict!\n" );
|
|
|
|
|
} else {
|
|
|
|
|
// New comment; suppress conflict.
|
|
|
|
|
$this->isConflict = false;
|
|
|
|
|
wfDebug( "EditPage::editForm conflict suppressed; new section\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2008-05-22 16:39:43 +00:00
|
|
|
$userid = $wgUser->getId();
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->isConflict) {
|
|
|
|
|
wfDebug( "EditPage::editForm conflict! getting section '$this->section' for time '$this->edittime' (article time '" .
|
2007-07-25 01:53:04 +00:00
|
|
|
$this->mArticle->getTimestamp() . "')\n" );
|
2005-08-21 07:28:11 +00:00
|
|
|
$text = $this->mArticle->replaceSection( $this->section, $this->textbox1, $this->summary, $this->edittime);
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
wfDebug( "EditPage::editForm getting section '$this->section'\n" );
|
2005-08-21 07:28:11 +00:00
|
|
|
$text = $this->mArticle->replaceSection( $this->section, $this->textbox1, $this->summary);
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2005-10-28 07:07:21 +00:00
|
|
|
if( is_null( $text ) ) {
|
|
|
|
|
wfDebug( "EditPage::editForm activating conflict; section replace failed.\n" );
|
|
|
|
|
$this->isConflict = true;
|
|
|
|
|
$text = $this->textbox1;
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2005-09-02 01:17:00 +00:00
|
|
|
# Suppress edit conflict with self, except for section edits where merging is required.
|
|
|
|
|
if ( ( $this->section == '' ) && ( 0 != $userid ) && ( $this->mArticle->getUser() == $userid ) ) {
|
2007-07-25 01:53:04 +00:00
|
|
|
wfDebug( "EditPage::editForm Suppressing edit conflict, same user.\n" );
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->isConflict = false;
|
|
|
|
|
} else {
|
|
|
|
|
# switch from section editing to normal editing in edit conflict
|
|
|
|
|
if($this->isConflict) {
|
|
|
|
|
# Attempt merge
|
|
|
|
|
if( $this->mergeChangesInto( $text ) ){
|
|
|
|
|
// Successful merge! Maybe we should tell the user the good news?
|
|
|
|
|
$this->isConflict = false;
|
2007-07-25 01:53:04 +00:00
|
|
|
wfDebug( "EditPage::editForm Suppressing edit conflict, successful merge.\n" );
|
2005-08-20 06:57:21 +00:00
|
|
|
} else {
|
|
|
|
|
$this->section = '';
|
|
|
|
|
$this->textbox1 = $text;
|
2007-07-25 01:53:04 +00:00
|
|
|
wfDebug( "EditPage::editForm Keeping edit conflict, failed merge.\n" );
|
2004-11-28 06:45:24 +00:00
|
|
|
}
|
2004-05-13 14:17:44 +00:00
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->isConflict ) {
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_CONFLICT_DETECTED;
|
2005-08-02 20:17:23 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2006-11-07 12:53:07 +00:00
|
|
|
$oldtext = $this->mArticle->getContent();
|
|
|
|
|
|
2007-11-12 07:30:40 +00:00
|
|
|
// Run post-section-merge edit filter
|
2008-06-19 03:14:05 +00:00
|
|
|
if ( !wfRunHooks( 'EditFilterMerged', array( $this, $text, &$this->hookError, $this->summary ) ) ) {
|
2007-11-12 07:30:40 +00:00
|
|
|
# Error messages etc. could be handled within the hook...
|
|
|
|
|
wfProfileOut( $fname );
|
2008-01-25 16:07:45 +00:00
|
|
|
return self::AS_HOOK_ERROR;
|
2007-11-12 07:30:40 +00:00
|
|
|
}
|
|
|
|
|
|
2006-11-07 12:53:07 +00:00
|
|
|
# Handle the user preference to force summaries here, but not for null edits
|
2008-05-24 14:55:54 +00:00
|
|
|
if( $this->section != 'new' && !$this->allowBlankSummary && $wgUser->getOption( 'forceeditsummary') &&
|
|
|
|
|
0 != strcmp($oldtext, $text) &&
|
|
|
|
|
!is_object( Title::newFromRedirect( $text ) ) # check if it's not a redirect
|
|
|
|
|
) {
|
|
|
|
|
|
2006-03-25 02:48:31 +00:00
|
|
|
if( md5( $this->summary ) == $this->autoSumm ) {
|
|
|
|
|
$this->missingSummary = true;
|
2006-11-02 13:33:38 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_SUMMARY_NEEDED;
|
2006-11-02 13:33:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-06 17:52:55 +00:00
|
|
|
# And a similar thing for new sections
|
2007-04-21 14:44:56 +00:00
|
|
|
if( $this->section == 'new' && !$this->allowBlankSummary && $wgUser->getOption( 'forceeditsummary' ) ) {
|
2006-11-02 13:33:38 +00:00
|
|
|
if (trim($this->summary) == '') {
|
|
|
|
|
$this->missingSummary = true;
|
2006-03-25 02:48:31 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_SUMMARY_NEEDED;
|
2006-03-25 02:48:31 +00:00
|
|
|
}
|
|
|
|
|
}
|
2006-03-25 00:57:14 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# All's well
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileIn( "$fname-sectionanchor" );
|
2005-08-20 06:57:21 +00:00
|
|
|
$sectionanchor = '';
|
|
|
|
|
if( $this->section == 'new' ) {
|
2006-03-01 23:00:07 +00:00
|
|
|
if ( $this->textbox1 == '' ) {
|
|
|
|
|
$this->missingComment = true;
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_TEXTBOX_EMPTY;
|
2006-03-01 23:00:07 +00:00
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
if( $this->summary != '' ) {
|
2007-09-08 02:08:08 +00:00
|
|
|
$sectionanchor = $wgParser->guessSectionNameFromWikiText( $this->summary );
|
2007-09-03 17:46:34 +00:00
|
|
|
# This is a new section, so create a link to the new section
|
|
|
|
|
# in the revision summary.
|
2007-09-08 02:08:08 +00:00
|
|
|
$cleanSummary = $wgParser->stripSectionName( $this->summary );
|
2007-09-06 16:17:09 +00:00
|
|
|
$this->summary = wfMsgForContent( 'newsectionsummary', $cleanSummary );
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
|
|
|
|
} elseif( $this->section != '' ) {
|
|
|
|
|
# Try to get a section anchor from the section source, redirect to edited section if header found
|
2005-08-21 07:28:11 +00:00
|
|
|
# XXX: might be better to integrate this into Article::replaceSection
|
2005-08-20 06:57:21 +00:00
|
|
|
# for duplicate heading checking and maybe parsing
|
|
|
|
|
$hasmatch = preg_match( "/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches );
|
|
|
|
|
# we can't deal with anchors, includes, html etc in the header for now,
|
|
|
|
|
# headline would need to be parsed to improve this
|
|
|
|
|
if($hasmatch and strlen($matches[2]) > 0) {
|
2007-09-08 02:08:08 +00:00
|
|
|
$sectionanchor = $wgParser->guessSectionNameFromWikiText( $matches[2] );
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-sectionanchor" );
|
2005-08-20 06:57:21 +00:00
|
|
|
|
|
|
|
|
// Save errors may fall down to the edit form, but we've now
|
|
|
|
|
// merged the section into full text. Clear the section field
|
|
|
|
|
// so that later submission of conflict forms won't try to
|
|
|
|
|
// replace that into a duplicated mess.
|
|
|
|
|
$this->textbox1 = $text;
|
|
|
|
|
$this->section = '';
|
|
|
|
|
|
2006-02-22 00:55:25 +00:00
|
|
|
// Check for length errors again now that the section is merged in
|
|
|
|
|
$this->kblength = (int)(strlen( $text ) / 1024);
|
|
|
|
|
if ( $this->kblength > $wgMaxArticleSize ) {
|
|
|
|
|
$this->tooBig = true;
|
|
|
|
|
wfProfileOut( $fname );
|
2008-01-25 10:34:43 +00:00
|
|
|
return self::AS_MAX_ARTICLE_SIZE_EXCEEDED;
|
2006-02-22 00:55:25 +00:00
|
|
|
}
|
|
|
|
|
|
2005-08-23 08:15:14 +00:00
|
|
|
# update the article here
|
|
|
|
|
if( $this->mArticle->updateArticle( $text, $this->summary, $this->minoredit,
|
2008-01-10 13:33:23 +00:00
|
|
|
$this->watchthis, $bot, $sectionanchor ) ) {
|
2005-08-23 08:15:14 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_SUCCESS_UPDATE;
|
2005-08-23 08:15:14 +00:00
|
|
|
} else {
|
|
|
|
|
$this->isConflict = true;
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2007-10-30 05:42:19 +00:00
|
|
|
return self::AS_END;
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2008-08-19 20:32:30 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check given input text against $wgSpamRegex, and return the text of the first match.
|
|
|
|
|
* @return mixed -- matching string or false
|
|
|
|
|
*/
|
|
|
|
|
public static function matchSpamRegex( $text ) {
|
|
|
|
|
global $wgSpamRegex;
|
|
|
|
|
if( $wgSpamRegex ) {
|
|
|
|
|
// For back compatibility, $wgSpamRegex may be a single string or an array of regexes.
|
|
|
|
|
$regexes = (array)$wgSpamRegex;
|
|
|
|
|
foreach( $regexes as $regex ) {
|
|
|
|
|
$matches = array();
|
|
|
|
|
if ( preg_match( $regex, $text, $matches ) ) {
|
|
|
|
|
return $matches[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialise form fields in the object
|
|
|
|
|
* Called on the first invocation, e.g. when a user clicks an edit link
|
|
|
|
|
*/
|
|
|
|
|
function initialiseForm() {
|
|
|
|
|
$this->edittime = $this->mArticle->getTimestamp();
|
2007-03-14 18:20:21 +00:00
|
|
|
$this->textbox1 = $this->getContent(false);
|
|
|
|
|
if ($this->textbox1 === false) return false;
|
2007-04-21 14:44:56 +00:00
|
|
|
|
2007-11-03 03:20:12 +00:00
|
|
|
if ( !$this->mArticle->exists() && $this->mTitle->getNamespace() == NS_MEDIAWIKI )
|
|
|
|
|
$this->textbox1 = wfMsgWeirdKey( $this->mTitle->getText() );
|
2006-06-01 08:19:02 +00:00
|
|
|
wfProxyCheck();
|
2007-03-14 18:20:21 +00:00
|
|
|
return true;
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
|
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
function setHeaders() {
|
|
|
|
|
global $wgOut, $wgTitle;
|
|
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
|
|
|
|
if ( $this->formtype == 'preview' ) {
|
|
|
|
|
$wgOut->setPageTitleActionText( wfMsg( 'preview' ) );
|
|
|
|
|
}
|
|
|
|
|
if ( $this->isConflict ) {
|
|
|
|
|
$wgOut->setPageTitle( wfMsg( 'editconflict', $wgTitle->getPrefixedText() ) );
|
|
|
|
|
} elseif( $this->section != '' ) {
|
|
|
|
|
$msg = $this->section == 'new' ? 'editingcomment' : 'editingsection';
|
|
|
|
|
$wgOut->setPageTitle( wfMsg( $msg, $wgTitle->getPrefixedText() ) );
|
|
|
|
|
} else {
|
|
|
|
|
# Use the title defined by DISPLAYTITLE magic word when present
|
|
|
|
|
if( isset($this->mParserOutput)
|
|
|
|
|
&& ( $dt = $this->mParserOutput->getDisplayTitle() ) !== false ) {
|
|
|
|
|
$title = $dt;
|
|
|
|
|
} else {
|
|
|
|
|
$title = $wgTitle->getPrefixedText();
|
|
|
|
|
}
|
|
|
|
|
$wgOut->setPageTitle( wfMsg( 'editing', $title ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
/**
|
|
|
|
|
* Send the edit form and related headers to $wgOut
|
2005-09-29 23:35:31 +00:00
|
|
|
* @param $formCallback Optional callable that takes an OutputPage
|
|
|
|
|
* parameter; will be called during form output
|
|
|
|
|
* near the top, for captchas and the like.
|
2005-08-20 06:57:21 +00:00
|
|
|
*/
|
2005-09-29 23:35:31 +00:00
|
|
|
function showEditForm( $formCallback=null ) {
|
2007-11-03 03:20:12 +00:00
|
|
|
global $wgOut, $wgUser, $wgLang, $wgContLang, $wgMaxArticleSize, $wgTitle;
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-03-03 16:40:42 +00:00
|
|
|
# If $wgTitle is null, that means we're in API mode.
|
|
|
|
|
# Some hook probably called this function without checking
|
|
|
|
|
# for is_null($wgTitle) first. Bail out right here so we don't
|
|
|
|
|
# do lots of work just to discard it right after.
|
|
|
|
|
if(is_null($wgTitle))
|
|
|
|
|
return;
|
2005-08-20 06:57:21 +00:00
|
|
|
|
2005-08-21 04:45:28 +00:00
|
|
|
$fname = 'EditPage::showEditForm';
|
|
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$sk = $wgUser->getSkin();
|
2006-11-08 07:12:03 +00:00
|
|
|
|
2005-12-11 11:20:12 +00:00
|
|
|
wfRunHooks( 'EditPage::showEditForm:initial', array( &$this ) ) ;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
#need to parse the preview early so that we know which templates are used,
|
|
|
|
|
#otherwise users with "show preview after edit box" will get a blank list
|
|
|
|
|
#we parse this near the beginning so that setHeaders can do the title
|
|
|
|
|
#setting work instead of leaving it in getPreviewText
|
|
|
|
|
$previewOutput = '';
|
|
|
|
|
if ( $this->formtype == 'preview' ) {
|
|
|
|
|
$previewOutput = $this->getPreviewText();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->setHeaders();
|
2004-03-18 06:56:14 +00:00
|
|
|
|
2004-01-17 09:49:43 +00:00
|
|
|
# Enabled article-related sidebar, toplinks, etc.
|
|
|
|
|
$wgOut->setArticleRelated( true );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->isConflict ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'explainconflict' );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-03-08 09:09:35 +00:00
|
|
|
$this->textbox2 = $this->textbox1;
|
2006-07-05 22:45:41 +00:00
|
|
|
$this->textbox1 = $this->getContent();
|
2004-03-08 09:09:35 +00:00
|
|
|
$this->edittime = $this->mArticle->getTimestamp();
|
2003-08-02 20:43:11 +00:00
|
|
|
} else {
|
2008-08-27 05:56:34 +00:00
|
|
|
if( $this->section != '' && $this->section != 'new' ) {
|
|
|
|
|
$matches = array();
|
|
|
|
|
if( !$this->summary && !$this->preview && !$this->diff ) {
|
|
|
|
|
preg_match( "/^(=+)(.+)\\1/mi",
|
|
|
|
|
$this->textbox1,
|
|
|
|
|
$matches );
|
|
|
|
|
if( !empty( $matches[2] ) ) {
|
|
|
|
|
global $wgParser;
|
|
|
|
|
$this->summary = "/* " .
|
|
|
|
|
$wgParser->stripSectionName(trim($matches[2])) .
|
|
|
|
|
" */ ";
|
2006-01-07 13:31:29 +00:00
|
|
|
}
|
2004-03-20 01:18:19 +00:00
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2006-03-01 23:00:07 +00:00
|
|
|
|
|
|
|
|
if ( $this->missingComment ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->wrapWikiMsg( '<div id="mw-missingcommenttext">$1</div>', 'missingcommenttext' );
|
2006-03-01 23:00:07 +00:00
|
|
|
}
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2006-11-03 01:37:06 +00:00
|
|
|
if( $this->missingSummary && $this->section != 'new' ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->wrapWikiMsg( '<div id="mw-missingsummary">$1</div>', 'missingsummary' );
|
2006-03-25 00:57:14 +00:00
|
|
|
}
|
2006-11-03 01:37:06 +00:00
|
|
|
|
2007-04-21 14:44:56 +00:00
|
|
|
if( $this->missingSummary && $this->section == 'new' ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->wrapWikiMsg( '<div id="mw-missingcommentheader">$1</div>', 'missingcommentheader' );
|
2007-04-21 14:44:56 +00:00
|
|
|
}
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2008-01-11 21:02:39 +00:00
|
|
|
if( $this->hookError !== '' ) {
|
2006-05-06 21:41:53 +00:00
|
|
|
$wgOut->addWikiText( $this->hookError );
|
|
|
|
|
}
|
2006-03-01 23:00:07 +00:00
|
|
|
|
2005-03-26 22:23:48 +00:00
|
|
|
if ( !$this->checkUnicodeCompliantBrowser() ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'nonunicodebrowser' );
|
2004-10-10 21:30:17 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-08-30 00:29:46 +00:00
|
|
|
if ( isset( $this->mArticle ) && isset( $this->mArticle->mRevision ) ) {
|
|
|
|
|
// Let sysop know that this will make private content public if saved
|
2007-11-24 01:34:54 +00:00
|
|
|
if( !$this->mArticle->mRevision->userCan( Revision::DELETED_TEXT ) ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'rev-deleted-text-permission' );
|
2007-11-24 01:34:54 +00:00
|
|
|
} else if( $this->mArticle->mRevision->isDeleted( Revision::DELETED_TEXT ) ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'rev-deleted-text-view' );
|
2007-02-17 04:17:53 +00:00
|
|
|
}
|
2008-08-30 00:29:46 +00:00
|
|
|
// Let user know they are editing an old version
|
2007-02-17 04:17:53 +00:00
|
|
|
if( !$this->mArticle->mRevision->isCurrent() ) {
|
|
|
|
|
$this->mArticle->setOldSubtitle( $this->mArticle->mRevision->getId() );
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'editingold' );
|
2007-02-17 04:17:53 +00:00
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( wfReadOnly() ) {
|
2008-08-20 21:27:12 +00:00
|
|
|
$wgOut->wrapWikiMsg( "<div id=\"mw-read-only-warning\">\n$1\n</div>", array( 'readonlywarning', wfReadOnlyReason() ) );
|
2006-02-23 14:37:51 +00:00
|
|
|
} elseif( $wgUser->isAnon() && $this->formtype != 'preview' ) {
|
2008-08-20 21:27:12 +00:00
|
|
|
$wgOut->wrapWikiMsg( '<div id="mw-anon-edit-warning">$1</div>', 'anoneditwarning' );
|
2006-02-23 14:37:51 +00:00
|
|
|
} else {
|
|
|
|
|
if( $this->isCssJsSubpage && $this->formtype != 'preview' ) {
|
|
|
|
|
# Check the skin exists
|
|
|
|
|
if( $this->isValidCssJsSubpage ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'usercssjsyoucanpreview' );
|
2006-02-23 14:37:51 +00:00
|
|
|
} else {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'userinvalidcssjstitle', $wgTitle->getSkinFromCssJsSubpage() );
|
2006-02-23 14:37:51 +00:00
|
|
|
}
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2007-01-12 04:43:33 +00:00
|
|
|
|
2007-11-01 17:56:19 +00:00
|
|
|
if( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
|
2007-01-20 19:17:45 +00:00
|
|
|
# Show a warning if editing an interface message
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'editinginterface' );
|
2007-11-01 17:56:19 +00:00
|
|
|
} elseif( $this->mTitle->isProtected( 'edit' ) ) {
|
2007-01-20 19:17:45 +00:00
|
|
|
# Is the title semi-protected?
|
2007-11-01 17:56:19 +00:00
|
|
|
if( $this->mTitle->isSemiProtected() ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$noticeMsg = 'semiprotectedpagewarning';
|
2006-02-06 09:49:28 +00:00
|
|
|
} else {
|
2008-01-09 21:40:40 +00:00
|
|
|
# Then it must be protected based on static groups (regular)
|
2008-02-18 07:25:35 +00:00
|
|
|
$noticeMsg = 'protectedpagewarning';
|
2006-02-06 09:49:28 +00:00
|
|
|
}
|
2008-07-28 15:41:17 +00:00
|
|
|
$wgOut->addHTML( "<div id='mw-edit-$noticeMsg'>\n" );
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( $noticeMsg );
|
2008-07-28 15:41:17 +00:00
|
|
|
$wgOut->addHTML( "</div>\n" );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2007-11-01 17:56:19 +00:00
|
|
|
if ( $this->mTitle->isCascadeProtected() ) {
|
2007-04-21 19:02:02 +00:00
|
|
|
# Is this page under cascading protection from some source pages?
|
2007-11-01 17:56:19 +00:00
|
|
|
list($cascadeSources, /* $restrictions */) = $this->mTitle->getCascadeProtectionSources();
|
2008-08-08 21:56:58 +00:00
|
|
|
$notice = "$1\n";
|
|
|
|
|
if ( count($cascadeSources) > 0 ) {
|
|
|
|
|
# Explain, and list the titles responsible
|
|
|
|
|
foreach( $cascadeSources as $page ) {
|
|
|
|
|
$notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
|
|
|
|
|
}
|
2007-08-21 03:57:54 +00:00
|
|
|
}
|
2008-08-08 21:56:58 +00:00
|
|
|
$wgOut->wrapWikiMsg( $notice, array( 'cascadeprotectedwarning', count($cascadeSources) ) );
|
2007-04-21 19:02:02 +00:00
|
|
|
}
|
2008-01-02 19:51:34 +00:00
|
|
|
if( !$this->mTitle->exists() && $this->mTitle->getRestrictions( 'create' ) != array() ){
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'titleprotectedwarning' );
|
2008-01-02 19:51:34 +00:00
|
|
|
}
|
2006-02-22 00:55:25 +00:00
|
|
|
|
|
|
|
|
if ( $this->kblength === false ) {
|
|
|
|
|
$this->kblength = (int)(strlen( $this->textbox1 ) / 1024);
|
|
|
|
|
}
|
|
|
|
|
if ( $this->tooBig || $this->kblength > $wgMaxArticleSize ) {
|
2008-07-28 15:41:17 +00:00
|
|
|
$wgOut->addHTML( "<div id='mw-edit-longpageerror'>\n" );
|
|
|
|
|
$wgOut->addWikiMsg( 'longpageerror', $wgLang->formatNum( $this->kblength ), $wgLang->formatNum( $wgMaxArticleSize ) );
|
|
|
|
|
$wgOut->addHTML( "</div>\n" );
|
2006-02-22 00:55:25 +00:00
|
|
|
} elseif( $this->kblength > 29 ) {
|
2008-07-28 15:41:17 +00:00
|
|
|
$wgOut->addHTML( "<div id='mw-edit-longpagewarning'>\n" );
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'longpagewarning', $wgLang->formatNum( $this->kblength ) );
|
2008-07-28 15:41:17 +00:00
|
|
|
$wgOut->addHTML( "</div>\n" );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
New edit toolbar for bold, italic, links, headlines, math, images, media,
sigs, horizontal lines (more can be added easily). Select text and click
to apply, or just click to see an example. Mouseover should show speedtips.
Also, access keys for the edit window (ALT+P=Preview, ALT+S=Save) -> Moz+IE
2004-01-11 04:11:43 +00:00
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
$q = 'action='.$this->action;
|
2004-03-08 09:09:35 +00:00
|
|
|
#if ( "no" == $redirect ) { $q .= "&redirect=no"; }
|
2007-11-03 03:20:12 +00:00
|
|
|
$action = $wgTitle->escapeLocalURL( $q );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2008-08-18 14:19:12 +00:00
|
|
|
$colonSep = wfMsg( 'colon-separator' );
|
|
|
|
|
$summary = wfMsg( 'summary' ) . $colonSep;
|
|
|
|
|
$subject = wfMsg( 'subject' ) . $colonSep;
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2007-11-03 03:20:12 +00:00
|
|
|
$cancel = $sk->makeKnownLink( $wgTitle->getPrefixedText(),
|
2006-05-17 13:26:42 +00:00
|
|
|
wfMsgExt('cancel', array('parseinline')) );
|
2006-09-22 13:07:06 +00:00
|
|
|
$edithelpurl = Skin::makeInternalOrExternalUrl( wfMsgForContent( 'edithelppage' ));
|
2004-06-09 06:59:05 +00:00
|
|
|
$edithelp = '<a target="helpwindow" href="'.$edithelpurl.'">'.
|
|
|
|
|
htmlspecialchars( wfMsg( 'edithelp' ) ).'</a> '.
|
|
|
|
|
htmlspecialchars( wfMsg( 'newwindow' ) );
|
2004-08-18 00:04:06 +00:00
|
|
|
|
|
|
|
|
global $wgRightsText;
|
2008-02-18 07:25:35 +00:00
|
|
|
if ( $wgRightsText ) {
|
2008-04-14 07:45:50 +00:00
|
|
|
$copywarnMsg = array( 'copyrightwarning',
|
2005-03-18 14:13:58 +00:00
|
|
|
'[[' . wfMsgForContent( 'copyrightpage' ) . ']]',
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgRightsText );
|
|
|
|
|
} else {
|
2008-04-14 07:45:50 +00:00
|
|
|
$copywarnMsg = array( 'copyrightwarning2',
|
2008-02-18 07:25:35 +00:00
|
|
|
'[[' . wfMsgForContent( 'copyrightpage' ) . ']]' );
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if( $wgUser->getOption('showtoolbar') and !$this->isCssJsSubpage ) {
|
2004-08-19 11:43:48 +00:00
|
|
|
# prepare toolbar for edit buttons
|
2008-06-09 14:17:16 +00:00
|
|
|
$toolbar = EditPage::getEditToolbar();
|
2004-04-11 23:21:44 +00:00
|
|
|
} else {
|
2004-08-22 17:24:50 +00:00
|
|
|
$toolbar = '';
|
New edit toolbar for bold, italic, links, headlines, math, images, media,
sigs, horizontal lines (more can be added easily). Select text and click
to apply, or just click to see an example. Mouseover should show speedtips.
Also, access keys for the edit window (ALT+P=Preview, ALT+S=Save) -> Moz+IE
2004-01-11 04:11:43 +00:00
|
|
|
}
|
|
|
|
|
|
2003-08-02 20:43:11 +00:00
|
|
|
// activate checkboxes if user wants them to be always active
|
2005-03-19 12:01:57 +00:00
|
|
|
if( !$this->preview && !$this->diff ) {
|
2006-03-18 19:22:33 +00:00
|
|
|
# Sort out the "watch" checkbox
|
|
|
|
|
if( $wgUser->getOption( 'watchdefault' ) ) {
|
|
|
|
|
# Watch all edits
|
|
|
|
|
$this->watchthis = true;
|
2007-11-01 17:56:19 +00:00
|
|
|
} elseif( $wgUser->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
|
2006-03-18 19:22:33 +00:00
|
|
|
# Watch creations
|
|
|
|
|
$this->watchthis = true;
|
2007-11-01 17:56:19 +00:00
|
|
|
} elseif( $this->mTitle->userIsWatching() ) {
|
2006-03-18 19:22:33 +00:00
|
|
|
# Already watched
|
|
|
|
|
$this->watchthis = true;
|
|
|
|
|
}
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
if( $wgUser->getOption( 'minordefault' ) ) $this->minoredit = true;
|
2004-03-08 09:09:35 +00:00
|
|
|
}
|
2004-03-18 06:56:14 +00:00
|
|
|
|
2006-11-26 13:58:40 +00:00
|
|
|
$wgOut->addHTML( $this->editFormPageTop );
|
|
|
|
|
|
2006-02-20 21:18:11 +00:00
|
|
|
if ( $wgUser->getOption( 'previewontop' ) ) {
|
2008-08-27 14:47:41 +00:00
|
|
|
$this->displayPreviewArea( $previewOutput, true );
|
2005-03-19 12:01:57 +00:00
|
|
|
}
|
|
|
|
|
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2006-11-22 20:53:11 +00:00
|
|
|
$wgOut->addHTML( $this->editFormTextTop );
|
|
|
|
|
|
2004-08-19 11:43:48 +00:00
|
|
|
# if this is a comment, show a subject line at the top, which is also the edit summary.
|
|
|
|
|
# Otherwise, show a summary field at the bottom
|
2004-09-24 13:14:52 +00:00
|
|
|
$summarytext = htmlspecialchars( $wgContLang->recodeForEdit( $this->summary ) ); # FIXME
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-02-28 00:47:00 +00:00
|
|
|
# If a blank edit summary was previously provided, and the appropriate
|
|
|
|
|
# user preference is active, pass a hidden tag as wpIgnoreBlankSummary. This will stop the
|
|
|
|
|
# user being bounced back more than once in the event that a summary
|
|
|
|
|
# is not required.
|
|
|
|
|
#####
|
|
|
|
|
# For a bit more sophisticated detection of blank summaries, hash the
|
|
|
|
|
# automatic one and pass that in the hidden field wpAutoSummary.
|
|
|
|
|
$summaryhiddens = '';
|
2008-04-11 16:40:24 +00:00
|
|
|
if( $this->missingSummary ) $summaryhiddens .= Xml::hidden( 'wpIgnoreBlankSummary', true );
|
2008-02-28 00:47:00 +00:00
|
|
|
$autosumm = $this->autoSumm ? $this->autoSumm : md5( $this->summary );
|
2008-04-11 16:40:24 +00:00
|
|
|
$summaryhiddens .= Xml::hidden( 'wpAutoSummary', $autosumm );
|
2005-08-20 06:57:21 +00:00
|
|
|
if( $this->section == 'new' ) {
|
2008-08-18 14:19:12 +00:00
|
|
|
$commentsubject="<span id='wpSummaryLabel'><label for='wpSummary'>{$subject}</label></span>\n<input tabindex='1' type='text' value=\"$summarytext\" name='wpSummary' id='wpSummary' maxlength='200' size='60' />{$summaryhiddens}<br />";
|
2008-06-20 19:50:06 +00:00
|
|
|
$editsummary = "<div class='editOptions'>\n";
|
2008-04-11 16:40:24 +00:00
|
|
|
global $wgParser;
|
|
|
|
|
$formattedSummary = wfMsgForContent( 'newsectionsummary', $wgParser->stripSectionName( $this->summary ) );
|
2008-08-18 14:19:12 +00:00
|
|
|
$subjectpreview = $summarytext && $this->preview ? "<div class=\"mw-summary-preview\">".wfMsg('subject-preview').$colonSep.$sk->commentBlock( $formattedSummary, $this->mTitle, true )."</div>\n" : '';
|
2006-11-14 06:57:46 +00:00
|
|
|
$summarypreview = '';
|
2005-08-20 06:57:21 +00:00
|
|
|
} else {
|
|
|
|
|
$commentsubject = '';
|
2008-08-18 14:19:12 +00:00
|
|
|
$editsummary="<div class='editOptions'>\n<span id='wpSummaryLabel'><label for='wpSummary'>{$summary}</label></span>\n<input tabindex='2' type='text' value=\"$summarytext\" name='wpSummary' id='wpSummary' maxlength='200' size='60' />{$summaryhiddens}<br />";
|
|
|
|
|
$summarypreview = $summarytext && $this->preview ? "<div class=\"mw-summary-preview\">".wfMsg('summary-preview').$colonSep.$sk->commentBlock( $this->summary, $this->mTitle )."</div>\n" : '';
|
2006-11-14 06:57:46 +00:00
|
|
|
$subjectpreview = '';
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# Set focus to the edit box on load, except on preview or diff, where it would interfere with the display
|
2005-03-19 12:01:57 +00:00
|
|
|
if( !$this->preview && !$this->diff ) {
|
2004-08-22 17:24:50 +00:00
|
|
|
$wgOut->setOnloadHandler( 'document.editform.wpTextbox1.focus()' );
|
2003-12-11 05:52:15 +00:00
|
|
|
}
|
2008-08-27 05:56:34 +00:00
|
|
|
$templates = $this->getTemplates();
|
2006-11-21 03:22:18 +00:00
|
|
|
$formattedtemplates = $sk->formatTemplates( $templates, $this->preview, $this->section != '');
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-02-25 13:38:21 +00:00
|
|
|
$hiddencats = $this->mArticle->getHiddenCategories();
|
|
|
|
|
$formattedhiddencats = $sk->formatHiddenCategories( $hiddencats );
|
|
|
|
|
|
2004-12-29 13:46:10 +00:00
|
|
|
global $wgUseMetadataEdit ;
|
2005-08-16 23:39:33 +00:00
|
|
|
if ( $wgUseMetadataEdit ) {
|
2004-12-29 13:46:10 +00:00
|
|
|
$metadata = $this->mMetaData ;
|
|
|
|
|
$metadata = htmlspecialchars( $wgContLang->recodeForEdit( $metadata ) ) ;
|
2006-05-15 01:11:06 +00:00
|
|
|
$top = wfMsgWikiHtml( 'metadata_help' );
|
2008-08-27 05:56:34 +00:00
|
|
|
/* ToDo: Replace with clean code */
|
|
|
|
|
$ew = $wgUser->getOption( 'editwidth' );
|
|
|
|
|
if ( $ew ) $ew = " style=\"width:100%\"";
|
|
|
|
|
else $ew = '';
|
|
|
|
|
/* /ToDo */
|
2004-12-29 15:18:12 +00:00
|
|
|
$metadata = $top . "<textarea name='metadata' rows='3' cols='{$cols}'{$ew}>{$metadata}</textarea>" ;
|
2004-12-29 13:46:10 +00:00
|
|
|
}
|
|
|
|
|
else $metadata = "" ;
|
|
|
|
|
|
2005-08-02 20:17:23 +00:00
|
|
|
$recreate = '';
|
2008-03-03 16:40:42 +00:00
|
|
|
if ($this->wasDeletedSinceLastEdit()) {
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( 'save' != $this->formtype ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg('deletedwhileediting');
|
2005-08-02 20:17:23 +00:00
|
|
|
} else {
|
|
|
|
|
// Hide the toolbar and edit area, use can click preview to get it back
|
|
|
|
|
// Add an confirmation checkbox and explanation.
|
|
|
|
|
$toolbar = '';
|
2005-08-20 07:47:56 +00:00
|
|
|
$recreate = $wgOut->parse( wfMsg( 'confirmrecreate', $this->lastDelete->user_name , $this->lastDelete->log_comment ));
|
2005-08-02 20:17:23 +00:00
|
|
|
$recreate .=
|
|
|
|
|
"<br /><input tabindex='1' type='checkbox' value='1' name='wpRecreate' id='wpRecreate' />".
|
2005-08-03 06:07:41 +00:00
|
|
|
"<label for='wpRecreate' title='".wfMsg('tooltip-recreate')."'>". wfMsg('recreate')."</label>";
|
2005-08-02 20:17:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-10 15:30:31 +00:00
|
|
|
$tabindex = 2;
|
2006-02-20 21:18:11 +00:00
|
|
|
|
2007-02-10 15:30:31 +00:00
|
|
|
$checkboxes = self::getCheckboxes( $tabindex, $sk,
|
|
|
|
|
array( 'minor' => $this->minoredit, 'watch' => $this->watchthis ) );
|
|
|
|
|
|
|
|
|
|
$checkboxhtml = implode( $checkboxes, "\n" );
|
|
|
|
|
|
|
|
|
|
$buttons = $this->getEditButtons( $tabindex );
|
|
|
|
|
$buttonshtml = implode( $buttons, "\n" );
|
2006-02-20 21:18:11 +00:00
|
|
|
|
2005-07-29 10:08:41 +00:00
|
|
|
$safemodehtml = $this->checkUnicodeCompliantBrowser()
|
2007-02-10 15:30:31 +00:00
|
|
|
? '' : Xml::hidden( 'safemode', '1' );
|
2004-12-29 13:46:10 +00:00
|
|
|
|
2004-12-19 08:00:50 +00:00
|
|
|
$wgOut->addHTML( <<<END
|
New edit toolbar for bold, italic, links, headlines, math, images, media,
sigs, horizontal lines (more can be added easily). Select text and click
to apply, or just click to see an example. Mouseover should show speedtips.
Also, access keys for the edit window (ALT+P=Preview, ALT+S=Save) -> Moz+IE
2004-01-11 04:11:43 +00:00
|
|
|
{$toolbar}
|
2006-05-21 10:06:02 +00:00
|
|
|
<form id="editform" name="editform" method="post" action="$action" enctype="multipart/form-data">
|
2005-09-29 23:35:31 +00:00
|
|
|
END
|
|
|
|
|
);
|
2006-02-20 21:18:11 +00:00
|
|
|
|
2005-09-29 23:35:31 +00:00
|
|
|
if( is_callable( $formCallback ) ) {
|
|
|
|
|
call_user_func_array( $formCallback, array( &$wgOut ) );
|
|
|
|
|
}
|
2005-12-02 03:29:37 +00:00
|
|
|
|
2007-04-02 21:53:06 +00:00
|
|
|
wfRunHooks( 'EditPage::showEditForm:fields', array( &$this, &$wgOut ) );
|
|
|
|
|
|
2005-12-02 03:29:37 +00:00
|
|
|
// Put these up at the top to ensure they aren't lost on early form submission
|
2008-08-27 05:56:34 +00:00
|
|
|
$this->showFormBeforeText();
|
2008-05-09 18:53:54 +00:00
|
|
|
|
2005-09-29 23:35:31 +00:00
|
|
|
$wgOut->addHTML( <<<END
|
2008-08-27 05:56:34 +00:00
|
|
|
{$recreate}
|
2003-08-02 20:43:11 +00:00
|
|
|
{$commentsubject}
|
2006-11-14 06:33:11 +00:00
|
|
|
{$subjectpreview}
|
2007-11-03 03:20:12 +00:00
|
|
|
{$this->editFormTextBeforeContent}
|
2004-12-19 08:00:50 +00:00
|
|
|
END
|
2008-05-09 18:53:54 +00:00
|
|
|
);
|
2008-08-27 05:56:34 +00:00
|
|
|
$this->showTextbox1();
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->wrapWikiMsg( "<div id=\"editpage-copywarn\">\n$1\n</div>", $copywarnMsg );
|
2008-08-27 05:56:34 +00:00
|
|
|
$wgOut->addHTML( <<<END
|
|
|
|
|
{$this->editFormTextAfterWarn}
|
2005-12-04 00:35:14 +00:00
|
|
|
{$metadata}
|
|
|
|
|
{$editsummary}
|
2006-11-14 06:33:11 +00:00
|
|
|
{$summarypreview}
|
2005-12-04 00:35:14 +00:00
|
|
|
{$checkboxhtml}
|
|
|
|
|
{$safemodehtml}
|
2008-08-27 05:56:34 +00:00
|
|
|
END
|
|
|
|
|
);
|
2005-12-02 03:29:37 +00:00
|
|
|
|
2006-05-20 08:07:16 +00:00
|
|
|
$wgOut->addHTML(
|
|
|
|
|
"<div class='editButtons'>
|
2007-02-10 15:30:31 +00:00
|
|
|
{$buttonshtml}
|
2006-02-20 21:18:11 +00:00
|
|
|
<span class='editHelp'>{$cancel} | {$edithelp}</span>
|
|
|
|
|
</div><!-- editButtons -->
|
|
|
|
|
</div><!-- editOptions -->");
|
2005-12-04 00:35:14 +00:00
|
|
|
|
2008-02-24 02:02:19 +00:00
|
|
|
/**
|
|
|
|
|
* To make it harder for someone to slip a user a page
|
|
|
|
|
* which submits an edit form to the wiki without their
|
|
|
|
|
* knowledge, a random token is associated with the login
|
|
|
|
|
* session. If it's not passed back with the submission,
|
|
|
|
|
* we won't save the page, or render user JavaScript and
|
|
|
|
|
* CSS previews.
|
|
|
|
|
*
|
|
|
|
|
* For anon editors, who may not have a session, we just
|
|
|
|
|
* include the constant suffix to prevent editing from
|
|
|
|
|
* broken text-mangling proxies.
|
|
|
|
|
*/
|
|
|
|
|
$token = htmlspecialchars( $wgUser->editToken() );
|
|
|
|
|
$wgOut->addHTML( "\n<input type='hidden' value=\"$token\" name=\"wpEditToken\" />\n" );
|
|
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
$this->showEditTools();
|
2008-08-26 15:10:52 +00:00
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
$wgOut->addHTML( <<<END
|
|
|
|
|
{$this->editFormTextAfterTools}
|
2008-02-28 00:47:00 +00:00
|
|
|
<div class='templatesUsed'>
|
|
|
|
|
{$formattedtemplates}
|
|
|
|
|
</div>
|
|
|
|
|
<div class='hiddencats'>
|
|
|
|
|
{$formattedhiddencats}
|
|
|
|
|
</div>
|
2008-08-27 05:56:34 +00:00
|
|
|
END
|
|
|
|
|
);
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-04-15 14:47:04 +00:00
|
|
|
if ( $this->isConflict && wfRunHooks( 'EditPageBeforeConflictDiff', array( &$this, &$wgOut ) ) ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->wrapWikiMsg( '==$1==', "yourdiff" );
|
2005-11-15 11:12:21 +00:00
|
|
|
|
2007-11-01 17:56:19 +00:00
|
|
|
$de = new DifferenceEngine( $this->mTitle );
|
2005-11-15 11:12:21 +00:00
|
|
|
$de->setText( $this->textbox2, $this->textbox1 );
|
|
|
|
|
$de->showDiff( wfMsg( "yourtext" ), wfMsg( "storedversion" ) );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->wrapWikiMsg( '==$1==', "yourtext" );
|
2008-08-27 05:56:34 +00:00
|
|
|
$this->showTextbox2();
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2006-11-22 20:53:11 +00:00
|
|
|
$wgOut->addHTML( $this->editFormTextBottom );
|
2003-08-02 20:43:11 +00:00
|
|
|
$wgOut->addHTML( "</form>\n" );
|
2006-02-20 21:18:11 +00:00
|
|
|
if ( !$wgUser->getOption( 'previewontop' ) ) {
|
2008-08-27 14:47:41 +00:00
|
|
|
$this->displayPreviewArea( $previewOutput, false );
|
2008-08-27 05:56:34 +00:00
|
|
|
}
|
2006-02-20 21:18:11 +00:00
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
wfProfileOut( $fname );
|
|
|
|
|
}
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
protected function showFormBeforeText() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->addHTML( "
|
|
|
|
|
<input type='hidden' value=\"" . htmlspecialchars( $this->section ) . "\" name=\"wpSection\" />
|
|
|
|
|
<input type='hidden' value=\"{$this->starttime}\" name=\"wpStarttime\" />\n
|
|
|
|
|
<input type='hidden' value=\"{$this->edittime}\" name=\"wpEdittime\" />\n
|
|
|
|
|
<input type='hidden' value=\"{$this->scrolltop}\" name=\"wpScrolltop\" id=\"wpScrolltop\" />\n" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function showTextbox1() {
|
|
|
|
|
$attribs = array( 'tabindex' => 1 );
|
|
|
|
|
|
|
|
|
|
if( $this->wasDeletedSinceLastEdit() )
|
|
|
|
|
$attribs['type'] = 'hidden';
|
|
|
|
|
|
|
|
|
|
$this->showTextbox( $this->textbox1, 'wpTextbox1', $attribs );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function showTextbox2() {
|
|
|
|
|
$this->showTextbox( $this->textbox2, 'wpTextbox2', array( 'tabindex' => 6 ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function showTextbox( $content, $name, $attribs = array() ) {
|
|
|
|
|
global $wgOut, $wgUser;
|
|
|
|
|
|
|
|
|
|
$wikitext = $this->safeUnicodeOutput( $content );
|
|
|
|
|
if( $wikitext !== '' ) {
|
|
|
|
|
// Ensure there's a newline at the end, otherwise adding lines
|
|
|
|
|
// is awkward.
|
|
|
|
|
// But don't add a newline if the ext is empty, or Firefox in XHTML
|
|
|
|
|
// mode will show an extra newline. A bit annoying.
|
|
|
|
|
$wikitext .= "\n";
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-27 06:06:39 +00:00
|
|
|
$attribs['accesskey'] = ',';
|
|
|
|
|
$attribs['id'] = $name;
|
2008-08-27 05:56:34 +00:00
|
|
|
|
|
|
|
|
if( $wgUser->getOption( 'editwidth' ) )
|
|
|
|
|
$attribs['style'] = 'width: 100%';
|
|
|
|
|
|
|
|
|
|
$wgOut->addHTML( Xml::textarea(
|
|
|
|
|
$name,
|
|
|
|
|
$wikitext,
|
|
|
|
|
$wgUser->getIntOption( 'cols' ), $wgUser->getIntOption( 'rows' ),
|
|
|
|
|
$attribs ) );
|
|
|
|
|
}
|
2006-02-20 21:18:11 +00:00
|
|
|
|
2008-08-27 14:47:41 +00:00
|
|
|
protected function displayPreviewArea( $previewOutput, $isOnTop = false ) {
|
2008-08-27 05:56:34 +00:00
|
|
|
global $wgOut;
|
2008-08-29 13:46:06 +00:00
|
|
|
$classes = array();
|
|
|
|
|
if( $isOnTop )
|
|
|
|
|
$classes[] = 'ontop';
|
|
|
|
|
|
|
|
|
|
$attribs = array( 'id' => 'wikiPreview', 'class' => implode( ' ', $classes ) );
|
|
|
|
|
|
|
|
|
|
if( $this->formtype != 'preview' )
|
|
|
|
|
$attribs['style'] = 'display: none;';
|
|
|
|
|
|
2008-08-28 21:16:46 +00:00
|
|
|
$wgOut->addHTML( Xml::openElement( 'div', $attribs ) );
|
2008-08-29 13:46:06 +00:00
|
|
|
|
2008-08-28 21:16:46 +00:00
|
|
|
if ( $this->formtype == 'preview' ) {
|
2008-08-27 05:56:34 +00:00
|
|
|
$this->showPreview( $previewOutput );
|
2008-08-26 14:07:31 +00:00
|
|
|
}
|
2008-08-29 13:46:06 +00:00
|
|
|
|
2008-08-28 21:16:46 +00:00
|
|
|
$wgOut->addHTML( '</div>' );
|
2008-08-26 14:07:31 +00:00
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
if ( $this->formtype == 'diff') {
|
|
|
|
|
$this->showDiff();
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-08-28 21:16:46 +00:00
|
|
|
/**
|
|
|
|
|
* Append preview output to $wgOut.
|
|
|
|
|
* Includes category rendering if this is a category page.
|
|
|
|
|
*
|
|
|
|
|
* @param string $text The HTML to be output for the preview.
|
|
|
|
|
*/
|
|
|
|
|
protected function showPreview( $text ) {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
|
|
|
|
|
if($this->mTitle->getNamespace() == NS_CATEGORY) {
|
|
|
|
|
$this->mArticle->openShowCategory();
|
|
|
|
|
}
|
|
|
|
|
wfRunHooks( 'OutputPageBeforeHTML',array( &$wgOut, &$text ) );
|
|
|
|
|
$wgOut->addHTML( $text );
|
|
|
|
|
if($this->mTitle->getNamespace() == NS_CATEGORY) {
|
|
|
|
|
$this->mArticle->closeShowCategory();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
/**
|
|
|
|
|
* Live Preview lets us fetch rendered preview page content and
|
|
|
|
|
* add it to the page without refreshing the whole page.
|
2006-01-07 13:09:30 +00:00
|
|
|
* If not supported by the browser it will fall through to the normal form
|
2005-08-20 06:57:21 +00:00
|
|
|
* submission method.
|
2006-01-07 13:09:30 +00:00
|
|
|
*
|
|
|
|
|
* This function outputs a script tag to support live preview, and
|
|
|
|
|
* returns an onclick handler which should be added to the attributes
|
2005-08-20 06:57:21 +00:00
|
|
|
* of the preview button
|
|
|
|
|
*/
|
|
|
|
|
function doLivePreviewScript() {
|
2008-05-09 20:18:35 +00:00
|
|
|
global $wgOut, $wgTitle;
|
|
|
|
|
$wgOut->addScriptFile( 'preview.js' );
|
2008-08-27 05:56:34 +00:00
|
|
|
$liveAction = $wgTitle->getLocalUrl( "action={$this->action}&wpPreview=true&live=true" );
|
2007-09-24 13:46:14 +00:00
|
|
|
return "return !lpDoPreview(" .
|
2006-02-20 21:18:11 +00:00
|
|
|
"editform.wpTextbox1.value," .
|
|
|
|
|
'"' . $liveAction . '"' . ")";
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
protected function showEditTools() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->addHtml( '<div class="mw-editTools">' );
|
|
|
|
|
$wgOut->addWikiMsgArray( 'edittools', array(), array( 'content' ) );
|
|
|
|
|
$wgOut->addHtml( '</div>' );
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-02 20:17:23 +00:00
|
|
|
function getLastDelete() {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2005-08-03 06:07:41 +00:00
|
|
|
$fname = 'EditPage::getLastDelete';
|
2005-08-02 20:17:23 +00:00
|
|
|
$res = $dbr->select(
|
|
|
|
|
array( 'logging', 'user' ),
|
|
|
|
|
array( 'log_type',
|
|
|
|
|
'log_action',
|
|
|
|
|
'log_timestamp',
|
|
|
|
|
'log_user',
|
|
|
|
|
'log_namespace',
|
|
|
|
|
'log_title',
|
|
|
|
|
'log_comment',
|
|
|
|
|
'log_params',
|
|
|
|
|
'user_name', ),
|
2007-11-01 17:56:19 +00:00
|
|
|
array( 'log_namespace' => $this->mTitle->getNamespace(),
|
|
|
|
|
'log_title' => $this->mTitle->getDBkey(),
|
2005-08-22 23:30:12 +00:00
|
|
|
'log_type' => 'delete',
|
|
|
|
|
'log_action' => 'delete',
|
2005-08-02 20:17:23 +00:00
|
|
|
'user_id=log_user' ),
|
2005-08-03 06:07:41 +00:00
|
|
|
$fname,
|
2005-08-02 20:17:23 +00:00
|
|
|
array( 'LIMIT' => 1, 'ORDER BY' => 'log_timestamp DESC' ) );
|
|
|
|
|
|
|
|
|
|
if($dbr->numRows($res) == 1) {
|
|
|
|
|
while ( $x = $dbr->fetchObject ( $res ) )
|
|
|
|
|
$data = $x;
|
|
|
|
|
$dbr->freeResult ( $res ) ;
|
|
|
|
|
} else {
|
|
|
|
|
$data = null;
|
|
|
|
|
}
|
|
|
|
|
return $data;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-19 12:01:57 +00:00
|
|
|
/**
|
2008-08-02 02:39:09 +00:00
|
|
|
* Get the rendered text for previewing.
|
|
|
|
|
* @return string
|
2005-03-19 12:01:57 +00:00
|
|
|
*/
|
2005-08-20 06:57:21 +00:00
|
|
|
function getPreviewText() {
|
2008-03-07 14:02:12 +00:00
|
|
|
global $wgOut, $wgUser, $wgTitle, $wgParser, $wgLang, $wgContLang;
|
2005-08-21 04:45:28 +00:00
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2005-08-21 04:45:28 +00:00
|
|
|
|
2006-06-07 08:28:43 +00:00
|
|
|
if ( $this->mTriedSave && !$this->mTokenOk ) {
|
2007-07-01 22:22:16 +00:00
|
|
|
if ( $this->mTokenOkExceptSuffix ) {
|
2007-12-10 06:02:29 +00:00
|
|
|
$note = wfMsg( 'token_suffix_mismatch' );
|
2007-07-01 22:22:16 +00:00
|
|
|
} else {
|
2007-12-10 06:02:29 +00:00
|
|
|
$note = wfMsg( 'session_fail_preview' );
|
2007-07-01 22:22:16 +00:00
|
|
|
}
|
2006-06-07 08:28:43 +00:00
|
|
|
} else {
|
2007-12-10 06:02:29 +00:00
|
|
|
$note = wfMsg( 'previewnote' );
|
2004-12-19 02:36:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$parserOptions = ParserOptions::newFromUser( $wgUser );
|
|
|
|
|
$parserOptions->setEditSection( false );
|
|
|
|
|
|
2006-06-06 06:21:50 +00:00
|
|
|
global $wgRawHtml;
|
|
|
|
|
if( $wgRawHtml && !$this->mTokenOk ) {
|
|
|
|
|
// Could be an offsite preview attempt. This is very unsafe if
|
|
|
|
|
// HTML is enabled, as it could be an attack.
|
|
|
|
|
return $wgOut->parse( "<div class='previewnote'>" .
|
|
|
|
|
wfMsg( 'session_fail_preview_html' ) . "</div>" );
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-19 02:36:04 +00:00
|
|
|
# don't parse user css/js, show message about preview
|
|
|
|
|
# XXX: stupid php bug won't let us use $wgTitle->isCssJsSubpage() here
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->isCssJsSubpage ) {
|
2007-11-03 03:20:12 +00:00
|
|
|
if(preg_match("/\\.css$/", $this->mTitle->getText() ) ) {
|
2004-12-19 02:36:04 +00:00
|
|
|
$previewtext = wfMsg('usercsspreview');
|
2007-11-03 03:20:12 +00:00
|
|
|
} else if(preg_match("/\\.js$/", $this->mTitle->getText() ) ) {
|
2004-12-19 02:36:04 +00:00
|
|
|
$previewtext = wfMsg('userjspreview');
|
|
|
|
|
}
|
2006-03-07 01:10:39 +00:00
|
|
|
$parserOptions->setTidy(true);
|
2007-11-03 03:20:12 +00:00
|
|
|
$parserOutput = $wgParser->parse( $previewtext , $this->mTitle, $parserOptions );
|
2008-08-27 05:56:34 +00:00
|
|
|
//$wgOut->addHTML( $parserOutput->mText );
|
2007-12-10 06:02:29 +00:00
|
|
|
$previewHTML = '';
|
2008-08-27 05:56:34 +00:00
|
|
|
} elseif( $rt = Title::newFromRedirect( $this->textbox1 ) ) {
|
2008-08-02 02:39:09 +00:00
|
|
|
$previewHTML = $this->mArticle->viewRedirect( $rt, false );
|
2004-12-19 02:36:04 +00:00
|
|
|
} else {
|
2007-09-13 18:35:54 +00:00
|
|
|
$toparse = $this->textbox1;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-07-13 21:25:30 +00:00
|
|
|
# If we're adding a comment, we need to show the
|
|
|
|
|
# summary as the headline
|
|
|
|
|
if($this->section=="new" && $this->summary!="") {
|
|
|
|
|
$toparse="== {$this->summary} ==\n\n".$toparse;
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-03-07 14:02:12 +00:00
|
|
|
if ( $this->mMetaData != "" ) $toparse .= "\n" . $this->mMetaData;
|
|
|
|
|
|
|
|
|
|
// Parse mediawiki messages with correct target language
|
|
|
|
|
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
|
|
|
|
|
$pos = strrpos( $this->mTitle->getText(), '/' );
|
|
|
|
|
if ( $pos !== false ) {
|
|
|
|
|
$code = substr( $this->mTitle->getText(), $pos+1 );
|
|
|
|
|
switch ($code) {
|
|
|
|
|
case $wgLang->getCode():
|
|
|
|
|
$obj = $wgLang; break;
|
|
|
|
|
case $wgContLang->getCode():
|
|
|
|
|
$obj = $wgContLang; break;
|
|
|
|
|
default:
|
|
|
|
|
$obj = Language::factory( $code );
|
|
|
|
|
}
|
|
|
|
|
$parserOptions->setTargetLanguage( $obj );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-03-07 01:10:39 +00:00
|
|
|
$parserOptions->setTidy(true);
|
2007-11-30 14:50:48 +00:00
|
|
|
$parserOptions->enableLimitReport();
|
2008-04-09 22:20:01 +00:00
|
|
|
$parserOutput = $wgParser->parse( $this->mArticle->preSaveTransform( $toparse ),
|
2007-11-03 03:20:12 +00:00
|
|
|
$this->mTitle, $parserOptions );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-01-01 20:08:08 +00:00
|
|
|
$previewHTML = $parserOutput->getText();
|
2008-08-27 05:56:34 +00:00
|
|
|
$this->mParserOutput = $parserOutput;
|
2006-01-01 20:08:08 +00:00
|
|
|
$wgOut->addParserOutputNoText( $parserOutput );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-12-10 06:02:29 +00:00
|
|
|
if ( count( $parserOutput->getWarnings() ) ) {
|
|
|
|
|
$note .= "\n\n" . implode( "\n\n", $parserOutput->getWarnings() );
|
|
|
|
|
}
|
2004-12-19 02:36:04 +00:00
|
|
|
}
|
2007-12-10 06:02:29 +00:00
|
|
|
|
|
|
|
|
$previewhead = '<h2>' . htmlspecialchars( wfMsg( 'preview' ) ) . "</h2>\n" .
|
|
|
|
|
"<div class='previewnote'>" . $wgOut->parse( $note ) . "</div>\n";
|
|
|
|
|
if ( $this->isConflict ) {
|
2008-08-27 05:56:34 +00:00
|
|
|
$previewhead .='<h2>' . htmlspecialchars( wfMsg( 'previewconflict' ) ) . "</h2>\n";
|
2007-12-10 06:02:29 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-08-27 05:56:34 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $previewhead . $previewHTML;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getTemplates() {
|
|
|
|
|
if( $this->preview || $this->section != '' ) {
|
|
|
|
|
$templates = array();
|
|
|
|
|
if( !isset($this->mParserOutput) ) return $templates;
|
|
|
|
|
foreach( $this->mParserOutput->getTemplates() as $ns => $template) {
|
|
|
|
|
foreach( array_keys( $template ) as $dbk ) {
|
|
|
|
|
$templates[] = Title::makeTitle($ns, $dbk);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $templates;
|
2008-04-09 22:20:01 +00:00
|
|
|
} else {
|
2008-08-27 05:56:34 +00:00
|
|
|
return $this->mArticle->getUsedTemplates();
|
2008-04-09 22:20:01 +00:00
|
|
|
}
|
2004-12-19 02:36:04 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
2006-05-02 17:06:24 +00:00
|
|
|
* Call the stock "user is blocked" page
|
2004-09-03 16:51:45 +00:00
|
|
|
*/
|
2006-06-24 20:58:10 +00:00
|
|
|
function blockedPage() {
|
|
|
|
|
global $wgOut, $wgUser;
|
|
|
|
|
$wgOut->blockedPage( false ); # Standard block notice on the top, don't 'return'
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2006-06-24 20:58:10 +00:00
|
|
|
# If the user made changes, preserve them when showing the markup
|
2007-01-13 19:58:40 +00:00
|
|
|
# (This happens when a user is blocked during edit, for instance)
|
2006-06-24 20:58:10 +00:00
|
|
|
$first = $this->firsttime || ( !$this->save && $this->textbox1 == '' );
|
2006-07-13 10:03:45 +00:00
|
|
|
if( $first ) {
|
2007-11-01 17:56:19 +00:00
|
|
|
$source = $this->mTitle->exists() ? $this->getContent() : false;
|
2006-07-13 10:03:45 +00:00
|
|
|
} else {
|
|
|
|
|
$source = $this->textbox1;
|
|
|
|
|
}
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2006-06-24 20:58:10 +00:00
|
|
|
# Spit out the source or the user's modified version
|
2006-07-13 10:03:45 +00:00
|
|
|
if( $source !== false ) {
|
2008-08-27 05:56:34 +00:00
|
|
|
$rows = $wgUser->getIntOption( 'rows' );
|
|
|
|
|
$cols = $wgUser->getIntOption( 'cols' );
|
2006-07-13 10:03:45 +00:00
|
|
|
$attribs = array( 'id' => 'wpTextbox1', 'name' => 'wpTextbox1', 'cols' => $cols, 'rows' => $rows, 'readonly' => 'readonly' );
|
|
|
|
|
$wgOut->addHtml( '<hr />' );
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( $first ? 'blockedoriginalsource' : 'blockededitsource', $this->mTitle->getPrefixedText() );
|
2008-05-03 12:27:53 +00:00
|
|
|
# Why we don't use Xml::element here?
|
|
|
|
|
# Is it because if $source is '', it returns <textarea />?
|
|
|
|
|
$wgOut->addHtml( Xml::openElement( 'textarea', $attribs ) . htmlspecialchars( $source ) . Xml::closeElement( 'textarea' ) );
|
2006-07-13 10:03:45 +00:00
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
2006-05-02 16:53:32 +00:00
|
|
|
* Produce the stock "please login to edit pages" page
|
2004-09-03 16:51:45 +00:00
|
|
|
*/
|
|
|
|
|
function userNotLoggedInPage() {
|
2007-11-03 03:20:12 +00:00
|
|
|
global $wgUser, $wgOut, $wgTitle;
|
2006-11-08 07:12:03 +00:00
|
|
|
$skin = $wgUser->getSkin();
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2006-10-30 06:25:31 +00:00
|
|
|
$loginTitle = SpecialPage::getTitleFor( 'Userlogin' );
|
2007-11-03 03:20:12 +00:00
|
|
|
$loginLink = $skin->makeKnownLinkObj( $loginTitle, wfMsgHtml( 'loginreqlink' ), 'returnto=' . $wgTitle->getPrefixedUrl() );
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$wgOut->setPageTitle( wfMsg( 'whitelistedittitle' ) );
|
2006-05-02 17:06:24 +00:00
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
2004-01-17 09:49:43 +00:00
|
|
|
$wgOut->setArticleRelated( false );
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2006-06-20 18:20:58 +00:00
|
|
|
$wgOut->addHtml( wfMsgWikiHtml( 'whitelistedittext', $loginLink ) );
|
2007-11-03 03:20:12 +00:00
|
|
|
$wgOut->returnToMain( false, $wgTitle );
|
2003-08-05 11:04:02 +00:00
|
|
|
}
|
|
|
|
|
|
2007-03-14 18:20:21 +00:00
|
|
|
/**
|
|
|
|
|
* Creates a basic error page which informs the user that
|
|
|
|
|
* they have attempted to edit a nonexistant section.
|
|
|
|
|
*/
|
|
|
|
|
function noSuchSectionPage() {
|
2007-11-03 03:20:12 +00:00
|
|
|
global $wgOut, $wgTitle;
|
2007-03-14 18:20:21 +00:00
|
|
|
|
|
|
|
|
$wgOut->setPageTitle( wfMsg( 'nosuchsectiontitle' ) );
|
|
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
|
|
|
|
$wgOut->setArticleRelated( false );
|
|
|
|
|
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'nosuchsectiontext', $this->section );
|
2007-11-03 03:20:12 +00:00
|
|
|
$wgOut->returnToMain( false, $wgTitle );
|
2007-03-14 18:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
2006-05-02 17:06:24 +00:00
|
|
|
* Produce the stock "your edit contains spam" page
|
|
|
|
|
*
|
|
|
|
|
* @param $match Text which triggered one or more filters
|
2004-09-03 16:51:45 +00:00
|
|
|
*/
|
2006-05-02 17:06:24 +00:00
|
|
|
function spamPage( $match = false ) {
|
2007-11-03 03:20:12 +00:00
|
|
|
global $wgOut, $wgTitle;
|
2006-05-02 17:06:24 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$wgOut->setPageTitle( wfMsg( 'spamprotectiontitle' ) );
|
2006-05-02 17:06:24 +00:00
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
2004-05-29 07:41:16 +00:00
|
|
|
$wgOut->setArticleRelated( false );
|
|
|
|
|
|
2007-12-22 15:13:25 +00:00
|
|
|
$wgOut->addHtml( '<div id="spamprotected">' );
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'spamprotectiontext' );
|
2006-05-02 17:06:24 +00:00
|
|
|
if ( $match )
|
2008-05-03 12:27:53 +00:00
|
|
|
$wgOut->addWikiMsg( 'spamprotectionmatch', wfEscapeWikiText( $match ) );
|
2007-12-22 15:13:25 +00:00
|
|
|
$wgOut->addHtml( '</div>' );
|
2007-01-13 19:58:40 +00:00
|
|
|
|
2007-11-03 03:20:12 +00:00
|
|
|
$wgOut->returnToMain( false, $wgTitle );
|
2004-05-29 07:41:16 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2004-09-03 16:51:45 +00:00
|
|
|
* @todo document
|
|
|
|
|
*/
|
2005-06-28 23:19:56 +00:00
|
|
|
function mergeChangesInto( &$editText ){
|
2005-07-25 07:00:20 +00:00
|
|
|
$fname = 'EditPage::mergeChangesInto';
|
|
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$db = wfGetDB( DB_MASTER );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-06-28 23:19:56 +00:00
|
|
|
// This is the revision the editor started from
|
2008-07-15 08:43:40 +00:00
|
|
|
$baseRevision = $this->getBaseRevision();
|
2005-06-28 23:19:56 +00:00
|
|
|
if( is_null( $baseRevision ) ) {
|
2005-07-25 07:00:20 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-06-28 23:19:56 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
$baseText = $baseRevision->getText();
|
|
|
|
|
|
|
|
|
|
// The current state, we want to merge updates into it
|
|
|
|
|
$currentRevision = Revision::loadFromTitle(
|
2007-11-03 03:20:12 +00:00
|
|
|
$db, $this->mTitle );
|
2005-06-28 23:19:56 +00:00
|
|
|
if( is_null( $currentRevision ) ) {
|
2005-07-25 07:00:20 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-06-28 23:19:56 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
$currentText = $currentRevision->getText();
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-11-23 08:25:56 +00:00
|
|
|
$result = '';
|
2005-06-28 23:19:56 +00:00
|
|
|
if( wfMerge( $baseText, $editText, $currentText, $result ) ){
|
|
|
|
|
$editText = $result;
|
2005-07-25 07:00:20 +00:00
|
|
|
wfProfileOut( $fname );
|
2004-03-14 15:05:52 +00:00
|
|
|
return true;
|
|
|
|
|
} else {
|
2005-07-25 07:00:20 +00:00
|
|
|
wfProfileOut( $fname );
|
2004-03-14 15:05:52 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-10-10 21:30:17 +00:00
|
|
|
|
2005-10-22 20:27:26 +00:00
|
|
|
/**
|
|
|
|
|
* Check if the browser is on a blacklist of user-agents known to
|
|
|
|
|
* mangle UTF-8 data on form submission. Returns true if Unicode
|
|
|
|
|
* should make it through, false if it's known to be a problem.
|
|
|
|
|
* @return bool
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-10-22 20:27:26 +00:00
|
|
|
*/
|
2004-10-10 21:30:17 +00:00
|
|
|
function checkUnicodeCompliantBrowser() {
|
|
|
|
|
global $wgBrowserBlackList;
|
2005-10-22 20:27:26 +00:00
|
|
|
if( empty( $_SERVER["HTTP_USER_AGENT"] ) ) {
|
|
|
|
|
// No User-Agent header sent? Trust it by default...
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2004-10-10 21:30:17 +00:00
|
|
|
$currentbrowser = $_SERVER["HTTP_USER_AGENT"];
|
|
|
|
|
foreach ( $wgBrowserBlackList as $browser ) {
|
|
|
|
|
if ( preg_match($browser, $currentbrowser) ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-06 04:11:45 +00:00
|
|
|
/**
|
2007-09-08 02:08:08 +00:00
|
|
|
* @deprecated use $wgParser->stripSectionName()
|
2007-09-06 04:11:45 +00:00
|
|
|
*/
|
|
|
|
|
function pseudoParseSectionAnchor( $text ) {
|
2007-09-08 02:08:08 +00:00
|
|
|
global $wgParser;
|
|
|
|
|
return $wgParser->stripSectionName( $text );
|
2007-09-06 04:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
2004-10-26 05:44:54 +00:00
|
|
|
/**
|
|
|
|
|
* Format an anchor fragment as it would appear for a given section name
|
|
|
|
|
* @param string $text
|
|
|
|
|
* @return string
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2004-10-26 05:44:54 +00:00
|
|
|
*/
|
|
|
|
|
function sectionAnchor( $text ) {
|
2007-09-08 02:08:08 +00:00
|
|
|
global $wgParser;
|
|
|
|
|
return $wgParser->guessSectionNameFromWikiText( $text );
|
2004-10-26 05:44:54 +00:00
|
|
|
}
|
2004-11-25 13:52:56 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Shows a bulletin board style toolbar for common editing functions.
|
|
|
|
|
* It can be disabled in the user preferences.
|
2008-06-09 17:53:04 +00:00
|
|
|
* The necessary JavaScript code can be found in skins/common/edit.js.
|
2008-06-09 14:17:16 +00:00
|
|
|
*
|
|
|
|
|
* @return string
|
2004-11-25 13:52:56 +00:00
|
|
|
*/
|
2008-06-09 14:17:16 +00:00
|
|
|
static function getEditToolbar() {
|
2008-07-04 10:34:41 +00:00
|
|
|
global $wgStylePath, $wgContLang, $wgLang, $wgJsMimeType;
|
2004-11-25 13:52:56 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* toolarray an array of arrays which each include the filename of
|
|
|
|
|
* the button image (without path), the opening tag, the closing tag,
|
|
|
|
|
* and optionally a sample text that is inserted between the two when no
|
|
|
|
|
* selection is highlighted.
|
|
|
|
|
* The tip text is shown when the user moves the mouse over the button.
|
|
|
|
|
*
|
|
|
|
|
* Already here are accesskeys (key), which are not used yet until someone
|
|
|
|
|
* can figure out a way to make them work in IE. However, we should make
|
|
|
|
|
* sure these keys are not defined on the edit page.
|
|
|
|
|
*/
|
2007-02-19 11:46:52 +00:00
|
|
|
$toolarray = array(
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-bold'),
|
|
|
|
|
'id' => 'mw-editbutton-bold',
|
|
|
|
|
'open' => '\'\'\'',
|
|
|
|
|
'close' => '\'\'\'',
|
|
|
|
|
'sample' => wfMsg('bold_sample'),
|
|
|
|
|
'tip' => wfMsg('bold_tip'),
|
|
|
|
|
'key' => 'B'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-italic'),
|
|
|
|
|
'id' => 'mw-editbutton-italic',
|
|
|
|
|
'open' => '\'\'',
|
|
|
|
|
'close' => '\'\'',
|
|
|
|
|
'sample' => wfMsg('italic_sample'),
|
|
|
|
|
'tip' => wfMsg('italic_tip'),
|
|
|
|
|
'key' => 'I'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-link'),
|
|
|
|
|
'id' => 'mw-editbutton-link',
|
|
|
|
|
'open' => '[[',
|
|
|
|
|
'close' => ']]',
|
|
|
|
|
'sample' => wfMsg('link_sample'),
|
|
|
|
|
'tip' => wfMsg('link_tip'),
|
|
|
|
|
'key' => 'L'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-extlink'),
|
|
|
|
|
'id' => 'mw-editbutton-extlink',
|
|
|
|
|
'open' => '[',
|
|
|
|
|
'close' => ']',
|
|
|
|
|
'sample' => wfMsg('extlink_sample'),
|
|
|
|
|
'tip' => wfMsg('extlink_tip'),
|
|
|
|
|
'key' => 'X'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-headline'),
|
|
|
|
|
'id' => 'mw-editbutton-headline',
|
|
|
|
|
'open' => "\n== ",
|
|
|
|
|
'close' => " ==\n",
|
|
|
|
|
'sample' => wfMsg('headline_sample'),
|
|
|
|
|
'tip' => wfMsg('headline_tip'),
|
|
|
|
|
'key' => 'H'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-image'),
|
|
|
|
|
'id' => 'mw-editbutton-image',
|
|
|
|
|
'open' => '[['.$wgContLang->getNsText(NS_IMAGE).':',
|
|
|
|
|
'close' => ']]',
|
|
|
|
|
'sample' => wfMsg('image_sample'),
|
|
|
|
|
'tip' => wfMsg('image_tip'),
|
|
|
|
|
'key' => 'D'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-media'),
|
|
|
|
|
'id' => 'mw-editbutton-media',
|
|
|
|
|
'open' => '[['.$wgContLang->getNsText(NS_MEDIA).':',
|
|
|
|
|
'close' => ']]',
|
|
|
|
|
'sample' => wfMsg('media_sample'),
|
|
|
|
|
'tip' => wfMsg('media_tip'),
|
|
|
|
|
'key' => 'M'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-math'),
|
|
|
|
|
'id' => 'mw-editbutton-math',
|
|
|
|
|
'open' => "<math>",
|
|
|
|
|
'close' => "</math>",
|
|
|
|
|
'sample' => wfMsg('math_sample'),
|
|
|
|
|
'tip' => wfMsg('math_tip'),
|
|
|
|
|
'key' => 'C'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-nowiki'),
|
|
|
|
|
'id' => 'mw-editbutton-nowiki',
|
|
|
|
|
'open' => "<nowiki>",
|
|
|
|
|
'close' => "</nowiki>",
|
|
|
|
|
'sample' => wfMsg('nowiki_sample'),
|
|
|
|
|
'tip' => wfMsg('nowiki_tip'),
|
|
|
|
|
'key' => 'N'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-sig'),
|
|
|
|
|
'id' => 'mw-editbutton-signature',
|
|
|
|
|
'open' => '--~~~~',
|
|
|
|
|
'close' => '',
|
|
|
|
|
'sample' => '',
|
|
|
|
|
'tip' => wfMsg('sig_tip'),
|
|
|
|
|
'key' => 'Y'
|
2007-02-19 11:46:52 +00:00
|
|
|
),
|
2008-07-04 10:34:41 +00:00
|
|
|
array(
|
|
|
|
|
'image' => $wgLang->getImageFile('button-hr'),
|
|
|
|
|
'id' => 'mw-editbutton-hr',
|
|
|
|
|
'open' => "\n----\n",
|
|
|
|
|
'close' => '',
|
|
|
|
|
'sample' => '',
|
|
|
|
|
'tip' => wfMsg('hr_tip'),
|
|
|
|
|
'key' => 'R'
|
2007-02-19 11:46:52 +00:00
|
|
|
)
|
2004-11-25 13:52:56 +00:00
|
|
|
);
|
2006-04-17 10:36:21 +00:00
|
|
|
$toolbar = "<div id='toolbar'>\n";
|
|
|
|
|
$toolbar.="<script type='$wgJsMimeType'>\n/*<![CDATA[*/\n";
|
2004-11-25 13:52:56 +00:00
|
|
|
|
|
|
|
|
foreach($toolarray as $tool) {
|
2008-03-03 01:53:45 +00:00
|
|
|
$params = array(
|
|
|
|
|
$image = $wgStylePath.'/common/images/'.$tool['image'],
|
|
|
|
|
// Note that we use the tip both for the ALT tag and the TITLE tag of the image.
|
|
|
|
|
// Older browsers show a "speedtip" type message only for ALT.
|
|
|
|
|
// Ideally these should be different, realistically they
|
|
|
|
|
// probably don't need to be.
|
|
|
|
|
$tip = $tool['tip'],
|
|
|
|
|
$open = $tool['open'],
|
|
|
|
|
$close = $tool['close'],
|
|
|
|
|
$sample = $tool['sample'],
|
|
|
|
|
$cssId = $tool['id'],
|
|
|
|
|
);
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-03-03 02:48:38 +00:00
|
|
|
$paramList = implode( ',',
|
|
|
|
|
array_map( array( 'Xml', 'encodeJsVar' ), $params ) );
|
2008-03-03 01:53:45 +00:00
|
|
|
$toolbar.="addButton($paramList);\n";
|
2004-11-25 13:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$toolbar.="/*]]>*/\n</script>";
|
2006-04-17 10:36:21 +00:00
|
|
|
$toolbar.="\n</div>";
|
2004-11-25 13:52:56 +00:00
|
|
|
return $toolbar;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2007-02-10 15:30:31 +00:00
|
|
|
/**
|
|
|
|
|
* Returns an array of html code of the following checkboxes:
|
|
|
|
|
* minor and watch
|
|
|
|
|
*
|
|
|
|
|
* @param $tabindex Current tabindex
|
|
|
|
|
* @param $skin Skin object
|
|
|
|
|
* @param $checked Array of checkbox => bool, where bool indicates the checked
|
|
|
|
|
* status of the checkbox
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public static function getCheckboxes( &$tabindex, $skin, $checked ) {
|
|
|
|
|
global $wgUser;
|
|
|
|
|
|
|
|
|
|
$checkboxes = array();
|
|
|
|
|
|
|
|
|
|
$checkboxes['minor'] = '';
|
|
|
|
|
$minorLabel = wfMsgExt('minoredit', array('parseinline'));
|
|
|
|
|
if ( $wgUser->isAllowed('minoredit') ) {
|
|
|
|
|
$attribs = array(
|
|
|
|
|
'tabindex' => ++$tabindex,
|
|
|
|
|
'accesskey' => wfMsg( 'accesskey-minoredit' ),
|
|
|
|
|
'id' => 'wpMinoredit',
|
|
|
|
|
);
|
|
|
|
|
$checkboxes['minor'] =
|
|
|
|
|
Xml::check( 'wpMinoredit', $checked['minor'], $attribs ) .
|
2008-08-13 15:11:36 +00:00
|
|
|
" <label for='wpMinoredit'".$skin->tooltip('minoredit', 'withaccess').">{$minorLabel}</label>";
|
2007-02-10 15:30:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$watchLabel = wfMsgExt('watchthis', array('parseinline'));
|
|
|
|
|
$checkboxes['watch'] = '';
|
|
|
|
|
if ( $wgUser->isLoggedIn() ) {
|
|
|
|
|
$attribs = array(
|
|
|
|
|
'tabindex' => ++$tabindex,
|
|
|
|
|
'accesskey' => wfMsg( 'accesskey-watch' ),
|
|
|
|
|
'id' => 'wpWatchthis',
|
|
|
|
|
);
|
|
|
|
|
$checkboxes['watch'] =
|
|
|
|
|
Xml::check( 'wpWatchthis', $checked['watch'], $attribs ) .
|
2008-08-13 15:11:36 +00:00
|
|
|
" <label for='wpWatchthis'".$skin->tooltip('watch', 'withaccess').">{$watchLabel}</label>";
|
2007-02-10 15:30:31 +00:00
|
|
|
}
|
|
|
|
|
return $checkboxes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns an array of html code of the following buttons:
|
|
|
|
|
* save, diff, preview and live
|
|
|
|
|
*
|
|
|
|
|
* @param $tabindex Current tabindex
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public function getEditButtons(&$tabindex) {
|
|
|
|
|
global $wgLivePreview, $wgUser;
|
|
|
|
|
|
|
|
|
|
$buttons = array();
|
|
|
|
|
|
|
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpSave',
|
|
|
|
|
'name' => 'wpSave',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => ++$tabindex,
|
|
|
|
|
'value' => wfMsg('savearticle'),
|
|
|
|
|
'accesskey' => wfMsg('accesskey-save'),
|
|
|
|
|
'title' => wfMsg( 'tooltip-save' ).' ['.wfMsg( 'accesskey-save' ).']',
|
|
|
|
|
);
|
2008-05-03 12:27:53 +00:00
|
|
|
$buttons['save'] = Xml::element('input', $temp, '');
|
2007-02-10 15:30:31 +00:00
|
|
|
|
|
|
|
|
++$tabindex; // use the same for preview and live preview
|
|
|
|
|
if ( $wgLivePreview && $wgUser->getOption( 'uselivepreview' ) ) {
|
|
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpPreview',
|
|
|
|
|
'name' => 'wpPreview',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => $tabindex,
|
|
|
|
|
'value' => wfMsg('showpreview'),
|
|
|
|
|
'accesskey' => '',
|
|
|
|
|
'title' => wfMsg( 'tooltip-preview' ).' ['.wfMsg( 'accesskey-preview' ).']',
|
|
|
|
|
'style' => 'display: none;',
|
|
|
|
|
);
|
2008-05-03 12:27:53 +00:00
|
|
|
$buttons['preview'] = Xml::element('input', $temp, '');
|
2007-02-10 15:30:31 +00:00
|
|
|
|
|
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpLivePreview',
|
|
|
|
|
'name' => 'wpLivePreview',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => $tabindex,
|
|
|
|
|
'value' => wfMsg('showlivepreview'),
|
|
|
|
|
'accesskey' => wfMsg('accesskey-preview'),
|
|
|
|
|
'title' => '',
|
|
|
|
|
'onclick' => $this->doLivePreviewScript(),
|
|
|
|
|
);
|
2008-05-03 12:27:53 +00:00
|
|
|
$buttons['live'] = Xml::element('input', $temp, '');
|
2007-02-10 15:30:31 +00:00
|
|
|
} else {
|
|
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpPreview',
|
|
|
|
|
'name' => 'wpPreview',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => $tabindex,
|
|
|
|
|
'value' => wfMsg('showpreview'),
|
|
|
|
|
'accesskey' => wfMsg('accesskey-preview'),
|
|
|
|
|
'title' => wfMsg( 'tooltip-preview' ).' ['.wfMsg( 'accesskey-preview' ).']',
|
|
|
|
|
);
|
2008-05-03 12:27:53 +00:00
|
|
|
$buttons['preview'] = Xml::element('input', $temp, '');
|
2007-02-10 15:30:31 +00:00
|
|
|
$buttons['live'] = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpDiff',
|
|
|
|
|
'name' => 'wpDiff',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => ++$tabindex,
|
|
|
|
|
'value' => wfMsg('showdiff'),
|
|
|
|
|
'accesskey' => wfMsg('accesskey-diff'),
|
|
|
|
|
'title' => wfMsg( 'tooltip-diff' ).' ['.wfMsg( 'accesskey-diff' ).']',
|
|
|
|
|
);
|
2008-05-03 12:27:53 +00:00
|
|
|
$buttons['diff'] = Xml::element('input', $temp, '');
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-02-13 00:31:02 +00:00
|
|
|
wfRunHooks( 'EditPageBeforeEditButtons', array( &$this, &$buttons ) );
|
2007-02-10 15:30:31 +00:00
|
|
|
return $buttons;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-19 02:36:04 +00:00
|
|
|
/**
|
|
|
|
|
* Output preview text only. This can be sucked into the edit page
|
|
|
|
|
* via JavaScript, and saves the server time rendering the skin as
|
|
|
|
|
* well as theoretically being more robust on the client (doesn't
|
|
|
|
|
* disturb the edit box's undo history, won't eat your text on
|
|
|
|
|
* failure, etc).
|
|
|
|
|
*
|
|
|
|
|
* @todo This doesn't include category or interlanguage links.
|
2007-02-09 20:34:57 +00:00
|
|
|
* Would need to enhance it a bit, <s>maybe wrap them in XML
|
|
|
|
|
* or something...</s> that might also require more skin
|
2004-12-19 02:36:04 +00:00
|
|
|
* initialization, so check whether that's a problem.
|
|
|
|
|
*/
|
|
|
|
|
function livePreview() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->disable();
|
2007-02-21 01:02:47 +00:00
|
|
|
header( 'Content-type: text/xml; charset=utf-8' );
|
2004-12-19 02:36:04 +00:00
|
|
|
header( 'Cache-control: no-cache' );
|
2007-02-09 20:34:57 +00:00
|
|
|
|
2007-09-24 13:46:14 +00:00
|
|
|
$previewText = $this->getPreviewText();
|
|
|
|
|
#$categories = $skin->getCategoryLinks();
|
|
|
|
|
|
2007-02-09 20:34:57 +00:00
|
|
|
$s =
|
|
|
|
|
'<?xml version="1.0" encoding="UTF-8" ?>' . "\n" .
|
2007-09-24 13:46:14 +00:00
|
|
|
Xml::tags( 'livepreview', null,
|
|
|
|
|
Xml::element( 'preview', null, $previewText )
|
|
|
|
|
#. Xml::element( 'category', null, $categories )
|
|
|
|
|
);
|
2007-02-09 20:34:57 +00:00
|
|
|
echo $s;
|
2004-12-19 02:36:04 +00:00
|
|
|
}
|
2004-11-25 13:52:56 +00:00
|
|
|
|
2005-05-15 11:11:23 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get a diff between the current contents of the edit box and the
|
|
|
|
|
* version of the page we're editing from.
|
|
|
|
|
*
|
|
|
|
|
* If this is a section edit, we'll replace the section as for final
|
|
|
|
|
* save and then make a comparison.
|
|
|
|
|
*/
|
2007-06-13 20:08:19 +00:00
|
|
|
function showDiff() {
|
2005-06-29 00:31:07 +00:00
|
|
|
$oldtext = $this->mArticle->fetchContent();
|
2005-08-21 07:28:11 +00:00
|
|
|
$newtext = $this->mArticle->replaceSection(
|
2005-05-15 11:11:23 +00:00
|
|
|
$this->section, $this->textbox1, $this->summary, $this->edittime );
|
2006-05-28 21:59:03 +00:00
|
|
|
$newtext = $this->mArticle->preSaveTransform( $newtext );
|
2006-05-17 13:26:42 +00:00
|
|
|
$oldtitle = wfMsgExt( 'currentrev', array('parseinline') );
|
|
|
|
|
$newtitle = wfMsgExt( 'yourtext', array('parseinline') );
|
2005-11-15 11:12:21 +00:00
|
|
|
if ( $oldtext !== false || $newtext != '' ) {
|
2007-11-01 17:56:19 +00:00
|
|
|
$de = new DifferenceEngine( $this->mTitle );
|
2005-11-15 11:12:21 +00:00
|
|
|
$de->setText( $oldtext, $newtext );
|
|
|
|
|
$difftext = $de->getDiff( $oldtitle, $newtitle );
|
2007-06-13 20:08:19 +00:00
|
|
|
$de->showDiffStyle();
|
2005-11-15 11:12:21 +00:00
|
|
|
} else {
|
|
|
|
|
$difftext = '';
|
2005-05-15 11:11:23 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2007-06-13 20:08:19 +00:00
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->addHtml( '<div id="wikiDiff">' . $difftext . '</div>' );
|
2005-05-15 11:11:23 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-29 10:08:41 +00:00
|
|
|
/**
|
|
|
|
|
* Filter an input field through a Unicode de-armoring process if it
|
|
|
|
|
* came from an old browser with known broken Unicode editing issues.
|
|
|
|
|
*
|
|
|
|
|
* @param WebRequest $request
|
|
|
|
|
* @param string $field
|
|
|
|
|
* @return string
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-07-29 10:08:41 +00:00
|
|
|
*/
|
|
|
|
|
function safeUnicodeInput( $request, $field ) {
|
|
|
|
|
$text = rtrim( $request->getText( $field ) );
|
|
|
|
|
return $request->getBool( 'safemode' )
|
|
|
|
|
? $this->unmakesafe( $text )
|
|
|
|
|
: $text;
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-07-29 10:08:41 +00:00
|
|
|
/**
|
2005-07-30 08:03:04 +00:00
|
|
|
* Filter an output field through a Unicode armoring process if it is
|
|
|
|
|
* going to an old browser with known broken Unicode editing issues.
|
2005-07-29 10:08:41 +00:00
|
|
|
*
|
|
|
|
|
* @param string $text
|
|
|
|
|
* @return string
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-07-29 10:08:41 +00:00
|
|
|
*/
|
|
|
|
|
function safeUnicodeOutput( $text ) {
|
|
|
|
|
global $wgContLang;
|
|
|
|
|
$codedText = $wgContLang->recodeForEdit( $text );
|
|
|
|
|
return $this->checkUnicodeCompliantBrowser()
|
|
|
|
|
? $codedText
|
|
|
|
|
: $this->makesafe( $codedText );
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-07-29 10:08:41 +00:00
|
|
|
/**
|
|
|
|
|
* A number of web browsers are known to corrupt non-ASCII characters
|
|
|
|
|
* in a UTF-8 text editing environment. To protect against this,
|
|
|
|
|
* detected browsers will be served an armored version of the text,
|
|
|
|
|
* with non-ASCII chars converted to numeric HTML character references.
|
|
|
|
|
*
|
|
|
|
|
* Preexisting such character references will have a 0 added to them
|
|
|
|
|
* to ensure that round-trips do not alter the original data.
|
|
|
|
|
*
|
|
|
|
|
* @param string $invalue
|
|
|
|
|
* @return string
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-07-29 10:08:41 +00:00
|
|
|
*/
|
|
|
|
|
function makesafe( $invalue ) {
|
|
|
|
|
// Armor existing references for reversability.
|
|
|
|
|
$invalue = strtr( $invalue, array( "&#x" => "�" ) );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-07-29 10:08:41 +00:00
|
|
|
$bytesleft = 0;
|
|
|
|
|
$result = "";
|
|
|
|
|
$working = 0;
|
|
|
|
|
for( $i = 0; $i < strlen( $invalue ); $i++ ) {
|
|
|
|
|
$bytevalue = ord( $invalue{$i} );
|
|
|
|
|
if( $bytevalue <= 0x7F ) { //0xxx xxxx
|
|
|
|
|
$result .= chr( $bytevalue );
|
|
|
|
|
$bytesleft = 0;
|
|
|
|
|
} elseif( $bytevalue <= 0xBF ) { //10xx xxxx
|
|
|
|
|
$working = $working << 6;
|
|
|
|
|
$working += ($bytevalue & 0x3F);
|
|
|
|
|
$bytesleft--;
|
|
|
|
|
if( $bytesleft <= 0 ) {
|
|
|
|
|
$result .= "&#x" . strtoupper( dechex( $working ) ) . ";";
|
|
|
|
|
}
|
|
|
|
|
} elseif( $bytevalue <= 0xDF ) { //110x xxxx
|
|
|
|
|
$working = $bytevalue & 0x1F;
|
|
|
|
|
$bytesleft = 1;
|
|
|
|
|
} elseif( $bytevalue <= 0xEF ) { //1110 xxxx
|
|
|
|
|
$working = $bytevalue & 0x0F;
|
|
|
|
|
$bytesleft = 2;
|
|
|
|
|
} else { //1111 0xxx
|
|
|
|
|
$working = $bytevalue & 0x07;
|
|
|
|
|
$bytesleft = 3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-07-29 10:08:41 +00:00
|
|
|
/**
|
|
|
|
|
* Reverse the previously applied transliteration of non-ASCII characters
|
|
|
|
|
* back to UTF-8. Used to protect data from corruption by broken web browsers
|
|
|
|
|
* as listed in $wgBrowserBlackList.
|
|
|
|
|
*
|
|
|
|
|
* @param string $invalue
|
|
|
|
|
* @return string
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-07-29 10:08:41 +00:00
|
|
|
*/
|
|
|
|
|
function unmakesafe( $invalue ) {
|
|
|
|
|
$result = "";
|
|
|
|
|
for( $i = 0; $i < strlen( $invalue ); $i++ ) {
|
|
|
|
|
if( ( substr( $invalue, $i, 3 ) == "&#x" ) && ( $invalue{$i+3} != '0' ) ) {
|
|
|
|
|
$i += 3;
|
|
|
|
|
$hexstring = "";
|
|
|
|
|
do {
|
|
|
|
|
$hexstring .= $invalue{$i};
|
|
|
|
|
$i++;
|
|
|
|
|
} while( ctype_xdigit( $invalue{$i} ) && ( $i < strlen( $invalue ) ) );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-07-29 10:08:41 +00:00
|
|
|
// Do some sanity checks. These aren't needed for reversability,
|
2006-01-07 13:09:30 +00:00
|
|
|
// but should help keep the breakage down if the editor
|
2005-07-29 10:08:41 +00:00
|
|
|
// breaks one of the entities whilst editing.
|
2006-01-07 13:09:30 +00:00
|
|
|
if ((substr($invalue,$i,1)==";") and (strlen($hexstring) <= 6)) {
|
2005-07-29 10:08:41 +00:00
|
|
|
$codepoint = hexdec($hexstring);
|
|
|
|
|
$result .= codepointToUtf8( $codepoint );
|
|
|
|
|
} else {
|
|
|
|
|
$result .= "&#x" . $hexstring . substr( $invalue, $i, 1 );
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$result .= substr( $invalue, $i, 1 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// reverse the transform that we made for reversability reasons.
|
|
|
|
|
return strtr( $result, array( "�" => "&#x" ) );
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-12-05 05:37:10 +00:00
|
|
|
function noCreatePermission() {
|
2006-06-20 18:20:58 +00:00
|
|
|
global $wgOut;
|
2005-12-05 05:37:10 +00:00
|
|
|
$wgOut->setPageTitle( wfMsg( 'nocreatetitle' ) );
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'nocreatetext' );
|
2005-12-05 05:37:10 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-06-04 23:43:08 +00:00
|
|
|
/**
|
|
|
|
|
* If there are rows in the deletion log for this page, show them,
|
|
|
|
|
* along with a nice little note for the user
|
|
|
|
|
*
|
|
|
|
|
* @param OutputPage $out
|
|
|
|
|
*/
|
2008-07-17 04:37:59 +00:00
|
|
|
protected function showDeletionLog( $out ) {
|
2008-04-02 20:20:47 +00:00
|
|
|
global $wgUser;
|
2008-04-12 22:27:16 +00:00
|
|
|
$loglist = new LogEventsList( $wgUser->getSkin(), $out );
|
2008-04-02 20:20:47 +00:00
|
|
|
$pager = new LogPager( $loglist, 'delete', false, $this->mTitle->getPrefixedText() );
|
|
|
|
|
if( $pager->getNumRows() > 0 ) {
|
2007-06-04 23:43:08 +00:00
|
|
|
$out->addHtml( '<div id="mw-recreate-deleted-warn">' );
|
2008-02-18 07:25:35 +00:00
|
|
|
$out->addWikiMsg( 'recreate-deleted-warn' );
|
2008-04-02 20:20:47 +00:00
|
|
|
$out->addHTML(
|
|
|
|
|
$loglist->beginLogEventsList() .
|
|
|
|
|
$pager->getBody() .
|
|
|
|
|
$loglist->endLogEventsList()
|
|
|
|
|
);
|
2007-10-23 05:48:06 +00:00
|
|
|
$out->addHtml( '</div>' );
|
|
|
|
|
}
|
2007-06-04 23:43:08 +00:00
|
|
|
}
|
2007-10-30 05:42:19 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Attempt submission
|
|
|
|
|
* @return bool false if output is done, true if the rest of the form should be displayed
|
|
|
|
|
*/
|
|
|
|
|
function attemptSave() {
|
2008-01-10 13:33:23 +00:00
|
|
|
global $wgUser, $wgOut, $wgTitle, $wgRequest;
|
2007-10-30 05:42:19 +00:00
|
|
|
|
|
|
|
|
$resultDetails = false;
|
2008-01-10 13:33:23 +00:00
|
|
|
$value = $this->internalAttemptSave( $resultDetails, $wgUser->isAllowed('bot') && $wgRequest->getBool('bot', true) );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-11-14 16:03:39 +00:00
|
|
|
if( $value == self::AS_SUCCESS_UPDATE || $value == self::AS_SUCCESS_NEW_ARTICLE ) {
|
2007-11-03 03:20:12 +00:00
|
|
|
$this->didSave = true;
|
|
|
|
|
}
|
2007-11-20 08:34:59 +00:00
|
|
|
|
2008-01-24 01:59:35 +00:00
|
|
|
switch ($value) {
|
2007-10-30 05:42:19 +00:00
|
|
|
case self::AS_HOOK_ERROR_EXPECTED:
|
|
|
|
|
case self::AS_CONTENT_TOO_BIG:
|
|
|
|
|
case self::AS_ARTICLE_WAS_DELETED:
|
|
|
|
|
case self::AS_CONFLICT_DETECTED:
|
|
|
|
|
case self::AS_SUMMARY_NEEDED:
|
|
|
|
|
case self::AS_TEXTBOX_EMPTY:
|
2008-01-25 10:34:43 +00:00
|
|
|
case self::AS_MAX_ARTICLE_SIZE_EXCEEDED:
|
2007-10-30 05:42:19 +00:00
|
|
|
case self::AS_END:
|
|
|
|
|
return true;
|
2008-01-24 01:59:35 +00:00
|
|
|
|
2007-10-30 05:42:19 +00:00
|
|
|
case self::AS_HOOK_ERROR:
|
|
|
|
|
case self::AS_FILTERING:
|
|
|
|
|
case self::AS_SUCCESS_NEW_ARTICLE:
|
|
|
|
|
case self::AS_SUCCESS_UPDATE:
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
case self::AS_SPAM_ERROR:
|
|
|
|
|
$this->spamPage ( $resultDetails['spam'] );
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
case self::AS_BLOCKED_PAGE_FOR_USER:
|
|
|
|
|
$this->blockedPage();
|
|
|
|
|
return false;
|
|
|
|
|
|
2008-01-20 07:05:59 +00:00
|
|
|
case self::AS_IMAGE_REDIRECT_ANON:
|
|
|
|
|
$wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
|
|
|
|
|
return false;
|
|
|
|
|
|
2007-10-30 05:42:19 +00:00
|
|
|
case self::AS_READ_ONLY_PAGE_ANON:
|
|
|
|
|
$this->userNotLoggedInPage();
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
case self::AS_READ_ONLY_PAGE_LOGGED:
|
|
|
|
|
case self::AS_READ_ONLY_PAGE:
|
|
|
|
|
$wgOut->readOnlyPage();
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
case self::AS_RATE_LIMITED:
|
|
|
|
|
$wgOut->rateLimited();
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
case self::AS_NO_CREATE_PERMISSION;
|
|
|
|
|
$this->noCreatePermission();
|
2007-10-30 16:00:35 +00:00
|
|
|
return;
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-10-30 05:42:19 +00:00
|
|
|
case self::AS_BLANK_ARTICLE:
|
2007-11-03 03:20:12 +00:00
|
|
|
$wgOut->redirect( $wgTitle->getFullURL() );
|
2007-10-30 05:42:19 +00:00
|
|
|
return false;
|
2008-01-20 07:05:59 +00:00
|
|
|
|
|
|
|
|
case self::AS_IMAGE_REDIRECT_LOGGED:
|
|
|
|
|
$wgOut->permissionRequired( 'upload' );
|
|
|
|
|
return false;
|
2007-10-30 05:42:19 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-07-15 08:43:40 +00:00
|
|
|
|
|
|
|
|
function getBaseRevision() {
|
|
|
|
|
if ($this->mBaseRevision == false) {
|
|
|
|
|
$db = wfGetDB( DB_MASTER );
|
|
|
|
|
$baseRevision = Revision::loadFromTimestamp(
|
|
|
|
|
$db, $this->mTitle, $this->edittime );
|
|
|
|
|
return $this->mBaseRevision = $baseRevision;
|
|
|
|
|
} else {
|
|
|
|
|
return $this->mBaseRevision;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|