Extension:EmailForm

What can this extension do?
This extension is used to create email response forms.

Both the input form and the results, which are defined on the same wiki page, can be fully formatted using standard wikitext.

Usage
The same page is used for the email input form and the target/results.

The contents of the input form are specified between  and   tags. Even though it's an XML-style extension, EmailForm renders wikitext within the tags. This lets you specify arbitrary content for the form, including tables, links, and styles in addition to the form fields. Similarly, the result is between  and   tags.

Form fields are identified by attributes to the  tag, such as   and. The same attributes are used to display the fields in the result, though the attribute values are ignored.

Example
Create a formatted input form and result block like this:

The rendered page would look like this, with the tags visible as when EmailForm is not installed:

With EmailForm installed, the resulting page looks like this after styles are applied (input form at the top, results at the bottom):



The "Contact me" form at my own web site is here.

Attributes
This extension adds a single tag, , to Wikitext markup. Multiple copies of the tag are used in combination to define a form. The meaning of each tag is specified by its attributes.

Predefined attribute/field values
Syntax:   
 * form (optional): Acts as a container for controls. It can contain text and markup (paragraphs, lists, etc.) in addition to form controls. This attribue is optional, i.e.   is equivalent to.
 * report: Acts as a container for controls. It can contain text and markup (paragraphs, lists, etc.) in addition to form controls. Any   fields in the   section are replaced by the values passed in the POST command, and can be used to provide feedback to the user.

User-specified attribute/field values
Syntax:    Fields whose value starts with a number (like  ) are treated as text fields. All others are treated as hidden fields, which can be used to pass predefined text to the mailer.
 * inputname=cols: Creates a text field named inputname that is cols columns wide
 * textname=rowsxcolumns: Creates a multiline text field named textname that is rows rows high by cols columns wide. Multiline fields are distinguished from single line fields by the x
 * hiddenname=val: Creates a hidden field named hiddenname with the value val.
 * submit=button label: Creates a submit button to submit the form. The value of the attribute is used for the button label, i.e.   creates a button labelled Send this. Clicking the button sends the form.

Settings in MediaWiki::EmailForm
The special page, MediaWiki:EmailForm, has one line for each page with an email form on it. Each line specifies the settings for that page, separated by the '|' character. The format of each line is:


 * page name: Name of the page that the form is on, e.g.
 * send to email address: Email address used as a target for the form, e.g. To:
 * prefix for subject: Prefix for the start of the email's subject. The first 60 characters of the message contents are appended to create the Subject: field.

Example:

Installation
The extension is a single script which you can save into your extensions directory and include in your LocalSettings.php file.

Security
There are obvious concerns when adding email form support to an open wiki. To prevent users from using it for spam, this extension is intended to be activated only by system administrators (see: Help:Administration). The destination email address is stored in a separate page instead of with the form code to help discourage spam bots.
 * For security reasons, this extension is only active on protected pages, which means only system administrators can change the form(s).
 * The email settings (including the destination address) must be specified in a special page, MediaWiki:EmailForm, in the MediaWiki namespace, which means only system administrators can change it.

Implementation
When the submit button is pressed, the form is posted to the same page. When the main   field is parsed, the message parameters are extracted from the POST data using the PHP global,.

The extension uses the built-in PHP function to send the message through the sendmail binary on your server. This lowest-common-denominator function works on most systems and provides adequate functionality, at least on my host.

Tips, tricks, and hoops

 * Even though it's an XML-style extension, EmailForm renders wikitext within the tags. This lets you specify arbitrary content for the form and results, including tables, links, and styles in addition to the form fields.
 * The function  uses a cloned copy of the parser object to render the wikitext contents (see How do I render wikitext in my extension?).
 * The extension checks  to ensure it only works on protected pages. This means only system administrators can change the form contents.
 * The page with the email addresses and other settings is in the 'MediaWiki' namespace, which means only system administrators can change it.
 * The function  creates a new   to load the settings page and   to get its wikitext contents.
 * The extension won't work if MediaWiki uses cached versions of the page with the email form and results.
 * It uses  to disable the cache. (see How do I disable caching for pages using my extension?).
 * It tells MediaWiki to flush the cache before it starts parsing the result page by passing  with every request as hidden field with the name 'action' and the value 'purge'.
 * The same wiki page is used for the email form, the POST target, and the results display.
 * The code checks the PHP global variable  for a special parameter, , to distinguish between input and result modes.

Version history

 * 0.8: 1 August 2007, initial public release

