Fulltext.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\CatalogSearch\Model\Indexer;
  7. use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\FullFactory;
  8. use Magento\CatalogSearch\Model\Indexer\Scope\StateFactory;
  9. use Magento\CatalogSearch\Model\ResourceModel\Fulltext as FulltextResource;
  10. use Magento\Framework\Indexer\DimensionProviderInterface;
  11. use Magento\Store\Model\StoreDimensionProvider;
  12. use Magento\Indexer\Model\ProcessManager;
  13. /**
  14. * Provide functionality for Fulltext Search indexing.
  15. *
  16. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  17. *
  18. * @api
  19. * @since 100.0.2
  20. */
  21. class Fulltext implements
  22. \Magento\Framework\Indexer\ActionInterface,
  23. \Magento\Framework\Mview\ActionInterface,
  24. \Magento\Framework\Indexer\DimensionalIndexerInterface
  25. {
  26. /**
  27. * Indexer ID in configuration
  28. */
  29. const INDEXER_ID = 'catalogsearch_fulltext';
  30. /**
  31. * @var array index structure
  32. */
  33. protected $data;
  34. /**
  35. * @var IndexerHandlerFactory
  36. */
  37. private $indexerHandlerFactory;
  38. /**
  39. * @var \Magento\CatalogSearch\Model\Indexer\Fulltext\Action\Full
  40. */
  41. private $fullAction;
  42. /**
  43. * @var FulltextResource
  44. */
  45. private $fulltextResource;
  46. /**
  47. * @var IndexSwitcherInterface
  48. */
  49. private $indexSwitcher;
  50. /**
  51. * @var \Magento\CatalogSearch\Model\Indexer\Scope\State
  52. */
  53. private $indexScopeState;
  54. /**
  55. * @var DimensionProviderInterface
  56. */
  57. private $dimensionProvider;
  58. /**
  59. * @var ProcessManager
  60. */
  61. private $processManager;
  62. /**
  63. * @param FullFactory $fullActionFactory
  64. * @param IndexerHandlerFactory $indexerHandlerFactory
  65. * @param FulltextResource $fulltextResource
  66. * @param IndexSwitcherInterface $indexSwitcher
  67. * @param StateFactory $indexScopeStateFactory
  68. * @param DimensionProviderInterface $dimensionProvider
  69. * @param array $data
  70. * @param ProcessManager $processManager
  71. */
  72. public function __construct(
  73. FullFactory $fullActionFactory,
  74. IndexerHandlerFactory $indexerHandlerFactory,
  75. FulltextResource $fulltextResource,
  76. IndexSwitcherInterface $indexSwitcher,
  77. StateFactory $indexScopeStateFactory,
  78. DimensionProviderInterface $dimensionProvider,
  79. array $data,
  80. ProcessManager $processManager = null
  81. ) {
  82. $this->fullAction = $fullActionFactory->create(['data' => $data]);
  83. $this->indexerHandlerFactory = $indexerHandlerFactory;
  84. $this->fulltextResource = $fulltextResource;
  85. $this->data = $data;
  86. $this->indexSwitcher = $indexSwitcher;
  87. $this->indexScopeState = $indexScopeStateFactory->create();
  88. $this->dimensionProvider = $dimensionProvider;
  89. $this->processManager = $processManager ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
  90. ProcessManager::class
  91. );
  92. }
  93. /**
  94. * Execute materialization on ids entities
  95. *
  96. * @param int[] $entityIds
  97. * @return void
  98. * @throws \InvalidArgumentException
  99. */
  100. public function execute($entityIds)
  101. {
  102. foreach ($this->dimensionProvider->getIterator() as $dimension) {
  103. $this->executeByDimensions($dimension, new \ArrayIterator($entityIds));
  104. }
  105. }
  106. /**
  107. * @inheritdoc
  108. *
  109. * @throws \InvalidArgumentException
  110. * @since 101.0.0
  111. */
  112. public function executeByDimensions(array $dimensions, \Traversable $entityIds = null)
  113. {
  114. if (count($dimensions) > 1 || !isset($dimensions[StoreDimensionProvider::DIMENSION_NAME])) {
  115. throw new \InvalidArgumentException('Indexer "' . self::INDEXER_ID . '" support only Store dimension');
  116. }
  117. $storeId = $dimensions[StoreDimensionProvider::DIMENSION_NAME]->getValue();
  118. $saveHandler = $this->indexerHandlerFactory->create([
  119. 'data' => $this->data
  120. ]);
  121. if (null === $entityIds) {
  122. $this->indexScopeState->useTemporaryIndex();
  123. $saveHandler->cleanIndex($dimensions);
  124. $saveHandler->saveIndex($dimensions, $this->fullAction->rebuildStoreIndex($storeId));
  125. $this->indexSwitcher->switchIndex($dimensions);
  126. $this->indexScopeState->useRegularIndex();
  127. $this->fulltextResource->resetSearchResultsByStore($storeId);
  128. } else {
  129. // internal implementation works only with array
  130. $entityIds = iterator_to_array($entityIds);
  131. $productIds = array_unique(
  132. array_merge($entityIds, $this->fulltextResource->getRelationsByChild($entityIds))
  133. );
  134. if ($saveHandler->isAvailable($dimensions)) {
  135. $saveHandler->deleteIndex($dimensions, new \ArrayIterator($productIds));
  136. $saveHandler->saveIndex($dimensions, $this->fullAction->rebuildStoreIndex($storeId, $productIds));
  137. }
  138. }
  139. }
  140. /**
  141. * Execute full indexation
  142. *
  143. * @return void
  144. * @throws \InvalidArgumentException
  145. */
  146. public function executeFull()
  147. {
  148. $userFunctions = [];
  149. foreach ($this->dimensionProvider->getIterator() as $dimension) {
  150. $userFunctions[] = function () use ($dimension) {
  151. $this->executeByDimensions($dimension);
  152. };
  153. }
  154. $this->processManager->execute($userFunctions);
  155. }
  156. /**
  157. * Execute partial indexation by ID list
  158. *
  159. * @param int[] $ids
  160. * @return void
  161. */
  162. public function executeList(array $ids)
  163. {
  164. $this->execute($ids);
  165. }
  166. /**
  167. * Execute partial indexation by ID
  168. *
  169. * @param int $id
  170. * @return void
  171. */
  172. public function executeRow($id)
  173. {
  174. $this->execute([$id]);
  175. }
  176. }