cloud_download Stáhnout

ORM - Práce s Entitami

ORM slouží jako vrstva nad databází pro přístup k uloženým datům.

Konfikurace

Pro nastavení připojení k databázi je nutný soubor "orm.json" v konfigurační složce, tedy například: "config/orm.json"

{
  "driver": "mysqli",
  "hostname": "localhost",
  "port": 3306,
  "username": "root",
  "password": "",
  "database": "gephart"
}

Entita

Entita je třída ve které jsou vlastnosti přístupné pomocí getterů a setterů.

V anotacích u vlastností definujeme jejich název a typ v databázi. U entity se v anotaci definuje název tabulky.

Příklad entity News uložené v "/src/App/Entity/News.php":

<?php

namespace App\Entity;

/**
 * @ORM\Table news
 * @ORM\Translation
 */
class News
{

    /**
     * @var int
     *
     * @ORM\Id
     */
    private $id = 0;

    /**
     * @var string
     *
     * @ORM\Type VARCHAR(255)
     * @ORM\Column title
     * @ORM\Translatable
     */
    private $title = "";

    /**
     * @var string
     *
     * @ORM\Type TEXT
     * @ORM\Column content
     * @ORM\Translatable
     */
    private $content = "";

    /**
     * @var bool
     *
     * @ORM\Type TINYINT(1)
     * @ORM\Column active
     * @ORM\Translatable
     */
    private $active = false;

    /**
     * @var \DateTime
     *
     * @ORM\Type DATE
     * @ORM\Column date
     * @ORM\Translatable
     */
    private $date;

    public function __construct()
    {
        $this->date = new \DateTime();
    }

    /**
     * @return int
     */
    public function getId(): int
    {
        return $this->id;
    }

    /**
     * @param int $id
     */
    public function setId(int $id)
    {
        $this->id = $id;
    }

    /**
     * @return string
     */
    public function getTitle(): string
    {
        return $this->title;
    }

    /**
     * @param string $title
     */
    public function setTitle(string $title)
    {
        $this->title = $title;
    }

    /**
     * @return string
     */
    public function getContent(): string
    {
        return $this->content;
    }

    /**
     * @param string $content
     */
    public function setContent(string $content)
    {
        $this->content = $content;
    }

    /**
     * @return bool
     */
    public function isActive(): bool
    {
        return $this->active;
    }

    /**
     * @param bool $active
     */
    public function setActive(bool $active)
    {
        $this->active = $active;
    }

    /**
     * @return \DateTime
     */
    public function getDate(): \DateTime
    {
        return $this->date;
    }

    /**
     * @param \DateTime $date
     */
    public function setDate(\DateTime $date)
    {
        $this->date = $date;
    }

}

Repozitář

Repozitář slouží vytáhnutí entit (už namapovaných objektů) z databáze.

Základní repozitář v "/src/App/Repository/NewsRepository.php" k entitě News může vypadat následovně:

<?php

namespace App\Repository;

use App\Entity\News;
use Gephart\ORM\EntityManager;

class NewsRepository
{

    /**
     * @var EntityManager
     */
    private $entity_manager;

    /**
     * @var string
     */
    private $entity_class;

    public function __construct(EntityManager $entity_manager)
    {
        $this->entity_class = News::class;
        $this->entity_manager = $entity_manager;
    }

    public function findBy(array $find_by = [], array $params = [])
    {
        return $this->entity_manager->findBy($this->entity_class, $find_by, $params);
    }

    public function find(int $id)
    {
        $result = $this->findBy(["id = %1", $id]);

        if (is_array($result) && !empty($result[0])) {
            return $result[0];
        }

        return null;
    }

}

Vygenerování tabulky

Třída Gephart\ORM\EntityManager má metodu, které okamžitě vytvoří tabulku v nastavené databázi.

$entity_manager = $container->get(\Gephart\ORM\EntityManager::class);
$entity_manager->createTable(\App\Entity\News::class);
// Hotovo, tabulka vytvořena

Controller

Nyní je vše připravené pro to, abychom mohli vytvářet, upravovat, vytahovat a mazat entity.

Zde je příklad controlleru "/src/App/Controller/NewsController.php", který to vše dělá:

<?php

namespace App\Controller;

use App\Entity\News;
use App\Repository\NewsRepository;
use Gephart\Framework\Response\TemplateResponse;
use Gephart\ORM\EntityManager;
use Gephart\Request\Request;
use Gephart\Routing\Router;

class NewsController
{

    /**
     * @var Router
     */
    private $router;

    /**
     * @var TemplateResponse
     */
    private $template_response;

    /**
     * @var Request
     */
    private $request;

    /**
     * @var NewsRepository
     */
    private $news_repository;

    /**
     * @var EntityManager
     */
    private $entity_manager;

    public function __construct(
        Router $router,
        TemplateResponse $template_response,
        Request $request,
        EntityManager $entity_manager,
        NewsRepository $news_repository
    )
    {
        $this->router = $router;
        $this->template_response = $template_response;
        $this->request = $request;
        $this->news_repository = $news_repository;
        $this->entity_manager = $entity_manager;
    }

    /**
     * @Route {
     *  "rule": "/admin/news",
     *  "name": "admin_news"
     * }
     */
    public function index()
    {
        if ($this->request->post("title")) {
            $news = new News();
            $news->setTitle($this->request->post("title"));
            $news->setContent($this->request->post("content"));
            $news->setActive($this->request->post("active"));
            $news->setDate(new \DateTime($this->request->post("date")));

            $this->entity_manager->save($news);

            $url = $this->router->generateUrl("admin_news");
            header("location: $url");
            exit;
        }

        $news = $this->news_repository->findBy([], [
            "ORDER BY" => "date DESC"
        ]);

        return $this->template_response->template("admin/news.html.twig", [
            "news" => $news
        ]);
    }

    /**
     * @Route {
     *  "rule": "/admin/news/edit/{id}",
     *  "name": "admin_news_edit"
     * }
     */
    public function edit($id)
    {
        $new = $this->news_repository->find($id);

        if ($this->request->post("title")) {
            $news->setTitle($this->request->post("title"));
            $news->setContent($this->request->post("content"));
            $news->setActive($this->request->post("active"));
            $news->setDate(new \DateTime($this->request->post("date")));

            $this->entity_manager->save($news);

            $url = $this->router->generateUrl("admin_news_edit", ["id"=>$news->getId()]);
            header("location: $url");
            exit;
        }


        return $this->template_response->template("admin/news.edit.html.twig", [
            "new" => $new
        ]);
    }

    /**
     * @Route {
     *  "rule": "/admin/news/delete/{id}",
     *  "name": "admin_news_delete"
     * }
     */
    public function delete($id)
    {
        $news = $this->news_repository->find($id);
        $news->setId($id);
        $this->entity_manager->remove($news);

        $url = $this->router->generateUrl("admin_news");
        header("location: $url");
        exit;
    }

}