Repository.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. namespace Michel\PaperORM\Repository;
  3. use InvalidArgumentException;
  4. use Michel\PaperORM\Entity\EntityInterface;
  5. use Michel\PaperORM\EntityManagerInterface;
  6. use Michel\PaperORM\Expression\Expr;
  7. use Michel\PaperORM\Mapper\ColumnMapper;
  8. use Michel\PaperORM\Mapper\EntityMapper;
  9. use Michel\PaperORM\Persistence\EntityPersistence;
  10. use Michel\PaperORM\Query\Fetcher;
  11. use Michel\PaperORM\Query\QueryBuilder;
  12. use Psr\EventDispatcher\EventDispatcherInterface;
  13. abstract class Repository
  14. {
  15. private EntityManagerInterface $em;
  16. private EntityPersistence $ep;
  17. public function __construct(EntityManagerInterface $em, EventDispatcherInterface $dispatcher = null)
  18. {
  19. $this->em = $em;
  20. $this->ep = new EntityPersistence($em, $dispatcher);
  21. }
  22. /**
  23. * Get the name of the table associated with this repository.
  24. *
  25. * @return string The name of the table.
  26. */
  27. final public function getTableName(): string
  28. {
  29. $entityName = $this->getEntityName();
  30. return EntityMapper::getTable($entityName);
  31. }
  32. /**
  33. * Get the name of the model associated with this repository.
  34. *
  35. * @return class-string<EntityInterface> The name of the model.
  36. */
  37. abstract public function getEntityName(): string;
  38. public function findBy(array $arguments = []): Fetcher
  39. {
  40. $expressions = [];
  41. foreach ($arguments as $key => $value) {
  42. if ($value instanceof EntityInterface) {
  43. $value = $value->getPrimaryKeyValue();
  44. } elseif (is_array($value)) {
  45. $expressions[] = Expr::in($key, $value);
  46. continue;
  47. } elseif (is_null($value)) {
  48. $expressions[] = Expr::isNull($key);
  49. continue;
  50. } elseif (is_string($value) && strtoupper($value) === "!NULL") {
  51. $expressions[] = Expr::isNotNull($key);
  52. continue;
  53. } elseif (!is_scalar($value)) {
  54. throw new InvalidArgumentException(
  55. sprintf('Argument "%s" must be scalar, array, null or EntityInterface, %s given', $key, gettype($value))
  56. );
  57. }
  58. $expressions[] = Expr::equal($key, $value);
  59. }
  60. return (new Fetcher($this->qb(), true))->where(...$expressions);
  61. }
  62. public function findOneBy(array $arguments = []): Fetcher
  63. {
  64. return $this->findBy($arguments)->first();
  65. }
  66. public function find(int $pk): Fetcher
  67. {
  68. $entityName = $this->getEntityName();
  69. $primaryKeyColumn = ColumnMapper::getPrimaryKeyColumnName($entityName);
  70. return $this->findOneBy([$primaryKeyColumn => $pk]);
  71. }
  72. public function insert(object $entityToInsert): int
  73. {
  74. return $this->ep->insert($entityToInsert);
  75. }
  76. public function update(object $entityToUpdate): int
  77. {
  78. return $this->ep->update($entityToUpdate);
  79. }
  80. public function delete(object $entityToDelete): int
  81. {
  82. $rows = $this->ep->delete($entityToDelete);
  83. $this->em->getCache()->invalidate(get_class($entityToDelete), $entityToDelete->getPrimaryKeyValue());
  84. return $rows;
  85. }
  86. public function qb(...$propertiesToSelect): QueryBuilder
  87. {
  88. $queryBuilder = new QueryBuilder($this->em);
  89. return $queryBuilder->select($this->getEntityName(), $propertiesToSelect);
  90. }
  91. public function clear(): void
  92. {
  93. $this->ep->clear();
  94. $this->em->getCache()->clear();
  95. }
  96. }