2004-02-18 02:15:00 +00:00
|
|
|
<?php
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Contain the EditPage class
|
2004-09-03 23:00:01 +00:00
|
|
|
* @package MediaWiki
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Splitting edit page/HTML interface from Article...
|
|
|
|
|
* The actual database and text munging is still in Article,
|
|
|
|
|
* but it should get easier to call those from alternate
|
|
|
|
|
* interfaces.
|
2004-09-03 23:00:01 +00:00
|
|
|
*
|
|
|
|
|
* @package MediaWiki
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2004-10-10 21:30:17 +00:00
|
|
|
|
2003-08-02 20:43:11 +00:00
|
|
|
class EditPage {
|
2006-05-11 20:24:28 +00:00
|
|
|
private
|
|
|
|
|
$allowBlankSummary = false,
|
|
|
|
|
$autoSumm = '',
|
|
|
|
|
$deletedSinceEdit = false,
|
|
|
|
|
$firsttime,
|
|
|
|
|
$formtype,
|
|
|
|
|
$hookError = '',
|
|
|
|
|
$isConflict = false,
|
|
|
|
|
$isCssJsSubpage = false,
|
|
|
|
|
$kblength = false,
|
|
|
|
|
$lastDelete,
|
|
|
|
|
$mArticle,
|
|
|
|
|
$missingComment = false,
|
|
|
|
|
$missingSummary = false,
|
|
|
|
|
$mMetaData = '',
|
|
|
|
|
$mTitle,
|
|
|
|
|
$mTokenOk = true,
|
|
|
|
|
$tooBig = false ;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-03-08 09:09:35 +00:00
|
|
|
# Form values
|
2006-05-11 20:24:28 +00:00
|
|
|
private
|
|
|
|
|
$diff = false,
|
|
|
|
|
$editintro = '',
|
|
|
|
|
$edittime = '',
|
|
|
|
|
$minoredit = false,
|
|
|
|
|
$oldid = 0,
|
|
|
|
|
$preview = false,
|
|
|
|
|
$recreate = false,
|
|
|
|
|
$save = false,
|
|
|
|
|
$scrolltop = null,
|
|
|
|
|
$section = '',
|
|
|
|
|
$starttime = '',
|
|
|
|
|
$summary = '',
|
|
|
|
|
$textbox1 = '',
|
|
|
|
|
$textbox2 = '',
|
|
|
|
|
$watchthis = false ;
|
2005-08-02 13:35:19 +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 ) {
|
|
|
|
|
$this->mArticle =& $article;
|
|
|
|
|
global $wgTitle;
|
|
|
|
|
$this->mTitle =& $wgTitle;
|
|
|
|
|
}
|
|
|
|
|
|
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-01-13 00:29:20 +00:00
|
|
|
$t = $this->mArticle->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 ;
|
|
|
|
|
}
|
|
|
|
|
|
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() {
|
2006-03-07 01:10:39 +00:00
|
|
|
global $wgOut, $wgUser, $wgRequest, $wgTitle;
|
|
|
|
|
global $wgEmailConfirmToEdit;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-11-10 10:30:25 +00:00
|
|
|
if ( ! wfRunHooks( 'AlternateEdit', array( &$this ) ) )
|
|
|
|
|
return;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-21 04:45:28 +00:00
|
|
|
$fname = 'EditPage::edit';
|
|
|
|
|
wfProfileIn( $fname );
|
2005-10-22 20:52:30 +00:00
|
|
|
wfDebug( "$fname: enter\n" );
|
2005-08-21 04:45:28 +00:00
|
|
|
|
2004-01-29 22:36:02 +00:00
|
|
|
// this is not an article
|
|
|
|
|
$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();
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2004-12-19 02:36:04 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
|
|
|
|
if ( ! $this->mTitle->userCanEdit() ) {
|
2005-10-22 20:52:30 +00:00
|
|
|
wfDebug( "$fname: user can't edit\n" );
|
2006-01-13 00:29:20 +00:00
|
|
|
$wgOut->readOnlyPage( $this->mArticle->getContent(), true );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2003-08-02 20:43:11 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2005-10-22 20:52:30 +00:00
|
|
|
wfDebug( "$fname: Checking blocks\n" );
|
2005-07-07 21:40:25 +00:00
|
|
|
if ( !$this->preview && !$this->diff && $wgUser->isBlockedFrom( $this->mTitle, !$this->save ) ) {
|
2005-02-17 22:56:51 +00:00
|
|
|
# When previewing, don't check blocked state - will get caught at save time.
|
|
|
|
|
# Also, check when starting edition is done against slave to improve performance.
|
2005-10-22 20:52:30 +00:00
|
|
|
wfDebug( "$fname: user is blocked\n" );
|
2006-01-06 23:09:37 +00:00
|
|
|
$wgOut->blockedPage();
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2003-08-02 20:43:11 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2005-06-25 06:24:46 +00:00
|
|
|
if ( !$wgUser->isAllowed('edit') ) {
|
|
|
|
|
if ( $wgUser->isAnon() ) {
|
2005-10-22 20:52:30 +00:00
|
|
|
wfDebug( "$fname: user must log in\n" );
|
2005-06-25 06:24:46 +00:00
|
|
|
$this->userNotLoggedInPage();
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-06-25 06:24:46 +00:00
|
|
|
return;
|
|
|
|
|
} else {
|
2005-10-22 20:52:30 +00:00
|
|
|
wfDebug( "$fname: read-only page\n" );
|
2006-01-13 00:29:20 +00:00
|
|
|
$wgOut->readOnlyPage( $this->mArticle->getContent(), true );
|
2005-08-21 06:08:51 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-06-25 06:24:46 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2003-08-05 11:04:02 +00:00
|
|
|
}
|
2006-02-10 09:34:31 +00:00
|
|
|
if ($wgEmailConfirmToEdit && !$wgUser->isEmailConfirmed()) {
|
|
|
|
|
wfDebug("$fname: user must confirm e-mail address\n");
|
|
|
|
|
$this->userNotConfirmedPage();
|
|
|
|
|
wfProfileOut($fname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2005-12-05 05:37:10 +00:00
|
|
|
if ( !$this->mTitle->userCan( 'create' ) && !$this->mTitle->exists() ) {
|
|
|
|
|
wfDebug( "$fname: no create permission\n" );
|
|
|
|
|
$this->noCreatePermission();
|
|
|
|
|
wfProfileOut( $fname );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
if ( wfReadOnly() ) {
|
2005-10-22 20:52:30 +00:00
|
|
|
wfDebug( "$fname: read-only mode is engaged\n" );
|
2004-03-08 09:09:35 +00:00
|
|
|
if( $this->save || $this->preview ) {
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->formtype = 'preview';
|
2005-03-19 12:01:57 +00:00
|
|
|
} else if ( $this->diff ) {
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->formtype = 'diff';
|
2003-08-02 20:43:11 +00:00
|
|
|
} else {
|
2006-01-13 00:29:20 +00:00
|
|
|
$wgOut->readOnlyPage( $this->mArticle->getContent() );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ( $this->save ) {
|
|
|
|
|
$this->formtype = 'save';
|
|
|
|
|
} else if ( $this->preview ) {
|
|
|
|
|
$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
|
|
|
|
|
|
|
|
wfProfileIn( "$fname-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
|
2006-02-23 14:37:51 +00:00
|
|
|
$this->isCssJsSubpage = $wgTitle->isCssJsSubpage();
|
|
|
|
|
$this->isValidCssJsSubpage = $wgTitle->isValidCssJsSubpage();
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
/* Notice that we can't use isDeleted, because it returns true if article is ever deleted
|
|
|
|
|
* no matter it's current state
|
|
|
|
|
*/
|
|
|
|
|
$this->deletedSinceEdit = false;
|
|
|
|
|
if ( $this->edittime != '' ) {
|
|
|
|
|
/* Note that we rely on logging table, which hasn't been always there,
|
|
|
|
|
* but that doesn't matter, because this only applies to brand new
|
|
|
|
|
* deletes. This is done on every preview and save request. Move it further down
|
|
|
|
|
* to only perform it on saves
|
|
|
|
|
*/
|
|
|
|
|
if ( $this->mTitle->isDeleted() ) {
|
2005-08-20 07:47:56 +00:00
|
|
|
$this->lastDelete = $this->getLastDelete();
|
|
|
|
|
if ( !is_null($this->lastDelete) ) {
|
|
|
|
|
$deletetime = $this->lastDelete->log_timestamp;
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( ($deletetime - $this->starttime) > 0 ) {
|
|
|
|
|
$this->deletedSinceEdit = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-12-24 05:19:04 +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->mTitle->getArticleID() && ('initial' == $this->formtype || $this->firsttime )) { # new article
|
|
|
|
|
$this->showIntro();
|
|
|
|
|
}
|
|
|
|
|
if( $this->mTitle->isTalkPage() ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'talkpagetext' ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 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() ) {
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( "$fname-business-end" );
|
|
|
|
|
wfProfileOut( $fname );
|
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 ) {
|
|
|
|
|
$this->initialiseForm();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->showEditForm();
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( "$fname-business-end" );
|
|
|
|
|
wfProfileOut( $fname );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-06-30 06:51:43 +00:00
|
|
|
/**
|
|
|
|
|
* Return true if this page should be previewed when the edit form
|
|
|
|
|
* is initially opened.
|
|
|
|
|
* @return bool
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-06-30 06:51:43 +00:00
|
|
|
*/
|
|
|
|
|
function previewOnOpen() {
|
|
|
|
|
global $wgUser;
|
2005-12-24 08:18:56 +00:00
|
|
|
return $this->section != 'new' &&
|
2005-12-24 08:23:32 +00:00
|
|
|
( ( $wgUser->getOption( 'previewonfirst' ) && $this->mTitle->exists() ) ||
|
2005-12-24 08:18:56 +00:00
|
|
|
( $this->mTitle->getNamespace() == NS_CATEGORY &&
|
|
|
|
|
!$this->mTitle->exists() ) );
|
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 );
|
|
|
|
|
|
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' );
|
2005-02-15 00:24:49 +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
|
|
|
|
|
$this->summary = $wgLang->truncate( $request->getText( 'wpSummary' ), 250 );
|
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
|
|
|
|
2005-10-31 22:36:35 +00:00
|
|
|
if( !$this->preview ) {
|
|
|
|
|
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" );
|
|
|
|
|
} 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
|
|
|
}
|
|
|
|
|
}
|
2005-03-19 12:01:57 +00:00
|
|
|
$this->save = ! ( $this->preview OR $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
|
2006-05-11 20:24:28 +00:00
|
|
|
if( ( $this->mTitle->getNamespace() == NS_USER || $this->mTitle->getNamespace() == 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' );
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-25 02:48:31 +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();
|
2005-02-15 00:24:49 +00:00
|
|
|
$this->preview = false;
|
|
|
|
|
$this->save = false;
|
2005-03-19 12:01:57 +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;
|
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-03-08 09:09:35 +00:00
|
|
|
# Section edit can come from either the form or a link
|
|
|
|
|
$this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
|
2005-08-02 13:35:19 +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;
|
2005-02-21 12:46:37 +00:00
|
|
|
if( $wgUser->isAnon() ) {
|
2005-02-15 00:24:49 +00:00
|
|
|
# Anonymous users may not have a session
|
|
|
|
|
# open. Don't tokenize.
|
2005-10-31 22:36:35 +00:00
|
|
|
$this->mTokenOk = true;
|
2005-02-15 00:24:49 +00:00
|
|
|
} else {
|
2005-10-31 22:36:35 +00:00
|
|
|
$this->mTokenOk = $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
|
2005-02-15 00:24:49 +00:00
|
|
|
}
|
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
|
|
|
|
2006-04-19 15:46:24 +00:00
|
|
|
/** */
|
2005-08-20 06:57:21 +00:00
|
|
|
function showIntro() {
|
2005-10-06 01:07:25 +00:00
|
|
|
global $wgOut, $wgUser;
|
2005-08-20 06:57:21 +00:00
|
|
|
$addstandardintro=true;
|
|
|
|
|
if($this->editintro) {
|
|
|
|
|
$introtitle=Title::newFromText($this->editintro);
|
|
|
|
|
if(isset($introtitle) && $introtitle->userCanRead()) {
|
|
|
|
|
$rev=Revision::newFromTitle($introtitle);
|
|
|
|
|
if($rev) {
|
2006-01-23 18:37:46 +00:00
|
|
|
$wgOut->addSecondaryWikiText($rev->getText());
|
2005-08-20 06:57:21 +00:00
|
|
|
$addstandardintro=false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if($addstandardintro) {
|
2006-01-07 13:09:30 +00:00
|
|
|
if ( $wgUser->isLoggedIn() )
|
2005-10-06 01:07:25 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'newarticletext' ) );
|
|
|
|
|
else
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'newarticletextanon' ) );
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
2005-08-20 06:57:21 +00:00
|
|
|
* Attempt submission
|
|
|
|
|
* @return bool false if output is done, true if the rest of the form should be displayed
|
2004-09-03 16:51:45 +00:00
|
|
|
*/
|
2005-08-20 06:57:21 +00:00
|
|
|
function attemptSave() {
|
|
|
|
|
global $wgSpamRegex, $wgFilterCallback, $wgUser, $wgOut;
|
2006-02-22 00:55:25 +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
|
|
|
|
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
|
|
|
|
|
if ( $wgSpamRegex && preg_match( $wgSpamRegex, $this->textbox1, $matches ) ) {
|
|
|
|
|
$this->spamPage ( $matches[0] );
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return false;
|
2005-08-02 20:17:23 +00:00
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $wgFilterCallback && $wgFilterCallback( $this->mTitle, $this->textbox1, $this->section ) ) {
|
|
|
|
|
# Error messages or other handling should be performed by the filter function
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-20 06:57:21 +00:00
|
|
|
return false;
|
2004-03-05 21:44:38 +00:00
|
|
|
}
|
2006-05-07 07:26:25 +00:00
|
|
|
if ( !wfRunHooks( 'EditFilter', array( $this, $this->textbox1, $this->section, &$this->hookError ) ) ) {
|
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 );
|
|
|
|
|
wfProfileOut( "$fname-checks" );
|
|
|
|
|
return false;
|
2006-05-06 21:41:53 +00:00
|
|
|
} elseif( $this->hookError != '' ) {
|
|
|
|
|
# ...or the hook could be expecting us to produce an error
|
|
|
|
|
wfProfileOut( "$fname-checks " );
|
|
|
|
|
wfProfileOut( $fname );
|
2006-05-06 21:48:19 +00:00
|
|
|
return true;
|
2005-09-29 23:35:31 +00:00
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $wgUser->isBlockedFrom( $this->mTitle, false ) ) {
|
|
|
|
|
# Check block state against master, thus 'false'.
|
|
|
|
|
$this->blockedIPpage();
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return false;
|
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 );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( !$wgUser->isAllowed('edit') ) {
|
|
|
|
|
if ( $wgUser->isAnon() ) {
|
2003-08-05 11:04:02 +00:00
|
|
|
$this->userNotLoggedInPage();
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return false;
|
2003-08-05 11:04:02 +00:00
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
else {
|
2003-08-02 20:43:11 +00:00
|
|
|
$wgOut->readOnlyPage();
|
2005-09-11 11:25:55 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return false;
|
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() ) {
|
|
|
|
|
$wgOut->readOnlyPage();
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if ( $wgUser->pingLimiter() ) {
|
|
|
|
|
$wgOut->rateLimited();
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# If the article has been deleted while editing, don't save it without
|
|
|
|
|
# confirmation
|
|
|
|
|
if ( $this->deletedSinceEdit && !$this->recreate ) {
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
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.
|
|
|
|
|
$aid = $this->mTitle->getArticleID( GAID_FOR_UPDATE );
|
|
|
|
|
if ( 0 == $aid ) {
|
2005-12-05 05:37:10 +00:00
|
|
|
// Late check for create permission, just in case *PARANOIA*
|
|
|
|
|
if ( !$this->mTitle->userCan( 'create' ) ) {
|
|
|
|
|
wfDebug( "$fname: no create permission\n" );
|
|
|
|
|
$this->noCreatePermission();
|
|
|
|
|
wfProfileOut( $fname );
|
|
|
|
|
return;
|
|
|
|
|
}
|
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.
|
2005-09-04 17:41:44 +00:00
|
|
|
if ( ( '' == $this->textbox1 ) ) {
|
2004-03-07 07:26:56 +00:00
|
|
|
$wgOut->redirect( $this->mTitle->getFullURL() );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return false;
|
2005-09-04 17:41:44 +00:00
|
|
|
}
|
2005-08-23 08:15:14 +00:00
|
|
|
|
|
|
|
|
$isComment=($this->section=='new');
|
|
|
|
|
$this->mArticle->insertNewArticle( $this->textbox1, $this->summary,
|
|
|
|
|
$this->minoredit, $this->watchthis, false, $isComment);
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
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
|
|
|
|
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
|
|
|
}
|
|
|
|
|
$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 '" .
|
|
|
|
|
$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 ) ) {
|
2005-08-20 06:57:21 +00:00
|
|
|
wfDebug( "Suppressing edit conflict, same user.\n" );
|
|
|
|
|
$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;
|
|
|
|
|
wfDebug( "Suppressing edit conflict, successful merge.\n" );
|
|
|
|
|
} else {
|
|
|
|
|
$this->section = '';
|
|
|
|
|
$this->textbox1 = $text;
|
|
|
|
|
wfDebug( "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 );
|
2005-08-20 06:57:21 +00:00
|
|
|
return true;
|
2005-08-02 20:17:23 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2006-03-25 00:57:14 +00:00
|
|
|
# Handle the user preference to force summaries here
|
2006-03-26 23:50:19 +00:00
|
|
|
if( $this->section != 'new' && !$this->allowBlankSummary && $wgUser->getOption( 'forceeditsummary' ) ) {
|
2006-03-25 02:48:31 +00:00
|
|
|
if( md5( $this->summary ) == $this->autoSumm ) {
|
|
|
|
|
$this->missingSummary = true;
|
|
|
|
|
wfProfileOut( $fname );
|
|
|
|
|
return( true );
|
|
|
|
|
}
|
|
|
|
|
}
|
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;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
if( $this->summary != '' ) {
|
|
|
|
|
$sectionanchor = $this->sectionAnchor( $this->summary );
|
|
|
|
|
}
|
|
|
|
|
} 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) {
|
|
|
|
|
$sectionanchor = $this->sectionAnchor( $matches[2] );
|
|
|
|
|
}
|
|
|
|
|
}
|
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 );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-23 08:15:14 +00:00
|
|
|
# update the article here
|
|
|
|
|
if( $this->mArticle->updateArticle( $text, $this->summary, $this->minoredit,
|
|
|
|
|
$this->watchthis, '', $sectionanchor ) ) {
|
|
|
|
|
wfProfileOut( $fname );
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
$this->isConflict = true;
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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();
|
2006-01-13 00:29:20 +00:00
|
|
|
$this->textbox1 = $this->mArticle->getContent();
|
2005-08-20 06:57:21 +00:00
|
|
|
$this->summary = '';
|
2005-12-28 14:47:30 +00:00
|
|
|
if ( !$this->mArticle->exists() && $this->mArticle->mTitle->getNamespace() == NS_MEDIAWIKI )
|
|
|
|
|
$this->textbox1 = wfMsgWeirdKey ( $this->mArticle->mTitle->getText() ) ;
|
2005-09-05 02:22:20 +00:00
|
|
|
wfProxyCheck();
|
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 ) {
|
2006-02-22 00:55:25 +00:00
|
|
|
global $wgOut, $wgUser, $wgLang, $wgContLang, $wgMaxArticleSize;
|
2005-08-20 06:57:21 +00:00
|
|
|
|
2005-08-21 04:45:28 +00:00
|
|
|
$fname = 'EditPage::showEditForm';
|
|
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
$sk =& $wgUser->getSkin();
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-12-11 11:20:12 +00:00
|
|
|
wfRunHooks( 'EditPage::showEditForm:initial', array( &$this ) ) ;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$wgOut->setRobotpolicy( 'noindex,nofollow' );
|
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 ) {
|
2004-08-22 17:24:50 +00:00
|
|
|
$s = wfMsg( 'editconflict', $this->mTitle->getPrefixedText() );
|
2003-08-02 20:43:11 +00:00
|
|
|
$wgOut->setPageTitle( $s );
|
2005-05-04 02:05:21 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'explainconflict' ) );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-03-08 09:09:35 +00:00
|
|
|
$this->textbox2 = $this->textbox1;
|
2006-01-13 00:29:20 +00:00
|
|
|
$this->textbox1 = $this->mArticle->getContent();
|
2004-03-08 09:09:35 +00:00
|
|
|
$this->edittime = $this->mArticle->getTimestamp();
|
2003-08-02 20:43:11 +00:00
|
|
|
} else {
|
|
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
if( $this->section != '' ) {
|
|
|
|
|
if( $this->section == 'new' ) {
|
2004-11-19 12:50:21 +00:00
|
|
|
$s = wfMsg('editingcomment', $this->mTitle->getPrefixedText() );
|
2003-08-02 20:43:11 +00:00
|
|
|
} else {
|
2004-11-19 12:50:21 +00:00
|
|
|
$s = wfMsg('editingsection', $this->mTitle->getPrefixedText() );
|
2005-07-14 01:36:49 +00:00
|
|
|
if( !$this->preview && !$this->diff ) {
|
|
|
|
|
preg_match( "/^(=+)(.+)\\1/mi",
|
|
|
|
|
$this->textbox1,
|
|
|
|
|
$matches );
|
|
|
|
|
if( !empty( $matches[2] ) ) {
|
|
|
|
|
$this->summary = "/* ". trim($matches[2])." */ ";
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
}
|
2004-03-20 01:18:19 +00:00
|
|
|
}
|
2004-11-06 09:21:28 +00:00
|
|
|
} else {
|
|
|
|
|
$s = wfMsg( 'editing', $this->mTitle->getPrefixedText() );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
$wgOut->setPageTitle( $s );
|
2006-03-01 23:00:07 +00:00
|
|
|
|
|
|
|
|
if ( $this->missingComment ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'missingcommenttext' ) );
|
|
|
|
|
}
|
2006-03-25 00:57:14 +00:00
|
|
|
|
|
|
|
|
if( $this->missingSummary ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'missingsummary' ) );
|
|
|
|
|
}
|
2006-05-06 21:41:53 +00:00
|
|
|
|
2006-05-07 07:26:25 +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() ) {
|
2004-10-10 21:30:17 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'nonunicodebrowser') );
|
|
|
|
|
}
|
2005-06-29 05:30:20 +00:00
|
|
|
if ( isset( $this->mArticle )
|
2005-06-29 05:30:50 +00:00
|
|
|
&& isset( $this->mArticle->mRevision )
|
2005-06-29 05:30:20 +00:00
|
|
|
&& !$this->mArticle->mRevision->isCurrent() ) {
|
2005-12-01 11:04:30 +00:00
|
|
|
$this->mArticle->setOldSubtitle( $this->mArticle->mRevision->getId() );
|
2005-05-04 02:05:21 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'editingold' ) );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( wfReadOnly() ) {
|
2005-05-04 02:05:21 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'readonlywarning' ) );
|
2006-02-23 14:37:51 +00:00
|
|
|
} elseif( $wgUser->isAnon() && $this->formtype != 'preview' ) {
|
2006-02-04 18:42:43 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'anoneditwarning' ) );
|
2006-02-23 14:37:51 +00:00
|
|
|
} else {
|
|
|
|
|
if( $this->isCssJsSubpage && $this->formtype != 'preview' ) {
|
|
|
|
|
# Check the skin exists
|
|
|
|
|
if( $this->isValidCssJsSubpage ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'usercssjsyoucanpreview' ) );
|
|
|
|
|
} else {
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage() ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2006-02-23 14:37:51 +00:00
|
|
|
|
2006-02-06 09:49:28 +00:00
|
|
|
if( $this->mTitle->isProtected( 'edit' ) ) {
|
2006-04-25 01:44:04 +00:00
|
|
|
# Is the protection due to the namespace, e.g. interface text?
|
|
|
|
|
if( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
|
|
|
|
|
# Yes; remind the user
|
|
|
|
|
$notice = wfMsg( 'editinginterface' );
|
|
|
|
|
} elseif( $this->mTitle->isSemiProtected() ) {
|
|
|
|
|
# No; semi protected
|
2006-02-06 09:49:28 +00:00
|
|
|
$notice = wfMsg( 'semiprotectedpagewarning' );
|
|
|
|
|
if( wfEmptyMsg( 'semiprotectedpagewarning', $notice ) || $notice == '-' ) {
|
|
|
|
|
$notice = '';
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2006-04-25 01:44:04 +00:00
|
|
|
# No; regular protection
|
2006-02-06 09:49:28 +00:00
|
|
|
$notice = wfMsg( 'protectedpagewarning' );
|
|
|
|
|
}
|
|
|
|
|
$wgOut->addWikiText( $notice );
|
2003-08-02 20:43:11 +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 ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'longpageerror', $wgLang->formatNum( $this->kblength ), $wgMaxArticleSize ) );
|
|
|
|
|
} elseif( $this->kblength > 29 ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'longpagewarning', $wgLang->formatNum( $this->kblength ) ) );
|
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
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$rows = $wgUser->getOption( 'rows' );
|
|
|
|
|
$cols = $wgUser->getOption( 'cols' );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$ew = $wgUser->getOption( 'editwidth' );
|
2003-08-02 20:43:11 +00:00
|
|
|
if ( $ew ) $ew = " style=\"width:100%\"";
|
2004-08-22 17:24:50 +00:00
|
|
|
else $ew = '';
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$q = 'action=submit';
|
2004-03-08 09:09:35 +00:00
|
|
|
#if ( "no" == $redirect ) { $q .= "&redirect=no"; }
|
2004-03-07 07:26:56 +00:00
|
|
|
$action = $this->mTitle->escapeLocalURL( $q );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$summary = wfMsg('summary');
|
|
|
|
|
$subject = wfMsg('subject');
|
|
|
|
|
$minor = wfMsg('minoredit');
|
|
|
|
|
$watchthis = wfMsg ('watchthis');
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-05-29 19:52:47 +00:00
|
|
|
$cancel = $sk->makeKnownLink( $this->mTitle->getPrefixedText(),
|
2004-08-22 17:24:50 +00:00
|
|
|
wfMsg('cancel') );
|
2006-04-16 17:57:34 +00:00
|
|
|
$edithelpurl = $sk->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;
|
|
|
|
|
$copywarn = "<div id=\"editpage-copywarn\">\n" .
|
2004-08-22 17:24:50 +00:00
|
|
|
wfMsg( $wgRightsText ? 'copyrightwarning' : 'copyrightwarning2',
|
2005-03-18 14:13:58 +00:00
|
|
|
'[[' . wfMsgForContent( 'copyrightpage' ) . ']]',
|
2004-08-18 00:04:06 +00:00
|
|
|
$wgRightsText ) . "\n</div>";
|
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
|
2004-11-25 13:52:56 +00:00
|
|
|
$toolbar = $this->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;
|
|
|
|
|
} elseif( $wgUser->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
|
|
|
|
|
# Watch creations
|
|
|
|
|
$this->watchthis = true;
|
|
|
|
|
} elseif( $this->mTitle->userIsWatching() ) {
|
|
|
|
|
# Already watched
|
|
|
|
|
$this->watchthis = true;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$minoredithtml = '';
|
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
|
|
|
|
2006-01-02 17:11:04 +00:00
|
|
|
if ( $wgUser->isAllowed('minoredit') ) {
|
2004-01-28 22:57:07 +00:00
|
|
|
$minoredithtml =
|
2004-08-19 11:26:44 +00:00
|
|
|
"<input tabindex='3' type='checkbox' value='1' name='wpMinoredit'".($this->minoredit?" checked='checked'":"").
|
|
|
|
|
" accesskey='".wfMsg('accesskey-minoredit')."' id='wpMinoredit' />".
|
|
|
|
|
"<label for='wpMinoredit' title='".wfMsg('tooltip-minoredit')."'>{$minor}</label>";
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2004-03-18 06:56:14 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$watchhtml = '';
|
2004-03-18 06:56:14 +00:00
|
|
|
|
2005-02-21 12:46:37 +00:00
|
|
|
if ( $wgUser->isLoggedIn() ) {
|
2005-08-02 13:35:19 +00:00
|
|
|
$watchhtml = "<input tabindex='4' type='checkbox' name='wpWatchthis'".
|
|
|
|
|
($this->watchthis?" checked='checked'":"").
|
|
|
|
|
" accesskey=\"".htmlspecialchars(wfMsg('accesskey-watch'))."\" id='wpWatchthis' />".
|
|
|
|
|
"<label for='wpWatchthis' title=\"" .
|
|
|
|
|
htmlspecialchars(wfMsg('tooltip-watch'))."\">{$watchthis}</label>";
|
2004-01-28 22:57:07 +00:00
|
|
|
}
|
2004-03-18 06:56:14 +00:00
|
|
|
|
2005-10-13 04:07:00 +00:00
|
|
|
$checkboxhtml = $minoredithtml . $watchhtml;
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2006-02-20 21:18:11 +00:00
|
|
|
if ( $wgUser->getOption( 'previewontop' ) ) {
|
|
|
|
|
|
|
|
|
|
if ( 'preview' == $this->formtype ) {
|
|
|
|
|
$this->showPreview();
|
|
|
|
|
} else {
|
|
|
|
|
$wgOut->addHTML( '<div id="wikiPreview"></div>' );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( 'diff' == $this->formtype ) {
|
2005-05-15 11:11:23 +00:00
|
|
|
$wgOut->addHTML( $this->getDiff() );
|
2005-03-19 12:01:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-08-02 20:43:11 +00:00
|
|
|
|
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
|
2005-08-20 06:57:21 +00:00
|
|
|
if( $this->section == 'new' ) {
|
2005-10-13 04:07:00 +00:00
|
|
|
$commentsubject="<span id='wpSummaryLabel'><label for='wpSummary'>{$subject}:</label></span> <div class='editOptions'><input tabindex='1' type='text' value=\"$summarytext\" name='wpSummary' id='wpSummary' maxlength='200' size='60' /><br />";
|
2005-08-20 06:57:21 +00:00
|
|
|
$editsummary = '';
|
|
|
|
|
} else {
|
|
|
|
|
$commentsubject = '';
|
2005-10-13 04:07:00 +00:00
|
|
|
$editsummary="<span id='wpSummaryLabel'><label for='wpSummary'>{$summary}:</label></span> <div class='editOptions'><input tabindex='2' type='text' value=\"$summarytext\" name='wpSummary' id='wpSummary' maxlength='200' size='60' /><br />";
|
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
|
|
|
}
|
2005-12-30 09:33:11 +00:00
|
|
|
$templates = $this->formatTemplates();
|
2005-08-02 13:35:19 +00:00
|
|
|
|
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 ) ) ;
|
2005-08-16 23:39:33 +00:00
|
|
|
$helppage = Title::newFromText( wfMsg( "metadata_page" ) ) ;
|
2005-12-26 07:14:42 +00:00
|
|
|
$top = wfMsg( 'metadata', $helppage->getLocalURL() );
|
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
|
|
|
$hidden = '';
|
|
|
|
|
$recreate = '';
|
2005-08-20 06:57:21 +00:00
|
|
|
if ($this->deletedSinceEdit) {
|
|
|
|
|
if ( 'save' != $this->formtype ) {
|
2005-08-03 06:07:41 +00:00
|
|
|
$wgOut->addWikiText( wfMsg('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 = '';
|
|
|
|
|
$hidden = 'type="hidden" style="display:none;"';
|
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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-02-20 21:18:11 +00:00
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpSave',
|
|
|
|
|
'name' => 'wpSave',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => '5',
|
|
|
|
|
'value' => wfMsg('savearticle'),
|
|
|
|
|
'accesskey' => wfMsg('accesskey-save'),
|
|
|
|
|
'title' => wfMsg('tooltip-save'),
|
|
|
|
|
);
|
|
|
|
|
$buttons['save'] = wfElement('input', $temp, '');
|
|
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpDiff',
|
|
|
|
|
'name' => 'wpDiff',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => '7',
|
|
|
|
|
'value' => wfMsg('showdiff'),
|
|
|
|
|
'accesskey' => wfMsg('accesskey-diff'),
|
|
|
|
|
'title' => wfMsg('tooltip-diff'),
|
|
|
|
|
);
|
|
|
|
|
$buttons['diff'] = wfElement('input', $temp, '');
|
|
|
|
|
|
|
|
|
|
global $wgLivePreview;
|
2006-02-23 20:03:51 +00:00
|
|
|
if ( $wgLivePreview && $wgUser->getOption( 'uselivepreview' ) ) {
|
2006-02-20 21:18:11 +00:00
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpPreview',
|
|
|
|
|
'name' => 'wpPreview',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => '6',
|
|
|
|
|
'value' => wfMsg('showpreview'),
|
|
|
|
|
'accesskey' => '',
|
|
|
|
|
'title' => wfMsg('tooltip-preview'),
|
|
|
|
|
'style' => 'display: none;',
|
|
|
|
|
);
|
|
|
|
|
$buttons['preview'] = wfElement('input', $temp, '');
|
|
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpLivePreview',
|
|
|
|
|
'name' => 'wpLivePreview',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => '6',
|
|
|
|
|
'value' => wfMsg('showlivepreview'),
|
|
|
|
|
'accesskey' => wfMsg('accesskey-preview'),
|
|
|
|
|
'title' => '',
|
|
|
|
|
'onclick' => $this->doLivePreviewScript(),
|
|
|
|
|
);
|
|
|
|
|
$buttons['live'] = wfElement('input', $temp, '');
|
|
|
|
|
} else {
|
|
|
|
|
$temp = array(
|
|
|
|
|
'id' => 'wpPreview',
|
|
|
|
|
'name' => 'wpPreview',
|
|
|
|
|
'type' => 'submit',
|
|
|
|
|
'tabindex' => '6',
|
|
|
|
|
'value' => wfMsg('showpreview'),
|
|
|
|
|
'accesskey' => wfMsg('accesskey-preview'),
|
|
|
|
|
'title' => wfMsg('tooltip-preview'),
|
|
|
|
|
);
|
|
|
|
|
$buttons['preview'] = wfElement('input', $temp, '');
|
|
|
|
|
$buttons['live'] = '';
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-29 10:08:41 +00:00
|
|
|
$safemodehtml = $this->checkUnicodeCompliantBrowser()
|
|
|
|
|
? ""
|
|
|
|
|
: "<input type='hidden' name=\"safemode\" value='1' />\n";
|
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}
|
2004-12-19 08:00:50 +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
|
|
|
|
|
|
|
|
// Put these up at the top to ensure they aren't lost on early form submission
|
|
|
|
|
$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" );
|
|
|
|
|
|
2005-09-29 23:35:31 +00:00
|
|
|
$wgOut->addHTML( <<<END
|
2005-08-02 20:17:23 +00:00
|
|
|
$recreate
|
2003-08-02 20:43:11 +00:00
|
|
|
{$commentsubject}
|
2005-10-26 10:59:44 +00:00
|
|
|
<textarea tabindex='1' accesskey="," name="wpTextbox1" id="wpTextbox1" rows='{$rows}'
|
2005-08-02 20:17:23 +00:00
|
|
|
cols='{$cols}'{$ew} $hidden>
|
2004-12-19 08:00:50 +00:00
|
|
|
END
|
2005-07-29 10:08:41 +00:00
|
|
|
. htmlspecialchars( $this->safeUnicodeOutput( $this->textbox1 ) ) .
|
2003-08-02 20:43:11 +00:00
|
|
|
"
|
2005-12-02 03:29:37 +00:00
|
|
|
</textarea>
|
|
|
|
|
" );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-12-04 00:35:14 +00:00
|
|
|
$wgOut->addWikiText( $copywarn );
|
|
|
|
|
$wgOut->addHTML( "
|
|
|
|
|
{$metadata}
|
|
|
|
|
{$editsummary}
|
|
|
|
|
{$checkboxhtml}
|
|
|
|
|
{$safemodehtml}
|
|
|
|
|
");
|
2005-12-02 03:29:37 +00:00
|
|
|
|
2006-02-20 21:18:11 +00:00
|
|
|
$wgOut->addHTML("
|
2005-10-13 04:07:00 +00:00
|
|
|
<div class='editButtons'>
|
2006-02-20 21:18:11 +00:00
|
|
|
{$buttons['save']}
|
|
|
|
|
{$buttons['preview']}
|
|
|
|
|
{$buttons['live']}
|
|
|
|
|
{$buttons['diff']}
|
|
|
|
|
<span class='editHelp'>{$cancel} | {$edithelp}</span>
|
|
|
|
|
</div><!-- editButtons -->
|
|
|
|
|
</div><!-- editOptions -->");
|
2005-12-04 00:35:14 +00:00
|
|
|
|
|
|
|
|
$wgOut->addWikiText( wfMsgForContent( 'edittools' ) );
|
|
|
|
|
|
|
|
|
|
$wgOut->addHTML( "
|
|
|
|
|
<div class='templatesUsed'>
|
|
|
|
|
{$templates}
|
|
|
|
|
</div>
|
|
|
|
|
" );
|
|
|
|
|
|
2005-02-21 12:46:37 +00:00
|
|
|
if ( $wgUser->isLoggedIn() ) {
|
2005-02-15 00:24:49 +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.
|
|
|
|
|
*/
|
2005-04-28 23:06:47 +00:00
|
|
|
$token = htmlspecialchars( $wgUser->editToken() );
|
2005-08-20 06:57:21 +00:00
|
|
|
$wgOut->addHTML( "\n<input type='hidden' value=\"$token\" name=\"wpEditToken\" />\n" );
|
2005-02-15 00:24:49 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-03-25 02:48:31 +00:00
|
|
|
# If a blank edit summary was previously provided, and the appropriate
|
|
|
|
|
# user preference is active, pass a hidden tag here. This will stop the
|
|
|
|
|
# user being bounced back more than once in the event that a summary
|
|
|
|
|
# is not required.
|
2006-03-25 00:57:14 +00:00
|
|
|
if( $this->missingSummary ) {
|
|
|
|
|
$wgOut->addHTML( "<input type=\"hidden\" name=\"wpIgnoreBlankSummary\" value=\"1\" />\n" );
|
|
|
|
|
}
|
2006-03-25 02:48:31 +00:00
|
|
|
|
|
|
|
|
# For a bit more sophisticated detection of blank summaries, hash the
|
|
|
|
|
# automatic one and pass that in a hidden field.
|
2006-03-28 00:03:23 +00:00
|
|
|
$autosumm = $this->autoSumm ? $this->autoSumm : md5( $this->summary );
|
2006-03-25 02:48:31 +00:00
|
|
|
$wgOut->addHTML( "<input type=\"hidden\" name=\"wpAutoSummary\" value=\"$autosumm\" />\n" );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->isConflict ) {
|
2004-08-21 09:32:34 +00:00
|
|
|
require_once( "DifferenceEngine.php" );
|
2005-05-14 17:55:04 +00:00
|
|
|
$wgOut->addWikiText( '==' . wfMsg( "yourdiff" ) . '==' );
|
2005-11-15 11:12:21 +00:00
|
|
|
|
|
|
|
|
$de = new DifferenceEngine( $this->mTitle );
|
|
|
|
|
$de->setText( $this->textbox2, $this->textbox1 );
|
|
|
|
|
$de->showDiff( wfMsg( "yourtext" ), wfMsg( "storedversion" ) );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2005-05-14 17:55:04 +00:00
|
|
|
$wgOut->addWikiText( '==' . wfMsg( "yourtext" ) . '==' );
|
2005-05-04 02:05:21 +00:00
|
|
|
$wgOut->addHTML( "<textarea tabindex=6 id='wpTextbox2' name=\"wpTextbox2\" rows='{$rows}' cols='{$cols}' wrap='virtual'>"
|
2005-08-20 06:57:21 +00:00
|
|
|
. htmlspecialchars( $this->safeUnicodeOutput( $this->textbox2 ) ) . "\n</textarea>" );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
$wgOut->addHTML( "</form>\n" );
|
2006-02-20 21:18:11 +00:00
|
|
|
if ( !$wgUser->getOption( 'previewontop' ) ) {
|
|
|
|
|
|
|
|
|
|
if ( $this->formtype == 'preview') {
|
|
|
|
|
$this->showPreview();
|
|
|
|
|
} else {
|
|
|
|
|
$wgOut->addHTML( '<div id="wikiPreview"></div>' );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $this->formtype == 'diff') {
|
|
|
|
|
$wgOut->addHTML( $this->getDiff() );
|
|
|
|
|
}
|
|
|
|
|
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2005-08-21 04:45:28 +00:00
|
|
|
|
|
|
|
|
wfProfileOut( $fname );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-11-03 22:40:02 +00:00
|
|
|
/**
|
|
|
|
|
* Append preview output to $wgOut.
|
|
|
|
|
* Includes category rendering if this is a category page.
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-11-03 22:40:02 +00:00
|
|
|
*/
|
|
|
|
|
function showPreview() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->addHTML( '<div id="wikiPreview">' );
|
|
|
|
|
if($this->mTitle->getNamespace() == NS_CATEGORY) {
|
|
|
|
|
$this->mArticle->openShowCategory();
|
|
|
|
|
}
|
|
|
|
|
$previewOutput = $this->getPreviewText();
|
|
|
|
|
$wgOut->addHTML( $previewOutput );
|
|
|
|
|
if($this->mTitle->getNamespace() == NS_CATEGORY) {
|
|
|
|
|
$this->mArticle->closeShowCategory();
|
|
|
|
|
}
|
|
|
|
|
$wgOut->addHTML( "<br style=\"clear:both;\" />\n" );
|
|
|
|
|
$wgOut->addHTML( '</div>' );
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
/**
|
|
|
|
|
* Prepare a list of templates used by this page. Returns HTML.
|
|
|
|
|
*/
|
2005-12-30 09:33:11 +00:00
|
|
|
function formatTemplates() {
|
2005-08-20 06:57:21 +00:00
|
|
|
global $wgUser;
|
2005-08-21 04:45:28 +00:00
|
|
|
|
2005-12-30 09:33:11 +00:00
|
|
|
$fname = 'EditPage::formatTemplates';
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
$sk =& $wgUser->getSkin();
|
|
|
|
|
|
2005-12-30 09:33:11 +00:00
|
|
|
$outText = '';
|
|
|
|
|
$templates = $this->mArticle->getUsedTemplates();
|
|
|
|
|
if ( count( $templates ) > 0 ) {
|
2006-01-11 06:33:48 +00:00
|
|
|
# Do a batch existence check
|
|
|
|
|
$batch = new LinkBatch;
|
|
|
|
|
foreach( $templates as $title ) {
|
|
|
|
|
$batch->addObj( $title );
|
|
|
|
|
}
|
|
|
|
|
$batch->execute();
|
|
|
|
|
|
|
|
|
|
# Construct the HTML
|
2005-12-30 09:33:11 +00:00
|
|
|
$outText = '<br />'. wfMsg( 'templatesused' ) . '<ul>';
|
|
|
|
|
foreach ( $templates as $titleObj ) {
|
|
|
|
|
$outText .= '<li>' . $sk->makeLinkObj( $titleObj ) . '</li>';
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2005-12-30 09:33:11 +00:00
|
|
|
$outText .= '</ul>';
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-12-30 09:33:11 +00:00
|
|
|
return $outText;
|
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() {
|
2006-02-20 21:18:11 +00:00
|
|
|
global $wgStylePath, $wgJsMimeType, $wgOut, $wgTitle;
|
2005-08-20 06:57:21 +00:00
|
|
|
$wgOut->addHTML( '<script type="'.$wgJsMimeType.'" src="' .
|
|
|
|
|
htmlspecialchars( $wgStylePath . '/common/preview.js' ) .
|
|
|
|
|
'"></script>' . "\n" );
|
|
|
|
|
$liveAction = $wgTitle->getLocalUrl( 'action=submit&wpPreview=true&live=true' );
|
2006-02-20 21:18:11 +00:00
|
|
|
return "return !livePreview(" .
|
|
|
|
|
"getElementById('wikiPreview')," .
|
|
|
|
|
"editform.wpTextbox1.value," .
|
|
|
|
|
'"' . $liveAction . '"' . ")";
|
2005-08-20 06:57:21 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-08-02 20:17:23 +00:00
|
|
|
function getLastDelete() {
|
|
|
|
|
$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', ),
|
2005-08-22 23:30:12 +00:00
|
|
|
array( 'log_namespace' => $this->mTitle->getNamespace(),
|
|
|
|
|
'log_title' => $this->mTitle->getDBkey(),
|
|
|
|
|
'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
|
|
|
/**
|
|
|
|
|
* @todo document
|
|
|
|
|
*/
|
2005-08-20 06:57:21 +00:00
|
|
|
function getPreviewText() {
|
2005-12-04 18:27:59 +00:00
|
|
|
global $wgOut, $wgUser, $wgTitle, $wgParser;
|
2005-08-21 04:45:28 +00:00
|
|
|
|
|
|
|
|
$fname = 'EditPage::getPreviewText';
|
|
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
2005-10-31 22:36:35 +00:00
|
|
|
if ( $this->mTokenOk ) {
|
|
|
|
|
$msg = 'previewnote';
|
|
|
|
|
} else {
|
|
|
|
|
$msg = 'session_fail_preview';
|
|
|
|
|
}
|
2005-02-25 09:13:03 +00:00
|
|
|
$previewhead = '<h2>' . htmlspecialchars( wfMsg( 'preview' ) ) . "</h2>\n" .
|
2005-10-31 22:36:35 +00:00
|
|
|
"<div class='previewnote'>" . $wgOut->parse( wfMsg( $msg ) ) . "</div>\n";
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->isConflict ) {
|
2005-10-13 01:25:55 +00:00
|
|
|
$previewhead.='<h2>' . htmlspecialchars( wfMsg( 'previewconflict' ) ) . "</h2>\n";
|
2004-12-19 02:36:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$parserOptions = ParserOptions::newFromUser( $wgUser );
|
|
|
|
|
$parserOptions->setEditSection( false );
|
|
|
|
|
|
|
|
|
|
# don't parse user css/js, show message about preview
|
|
|
|
|
# XXX: stupid php bug won't let us use $wgTitle->isCssJsSubpage() here
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->isCssJsSubpage ) {
|
2004-12-19 02:36:04 +00:00
|
|
|
if(preg_match("/\\.css$/", $wgTitle->getText() ) ) {
|
|
|
|
|
$previewtext = wfMsg('usercsspreview');
|
|
|
|
|
} else if(preg_match("/\\.js$/", $wgTitle->getText() ) ) {
|
|
|
|
|
$previewtext = wfMsg('userjspreview');
|
|
|
|
|
}
|
2006-03-07 01:10:39 +00:00
|
|
|
$parserOptions->setTidy(true);
|
2004-12-19 02:36:04 +00:00
|
|
|
$parserOutput = $wgParser->parse( $previewtext , $wgTitle, $parserOptions );
|
|
|
|
|
$wgOut->addHTML( $parserOutput->mText );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-02-15 00:24:49 +00:00
|
|
|
return $previewhead;
|
2004-12-19 02:36:04 +00:00
|
|
|
} else {
|
|
|
|
|
# if user want to see preview when he edit an article
|
|
|
|
|
if( $wgUser->getOption('previewonfirst') and ($this->textbox1 == '')) {
|
2006-01-13 00:29:20 +00:00
|
|
|
$this->textbox1 = $this->mArticle->getContent();
|
2004-12-19 02:36:04 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-13 21:25:30 +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
|
|
|
|
2004-12-29 13:46:10 +00:00
|
|
|
if ( $this->mMetaData != "" ) $toparse .= "\n" . $this->mMetaData ;
|
2006-03-07 01:10:39 +00:00
|
|
|
$parserOptions->setTidy(true);
|
2004-12-29 13:46:10 +00:00
|
|
|
$parserOutput = $wgParser->parse( $this->mArticle->preSaveTransform( $toparse ) ."\n\n",
|
2005-08-02 13:35:19 +00:00
|
|
|
$wgTitle, $parserOptions );
|
|
|
|
|
|
2006-01-01 20:08:08 +00:00
|
|
|
$previewHTML = $parserOutput->getText();
|
|
|
|
|
$wgOut->addParserOutputNoText( $parserOutput );
|
2005-08-21 04:45:28 +00:00
|
|
|
|
|
|
|
|
wfProfileOut( $fname );
|
2005-02-15 00:24:49 +00:00
|
|
|
return $previewhead . $previewHTML;
|
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
|
|
|
*/
|
|
|
|
|
function blockedIPpage() {
|
2006-01-06 23:09:37 +00:00
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->blockedPage();
|
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() {
|
2006-04-26 09:30:31 +00:00
|
|
|
global $wgUser, $wgOut;
|
|
|
|
|
$skin = $wgUser->getSkin();
|
2006-05-02 16:53:32 +00:00
|
|
|
|
2006-04-26 09:30:31 +00:00
|
|
|
$loginTitle = Title::makeTitle( NS_SPECIAL, 'Userlogin' );
|
2006-05-02 02:59:18 +00:00
|
|
|
$loginLink = $skin->makeKnownLinkObj( $loginTitle, wfMsgHtml( 'loginreqlink' ), 'returnto=' . $this->mTitle->getPrefixedUrl() );
|
2006-04-26 09:30:31 +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 );
|
2006-04-26 09:30:31 +00:00
|
|
|
|
|
|
|
|
$wgOut->addHtml( wfMsgWikiHtml( 'whitelistedittext', $loginLink ) );
|
2006-05-02 16:53:32 +00:00
|
|
|
$wgOut->returnToMain( false, $this->mTitle->getPrefixedUrl() );
|
2003-08-05 11:04:02 +00:00
|
|
|
}
|
|
|
|
|
|
2006-02-10 09:37:46 +00:00
|
|
|
/**
|
|
|
|
|
* Creates a basic error page which informs the user that
|
|
|
|
|
* they have to validate their email address before being
|
|
|
|
|
* allowed to edit.
|
|
|
|
|
*/
|
2006-02-10 09:34:31 +00:00
|
|
|
function userNotConfirmedPage() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
|
|
|
|
|
$wgOut->setPageTitle( wfMsg( 'confirmedittitle' ) );
|
2006-05-02 17:06:24 +00:00
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
2006-02-10 09:34:31 +00:00
|
|
|
$wgOut->setArticleRelated( false );
|
2006-05-02 17:06:24 +00:00
|
|
|
|
2006-02-10 09:34:31 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'confirmedittext' ) );
|
|
|
|
|
$wgOut->returnToMain( false );
|
|
|
|
|
}
|
|
|
|
|
|
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 ) {
|
2004-06-21 07:41:53 +00:00
|
|
|
global $wgOut;
|
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 );
|
|
|
|
|
|
2004-08-13 20:52:15 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'spamprotectiontext' ) );
|
2006-05-02 17:06:24 +00:00
|
|
|
if ( $match )
|
2004-12-11 11:32:53 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'spamprotectionmatch', "<nowiki>{$match}</nowiki>" ) );
|
2006-05-02 17:06:24 +00:00
|
|
|
|
2004-05-29 07:41:16 +00:00
|
|
|
$wgOut->returnToMain( false );
|
|
|
|
|
}
|
|
|
|
|
|
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 );
|
|
|
|
|
|
2005-05-28 12:21:56 +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
|
|
|
|
|
$baseRevision = Revision::loadFromTimestamp(
|
|
|
|
|
$db, $this->mArticle->mTitle, $this->edittime );
|
|
|
|
|
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(
|
|
|
|
|
$db, $this->mArticle->mTitle );
|
|
|
|
|
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
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
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 ) {
|
2005-05-31 11:54:36 +00:00
|
|
|
$headline = Sanitizer::decodeCharReferences( $text );
|
2005-08-02 13:35:19 +00:00
|
|
|
# strip out HTML
|
2004-10-26 05:44:54 +00:00
|
|
|
$headline = preg_replace( '/<.*?' . '>/', '', $headline );
|
|
|
|
|
$headline = trim( $headline );
|
|
|
|
|
$sectionanchor = '#' . urlencode( str_replace( ' ', '_', $headline ) );
|
|
|
|
|
$replacearray = array(
|
|
|
|
|
'%3A' => ':',
|
|
|
|
|
'%' => '.'
|
|
|
|
|
);
|
|
|
|
|
return str_replace(
|
|
|
|
|
array_keys( $replacearray ),
|
|
|
|
|
array_values( $replacearray ),
|
|
|
|
|
$sectionanchor );
|
|
|
|
|
}
|
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.
|
|
|
|
|
* The necessary JavaScript code can be found in style/wikibits.js.
|
|
|
|
|
*/
|
|
|
|
|
function getEditToolbar() {
|
2006-01-07 13:36:19 +00:00
|
|
|
global $wgStylePath, $wgContLang, $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.
|
|
|
|
|
*/
|
|
|
|
|
$toolarray=array(
|
|
|
|
|
array( 'image'=>'button_bold.png',
|
|
|
|
|
'open' => "\'\'\'",
|
|
|
|
|
'close' => "\'\'\'",
|
|
|
|
|
'sample'=> wfMsg('bold_sample'),
|
|
|
|
|
'tip' => wfMsg('bold_tip'),
|
|
|
|
|
'key' => 'B'
|
|
|
|
|
),
|
|
|
|
|
array( 'image'=>'button_italic.png',
|
|
|
|
|
'open' => "\'\'",
|
|
|
|
|
'close' => "\'\'",
|
|
|
|
|
'sample'=> wfMsg('italic_sample'),
|
|
|
|
|
'tip' => wfMsg('italic_tip'),
|
|
|
|
|
'key' => 'I'
|
|
|
|
|
),
|
|
|
|
|
array( 'image'=>'button_link.png',
|
|
|
|
|
'open' => '[[',
|
|
|
|
|
'close' => ']]',
|
|
|
|
|
'sample'=> wfMsg('link_sample'),
|
|
|
|
|
'tip' => wfMsg('link_tip'),
|
|
|
|
|
'key' => 'L'
|
|
|
|
|
),
|
|
|
|
|
array( 'image'=>'button_extlink.png',
|
|
|
|
|
'open' => '[',
|
|
|
|
|
'close' => ']',
|
|
|
|
|
'sample'=> wfMsg('extlink_sample'),
|
|
|
|
|
'tip' => wfMsg('extlink_tip'),
|
|
|
|
|
'key' => 'X'
|
|
|
|
|
),
|
|
|
|
|
array( 'image'=>'button_headline.png',
|
|
|
|
|
'open' => "\\n== ",
|
|
|
|
|
'close' => " ==\\n",
|
|
|
|
|
'sample'=> wfMsg('headline_sample'),
|
|
|
|
|
'tip' => wfMsg('headline_tip'),
|
|
|
|
|
'key' => 'H'
|
|
|
|
|
),
|
|
|
|
|
array( 'image'=>'button_image.png',
|
2006-01-07 13:36:19 +00:00
|
|
|
'open' => '[['.$wgContLang->getNsText(NS_IMAGE).":",
|
2004-11-25 13:52:56 +00:00
|
|
|
'close' => ']]',
|
|
|
|
|
'sample'=> wfMsg('image_sample'),
|
|
|
|
|
'tip' => wfMsg('image_tip'),
|
|
|
|
|
'key' => 'D'
|
|
|
|
|
),
|
2005-04-28 20:44:26 +00:00
|
|
|
array( 'image' =>'button_media.png',
|
2006-01-07 13:36:19 +00:00
|
|
|
'open' => '[['.$wgContLang->getNsText(NS_MEDIA).':',
|
2004-11-25 13:52:56 +00:00
|
|
|
'close' => ']]',
|
|
|
|
|
'sample'=> wfMsg('media_sample'),
|
|
|
|
|
'tip' => wfMsg('media_tip'),
|
|
|
|
|
'key' => 'M'
|
|
|
|
|
),
|
2005-04-28 20:44:26 +00:00
|
|
|
array( 'image' =>'button_math.png',
|
2004-11-25 13:52:56 +00:00
|
|
|
'open' => "\\<math\\>",
|
|
|
|
|
'close' => "\\</math\\>",
|
|
|
|
|
'sample'=> wfMsg('math_sample'),
|
|
|
|
|
'tip' => wfMsg('math_tip'),
|
|
|
|
|
'key' => 'C'
|
|
|
|
|
),
|
2005-04-28 20:44:26 +00:00
|
|
|
array( 'image' =>'button_nowiki.png',
|
2004-11-25 13:52:56 +00:00
|
|
|
'open' => "\\<nowiki\\>",
|
|
|
|
|
'close' => "\\</nowiki\\>",
|
|
|
|
|
'sample'=> wfMsg('nowiki_sample'),
|
|
|
|
|
'tip' => wfMsg('nowiki_tip'),
|
|
|
|
|
'key' => 'N'
|
|
|
|
|
),
|
2005-04-28 20:44:26 +00:00
|
|
|
array( 'image' =>'button_sig.png',
|
2004-11-25 13:52:56 +00:00
|
|
|
'open' => '--~~~~',
|
|
|
|
|
'close' => '',
|
|
|
|
|
'sample'=> '',
|
|
|
|
|
'tip' => wfMsg('sig_tip'),
|
|
|
|
|
'key' => 'Y'
|
|
|
|
|
),
|
2005-04-28 20:44:26 +00:00
|
|
|
array( 'image' =>'button_hr.png',
|
2004-11-25 13:52:56 +00:00
|
|
|
'open' => "\\n----\\n",
|
|
|
|
|
'close' => '',
|
|
|
|
|
'sample'=> '',
|
|
|
|
|
'tip' => wfMsg('hr_tip'),
|
|
|
|
|
'key' => 'R'
|
|
|
|
|
)
|
|
|
|
|
);
|
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) {
|
|
|
|
|
|
|
|
|
|
$image=$wgStylePath.'/common/images/'.$tool['image'];
|
|
|
|
|
$open=$tool['open'];
|
|
|
|
|
$close=$tool['close'];
|
2005-04-30 08:04:02 +00:00
|
|
|
$sample = wfEscapeJsString( $tool['sample'] );
|
2004-11-25 13:52:56 +00:00
|
|
|
|
|
|
|
|
// 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.
|
2005-04-30 09:13:44 +00:00
|
|
|
$tip = wfEscapeJsString( $tool['tip'] );
|
2004-11-25 13:52:56 +00:00
|
|
|
|
|
|
|
|
#$key = $tool["key"];
|
|
|
|
|
|
|
|
|
|
$toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$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
|
|
|
|
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.
|
|
|
|
|
* Would need to enhance it a bit, maybe wrap them in XML
|
|
|
|
|
* or something... that might also require more skin
|
|
|
|
|
* initialization, so check whether that's a problem.
|
|
|
|
|
*/
|
|
|
|
|
function livePreview() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->disable();
|
|
|
|
|
header( 'Content-type: text/xml' );
|
|
|
|
|
header( 'Cache-control: no-cache' );
|
|
|
|
|
# FIXME
|
2006-02-20 21:18:11 +00:00
|
|
|
echo $this->getPreviewText( );
|
|
|
|
|
/* To not shake screen up and down between preview and live-preview */
|
|
|
|
|
echo "<br style=\"clear:both;\" />\n";
|
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.
|
|
|
|
|
*
|
|
|
|
|
* @return string HTML
|
|
|
|
|
*/
|
|
|
|
|
function getDiff() {
|
|
|
|
|
require_once( 'DifferenceEngine.php' );
|
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 );
|
|
|
|
|
$oldtitle = wfMsg( 'currentrev' );
|
|
|
|
|
$newtitle = wfMsg( 'yourtext' );
|
2005-11-15 11:12:21 +00:00
|
|
|
if ( $oldtext !== false || $newtext != '' ) {
|
|
|
|
|
$de = new DifferenceEngine( $this->mTitle );
|
|
|
|
|
$de->setText( $oldtext, $newtext );
|
|
|
|
|
$difftext = $de->getDiff( $oldtitle, $newtitle );
|
|
|
|
|
} else {
|
|
|
|
|
$difftext = '';
|
2005-05-15 11:11:23 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-05-15 11:11:23 +00:00
|
|
|
return '<div id="wikiDiff">' . $difftext . '</div>';
|
|
|
|
|
}
|
|
|
|
|
|
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() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->setPageTitle( wfMsg( 'nocreatetitle' ) );
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'nocreatetext' ) );
|
|
|
|
|
}
|
2005-07-29 10:08:41 +00:00
|
|
|
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
?>
|