Fork me on GitHub

Model Definition

Model is the central manager for ORM repositories, it provides them and manages their loading. Model requires a repository loader. Orm comes with OrmExtension that will help you integrate all needed services with Nette\DI component.

PhpDoc repository definition#

The most common usecase is to define available repositories as PhpDoc annotations of your model class. Orm extension will take care of your repositories and automatically creates their definition for DI container. Also, a lazy loader will be injected into model. The loader will provide repositories directly from your DI container.

To define model repository use PhpDoc @property-read annotation:

namespace MyApp;

/**
 * @property-read PostsRepository $posts
 * @property-read UsersRepository $users
 * @property-read TagsRepository $tags
 */
class Orm extends \Nextras\Orm\Model\Model
{
}

Then configure Orm extension in your application config.neon:

extensions:
    nextras.orm: Nextras\Orm\Bridges\NetteDI\OrmExtension

nextras.orm:
    model: MyApp\Orm
    metadataParserFactory: MyApp\MyMetadataParserFactory

The key model accepts class name of your project's model. Optionally, you may define your metadata parser factory, in which you will be able to customize metadata parsing (add support to new modifiers, etc.). You can easily inject Orm class into your presenters / services / classes and use property access to get needed repositories:

namespace MyApp;

class MyService
{
    /** @var Orm */
    private $orm;

    public function __construct(Orm $orm)
    {
        $this->orm = $orm;
    }

    public function doSomething($postId)
    {
        $post = $this->orm->posts->getById($postId);
        // ...
    }
}

DI repository definition#

You may want to define all your repositories dynamically in the DI config. For such usecase, Orm provider different repository finder. Orm will not create any repository DI definitions and will use all IRepository instances in your config.

extensions:
    nextras.orm: Nextras\Orm\Bridges\NetteDI\OrmExtension

nextras.orm:
    repositoryFinder: Nextras\Orm\Bridges\NetteDI\DIRepositoryFinder

services:
    - MyApp\PostsRepository(MyApp\PostsMapper())
namespace MyApp;

class MyService
{
    /** @var Orm */
    private $orm;

    public function __construct(Orm $orm)
    {
        $this->orm = $orm;
    }

    public function doSomething($postId)
    {
        $post = $this->orm->getRepository(PostsRepository::class)->getById($postId);
        // ...
    }
}

Model with simple loader#

If you do not use Nette\DI, you can use predefined SimpleRepositoryLoader. This loader requires already instantiated array of repositories. For creating the stack easily, you can use SimpleLoaderFactory. You have to create instances of repositories and mappers on your own.

$cache = new Nette\Caching\Cache(...);
$connection = new Nextras\Dbal\Connection(...);
$metadataParserFactory = new Nextras\Orm\Entity\Reflection\MetadataParserFactory();

$simpleModelFactory = new SimpleModelFactory($cache, [
    'posts' => new MyApp\PostsRepository(new MyApp\PostsMapper($connection, $cache)),
    'users' => new MyApp\UsersRepository(new MyApp\UsersMapper($connection, $cache)),
    'tags' => new MyApp\TagsRepository(new MyApp\TagsMapper($connection, $cache)),
], $metadataParserFactory);

$model = $simpleModelFactory->create();

Of course, you can create your own repository loader by implementing Nextras\Orm\Model\IRepositoryLoader interface. Metadata parser factory optional dependency.