Drupal a Webform: jak zpracovávat data z formulářů pomocí PHP

Rozšíření systému Drupal o modul Webform poskytuje výkonnou funkci pro získávání dat od uživatelů prostřednictvím formulářů. Data jsou ukládána v databázi a lze je exportovat do Excelu. Jak je však zobrazit na další stránce, pokud si nechcete rovnou psát speciální modul na míru?

Vytvoření webového formuláře pomocí modulu Webform je čistě klikací záležitost. Webform poskytuje různé typy políček, od textových, k různým vybíračkám. Umí také validovat základní vstupní formáty, další kontrolu zadaných dat si pro formulář doplníte pomocí vlastního kódu v PHP. Stačí jej doplnit do nastavení formuláře.

Nevýhodou formuláře Webform je „nemožnost" ihned zpracovat data vyplněná pomocí tohoto modulu. Typickým požadavkem je zpracování vstupu od uživatele a jeho následné zobrazení nebo využití na jiné stránce v rámci webu. Pokud něco potřebujete, je podle mého názoru vhodnější připravit si vlastní modul přímo na míru. Ovšem v některých případech si vystačíte i s Webformem. Nemožnost zpracovat vložená data je totiž jen zdánlivá. Stačí základní znalosti PHP pro práci se sessions. Jak na to?

Uložení dat z Webformu do sessions

V první řadě si tedy nainstalujte modul Webform a naklikejte si jeho prostřednictvím formulář. V následujícím textu budu předpokládat, že tuto základní činnost zvládnete bez problémů. Kdyžtak vše potřebné najdete v mé knize o Drupalu.

Při definici políček ve Webformu se ujistěte, že vzniknou se srozumitelným strojovým názvem, který využijete při dalším zpracování. Najdete jej při definici nového prvku formuláře v sekci Pokročilé volby jako Identifikátor pole. Pro příklad použiji formulář s jediným políčkem, které bude mít identifikátor nastavený na jmeno.

Drupal a Webform

Drupal a Webform

Po vytvoření políček se přepněte zpátky do Konfigurace formuláře. Rozklepněte sekci Pokročilá nastavení a najděte pole Dodatečné zpracování. Sem vložte kód, kterým budete data z formuláře nějakým způsobem zpracovávat. K dispozici máte pole $form a $form_state, se kterými lze mimochodem pracovat stejným způsobem, jako při tvorbě samostatného modulu a nějakého formuláře.

Obsah pole $form_state udržujícího vyplněné hodnoty si zobrazíte příkazem print_r následovně:

<?php
print '<pre>';
print_r($form_state);
print '</pre>';
die;
?>

Příkaz die je na konci uveden zcela záměrně. Zastaví totiž následné provádění skriptů, takže vám zůstane jen bílá stránka s obsahem pole. Značky <pre></pre> zajistí přehledné zformátování tohoto výstupu.

Jak tedy zjistíte, hodnoty z políček jsou uloženy ve $form_state['values']['submitted_tree']. S touto znalostí je můžete jednoduše uložit do sessions. Předchozí kód vypisující obsah z formulářového pole odstraňte a namísto něj vložte kód, který nejprve nastartuje práci se sessions a poté do jednotlivých session uloží hodnoty z políček. V naší ukázce uložíme jen jednu hodnotu, a to z políčka pro zadání jména:

<?php
session_start();
$_SESSION['jmeno'] = $form_state['values']['submitted_tree']['jmeno'];
?>

Nyní jsou hodnoty z formuláře uloženy v session a může dojít k přesměrování na stránku, kde je zpracujete. V konfiguraci Webformu zadejte adresu této stránky do pole Potvrzovací zpráva nebo uzel pro přesměrování a stránku se zadanou adresou v Drupalu vytvořte.

Zpracování dat ze sessions

Vytvořte novou stránku na adrese, kterou jste ve Webformu nastavili pro přesměrování vyplněného formuláře. Do stránky vložte kód, který data ze sessions načte a následně je zobrazí. Následující ukázka opět nastartuje práci se sessions a následně zobrazí řetězec, ke kterému doplní hodnotu načtenou ze session. Konkrétně v předchozím kroku uložené jméno z formuláře:

<?php
session_start();
print 'Zadané jméno je '.$_SESSION['jmeno'];
?>

