CoolCMS API

VisibilityConstrainedDocumentSourceInterface extends DocumentSourceInterface

Source that can pass its visibility conditions to the ES query.

Optional extension of DocumentSourceInterface: a source without it sends the plain query (EsSearcher).

The DB stays the arbiter of visibility. Caller filters are still applied on both paths (SearchTrait), so a stale document never leaks an invisible entity; this interface only pre-narrows the ES side so paging runs over a reasonable set. Adverts need it because expired and inactive ones stay in the index, so relevance paging in ES would return short pages and an inflated totalCount.

IMPORTANT: the opposite direction (a document marked invisible but visible in the DB) is the price of pre-narrowing: such an entity drops out of search until a reindex or hook catches up. Therefore only conditions whose change the source can already propagate to the index belong here, plus query-time conditions over time, which cannot go stale.

Table of Contents

Methods

buildDocuments()  : array<string, array<string, array<string, mixed>>>
Builds the documents of an entity as `indexBase => (_id => document)`. An empty array means the entity must not be indexed (deactivated or without an active translation), so it is deleted.
expectedDocumentBounds()  : array{min: int, max: int}
Returns the expected range of the document count in the source index (across all bases and languages).
fetchExistingIds()  : array<string|int, int>
Returns which of the given ids really exist in the DB; orphan cleanup deletes from ES the documents of entities no longer in the DB.
fetchFresh()  : array<int, object>
Returns fresh entities after commit (service `find` with `useCache: false`). An entity from `completedSave` is not authoritative, because `afterSave` changes the DB through `updateColumn` after the flush. A missing id is omitted.
fetchIdsChangedSince()  : array<string|int, int>
Returns ids of entities changed or created since `$since` (DB, no cache) as the input of the incremental sync. It must cover both insert and update (`insertTime` or `updateDatetime`); mutations outside the ORM (`updateColumn`, raw SQL) are never covered and the nightly full reindex catches them up.
fetchReindexBatch()  : array<int, object>
Returns a batch of entities for a full reindex by key: `id > $afterId`, ordered ascending by id, at most `$limit` (with includes, no cache). The array key is the entity id; the last one becomes the cursor the next part of the reindex continues from.
getAllDocumentIds()  : array<string, array<string|int, string>>
Returns every possible `_id` of the entity across languages as `indexBase => [_id, …]`.
getEntityIdField()  : string
Returns the ES document field holding the entity id (e.g. `articleId`); sync sorts and pages (`search_after`) by it during the orphan scan.
getIndexBaseForLanguage()  : string|null
Returns the index base for a language alias (`cs`), null when the language does not exist.
getIndexBases()  : array<string|int, string>
Returns index base names without prefix and version; one per language for translated entities (e.g. `['blog_article_cs', 'blog_article_en']`).
getIndexDefinition()  : array<string, mixed>
Returns the index definition (settings and mappings) for index creation.
getKey()  : string
Returns the source key for the `enabledSources` allowlist and `EsSearcher`, e.g. `blog_article`.
getSearchFields()  : array<string, int|float>
Returns the `multi_match` fields with boosts, e.g. `['name' => 3, 'perex' => 2, 'content' => 1]`.
getVisibilityFilters()  : array<int, array<string, mixed>>
Returns clauses for `bool.filter` of the search query (they only narrow, the score is not affected).

Methods

buildDocuments()

Builds the documents of an entity as `indexBase => (_id => document)`. An empty array means the entity must not be indexed (deactivated or without an active translation), so it is deleted.

public buildDocuments(object $entity) : array<string, array<string, array<string, mixed>>>
Parameters
$entity : object
Return values
array<string, array<string, array<string, mixed>>>

expectedDocumentBounds()

Returns the expected range of the document count in the source index (across all bases and languages).

public expectedDocumentBounds() : array{min: int, max: int}

