Skip to content

Instantly share code, notes, and snippets.

@manviny
Forked from Rayden/form-builder.inc
Created December 11, 2013 13:49
Show Gist options
  • Save manviny/7910721 to your computer and use it in GitHub Desktop.
Save manviny/7910721 to your computer and use it in GitHub Desktop.
<?php
/**
* If you want to add-on runtime hooks, validation or additional functionality to Form Builder,
* place this file in /site/templates/form-builder.inc
*
* It will be included by /site/templates/form-builder.php when present.
*
*/
if(!defined("PROCESSWIRE")) die();
/**
* Configuration settings for your SMTP mail account
*
* See PHPMailer for more information
* https://github.com/PHPMailer/PHPMailer
*
*/
define("MAILHOST", "");
define("MAILUSER", "");
define("MAILPASS", "");
define("MAILCHARSET", "UTF-8");
define("SMTPSECURE", "tls"); // Enable encryption, 'ssl' also accepted
define("PHPMAILERPATH", wire('config')->paths->templates . "/PHPMailer/"); // path to PHPMailer
// ----- End of config
$forms->addHookBefore('FormBuilderProcessor::emailForm', null, 'hookEmailForm');
$forms->addHookBefore('FormBuilderProcessor::emailFormResponder', null, 'hookEmailFormResponder');
function hookEmailFormResponder(HookEvent $event) {
$event->replace = true;
$obj = $event->object;
$skipFieldNames = array();
$skipFieldTypes = array(
'InputfieldSubmit',
);
$values = $obj->getValues();
if(!strlen($obj->responderTo)) return false;
$field = $values[$obj->responderTo];
if(!$field) return false;
$responderTo = wire('sanitizer')->email($field);
if(!strlen($responderTo)) return false;
$to = emailsToArray($responderTo, $obj->getValues());
$from = $obj->responderFrom;
$subject = wire('sanitizer')->text($obj->responderSubject);
// autogenerate an email subject if not provided
if(!$subject) $subject = sprintf($this->_('%s form submission'), $obj->formName);
$body = $obj->responderBody;
if($obj->honeypot) $skipFieldNames[] = $obj->honeypot;
$values = array();
$labels = array();
$formArray = $obj->getFormArray();
foreach($obj->getValues() as $key=>$value) {
if(in_array($key, $skipFieldNames)) continue;
$len = strlen($value);
$value = str_replace(array('<ul>', '<li>', '</ul>', '</li>'), array('', '', '', "\n"), $value);
if($len !== strlen($value)) $value = nl2br($value);
$values[$key] = trim($value);
$labels[$key] = htmlentities($formArray['children'][$key]['label'], ENT_QUOTES, 'UTF-8');
}
$template = "email-autoresponder";
// 1. first try /site/templates/FormBuilder/[template]-[form].php
$filename = wire('config')->paths->templates . "FormBuilder/$template-{$obj->formName}.php";
// 2. next try /site/templates/FormBuilder/[template].php
if(!is_file($filename)) $filename = wire('config')->paths->templates . "FormBuilder/$template.php";
// 3. otherwise, use the predefined one in /site/modules/FormBuilder/[template].php
if(!is_file($filename)) $filename = wire('config')->paths->FormBuilder . "/$template.php";
$t = new TemplateFile($filename);
$t->set('values', $values);
$t->set('labels', $labels);
$t->set('body', populateTags($body, $labels, $values));
$t->set('subject', $subject);
$t->set('form', $obj);
$body = $t->render();
$params = wire('config')->phpMailAdditionalParameters;
if(!$params) $params = '';
require_once(PHPMAILERPATH . 'class.phpmailer.php');
$mail = new PHPMailer;
$mail->CharSet = MAILCHARSET;
$mail->isSMTP();
$mail->Host = MAILHOST;
$mail->SMTPAuth = true;
$mail->Username = MAILUSER;
$mail->Password = MAILPASS;
$mail->SMTPSecure = SMTPSECURE;
$mail->From = $from;
$mail->FromName = $from;
$mail->addReplyTo($from);
$mail->Subject = $subject;
foreach($to as $email) {
$mail->addAddress($email);
}
$mail->WordWrap = 50;
$mail->isHTML(true);
$mail->Body = $body;
$mail->AltBody = strip_tags($body);
$result = $mail->send();
return $result;
}
function hookEmailForm(HookEvent $event) {
$event->replace = true;
$obj = $event->object;
$skipFieldNames = array();
$skipFieldTypes = array(
'InputfieldSubmit',
);
$values = $obj->getValues();
// generate to array
$to = emailsToArray($obj->emailTo, $obj->getValues());
// no addresses to send to
if(!count($to)) return false;
$from = $values[$obj->emailFrom];
$subject = wire('sanitizer')->text($obj->emailSubject);
// autogenerate an email subject if not provided
if(!$subject) $subject = sprintf($this->_('%s form submission'), $obj->formName);
$body = "";
if($obj->honeypot) $skipFieldNames[] = $obj->honeypot;
$values = array();
$labels = array();
$formArray = $obj->getFormArray();
foreach($obj->getValues() as $key=>$value) {
if(in_array($key, $skipFieldNames)) continue;
$len = strlen($value);
$value = str_replace(array('<ul>', '<li>', '</ul>', '</li>'), array('', '', '', "\n"), $value);
if($len !== strlen($value)) $value = nl2br($value);
$values[$key] = trim($value);
$labels[$key] = htmlentities($formArray['children'][$key]['label'], ENT_QUOTES, 'UTF-8');
}
$template = "email-administrator";
// 1. first try /site/templates/FormBuilder/[template]-[form].php
$filename = wire('config')->paths->templates . "FormBuilder/$template-{$obj->formName}.php";
// 2. next try /site/templates/FormBuilder/[template].php
if(!is_file($filename)) $filename = wire('config')->paths->templates . "FormBuilder/$template.php";
// 3. otherwise, use the predefined one in /site/modules/FormBuilder/[template].php
if(!is_file($filename)) $filename = wire('config')->paths->FormBuilder . "/$template.php";
$t = new TemplateFile($filename);
$t->set('values', $values);
$t->set('labels', $labels);
$t->set('body', populateTags($body, $labels, $values));
$t->set('subject', $subject);
$t->set('form', $obj);
$body = $t->render();
$params = wire('config')->phpMailAdditionalParameters;
if(!$params) $params = '';
require_once(PHPMAILERPATH . 'class.phpmailer.php');
$mail = new PHPMailer;
$mail->CharSet = MAILCHARSET;
$mail->isSMTP();
$mail->Host = MAILHOST;
$mail->SMTPAuth = true;
$mail->Username = MAILUSER;
$mail->Password = MAILPASS;
$mail->SMTPSecure = SMTPSECURE;
$mail->From = $from;
$mail->FromName = $from;
$mail->addReplyTo($from);
$mail->Subject = $subject;
foreach($to as $email) {
$mail->addAddress($email);
}
$mail->WordWrap = 50;
$mail->isHTML(true);
$mail->Body = $body;
$mail->AltBody = strip_tags($body);
$result = $mail->send();
return $result;
}
function matches($value1, $operator, $value2) {
$matches = false;
switch($operator) {
case '==':
case '=': if($value1 == $value2) $matches = true; break;
case '>': if($value1 > $value2) $matches = true; break;
case '<': if($value1 < $value2) $matches = true; break;
case '>=': if($value1 >= $value2) $matches = true; break;
case '<=': if($value1 <= $value2) $matches = true; break;
case '*=': if(strpos($value2, $value1) !== false) $matches = true; break;
case '!=': if($value1 != $value2) $matches = true; break;
}
return $matches;
}
function emailsToArray($str, array $fields) {
$emails = array();
foreach(explode("\n", $str) as $line) {
$line = trim($line);
if(strpos($line, '?') !== false) {
// conditional address
// VARIABLES: 1:field name 2:operator 3:value 4:email
if(!preg_match('/^([-_.a-zA-Z0-9]+)\s*(=|==|>|<|>=|<=|\*=|!=)([^\?]*)\?\s*(.*)$/', $line, $matches)) continue;
$field = $matches[1];
$subfield = '';
if(strpos($field, '.') !== false) list($field, $subfield) = explode('.', $field);
$operator = $matches[2];
$requireValue = $matches[3];
$addrs = explode(',', $matches[4]); // one email or optional multiple CSV string of emails
if(!count($addrs)) continue; // invalid email address
$inputValue = $fields[$field];
// pull subfield value from an object, typically a $page
if(is_object($inputValue) && $subfield) $inputValue = $inputValue->$subfield;
if(!matches($inputValue, $operator, $requireValue)) continue; // condition does not match
// condition matches
foreach($addrs as $email) $emails[] = $email;
} else if(strpos($line, ',') !== false) {
// multiple addresses on 1 line
foreach(explode(',', $line) as $email) $emails[] = $email;
} else {
// just an email address
$emails[] = $line;
}
}
// sanitize and validate all found emails
foreach($emails as $key => $email) {
$email = wire('sanitizer')->email($email);
if(!strlen($email)) unset($emails[$key]);
else $emails[$key] = $email;
}
return $emails;
}
function populateTags($body, $labels, $values) {
if(strpos($body, '[') === false) return $body;
if(!preg_match_all('/\[([_.a-zA-Z0-9]+)\]/', $body, $matches)) return $body;
foreach($matches[1] as $key => $fieldName) {
//$field = $this->form->get($fieldName);
//if(!$field || !$field instanceof Inputfield) continue;
$value = strip_tags(rtrim(str_replace("</li>", ", ", $values[$fieldName]), ", "));
$body = str_replace($matches[0][$key], $value, $body);
}
return $body;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment