mediawiki-extensions-InputBox/InputBox.classes.php

576 lines
14 KiB
PHP
Raw Normal View History

2008-10-27 20:33:18 +00:00
<?php
/**
* Classes for InputBox extension
*
* @file
* @ingroup Extensions
*/
// InputBox class
class InputBox {
/* Fields */
private $mParser;
2008-11-13 08:50:13 +00:00
private $mType = '';
private $mWidth = 50;
private $mPreload = '';
private $mEditIntro = '';
private $mSummary = '';
private $mNosummary = '';
private $mMinor = '';
2008-11-13 08:50:13 +00:00
private $mPage = '';
private $mBR = 'yes';
private $mDefaultText = '';
private $mBGColor = 'transparent';
private $mButtonLabel = '';
private $mSearchButtonLabel = '';
private $mFullTextButton = '';
private $mLabelText = '';
private $mHidden = '';
private $mNamespaces = '';
private $mID = '';
private $mInline = false;
private $mPrefix = '';
2008-10-27 20:33:18 +00:00
/* Functions */
2008-10-27 20:33:18 +00:00
public function __construct( $parser ) {
$this->mParser = $parser;
2008-10-27 20:33:18 +00:00
}
2008-10-27 20:33:18 +00:00
public function render() {
// Handle various types
switch( $this->mType ) {
2008-10-27 20:33:18 +00:00
case 'create':
case 'comment':
return $this->getCreateForm();
case 'commenttitle':
return $this->getCommentForm();
2008-10-27 20:33:18 +00:00
case 'search':
return $this->getSearchForm('search');
case 'fulltext':
return $this->getSearchForm('fulltext');
2008-10-27 20:33:18 +00:00
case 'search2':
return $this->getSearchForm2();
default:
return Xml::tags( 'div', null,
Xml::element( 'strong',
array(
'class' => 'error'
),
strlen( $this->mType ) > 0
? wfMsgForContent( 'inputbox-error-bad-type', $this->mType )
: wfMsgForContent( 'inputbox-error-no-type' )
2008-10-27 20:33:18 +00:00
)
);
}
}
/**
* Generate search form
* @param $type
2008-10-27 20:33:18 +00:00
*/
public function getSearchForm( $type ) {
global $wgContLang, $wgNamespaceAliases;
2008-10-27 20:33:18 +00:00
// Use button label fallbacks
if ( !$this->mButtonLabel ) {
$this->mButtonLabel = wfMsgHtml( 'tryexact' );
2008-10-27 20:33:18 +00:00
}
if ( !$this->mSearchButtonLabel ) {
$this->mSearchButtonLabel = wfMsgHtml( 'searchfulltext' );
2008-10-27 20:33:18 +00:00
}
2008-10-27 20:33:18 +00:00
// Build HTML
$htmlOut = Xml::openElement( 'div',
array(
'align' => 'center',
'style' => 'background-color:' . $this->mBGColor
2008-10-27 20:33:18 +00:00
)
);
$htmlOut .= Xml::openElement( 'form',
array(
'name' => 'searchbox',
'id' => 'searchbox',
'class' => 'searchbox',
'action' => SpecialPage::getTitleFor( 'Search' )->escapeLocalUrl(),
)
);
$htmlOut .= Xml::element( 'input',
array(
'class' => 'searchboxInput',
'name' => 'search',
'type' => $this->mHidden ? 'hidden' : 'text',
'value' => $this->mDefaultText,
'size' => $this->mWidth,
2008-10-27 20:33:18 +00:00
)
);
if( $this->mPrefix != '' ){
$htmlOut .= Xml::element( 'input',
array(
'name' => 'prefix',
'type' => 'hidden',
'value' => $this->mPrefix,
)
);
}
$htmlOut .= $this->mBR;
2008-10-27 20:33:18 +00:00
// Determine namespace checkboxes
$namespacesArray = explode( ',', $this->mNamespaces );
if ( $this->mNamespaces ) {
$namespaces = $wgContLang->getNamespaces();
$nsAliases = array_merge( $wgContLang->getNamespaceAliases(), $wgNamespaceAliases );
$showNamespaces = array();
# Check for valid namespaces
foreach ( $namespacesArray as $userNS ) {
$userNS = trim( $userNS ); # no whitespace
$checkedNS = array();
# Namespace needs to be checked if flagged with "**"
if ( strpos( $userNS, '**' ) ) {
$userNS = str_replace( '**', '', $userNS );
$checkedNS[$userNS] = true;
}
$mainMsg = wfMsgForContent( 'inputbox-ns-main' );
if( $userNS == 'Main' || $userNS == $mainMsg ) {
$i = 0;
} elseif( array_search( $userNS, $namespaces ) ) {
$i = array_search( $userNS, $namespaces );
} elseif ( isset( $nsAliases[$userNS] ) ) {
$i = $nsAliases[$userNS];
} else {
continue; # Namespace not recognised, skip
}
$showNamespaces[$i] = $userNS;
if( isset( $checkedNS[$userNS] ) && $checkedNS[$userNS] ) {
$checkedNS[$i] = true;
}
}
# Show valid namespaces
foreach( $showNamespaces as $i => $name ) {
2008-10-27 20:33:18 +00:00
$checked = array();
// Namespace flagged with "**" or if it's the only one
if ( ( isset( $checkedNS[$i] ) && $checkedNS[$i] ) || count( $showNamespaces ) == 1 ) {
2008-10-27 20:33:18 +00:00
$checked = array( 'checked' => 'checked' );
}
if ( count( $showNamespaces ) == 1 ) {
// Checkbox
$htmlOut .= Xml::element( 'input',
array(
'type' => 'hidden',
'name' => 'ns' . $i,
'value' => 1,
'id' => 'mw-inputbox-ns' . $i
) + $checked
);
} else {
// Checkbox
$htmlOut .= ' <div class="inputbox-element" style="display: inline; white-space: nowrap;">';
$htmlOut .= Xml::element( 'input',
array(
'type' => 'checkbox',
'name' => 'ns' . $i,
'value' => 1,
'id' => 'mw-inputbox-ns' . $i
) + $checked
);
// Label
$htmlOut .= '&#160;' . Xml::label( $name, 'mw-inputbox-ns' . $i );
$htmlOut .= '</div> ';
2008-10-27 20:33:18 +00:00
}
}
// Line break
$htmlOut .= $this->mBR;
} elseif( $type == 'search' ) {
2008-10-27 20:33:18 +00:00
// Go button
$htmlOut .= Xml::element( 'input',
array(
'type' => 'submit',
'name' => 'go',
'class' => 'searchboxGoButton',
'value' => $this->mButtonLabel
2008-10-27 20:33:18 +00:00
)
);
Remove most named character references from output Recommit of r66254 to trunk. This was just find extensions phase3 -iname '*.php' \! -iname '*.i18n.php' \! -iname 'Messages*.php' \! -iname '*_Messages.php' -exec sed -i 's/&nbsp;/\&#160;/g;s/&mdash;/―/g;s/&bull;/•/g;s/&aacute;/á/g;s/&acute;/´/g;s/&agrave;/à/g;s/&alpha;/α/g;s/&auml;/ä/g;s/&ccedil;/ç/g;s/&copy;/©/g;s/&darr;/↓/g;s/&deg;/°/g;s/&eacute;/é/g;s/&ecirc;/ê/g;s/&euml;/ë/g;s/&egrave;/è/g;s/&euro;/€/g;s/&harr;//g;s/&hellip;/…/g;s/&iacute;/í/g;s/&igrave;/ì/g;s/&larr;/←/g;s/&ldquo;/“/g;s/&middot;/·/g;s/&minus;/−/g;s/&ndash;/–/g;s/&oacute;/ó/g;s/&ocirc;/ô/g;s/&oelig;/œ/g;s/&ograve;/ò/g;s/&otilde;/õ/g;s/&ouml;/ö/g;s/&pound;/£/g;s/&prime;/′/g;s/&Prime;/″/g;s/&raquo;/»/g;s/&rarr;/→/g;s/&rdquo;/”/g;s/&Sigma;/Σ/g;s/&times;/×/g;s/&uacute;/ú/g;s/&uarr;/↑/g;s/&uuml;/ü/g;s/&yen;/¥/g' {} + followed by reading over every single line of the resulting diff and fixing a whole bunch of false positives. The reason for this change is given in <http://lists.wikimedia.org/pipermail/wikitech-l/2010-April/047617.html>. I cleared it with Tim and Brion on IRC before committing. It might cause a few problems, but I tried to be careful; please report any issues. I skipped all messages files. I plan to make a follow-up commit that alters wfMsgExt() with 'escapenoentities' to sanitize all the entities. That way, the only messages that will be problems will be ones that output raw HTML, and we want to get rid of those anyway. This should get rid of all named entities everywhere except messages. I skipped a few things like &nbsp that I noticed in manual inspection, because they weren't well-formed XML anyway. Also, to everyone who uses non-breaking spaces when they could use a normal space, or nothing at all, or CSS padding: I still hate you. Die.
2010-05-30 17:33:59 +00:00
$htmlOut .= '&#160;';
2008-10-27 20:33:18 +00:00
}
2008-10-27 20:33:18 +00:00
// Search button
$htmlOut .= Xml::element( 'input',
array(
'type' => 'submit',
'name' => 'fulltext',
'class' => 'searchboxSearchButton',
'value' => $this->mSearchButtonLabel
2008-10-27 20:33:18 +00:00
)
);
// Hidden fulltext param for IE (bug 17161)
if( $type == 'fulltext' ) {
$htmlOut .= Html::hidden( 'fulltext', 'Search' );
}
2008-10-27 20:33:18 +00:00
$htmlOut .= Xml::closeElement( 'form' );
$htmlOut .= Xml::closeElement( 'div' );
2008-10-27 20:33:18 +00:00
// Return HTML
return $htmlOut;
}
2011-10-26 03:49:06 +00:00
/**
2008-10-27 20:33:18 +00:00
* Generate search form version 2
*/
public function getSearchForm2() {
2008-10-27 20:33:18 +00:00
// Use button label fallbacks
if ( !$this->mButtonLabel ) {
$this->mButtonLabel = wfMsgHtml( 'tryexact' );
2008-10-27 20:33:18 +00:00
}
$id = Sanitizer::escapeId( $this->mID, 'noninitial' );
2008-10-27 20:33:18 +00:00
$htmlLabel = '';
if ( isset( $this->mLabelText ) && strlen( trim( $this->mLabelText ) ) ) {
$this->mLabelText = $this->mParser->recursiveTagParse( $this->mLabelText );
$htmlLabel = Xml::openElement( 'label', array( 'for' => 'bodySearchInput' . $id ) );
$htmlLabel .= $this->mLabelText;
$htmlLabel .= Xml::closeElement( 'label' );
2008-10-27 20:33:18 +00:00
}
$htmlOut = Xml::openElement( 'form',
array(
'name' => 'bodySearch' . $id,
'id' => 'bodySearch' . $id,
'class' => 'bodySearch',
'action' => SpecialPage::getTitleFor( 'Search' )->escapeLocalUrl(),
'style' => $this->mInline ? 'display: inline;' : ''
2008-10-27 20:33:18 +00:00
)
);
$htmlOut .= Xml::openElement( 'div',
array(
'class' => 'bodySearchWrap',
'style' => 'background-color:' . $this->mBGColor . ';' .
$this->mInline ? 'display: inline;' : ''
2008-10-27 20:33:18 +00:00
)
);
$htmlOut .= $htmlLabel;
$htmlOut .= Xml::element( 'input',
array(
'type' => $this->mHidden ? 'hidden' : 'text',
2008-10-27 20:33:18 +00:00
'name' => 'search',
'size' => $this->mWidth,
'id' => 'bodySearchInput' . $id
2008-10-27 20:33:18 +00:00
)
);
$htmlOut .= Xml::element( 'input',
array(
'type' => 'submit',
'name' => 'go',
'value' => $this->mButtonLabel,
2008-10-27 20:33:18 +00:00
'class' => 'bodySearchBtnGo' . $id
)
);
// Better testing needed here!
if ( !empty( $this->mFullTextButton ) ) {
2008-10-27 20:33:18 +00:00
$htmlOut .= Xml::element( 'input',
array(
'type' => 'submit',
'name' => 'fulltext',
'class' => 'bodySearchBtnSearch',
'value' => $this->mSearchButtonLabel
2008-10-27 20:33:18 +00:00
)
);
}
2008-10-27 20:33:18 +00:00
$htmlOut .= Xml::closeElement( 'div' );
$htmlOut .= Xml::closeElement( 'form' );
// Return HTML
return $htmlOut;
}
/**
* Generate create page form
*/
public function getCreateForm() {
global $wgScript;
2008-10-27 20:33:18 +00:00
if ( $this->mType == "comment" ) {
if ( !$this->mButtonLabel ) {
$this->mButtonLabel = wfMsgHtml( "postcomment" );
2008-10-27 20:33:18 +00:00
}
} else {
if ( !$this->mButtonLabel ) {
$this->mButtonLabel = wfMsgHtml( 'createarticle' );
2008-10-27 20:33:18 +00:00
}
}
2008-10-27 20:33:18 +00:00
$htmlOut = Xml::openElement( 'div',
array(
'align' => 'center',
'style' => 'background-color:' . $this->mBGColor
2008-10-27 20:33:18 +00:00
)
);
$createBoxParams = array(
'name' => 'createbox',
'class' => 'createbox',
'action' => $wgScript,
'method' => 'get'
2008-10-27 20:33:18 +00:00
);
if( isset( $this->mId ) ) {
$createBoxParams['id'] = Sanitizer::escapeId( $this->mId );
}
$htmlOut .= Xml::openElement( 'form', $createBoxParams );
2008-10-27 20:33:18 +00:00
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'action',
'value' => 'edit',
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'preload',
'value' => $this->mPreload,
2008-10-27 20:33:18 +00:00
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'editintro',
'value' => $this->mEditIntro,
2008-10-27 20:33:18 +00:00
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'summary',
'value' => $this->mSummary,
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'nosummary',
'value' => $this->mNosummary,
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'prefix',
'value' => $this->mPrefix,
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'minor',
'value' => $this->mMinor,
)
);
if ( $this->mType == 'comment' ) {
2008-10-27 20:33:18 +00:00
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'section',
'value' => 'new',
)
);
}
$htmlOut .= Xml::openElement( 'input',
array(
'type' => $this->mHidden ? 'hidden' : 'text',
2008-10-27 20:33:18 +00:00
'name' => 'title',
'class' => 'createboxInput',
'value' => $this->mDefaultText,
'size' => $this->mWidth
2008-10-27 20:33:18 +00:00
)
);
$htmlOut .= $this->mBR;
2008-10-27 20:33:18 +00:00
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'submit',
'name' => 'create',
'class' => 'createboxButton',
'value' => $this->mButtonLabel
2008-10-27 20:33:18 +00:00
)
);
$htmlOut .= Xml::closeElement( 'form' );
$htmlOut .= Xml::closeElement( 'div' );
2008-10-27 20:33:18 +00:00
// Return HTML
return $htmlOut;
}
/**
* Generate new section form
*/
public function getCommentForm() {
global $wgScript;
if ( !$this->mButtonLabel ) {
$this->mButtonLabel = wfMsgHtml( "postcomment" );
}
$htmlOut = Xml::openElement( 'div',
array(
'align' => 'center',
'style' => 'background-color:' . $this->mBGColor
)
);
$commentFormParams = array(
'name' => 'commentbox',
'class' => 'commentbox',
'action' => $wgScript,
'method' => 'get'
);
if( isset( $this->mId ) ) {
$commentFormParams['id'] = Sanitizer::escapeId( $this->mId );
}
$htmlOut .= Xml::openElement( 'form', $commentFormParams );
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'action',
'value' => 'edit',
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'preload',
'value' => $this->mPreload,
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'editintro',
'value' => $this->mEditIntro,
)
);
$htmlOut .= Xml::openElement( 'input',
array(
2008-11-17 21:54:38 +00:00
'type' => $this->mHidden ? 'hidden' : 'text',
'name' => 'preloadtitle',
'class' => 'commentboxInput',
'value' => $this->mDefaultText,
'size' => $this->mWidth
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'section',
'value' => 'new',
)
);
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'hidden',
'name' => 'title',
'value' => $this->mPage
)
);
$htmlOut .= $this->mBR;
$htmlOut .= Xml::openElement( 'input',
array(
'type' => 'submit',
'name' => 'create',
'class' => 'commentboxButton',
'value' => $this->mButtonLabel
)
);
$htmlOut .= Xml::closeElement( 'form' );
$htmlOut .= Xml::closeElement( 'div' );
// Return HTML
return $htmlOut;
}
2008-10-27 20:33:18 +00:00
/**
* Extract options from a blob of text
*
* @param string $text Tag contents
*/
public function extractOptions( $text ) {
wfProfileIn( __METHOD__ );
2008-10-27 20:33:18 +00:00
// Parse all possible options
$values = array();
foreach ( explode( "\n", $text ) as $line ) {
if ( strpos( $line, '=' ) === false )
2008-10-27 20:33:18 +00:00
continue;
list( $name, $value ) = explode( '=', $line, 2 );
$values[ strtolower( trim( $name ) ) ] = Sanitizer::decodeCharReferences( trim( $value ) );
2008-10-27 20:33:18 +00:00
}
2008-11-13 08:50:13 +00:00
// Build list of options, with local member names
2008-10-27 20:33:18 +00:00
$options = array(
2008-11-13 08:50:13 +00:00
'type' => 'mType',
'width' => 'mWidth',
'preload' => 'mPreload',
'page' => 'mPage',
'editintro' => 'mEditIntro',
'summary' => 'mSummary',
'nosummary' => 'mNosummary',
'minor' => 'mMinor',
2008-11-13 08:50:13 +00:00
'break' => 'mBR',
'default' => 'mDefaultText',
'bgcolor' => 'mBGColor',
'buttonlabel' => 'mButtonLabel',
'searchbuttonlabel' => 'mSearchButtonLabel',
'fulltextbutton' => 'mFullTextButton',
'namespaces' => 'mNamespaces',
'labeltext' => 'mLabelText',
'hidden' => 'mHidden',
'id' => 'mID',
'inline' => 'mInline',
'prefix' => 'mPrefix',
2008-10-27 20:33:18 +00:00
);
foreach ( $options as $name => $var ) {
if ( isset( $values[$name] ) ) {
2008-11-13 08:50:13 +00:00
$this->$var = $values[$name];
2008-10-27 20:33:18 +00:00
}
}
2008-10-27 20:33:18 +00:00
// Insert a line break if configured to do so
$this->mBR = ( strtolower( $this->mBR ) == "no" ) ? ' ' : '<br />';
2008-10-27 20:33:18 +00:00
// Validate the width; make sure it's a valid, positive integer
$this->mWidth = intval( $this->mWidth <= 0 ? 50 : $this->mWidth );
// Validate background color
if ( !$this->isValidColor( $this->mBGColor ) ) {
$this->mBGColor = 'transparent';
}
2008-10-27 20:33:18 +00:00
wfProfileOut( __METHOD__ );
}
/**
* Do a security check on the bgcolor parameter
*/
public function isValidColor( $color ) {
$regex = <<<REGEX
/^ (
[a-zA-Z]* | # color names
\# [0-9a-f]{3} | # short hexadecimal
\# [0-9a-f]{6} | # long hexadecimal
rgb \s* \( \s* (
\d+ \s* , \s* \d+ \s* , \s* \d+ | # rgb integer
[0-9.]+% \s* , \s* [0-9.]+% \s* , \s* [0-9.]+% # rgb percent
) \s* \)
) $ /xi
REGEX;
return (bool) preg_match( $regex, $color );
}
2008-10-27 20:33:18 +00:00
}