Repository ve fasádě v Doctrine 2

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

Dobrý večer, tvořím fasádu podle článku zde. V článku je napsáno, že fasáda zbavuje závislost presenterů na entityManageru, takže mi přišlo logické, aby se s repository pracovalo zde. Nastalo mi ale dilema, jak z repository přes facade data předávat.

1. Způsob (předat celý objekt Doctrine\ORM\EntityRepository)

class NewsFacade extends Nette\Object
{
	private $article;
	private $comment;

	public function __construct(Doctrine\ORM\EntityRepository $article, Doctrine\ORM\EntityRepository $comment)
	{
		$this->article = $article;
		$this->comment = $comment;
	}

	public function getArticle()
	{
		return $this->article;
	}

	public function getComment()
	{
		return $this->comment();
	}
}

2. Způsob (vytvořit metodu pro každý findBy*, findOneBy*)

class NewsFacade extends Nette\Object
{
	private $article;
	private $comment;

	public function __construct(Doctrine\ORM\EntityRepository $article, Doctrine\ORM\EntityRepository $comment)
	{
		$this->article = $article;
		$this->comment = $comment;
	}

	public function getArticle(array $criteria)
	{
		return $this->article->findOneBy($criteria);
	}

	public function getArticles(array $criteria)
	{
		return $this->article->findBy($criteria);
	}

	public function getAllArticle()
	{
		return $this->article->findAll();
	}
}

3. Způsob (Generovat metody automaticky. Podařilo se mi to jakž takž zabudovat do BaseFacade přes metodu __call. Přijde mi to jako hloupost, protože přijdu o napovídání v IDE, ale jen mě zajímal názor)

class NewsPresenter extends Nette\Object
{
	private $newsFacade;

	public function startup()
	{
		parent::startup();
		$this->newsFacade = $this->context->newsFacade;
	}

	public function renderDefault($id)
	{
		$this->newsFacade->findArticleBy(array('id' => $id));
		//v articleFacade zavolá: $this->article->findOneBy(array $criteria)
	}
}

Všem děkuji předem za odpovědi.

Editoval Pan Dobrman (20. 8. 2012 22:12)

Filip Procházka
Moderator | 4668
+
0
-

Položím ti prostou otázku: proč bys ty metody měl psát?

Vůbec je nepiš. Otevři si presenter a programuj. V momentě, kdy budeš potřebovat konkrétní data, napiš konkrétní metodu.

Facade je od toho, aby zašťitovala konkrétní operace nad službami. Ty metody find() by tam, pokud možno, vůbec být neměly.

Editoval HosipLan (20. 8. 2012 23:18)

bazo
Člen | 620
+
0
-

HosipLan napsal(a):
Facade je od toho, aby zašťitovala konkrétní operace nad službami. Ty metody find() by tam, pokud možno, vůbec být neměly.

a find() nie je konkretna operacia?

llook
Člen | 407
+
0
-

Přijde mi to jako hloupost, protože přijdu o napovídání v IDE, ale jen mě zajímal názor

Pokud by byl problém pouze v tomto, tak na to existuje phpdoc tag @method.

Pan Dobrman
Člen | 45
+
0
-

Teď v tom mám guláš. První způsob je hloupost, ale v druhém způsobu mi přijde, že používám konkrétní operace.

bene
Člen | 82
+
0
-

Konkretni data treba takto:

class NewsFacade extends Nette\Object
{
	private $articleRepository;

        public function __construct(Doctrine\ORM\EntityRepository $articleRepository)
        {
        	$this->articleRepository = $articleRepository;
        }

        public function getArticle($id)
        {
                return $this->articleRepository->findOneBy(array('id' => $id));
        }

	// napr. pro zobrazeni clanku na strance
        public function getPublishedArticles($limit, $offset)
        {
		// nevim, jak se to zapiseje v doctrine
                return $this->articleRepository->findBy($array('is_publish' => true))
				->order('publish_date')
				->limit($limit)
				->offset($offset)
				->fetchAll();
        }

	// Tohle zavolas treba v presenteru, kdyz sefredaktor klikne na tlacitko
	// publikovat ve vypisu clanku v adminu.
	// Takze v akci budes mit jen: $facade->publishArticle($id);
	//
	// A pak tu metodu pouzijes treba pro sefredaktora,
	// kteremu prijde emailem cely clanek s odkazem na publikovani
	// (EmailHandlerPresenter) na konci emailu, atd.
	public function publishArticle($id, $publishDate)
	{
		// nevim, jak se to zapiseje v doctrine
		$article = $this->getArticle($id);
		$article->is_published = true;
		$article->publish_date = $publishDate
		$this->articleRepository->save(article);
	}



}