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 {
|
|
|
|
|
var $mArticle;
|
|
|
|
|
var $mTitle;
|
2004-12-29 13:46:10 +00:00
|
|
|
var $mMetaData = '';
|
2005-08-20 06:57:21 +00:00
|
|
|
var $isConflict = false;
|
|
|
|
|
var $isCssJsSubpage = false;
|
|
|
|
|
var $deletedSinceEdit = false;
|
|
|
|
|
var $formtype;
|
|
|
|
|
var $firsttime;
|
2005-08-20 07:47:56 +00:00
|
|
|
var $lastDelete;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-03-08 09:09:35 +00:00
|
|
|
# Form values
|
2005-03-19 12:01:57 +00:00
|
|
|
var $save = false, $preview = false, $diff = false;
|
2005-08-02 20:17:23 +00:00
|
|
|
var $minoredit = false, $watchthis = false, $recreate = false;
|
2004-08-22 17:24:50 +00:00
|
|
|
var $textbox1 = '', $textbox2 = '', $summary = '';
|
2005-08-02 20:17:23 +00:00
|
|
|
var $edittime = '', $section = '', $starttime = '';
|
2005-08-20 06:57:21 +00:00
|
|
|
var $oldid = 0, $editintro = '';
|
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 = '' ;
|
2004-12-29 13:46:10 +00:00
|
|
|
$t = $this->mArticle->getContent ( true ) ;
|
|
|
|
|
|
|
|
|
|
# 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 ) ;
|
|
|
|
|
$wl = explode ( "\n" , $wl_article->getContent(true) ) ;
|
|
|
|
|
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
|
|
|
/**
|
2005-08-20 06:57:21 +00:00
|
|
|
* This is the function that gets called for "action=edit". It
|
|
|
|
|
* sets up various member variables, then passes execution to
|
|
|
|
|
* another function, usually showEditForm()
|
|
|
|
|
*
|
|
|
|
|
* 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() {
|
2005-08-20 06:57:21 +00:00
|
|
|
global $wgOut, $wgUser, $wgRequest, $wgTitle;
|
2005-08-21 04:45:28 +00:00
|
|
|
|
|
|
|
|
$fname = 'EditPage::edit';
|
|
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
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() ) {
|
2004-04-30 08:19:59 +00:00
|
|
|
$wgOut->readOnlyPage( $this->mArticle->getContent( true ), true );
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2003-08-02 20:43:11 +00:00
|
|
|
return;
|
|
|
|
|
}
|
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.
|
2003-08-02 20:43:11 +00:00
|
|
|
$this->blockedIPpage();
|
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() ) {
|
|
|
|
|
$this->userNotLoggedInPage();
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-06-25 06:24:46 +00:00
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
$wgOut->readOnlyPage( $this->mArticle->getContent( true ), 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
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
if ( wfReadOnly() ) {
|
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 {
|
2004-04-30 08:19:59 +00:00
|
|
|
$wgOut->readOnlyPage( $this->mArticle->getContent( true ) );
|
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" );
|
2005-08-20 06:57:21 +00:00
|
|
|
|
|
|
|
|
$this->isConflict = false;
|
|
|
|
|
// css / js subpages of user pages get a special treatment
|
|
|
|
|
$this->isCssJsSubpage = $wgTitle->isCssJsSubpage();
|
|
|
|
|
|
|
|
|
|
/* 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
|
|
|
}
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 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
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
function previewOnOpen() {
|
|
|
|
|
global $wgUser;
|
|
|
|
|
return $wgUser->getOption( 'previewonfirst' ) ||
|
|
|
|
|
( $this->mTitle->getNamespace() == NS_CATEGORY &&
|
|
|
|
|
!$this->mTitle->exists() );
|
|
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
|
|
|
|
* @todo document
|
|
|
|
|
*/
|
2004-03-08 09:09:35 +00:00
|
|
|
function importFormData( &$request ) {
|
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-06-01 08:18:34 +00:00
|
|
|
$this->summary = $request->getText( 'wpSummary' );
|
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-02-15 00:24:49 +00:00
|
|
|
if( is_null( $this->edittime ) ) {
|
|
|
|
|
# If the form is incomplete, force to preview.
|
|
|
|
|
$this->preview = true;
|
|
|
|
|
} else {
|
|
|
|
|
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.
|
|
|
|
|
$this->preview = $request->getCheck( 'wpPreview' );
|
2005-03-19 12:01:57 +00:00
|
|
|
$this->diff = $request->getCheck( 'wpDiff' );
|
2005-02-15 00:24:49 +00:00
|
|
|
} else {
|
|
|
|
|
# Page might be a hack attempt posted from
|
|
|
|
|
# an external site. Preview instead of saving.
|
|
|
|
|
$this->preview = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->recreate = $request->getCheck( 'wpRecreate' );
|
|
|
|
|
|
2005-02-15 00:24:49 +00:00
|
|
|
$this->minoredit = $request->getCheck( 'wpMinoredit' );
|
|
|
|
|
$this->watchthis = $request->getCheck( 'wpWatchthis' );
|
|
|
|
|
} else {
|
|
|
|
|
# Not a posted form? Start with nothing.
|
|
|
|
|
$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' );
|
|
|
|
|
|
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.
|
|
|
|
|
*
|
|
|
|
|
* @param WebRequest $request
|
|
|
|
|
* @return bool
|
|
|
|
|
* @access 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.
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
function showIntro() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
$addstandardintro=true;
|
|
|
|
|
if($this->editintro) {
|
|
|
|
|
$introtitle=Title::newFromText($this->editintro);
|
|
|
|
|
if(isset($introtitle) && $introtitle->userCanRead()) {
|
|
|
|
|
$rev=Revision::newFromTitle($introtitle);
|
|
|
|
|
if($rev) {
|
|
|
|
|
$wgOut->addWikiText($rev->getText());
|
|
|
|
|
$addstandardintro=false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if($addstandardintro) {
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'newarticletext' ) );
|
|
|
|
|
}
|
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;
|
2005-02-21 12:23:52 +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
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
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-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;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-21 07:28:11 +00:00
|
|
|
wfProfileOut( "$fname-checks" );
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# If article is new, insert it.
|
|
|
|
|
$aid = $this->mTitle->getArticleID( GAID_FOR_UPDATE );
|
|
|
|
|
if ( 0 == $aid ) {
|
|
|
|
|
# Don't save a new article if it's blank.
|
|
|
|
|
if ( ( '' == $this->textbox1 ) ||
|
|
|
|
|
( wfMsg( 'newarticletext' ) == $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;
|
2004-11-28 06:45:24 +00:00
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
if (wfRunHooks('ArticleSave', array(&$this->mArticle, &$wgUser, &$this->textbox1,
|
|
|
|
|
&$this->summary, &$this->minoredit, &$this->watchthis, NULL)))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
$isComment=($this->section=='new');
|
|
|
|
|
$this->mArticle->insertNewArticle( $this->textbox1, $this->summary,
|
|
|
|
|
$this->minoredit, $this->watchthis, false, $isComment);
|
|
|
|
|
wfRunHooks('ArticleSaveComplete', array(&$this->mArticle, &$wgUser, $this->textbox1,
|
|
|
|
|
$this->summary, $this->minoredit,
|
|
|
|
|
$this->watchthis, NULL));
|
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 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
|
2004-03-14 22:28:52 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
if( ( $this->section != 'new' ) &&
|
|
|
|
|
($this->mArticle->getTimestamp() != $this->edittime ) )
|
|
|
|
|
{
|
|
|
|
|
$this->isConflict = true;
|
|
|
|
|
}
|
|
|
|
|
$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
|
|
|
}
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
# Suppress edit conflict with self
|
|
|
|
|
if ( ( 0 != $userid ) && ( $this->mArticle->getUser() == $userid ) ) {
|
|
|
|
|
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
|
|
|
}
|
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
|
|
|
}
|
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' ) {
|
|
|
|
|
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 = '';
|
|
|
|
|
|
|
|
|
|
if (wfRunHooks('ArticleSave', array(&$this->mArticle, &$wgUser, &$text,
|
|
|
|
|
&$this->summary, &$this->minoredit,
|
|
|
|
|
&$this->watchthis, &$sectionanchor)))
|
|
|
|
|
{
|
|
|
|
|
# update the article here
|
|
|
|
|
if($this->mArticle->updateArticle( $text, $this->summary, $this->minoredit,
|
|
|
|
|
$this->watchthis, '', $sectionanchor ))
|
|
|
|
|
{
|
|
|
|
|
wfRunHooks('ArticleSaveComplete',
|
|
|
|
|
array(&$this->mArticle, &$wgUser, $text,
|
|
|
|
|
$this->summary, $this->minoredit,
|
|
|
|
|
$this->watchthis, $sectionanchor));
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
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();
|
|
|
|
|
$this->textbox1 = $this->mArticle->getContent( true );
|
|
|
|
|
$this->summary = '';
|
|
|
|
|
$this->proxyCheck();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Send the edit form and related headers to $wgOut
|
|
|
|
|
*/
|
|
|
|
|
function showEditForm() {
|
|
|
|
|
global $wgOut, $wgUser, $wgAllowAnonymousMinor, $wgLang, $wgContLang;
|
|
|
|
|
|
2005-08-21 04:45:28 +00:00
|
|
|
$fname = 'EditPage::showEditForm';
|
|
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
$sk =& $wgUser->getSkin();
|
|
|
|
|
|
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;
|
2004-04-30 08:19:59 +00:00
|
|
|
$this->textbox1 = $this->mArticle->getContent( true );
|
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])." */ ";
|
|
|
|
|
}
|
|
|
|
|
}
|
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 );
|
2005-03-26 22:23:48 +00:00
|
|
|
if ( !$this->checkUnicodeCompliantBrowser() ) {
|
2004-10-10 21:30:17 +00:00
|
|
|
$this->mArticle->setOldSubtitle();
|
|
|
|
|
$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() ) {
|
2003-08-02 20:43:11 +00:00
|
|
|
$this->mArticle->setOldSubtitle();
|
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' ) );
|
2005-08-20 06:57:21 +00:00
|
|
|
} else if ( $this->isCssJsSubpage and 'preview' != $this->formtype) {
|
2005-05-04 02:05:21 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'usercssjsyoucanpreview' ));
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
2004-11-24 12:55:48 +00:00
|
|
|
if( $this->mTitle->isProtected('edit') ) {
|
2005-05-04 02:05:21 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'protectedpagewarning' ) );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
|
2004-03-08 09:09:35 +00:00
|
|
|
$kblength = (int)(strlen( $this->textbox1 ) / 1024);
|
2003-08-02 20:43:11 +00:00
|
|
|
if( $kblength > 29 ) {
|
2005-05-04 02:05:21 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'longpagewarning', $wgLang->formatNum( $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');
|
|
|
|
|
$save = wfMsg('savearticle');
|
|
|
|
|
$prev = wfMsg('showpreview');
|
2005-03-19 12:01:57 +00:00
|
|
|
$diff = wfMsg('showdiff');
|
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') );
|
2005-06-25 21:32:11 +00:00
|
|
|
$edithelpurl = $sk->makeInternalOrExternalUrl( wfMsg( '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 ) {
|
2004-08-22 17:24:50 +00:00
|
|
|
if( $wgUser->getOption( 'watchdefault' ) ) $this->watchthis = true;
|
|
|
|
|
if( $wgUser->getOption( 'minordefault' ) ) $this->minoredit = true;
|
2004-03-18 06:56:14 +00:00
|
|
|
|
2004-03-08 09:09:35 +00:00
|
|
|
// activate checkbox also if user is already watching the page,
|
|
|
|
|
// require wpWatchthis to be unset so that second condition is not
|
|
|
|
|
// checked unnecessarily
|
|
|
|
|
if( !$this->watchthis && $this->mTitle->userIsWatching() ) $this->watchthis = true;
|
|
|
|
|
}
|
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
|
|
|
|
2005-02-21 12:46:37 +00:00
|
|
|
if ( $wgUser->isLoggedIn() || $wgAllowAnonymousMinor ) {
|
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
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$checkboxhtml = $minoredithtml . $watchhtml . '<br />';
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-12-19 02:36:04 +00:00
|
|
|
$wgOut->addHTML( '<div id="wikiPreview">' );
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( 'preview' == $this->formtype) {
|
|
|
|
|
$previewOutput = $this->getPreviewText();
|
2005-03-19 12:01:57 +00:00
|
|
|
if ( $wgUser->getOption('previewontop' ) ) {
|
2004-12-19 02:36:04 +00:00
|
|
|
$wgOut->addHTML( $previewOutput );
|
2005-06-27 00:06:30 +00:00
|
|
|
if($this->mTitle->getNamespace() == NS_CATEGORY) {
|
|
|
|
|
$this->mArticle->closeShowCategory();
|
2005-08-02 13:35:19 +00:00
|
|
|
}
|
2004-05-10 13:15:28 +00:00
|
|
|
$wgOut->addHTML( "<br style=\"clear:both;\" />\n" );
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
2004-12-19 02:36:04 +00:00
|
|
|
$wgOut->addHTML( '</div>' );
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( 'diff' == $this->formtype ) {
|
2005-03-19 12:01:57 +00:00
|
|
|
if ( $wgUser->getOption('previewontop' ) ) {
|
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' ) {
|
|
|
|
|
$commentsubject="{$subject}: <input tabindex='1' type='text' value=\"$summarytext\" name=\"wpSummary\" maxlength='200' size='60' /><br />";
|
|
|
|
|
$editsummary = '';
|
|
|
|
|
} else {
|
|
|
|
|
$commentsubject = '';
|
|
|
|
|
$editsummary="{$summary}: <input tabindex='2' type='text' value=\"$summarytext\" name=\"wpSummary\" maxlength='200' size='60' /><br />";
|
|
|
|
|
}
|
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-08-20 06:57:21 +00:00
|
|
|
$templates = $this->getTemplatesUsed();
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
global $wgLivePreview;
|
|
|
|
|
if ( $wgLivePreview ) {
|
|
|
|
|
$liveOnclick = $this->doLivePreviewScript();
|
2004-12-19 02:36:04 +00:00
|
|
|
} else {
|
|
|
|
|
$liveOnclick = '';
|
|
|
|
|
}
|
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" ) ) ;
|
|
|
|
|
$top = wfMsg( 'metadata', $helppage->getInternalURL() );
|
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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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-08-02 20:17:23 +00:00
|
|
|
$recreate
|
2003-08-02 20:43:11 +00:00
|
|
|
{$commentsubject}
|
2004-12-19 08:00:50 +00:00
|
|
|
<textarea tabindex='1' accesskey="," name="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
|
|
|
"
|
2004-04-29 12:17:33 +00:00
|
|
|
</textarea>
|
2004-12-29 13:46:10 +00:00
|
|
|
{$metadata}
|
2004-04-03 10:01:08 +00:00
|
|
|
<br />{$editsummary}
|
2003-08-02 20:43:11 +00:00
|
|
|
{$checkboxhtml}
|
2005-07-29 10:08:41 +00:00
|
|
|
{$safemodehtml}
|
2004-06-10 18:42:05 +00:00
|
|
|
<input tabindex='5' id='wpSave' type='submit' value=\"{$save}\" name=\"wpSave\" accesskey=\"".wfMsg('accesskey-save')."\"".
|
2005-05-03 20:27:34 +00:00
|
|
|
" title=\"".wfMsg('tooltip-save')."\"/>
|
2004-12-19 02:36:04 +00:00
|
|
|
<input tabindex='6' id='wpPreview' type='submit' $liveOnclick value=\"{$prev}\" name=\"wpPreview\" accesskey=\"".wfMsg('accesskey-preview')."\"".
|
2004-04-09 19:22:51 +00:00
|
|
|
" title=\"".wfMsg('tooltip-preview')."\"/>
|
2005-05-12 08:28:26 +00:00
|
|
|
<input tabindex='7' id='wpDiff' type='submit' value=\"{$diff}\" name=\"wpDiff\" accesskey=\"".wfMsg('accesskey-diff')."\"".
|
2005-03-19 12:01:57 +00:00
|
|
|
" title=\"".wfMsg('tooltip-diff')."\"/>
|
2004-08-19 11:26:44 +00:00
|
|
|
<em>{$cancel}</em> | <em>{$edithelp}</em>{$templates}" );
|
2004-08-18 00:04:06 +00:00
|
|
|
$wgOut->addWikiText( $copywarn );
|
|
|
|
|
$wgOut->addHTML( "
|
2004-04-03 10:01:08 +00:00
|
|
|
<input type='hidden' value=\"" . htmlspecialchars( $this->section ) . "\" name=\"wpSection\" />
|
2005-08-02 20:17:23 +00:00
|
|
|
<input type='hidden' value=\"{$this->starttime}\" name=\"wpStarttime\" />\n
|
2004-04-03 10:01:08 +00:00
|
|
|
<input type='hidden' value=\"{$this->edittime}\" name=\"wpEdittime\" />\n" );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
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" ) . '==' );
|
2004-03-14 13:42:16 +00:00
|
|
|
DifferenceEngine::showDiff( $this->textbox2, $this->textbox1,
|
2003-08-02 20:43:11 +00:00
|
|
|
wfMsg( "yourtext" ), wfMsg( "storedversion" ) );
|
|
|
|
|
|
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" );
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->formtype == 'preview' && !$wgUser->getOption( 'previewontop' ) ) {
|
2005-03-19 12:01:57 +00:00
|
|
|
$wgOut->addHTML( '<div id="wikiPreview">' . $previewOutput . '</div>' );
|
|
|
|
|
}
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->formtype == 'diff' && !$wgUser->getOption( 'previewontop' ) ) {
|
2005-05-15 11:11:23 +00:00
|
|
|
#$wgOut->addHTML( '<div id="wikiPreview">' . $difftext . '</div>' );
|
|
|
|
|
$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
|
|
|
}
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
/**
|
|
|
|
|
* Prepare a list of templates used by this page. Returns HTML.
|
|
|
|
|
*/
|
|
|
|
|
function getTemplatesUsed() {
|
|
|
|
|
global $wgUser;
|
2005-08-21 04:45:28 +00:00
|
|
|
|
|
|
|
|
$fname = 'EditPage::getTemplatesUsed';
|
|
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
2005-08-20 06:57:21 +00:00
|
|
|
$sk =& $wgUser->getSkin();
|
|
|
|
|
|
|
|
|
|
$templates = '';
|
|
|
|
|
$articleTemplates = $this->mArticle->getUsedTemplates();
|
|
|
|
|
if ( count( $articleTemplates ) > 0 ) {
|
|
|
|
|
$templates = '<br />'. wfMsg( 'templatesused' ) . '<ul>';
|
|
|
|
|
foreach ( $articleTemplates as $tpl ) {
|
|
|
|
|
if ( $titleObj = Title::makeTitle( NS_TEMPLATE, $tpl ) ) {
|
|
|
|
|
$templates .= '<li>' . $sk->makeLinkObj( $titleObj ) . '</li>';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$templates .= '</ul>';
|
|
|
|
|
}
|
2005-08-21 04:45:28 +00:00
|
|
|
wfProfileOut( $fname );
|
2005-08-20 06:57:21 +00:00
|
|
|
return $templates;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Live Preview lets us fetch rendered preview page content and
|
|
|
|
|
* add it to the page without refreshing the whole page.
|
|
|
|
|
* If not supported by the browser it will fall through to the normal form
|
|
|
|
|
* submission method.
|
|
|
|
|
*
|
|
|
|
|
* This function outputs a script tag to support live preview, and
|
|
|
|
|
* returns an onclick handler which should be added to the attributes
|
|
|
|
|
* of the preview button
|
|
|
|
|
*/
|
|
|
|
|
function doLivePreviewScript() {
|
|
|
|
|
global $wgStylePath, $wgJsMimeType, $wgOut;
|
|
|
|
|
$wgOut->addHTML( '<script type="'.$wgJsMimeType.'" src="' .
|
|
|
|
|
htmlspecialchars( $wgStylePath . '/common/preview.js' ) .
|
|
|
|
|
'"></script>' . "\n" );
|
|
|
|
|
$liveAction = $wgTitle->getLocalUrl( 'action=submit&wpPreview=true&live=true' );
|
|
|
|
|
return 'onclick="return !livePreview('.
|
|
|
|
|
'getElementById(\'wikiPreview\'),' .
|
|
|
|
|
'editform.wpTextbox1.value,' .
|
|
|
|
|
htmlspecialchars( '"' . $liveAction . '"' ) . ')"';
|
|
|
|
|
}
|
|
|
|
|
|
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-03-19 12:01:57 +00:00
|
|
|
global $wgOut, $wgUser, $wgTitle, $wgParser, $wgAllowDiffPreview, $wgEnableDiffPreviewPreference;
|
2005-08-21 04:45:28 +00:00
|
|
|
|
|
|
|
|
$fname = 'EditPage::getPreviewText';
|
|
|
|
|
wfProfileIn( $fname );
|
|
|
|
|
|
2005-02-25 09:13:03 +00:00
|
|
|
$previewhead = '<h2>' . htmlspecialchars( wfMsg( 'preview' ) ) . "</h2>\n" .
|
|
|
|
|
"<p class='previewnote'>" . htmlspecialchars( wfMsg( 'previewnote' ) ) . "</p>\n";
|
2005-08-20 06:57:21 +00:00
|
|
|
if ( $this->isConflict ) {
|
2005-02-25 09:13:03 +00:00
|
|
|
$previewhead.='<h2>' . htmlspecialchars( wfMsg( 'previewconflict' ) ) .
|
2004-12-19 02:36:04 +00:00
|
|
|
"</h2>\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$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');
|
|
|
|
|
}
|
|
|
|
|
$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 == '')) {
|
|
|
|
|
$this->textbox1 = $this->mArticle->getContent(true);
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-13 21:25:30 +00:00
|
|
|
$toparse = $this->textbox1;
|
|
|
|
|
|
|
|
|
|
# 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;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-29 13:46:10 +00:00
|
|
|
if ( $this->mMetaData != "" ) $toparse .= "\n" . $this->mMetaData ;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
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 );
|
|
|
|
|
|
2004-12-19 02:36:04 +00:00
|
|
|
$previewHTML = $parserOutput->mText;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 02:36:04 +00:00
|
|
|
$wgOut->addCategoryLinks($parserOutput->getCategoryLinks());
|
|
|
|
|
$wgOut->addLanguageLinks($parserOutput->getLanguageLinks());
|
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
|
|
|
/**
|
|
|
|
|
* @todo document
|
|
|
|
|
*/
|
|
|
|
|
function blockedIPpage() {
|
2004-09-24 13:14:52 +00:00
|
|
|
global $wgOut, $wgUser, $wgContLang, $wgIP;
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$wgOut->setPageTitle( wfMsg( 'blockedtitle' ) );
|
|
|
|
|
$wgOut->setRobotpolicy( 'noindex,nofollow' );
|
2004-01-17 09:49:43 +00:00
|
|
|
$wgOut->setArticleRelated( false );
|
2003-08-02 20:43:11 +00:00
|
|
|
|
|
|
|
|
$id = $wgUser->blockedBy();
|
|
|
|
|
$reason = $wgUser->blockedFor();
|
2004-08-20 14:59:49 +00:00
|
|
|
$ip = $wgIP;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-07-10 01:09:36 +00:00
|
|
|
if ( is_numeric( $id ) ) {
|
2004-08-20 14:59:49 +00:00
|
|
|
$name = User::whoIs( $id );
|
2004-07-10 01:09:36 +00:00
|
|
|
} else {
|
|
|
|
|
$name = $id;
|
2004-06-21 07:41:53 +00:00
|
|
|
}
|
2005-02-21 12:23:52 +00:00
|
|
|
$link = '[[' . $wgContLang->getNsText( NS_USER ) .
|
2003-08-02 20:43:11 +00:00
|
|
|
":{$name}|{$name}]]";
|
|
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'blockedtext', $link, $reason, $ip, $name ) );
|
2003-08-02 20:43:11 +00:00
|
|
|
$wgOut->returnToMain( false );
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
|
|
|
|
* @todo document
|
|
|
|
|
*/
|
|
|
|
|
function userNotLoggedInPage() {
|
2005-02-21 12:46:37 +00:00
|
|
|
global $wgOut;
|
2003-08-05 11:04:02 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$wgOut->setPageTitle( wfMsg( 'whitelistedittitle' ) );
|
|
|
|
|
$wgOut->setRobotpolicy( 'noindex,nofollow' );
|
2004-01-17 09:49:43 +00:00
|
|
|
$wgOut->setArticleRelated( false );
|
2003-08-05 11:04:02 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
$wgOut->addWikiText( wfMsg( 'whitelistedittext' ) );
|
2003-08-05 11:04:02 +00:00
|
|
|
$wgOut->returnToMain( false );
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
|
|
|
|
* @todo document
|
|
|
|
|
*/
|
2004-12-11 11:32:53 +00:00
|
|
|
function spamPage ( $match = false )
|
2004-05-29 07:41:16 +00:00
|
|
|
{
|
2004-06-21 07:41:53 +00:00
|
|
|
global $wgOut;
|
2004-08-22 17:24:50 +00:00
|
|
|
$wgOut->setPageTitle( wfMsg( 'spamprotectiontitle' ) );
|
|
|
|
|
$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' ) );
|
2004-12-11 11:32:53 +00:00
|
|
|
if ( $match ) {
|
|
|
|
|
$wgOut->addWikiText( wfMsg( 'spamprotectionmatch', "<nowiki>{$match}</nowiki>" ) );
|
2004-08-13 20:52:15 +00:00
|
|
|
}
|
2004-05-29 07:41:16 +00:00
|
|
|
$wgOut->returnToMain( false );
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
|
|
|
|
* Forks processes to scan the originating IP for an open proxy server
|
|
|
|
|
* MemCached can be used to skip IPs that have already been scanned
|
|
|
|
|
*/
|
|
|
|
|
function proxyCheck() {
|
2004-03-10 14:24:40 +00:00
|
|
|
global $wgBlockOpenProxies, $wgProxyPorts, $wgProxyScriptPath;
|
|
|
|
|
global $wgIP, $wgUseMemCached, $wgMemc, $wgDBname, $wgProxyMemcExpiry;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-03-10 14:24:40 +00:00
|
|
|
if ( !$wgBlockOpenProxies ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-03-10 14:24:40 +00:00
|
|
|
# Get MemCached key
|
|
|
|
|
$skip = false;
|
2004-03-13 02:20:35 +00:00
|
|
|
if ( $wgUseMemCached ) {
|
2004-08-22 17:24:50 +00:00
|
|
|
$mcKey = $wgDBname.':proxy:ip:'.$wgIP;
|
2004-03-10 14:24:40 +00:00
|
|
|
$mcValue = $wgMemc->get( $mcKey );
|
|
|
|
|
if ( $mcValue ) {
|
|
|
|
|
$skip = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-08-05 11:04:02 +00:00
|
|
|
|
2004-03-10 14:24:40 +00:00
|
|
|
# Fork the processes
|
|
|
|
|
if ( !$skip ) {
|
2004-08-22 17:24:50 +00:00
|
|
|
$title = Title::makeTitle( NS_SPECIAL, 'Blockme' );
|
2004-04-06 01:25:26 +00:00
|
|
|
$iphash = md5( $wgIP . $wgProxyKey );
|
2004-08-22 17:24:50 +00:00
|
|
|
$url = $title->getFullURL( 'ip='.$iphash );
|
2004-04-06 01:25:26 +00:00
|
|
|
|
2004-03-10 14:24:40 +00:00
|
|
|
foreach ( $wgProxyPorts as $port ) {
|
2004-08-22 17:24:50 +00:00
|
|
|
$params = implode( ' ', array(
|
2004-04-06 01:25:26 +00:00
|
|
|
escapeshellarg( $wgProxyScriptPath ),
|
|
|
|
|
escapeshellarg( $wgIP ),
|
|
|
|
|
escapeshellarg( $port ),
|
|
|
|
|
escapeshellarg( $url )
|
|
|
|
|
));
|
2004-03-10 14:24:40 +00:00
|
|
|
exec( "php $params &>/dev/null &" );
|
|
|
|
|
}
|
|
|
|
|
# Set MemCached key
|
|
|
|
|
if ( $wgUseMemCached ) {
|
|
|
|
|
$wgMemc->set( $mcKey, 1, $wgProxyMemcExpiry );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-03-14 15:05:52 +00:00
|
|
|
|
2004-09-03 16:51:45 +00:00
|
|
|
/**
|
|
|
|
|
* @access private
|
|
|
|
|
* @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
|
|
|
|
|
|
|
|
|
|
|
|
|
function checkUnicodeCompliantBrowser() {
|
|
|
|
|
global $wgBrowserBlackList;
|
|
|
|
|
$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
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
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() {
|
2005-05-05 21:00:49 +00:00
|
|
|
global $wgStylePath, $wgLang, $wgMimeType, $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',
|
|
|
|
|
'open' => '[['.$wgLang->getNsText(NS_IMAGE).":",
|
|
|
|
|
'close' => ']]',
|
|
|
|
|
'sample'=> wfMsg('image_sample'),
|
|
|
|
|
'tip' => wfMsg('image_tip'),
|
|
|
|
|
'key' => 'D'
|
|
|
|
|
),
|
2005-04-28 20:44:26 +00:00
|
|
|
array( 'image' =>'button_media.png',
|
2004-11-25 13:52:56 +00:00
|
|
|
'open' => '[['.$wgLang->getNsText(NS_MEDIA).':',
|
|
|
|
|
'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'
|
|
|
|
|
)
|
|
|
|
|
);
|
2005-05-05 21:00:49 +00:00
|
|
|
$toolbar ="<script type='$wgJsMimeType'>\n/*<![CDATA[*/\n";
|
2004-11-25 13:52:56 +00:00
|
|
|
|
|
|
|
|
$toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
|
|
|
|
|
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";
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-30 08:04:02 +00:00
|
|
|
$toolbar.="addInfobox('" . wfEscapeJsString( wfMsg( "infobox" ) ) .
|
|
|
|
|
"','" . wfEscapeJsString( wfMsg( "infobox_alert" ) ) . "');\n";
|
2004-11-25 13:52:56 +00:00
|
|
|
$toolbar.="document.writeln(\"</div>\");\n";
|
|
|
|
|
|
|
|
|
|
$toolbar.="/*]]>*/\n</script>";
|
|
|
|
|
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
|
|
|
|
|
echo $this->getPreviewText( false, false );
|
|
|
|
|
}
|
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' );
|
|
|
|
|
if ( $oldtext != wfMsg( 'noarticletext' ) || $newtext != '' ) {
|
|
|
|
|
$difftext = DifferenceEngine::getDiff( $oldtext, $newtext, $oldtitle, $newtitle );
|
|
|
|
|
}
|
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
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
function safeUnicodeInput( $request, $field ) {
|
|
|
|
|
$text = rtrim( $request->getText( $field ) );
|
|
|
|
|
return $request->getBool( 'safemode' )
|
|
|
|
|
? $this->unmakesafe( $text )
|
|
|
|
|
: $text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
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
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
function safeUnicodeOutput( $text ) {
|
|
|
|
|
global $wgContLang;
|
|
|
|
|
$codedText = $wgContLang->recodeForEdit( $text );
|
|
|
|
|
return $this->checkUnicodeCompliantBrowser()
|
|
|
|
|
? $codedText
|
|
|
|
|
: $this->makesafe( $codedText );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
function makesafe( $invalue ) {
|
|
|
|
|
// Armor existing references for reversability.
|
|
|
|
|
$invalue = strtr( $invalue, array( "&#x" => "�" ) );
|
|
|
|
|
|
|
|
|
|
$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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
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 ) ) );
|
|
|
|
|
|
|
|
|
|
// Do some sanity checks. These aren't needed for reversability,
|
|
|
|
|
// but should help keep the breakage down if the editor
|
|
|
|
|
// breaks one of the entities whilst editing.
|
|
|
|
|
if ((substr($invalue,$i,1)==";") and (strlen($hexstring) <= 6)) {
|
|
|
|
|
$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" ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-08-02 20:43:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
?>
|