Nyní můžete celou kombinaci vyzkoušet. Protože kód ve stránce se provede i v případě, že někdo zadá přímo její adresu bez toho, že by nejprve vyplnil formulář, můžete jej vylepšit následujícím způsobem. Doplňte podmínku ověřující, že je zadána nějaká hodnota v sessions (které nastavilo zpracování formuláře). Pokud tomu tak nebude, dojde k nastavení upozorňujícího hlášení a přesměrování na stránku s formulářem:

{syntaxhighlighter brush:php} <?php session_start(); if ($_SESSION['jmeno'] == NULL || $_SESSION['jmeno'] == '') { drupal_set_message('Nejprve musíte vyplnit formulář'); drupal_goto('node/12'); } print 'Zadané jméno je '.$_SESSION['jmeno']; ?> {/syntaxhighlighter}

Adresu node/12 si samozřejmě upravte tak, aby došlo k přesměrování na uzel ve vašem webu. Kód v této ukázce je velmi jednoduchý, ale věřím, že vám pomůže pochopit způsob zpracování dat z formuláře a brzy se v komentářích pochlubíte, kde jste jej prakticky využili.

Tagy

Buďme ve spojení, přihlaste se k newsletteru

Odesláním formuláře souhlasíte s podmínkami zpracováním osobních údajů. 
Více informací v Ochrana osobních údajů.

Autor článku: Jan Polzer

Tvůrce webů z Brna se specializací na Drupal, WordPress a Symfony. Acquia Certified Developer & Site Builder. Autor několika knih o Drupalu.
Web Development Director v Lesensky.cz. Ve volných chvílích podnikám výlety na souši i po vodě. Více se dozvíte na polzer.cz a mém LinkedIn profilu.

Komentáře k článku

návštěvník

Musím uznat, že mi vždy Vaše postřehy a návody přijdou právě vhod :-) Nechal jsem se inspirovat tak, že jsem si vytvořil 1 ověřující formulář a 2. který se zobrazí až po ověření. Konkrétně po kladném ověření se vytvoří session a uživatel je přesměrován na 2. formulář, kde se údaj ze session použije do políčka jako výchozí hodnota %session[klic]. Všechno mi ale bohužel funguje pouze pokud jsem přihlášen. Je toto limitace session, mého chápání, nebo to lze nějak obejít? Ověření proběhne správně, ale když jsem nepřihlášen, ve 2. formuláři se do pole nic nenačte. Děkuji za každou radu.

Profile picture for user Jan Polzer

Jak tu session ukládáte? Pozor na to, že Drupal má své vlastní sessions. Nebije se Vám to?

návštěvník

V poli Dodatečné zpracování 1. formuláře mám session takto:

Pokud $cislo projde kontrolou, proveď:
session_start();
$_SESSION['cislo'] = $cislo;
drupal_set_message('Číslo ověřeno.');
drupal_goto('node/XX');

U 2. formuláře mám políčko, které má nastavenu Výchozí hodnotu:
%session[cislo]

Je možné, že 1. formulář uloží do klasické session, ale 2. se snaží načítat z Drupal session? Jak by se pak vysvětlilo fungování u přihlášeného uživatele? Děkuji.

Profile picture for user Jan Polzer

Je to jisté :-) Koukněte do nápovědy pod políčkem, kde tu %session vkládáte. Pokud to chcete používat tímto způsobem, upravte si můj kód tak, že pro generování session z prvního formuláře použijete drupalovskou funkci pro práci se session uživatele. Viz sess_write() tady http://api.drupal.org/api/drupal/includes--session.inc/6 Akorát se obávám, že to pak nebude reagovat na anonymy.

návštěvník

Aha :-) Nevšiml jsem si rozdělení na all users a authorised users, četl jsem detaily dole. Vypsání Vámi definované session do políčka formuláře tedy funguje jen pro přihlášené a pro nepřihlášené musím použít zapsání do url a natažení pomocí get? Nebo je to omezené jenom u formulářů? Děkuji.

Profile picture for user Jan Polzer

Moje $_SESSION funguje pro všechny a je nezávislé na Drupalu. vaše %session bere údaje z Drupalu.

návštěvník

DD. No a kdy je teda lepší si vytvořit úplně nový modul?

Profile picture for user Jan Polzer

