Edit on GitHub
Jump to docs navigation

Extending / Storage Layer / Working with Repositories

Note: You are currently reading the documentation for Bolt 3.7. Looking for the documentation for Bolt 5.2 instead?

Repositories manage collections of entities. At a conceptual level where an entity represents a row of data in the database, the repository represents the table. When you request a repository in Bolt you will normally ask for it via the name of the entity, and you will receive back an object that will be able to perform find, save and delete operations on a collection of (or single) entities.

Here are some of the built in ways to interact with a repository.

Overview

A repository in Bolt is the primary method used for interacting with an entity, or collections of entities.

It's not recommended to create a repository directly, instead you request a repository instance from the entity manager, as in the following example:

$repo = $app['storage']->getRepository('Bolt\Storage\Entity\Users');

You can also use short aliases for any of the built-in tables so the following is equivalent.

$repo = $app['storage']->getRepository('users');

Once you have a repository instance then the operations you perform will interact with the specific storage table and will return objects of the entity type managed.

It is also possible to define content structure through in your contenttypes.yml file. For more information about this see the section on Repository and Content defined through the contenttypes.yml file

createQueryBuilder()

$repo = $app['storage']->getRepository('users');
$qb = $repo->createQueryBuilder();

Apart from more basic queries, which can use the simpler finder methods, the primary method of querying the database is via a QueryBuilder instance. This method fetches an instance of QueryBuilder that is preset to select on the managed storage table.

The returned instance is always an object of type Doctrine\DBAL\Query\QueryBuilder. Much more in-depth documentation for using this can be found here.

Once you have finished building your query then you can fetch results by calling ->execute() followed by one of ->fetch() or ->fetchAll().

For example the following fetches the ten most recent published entries and for reference is functionally identical to the example in the findBy method documentation below.

$repo = $app['storage']->getRepository('entries');
$qb = $repo->createQueryBuilder();
$qb->where('status="published"')
    ->orderBy('datepublish', 'DESC')
    ->setMaxResults(10);

$entries = $qb->execute()->fetchAll();

find($id)

$repo = $app['storage']->getRepository('users');
$user = $repo->find(1);

This method finds a row by id from the table and returns a single Entity object.


findBy(array $criteria, array $orderBy, $limit, $offset)

We can now graduate to more flexible querying on the storage layer. The findBy() method allows us to pass key value parameters to the query which in turn filters the results fetched from the storage layer.

For example:

$repo = $app['storage']->getRepository('users');
$users = $repo->findBy(['displayname' => 'Editor']);

As you can see from the accepted parameter list you can also pass in order, limit and offset parameters to the method allowing you to perform most simple queries using this method. For instance here is a query that finds the 10 most recent published entries.

$repo = $app['storage']->getRepository('entries');
$entries = $repo->findBy(['status' => 'published'], ['datepublish', 'DESC'], 10);

findOneBy(array $criteria, array $orderBy)

This method works identically to the findBy method above but will return a single Entity object rather than a collection. This is most suited for when you want to guarantee a single result, for example:

$repo = $app['storage']->getRepository('users');
$user = $repo->findOneBy(['username' => $postedUser, 'password'=> $passHash]);
$newestUser = $repo->findOneBy([], ['id', 'DESC']);

findAll()

$repo = $app['storage']->getRepository('users');
$users = $repo->findAll();

The findAll method returns a collection of all the applicable entities unfiltered from the storage layer. In SQL terms it is identical to performing a SELECT * from tablename.


findWith(QueryBuilder $qb)

$repo = $app['storage']->getRepository('entries');
$qb = $repo->createQueryBuilder('e')
    ->join('e', 'bolt_relations', 'r', '
        r.from_contenttype = "entries" AND
        r.from_id = e.id AND
        r.to_contenttype = "categories"
    ')
    ->join('r', 'categories', 'c', '
        c.id = r.to_id AND
        c.status = "published"
    ')
    ->andWhere('e.status = :status')->setParameter('status', 'published')
    ->andWhere('c.slug = :cslug')->setParameter('cslug', $categorySlug, \PDO::PARAM_STR)
    ->addOrderBy('e.datepublish', 'desc')
    ->setMaxResults($limit)
;

$entries = $repo->findWith($qb);

This method lets you fetch data with more complex query previously built with QueryBuilder and it automatically hydrates results to fulfilled Entities.


findOneWith(QueryBuilder $qb)

This method works identically to the findWith method above but will return a single Entity object rather than a collection. This is most suited for when you want to guarantee a single result, for example:

$repo = $app['storage']->getRepository('entries');
$qb = $repo->createQueryBuilder('e')
    ->join('e', 'bolt_relations', 'r', '
        r.from_contenttype = "entries" AND
        r.from_id = e.id AND
        r.to_contenttype = "categories"
    ')
    ->join('r', 'categories', 'c', '
        c.id = r.to_id AND
        c.status = "published"
    ')
    ->andWhere('e.status = :status')->setParameter('status', 'published')
    ->andWhere('c.slug = :cslug')->setParameter('cslug', $categorySlug, \PDO::PARAM_STR)
    ->addOrderBy('e.datepublish', 'desc')
    ->setMaxResults(1)
;

$entry = $repo->findOneWith($qb);

save($entity)

$repo = $app['storage']->getRepository('users');
$user = $repo->find(1);

$user->username = "A new username";

$result = $repo->save($entity);

This method takes a modified object and persists the changes back to the database.

It returns false on failure and the successfully saved id on success.


delete($entity)

$repo = $app['storage']->getRepository('users');
$user = $repo->find(1);
$result = $repo->delete($user);

This method takes the supplied entity object and deletes that row from the storage table.

It returns the number of deleted rows if successful, and false on failure.



Edit this page on GitHub
Couldn't find what you were looking for? We are happy to help you in the forum, on Slack or on Github.