It must mirror the guards of buildDocuments() exactly, otherwise monitoring would report a false drift. Used by EsMonitor to detect ES vs. DB mismatch. min === max for a single language entity (one document per entity); for multi-language sources (Article) max is an upper estimate, because not every entity has all languages active.

Return values
array{min: int, max: int}

fetchExistingIds()

Returns which of the given ids really exist in the DB; orphan cleanup deletes from ES the documents of entities no longer in the DB.

public fetchExistingIds(array<string|int, int> $ids) : array<string|int, int>
Parameters
$ids : array<string|int, int>
Return values
array<string|int, int>

fetchFresh()

Returns fresh entities after commit (service `find` with `useCache: false`). An entity from `completedSave` is not authoritative, because `afterSave` changes the DB through `updateColumn` after the flush. A missing id is omitted.

public fetchFresh(array<string|int, int> $ids) : array<int, object>
Parameters
$ids : array<string|int, int>
Return values
array<int, object> —

keyed by id

fetchIdsChangedSince()

Returns ids of entities changed or created since `$since` (DB, no cache) as the input of the incremental sync. It must cover both insert and update (`insertTime` or `updateDatetime`); mutations outside the ORM (`updateColumn`, raw SQL) are never covered and the nightly full reindex catches them up.

public fetchIdsChangedSince(DateTimeImmutable $since) : array<string|int, int>
Parameters
$since : DateTimeImmutable
Return values
array<string|int, int>

fetchReindexBatch()

Returns a batch of entities for a full reindex by key: `id > $afterId`, ordered ascending by id, at most `$limit` (with includes, no cache). The array key is the entity id; the last one becomes the cursor the next part of the reindex continues from.

public fetchReindexBatch(int $afterId, int $limit) : array<int, object>
Parameters
$afterId : int
$limit : int
Return values
array<int, object> —

keyed by id, ascending

getAllDocumentIds()

Returns every possible `_id` of the entity across languages as `indexBase => [_id, …]`.

public getAllDocumentIds(int $id) : array<string, array<string|int, string>>

It serves targeted deletion of orphan language documents (orphanRemoval on translations) and delete; delete_by_query must never be used.

Parameters
$id : int
Return values
array<string, array<string|int, string>>

getEntityIdField()

Returns the ES document field holding the entity id (e.g. `articleId`); sync sorts and pages (`search_after`) by it during the orphan scan.

public getEntityIdField() : string
Return values
string

getIndexBaseForLanguage()

Returns the index base for a language alias (`cs`), null when the language does not exist.

public getIndexBaseForLanguage(string|null $languageAlias) : string|null
Parameters
$languageAlias : string|null
Return values
string|null

getIndexBases()

Returns index base names without prefix and version; one per language for translated entities (e.g. `['blog_article_cs', 'blog_article_en']`).

public getIndexBases() : array<string|int, string>
Return values
array<string|int, string>

getIndexDefinition()

Returns the index definition (settings and mappings) for index creation.

public getIndexDefinition(string $indexBase) : array<string, mixed>
Parameters
$indexBase : string
Return values
array<string, mixed>

getKey()

Returns the source key for the `enabledSources` allowlist and `EsSearcher`, e.g. `blog_article`.

public getKey() : string
Return values
string

getSearchFields()

Returns the `multi_match` fields with boosts, e.g. `['name' => 3, 'perex' => 2, 'content' => 1]`.

public getSearchFields() : array<string, int|float>
Return values
array<string, int|float>

getVisibilityFilters()

Returns clauses for `bool.filter` of the search query (they only narrow, the score is not affected).

public getVisibilityFilters() : array<int, array<string, mixed>>

They mirror what the DB considers visible. For adverts that is exactly two things, the same pair the front end builds in AdvertListTrait::prepareFilters():

  • a term on the denormalized flag (generated DB column active),
  • a range on the expiry date as a query-time condition (now/d), because NOW() cannot go into a generated column and would go stale in the index every midnight.

An empty array means no pre-narrowing is wanted (the query is then the plain one).

Return values
array<int, array<string, mixed>>
On this page

Search results