From 63601400e476c6cf43d985f3e7b9864681695ed4 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Fri, 18 Jan 2013 16:46:04 +0100 Subject: Update to MediaWiki 1.20.2 this update includes: * adjusted Arch Linux skin * updated FluxBBAuthPlugin * patch for https://bugzilla.wikimedia.org/show_bug.cgi?id=44024 --- includes/HTMLForm.php | 716 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 553 insertions(+), 163 deletions(-) (limited to 'includes/HTMLForm.php') diff --git a/includes/HTMLForm.php b/includes/HTMLForm.php index 7326bf5c..5c00b9f6 100644 --- a/includes/HTMLForm.php +++ b/includes/HTMLForm.php @@ -1,4 +1,25 @@ $info, * where $info is an Associative Array with any of the following: * @@ -30,13 +55,14 @@ * the message. * 'label' -- alternatively, a raw text message. Overridden by * label-message + * 'help' -- message text for a message to use as a help text. * 'help-message' -- message key for a message to use as a help text. * can be an array of msg key and then parameters to * the message. - * Overwrites 'help-messages'. + * Overwrites 'help-messages' and 'help'. * 'help-messages' -- array of message key. As above, each item can * be an array of msg key and then parameters. - * Overwrites 'help-message'. + * Overwrites 'help'. * 'required' -- passed through to the object, indicating that it * is a required field. * 'size' -- the length of text fields @@ -51,6 +77,19 @@ * (eg one without the "wp" prefix), specify it here and * it will be used without modification. * + * Since 1.20, you can chain mutators to ease the form generation: + * @par Example: + * @code + * $form = new HTMLForm( $someFields ); + * $form->setMethod( 'get' ) + * ->setWrapperLegendMsg( 'message-key' ) + * ->suppressReset() + * ->prepareForm() + * ->displayForm(); + * @endcode + * Note that you will have prepareForm and displayForm at the end. Other + * methods call done after that would simply not be part of the form :( + * * TODO: Document 'section' / 'subsection' stuff */ class HTMLForm extends ContextSource { @@ -111,7 +150,7 @@ class HTMLForm extends ContextSource { /** * Form action URL. false means we will use the URL to set Title * @since 1.19 - * @var false|string + * @var bool|string */ protected $mAction = false; @@ -120,16 +159,33 @@ class HTMLForm extends ContextSource { protected $mButtons = array(); protected $mWrapperLegend = false; - + /** * If true, sections that contain both fields and subsections will * render their subsections before their fields. - * + * * Subclasses may set this to false to render subsections after fields * instead. */ protected $mSubSectionBeforeFields = true; + /** + * Format in which to display form. For viable options, + * @see $availableDisplayFormats + * @var String + */ + protected $displayFormat = 'table'; + + /** + * Available formats in which to display the form + * @var Array + */ + protected $availableDisplayFormats = array( + 'table', + 'div', + 'raw', + ); + /** * Build a new HTMLForm from an array of field attributes * @param $descriptor Array of Field constructs, as described above @@ -138,13 +194,13 @@ class HTMLForm extends ContextSource { * @param $messagePrefix String a prefix to go in front of default messages */ public function __construct( $descriptor, /*IContextSource*/ $context = null, $messagePrefix = '' ) { - if( $context instanceof IContextSource ){ + if ( $context instanceof IContextSource ) { $this->setContext( $context ); $this->mTitle = false; // We don't need them to set a title $this->mMessagePrefix = $messagePrefix; } else { // B/C since 1.18 - if( is_string( $context ) && $messagePrefix === '' ){ + if ( is_string( $context ) && $messagePrefix === '' ) { // it's actually $messagePrefix $this->mMessagePrefix = $context; } @@ -188,6 +244,30 @@ class HTMLForm extends ContextSource { $this->mFieldTree = $loadedDescriptor; } + /** + * Set format in which to display the form + * @param $format String the name of the format to use, must be one of + * $this->availableDisplayFormats + * @since 1.20 + * @return HTMLForm $this for chaining calls (since 1.20) + */ + public function setDisplayFormat( $format ) { + if ( !in_array( $format, $this->availableDisplayFormats ) ) { + throw new MWException ( 'Display format must be one of ' . print_r( $this->availableDisplayFormats, true ) ); + } + $this->displayFormat = $format; + return $this; + } + + /** + * Getter for displayFormat + * @since 1.20 + * @return String + */ + public function getDisplayFormat() { + return $this->displayFormat; + } + /** * Add the HTMLForm-specific JavaScript, if it hasn't been * done already. @@ -217,13 +297,22 @@ class HTMLForm extends ContextSource { $descriptor['fieldname'] = $fieldname; + # TODO + # This will throw a fatal error whenever someone try to use + # 'class' to feed a CSS class instead of 'cssclass'. Would be + # great to avoid the fatal error and show a nice error. $obj = new $class( $descriptor ); return $obj; } /** - * Prepare form for submission + * Prepare form for submission. + * + * @attention When doing method chaining, that should be the very last + * method call before displayForm(). + * + * @return HTMLForm $this for chaining calls (since 1.20) */ function prepareForm() { # Check if we have the info we need @@ -233,6 +322,7 @@ class HTMLForm extends ContextSource { # Load data from the request. $this->loadData(); + return $this; } /** @@ -249,7 +339,7 @@ class HTMLForm extends ContextSource { $editToken = $this->getRequest()->getVal( 'wpEditToken' ); if ( $this->getUser()->isLoggedIn() || $editToken != null ) { // Session tokens for logged-out users have no security value. - // However, if the user gave one, check it in order to give a nice + // However, if the user gave one, check it in order to give a nice // "session expired" error instead of "permission denied" or such. $submit = $this->getUser()->matchEditToken( $editToken ); } else { @@ -266,7 +356,7 @@ class HTMLForm extends ContextSource { /** * The here's-one-I-made-earlier option: do the submission if - * posted, or display the form with or without funky valiation + * posted, or display the form with or without funky validation * errors * @return Bool or Status whether submission was successful. */ @@ -274,7 +364,7 @@ class HTMLForm extends ContextSource { $this->prepareForm(); $result = $this->tryAuthorizedSubmit(); - if ( $result === true || ( $result instanceof Status && $result->isGood() ) ){ + if ( $result === true || ( $result instanceof Status && $result->isGood() ) ) { return $result; } @@ -307,6 +397,9 @@ class HTMLForm extends ContextSource { } $callback = $this->mSubmitCallback; + if ( !is_callable( $callback ) ) { + throw new MWException( 'HTMLForm: no submit callback provided. Use setSubmitCallback() to set one.' ); + } $data = $this->filterDataForSubmit( $this->mFieldData ); @@ -322,45 +415,60 @@ class HTMLForm extends ContextSource { * the output from HTMLForm::filterDataForSubmit, and must * return Bool true on success, Bool false if no submission * was attempted, or String HTML output to display on error. + * @return HTMLForm $this for chaining calls (since 1.20) */ function setSubmitCallback( $cb ) { $this->mSubmitCallback = $cb; + return $this; } /** * Set a message to display on a validation error. - * @param $msg Mixed String or Array of valid inputs to wfMsgExt() + * @param $msg Mixed String or Array of valid inputs to wfMessage() * (so each entry can be either a String or Array) + * @return HTMLForm $this for chaining calls (since 1.20) */ function setValidationErrorMessage( $msg ) { $this->mValidationErrorMessage = $msg; + return $this; } /** * Set the introductory message, overwriting any existing message. * @param $msg String complete text of message to display + * @return HTMLForm $this for chaining calls (since 1.20) */ function setIntro( $msg ) { $this->setPreText( $msg ); + return $this; } /** * Set the introductory message, overwriting any existing message. * @since 1.19 * @param $msg String complete text of message to display + * @return HTMLForm $this for chaining calls (since 1.20) */ - function setPreText( $msg ) { $this->mPre = $msg; } + function setPreText( $msg ) { + $this->mPre = $msg; + return $this; + } /** * Add introductory text. * @param $msg String complete text of message to display + * @return HTMLForm $this for chaining calls (since 1.20) */ - function addPreText( $msg ) { $this->mPre .= $msg; } + function addPreText( $msg ) { + $this->mPre .= $msg; + return $this; + } /** * Add header text, inside the form. * @param $msg String complete text of message to display * @param $section string The section to add the header to + * @return HTMLForm $this for chaining calls (since 1.20) */ function addHeaderText( $msg, $section = null ) { if ( is_null( $section ) ) { @@ -371,6 +479,7 @@ class HTMLForm extends ContextSource { } $this->mSectionHeaders[$section] .= $msg; } + return $this; } /** @@ -378,6 +487,7 @@ class HTMLForm extends ContextSource { * @since 1.19 * @param $msg String complete text of message to display * @param $section The section to add the header to + * @return HTMLForm $this for chaining calls (since 1.20) */ function setHeaderText( $msg, $section = null ) { if ( is_null( $section ) ) { @@ -385,12 +495,14 @@ class HTMLForm extends ContextSource { } else { $this->mSectionHeaders[$section] = $msg; } + return $this; } /** * Add footer text, inside the form. * @param $msg String complete text of message to display * @param $section string The section to add the footer text to + * @return HTMLForm $this for chaining calls (since 1.20) */ function addFooterText( $msg, $section = null ) { if ( is_null( $section ) ) { @@ -401,6 +513,7 @@ class HTMLForm extends ContextSource { } $this->mSectionFooters[$section] .= $msg; } + return $this; } /** @@ -408,6 +521,7 @@ class HTMLForm extends ContextSource { * @since 1.19 * @param $msg String complete text of message to display * @param $section string The section to add the footer text to + * @return HTMLForm $this for chaining calls (since 1.20) */ function setFooterText( $msg, $section = null ) { if ( is_null( $section ) ) { @@ -415,39 +529,65 @@ class HTMLForm extends ContextSource { } else { $this->mSectionFooters[$section] = $msg; } + return $this; } /** * Add text to the end of the display. * @param $msg String complete text of message to display + * @return HTMLForm $this for chaining calls (since 1.20) */ - function addPostText( $msg ) { $this->mPost .= $msg; } + function addPostText( $msg ) { + $this->mPost .= $msg; + return $this; + } /** * Set text at the end of the display. * @param $msg String complete text of message to display + * @return HTMLForm $this for chaining calls (since 1.20) */ - function setPostText( $msg ) { $this->mPost = $msg; } + function setPostText( $msg ) { + $this->mPost = $msg; + return $this; + } /** * Add a hidden field to the output * @param $name String field name. This will be used exactly as entered * @param $value String field value * @param $attribs Array + * @return HTMLForm $this for chaining calls (since 1.20) */ public function addHiddenField( $name, $value, $attribs = array() ) { $attribs += array( 'name' => $name ); $this->mHiddenFields[] = array( $value, $attribs ); + return $this; } + /** + * Add a button to the form + * @param $name String field name. + * @param $value String field value + * @param $id String DOM id for the button (default: null) + * @param $attribs Array + * @return HTMLForm $this for chaining calls (since 1.20) + */ public function addButton( $name, $value, $id = null, $attribs = null ) { $this->mButtons[] = compact( 'name', 'value', 'id', 'attribs' ); + return $this; } /** * Display the form (sending to $wgOut), with an appropriate error * message or stack of messages, and any validation errors, etc. + * + * @attention You should call prepareForm() before calling this function. + * Moreover, when doing method chaining this should be the very last method + * call just after prepareForm(). + * * @param $submitResult Mixed output from HTMLForm::trySubmit() + * @return Nothing, should be last call */ function displayForm( $submitResult ) { $this->getOutput()->addHTML( $this->getHTML( $submitResult ) ); @@ -478,7 +618,7 @@ class HTMLForm extends ContextSource { } /** - * Wrap the form innards in an actual
element + * Wrap the form innards in an actual "" element * @param $html String HTML contents to wrap. * @return String wrapped HTML. */ @@ -511,15 +651,15 @@ class HTMLForm extends ContextSource { * @return String HTML. */ function getHiddenFields() { - global $wgUsePathInfo; + global $wgArticlePath; $html = ''; - if( $this->getMethod() == 'post' ){ + if ( $this->getMethod() == 'post' ) { $html .= Html::hidden( 'wpEditToken', $this->getUser()->getEditToken(), array( 'id' => 'wpEditToken' ) ) . "\n"; $html .= Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) . "\n"; } - if ( !$wgUsePathInfo && $this->getMethod() == 'get' ) { + if ( strpos( $wgArticlePath, '?' ) !== false && $this->getMethod() == 'get' ) { $html .= Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) . "\n"; } @@ -560,7 +700,7 @@ class HTMLForm extends ContextSource { 'input', array( 'type' => 'reset', - 'value' => wfMsg( 'htmlform-reset' ) + 'value' => $this->msg( 'htmlform-reset' )->text() ) ) . "\n"; } @@ -620,7 +760,7 @@ class HTMLForm extends ContextSource { /** * Format a stack of error messages into a single HTML string * @param $errors Array of message keys/values - * @return String HTML, a