use
CleanPhp\Invoicer\Domain\Entity\AbstractEntity;
use
CleanPhp\Invoicer\Domain\Repository\RepositoryInterface;
use
Doctrine\ORM\EntityManager;
abstract class
AbstractDoctrineRepository
implements
RepositoryInterface {
protected
$entityManager
;
protected
$entityClass
;
public function
__construct
(EntityManager
$em
) {
if
(
empty
(
$this
->
entityClass
)) {
throw new
\RuntimeException(
get_class
(
$this
)
.
'::$entityClass is not defined'
);
}
$this
->
entityManager
=
$em
;
}
public function
getById
(
$id
) {
return
$this
->
entityManager
->
find
(
$this
->
entityClass
,
$id
);
}
public function
getAll
() {
return
$this
->
entityManager
->
getRepository
(
$this
->
entityClass
)
->
findAll
();
}
public function
getBy
(
$conditions
=
[],
$order
=
[],
$limit
=
null
,
$offset
=
null
) {
$repository
=
$this
->
entityManager
->
getRepository
(
$this
->
entityClass
);
$results
=
$repository
->
findBy
(
$conditions
,
$order
,
$limit
,
$offset
Doctrine 2
199
);
return
$results
;
}
public function
persist
(AbstractEntity
$entity
) {
$this
->
entityManager
->
persist
(
$entity
);
return
$this
;
}
public function
begin
() {
$this
->
entityManager
->
beginTransaction
();
return
$this
;
}
public function
commit
() {
$this
->
entityManager
->
flush
();
$this
->
entityManager
->
commit
();
return
$this
;
}
}
This class has a member named
$entityClass
, which must be supplied with the fully qualified
name of the Entity class that the repository will be managing. To ensure this requirement is met,
we check it in the constructor and throw an exception if no string is provided. Each subclass will
be required to provide a value for this member variable.
Additionally, the constructor accepts an instance of Doctrine’s
EntityManager
, which we use
extensively in the rest of the methods to get the work done.
Each of the additional methods simply implements a method of the interface, and uses the
EntityManager
to retrieve and persist data as necessary.
With this abstract class in place, we can start to implement some concrete repositories.
CustomerRepository
// src/Persistence/Doctrine/Repository/CustomerRepository.php
namespace
CleanPhp\Invoicer\Persistence\Doctrine\Repository;
use
CleanPhp\Invoicer\Domain\Repository\CustomerRepositoryInterface;
class
CustomerRepository
extends
AbstractDoctrineRepository
implements
CustomerRepositoryInterface {
protected
$entityClass
=
'CleanPhp\Invoicer\Domain\Entity\Customer'
;
}
Doctrine 2
200
Since we don’t have any custom methods outside of what
AbstractDoctrineRepository
defines,
we’re done!
OrderRepository
// src/Persistence/Doctrine/Repository/OrderRepository.php
namespace
CleanPhp\Invoicer\Persistence\Doctrine\Repository;
use
CleanPhp\Invoicer\Domain\Repository\OrderRepositoryInterface;
use
Doctrine\ORM\Query\Expr\Join;
class
OrderRepository
extends
AbstractDoctrineRepository
implements
OrderRepositoryInterface {
protected
$entityClass
=
'CleanPhp\Invoicer\Domain\Entity\Order'
;
public function
getUninvoicedOrders
() {
$builder
=
$this
->
entityManager
->
createQueryBuilder
()
->
select
(
'o'
)
->
from
(
$this
->
entityClass
,
'o'
)
->
leftJoin
(
'CleanPhp\Invoicer\Domain\Entity\Invoice'
,
'i'
,
Join
::
WITH
,
'i.order = o'
)
->
where
(
'i.id IS NULL'
);
return
$builder
->
getQuery
()
->
getResult
();
}
}
The
OrderRepositoryInterface
specifies an additional method to retrieve all orders without
invoices, so we have implemented that functionality using Doctrine’s
QueryBuilder
class, which
allows us to define queries against entity objects. Note that this is a bit different from doing
queries against a database schema: we’re using the language of the domain, not the database.
This query language is called
Doctrine Query Language (DQL)⁵⁶
.
Doctrine provides
extensive documentation⁵⁷
for the
QueryBuilder
class if you are interested
more details.
Invoice Repository
The
InvoiceRepository
is another simple subclass that requires no further customization:
⁵⁶
http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html
⁵⁷
http://doctrine-orm.readthedocs.org/en/latest/reference/query-builder.html
Doctrine 2
201
// src/Persistence/Doctrine/Repository/InvoiceRepository.php
namespace
CleanPhp\Invoicer\Persistence\Doctrine\Repository;
use
CleanPhp\Invoicer\Domain\Repository\InvoiceRepositoryInterface;
Do'stlaringiz bilan baham: |