KLEmailForm
This MediaWiki extension is used to create an email form in any article. Both the form fields and the response to submittal are formatted using standard wikitext. Upon submittal, the user is returned to the same page and the response is displayed in place of the form.
See Help:KLEmailForm for a discussion of usage.
Installation
To install:
- Copy the code from the code block at the end of this page to the file
$IP/extensions/KLEmailForm.php - Add this line to LocalSettings.php:
require_once("$IP/extensions/KLEmailForm.php");
Code
<?php
/**
* KLEmailForm.php
* This extension inserts a form mailer into a page
* written by Kennylucius http://kennylucius.com/
* LocalSettings.php file:
* require_once("$IP/extensions/KLEmailForm.php");
*/
define("EMAILFORM_NAME", "EmailForm"); // Name of tag
define("EMAILFORM_SUBMIT_BUTTON", "Submit Email"); // Name of POST identifier flag
if(! defined( 'MEDIAWIKI' ) ) {
die("This is not a valid entry point.\n");
}
$wgExtensionCredits['parserhook'][] = array(
'name' => 'KLEmailForm',
'version' => '0.1',
'author' =>'Kenny Lucius',
'url' => 'http://www.kennylucius.com/KLEmailForm',
'description' => 'Inserts an email form into a page via <EmailForm>'
);
# EmailForm MediaWiki extension
$wgExtensionFunctions[] = "wfKLEmailForm_Extension";
function wfKLEmailForm_Extension() {
global $wgParser;
// set hook for <EmailForm> ... </EmailForm>
$wgParser->setHook(EMAILFORM_NAME, 'renderKLEmailForm' );
}
// Callback function for converting wikitext to HTML output
// Normally, a form is returned. If the submit button was pressed
$KLEmailFormObj = null;
function renderKLEmailForm( $text, $argv, &$parser ) {
global $KLEmailFormObj;
//it is important to disable the cache for dynamic data
$parser->disableCache();
//if the object already exists, then we are processing nested tags
if(is_object($KLEmailFormObj)) {
return $KLEmailFormObj->recursive_parsing($text, $argv, $parser);
}
//if null object, instantiate it, process the input, then return processed HTML
else {
$KLEmailFormObj = new KLEmailFormClass();
$output = $KLEmailFormObj->get_HTML_for_input($text, $argv, $parser);
//print_r($KLEmailFormObj);die();
$KLEmailFormObj = null;
return $output;
}
}
class KLEmailFormClass {
var $sendto;
var $submitted;
var $posted;
var $processing_result;
var $ispost;
var $formHTML;
var $resultHTML;
var $errors;
function __construct() {
$this->sendto = '';
$this->processing_result = false;
$this->resultHTML = '';
$this->formHTML ='';
$this->posted = array();
$this->default = array();
$this->errors = array();
//process $_POST data
if($_POST['submit'] == EMAILFORM_SUBMIT_BUTTON) {
$this->submitted = true;
$post=$_POST;
unset($post['submit']);
$this->set_posted_name( $post['name'] ); unset($post['name']);
$this->set_posted_from( $post['from'] ); unset($post['from']);
$this->set_posted_subject($post['subject']); unset($post['subject']);
$this->set_posted_message($post['message']); unset($post['message']);
//remainder of fields are added to message
$this->message_addons = '';
foreach ($post as $arg => $value) {
$this->posted['addons'] .= "{$arg}: {$value}\n\n";
}
}
//generate default post data
else {
$this->submitted = false;
$this->set_posted_name('');
$this->set_posted_from('');
//newlines
$nls = array("\n", "\r", '\n');
$this->set_posted_subject(str_replace($nls, ' ', $_GET['subject']));
$this->set_posted_message(str_replace($nls, '
', $_GET['message']));
}
}
function recursive_parsing($text, $argv, &$parser) {
// recursive function for parsing tags
// <emailform name=60 />
$return = '';
if(isset($argv['prefill'])) {
$prefill = $argv['prefill'];
unset($argv['prefill']);
}
else {
$prefill = '';
}
foreach ($argv as $arg => $value) {
//within <emailform result>, just print the posted value
if($arg == 'result') {
$this->processing_result = true;
$this->resultHTML = $this->parse_subtext($text);
$this->processing_result = false;
return '';
}
elseif($this->processing_result) {
$return = $this->posted[$arg];
}
//outside <emailform result>, just print an appropriate form field
elseif($arg == 'sendto') {
$s = trim($value);
//to prevent email harvesting
//change ' at ' to @, ' dot ' to .
//and remove all spaces from string
$s = preg_replace('/ +?at +/', '@', $s);
$s = preg_replace('/ +?dot +/', '.', $s);
$s = str_replace(' ', '', $s);
$this->sendto = $s;
}
elseif($arg == 'submit') {
$return = ' <input type="submit" name="submit" value="' . EMAILFORM_SUBMIT_BUTTON . '"/> ' ;
}
elseif ( $value > 0 ) { // If the argument is numeric, it's a text field size
$size = explode( 'x', $value );
if ( $size[1] )
$return = '<textarea name="'.$arg.'" cols="'.$size[0].'" rows="'.$size[1].'" >'.$this->get_posted($arg,$prefill).'</textarea>' ;
else
$return = '<input type="text" name="'. $arg.'" size="'.$value.'" value="'.$this->get_posted($arg,$prefill).'" />' ;
}
else {
$return = '<input type="hidden" name="'.$arg.'" value="'.$value.'" />';
}
}
if($text) $return .= $this->parse_subtext($text);
return $return;
}
/* Returns HTML for:
The result if the user submitted and email was successful
The form, otherwise.
*/
function get_HTML_for_input($text, $argv, &$parser) {
global $wgTitle, $wgSitename, $wgUser;
// this sets up new output for processing the entire <emailform>
$this->resultHTML = '';
$this->formHTML ='<form action="'. $wgTitle->getFullURL() . '" method="post">';
$this->formHTML .= $this->recursive_parsing($text, $argv, $parser);
$this->formHTML .= '</form>';
//now that all input has been processed, output HTML
//if no sendto, output an error
if(! $this->sendto) {
$this->errors = array('The SendTo email address has not been defined. The form will not function.');
return $this->error_HTML() . $this->formHTML;
}
//if the form was not submitted, just output the form itself
if(! $this->submitted) {
return $this->formHTML;
}
//mail the form and return resultHTML or an error
if(count($this->errors)) {
return ($this->error_HTML() . $this->formHTML );
}
$from = "{$this->posted['name']} <{$this->posted['from']}>";
if(! mail( $this->sendto, $this->posted['subject'],
"Submitted at {$wgSitename}\nby {$this->posted['name']} <{$this->posted['from']}> \n\n"
. $this->posted['message'] ."\n\n"
. $this->posted['addon'],
"From: {$this->posted['name']} <{$this->posted['from']}>") ) {
return $this->error_HTML('The email was not sent due to an unknown error. PHP "mail()" returned false.')
. $this->formHTML;
}
return $this->resultHTML;
}
/* this returns the most appropriate value in this priority:
1. User-posted or link-prefilled value
2. Prefill value defined in the form
3. Default value
*/
function get_posted($field, $prefill='') {
if($this->posted[$field])
return $this->posted[$field];
if ($prefill)
return $prefill;
if($this->default[$field])
return $this->default[$field];
return '';
}
/* FIELD CHECKING FUNCTIONS
Each of these take a value that is assumed to be a $_POST value
and examines it, possibly registering an error that may be displayed
if the user submitted the form.
Each function also creates default values where possible or advisable.
*/
function set_posted_name($value) {
global $wgUser, $wgSitename;
//posted
if($value) {
$this->posted['name'] = $value;
}
else {
$this->posted['name'] = '';
}
//default
if($wgUser->isLoggedIn()) {
if(! $this->default['name'] = $wgUser->getRealName() ) {
$this->default['name'] = $wgUser->getName();
}
}
else {
$this->default['name'] = $wgSitename . ' User';
}
}
function set_posted_from($value) {
global $wgUser;
//posted
if($value) {
$this->posted['from'] = $value;
//validate email
$pos = strpos( $this->posted['from'], '@' );
if(! $pos || ($pos+1) >= strlen($this->posted['from']) ) {
$this->errors[] = 'Your email address appears invalid.';
}
}
else {
$this->posted['from'] = '';
}
//default
if($wgUser->isLoggedIn() && $this->default['from']=$wgUser->getEmail() ) {
//its done
}
else {
$this->default['from'] = '';
}
//error if posted value is empty
if(! $this->posted['from']) {
$this->errors[] = 'Your email address is required.';
}
}
function set_posted_subject($value) {
global $wgSitename;
//posted
if($value) {
$this->posted['subject'] = str_replace("\n", " ", $value);
}
else {
$this->posted['subject'] = '';
}
//default
$this->default['subject'] = 'Message from ' . $this->get_posted('name');
}
function set_posted_message($value) {
//posted
if($value) {
$this->posted['message'] = $value;
}
else {
$this->posted['message'] = '';
}
$this->default['message'] = '';
//error if posted message is empty
if(! $this->posted['message']) {
$this->errors[] = 'The message is blank.';
}
}
//helper functions
private function parse_subtext($text) {
global $wgParser;
$lparse = clone $wgParser;
$lparse->disableCache();
$output = $lparse->parse( $text, $wgParser->mTitle, $wgParser->mOptions, true, false );
return $output->getText();
}
private function error_HTML() {
$ret = "\n".'<center><table style="background:#faa; border:1px solid gray;border-collapse:collapse;">'
. '<tr><td style="padding:.1em .5em;">'
. 'Error: ';
if(count($this->errors)==1) {
$ret .= $this->errors[0] . ' Message not sent.';
}
else {
$ret .= 'Message not sent because:<br/>• '
. implode("\n<br/>• ", $this->errors) ;
}
return $ret ."</td></tr></table></center>\n" ;
}
} //end class
