Doctrine
Mark the entities whose changes update a document. The bundle listens to Doctrine and queues a sync or delete after every successful flush, at the end of the request all changes are sent at once.
The integration needs doctrine/orm and the DoctrineBundle, it is enabled automatically. Disable it with
batteryincluded.doctrine.enabled: false.
The attribute
use Batteryincluded\BatteryincludedBundle\Doctrine\Attribute\BatteryIncludedDocument;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[BatteryIncludedDocument('PRODUCT', deleteMissing: true)]
class Product
{
#[ORM\Id, ORM\GeneratedValue, ORM\Column]
private ?int $id = null;
}
Saving product 5 syncs the document PRODUCT-5, removing it deletes the document. The document itself comes from
your PartialDataProviderInterface, the attribute only tells which ids changed. So a
product the provider does not deliver anymore (e.g. deactivated) is deleted with deleteMissing: true.
| Option | Default | Meaning |
|---|---|---|
type |
– | Document type, e.g. PRODUCT, the document id is <TYPE>-<identifier> |
identifier |
Doctrine id | Method, getter (sku → getSku()) or property delivering the identifier. null skips the entity. Composite ids need it. |
collection |
default |
Name of the collection in the configuration |
deleteOnRemove |
true |
Removing the entity deletes the document, otherwise the document is synced |
deleteMissing |
false |
Deletes the document if the providers do not deliver it anymore |
Enable deleteMissing only if a PartialDataProviderInterface handles the type, otherwise every change deletes the
document.
Related entities
The attribute is repeatable and inherited by child classes. A variant updates its own document and the one of its product, removing the variant only updates the product:
#[ORM\Entity]
#[BatteryIncludedDocument('VARIANT', identifier: 'sku', collection: 'ch')]
#[BatteryIncludedDocument('PRODUCT', identifier: 'getProductId', deleteOnRemove: false)]
class Variant
{
public function getProductId(): ?int
{
return $this->product?->getId();
}
}
For relations the listener cannot see (e.g. a price list changing many products) schedule the documents yourself
with the DocumentChangeQueue.
When documents are sent
persist(), changes andremove()are collected during the flush. The identifier of a removed entity is read before Doctrine resets it.- After a successful flush the changes are handed to the
DocumentChangeQueue. A failed or rolled back flush andclear()discard them. - At the end of the request (
kernel.terminate, after the response was sent), the command (console.terminate) or the message (Messenger worker) the queue sends all changes: asSyncDocumentsMessage/DeleteDocumentsMessagewith symfony/messenger, otherwise directly.
Several flushes of one request lead to one API call per collection and action. Errors are logged to the
batteryincluded channel and never break the response.
Route the messages to an async transport in production. Without Messenger the API calls
run in kernel.terminate, which only happens after the response with PHP-FPM.