Kdyby/Doctrine – Jak přistoupit k DAO

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
kastanekdavid
Člen | 39
+
0
-

Ahoj,

zkouším rozchodit Kdyby/Doctrine extension a nevím, jak vůbec získat dané DAO, prostřednictvím kterého chci uložit entitu uživatele do DB.

Když udělám v signPresenteru:

private $em;

protected function startup() {
	parent::startup();

	$this->em = new \Doctrine\Common\EventManager();
}
public function signInFormSucceeded($form)
{
	dump($this->em->getDao(App\Model\Dao\UserDao::getClassName()));die();
}

Vyhodí mně laděnka: Call to undefined method Doctrine\Common\EventManager::getDao()

Prošel jsem si dokumentaci a nikde jsem vlastně nenašel, jak si správně vytvořit EntityManagera.

Můžete mi, prosím, poradit? :)

V config.neon mám:

doctrine:
	user: root
	password:
	dbname: databaze
	metadata:
		App\Model\User: annotations("%appDir%/model")

Entita uživatel:

<?php

namespace App\Model\User;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="\Dao\UserDao")
 */
class User extends \Kdyby\Doctrine\Entities\IdentifiedEntity
{
    /**
     * @ORM\Column(type="string")
     */
    protected $nick;
}

DAO uživatele:

<?php
namespace App\Model\Dao;

class UserDao extends \Kdyby\Doctrine\EntityDao
{

}
Filip Procházka
Moderator | 4668
+
0
-

Když udělám v signPresenteru:

Zaprvé není to EventManager, ale EntityManager.

A zadruhé, používáme dependency injection! A protože se bavíme o presenteru, tak využijeme public property inject.

/** @var \Kdyby\Doctrine\EntityManager @inject */
public $em;

public function signInFormSucceeded($form)
{
 	dump($this->em->getDao(App\Model\Dao\UserDao::getClassName()));
}

V config.neon mám:

Tu sekci s metadaty můžeš zjednodušit takto, protože anotace jsou výchozí typ metadat :)

doctrine:
	user: root
	password:
	dbname: databaze
	metadata:
		App\Model: "%appDir%/model"

A taky není od věci dát takto tam celou složku s modely, vypisovat všechny entity po jedné je celkem otravné, ne?

Entita uživatel:

Sice nemám rád když se DAO dědí (protože je to v 99% zbytečné), ale dejme tomu

Víš že tam máš blbě namespace?

/**
 * @ORM\Entity(repositoryClass="\App\Model\Dao\UserDao")
 */

Pokud dao dědíš, tak většinou i chceš, abys ho pak mohl autowirovat, tedy bys ho měl registrovat jako službu

services:
	app.userDao:
		class: App\Model\Dao\UserDao
		create: @doctrine.dao(App\Model\User)

Služba doctrine.orm, kterou definuje kdyby/doctrine, je factory, které předáš název entity a ona ti vrátí sdílenou instanci DAO z EntityManageru, tedy potom v presenteru můžeš udělat jednoduše

/** @var App\Model\Dao\UserDao @inject */
public $userDao;

public function signInFormSucceeded($form)
{
 	dump($this->userDao);
}
kastanekdavid
Člen | 39
+
0
-

Hmm, sám autor, luxus :)

Díky moc za podrobnej rozbor, snažil jsem se všechno spravit. V Nette jsem takovej 3/4 roční začátečník, takže sorry, že mi nějaký principy ještě unikají :)

DAO dědit nepotřebuju, takže to v každým presenteru načítám takto (jaks radil):

class SignPresenter extends BasePresenter
{
	/** @var App\Model\Dao\UserDao @inject */
	public $userDao;

Ještě mi není úplně jasný, jak s tímhle způsobem načítání vytvořím službu UserDao? Je na to nějakej fundovanej postup? Laděnka řve toto: Service of type App\Model\Dao\UserDao not found.

Pokud to definuju způsobem, který radíš pro dědění DAO, tak mi to zase hlásí: Service 'app.userDao': Reference to missing service 'doctrine.orm'.

Díky za tvůj čas :)

Filip Procházka
Moderator | 4668
+
0
-

Pokud to definuju způsobem, který radíš pro dědění DAO, tak mi to zase hlásí: Service ‚app.userDao‘: Reference to missing service ‚doctrine.orm‘.

Promiň, překlep, mělo to být doctrine.dao, tedy

services:
    app.userDao:
        class: App\Model\Dao\UserDao
        create: @doctrine.dao(App\Model\User)

DAO dědit nepotřebuju, takže to v každým presenteru načítám takto (jaks radil):

Pokud ho dědit nepotřebuješ, tak vyžaduj v presenteru EntityManager, nebo konrétní služby kterým předáš EntityManager přes konstruktor.

namespace App\Models;

class Users extends Nette\Object
{
	private $em;

	public function __construct(EntityManager $em)
	{
		$this->em = $em;
	}

	// ...
}

Službu zaregistruješ

services:
	- App\Models\Users()

Vyžádáš v presenteru a používáš

/** @var \App\Models\Users @inject */
public $users;

public function signInFormSucceeded($form)
{
	// $this->users->nejakaMojeMetoda();
}

Do takové služby si potom dáš jakékoliv metody na práci s uživatelem, které potřebuješ.

kastanekdavid
Člen | 39
+
0
-

Supr, konečně jsem to rozchodil :) … Fajnová věcička, kvalitní koncept, díky moc!