PaymentItemRepository
extends OrmRepository
in package
uses
PaymentItemScopeTrait
Abstract ORM repository with dynamic-includes support.
Every concrete repository extends this class.
Table of Contents
Properties
- $db : EntityManagerInterface
- $entityManager : EntityManagerInterface
- $entityUpdater : EntityUpdater
- $managerProvider : ManagerProvider
- $transactionManager : TransactionManager
Methods
- __construct() : mixed
- beginTransaction() : void
- commit() : void
- computeTotalCount() : int
- Counts the total number of records with applied filters.
- delete() : Result
- deleteRelations() : Result
- Deletes rows from a relation table by parent FK column.
- get() : BaseEntity|null
- Finds a single entity by ID with dynamic includes.
-
getAll()
: array{0: array
, 1: int} - getBy() : BaseEntity|null
- Finds a single entity by filters with dynamic includes.
- getEntityClass() : class-string
- Returns the entity class name.
- getTransactionLevel() : int
- insertRelations() : Result
- Inserts rows into a relation table.
- isInTransaction() : bool
- recalcTopedUntilForAdverts() : Result
- Recalculates `toped_until` of the adverts absolutely, to the furthest `validity_datetime` of their active topping items (tariff `$toppingTariffId`).
- rollback() : void
- save() : Result
- selectRelationIds() : array<int, int>|null
- Returns ids of target records linked to the parent in a relation table (for example gallery asset ids).
- setTransactionManager() : void
- updateAdvertsAsPaid() : Result
- Marks adverts as paid (`paid = 1`); called after a category is paid, when the advert becomes displayable.
- updateCategoryRelsAsPaid() : Result
- updateColumns() : Result
- Updates a table using pre-prepared data from a mapper.
- updateExpirationDateForPayment() : Result
- Extends the expiration of adverts to the furthest `validity_datetime` of their paid (`active = 1`) items of the given payment, so an advert does not expire before a paid tariff (for example topping) ends.
- updateRelations() : Result
- Updates rows in a relation table.
- updateTopedUntilForAdverts() : Result
- Extends `toped_until` of the adverts to the furthest `validity_datetime` of their active topping items (tariff `$toppingTariffId`, default 1 from {@see \App\Core\Config\AdvertToppingConfig}).
- updateValidityDatetimeForPayment() : Result
- Sets the validity of the payment items, continuing after the latest active item of the same tariff and advert.
- applyFilters() : void
- applyIdentifierFilter() : void
- applyIncludes() : array<int, string>
- Applies includes as LEFT JOINs for hydration.
- applyOrdering() : void
- dumpDbError() : void
- entityHasMethod() : bool
- Checks whether the entity class has the given method (association).
- fetchCompleteEntities() : array<string|int, mixed>
- Second phase: pure hydration.
- fetchIdentifiers() : array<int, array<string|int, mixed>>
- fetchSimple() : array<string|int, mixed>
- getAssociationFromMethod() : string
- Derives the association name from a getter method.
- getClassMetadata() : ClassMetadata<string|int, object>
- Returns the Doctrine metadata for the entity.
- getDefaultIncludes() : array<string|int, string>
- Default includes for this entity.
- getEntityManager() : EntityManagerInterface
- Returns the EntityManager.
- getJoinedAliases() : array<string, true>
- Returns all aliases already joined in the QueryBuilder.
- getPrimaryKey() : string
- Returns the entity primary key.
- getPrimaryKeyField() : string
- Returns the primary key field name.
- getRelationField() : string|null
- Returns the field name of the relation to the target entity.
- getTableAlias() : string|null
- Reads the table alias from the `TableAlias` attribute, escaped against reserved keywords.
- hydrateByIdentifiers() : array<int, mixed>
- Loads entities by PK and hydrates includes while avoiding the cartesian explosion caused by parallel ToMany joins.
- isJoined() : bool
- Checks whether the alias is already joined in the QueryBuilder.
- mergeWithDefaults() : array<string|int, string>
- Merges explicit includes with the defaults.
- sortResultsByIdentifiers() : array<int, mixed>
- buildDistinctIdentityExpression() : string
- Returns the expression whose distinct values are the distinct rows of the root entity.
- extractIdsFromScalarResult() : array<int, int|string|array<string, mixed>>
- Converts the scalar result of `fetchIdentifiers()` (`{alias}_{field}` keys) to the format the hydrator expects (scalar for a single PK, `[field => value]` for a composite one).
- identityProjectionAlias() : string
- Alias of an `IDENTITY()` projection of an association identifier. Deliberately outside the `{alias}_{relation}` namespace JoinHelper uses for JOIN aliases.
- paymentScopeParams() : ArrayParameterType>}
- rawSqlParam() : mixed
- Returns the value for a bare SQL parameter (no DBAL type).
Properties
$db
protected
EntityManagerInterface
$db
$entityManager
protected
EntityManagerInterface
$entityManager
$entityUpdater
protected
EntityUpdater
$entityUpdater
$managerProvider
protected
ManagerProvider
$managerProvider
$transactionManager
protected
TransactionManager
$transactionManager
Methods
__construct()
public
__construct(ManagerProvider $managerProvider, EntityUpdater $entityUpdater, EntityManagerInterface $entityManager, TransactionManager $transactionManager) : mixed
Parameters
- $managerProvider : ManagerProvider
- $entityUpdater : EntityUpdater
- $entityManager : EntityManagerInterface
- $transactionManager : TransactionManager
beginTransaction()
public
beginTransaction() : void
commit()
public
commit() : void
computeTotalCount()
Counts the total number of records with applied filters.
public
computeTotalCount(array<string|int, mixed> $filters) : int
Parameters
- $filters : array<string|int, mixed>
Return values
intdelete()
public
delete(BaseEntity $entity) : Result
Parameters
- $entity : BaseEntity
Return values
ResultdeleteRelations()
Deletes rows from a relation table by parent FK column.
public
deleteRelations(string $table, string $column, array<string|int, mixed> $parentIds) : Result
Parameters
- $table : string
-
Table name
- $column : string
-
FK column name
- $parentIds : array<string|int, mixed>
-
Parent IDs to delete
Return values
Resultget()
Finds a single entity by ID with dynamic includes.
public
get(int $id[, string|array<string|int, mixed> $includes = [] ]) : BaseEntity|null
Delegates to getAll() with a PK filter and limit 1 and shares its two-phase fetch,
which avoids the LIMIT+JOIN problem (a join multiplies rows, so LIMIT 1 would cut
collection members).
Parameters
- $id : int
- $includes : string|array<string|int, mixed> = []
-
e.g. ['translations', 'routes.translations'] or '*' for all
Return values
BaseEntity|nullgetAll()
public
getAll([array<string|int, mixed>|null $filters = [] ][, array<string|int, mixed>|null $orderBys = null ][, int|null $offset = null ][, int|null $limit = null ][, array<string|int, mixed>|null $columns = null ][, bool $computeTotalCount = false ][, string|array<string|int, mixed> $includes = [] ]) : array{0: array, 1: int}
Parameters
- $filters : array<string|int, mixed>|null = []
- $orderBys : array<string|int, mixed>|null = null
- $offset : int|null = null
- $limit : int|null = null
- $columns : array<string|int, mixed>|null = null
- $computeTotalCount : bool = false
- $includes : string|array<string|int, mixed> = []
Return values
array{0: array[entities (or $columns rows), total count]
getBy()
Finds a single entity by filters with dynamic includes.
public
getBy([array<string|int, mixed>|null $filters = null ][, string|array<string|int, mixed> $includes = [] ]) : BaseEntity|null
Delegates to getAll() with limit 1 and shares its two-phase fetch, which avoids the
LIMIT+JOIN problem (a join multiplies rows, so LIMIT 1 would cut collection members).
Parameters
- $filters : array<string|int, mixed>|null = null
- $includes : string|array<string|int, mixed> = []
-
e.g. ['translations', 'routes.translations'] or '*' for all
Return values
BaseEntity|nullgetEntityClass()
Returns the entity class name.
public
getEntityClass() : class-string
Return values
class-stringgetTransactionLevel()
public
getTransactionLevel() : int
Return values
intinsertRelations()
Inserts rows into a relation table.
public
insertRelations(string $table, array<int, array<string, mixed>> $rows) : Result
Parameters
- $table : string
-
Table name
- $rows : array<int, array<string, mixed>>
-
Array of ['column_name' => value] rows
Return values
ResultisInTransaction()
public
isInTransaction() : bool
Return values
boolrecalcTopedUntilForAdverts()
Recalculates `toped_until` of the adverts absolutely, to the furthest `validity_datetime` of their active topping items (tariff `$toppingTariffId`).
public
recalcTopedUntilForAdverts(array<string|int, int> $advertIds, int $toppingTariffId) : Result
Unlike updateTopedUntilForAdverts it can also shorten the value, and with no active item it sets null (left join). Meant for the admin path (deactivation, shorter validity, item deletion), not for the gateway.
Parameters
- $advertIds : array<string|int, int>
- $toppingTariffId : int
Return values
Resultrollback()
public
rollback() : void
save()
public
save(T $entity[, array<string|int, string> $skipFields = [] ]) : Result
Parameters
- $entity : T
- $skipFields : array<string|int, string> = []
-
Field names to skip during UPDATE (e.g. ['userRoles'])
Return values
ResultselectRelationIds()
Returns ids of target records linked to the parent in a relation table (for example gallery asset ids).
public
selectRelationIds(string $table, string $parentColumn, int $parentId, string $targetColumn) : array<int, int>|null
Soft-removed rows are read too, as they still belong to the same parent. On a database
error it returns null; the caller decides, and a foreign id must then not be accepted.
Parameters
- $table : string
- $parentColumn : string
- $parentId : int
- $targetColumn : string
Return values
array<int, int>|nullsetTransactionManager()
public
setTransactionManager(TransactionManager $transactionManager) : void
Parameters
- $transactionManager : TransactionManager
updateAdvertsAsPaid()
Marks adverts as paid (`paid = 1`); called after a category is paid, when the advert becomes displayable.
public
updateAdvertsAsPaid(array<string|int, int> $advertIds) : Result
Parameters
- $advertIds : array<string|int, int>
Return values
ResultupdateCategoryRelsAsPaid()
public
updateCategoryRelsAsPaid(int $advertId, array<string|int, int> $categoryIds) : Result
Parameters
- $advertId : int
- $categoryIds : array<string|int, int>
Return values
ResultupdateColumns()
Updates a table using pre-prepared data from a mapper.
public
updateColumns(array<string, mixed> $set, array<int, array<string, array{column: string, value: mixed}>> $where, string $table) : Result
Parameters
- $set : array<string, mixed>
-
['column_name' => value|SqlValue]
- $where : array<int, array<string, array{column: string, value: mixed}>>
-
[[ 'paramName' => ['column'=>col, 'value'=>val], ... ], ... ]
- $table : string
-
table name
Return values
ResultupdateExpirationDateForPayment()
Extends the expiration of adverts to the furthest `validity_datetime` of their paid (`active = 1`) items of the given payment, so an advert does not expire before a paid tariff (for example topping) ends.
public
updateExpirationDateForPayment(int $paymentId[, array<int, int>|null $itemIds = null ]) : Result
NOTE: run only after validity_datetime and active = 1 are set.
$itemIds limits the update to those payment items; null means all items of the payment (first
activation). An empty list does nothing.
Parameters
- $paymentId : int
- $itemIds : array<int, int>|null = null
Return values
ResultupdateRelations()
Updates rows in a relation table.
public
updateRelations(string $table, array<int, array{set: array, where: array}> $updates) : Result
Parameters
- $table : string
-
Table name
-
$updates
: array<int, array{set: array
, where: array }> -
Array of ['set' => [col => val], 'where' => [col => val]]
Return values
ResultupdateTopedUntilForAdverts()
Extends `toped_until` of the adverts to the furthest `validity_datetime` of their active topping items (tariff `$toppingTariffId`, default 1 from {@see \App\Core\Config\AdvertToppingConfig}).
public
updateTopedUntilForAdverts(array<string|int, int> $advertIds, int $toppingTariffId) : Result
Idempotent and monotonic (it only extends), so it is safe to call from the gateway and from the admin save. The Discussion counterpart is PaymentItemRepository::updateTopedUntilForMessages.
Parameters
- $advertIds : array<string|int, int>
- $toppingTariffId : int
Return values
ResultupdateValidityDatetimeForPayment()
Sets the validity of the payment items, continuing after the latest active item of the same tariff and advert.
public
updateValidityDatetimeForPayment(int $paymentId[, array<int, int>|null $itemIds = null ]) : Result
An item that is already active (a further paid transaction of the same payment) stacks on its own validity too, so paying again adds another period instead of recomputing the same one.
$itemIds limits the update to those payment items; null means all items of the payment (first
activation). An empty list does nothing.
Parameters
- $paymentId : int
- $itemIds : array<int, int>|null = null
Return values
ResultapplyFilters()
protected
applyFilters(QueryBuilder $qb, array<string|int, mixed>|null $filters, class-string $entityClass, string $fromTableAlias) : void
Parameters
- $qb : QueryBuilder
- $filters : array<string|int, mixed>|null
- $entityClass : class-string
- $fromTableAlias : string
applyIdentifierFilter()
protected
applyIdentifierFilter(QueryBuilder $qb, array<int, array<string|int, mixed>> $identifiers, array<int, string> $identifierFields, string $fromTableAlias) : void
Parameters
- $qb : QueryBuilder
- $identifiers : array<int, array<string|int, mixed>>
- $identifierFields : array<int, string>
- $fromTableAlias : string
applyIncludes()
Applies includes as LEFT JOINs for hydration.
protected
applyIncludes(QueryBuilder $qb, array<string|int, mixed> $includes, string $alias[, array<string|int, mixed> &$joinedAliases = [] ][, class-string|null $entityClass = null ]) : array<int, string>
Hydration only: no WHERE and no WITH conditions. Filters are applied in the first phase
(fetchIdentifiers()) over ids; the second phase only loads the full collections for the
selected entities.
Parameters
- $qb : QueryBuilder
-
Query builder
- $includes : array<string|int, mixed>
-
Includes, e.g. ['translations', 'routes.translations']
- $alias : string
-
Alias of the root entity
- $joinedAliases : array<string|int, mixed> = []
-
Reference tracking already-joined aliases
- $entityClass : class-string|null = null
-
Root entity for resolving includes (default: root repo entity)
Return values
array<int, string> —Aliases for the SELECT
applyOrdering()
protected
applyOrdering(QueryBuilder $qb, array<string|int, mixed>|null $orderBys, string $fromTableAlias) : void
Parameters
- $qb : QueryBuilder
- $orderBys : array<string|int, mixed>|null
- $fromTableAlias : string
dumpDbError()
protected
dumpDbError(Throwable $e) : void
Parameters
- $e : Throwable
entityHasMethod()
Checks whether the entity class has the given method (association).
protected
entityHasMethod(string $entityClass, string $method) : bool
Parameters
- $entityClass : string
- $method : string
-
Method name, e.g. 'getTranslations'
Return values
boolfetchCompleteEntities()
Second phase: pure hydration.
protected
fetchCompleteEntities(class-string $entityClass, string $fromTableAlias, array<int, array<string|int, mixed>> $identifiers, array<string|int, mixed>|null $columns, array<string|int, mixed> $includes[, array<string|int, mixed>|null $filters = null ]) : array<string|int, mixed>
Delegates to the shared hydrateByIdentifiers() of OrmRepository, which loads
to-many branches separately via WHERE parent_id IN (:ids) (no cartesian explosion
from parallel to-many joins).
Parameters
- $entityClass : class-string
- $fromTableAlias : string
- $identifiers : array<int, array<string|int, mixed>>
- $columns : array<string|int, mixed>|null
- $includes : array<string|int, mixed>
- $filters : array<string|int, mixed>|null = null
Return values
array<string|int, mixed>fetchIdentifiers()
protected
fetchIdentifiers(class-string $entityClass, string $fromTableAlias, array<string|int, mixed>|null $filters, array<string|int, mixed>|null $orderBys, int|null $offset, int|null $limit) : array<int, array<string|int, mixed>>
Parameters
- $entityClass : class-string
- $fromTableAlias : string
- $filters : array<string|int, mixed>|null
- $orderBys : array<string|int, mixed>|null
- $offset : int|null
- $limit : int|null
Return values
array<int, array<string|int, mixed>> —scalar rows keyed {alias}_{field}
fetchSimple()
protected
fetchSimple(class-string $entityClass, string $fromTableAlias, array<string|int, mixed>|null $filters, array<string|int, mixed>|null $orderBys, int|null $offset, int|null $limit, array<string|int, mixed>|null $columns) : array<string|int, mixed>
Parameters
- $entityClass : class-string
- $fromTableAlias : string
- $filters : array<string|int, mixed>|null
- $orderBys : array<string|int, mixed>|null
- $offset : int|null
- $limit : int|null
- $columns : array<string|int, mixed>|null
Return values
array<string|int, mixed>getAssociationFromMethod()
Derives the association name from a getter method.
protected
getAssociationFromMethod(string $method) : string
E.g. 'getTranslations' → 'translations'.
Parameters
- $method : string
Return values
stringgetClassMetadata()
Returns the Doctrine metadata for the entity.
protected
getClassMetadata() : ClassMetadata<string|int, object>
Return values
ClassMetadata<string|int, object>getDefaultIncludes()
Default includes for this entity.
protected
getDefaultIncludes() : array<string|int, string>
Override in a child, or place the DefaultIncludes attribute on the entity.
Return values
array<string|int, string>getEntityManager()
Returns the EntityManager.
protected
getEntityManager() : EntityManagerInterface
Return values
EntityManagerInterfacegetJoinedAliases()
Returns all aliases already joined in the QueryBuilder.
protected
getJoinedAliases(QueryBuilder $qb) : array<string, true>
Parameters
- $qb : QueryBuilder
Return values
array<string, true>getPrimaryKey()
Returns the entity primary key.
protected
getPrimaryKey() : string
Return values
stringgetPrimaryKeyField()
Returns the primary key field name.
protected
getPrimaryKeyField() : string
Return values
stringgetRelationField()
Returns the field name of the relation to the target entity.
protected
getRelationField(class-string $entityClass, string $targetEntity) : string|null
Parameters
- $entityClass : class-string
- $targetEntity : string
Return values
string|nullgetTableAlias()
Reads the table alias from the `TableAlias` attribute, escaped against reserved keywords.
protected
getTableAlias(class-string $entityClass) : string|null
The attribute value is used verbatim as the QueryBuilder identification variable and FROM
alias (e.g. ->createQueryBuilder('order')), and the query lexer treats a bare reserved word
as a keyword token instead of an identifier, which breaks the parser. Escaping here, the
single choke point that find() and getAll() funnel through, protects every present and
future entity without hand-picking alias strings per #[TableAlias] declaration.
Parameters
- $entityClass : class-string
Return values
string|nullhydrateByIdentifiers()
Loads entities by PK and hydrates includes while avoiding the cartesian explosion caused by parallel ToMany joins.
protected
hydrateByIdentifiers(class-string $entityClass, string $fromTableAlias, array<string|int, int|string|array<string, mixed>> $ids, array<string|int, mixed> $includes[, array<string|int, mixed>|null $columns = null ][, array<string|int, mixed>|null $filters = null ]) : array<int, mixed>
The root query holds only ToOne chains (no DISTINCT / temp table). Every
ToMany branch is loaded separately via WHERE parent_id IN (:ids) and the
collections are then stitched back onto the parent entities in PHP.
Filters (if passed) propagate into the ToMany branches only when they opt in with
BaseFilter::setApplyToCollections(true): such a filter with the dot-path A.B.C
is applied to every branch whose path is a prefix of it (with matching trimming).
Other filters, and those with isPhaseOneOnly() === true, stay purely in phase 1,
so included collections are loaded complete. See filtersForBranch().
Parameters
- $entityClass : class-string
-
Root entity
- $fromTableAlias : string
-
alias of the root entity in the query
- $ids : array<string|int, int|string|array<string, mixed>>
-
PK list: either scalar (single-column PK), or [field => value] (composite)
- $includes : array<string|int, mixed>
-
Dot-notation includes, e.g. ['routes.translations', 'parameterRels.parameter']
- $columns : array<string|int, mixed>|null = null
-
Column restriction on the root entity
- $filters : array<string|int, mixed>|null = null
-
Phase 1 filters (for propagation into ToMany branches)
Return values
array<int, mixed> —entities (or column rows when $columns is given)
isJoined()
Checks whether the alias is already joined in the QueryBuilder.
protected
isJoined(QueryBuilder $qb, string $alias) : bool
Parameters
- $qb : QueryBuilder
- $alias : string
Return values
boolmergeWithDefaults()
Merges explicit includes with the defaults.
protected
mergeWithDefaults(string|array<string|int, string> $includes) : array<string|int, string>
Passing '*' loads every association of the entity.
Parameters
- $includes : string|array<string|int, string>
-
Explicit includes, or '*' for all
Return values
array<string|int, string> —Merged includes
sortResultsByIdentifiers()
protected
sortResultsByIdentifiers(array<string|int, mixed> $results, array<int, array<string|int, mixed>> $identifiers, class-string $entityClass, string $fromTableAlias) : array<int, mixed>
Parameters
- $results : array<string|int, mixed>
- $identifiers : array<int, array<string|int, mixed>>
- $entityClass : class-string
- $fromTableAlias : string
Return values
array<int, mixed>buildDistinctIdentityExpression()
Returns the expression whose distinct values are the distinct rows of the root entity.
private
buildDistinctIdentityExpression(ClassMetadata<string|int, object> $metadata, string $alias) : string
IMPORTANT: every identifier component must be counted. Counting only the first one makes a
compound identity (CategoryText = languageId + parent) return the number of distinct
languages instead of rows. DQL has no multi-column COUNT(DISTINCT), so the components are
joined with a separator; an association component goes through IDENTITY() (its FK), a
scalar one directly. CONCAT is portable (the SQLite platform renders ||), and the
separator cannot occur inside integer keys.
Parameters
- $metadata : ClassMetadata<string|int, object>
- $alias : string
Return values
stringextractIdsFromScalarResult()
Converts the scalar result of `fetchIdentifiers()` (`{alias}_{field}` keys) to the format the hydrator expects (scalar for a single PK, `[field => value]` for a composite one).
private
extractIdsFromScalarResult(array<int, array<string|int, mixed>> $identifiers, array<int, string> $identifierFields, string $fromTableAlias) : array<int, int|string|array<string, mixed>>
Parameters
- $identifiers : array<int, array<string|int, mixed>>
- $identifierFields : array<int, string>
- $fromTableAlias : string
Return values
array<int, int|string|array<string, mixed>>identityProjectionAlias()
Alias of an `IDENTITY()` projection of an association identifier. Deliberately outside the `{alias}_{relation}` namespace JoinHelper uses for JOIN aliases.
private
static identityProjectionAlias(string $fromTableAlias, string $idField) : string
Parameters
- $fromTableAlias : string
- $idField : string
Return values
stringpaymentScopeParams()
private
static paymentScopeParams(int $paymentId, array<int, int>|null $itemIds) : ArrayParameterType>}
Parameters
- $paymentId : int
- $itemIds : array<int, int>|null
Return values
ArrayParameterType>}rawSqlParam()
Returns the value for a bare SQL parameter (no DBAL type).
private
rawSqlParam(mixed $value) : mixed
The mysqli driver would send false as '' and cannot bind a DateTime at all; a database
in strict mode then rejects the write ("Incorrect integer value"), while a non-strict one
silently converts it to 0.
Parameters
- $value : mixed