Jeżeli coś jest wartego uwagi a nie jest to materiał na pełnoprawnwgo posta na blogu to będę starać się to umieszczać w tym miejscu.
- Szukasz po tagu: doctrine
- Ilość rekordów w bazie: 9
read model doctrine symfony
class StatusFinder extends FinderAbstract
{
public function getTableName(): string
{
return 'payment_mokka_status';
}
public function getAlias(): string
{
return 'pmos';
}
/**
* @param string $orderNumber
*
* @return StatusReadModel[]
*/
public function getStatusCollection(string $orderNumber): array
{
return array_map(
static fn($order) => StatusReadModel::create($order),
$this->getQueryBuilder()
->andWhere(sprintf('%s.order_number = :order_id', $this->getAlias()))
->setParameter('order_id', $orderNumber, PDO::PARAM_STR)
->execute()
->fetchAll()
);
}
public function getLatestStatus(string $orderNumber): ?StatusReadModel
{
$qb = $this->getQueryBuilder()
->andWhere(sprintf('%s.order_number = :order_id', $this->getAlias()))
->orderBy(sprintf('%s.id', $this->getAlias()), 'desc')
->setMaxResults(1)
->setParameter('order_id', $orderNumber, PDO::PARAM_STR)
->execute();
$data = $qb->fetch();
if ($data) {
return StatusReadModel::create($data);
}
return null;
}
}
class StatusReadModel
{
private int $id;
private string $orderNumber;
private array $response;
private DateTimeInterface $createdAt;
private function __construct(int $id, string $orderNumber, array $response, DateTimeInterface $createdAt)
{
$this->id = $id;
$this->orderNumber = $orderNumber;
$this->response = $response;
$this->createdAt = $createdAt;
}
public function getId(): ?int
{
return $this->id;
}
public function getOrderNumber(): string
{
return $this->orderNumber;
}
public function getResponse(): array
{
return $this->response;
}
public function getCreatedAt(): DateTimeInterface
{
return $this->createdAt;
}
public static function create(array $data): self
{
return new self(
(int)($data['id'] ?? 0),
$data['order_number'],
json_decode($data['response'], true),
new DateTime($data['created_at'])
);
}
public function getOrderData(): array
{
return $this->response[ApiParameterEnum::CURRENT_ORDER] ?? [];
}
public function getOrderStatus(): ?string
{
return $this->response[ApiParameterEnum::CURRENT_ORDER][ApiParameterEnum::STATUS] ?? null;
}
public function paymentHasBeenApproved(): bool
{
return ($this->getOrderData()[ApiParameterEnum::DECISION] ?? null) === PaymentDecisionEnum::APPROVED
&& !empty($this->getPaymentId());
}
public function getPaymentId(): ?string
{
return $this->getOrderData()[ApiParameterEnum::PAYMENT_ID] ?? null;
}
}
Flush persist w repozytorium
/**
* EM flush
*/
public function flush()
{
$this->getEntityManager()->flush();
}
/**
* EM persist
*
* @param ClientStatData $entity
*/
public function persist(ClientInstytutionStat $entity)
{
$this->getEntityManager()->persist($entity);
}
Update BETWEEN
return $this->createQueryBuilder('c')
->update()
->set('c.modifiedDatetime', ':modifiedDatetime')->setParameter('modifiedDatetime', $dateTimeNow)
->andWhere('c.requestedDatetime BETWEEN :requestedDatetimeStart AND :requestedDatetimeEnd')->setParameter('requestedDatetimeStart', $dateFrom)->setParameter('requestedDatetimeEnd', $dateTo)
->andWhere('( (c.modifiedDatetime NOT BETWEEN :dateStart AND :dateEnd) or c.modifiedDatetime is null )')->setParameter('dateStart', $dateFrom)->setParameter('dateEnd', $dateTo)
->getQuery()
->getSingleScalarResult();
Wybrane pola mapowane na obiekt w doctrine
public function findPosts() {
$posts = $this->getEntityManager()->createQueryBuilder('p');
$posts
->select('partial p.{id, title, slug,shortcontent,publishedAt}', 't')
->from('App:Post', 'p')
->leftJoin('p.tags', 't')
->orderBy('p.id', 'DESC');
return $posts;
}
Customowe pole w doctrine
stepNumber:
columnDefinition : 'TINYINT NOT NULL'
nullable: false
Data od do w doctrine
public function getUniqueTransactionCountByStatusInDateRange(\DateTime $dateFrom, \DateTime $dateTo, $transactionStatus) {
$query = $this->getEntityManager()->createQueryBuilder()
->from(Transaction::class, 't')
->select('COUNT(DISTINCT(t.transaction_id))')
->where('t.created_at >= :DateTimeBegin')->setParameter('DateTimeBegin', $dateFrom->format('Y-m-d H:i:s'))
->andWhere('t.created_at <= :DateTimeEnd')->setParameter('DateTimeEnd', $dateTo->format('Y-m-d H:i:s'))
->andWhere('t.status = :Status')->setParameter('Status', $transactionStatus)
;
try {
return (int) $query->getQuery()->getSingleScalarResult();
} catch (\Doctrine\ORM\NoResultException $e) {
return 0;
}
}
Doctrine2 typy pól
const TARRAY = 'array';
const SIMPLE_ARRAY = 'simple_array';
const JSON_ARRAY = 'json_array';
const BIGINT = 'bigint';
const BOOLEAN = 'boolean';
const DATETIME = 'datetime';
const DATETIMETZ = 'datetimetz';
const DATE = 'date';
const TIME = 'time';
const DECIMAL = 'decimal';
const INTEGER = 'integer';
const OBJECT = 'object';
const SMALLINT = 'smallint';
const STRING = 'string';
const TEXT = 'text';
const BINARY = 'binary';
const BLOB = 'blob';
const FLOAT = 'float';
const GUID = 'guid';
Doctrine hydracja
W takim razie problemem raczej jest sposób hydrowania danych, można to rozwiązać na dwa sposoby:
1. Użyć odpowiedniej adnotacji (LAZY, EAGER lub EXTRA LAZY), więcej np. tutaj: http://docs.doctrine-project.org/projects/...sociations.html i to się sprawdzi jeśli wiemy, że np. wraz z obiektem User zawsze będziemy potrzebowali kolekcji emaili (wtedy ustawiamy na EAGER)
2. Jeśli sposób hydrowania jest zależny od kontekstu, to nie ma innego (wygodnego) wyjścia jak użyć query buildera. Jednak nie wystarczy:
-
$qb->join('u.emails', 'e');
- trzeba jeszcze wymusić pobieranie poprzez dodanie select:
-
$qb->select('u', 'e');
W ten sposób emaile zawsze będą w user niezależnie od tego, czy są potrzebne czy nie.
Więcej nie da się powiedzieć bo nie znam Twojego kodu, równie dobrze problemem mogą być źle zaprojektowane encje.
wybranie pola z relacji w symfony
public function getRejectedInstitutionsIdsForClientByInstitutionsIdsAndDate(Client $client, array $institutionsIds, \DateTime $dateTime): array {
$query = $this->createQueryBuilder('cis')
->select('IDENTITY(cis.institution)')
->andWhere('cis.client = :client')->setParameter('client', $client)
->andWhere('cis.institution IN (:institutions)')->setParameter('institutions', $institutionsIds)
->andWhere('cis.date_of_possible_next_serve >= :date_of_possible_next_serve')->setParameter('date_of_possible_next_serve', $dateTime);
$result = $query->getQuery()->getResult();
return array_map(function($value) {
return $value['1'];
}, $result);
}