Permalink
181 lines (125 sloc) 5 KB

Quickstart

This extension is here to provide integration of Doctrine 2 ORM into Nette Framework.

Installation

The best way to install Kdyby/Doctrine is using Composer:

$ composer require kdyby/doctrine
$ composer require kdyby/events

and now enable the extension using your neon config

extensions:
	# add theese four lines
	console: Kdyby\Console\DI\ConsoleExtension
	events: Kdyby\Events\DI\EventsExtension
	annotations: Kdyby\Annotations\DI\AnnotationsExtension
	doctrine: Kdyby\Doctrine\DI\OrmExtension

Please see documentation, on how to configure Kdyby/Events, Kdyby/Console and Kdyby/Annotations.

Also, you don't have to install Kdyby/Events if you don't want to, Kdyby/Doctrine should work fine without it.

Minimal configuration

This extension creates new configuration section doctrine, the absolute minimal configuration might look like this

doctrine:
	user: root
	password: pass
	dbname: sandbox
	metadata:
		App: %appDir%

The metadata section, as you might have guessed, configures your mapping drivers. The key is namespace and the value is usualy a directory.

Simplest entity

namespace App;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Article
{

	/**
	 * @ORM\Id
	 * @ORM\Column(type="integer")
	 * @ORM\GeneratedValue
	 */
	protected $id;

	/**
	 * @ORM\Column(type="string")
	 */
	protected $title;

}

The full name of annotation @ORM\Entity is Doctrine\ORM\Mapping\Entity, that's why there is that namespace alias before class definition.

If you don't want to declare $id column in every entity, you can use Identifier trait included in Kdyby\Doctrine\Entities\Attributes\Identifier. However, traits are only available since PHP 5.4. See documentation.

class Article
{

	use \Kdyby\Doctrine\Entities\Attributes\Identifier; // Using Identifier trait for id column

	// ...
}

You can also use an UUID - Universally unique identifier using similar approach, but different trait named UniversallyUniqueIdentifier.

class Article
{

	use \Kdyby\Doctrine\Entities\Attributes\UniversallyUniqueIdentifier; // Using UUI trait for id column

	// ...

}

Now we care only about method ::getClassName(), because we will use it right away. All it does is return the class name. Oh, but what is it good for? Well, most modern IDE's works with classnames in code as if they were reference - they can find you usages and provide you refactorings. This wouldn't work, if the classname would be simply written in string. Instead, we call static method, that returns the classname. That way, it's always actual, even when you rename the class in your project!

Working with entities

Saving your first entity is as easy as

$article = new Article();
$article->title = "The Tigger Movie";

$entityManager->persist($article); // start managing the entity
$entityManager->flush(); // save it to the database

And if you wanna read it

$articles = $entityManager->getRepository(App\Article::class);

$article = $articles->find(1);
echo $article->title; // "The Tigger Movie"

You can learn more in the Doctrine Quickstart.

Configuring services

You should always pass the EntityManager to your services and then get the Repositories from it. Thanks to autowiring, it's really easy :)

services:
	- App\Articles()

Ideally, to not violate the SRP, you should not extend repository to add custom business logic, but rather decorate it.

class Articles
{
	private $em;
	private $articles;

	public function __construct(Kdyby\Doctrine\EntityManager $em)
	{
		$this->em = $em;
		$this->articles = $em->getRepository(App\Article::class);
		// $this->articles = $em->getRepository(App\Article::getClassName()); // for older PHP
	}

	public function publish(App\Article $article)
	{
		// validate that the article has title and content, or whatever you want to validate here
		$article->published = TRUE;
		$this->em->persist($article);
		// don't forget to call $em->flush() in your presenter
	}
}

Want more?

Read also about