<?php $waitSessionName = $modx->getOption('waitSessionName', $formit->config, 'waitSession'); $delay = $modx->getOption('delay', $formit->config, 15); $delayPenalty = $modx->getOption('delayPenalty', $formit->config, 30); $delayTimer = ($_SESSION[$waitSessionName] - time()) + $delayPenalty ; $s = $delayTimer%60; $dTm = floor(($delayTimer % 3600) / 60); $dTh = floor(($delayTimer % 86400) / 3600); $m = $dTm>0?$dTm.' minute'.($dTm>1?'s':''):''; $h = $dTh>0?$dTh.' hour'.($dTh>1?'s':''):''; $timeRemaining = "$h $m $s seconds - " . $delayTimer; $waitErrorMsg = $modx->getOption('waitErrorMsg', $formit->config, 'Too soon, please wait <strong id="countdown"></strong> ([[!+timeRemaining]])'); if ($_SESSION[$waitSessionName] + $delay <= time()){ $_SESSION[$waitSessionName] = time(); return true; } else { $_SESSION[$waitSessionName] = time() + $delayTimer; $modx->log(modX::LOG_LEVEL_INFO, $_SESSION[$waitSessionName]); $hook->addError('waitError',$waitErrorMsg); $modx->setPlaceholder('timeRemaining', $timeRemaining); $modx->regClientStartupScript('assets/components/waitforit/js/waitCountdown.js'); $newDelay = $delayTimer + $delay; $modx->regClientStartupHTMLBlock('<script type="text/javascript">countSeconds('.$newDelay.');</script>'); return false; }
function countSeconds(seconds) { initialSecs = seconds; currentSecs = initialSecs; } setTimeout(decrement,1000); function decrement() { var displayedSecs = currentSecs % 60; var displayedMin = Math.floor(currentSecs / 60) % 60; var displayedHrs = Math.floor(currentSecs / 60 /60); if(displayedMin <= 9) displayedMin = "0" + displayedMin; if(displayedSecs <= 9) displayedSecs = "0" + displayedSecs; currentSecs--; document.getElementById("countdown").innerHTML = displayedHrs + ":" + displayedMin + ":" + displayedSecs; if(currentSecs !== -1) setTimeout(decrement,1000); }
I had the same idea some time ago, thank you for sharing! That will be helpful for many people.
Adding an extra, unused field, like 'user_name' or 'enter_subject' that is not visible and rejecting things when it's filled out can also help. You can do it with the FormIt spam hook, or on your own with a postHook.
<?php $waitSessionName = $modx->getOption('waitSessionName', $formit->config, 'waitSession'); if (!isset($_SESSION[$waitSessionName])) { $_SESSION[$waitSessionName] = time(); } // debug // $hook->setValue('session', $_SESSION[$waitSessionName] . ' - ' . time()); return true;
<?php $waitSessionName = $modx->getOption('waitSessionName', $formit->config, 'waitSession'); $delay = $modx->getOption('delay', $formit->config, 15); $delayPenalty = $modx->getOption('delayPenalty', $formit->config, 30); $delayTimer = ($_SESSION[$waitSessionName] - time()) + $delayPenalty; $s = $delayTimer%60; $dTm = floor(($delayTimer % 3600) / 60); $dTh = floor(($delayTimer % 86400) / 3600); $m = $dTm>0?$dTm.' minute'.($dTm>1?'s':''):''; $h = $dTh>0?$dTh.' hour'.($dTh>1?'s':''):''; $timeRemaining = "$h $m $s seconds" . ' ' . $_SESSION[$waitSessionName] . ' ' . $delayTimer; $waitErrorMsg = $modx->getOption('waitErrorMsg', $formit->config, 'Too soon, please wait [[!+timeRemaining]]'); if ($_SESSION[$waitSessionName]+$delay <= time()){ $_SESSION[$waitSessionName] = time(); return true; } else { $_SESSION[$waitSessionName] = time() + $delayTimer; $modx->log(modX::LOG_LEVEL_INFO, $_SESSION[$waitSessionName]); $hook->addError('waitError',$waitErrorMsg); $modx->setPlaceholder('timeRemaining', $timeRemaining); return false; }
[[!FormIt? &preHooks=`FormItWaitForItPreHook` &hooks=`FormItWaitForIt,redirect` &emailTpl=`MyEmailChunk` &emailTo=`[email protected]` &redirectTo=`1` ]] <h1>Session Form</h1> <span class="errors">[[!+fi.error.waitError]]</span> <form action="[[~[[*id]]]]" method="post" class="form"> <div class="form-row"> <label for="session">Session</label> <input type="text" name="session" size="50" autocomplete="off" class="form-field" value="[[!+fi.session]]"/> </div> <button type="submit" class="submit-button">Submit</button> </form>