vendor/friendsofsymfony/elastica-bundle/src/Doctrine/Listener.php line 183
<?php/** This file is part of the FOSElasticaBundle package.** (c) FriendsOfSymfony <https://friendsofsymfony.github.com/>** For the full copyright and license information, please view the LICENSE* file that was distributed with this source code.*/namespace FOS\ElasticaBundle\Doctrine;use Doctrine\Persistence\Event\LifecycleEventArgs;use FOS\ElasticaBundle\Persister\ObjectPersister;use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;use FOS\ElasticaBundle\Provider\IndexableInterface;use Psr\Log\LoggerInterface;use Symfony\Component\PropertyAccess\PropertyAccess;use Symfony\Component\PropertyAccess\PropertyAccessorInterface;/*** Automatically update ElasticSearch based on changes to the Doctrine source* data. One listener is generated for each Doctrine entity / ElasticSearch type.*/class Listener{/*** Objects scheduled for insertion.*/public array $scheduledForInsertion = [];/*** Objects scheduled to be updated or removed.*/public array $scheduledForUpdate = [];/*** IDs of objects scheduled for removal.*/public array $scheduledForDeletion = [];/*** Object persister.*/protected ObjectPersisterInterface $objectPersister;/*** PropertyAccessor instance.*/protected PropertyAccessorInterface $propertyAccessor;/*** Configuration for the listener.*/private array $config;private IndexableInterface $indexable;public function __construct(ObjectPersisterInterface $objectPersister,IndexableInterface $indexable,array $config = [],?LoggerInterface $logger = null) {$this->config = \array_merge(['identifier' => 'id','defer' => false,], $config);$this->indexable = $indexable;$this->objectPersister = $objectPersister;$this->propertyAccessor = PropertyAccess::createPropertyAccessor();if ($logger && $this->objectPersister instanceof ObjectPersister) {$this->objectPersister->setLogger($logger);}}/*** Handler for the "kernel.terminate" and "console.terminate" Symfony events.* These event are subscribed to if the listener is configured to persist asynchronously.*/public function onTerminate(){if ($this->config['defer']) {$this->config['defer'] = false;$this->persistScheduled();$this->config['defer'] = true;}}/*** Looks for new objects that should be indexed.*/public function postPersist(LifecycleEventArgs $eventArgs){$entity = $eventArgs->getObject();if ($this->objectPersister->handlesObject($entity) && $this->isObjectIndexable($entity)) {$this->scheduledForInsertion[] = $entity;}}/*** Looks for objects being updated that should be indexed or removed from the index.*/public function postUpdate(LifecycleEventArgs $eventArgs){$entity = $eventArgs->getObject();if ($this->objectPersister->handlesObject($entity)) {if ($this->isObjectIndexable($entity)) {$this->scheduledForUpdate[] = $entity;} else {// Delete if no longer indexable$this->scheduleForDeletion($entity);}}}/*** Delete objects preRemove instead of postRemove so that we have access to the id. Because this is called* preRemove, first check that the entity is managed by Doctrine.*/public function preRemove(LifecycleEventArgs $eventArgs){$entity = $eventArgs->getObject();if ($this->objectPersister->handlesObject($entity)) {$this->scheduleForDeletion($entity);}}/*** Iterate through scheduled actions before flushing to emulate 2.x behavior.* Note that the ElasticSearch index will fall out of sync with the source* data in the event of a crash during flush.** This method is only called in legacy configurations of the listener.** @deprecated This method should only be called in applications that depend* on the behaviour that entities are indexed regardless of if a* flush is successful*/public function preFlush(){$this->persistScheduled();}/*** Iterating through scheduled actions *after* flushing ensures that the* ElasticSearch index will be affected only if the query is successful.*/public function postFlush(){$this->persistScheduled();}/*** Determines whether or not it is okay to persist now.** @return bool*/private function shouldPersist(){return !$this->config['defer'];}/*** Persist scheduled objects to ElasticSearch* After persisting, clear the scheduled queue to prevent multiple data updates when using multiple flush calls.*/private function persistScheduled(){if ($this->shouldPersist()) {if (\count($this->scheduledForInsertion)) {$this->objectPersister->insertMany($this->scheduledForInsertion);$this->scheduledForInsertion = [];}if (\count($this->scheduledForUpdate)) {$this->objectPersister->replaceMany($this->scheduledForUpdate);$this->scheduledForUpdate = [];}if (\count($this->scheduledForDeletion)) {$this->objectPersister->deleteManyByIdentifiers($this->scheduledForDeletion);$this->scheduledForDeletion = [];}}}/*** Record the specified identifier to delete. Do not need to entire object.** @param object $object*/private function scheduleForDeletion($object){if ($identifierValue = $this->propertyAccessor->getValue($object, $this->config['identifier'])) {$this->scheduledForDeletion[] = !\is_scalar($identifierValue) ? (string) $identifierValue : $identifierValue;}}/*** Checks if the object is indexable or not.** @param object $object** @return bool*/private function isObjectIndexable($object){return $this->indexable->isObjectIndexable($this->config['indexName'],$object);}}