Eliminate Your PHP Errors
I implemented this extension by the instructions above and my wiki page gave me a list of repeated errors like follows on the page where I placed the :

PHP Notice: Undefined index: sendEmailForm in C:\Inetpub\wwwroot\mediawiki\extensions\emailform\EmailForm.php on line 49

PHP Notice: Undefined offset: 0 in C:\Inetpub\wwwroot\mediawiki\extensions\emailform\EmailForm.php on line 58

PHP Notice: Undefined offset: 1 in C:\Inetpub\wwwroot\mediawiki\extensions\emailform\EmailForm.php on line 127

This drove me nuts, so I edited the EmailForm.php file so that these errors no longer display. I have verified that the EmailForm still functions perfectly. I also changed the subject line in the emails so that they only display the prefix and the name information instead of the entire content of the email.

All of my changes are very obvious and I left the original code in place behind comment symbols. I hope this helps you too!

<?php /** * EmailForm.php * This extension inserts a form mailer into a page * written by Eric Hartwell http://www.ehartwell.com/About * To activate the functionality of this extension include the following in your * LocalSettings.php file: * require_once("$IP/extensions/EmailForm.php"); * * Minor adjustments made by John Adams */ define("EMAILFORM_NAME", "EmailForm");            # Name of tag define("POST_IDENTIFIER", "sendEmailForm");       # Name of POST identifier flag if(! defined( 'MEDIAWIKI' ) ) { echo( "This is an extension to the MediaWiki package and cannot be run standalone.\n" ); die( -1 ); } else { $wgExtensionCredits['parserhook'][] = array(        'name' => EMAILFORM_NAME,         'version' => '0.8a',         'author' =>'Eric Hartwell (Minor fixes by John Adams', 'url' => 'http://www.mediawiki.org/wiki/Extension:EmailForm', 'description' => 'Inserts a form mailer into a page' ); } $wgExtensionFunctions[] = "wfEmailFormExtension"; function wfEmailFormExtension {    global $wgParser;     global $wgHooks;     # register the extension with the WikiText parser     # the first parameter is the name of the new tag.     # In this case it defines the tag  ...      # the second parameter is the callback function for     # processing the text between the tags     $wgParser->setHook( /*Default: */    EMAILFORM_NAME, "renderEmailForm" ); } function renderEmailForm( $input, $argv, &$parser ) {
 * 1) Name used for the extension, tag, and settings page name #######
 * 1) EmailForm MediaWiki extension
 * 1) The callback function for converting the input text to HTML output
 * 2) On a normal invocation, this tag builds a mail input form. The submit button
 * 3) redirects to the same page, where the tag detects the parameters in $_GET
 * 4) and processes the actual email send. It then outputs the result message
 * 5) There are two main blocks: and

#######################   ##### Custom Code ##### #######################

reset($_POST);			#This code eliminates an error related to referencing the $_POST array by 'sendEmailForm' $ispost = current($_POST);

##############################   ##### End of Custom Code ##### ##############################

#ORIGINAL# $ispost = $_POST[POST_IDENTIFIER]; # Cases: # wikitext with for each field # Basic inline form e.g. [text field][submit button] # Single field - assume it's inside a bracketing # for results output $keys = array_keys($argv);

#######################   ##### Custom Code ##### #######################

$mode = strtolower(key($keys));		#This code eliminates an error related to referencing the $keys array by numerical keys

##############################   ##### End of Custom Code ##### ##############################

#ORIGINAL# $mode = strtolower($keys[0]);   # See if first argument is 'form' or 'result'

if ( $mode=='form' )   $argv = array_shift( $argv );    # Drop 'form' or 'result' for now else                   $mode = 'form';                    # Empty or a field type # Process form field(s) # Put this in a loop to allow multiple fields in one tag, # e.g.  $output = ''; foreach ($argv as $arg => $value) { $output .= render_email_field($arg, $value, $ispost, $input, $parser, ''); }   # Render the outer tag as input text if ( count($keys) != 1 ) $output = render_email_field( $mode, '', $ispost, $input, $parser, $output ); return( $output ); } function render_email_field($arg, $value, $ispost, $input, &$parser, $extra) { global $wgTitle; switch ( strtolower($arg) ) { case 'result':   # Wrapper for results display if ( $ispost ) {           $parser->disableCache;     #### Important: Disable Cache #### return ( render_wikitext($parser, $input) );   # Show the results }       return ( '' );        # Hide the results when showing the form case 'form':   # Form wrapper # See if we're building the form if ( $ispost ) { # Get the remaining settings from MediaWiki:EmailForm $settings = get_MediaWikiEmailForm_settings ( $wgTitle->getText ); if ( $settings ) { send_email($settings);       # Send the email message return ( '' );               # Hide the input form when showing results } else { return ( EMAILFORM_NAME . ': MediaWiki:' . EMAILFORM_NAME . ' has no settings for ' . $wgTitle->getText . '' ); }       } else { if ( !($wgTitle->isProtected ('edit')) ) return ( EMAILFORM_NAME . " is only active on protected pages." ); $parser->disableCache;    #### Important: Disable Cache #### return (                     'getFullURL . '" method="post">'                    . ''                    . ''                    . render_wikitext($parser, $input) . $extra                    . ' '             ); }   case 'submit':        return( '  ' ); default: # Result: Display contents of corresponding field if ($ispost)    return( $_POST[$arg] ); # Build other form fields # If the argument is numeric, it's a text field size if ( $value > 0 ) { $size = explode( 'x', $value );
 * 1) This function translates one field
 * 2) Returns string for output
 * 3) How do I disable caching for pages using my extension?
 * 4) http://www.mediawiki.org/wiki/Extensions_FAQ#Recent_versions
 * 5) In MediaWiki 1.7.0 and upwards, the following should be sufficient:

#######################           ##### Custom Code ##### #######################

if(count($size)>1) {	#This code eliminates an error related to referencing the $size array by numerical keys reset($size); $firstpiece = (' ' ); return($firstpiece.$secondpiece); }

##############################           ##### End of Custom Code ##### ##############################

#ORIGINAL# if ( $size[1] ) return( ' ' ); else           return( '' ); }       # Arbitrary hidden fields return( '' ); } } function send_email( $settings ) { # Wrap the form's fields into a message string $message = $name = $from = ""; foreach ($_POST as $arg => $value) { switch ( strtolower($arg) ) { # Ignore framework fields case strtolower(POST_IDENTIFIER): case 'action': case 'submit':           break; case 'name':       $name = $value;        break; case 'from':       $from = $value;        break; default:           $message .= $arg. ": " . $value. "\n";   break; }   }    # The name and email address are optional. Format as "Name " or "Name" or "email" if ( $name ) { if ( $from )   $from = $name. ' <' . $from. '>';       else            $from = $name; }   if ( !$from )        $from = $settings['prefix']; # GoDaddy: If you use the mail function in your PHP, you do not need to specify # an outgoing mail server. If you are are using some other method besides mail # in your PHP code, use relay-hosting.secureserver.net for your relay server. # mail returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise. #######################   ##### Custom Code ##### #######################
 * 1) This function formats and sends the email
 * 2) Message parameters come from the global $_POST arguments
 * 3) $settings: parameters come from the MediaWiki:EmailForm page
 * 4) Returns true if the message was accepted for output

$subject = $settings['prefix']. $name;	#This reduces the subject line to just the prefix and the name

##############################   ##### End of Custom Code ##### ##############################

#ORIGINAL# $subject = $settings['prefix']. str_replace("\n", " ", substr( $message, stripos($message,":")+1, 60) );

$sent = mail ( $settings['to'], $subject, "From: " . $from . "\n" . $message); return( $sent ); } function render_wikitext($parser, $input) {   $lparse = clone $parser; $output = $lparse->parse( $input, $parser->mTitle, $parser->mOptions, true, false ); return( $output->getText ); } function get_MediaWikiEmailForm_settings ( $pagetitle ) { $settingpage= new Article( Title::newFromText('MediaWiki:'. EMAILFORM_NAME) ); if ( !$settingpage)   return(null); $content = $settingpage->fetchContent(0,false,false); if ( $content )   { # Find the settings for this particular form $lines = explode ( "\n", $content ); foreach ( $lines as $line ) { $settings = explode( '|', $line ); if ( trim(strtolower($settings[0])) == strtolower($pagetitle) ) return( array( 'to'=>trim($settings[1]), 'prefix'=>trim($settings[2] ) ) ); }   }    # Default: No data return( null ); } ?> -66.162.87.252 22:58, 19 December 2007 (UTC)
 * 1) How do I render wikitext in my extension?
 * 2) http://www.mediawiki.org/wiki/Extensions_FAQ#Parser_hooks
 * 1) Load the email form settings from a special page MediaWiki:EmailForm
 * 2) $pagetitle is the name of the page with the form on it