Přijde na to. Záleží na tom, zda to zvládnete, případně zda máte natolik specifické požadavky, že je nový modul jediné řešení.

návštěvník

Nastvenie Webformu som pomerne zvládol, no nastavením v "E-mail template" neviem pohnúť.
Časť textov nie je prelužená a moje znalosti sú biedné. V Drupal 6.16 mám modul Webform 6.x-3.0-beta 2.

Modul kompletne šlape. Ak mám v E-mail template uvedené "%email_values" odošlú sa komplet informácie uvedené v políčkach.
Chcel som zmeniť šablonu (myslím že by som tam mal dopísať %email[key]) aspom tak som to pochopil, no ako to napísať v akom formáte ... nemám ani paru a to som už vyskúšal všeličo a na webe som nič nenašiel (aspom na SK, CZ stránkach).

Potrebujem aby niektoré políčka (vyplnené) neboli súčasťou e-mail správy. Myslel som, že to rieši "Included e-mail values" no nejak mi to nefunguje.

Viete mi napísať či je možné do "E-mail template" uviesť nejaké hodnoty pre každé políčko zvlášť ?

návštěvník

Dobry den,

mam ve formulari policko email. Do validace si davam dotaz do db, jestli uz nekdo s timto mailem formular odesilal, pokud ano, vracim mu hlasku ze uz formular nemuze vyplnit.

Bohuzel mi ale drupal tento kod ignoruje a to i kdyz tam dam pouze die(); Tak stejne formular proskoci.

Netusite cim by to mohlo byt?

Kod vypada takto:

<?php

$mail = $form_state['values']['submitted'][23];

$query = "SELECT data FROM webform_submitted_data WHERE data LIKE '".$mail."' LIMIT 1";

$result = db_query($query);

$node = db_fetch_object($result)

if ($node->data == $mail) {
form_set_error('email','S tímto mailem již formulář byl vyplněn.');
}

?>

návštěvník

Hm, zajímavé a užitečné. Ale jak docílit toho, že se podle zadaných hodnot upraví odeslaný e-mail uživateli, který formulář vyplnil? Typicky - vyplní objednávku a podle zvolené metody platby se mu do mailu vloží výsledná cena.

Profile picture for user Jan Polzer

Na to už potřebujete znalosti PHP. Vypnete odeslání mailu, který generuje Webform a do políčka pro dodatečné zpracování vložíte vlastní funkci pro sestavení a odeslání e-mailu. Posbírání hodnot z formuláře je v článku popsáno.

návštěvník

Tu stránku s posbíranými hodnotami a výsledky upravenými dle hodnot z formuláře mám. Tam mi váš článek a PHP dosti pomohlo. Ted by mi stacilo tu stránku poslat mailem. Mám se vydat čistě směrem php řešení, nebo je na to nějaký Drupal fígl?

návštěvník

Dobrý den, omlouvám se, že otevírám znovu tuto diskuzi, ale potřebuji dodatečně zpracovat data formuláře vytvořeného pomocí Webformu, ovšem, zjistil jsem, že verze 3.x již nedisponuje v základu možností dodatečného zpracování pomocí PHP. Napadá vás, jak by to šlo zařídit? Nešlo by k tomu účelu použít přesměrování na "Confirmation page" s povoleným PHP filtrem?

Děkuji předem za reakce...

Profile picture for user Jan Polzer

Zdravím. Pro šestkovou řadu Webformu je k dispozici modul Webform PHP, ovšem je neudržovaný a nedoporučují jej používat. Já bych to řešil asi modulem, kde implementuji hook_form(), navěsím se na daný formulář a vezmu si z něj data.

Přidat komentář

Odesláním komentáře souhlasíte s podmínkami Ochrany osobních údajů

reklama
Moje kniha o CMS Drupal

 

Kniha 333 tipů a triků pro Drupal 9


Více na KnihyPolzer.cz

Sledujte Maxiorla na Facebooku

Maxiorel na Facebooku

Hosting pro Drupal a WordPress

Hledáte český webhosting vhodný nejenom pro redakční systém Drupal? Tak vyzkoušejte Webhosting C4 za 1200 Kč na rok s doménou v ceně, 20 GB prostoru a automatické navyšováním o 2 GB každý rok. Podrobnosti zde.

@maxiorel na Twitteru

Maxiorel na Twitteru