Produkty Objednávky Zákazníci Dokumentace
Nepřihlášen Uživatel 1 Uživatel 2 Uživatel 3
Část II · Zdroje dat

3.2. Parametry a Latte SQL

Soubor s dotazem je Latte šablona: dostane parametry a podle nich se poskládá – včetně podmínek, takže se dá měnit i tvar dotazu, ne jen hodnoty.

Ukázka

Přepínač není součástí gridu – jsou to obyčejné odkazy měnící parametr v URL.

Zdrojový kód

php app/Modules/AdminModule/Components/Docs/Data/SqlParamsGridControl/SqlParamsGridControl.php
<?php

declare(strict_types=1);

namespace App\Components\Docs\Data\SqlParamsGridControl;

use Xart\Grid\Button\ButtonManager;
use Xart\Grid\Column\ColumnManager;
use Xart\Grid\Control\GridControl;
use Xart\Grid\DataOutput\Row;
use Xart\Grid\DataSource\DataSource;
use Xart\Grid\DataSource\SQL\SQLDataSource;

/**
 * Dokumentace, kapitola 3.2 – Parametry a Latte SQL.
 *
 * Dotaz je Latte šablona: dostane parametry a podle nich se poskládá. Hodnoty se do SQL nevkládají
 * ručně – escapuje je LatteSQL, takže je jedno, co v nich přijde.
 *
 * Parametry si nastavuje presenter (viz setCategory()) ještě před vykreslením. Že se to stihne,
 * není náhoda: createDataSource() se volá líně, až když si grid o data řekne.
 */
class SqlParamsGridControl extends GridControl
{
    private ?string $category = null;

    private int $minQuantity = 0;


    public function setCategory(?string $category): static
    {
        $this->category = $category;
        return $this;
    }


    public function setMinQuantity(int $minQuantity): static
    {
        $this->minQuantity = $minQuantity;
        return $this;
    }


    public function createDataSource(): DataSource
    {
        return new SQLDataSource(__DIR__ . '/SqlParamsGridControl.sql', [
            'category' => $this->category,
            'minQuantity' => $this->minQuantity,
        ]);
    }


    public function columns(ColumnManager $cm): void
    {
        $cm->add('name', 'Název');
        $cm->add('category', 'Kategorie');
        $cm->addNumber('price', 'Cena', 2, 'Kč');
        $cm->addNumber('quantity', 'Skladem', 0);
    }


    public function buttons(ButtonManager $bm): void
    {
    }


    public function rows(Row $row): void
    {
    }


    public function render(): void
    {
        $this->template->render(__DIR__ . '/SqlParamsGridControl.latte');
    }
}
sql app/Modules/AdminModule/Components/Docs/Data/SqlParamsGridControl/SqlParamsGridControl.sql
SELECT
    id,
    name,
    category,
    price / 100 AS price,
    quantity
FROM `product`
WHERE quantity >= {$minQuantity}
{if $category !== null}
    AND category = {$category}
{/if}

Parametry

return new SQLDataSource(__DIR__ . '/X.sql', ['category' => $this->category]);

Hodnoty escapuje knihovna: řetězce přes PDO::quote(), čísla jako čísla, null jako NULL, bool jako 0/1. Ručně se |escape nepíše; jiný typ skončí výjimkou, ne nesmyslem v dotazu. Podmínky z filtrů gridu se do dotazu textem nevkládají nikdy – ty jdou jako vázané parametry.

Proč to presenter stihne nastavit

createDataSource() se volá líně – až když si grid poprvé řekne o data nebo aliasy, tedy dlouho po tom, co presenter zavolal settery. V konstruktoru by zdroj o jejich hodnoty přišel.