Extension:EmailForm

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual
Crystal Clear action run.png
EmailForm

Release status: unmaintained

EmailFormScreenshots.gif
Implementation Tag
Description Inserts an email form into a page.
Author(s) Eric Hartwell
Latest version 0.81. (June 2009)
MediaWiki 1.14+
Database changes No
License No license specified
Download See the code section
Tags
<emailform>

Translate the EmailForm extension if it is available at translatewiki.net

Check usage and version matrix; code metrics

The EmailForm extension allows 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.


Installation[edit | edit source]

  • Copy the code into file and extract the file(s) in a directory called EmailForm in your extensions/ folder. If you're a developer and this extension is in a Git repository, then instead you should clone the repository.
  • Add the following code at the bottom of your LocalSettings.php:
require_once "$IP/extensions/EmailForm/EmailForm.php";
  • Done! Navigate to "Special:Version" on your wiki to verify that the extension is successfully installed.

Code[edit | edit source]

EmailForm.php
<?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/EmailForm.php");
 *
 * Minor adjustments made by John Adams
 */

 
###### Name used for the extension, tag, and settings page name #######
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.8.1',
         'author' =>'Eric Hartwell',
         'url' => 'https://www.mediawiki.org/wiki/Extension:EmailForm',
         'description' => 'Inserts a form mailer into a page'
         );
}
 
# EmailForm MediaWiki extension
$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 <EmailForm> ... </EmailForm>
    # the second parameter is the callback function for
    # processing the text between the tags
    $wgParser->setHook( /*Default: <EmailForm>*/    EMAILFORM_NAME, "renderEmailForm" );
}
 
# The callback function for converting the input text to HTML output
# On a normal invocation, this tag builds a mail input form. The submit button
# redirects to the same page, where the tag detects the parameters in $_GET
# and processes the actual email send. It then outputs the result message
# There are two main blocks: <emailform form> and <emailform result>
function renderEmailForm( $input, $argv, $parser ) {

    #######################
   ##### 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:
   # <emailform> wikitext with <emailform fields /> for each field </emailform>
   # <emailform field1= field2= /> Basic inline form e.g. [text field][submit button]
   # <emailform field= /> Single field - assume it's inside a bracketing <emailform></emailform>
   # <emailform results> 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. <emailform name=60 email=60 comment=60x15 action=purge />
   $output = '';
    foreach ($argv as $arg => $value) {
        $output .= render_email_field($arg, $value, $ispost, $input, $parser, '');
    }
 
    # Render the outer tag as <form>input text<fields></form>
   if ( count($keys) != 1 )
        $output = render_email_field( $mode, '', $ispost, $input, $parser, $output );
    return( $output );
}
 
# This function translates one field
# Returns string for output
# How do I disable caching for pages using my extension?
# http://www.mediawiki.org/wiki/Extensions_FAQ#Recent_versions
# In MediaWiki 1.7.0 and upwards, the following should be sufficient:
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 (
                      '<form action="'. $wgTitle->getFullURL() . '" method="post">'
                    . '<input type="hidden" name="action" value="view" />'
                    . '<input type="hidden" name="' . POST_IDENTIFIER . '" value="send" />'
                    . render_wikitext($parser, $input) . $extra
                    . '</form>'
            );
        }
 
    case 'submit':        return( ' <input type="submit" name="submit" value="' . $value . '"/> ' );
 
    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 );

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

                if(count($size)>1) {    #This code eliminates an error related to referencing the $size array by numerical keys
                        reset($size);
                        $firstpiece = ('<textarea name="'.$arg.'" cols="'.current($size).'"');
                        next($size);
                        $secondpiece = (' rows="'.current($size).'" ></textarea>' );
                        return($firstpiece.$secondpiece);
                }

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

            #ORIGINAL# if ( $size[1] ) return( '<textarea name="'.$arg.'" cols="'.$size[0].'" rows="'.$size[1].'" ></textarea>' );
           else            return( '<input type="text" name="'. $arg.'" size="'.$value.'" />' );
        }
 
        # Arbitrary hidden fields
       return( '<input type="hidden" name="'.$arg.'" value="'.$value.'" />' );
    }
}
 
