We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
  • I've written a custom hook for FormIt, and it IS executing -- but it looks like it's running cached -- my updates to the hook are not showing up. The FormIt call itself is called uncached, but it looks like the code in the hooks is being cached. Is this a correct analysis? And if yes, how can you force your custom hooks so they are not cached?
    • Yeah, this is definitely caching the code from the custom hooks. Clearing the site cache does not clear out the cached code from the custom hooks. This is maddening. Anyone know of a work-around?

      MODx 2.1.3-pl.
        • 4172
        • 5,888 Posts
        some code, your hook-snippet, your-formit-call?
          -------------------------------

          you can buy me a beer, if you like MIGX

          http://webcmsolutions.de/migx.html

          Thanks!
        • 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.
            • 3749
            • 24,544 Posts
            I assume that you've tried deleting the files in core/cache. I've had code get stuck until I did that. Also, make sure you're not "including" a file and editing a different file.

            I don't think this helps you, but here's what OpenGeek says on the topic:

            If the snippet you are calling is embedded in content that is cached, then that is the only way this would not be possible. the runSnippet() function does not have the ability to return cached content.

            How about putting this at the top of your snippet:

            $modx->cacheManager->refresh();


            This will clear the whole cache. With the right argument to refresh(), it should just refresh the snippet:

            http://forums.modx.com/thread/69839/using-modx--cachemanager--refresh-with-custom-components [ed. note: BobRay last edited this post 12 years, 5 months ago.]
              Did I help you? Buy me a beer
              Get my Book: MODX:The Official Guide
              MODX info for everyone: http://bobsguides.com/modx.html
              My MODX Extras
              Bob's Guides is now hosted at A2 MODX Hosting
            • Moved this to a new server, and the caching issue vanished (??), but the form submissions were white-screening. Turned out to be mod_security ... was thinking this was some kind of attack and blocking the execution of the PHP.

              Thanks for the input, as always. Just received your book, Bob -- looking forward to reading through it.
                • 34178
                • 212 Posts
                Hi Everett,
                I guess your problem is caused by the setting "Enable Database Cache" (cache_db). If it is set to yes your database-retrievings are cached. If you set it "no" you will have no problems anymore regarding this issue.

                I don´t know how much this setting speeds up modx. If the difference is not high you can probably solve this problem by setting cache_db to no.

                Do you meanwhile find a way to call hooks uncached?
                • The issue was caused by mod_security, the Apache application level firewall. Correcting my mod_security rules is what fixed the problem.