Poll control – komponenta pro realizaci anket (hlasování)
Tento plugin umožňuje jednoduše vkládat, zobrazovat a formátovat zobrazení rúzných typů anket. V distribuci jsou dodávané dva příklady, pro anketu řízenou „odkazy“ a „formulářem“.
| Verze | 0.2 |
| GitHub | http://github.com/…-PollControl |
| Ukázka | http://nette.warden.cz/poll-control/ |
| Forum thread | http://forum.nette.org/…et-hlasovani |
| Autor | Ondřej Brejla |
| Licence | New BSD License |
Instalace
Stáhněte z GitHubu všechny potřebné soubory a nahrajte je do stresáře „app/controls/poll-control/“. V archivu není ukázkový presenter, jeho kód naleznete na konci tohoto článku. Ve staženém archivu je soubor „poll_control.sql“, kde se nachází vyexportovaná příkladová databáze (jednoduché řešení). Importujte ji do své databáze. Nyní máte připravené zázemí a můžete začít s implementací do Nette.
Implementace do aplikace
V presenteru (nebo ve vašich controlech) vytvořte továrničku
pro vytvoření PollControlu (dle příkladového presenteru –
LinkPollControl, FormPollControl). Poté je potřeba
vytvořenému objektu předat objekt modelu, což je jakákoliv třída
implementující rozhraní PollControlModel. PollControl je
distribuován i s příkladovým modelem, který spolupracuje s přiloženým
exportem databáze. Počítá s připojením do databáze využitím informací
ze souboru config.neon.
V šabloně pak stačí uvést makro control se jménem
komponenty (případně použít jinou možnost vyrenderování komponenty).
Kontrola vícenásobného hlasování
V modelu je nastíněná možná kontrola vícenásobného hlasování. Kontrola je realizována pomocí session a pomocí kontroly IP (ukládáno do databáze). Z jedné IP je možné hlasovat jednou za 30s (je to pouze příklad), takže v případě vymazávání cookies můžete hlasovat každých 30s a testovat (nebo si přepište model a upravte chování dle svého).
Příklad použití
Následuje zdrojový kód příkladového Presenteru.
use Nette\Application\UI\Presenter;
class PollControlPresenter extends Presenter {
/**
* Returns LinkPollControl component.
*
* @return PollControl Link poll control.
*/
public function createComponentPollControl() {
$poll = PollControl::factory('link');
// alternatively:
// $poll = new LinkPollControl();
$poll->setModel(new PollControlModelImpl(1));
return $poll;
}
/**
* Returns FormPollControl component.
*
* @return PollControl Form poll control.
*/
public function createComponentPollControl2() {
$poll = new FormPollControl();
// alternatively:
// $poll = PollControl::factory('form');
$poll->setModel(new PollControlModelImpl(1));
return $poll;
}
}
Komentáře 
radas | 25. 2. 2010, 8:33 | comment
Mám takový návrh na vylepšení. Pokud by se přidal parametr, nebylo by možné v anketě hlasovat (neexistovaly by odkazy nebo formulář). Využití by to našlo u anket, jejichž hlasování již bylo ukončeno, ale přesto se zobrazují.
radas | 25. 2. 2010, 17:48 | comment
A ještě jedna myšlenka, jak by šly ankety vylepšit. Předáním data a času od kdy do kdy má být anketa aktivní, tedy v jakém časovém intervalu by bylo možné hlasovat (viz předchozí komentář). Tyto parametry by vlastně mohly být dva sloupce v tabulce v databázi anket.
Ondřej Brejla | 23. 3. 2010, 16:56 | comment
- Šoupnu si to do Todo, až bude čas, tak na to kouknu.
- Logiku „hlasovatelnosti“ ankety šoupnout do metody isVotable() modelu. Podle booleanu, který metoda vrací, se buď odkazy zobrazí, nebo ne (a v ukázkovém modelu je na isVotable() závislé i samotné vložení hlasu do db).
- Opět logika isVotable(), v metodě si zjistím, jestli je „správný čas“ a anketu podle toho zobrazím, nebo ne (je „hlasovatelná“, nebo není).
Komponenta nic neříká o struktuře databáze (nebo jiného úložiště), ve kterém je anketa uložena, pouze definuje rozhraní modelu, se kterým pracuje.
Nicméně až budu dělat opravy a úpravy, tak to případně přidám.
Díky.
joe | 25. 6. 2011, 2:23 | comment
Předně díky za komponentu, hned jsem našel využití, ale trošičku jsem ji musel upravit.
Návrhy na zlepšení, opravu chyb pošlu do příslušné diskuse – teď si všímám, že je zamknutá, nevím proč – tak sem:
- Od nějaké verze Nette je hlavička createTemplate($class = NULL), tzn. s parametrem, vyhazuje to vyjímku, která se v laděnce neobjeví – chvilku mi trvalo, než jsem přišel na to, kde je problém
- Nevím proč je použitý dotaz ke zjištění počtu celkových hlasů – to je přeci už v jednotlivých odpovědích, co se z db načítají
- V modelu se v metodě getAnswers() volá stejný dotaz
- Pokud chci AJAXovou verzi, všechno sice funguje jak má, problém je ovšem v tom, že pak bych musel upravovat své metody action/renderXXX kvůli tomu, aby nedocházelo behěm AJAX požadavku ke zbytečnému načítání dat, které se nepoužijí. Tedy přesně to, na co jsem narážel v diskusi:
http://forum.nette.org/…xx-pri-ajaxu
V komponentě je řešení celkem jednoduché – do signálu handleVote jsem si doplnil v případě AJAX požadavku tyto řádky:
$this->snippetMode = TRUE;
$this->invalidateControl();
$this->render();
$this->getPresenter()->sendPayload();
Pak je vše tak, jak má být a nezpracovává se dál můj kód v Presenterech.

radas | 21. 2. 2010, 17:55 | comment
Pokud mám na jedné stránce dvě ankety, pak po hlasování v jedné z nich se pak u druhé objeví noticka „Undefined offset: $id in …PollControlModel.php on line 89“, kde $id je ID otázky z databáze. Jde to samozřejmě potlačit přidáním @ před $sess->poll$this->id na tom řádku 89, ale to není systémové řešení.