# This function formats and sends the email
# Message parameters come from the global $_POST arguments
# $settings: parameters come from the [[MediaWiki:EmailForm]] page
# Returns true if the message was accepted for output
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 <email>" 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 #####
   #######################

    $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 );
}
 
# How do I render wikitext in my extension?
# http://www.mediawiki.org/wiki/Extensions_FAQ#Parser_hooks
function render_wikitext($parser, $input) {
 
# Uncomment these lines if you are running MediaWiki prior to 1.14:
#    $lparse = clone $parser;
#    $output = $lparse->parse( $input, $parser->mTitle, $parser->mOptions, true, false );
#   return( $output->getText() );

# Otherwise use these lines:
   $output = $parser->recursiveTagParse( $input );
    return( $output );
}
 
# Load the email form settings from a special page MediaWiki:EmailForm
# $pagetitle is the name of the page with the form on it
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 );
}

Security[edit | edit source]

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.

Usage[edit | edit source]

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

The contents of the input form are specified between <EmailForm> and </EmailForm> 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 <EmailForm result> and </EmailForm> tags.

Form fields are identified by attributes to the <EmailForm> tag, such as <emailform name=40 /> and <emailform submit="Send Comments" />. The same attributes are used to display the fields in the result, though the attribute values are ignored.

Example[edit | edit source]

Create a formatted input form and result block like this:

<emailform>
 {| 
 | Name: || <emailform name=40 /> || (optional)
 |-
 | Email: || <emailform from=40 /> || (optional, unless you'd like a reply)
 |-
 | Comments:
 | colspan="2" | <emailform comments=80x8 />
 |-
 | colspan="3" align="center" | <emailform submit="Send Comments" />
 |}
 </emailform>
 <emailform result>
 Thanks for your comments!
 {| width="300px"
 | '''From:''' <emailform name /> <emailform from/><br />
 '''Comments:''' <emailform comments />
 |}
 </emailform>

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

<emailform>

Name: <emailform name=40 /> (optional)
Email: <emailform from=40 /> (optional, unless you'd like a reply)
Comments: <emailform comments=80x8 />
<emailform submit="Send Comments" />

</emailform> <emailform result> Thanks for your comments!

From: <emailform name /> <emailform from/>

Comments: <emailform comments />

</emailform>

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

EmailFormScreenshots.gif

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

Attributes[edit | edit source]

This extension adds a single tag, <emailform>, 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[edit | edit source]

Syntax: <emailform attribute>

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. <emailform form> is equivalent to <emailform>.
report
Acts as a container for controls. It can contain text and markup (paragraphs, lists, etc.) in addition to form controls. Any <emailform fields in the report 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[edit | edit source]

Syntax: <emailform attribute=value>

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.

Fields whose value starts with a number (like <emailForm name=80 />) are treated as text fields. All others are treated as hidden fields, which can be used to pass predefined text to the mailer.

submit=button label
Creates a submit button to submit the form. The value of the attribute is used for the button label, i.e. <emailform submit="Send this" /> creates a button labelled Send this. Clicking the button sends the form.

Settings in MediaWiki:EmailForm[edit | edit source]

The special page, MediaWiki:EmailForm (/servername/yoursitename/index.php?title=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 | send to email address | prefix for subject
page name
Name of the page that the form is on, e.g. Contact me
send to email address
Email address used as a target for the form, e.g. To: eat-this@spam.bot
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:

Contact me | eat-this@spam.bot | (from contact form)
Request help | eat-this@spam.bot | (from help form)

Implementation[edit | edit source]

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

The extension uses the built-in PHP mail() 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[edit | edit source]

  • 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 render_wikitext 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 $wgTitle->isProtected('edit') 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 get_MediaWikiEmailForm_settings creates a new Article to load the settings page and $article->fetchContent() 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 $parser->disableCache() 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 action=purge 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 $_POST for a special parameter, sendEmailForm, to distinguish between input and result modes.

Version history[edit | edit source]

  • 0.8: 1 August 2007, initial public release
  • 0.8.1: June 2009, bugfix release for MediaWiki 1.14 and above

See also[edit | edit source]