Přeskočit na hlavní obsah

Základy a pravidla

Kolekce jsou základním stavebním kamenem pro vytváření API a datagridů. Definují se v adresáři app/Recipe, pomocí tzv. recipes (receptů). Každý recipe musí podědit třídu CollectionRecipe a musí implementovat metody source a key.

  • Pomocí metody source se definuje, která entita (DB tabulka) bude zdrojem dat.
  • Pomocí metody key se definuje API endpoint, přes který bude možné s daty pracovat.

Vytvoření kolekce

app/Recipe/UserRecipe.php
class UserRecipe extends CollectionRecipe
{
// Definice zdroje dat - entita (reprezentace DB tabulky)
public function source(): string
{
return User::class;
}

// Definice API endpointu
public function key(): string
{
return 'user';
}
}

A máte hotovo!

Díky této krátké konfiguraci se vám automaticky vygeneruje datagrid a API pro entitu User.

Vygenerovaný datagrid

V datagridu se zobrazí veškeré sloupce, které jsou definovány v přiřazené entitě - toto lze samozřejmě kompletně uzpůsobit pomocí pár řádků kódu - na podrobnou konfiguraci kolekcí se podíváme hned v dalších kapitolách.

User datagrid

Vygenerované REST API (CRUD)

Také se automaticky vygeneruje REST API pro všechny CRUD metody (Create, Read, Update, Delete a ReadAll). Příklady použití těchto metod naleznete v sekci Collections v REST API dokumentaci. Pro maximální pohodlí je vhodné využít JS/TS knihovnu megio-api, která vám bude našeptávat dostupné metody a parametry přímo při psaní kódu.

User REST API

Pravidla pro entitu

Aby kolekce fungovala správně, je potřeba, aby zdrojová entita splňovala několik pravidel.

Hlavní pravidlo

Entita musí obsahovat 3 hlavní #[ORM] atributy a musí implementovat rozhraní ICrudable.

#[ORM\Entity]
#[ORM\Table(name: '`user`')]
#[ORM\HasLifecycleCallbacks]
class User implements ICrudable
{
use TId, TCreatedAt, TUpdatedAt;
}

Pravidlo pro relace

Jakákoliv entita ve vašem projektu, jenž je součástí nějaké relace může implementovat rozhraní IJoinable. Díky implementaci tohoto rozhraní dokáže datagrid automaticky zobrazit sloupec s relací a také správné editační políčko pro formulář.

class Author implements IJoinable
{
#[ORM\Id]
#[ORM\Column(type: Types::GUID, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: UuidV6Generator::class)]
protected string $id;

#[ORM\Column(length: 64)]
protected string $firstName;

#[ORM\Column(length: 64)]
protected string $lastName;

#[ORM\OneToMany(mappedBy: 'author', targetEntity: Article::class, fetch: 'LAZY')]
protected Collection $articles;

public function getId(): string
{
return $this->id;
}

public function getJoinableLabel(): array
{
return [
// Zdroj dat pro výpis v datagridu a API
'fields' => ['firstName', 'lastName'],

// Formát pro výpis dat v datagridu a API
'format' => '%s %s'
];
}
}

Velmi doporučené pravidlo

Doctrine ORM umožňuje definovat 4 typy relací: OneToOne, OneToMany, ManyToOne a ManyToMany.

Tyto relace je potřeba vždy definovat pomocí PHP atributů a hlavně je potřeba uvést parametry targetEntity, mappedBy či inversedBy - jinak se kolekce nemusí chovat správně.

class Article
{
#[ORM\ManyToOne(targetEntity: Author::class, inversedBy: 'articles')]
#[ORM\JoinColumn(name: 'author_id', referencedColumnName: 'id')]
protected ?Author $author = null;
}

Megio díky těmto parametrům dokáže správně ukládat obousměrné relace do databáze (Doctrine ORM toto sama o sobě neumí). Pokud byste tyto parametry neuvedli, je potřeba vždy myslet na to, která entita vlastní relaci. Obecně to znamená, že byste vždy museli manuálně zajistit aktualizaci entity na straně vlastníka - snazší ale bude, když si zapamatujete toto pravidlo.