10. díl - FormControl - Předek pro formulářové kontrolky v PHP

PHP Knihovny FormControl - Předek pro formulářové kontrolky v PHP American English version English version

V minulém dílu našeho seriálu tutoriálu o tvorbě PHP knihoven jsme si vytvořili HTML builder pro snadné generování krátkých úseků HTML. V dnešním dílu vytvoříme abstraktní třídu FormControl, která bude sloužit jako předek pro konkrétní kontrolky formuláře (např. pro TextBox).

FormControl

Jak již bylo řečeno, třída FormControl bude předkem pro všechny formulářové prvky. Bude obsahovat zejména mechanismus validací a několik společných vlastností a metod, aby se s kontrolkami mohlo pracovat pomocí stejného rozhraní. Připravme si tedy prázdnou třídu:

abstract class FormControl
{

}

Společné vlastnosti

Začněme jednoduše. Každá kontrolka bude mít nějaký název, popisek a HTML atributy. Do třídy tyto vlastnosti přidáme a napíšeme pro ně konstruktor:

public $label;
public $htmlParams = array();
public $name;

public function __construct($name, $label = '', $htmlParams = array())
{
        $this->name = $name;
        $this->label = $label;
        $this->htmlParams = $htmlParams;
        $this->htmlParams['name'] = $name;
        $this->htmlParams['id'] = $name;
}

Jméno a id kontrolky rovnou nastavíme do jejích HTML parametrů. To jsou HTML atributy, které se k elementu při renderování (převodu do HTML kódu) přidají.

Když jsme u těch jednoduchých vlastností, přidejme ještě setter na vlastnost ToolTip. To je text, který se zobrazí když na kontrolku najedete myší, stačí ho jen nastavit do HTML atributu title. Typicky obsahuje nápovědu co do pole zadat:

public function setTooltip($toolTip)
{
        $this->htmlParams['title'] = $toolTip;
        return $this;
}

Gettery a settery se v PHP oproti např. Javě příliš nepoužívají. V tomto případě však hrají důležitou úlohu. Setter vrací instanci FormControl, budou to tak dělat všechny settery. Když budeme kontrolkám nastavovat nějaké vlastnosti, museli bychom to bez setterů udělat následujícím stylem:

$jmenoBox = $form->addTextBox('jmeno', 'Jméno', true);
$jmenoBox->toolTip = 'Zadejte své celé jméno';
$jmenoBox->text = 'Jan Novák';

Díky tomu, že settery vrací instanci, na které je metoda volána, můžeme na ni zas zavolat další metodu a tak je krásně řetězit. Kód výše můžeme tedy zapsat takto:

$form->addTextBox('jmeno', 'Jméno', true)
         ->setToolTip('Zadejte své celé jméno')
         ->setText('Jan Novák');

Jistě uznáte, že tato varianta je mnohem čitelnější a protože definice formulářů budou obsáhlejší, tak na kompaktnosti kódu velmi záleží.

Přidejme kontrolce ještě metodu, která k ní přiřadí nějakou CSS třídu. Musíme počítat i s tím, že již nějakou má.

public function addClass($class)
{
        if (isset($this->htmlParams['class']))
                $this->htmlParams['class'] .= ' ' . $class;
        else
                $this->htmlParams['class'] = $class;
}

Validace

Přejděme k validační části třídy, která je bezesporu ta nejdůležitější.

Validační pravidla

Validace formulářových polí budeme realizovat tak, že bude možné každému poli přidat několik validačních pravidel. Proto přidáme kolekci $rules:

private $rules = array();

Jednotlivá pravidla budou např. pravidlo povinného pole, pravidlo regulárního výrazu, pravidlo pro heslo a podobně. Po odeslání formuláře se každé kontrolce ověří její pravidla a to jak na klientovi, tak na serveru.

Jednotlivá pravidla nebo validátory, chcete-li, jsem se rozhodl realizovat přímo uvnitř třídy FormControl a to pomocí jednoduchých metod. Dalším přístupem by bylo oddělit každé pravidlo do samostatné třídy, ale třídy by byly tak jednoduché a podobné, že mi to přišlo jako příliš vysoká granularita. Druhý přístup více tříd jsem naopak zvolil dále u konkrétních kontrolek formuláře.

Konstanty

Jednotlivá pravidla budeme rozlišovat pomocí konstant, přidejme si je:

const RULE_REQUIRED = 0;
const RULE_MAX_LENGTH = 1;
const RULE_PASSWORD = 2;
const RULE_DATETIME = 3;
const RULE_PATTERN = 4;
const RULE_REQUIRED_FILE = 5;

Podle názvu jistě poznáte, co které pravidlo ověřuje. Další pravidla lze sestavit různými kombinacemi.

Přidávání pravidel

Každé pravidlo bude reprezentované jako asociativní pole. K jejich přidání do kolekce $rules si vytvoříme privátní metodu:

private function addRule($rule, $validateClient, $validateServer)
{
        $rule['validate_client'] = $validateClient;
        $rule['validate_server'] = $validateServer;
        $this->rules[] = $rule;
        return $this;
}

Metoda bere pole, které obsahuje data pravidla. Další dva parametry označují, zda se má pravidlo kontrolovat na klientovi a na serveru. Pravidlu přidáme tyto vlastnosti podle parametrů a uložíme ho do kolekce. Za účelem dodržení přístupu setterů vrátíme instanci.

Pravidlo povinného pole

Přidejme metodu, která kontrolce přidá pravidlo povinného pole:

public function addRequiredRule($validateClient = true, $validateServer = true)
{
        return $this->addRule(array(
                'type' => self::RULE_REQUIRED,
                'message' => 'Povinné pole',
        ), $validateClient, $validateServer);
}

Metoda vyrobí pole s pravidlem. Každé pravidlo bude vždy obsahovat klíč "type" s typem pravidla a poté klíč "message" s chybovou hláškou. Ta se zobrazí v případě, že pravidlo nebude splněno, zde tedy když je pole nevyplněné nebo úplně chybí. Pravidlo (pole) přidáme pomocí privátní metody do kolekce $rules.

Stejným způsobem vytvoříme další metody pro přidání pravidel dalších typů.

Pravidlo maximální délky

Pravidlo maximální délky se později na klientovi přeloží na atribut maxlength. Bude vypadat následovně:

public function addMaxLengthRule($maxLength, $validateClient = true, $validateServer = true)
{
        return $this->addRule(array(
                'type' => self::RULE_MAX_LENGTH,
                'max_length' => $maxLength,
                'message' => 'Maximální délka hodnoty je ' . $maxLength,
        ), $validateClient, $validateServer);
}

Pravidlo pro regulární výraz

Naprosto klíčové pravidlo pro nás bude pravidlo ověřující hodnotu pole regulárním výrazem.

public function addPatternRule($pattern, $validateClient = true, $validateServer = true)
{
        return $this->addRule(array(
                'type' => self::RULE_PATTERN,
                'pattern' => $pattern,
                'message' => 'Hodnota má nesprávný formát',
        ), $validateClient, $validateServer);
}

Pravidlo budeme hojně používat v dalších pravidlech. Do třídy si přidáme několik konstant pro nejpoužívanější regulární výrazy:

const PATTERN_URL = '(http|https)://.*';
const PATTERN_INTEGER = '[0-9]+';
const PATTERN_EMAIL = '[a-z0-9._-]+@[a-z0-9.-]+\.[a-z]{2,4}$';

Pravidla budeme psát bez stříšky na začátku a dolaru na konci (^ a $), přidají se tam později automaticky. Příště třídu dokončíme přidáním zejména metod pro zbylá pravidla a také metody pro jejich vyhodnocení.


 

  Aktivity (2)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (2 hlasů) :
55555


 


Miniatura
Všechny články v sekci
Knihovny pro PHP
Miniatura
Následující článek
Dokončení třídy FormControl v PHP

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!