V článku jsem nastínil, jak chránit webový formulář antispamem bez zbytečné interakce uživatelů.
Jak to ale propojit s NETTE a jeho generací formulářů.
Příklad je napsán bez použití kompletního frameworku. Používám NETTE jen jako knihovnu.
PHP:
include_once $_SERVER['DOCUMENT_ROOT'] . '/_libs/nette.min.php'; use Nette\Mail\Message, Nette\Forms\Form; // vytvoření formuláře $form = new Form; $form->addText('jmeno', 'Jméno a příjmení *:') ->setRequired('Zadejte prosím jméno'); $form->addText('mail', 'E-mail:'); $form->addText('tel', 'Telefon:') ->addConditionOn($form['mail'], Form::EQUAL, '') ->addRule(Form::FILLED, 'Zadejte prosím alespoň jeden z kontaktů'); $form['mail']->addConditionOn($form['tel'], Form::EQUAL, '') ->addRule(Form::FILLED, 'Zadejte prosím alespoň jeden z kontaktů') ->addRule(Form::EMAIL, 'E-mail nemá správný formát'); $form->addSelect('zajem', 'Mám zájem o:', array('sádrokartony, rekonstrukce' => 'sádrokartony, rekonstrukce', 'malby, nátěry' => 'malby, nátěry', 'ostatní' => 'ostatní')); $form->addTextArea('pozn', 'Poznámka:', 40, 4); // antispam // Nelze řešit přes RAND, jelikož po odeslání by se nám hodnoty změnily, toto beru jako zajímavé "konstanty", které mají platnost jeden den. // Nápady jak toto lépe řešit uvítám v diskuzi. $c1 = date('j')+3; $c2 = date('N')+2; $s = $c1 + $c2; $form->addText('soucet', sprintf('Zadejte součet %s+%s *:', $c1, $c2)) ->setRequired('Je třeba zadat součet jako ochranu proti SPAMu') ->addRule(Form::EQUAL, 'Je třeba zadat součet jako ochranu proti SPAMu', $s); $form->addHidden('c1', $c1); $form->addHidden('c2', $c2); $form->addSubmit('send', 'Odeslat'); // zpracování formuláře po odeslání if ($form->isSuccess()) { $val = $form->getValues(); $mail = new Message; $from = ($val['mail'] == '') ? 'Z webu <web @nejaky-web.cz>' : $val['jmeno'] . ' < ' . $val['mail'] . '>'; $mail->setFrom($from) ->addTo('Info <info @nejaky-web.cz>') ->setSubject('Poptávka z webu') ->setBody(sprintf("Dobrý den,\nJméno: %s\nE-mail: %s\nTelefon: %s\nZájem o: %s\nPoznámka:\n%s", $val['jmeno'], $val['mail'], $val['tel'], $val['zajem'], $val['pozn'])) ->send(); // nesouvisí s příkladem - vložíme poděkování include $_SERVER['DOCUMENT_ROOT'] . '/templates/formular-odeslan.php'; } else { echo $form; } |
Vypíchnu raději bokem samotnou podstatu antispamového řešení:
// antispam // Nelze řešit přes RAND, jelikož po odeslání by se nám hodnoty změnily, toto beru jako zajímavé "konstanty", které mají platnost jeden den. // Nápady jak toto lépe řešit uvítám v diskuzi. $c1 = date('j')+3; $c2 = date('N')+2; $s = $c1 + $c2; $form->addText('soucet', sprintf('Zadejte součet %s+%s *:', $c1, $c2)) ->setRequired('Je třeba zadat součet jako ochranu proti SPAMu') ->addRule(Form::EQUAL, 'Je třeba zadat součet jako ochranu proti SPAMu', $s); $form->addHidden('c1', $c1); $form->addHidden('c2', $c2) |
Obslužný JS, který nám v případě zapnutého JS skryje antispamový prvek
<script type="text/javascript"> document.getElementById("frm-soucet").value = parseInt(document.getElementById("frm-c1").value) + parseInt(document.getElementById("frm-c2").value); document.getElementById("frm-soucet").parentNode.parentNode.style.display = "none"; // musíme se dostat až ke značce TR </script> |
Díky. To se hodilo.
Funguje to ? :)
A proč bych to tu jinak psal?
Myslim jako praktickou funkcnost jeslti to boti za nejakou dobu neprovali :)
AntiSPAM je nekonečný boj. Je to stejně nekonečná práce jako SEO optimalizace. Každopádně mi to zatím funguje.
Aplikoval sem to na par webu a zatim je to cisty :) Takze diky za uverejneni
Moc děkuju, perfektní řešení.