User:Leucosticte/InputBox.classes.php

<?php /** * Classes for InputBox extension * * @file * @ingroup Extensions */

// InputBox class class InputBox {

/* Fields */

private $mParser; private $mType = ''; private $mWidth = 50; private $mPreload = ''; private $mEditIntro = ''; private $mSummary = ''; private $mNosummary = ''; private $mMinor = ''; private $mPage = ''; private $mBR = 'yes'; private $mDefaultText = ''; private $mPlaceholderText = ''; private $mBGColor = 'transparent'; private $mButtonLabel = ''; private $mSearchButtonLabel = ''; private $mFullTextButton = ''; private $mLabelText = ''; private $mHidden = ''; private $mNamespaces = ''; private $mID = ''; private $mInline = false; private $mPrefix = ''; private $mDir = ''; private $mUrl = ''; private $mUrlParameter = '';

/* Functions */

public function __construct( $parser ) { $this->mParser = $parser; // Default value for dir taken from the page language (bug 37018) $this->mDir = $this->mParser->getTargetLanguage->getDir; // Split caches by language, to make sure visitors do not see a cached // version in a random language (since labels are in the user language) $this->mParser->getOptions->getUserLangObj; }

public function render { // Handle various types switch( $this->mType ) { case 'create': case 'comment': return $this->getCreateForm; case 'commenttitle': return $this->getCommentForm; case 'search': if ( isset ( $this->mUrl ) ) { if ( $this->mUrl ) { return $this->getSearchForm('search', $this->mUrl ); }				}				if ( isset ( $this->mUrlParameter ) ) { return ''; }				return $this->getSearchForm('search' ); case 'fulltext': return $this->getSearchForm('fulltext'); case 'search2': return $this->getSearchForm2; default: return Xml::tags( 'div', null,					Xml::element( 'strong', array(							'class' => 'error'						), strlen( $this->mType ) > 0 ? wfMessage( 'inputbox-error-bad-type', $this->mType )->text : wfMessage( 'inputbox-error-no-type' )->text )				);		}	}

/**	 * Generate search form * @param $type * @return string HTML */	public function getSearchForm( $type, $url = false ) { global $wgContLang, $wgNamespaceAliases;

// Use button label fallbacks if ( !$this->mButtonLabel ) { $this->mButtonLabel = wfMessage( 'tryexact' )->escaped; }		if ( !$this->mSearchButtonLabel ) { $this->mSearchButtonLabel = wfMessage( 'searchfulltext' )->escaped; }

// Build HTML $htmlOut = Xml::openElement( 'div',			array( 'style' => 'margin-left: auto; margin-right: auto; text-align: center; background-color:'. $this->mBGColor )		);		if ( $url ) { $actionUrl = htmlentities ( $url ); } else { $actionUrl = SpecialPage::getTitleFor( 'Search' )->escapeLocalUrl; }		$htmlOut .= Xml::openElement( 'form',			array( 'name' => 'searchbox', 'id' => 'searchbox', 'class' => 'searchbox', 'action' => $actionUrl, )		);		$htmlOut .= Xml::element( 'input',			array( 'class' => 'searchboxInput', 'name' => 'search', 'type' => $this->mHidden ? 'hidden' : 'text', 'value' => $this->mDefaultText, 'placeholder' => $this->mPlaceholderText, 'size' => $this->mWidth, 'dir' => $this->mDir, )		);

if( $this->mPrefix != '' ){ $htmlOut .= Xml::element( 'input',				array( 'name' => 'prefix', 'type' => 'hidden', 'value' => $this->mPrefix, )			);		}

$htmlOut .= $this->mBR;

// Determine namespace checkboxes $namespacesArray = explode( ',', $this->mNamespaces ); if ( $this->mNamespaces ) { $namespaces = $wgContLang->getNamespaces; $nsAliases = array_merge( $wgContLang->getNamespaceAliases, $wgNamespaceAliases ); $showNamespaces = array; $checkedNS = array; # Check for valid namespaces foreach ( $namespacesArray as $userNS ) { $userNS = trim( $userNS ); # no whitespace

# Namespace needs to be checked if flagged with "**" if ( strpos( $userNS, '**' ) ) { $userNS = str_replace( '**', '', $userNS ); $checkedNS[$userNS] = true; }

$mainMsg = wfMessage( 'inputbox-ns-main' )->inContentLanguage->text; 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 ) { $checked = array; // Namespace flagged with "**" or if it's the only one if ( ( isset( $checkedNS[$i] ) && $checkedNS[$i] ) || count( $showNamespaces ) == 1 ) { $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 .= ' '; $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 .= ' '; }			}

// Line break $htmlOut .= $this->mBR; } elseif( $type == 'search' ) { // Go button $htmlOut .= Xml::element( 'input',				array( 'type' => 'submit', 'name' => 'go', 'class' => 'searchboxGoButton', 'value' => $this->mButtonLabel )			);			$htmlOut .= '&#160;'; }

// Search button $htmlOut .= Xml::element( 'input',			array( 'type' => 'submit', 'name' => 'fulltext', 'class' => 'searchboxSearchButton', 'value' => $this->mSearchButtonLabel )		);

// Hidden fulltext param for IE (bug 17161) if( $type == 'fulltext' ) { $htmlOut .= Html::hidden( 'fulltext', 'Search' ); }

$htmlOut .= Xml::closeElement( 'form' ); $htmlOut .= Xml::closeElement( 'div' );

// Return HTML return $htmlOut; }

/**	 * Generate search form version 2 */	public function getSearchForm2 { // Use button label fallbacks if ( !$this->mButtonLabel ) { $this->mButtonLabel = wfMessage( 'tryexact' )->escaped; }

$id = Sanitizer::escapeId( $this->mID, 'noninitial' ); $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' ); }		$htmlOut = Xml::openElement( 'form',			array( 'name' => 'bodySearch'. $id, 'id' => 'bodySearch'. $id, 'class' => 'bodySearch', 'action' => SpecialPage::getTitleFor( 'Search' )->escapeLocalUrl, 'style' => $this->mInline ? 'display: inline;' : '' )		);		$htmlOut .= Xml::openElement( 'div',			array( 'class' => 'bodySearchWrap', 'style' => 'background-color:'. $this->mBGColor. ';' .					$this->mInline ? 'display: inline;' : '' )		);		$htmlOut .= $htmlLabel; $htmlOut .= Xml::element( 'input',			array( 'type' => $this->mHidden ? 'hidden' : 'text', 'name' => 'search', 'size' => $this->mWidth, 'id' => 'bodySearchInput'. $id, 'dir' => $this->mDir, )		);		$htmlOut .= Xml::element( 'input',			array( 'type' => 'submit', 'name' => 'go', 'value' => $this->mButtonLabel, 'class' => 'bodySearchBtnGo'. $id )		);

// Better testing needed here! if ( !empty( $this->mFullTextButton ) ) { $htmlOut .= Xml::element( 'input',				array( 'type' => 'submit', 'name' => 'fulltext', 'class' => 'bodySearchBtnSearch', 'value' => $this->mSearchButtonLabel )			);		}

$htmlOut .= Xml::closeElement( 'div' ); $htmlOut .= Xml::closeElement( 'form' );

// Return HTML return $htmlOut; }

/**	 * Generate create page form */	public function getCreateForm { global $wgScript;

if ( $this->mType == "comment" ) { if ( !$this->mButtonLabel ) { $this->mButtonLabel = wfMessage( "postcomment" )->escaped; }		} else { if ( !$this->mButtonLabel ) { $this->mButtonLabel = wfMessage( 'createarticle' )->escaped; }		}

$htmlOut = Xml::openElement( 'div',			array( 'style' => 'margin-left: auto; margin-right: auto; text-align: center; background-color:'. $this->mBGColor )		);		$createBoxParams = array(			'name' => 'createbox',			'class' => 'createbox',			'action' => $wgScript,			'method' => 'get'		); if( isset( $this->mId ) ) { $createBoxParams['id'] = Sanitizer::escapeId( $this->mId ); }		$htmlOut .= Xml::openElement( 'form', $createBoxParams ); $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( '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' ) { $htmlOut .= Xml::openElement( 'input',				array( 'type' => 'hidden', 'name' => 'section', 'value' => 'new', )			);		}		$htmlOut .= Xml::openElement( 'input',			array( 'type' => $this->mHidden ? 'hidden' : 'text', 'name' => 'title', 'class' => 'createboxInput', 'value' => $this->mDefaultText, 'placeholder' => $this->mPlaceholderText, 'size' => $this->mWidth, 'dir' => $this->mDir, )		);		$htmlOut .= $this->mBR; $htmlOut .= Xml::openElement( 'input',			array( 'type' => 'submit', 'name' => 'create', 'class' => 'createboxButton', 'value' => $this->mButtonLabel )		);		$htmlOut .= Xml::closeElement( 'form' ); $htmlOut .= Xml::closeElement( 'div' );

// Return HTML return $htmlOut; }

/**	 * Generate new section form */	public function getCommentForm { global $wgScript;

if ( !$this->mButtonLabel ) { $this->mButtonLabel = wfMessage( "postcomment" )->escaped; }

$htmlOut = Xml::openElement( 'div',			array( 'style' => 'margin-left: auto; margin-right: auto; text-align: center; 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( 'type' => $this->mHidden ? 'hidden' : 'text', 'name' => 'preloadtitle', 'class' => 'commentboxInput', 'value' => $this->mDefaultText, 'placeholder' => $this->mPlaceholderText, 'size' => $this->mWidth, 'dir' => $this->mDir, )		);		$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; }

/**	 * Extract options from a blob of text *	 * @param string $text Tag contents */	public function extractOptions( $text, $parser ) { wfProfileIn( __METHOD__ );

// Parse all possible options $values = array; foreach ( explode( "\n", $text ) as $line ) { if ( strpos( $line, '=' ) === false ) continue; list( $name, $value ) = explode( '=', $line, 2 ); $values[ strtolower( trim( $name ) ) ] = Sanitizer::decodeCharReferences( trim( $value ) ); }

// Validate the dir value. if ( isset( $values['dir'] ) && !in_array( $values['dir'], array( 'ltr', 'rtl' ) ) ) { unset( $values['dir'] ); }

// Build list of options, with local member names $options = array(			'type' => 'mType',			'width' => 'mWidth',			'preload' => 'mPreload',			'page' => 'mPage',			'editintro' => 'mEditIntro',			'summary' => 'mSummary',			'nosummary' => 'mNosummary',			'minor' => 'mMinor',			'break' => 'mBR',			'default' => 'mDefaultText',			'placeholder' => 'mPlaceholderText',			'bgcolor' => 'mBGColor',			'buttonlabel' => 'mButtonLabel',			'searchbuttonlabel' => 'mSearchButtonLabel',			'fulltextbutton' => 'mFullTextButton',			'namespaces' => 'mNamespaces',			'labeltext' => 'mLabelText',			'hidden' => 'mHidden',			'id' => 'mID',			'inline' => 'mInline',			'prefix' => 'mPrefix',			'dir' => 'mDir',			'url' => 'mUrl',			'urlparameter' => 'mUrlParameter',		); foreach ( $options as $name => $var ) { if ( isset( $values[$name] ) ) { $this->$var = $values[$name]; }		}		if ( ( !$this->mUrl || $this->mUrl == 1 ) && $this->mUrlParameter ) { $contentsPage = WikiPage::factory ( $parser->getTitle ); if ( version_compare( $wgVersion, '1.21', '<' ) ) { $contents = $contentsPage->getText( Revision::RAW ); } else { $contents = $contentsPage->getContent( Revision::RAW ); }			// A template line with data will start with a |, e.g. |search URL = wikiindex.org if ( $begin = strpos ( $contents, '|'. $this->mUrlParameter ) ) { if ( $equals = strpos ( $contents, '=', $begin ) ) { $closingBrace = strpos ( $contents, "}}", $equals ); // End this string at the newline or the }} (closing the template), whichever // comes first $newline = strpos ( $contents, "\n", $equals ); if ( $closingBrace && $closingBrace < $newline ) { $newline = $closingBrace; }					if ( $newline ) { $this->mUrl = trim( substr ( $contents, $equals + 1, $newline - $equals - 1 ) ); }				}			}		}

// Insert a line break if configured to do so $this->mBR = ( strtolower( $this->mBR ) == "no" ) ? ' ' : ' ';

// 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'; }		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 ); } }