Skip to content

Instantly share code, notes, and snippets.

@netcarver
Created April 30, 2012 19:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save netcarver/dfe078ef4892dbec629d to your computer and use it in GitHub Desktop.
Save netcarver/dfe078ef4892dbec629d to your computer and use it in GitHub Desktop.
Simple contact form for PW. Depends on flourish by Will Bond.
<?php
include('head.inc'); // Include your head setup.
/* Setup the flourish class autoloader. */
function flourish_loader( $class_name )
{
// ** Customize this to your root Flourish directory **
$flourish_root = wire('config')->paths->root . 'site/.flourish/';
$file = $flourish_root . $class_name . '.php';
if (file_exists($file)) {
include $file;
}
}
spl_autoload_register( 'flourish_loader', true );
/* Bring in the contact form code. */
require_once('glue.php'); // Rename the file if you want to, glue.php doesn't really make sense in this context.
/* Setup for outgoing email -- the connection is only made if an email is actually sent. */
$smtp = new fSMTP('smtp.gateway.domain', ... ); // Setup your SMTP gateway here. See http://flourishlib.com/docs/fSMTP for details.
$smtp->authenticate( 'your.smtp.username', 'your.smtp.password' );
echo pwContactForm( 'you@yourdomain.com', $smtp ); // Causes the form to be rendered and takes all needed action to process it and email you the results.
<?php
class pwContactForm
{
protected $email = '';
protected $smtp = null;
protected $name = '';
public function setEmail( $email ) { $this->email = $email; return $this; }
public function setNamel( $name ) { $this->name = $name; return $this; }
public function setSMTP ( $smtp ) { $this->smtp = $smtp; return $this; }
public function getEmail() { return $this->email; }
public function getName () { return $this->name; }
public function getSMTP () { return $this->smtp; }
public function __construct( $to, fSMTP &$smtp=null )
{
$this->email = $to;
$this->smtp = $smtp;
$this->name = __CLASS__;
}
protected function sendMessage( $name, $reply_to, $message )
{
$eml = new fEmail();
$eml->addRecipient( $this->email );
$eml->setFromEmail( 'noreply@yourdomian.com', 'Webmail contact form' );
$eml->setBounceToEmail( 'noreply@yourdomain.com' );
$eml->setSubject( "Message from website contact form" );
$eml->setBody( "From: $name <$reply_to>.\nMessage...\n$message" );
$eml->send( $this->smtp );
unset( $eml );
}
protected function render( $token, $name='', $from_email='', $message='', $errors='' )
{
$o = <<<FORM
<form class=\"contact\" action="" method="post">
<input type="hidden" name="_form_token" value="$token" />
<legend>Contact Form</legend>
$errors
<div class="control-group">
<label class="control-label" for="name">Your name</label>
<div class="controls">
<input class="input-xlarge" id="name" name="name" type="text" value="$name" length="64" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="from_email">Your email</label>
<div class="controls">
<input class="input-xlarge" id="from_email" name="from_email" type="text" value="$from_email" length="128" />
<p class="help-block">Please use a valid email address at which you can be reached.</p>
</div>
</div>
<div class="control-group">
<label class="control-label" for="message">Message</label>
<div class="controls">
<textarea class="input-xlarge" name="message" id="message" rows="8">$message</textarea>
</div>
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form>
FORM;
return $o;
}
public function __toString()
{
$o = '';
if( fRequest::isPost() ) {
#
# Form posted, validate the token matches that stored in the session for this form...
#
$token = fRequest::encode('_form_token');
$token_ok = CSRFToken::check( $this->name, $token );
CSRFToken::clear( $this->name );
if( $token_ok ) {
#
# Anti-CSRF token validated ok...
#
$name = fRequest::encode('name');
$from_email = fRequest::encode('from_email');
$message = fRequest::encode('message');
try {
$validator = new fValidation();
$validator->addRequiredFields('name', 'from_email', 'message');
$validator->overrideFieldName('from_email', 'Your email address');
$validator->addEmailFields('from_email');
$validator->addEmailHeaderFields('name', 'from_email');
#
# Check the other input values. Throws an exception if validation fails...
#
$validator->validate();
#
# Validated OK, send email and show success message on screen...
$this->sendMessage( $name, $from_email, $message );
$o .= "<p>Thank you, your message has been sent.</p>";
} catch (fValidationException $e) {
#
# Validation of form values failed. Re-render the form with the values received & new token...
#
$o = $this->render( CSRFToken::get( $this->name ), $name, $from_email, $message, $e->getMessage() );
}
} else {
#
# Invalid CSRF token. To prevent CSRF, reject this.
#
$o .= "<p>Something strange happened during the submission of your form. Please try again.</p>";
}
} else {
#
# This is a get request (landing page) so create a new token and render the empty form...
#
$o = $this->render( CSRFToken::get( $this->name ) );
}
return $o;
}
}
function pwContactForm( $to, $smtp=null )
{
return new pwContactForm( $to, $smtp );
}
class CSRFToken
{
static public function get( $form_name )
{
$tok = fCryptography::randomString(32);
wire()->session->set( $form_name . '.CSRFToken', $tok );
return $tok;
}
static public function check( $form_name, $value )
{
$stored = wire()->session->get( $form_name . '.CSRFToken' );
return ( $stored === $value );
}
static public function clear( $form_name )
{
wire()->session->remove( $form_name . '.CSRFToken' );
return $this;
}
}
#eof
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment