Last active
February 19, 2020 11:43
-
-
Save luca-rath/d3fe7a6c4a182f21d11e30ce3496757d to your computer and use it in GitHub Desktop.
Repository design
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Intosite\Bundle\RecipeBundle\Recipe\Infrastructure\Doctrine; | |
use HandcraftedInTheAlps\Util\Model\Repository\ResourceRepository; | |
use Intosite\Bundle\RecipeBundle\Recipe\Domain\Model\BookInterface; | |
use Intosite\Bundle\RecipeBundle\Recipe\Domain\Repository\BookRepositoryInterface; | |
class BookRepository extends ResourceRepository implements BookRepositoryInterface | |
{ | |
public function findOneBy(array $criteria, ?array $selectionStrategies = null, ?string $sortingStrategy = null, ?array $orderBy = null): ?BookInterface | |
{ | |
$books = $this->findBy($criteria, $selectionStrategies, $sortingStrategy, $orderBy, 1, 0); | |
if (empty($books)) { | |
return null; | |
} | |
return $books[0]; | |
} | |
public function findBy(array $criteria, ?array $selectionStrategy = null, ?string $sortingStrategy = null, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array | |
{ | |
if (static::SORTING_STRATEGY_IDS === $sortingStrategy) { | |
if (!array_key_exists('id', $criteria) || is_array($criteria['id'])) { | |
throw new \InvalidArgumentException('If SORTING_STRATEGY_IDS is beeing used, $criteria must contain an array if ids.'); | |
} | |
$ids = $criteria['id']; | |
$qb = $this->createQueryBuilder('b'); | |
$qb | |
->select('b') | |
->where($qb->expr()->in('b.id', $ids)) | |
->orderBy(sprintf('FIELD(b.id, %s)', implode(', ', $ids))); | |
$books = $qb->getQuery()->getArrayResult(); | |
return $books; | |
} | |
/** @var BookInterface[] $books */ | |
$books = $this->entityRepository->findBy($criteria, $orderBy, $limit, $offset); | |
return $books; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Intosite\Bundle\RecipeBundle\Recipe\Domain\Repository; | |
use HandcraftedInTheAlps\Util\Model\Repository\ResourceRepositoryInterface; | |
use Intosite\Bundle\RecipeBundle\Recipe\Domain\Model\BookInterface; | |
interface BookRepositoryInterface extends ResourceRepositoryInterface | |
{ | |
public const SELECTION_STRATEGY_ALL = 'all'; | |
public const SORTING_STRATEGY_IDS = 'ids'; | |
/** | |
* @param array<string, mixed> $criteria | |
* @param array<string>|null $selectionStrategies | |
* @param array<string>|null $sortingStrategies | |
*/ | |
public function findOneBy(array $criteria, ?array $selectionStrategies = null, ?string $sortingStrategies = null, ?array $orderBy = null): ?BookInterface; | |
/** | |
* @param array<string, mixed> $criteria | |
* @param array<string>|null $selectionStrategies | |
* @param array<string>|null $sortingStrategies | |
* | |
* @return array<BookInterface> | |
*/ | |
public function findBy(array $criteria, ?array $selectionStrategies = null, ?string $sortingStrategy = null, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace HandcraftedInTheAlps\Util\Model\Repository; | |
use Doctrine\ORM\EntityManagerInterface; | |
use Doctrine\ORM\EntityRepository; | |
use Doctrine\ORM\Mapping\ClassMetadata; | |
use Doctrine\ORM\QueryBuilder; | |
abstract class ResourceRepository implements ResourceRepositoryInterface | |
{ | |
/** | |
* @var string | |
*/ | |
protected $className; | |
/** | |
* @var EntityRepository | |
*/ | |
protected $entityRepository; | |
/** | |
* @var EntityManagerInterface | |
*/ | |
protected $entityManager; | |
public function __construct( | |
EntityManagerInterface $em, | |
ClassMetadata $class | |
) { | |
$this->entityRepository = new EntityRepository($em, $class); | |
$this->entityManager = $em; | |
$this->className = $this->entityRepository->getClassName(); | |
} | |
public function create(): object | |
{ | |
$book = new $this->className(); | |
return $book; | |
} | |
public function add(object $book): void | |
{ | |
$this->entityManager->persist($book); | |
} | |
public function remove(object $book): void | |
{ | |
$this->entityManager->remove($book); | |
} | |
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder | |
{ | |
return $this->entityRepository->createQueryBuilder($alias, $indexBy); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace HandcraftedInTheAlps\Util\Model\Repository; | |
use Doctrine\ORM\QueryBuilder; | |
interface ResourceRepositoryInterface | |
{ | |
public function create(): object; | |
public function add(object $book): void; | |
public function remove(object $book): void; | |
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder; | |
} |
maybe change SELECTION_STRATEGY
to RESOLVE_STRATEGY
Wouldn't call them STRATEGY
at all, because in my mind that would be an implementation of the Strategy Pattern, which it isn't. And I think the others agree when saying that returning object
is far from ideal, since all type saftey is gone.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is one drawback, the type definitions for
create()
,add()
andremove()
are justobject
instead ofBookInterface
.