Extension:FormHandler send form by Email

FormHandler send form by Email extension allows to create forms on wiki pages in a save way. The contents can be sent by email. It sends all fields and the user IP and - if the user is logged in - his/her username. This extension is suitable for creating simple forms. If you need very sophisticated things, you are probably better off not doing it inside MediaWiki anyway.

History: Initial Version

''This is the initial release. It has only been tested with MediaWiki 1.5.7 and is probably not fully compatible with 1.4 or 1.3. If you have any questions/comments, please send the author an email.''

Installation
To activate the extension, put the code into a file in your MediaWiki installation and include it from your LocalSettings.php with: include("extensions/FormHandler.php");

Dont forget to put <?php as first thing around the code in your new file.

To avoid spam, you should make sure that only trusted users can edit the pages which use the extension.

Syntax
Version 0.1 supports the field types text, textarea and select. Additionally hidden can be used to pass additional information with the Email. The syntax is very simple: [type]:(*) [param]="[value]", with the *, you mark entries which are required, the rest is considered optional. The form is included with the extension tag. It has some attributes to configure the form:

It is an error to not set at least one of sender or email.
 * name: A name to identify the form, useful if you use different forms on a page (required)
 * method: tells how to treat data (for now, only email is implemented) (required)
 * target: target for this form (with method email, this is the email address and required)
 * submit: if present, defines the text of the submit button, otherwise it is "Submit"
 * reset: if present, adds a reset button with its value as caption. Otherwise, no reset button is provided with the form.
 * email: if present, an email field is added to the top of the form with this attributes value as prompt. It is used as reply-to when sending the form.
 * sender: if present, must be a valid email address which is used as sender address to avoid problem with user specified email address.

An Example
 hidden: name="testform" value="additional info" text:* name="name" prompt="Your RealName" select: name="category" prompt="Please select problem category" option="Linux Software" option="Linux Hardware" text:* name="summary" prompt="Problem summary" textarea: name="description" prompt="Problem description" rows="10" cols="50" select: name="priority" prompt="Priority" option="Low" option="Medium" option="High" value="Medium"

Implementation
Hidden fields are not passed to the client at all, but sent as defined in the wiki page. This avoids users changing them. If you have a reasonable example why this could be a problem, i can happily change the behaviour.

Known Bugs
There is a problem with server side caching of the output of our extension. For now, we pass action=purge with every request which seems to help.

Todo

 * Develop a security concept. It must ensure that only trusted users can use the extension in the wiki pages. At the very last, a configuration option should limit the possible addresses to send form data to. (This however would require the admin to edit the php file, which is complicated.)
 * Add more supported field types, e.g. radio and checkbox
 * It would be easy to implement writing to a file or into into a database.

Code
Copy the following into a file named extensions/FormHandler.php

';   return $output; }

function submit { global $wgUser, $wgDBname, $wgIP; $error = ''; foreach($this->fields as $field) { $this->fields[$field['name']]['value'] = $this->request->getText('FormHandler_'.$field['name']); if (isset($field['required'])) { if (empty($_POST['FormHandler_'.$field['name']])) { $error .= $field['prompt']. ' '; //todo: better would be to highlight the fields. for this we would keep a list of required fields here. }     }    }    if (! empty($error)) { return $this->show("Not all required fields have been filled out: \n$error"); }

if ( 0 != $wgUser->getID ) { $username = $wgUser->getName; } else { $username = '(not logged in)'; }

$usermail = $this->request->getText('FormHandlerEmail'); if (empty($usermail)) $usermail=false;

$message = 'Form '.$this->argv['name']." has been submitted by $username (IP: $wgIP, Email: " . ($usermail ? $usermail : 'not specified') .') This Email is sent to you by MediaWiki FormHandler extension from http://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF']."\n\n"; foreach($this->fields as $field) { $message .= $field['name']. ': ';     switch($field['type']) { case 'text': case 'select': case 'textarea': $value = $this->request->getText('FormHandler_'.$field['name']); break; case 'hidden': $value = $field['value']; //we do not put it into form and not treat it, but keep it at server side... break; case 'invalid': $value = 'There is an invalid line in the form: '.$field['value']; break; default: $value = 'Implementation Error in FormHandler: unexpected field type '.$field['type']; break; }     $message .= (empty($value) ? '[not set]' : $value). "\n"; }

switch ($this->argv['method']) { case 'email': require_once('UserMailer.php'); if ($usermail!==false && ! $this->isValidEmail($usermail)) return $this->show('Your specified Email adress is invalid: '.$usermail); //sender is either == usermail or tested above

if (! $this->sender) { if (! $usermail) return $this->show("The Email field is required, please fill in."); $this->sender=$usermail; }

$error = userMailer( $this->sender, 			    $this->target, 			     'Contact form '.$this->argv['name'],			     $message,			     $usermail); if (empty($error)) { return 'Thank you for sending a message to '.$this->target."

\n&lt;pre>".nl2br($message).'&lt;/pre>';	} else {	 return "Sorry, sending the form failed.\n" . htmlspecialchars($error);	}	break;      default:	return 'Sorry, this is an invalid form, i do not know the method to store the information: '.$this->argv['method'];    }  }  /*    * Check Email for validity, using a regular expression.   */    function isValidEmail($candidate) {    return (eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $candidate));  } }