I don't think it's entirely relevant because I've verified that the code in my hook is not being evaluated after the initial caching.
Something like this for the FormIt call:
[[!FormIt? &hooks=`spam,form2db,email,redirect` &emailTpl=`ContactForm` &emailTo=`[email protected]` &redirectTo=`6` &validate=`first_name:required, last_name:required, email:email:required` ]]
<h2>Form</h2>
<p>[[!+fi.error_message:notempty=`</p>
<p>[[!+fi.error_message]]</p>
<p>`]]</p>
<form class="form" action="[[~[[*id]]]]" method="post">
<input type="hidden" name="nospam:blank" value="" />
<input type="hidden" name="form_name" value="test_form" />
<input type="hidden" name="contest_name" value="test_contest" />
<label for="first_name"> First Name: <span class="error">[[!+fi.error.first_name]]</span> </label>
<input id="first_name" type="text" name="first_name" value="[[!+fi.first_name]]" />
<label for="last_name"> Last Name: <span class="error">[[!+fi.error.last_name]]</span> </label>
<input id="last_name" type="text" name="last_name" value="[[!+fi.last_name]]" />
<label for="email"> Email: <span class="error">[[!+fi.error.email]]</span> </label>
<input id="email" type="text" name="email" value="[[!+fi.email]]" />
<label for="phone"> Phone: <span class="error">[[!+fi.error.phone]]</span> </label>
<input id="phone" type="text" name="phone" value="[[!+fi.phone]]" />
<label for="address1"> Address 1: <span class="error">[[!+fi.error.address1]]</span> </label>
<input id="address1" type="text" name="address1" value="[[!+fi.address1]]" />
<label for="address2"> Address 2: <span class="error">[[!+fi.error.address2]]</span> </label>
<input id="address2" type="text" name="address2" value="[[!+fi.address2]]" />
<label for="city"> City: <span class="error">[[!+fi.error.city]]</span> </label>
<input id="city" type="text" name="city" value="[[!+fi.city]]" />
<label for="state"> state: <span class="error">[[!+fi.error.state]]</span> </label>
<input id="state" type="text" name="state" value="[[!+fi.state]]" />
<label for="zip"> zip: <span class="error">[[!+fi.error.zip]]</span> </label>
<input id="zip" type="text" name="zip" value="[[!+fi.zip]]" />
<label for="dob"> Date of Birth: <span class="error">[[!+fi.error.dob]]</span> </label>
<input id="dob" type="text" name="dob" value="[[!+fi.dob]]" />
<label for="opt_in">Opt In: <span class="error">[[!+fi.error.opt_in]]</span> </label>
<input id="opt_in" type="checkbox" name="opt_in" value="1" [[!+fi.opt_in:FormItIsChecked=`1`]]/>
<br class="clear" />
<div class="form-buttons"><input type="submit" value="Submit" /></div>
</form>
My form2db hook looks like this:
<?php
/*------------------------------------------------------------------------------
NOTE: you must create the necessary database tables and classes for this
to work. The database table should look like this:
CREATE TABLE `form2db_submissions2` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`form_name` varchar(255) DEFAULT NULL,
`contest_name` varchar(255) DEFAULT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`phone` varchar(16) DEFAULT NULL,
`address1` varchar(255) DEFAULT NULL,
`address2` varchar(255) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`state` varchar(16) DEFAULT NULL,
`zip` varchar(16) DEFAULT NULL,
`dob` date DEFAULT NULL,
`opt_in` tinyint(1) unsigned DEFAULT '0',
`ip` varchar(16) DEFAULT '',
`user_agent` varchar(255) DEFAULT NULL,
`datestamp_submitted` datetime DEFAULT NULL,
`payload` text COMMENT 'contains JSON version of full $_POST array',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
------------------------------------------------------------------------------*/
// IP Address --------------------------------------------------------
$ip = '';
if (isset($_SERVER)) {
if(isset($_SERVER['HTTP_CLIENT_IP'])){
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
elseif(isset($_SERVER['HTTP_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_FORWARDED_FOR'];
}
elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else{
$ip = $_SERVER['REMOTE_ADDR'];
}
}
else {
if (getenv( 'HTTP_CLIENT_IP')) {
$ip = getenv( 'HTTP_CLIENT_IP' );
}
elseif (getenv('HTTP_FORWARDED_FOR')) {
$ip = getenv('HTTP_FORWARDED_FOR');
}
elseif (getenv('HTTP_X_FORWARDED_FOR')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
}
else {
$ip = getenv('REMOTE_ADDR');
}
}
// User Agent -------------------------------------------------------
$browser = '';
if(stristr($_SERVER['HTTP_USER_AGENT'],'Opera Mini')) {
if(isset($_SERVER['HTTP_X_OPERAMINI_PHONE_UA'])) {
$browser = addslashes(strip_tags($_SERVER['HTTP_X_OPERAMINI_PHONE_UA']));
}
else {
$browser = addslashes(strip_tags($_SERVER['HTTP_USER_AGENT']));
}
}
else {
$browser = addslashes(strip_tags($_SERVER['HTTP_USER_AGENT']));
}
// Datestamp ------------------------------------------------------
$datestamp = date('Y-m-d H:i:s');
// We make the calculated fields available to the email (if needed)
$hook->setValue('ip',$ip);
$hook->setValue('user_agent',$browser);
$hook->setValue('datestamp_submitted', $datestamp);
$payload = json_encode($_POST);
$modx->addPackage('form2db', MODX_CORE_PATH .'components/form2db/model/','form2db_');
$submission = $modx->newObject('Submissions');
$submission->set('form_name', $hook->getValue('form_name'));
$submission->set('contest_name', $hook->getValue('contest_name'));
$submission->set('first_name', $hook->getValue('first_name'));
$submission->set('last_name', $hook->getValue('last_name'));
$submission->set('email', $hook->getValue('email'));
$submission->set('phone', $hook->getValue('phone'));
$submission->set('address1', $hook->getValue('address1'));
$submission->set('address2', $hook->getValue('address2'));
$submission->set('city', $hook->getValue('city'));
$submission->set('state', $hook->getValue('state'));
$submission->set('zip', $hook->getValue('zip'));
$submission->set('dob', $hook->getValue('dob'));
$submission->set('opt_in', $hook->getValue('opt_in'));
$submission->set('ip', $ip);
$submission->set('user_agent', $browser);
$submission->set('datestamp_submitted', $datestamp);
$submission->set('payload', $payload);
if ($submission->save() === false) {
$modx->log(xPDO::LOG_LEVEL_ERROR, 'form2db failed to save form data to the database! Here is the payload: ' . $payload);
}
return true;
But it doesn't matter what my hook code is... I updated it to do this:
$hook->addError('first_name','Pointless error for testing');
$modx->log(xPDO::LOG_LEVEL_ERROR, 'Error!');
return false;
That should cause the form submission to fail with an error, but it does not, even after clearing the cache. The form submits without an error, the old code executes and inserts a row in the database, and nothing shows up in the MODx error log. It is obviously using a cached version of my form2db Snippet.