Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 3 - FormControl - Předek pro formulářové kontrolky v PHP

V minulé lekci, Tvorba formulářového frameworku v PHP - HtmlBuilder, jsme si vytvořili HTML builder pro snadné generování krátkých úseků HTML.

V dnešním dílu našeho PHP tutoriálu vytvoříme abstraktní třídu FormControl, která sloužit jako předek pro konkrétní kontrolky formuláře (např. pro TextBox).

Deklarace třídy 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 string $label;
public array $htmlParams = array();
public string $name;

public function __construct(string $name, string $label = '', array $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 HTML parametrů. To jsou HTML atributy, které se k elementu při renderování (převodu do HTML kódu) přidají.

Setter pro ToolTip

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(string $toolTip) : FormControl
{
    $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ší. Protože definice formulářů budou ještě obsáhlejší, tak na kompaktnosti kódu velmi záleží.

Přiřazení CSS třídy

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(string $class) : void
{
    if (isset($this->htmlParams['class']))
        $this->htmlParams['class'] .= ' ' . $class;
    else
        $this->htmlParams['class'] = $class;
}

Nastavení validace

Přejděme k validační části třídy, která je bezesporu tou 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 array $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 pomocí jednoduchých metod. Mohli bychom také oddělit každé pravidlo do samostatné třídy, ale v našem případě bychom získali velmi jednoduché a podobné třídy. Dosáhli bychom tak, podle mého názoru, příliš vysoké granularity kódu. Druhý přístup jsem naopak zvolil dále u konkrétních kontrolek formuláře.

Výčet pravidel

Jednotlivá pravidla si uložíme výčtového typu (enum). Přidáme si šest položek:

enum Rules
{
    case Required;
    case MaxLength;
    case Password;
    case DateTime;
    case Pattern;
    case RequiredFile;
}

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(array $rule, bool $validateClient, bool $validateServer) : FormControl
{
    $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(bool $validateClient = true, bool $validateServer = true) : FormControl
{
    return $this->addRule(array(
        'type' => 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. Metoda addRequiredRule() tedy zobrazí message, pokud je pole nevyplněné nebo úplně chybí. Pravidlo přidáme pomocí privátní metody addRule() 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(int $maxLength, bool $validateClient = true, bool $validateServer = true) : FormControl
{
    return $this->addRule(array(
        'type' => Rule::MaxLength,
        'max_length' => $maxLength,
        'message' => 'Maximální délka hodnoty je ' . $maxLength,
    ), $validateClient, $validateServer);
}

Pravidlo pro regulární výraz

Naprosto klíčové pro nás bude pravidlo, které ověří hodnotu pole regulárním výrazem:

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

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

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.

V příští lekci, Dokončení třídy FormControl v PHP, přidáme do třídy FormControl další metody pro pravidla a také metody pro jejich vyhodnocení.


 

Předchozí článek
Tvorba formulářového frameworku v PHP - HtmlBuilder
Všechny články v sekci
Pokročilá obsluha formulářů v PHP
Přeskočit článek
(nedoporučujeme)
Dokončení třídy FormControl v PHP
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
11 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity