Source of file Indexer.php
Size: 6,894 Bytes - Last Modified: 2021-12-23T10:34:25+00:00
/var/www/docs.ssmods.com/process/src/src/Service/Indexer.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 | <?php namespace SilverStripe\SearchService\Service; use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Injector\Injectable; use SilverStripe\SearchService\Interfaces\DependencyTracker; use SilverStripe\SearchService\Interfaces\DocumentAddHandler; use SilverStripe\SearchService\Interfaces\DocumentInterface; use SilverStripe\SearchService\Interfaces\DocumentRemoveHandler; use SilverStripe\SearchService\Interfaces\IndexingInterface; use InvalidArgumentException; use SilverStripe\SearchService\Service\Traits\ConfigurationAware; use SilverStripe\SearchService\Service\Traits\ServiceAware; class Indexer { use Injectable; use Configurable; use ConfigurationAware; use ServiceAware; const METHOD_DELETE = 0; const METHOD_ADD = 1; /** * @var array */ private static $dependencies = [ 'IndexService' => '%$' . IndexingInterface::class, ]; /** * @var bool */ private $finished = false; /** * @var array */ private $chunks = []; /** * @var DocumentInterface[] */ private $documents = []; /** * @var int */ private $batchSize; /** * @var int */ private $method; /** * @var bool */ private $processDependencies = true; /** * @var bool */ private $isComplete = false; /** * Indexer constructor. * @param array $documents * @param int $method * @param int|null $batchSize */ public function __construct( array $documents = [], int $method = self::METHOD_ADD, ?int $batchSize = null ) { $this->setConfiguration(IndexConfiguration::singleton()); $this->setMethod($method); $this->setBatchSize($batchSize ?: $this->getConfiguration()->getBatchSize()); $this->setProcessDependencies($this->getConfiguration()->shouldTrackDependencies()); $this->setDocuments($documents); } /** * @return void */ public function processNode(): void { $remainingChildren = $this->chunks; $documents = array_shift($remainingChildren); if ($this->method === static::METHOD_DELETE) { $this->getIndexService()->removeDocuments($documents); } else { $toRemove = []; $toUpdate = []; /* @var DocumentInterface $document */ foreach ($documents as $document) { if (!$this->getConfiguration()->isClassIndexed($document->getSourceClass())) { continue; } if ($document->shouldIndex()) { if ($document instanceof DocumentAddHandler) { $document->onAddToSearchIndexes(DocumentAddHandler::BEFORE_ADD); } $toUpdate[] = $document; } else { if ($document instanceof DocumentRemoveHandler) { $document->onRemoveFromSearchIndexes(DocumentRemoveHandler::BEFORE_REMOVE); } $toRemove[] = $document; } } if (!empty($toUpdate)) { $this->getIndexService()->addDocuments($toUpdate); foreach ($toUpdate as $document) { if ($document instanceof DocumentAddHandler) { $document->onAddToSearchIndexes(DocumentAddHandler::AFTER_ADD); } } } if (!empty($toRemove)) { $this->getIndexService()->removeDocuments($toRemove); foreach ($toRemove as $document) { if ($document instanceof DocumentRemoveHandler) { $document->onRemoveFromSearchIndexes(DocumentRemoveHandler::AFTER_REMOVE); } } } } $this->chunks = $remainingChildren; if ($this->processDependencies) { foreach ($documents as $document) { if ($document instanceof DependencyTracker) { $dependentDocs = array_filter( $document->getDependentDocuments(), function (DocumentInterface $dependentDocument) use ($document) { return $dependentDocument->getIdentifier() !== $document->getIdentifier(); } ); if (!empty($dependentDocs)) { $child = Indexer::create($dependentDocs, self::METHOD_ADD, $this->getBatchSize()); while (!$child->finished()) { $child->processNode(); } } } } } if (!count($remainingChildren)) { $this->isComplete = true; return; } } /** * @param $method * @return $this */ public function setMethod($method): Indexer { if (!in_array($method, [self::METHOD_ADD, self::METHOD_DELETE])) { throw new InvalidArgumentException(sprintf( 'Invalid method: %s', $method )); } $this->method = $method; return $this; } /** * @return int */ public function getMethod(): int { return $this->method; } /** * @param bool $processDependencies * @return Indexer */ public function setProcessDependencies(bool $processDependencies): Indexer { $this->processDependencies = $processDependencies; return $this; } /** * @param int $batchSize * @return Indexer */ public function setBatchSize(int $batchSize): Indexer { if ($batchSize < 1) { throw new InvalidArgumentException('Batch size must be greater than 0'); } $this->batchSize = $batchSize; $this->chunks = array_chunk($this->documents, $batchSize); return $this; } /** * @return int */ public function getBatchSize(): int { return $this->batchSize; } /** * @return bool */ public function finished(): bool { return $this->isComplete; } /** * @return int */ public function getChunkCount(): int { return sizeof($this->chunks); } /** * @return DocumentInterface[] */ public function getDocuments(): array { return $this->documents; } /** * @param DocumentInterface[] $documents * @return Indexer */ public function setDocuments(array $documents): Indexer { $this->documents = $documents; $this->chunks = array_chunk($this->documents, $this->getBatchSize()); return $this; } } |