Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
IndexerHandler.php
Go to the documentation of this file.
1 <?php
7 
15 
20 {
24  protected $dataTypes = ['searchable', 'filterable'];
25 
29  protected $indexStructure;
30 
34  protected $data;
35 
39  protected $fields;
40 
44  protected $resource;
45 
49  protected $batch;
50 
54  protected $batchSize;
55 
59  protected $scopeResolvers;
60 
65  protected $connection;
66 
76  public function __construct(
79  Batch $batch,
80  IndexScopeResolver $indexScopeResolver,
81  FlatScopeResolver $flatScopeResolver,
82  array $data,
83  $batchSize = 100
84  ) {
85  $this->indexStructure = $indexStructure;
86  $this->resource = $resource;
87  $this->connection = $resource->getConnection();
88  $this->batch = $batch;
89  $this->scopeResolvers[$this->dataTypes[0]] = $indexScopeResolver;
90  $this->scopeResolvers[$this->dataTypes[1]] = $flatScopeResolver;
91  $this->data = $data;
92  $this->batchSize = $batchSize;
93 
94  $this->fields = [];
95  $this->prepareFields();
96  }
97 
101  public function saveIndex($dimensions, \Traversable $documents)
102  {
103  foreach ($this->batch->getItems($documents, $this->batchSize) as $batchDocuments) {
104  $this->insertDocumentsForSearchable($batchDocuments, $dimensions);
105  $this->insertDocumentsForFilterable($batchDocuments, $dimensions);
106  }
107  }
108 
112  public function deleteIndex($dimensions, \Traversable $documents)
113  {
114  foreach ($this->dataTypes as $dataType) {
115  foreach ($this->batch->getItems($documents, $this->batchSize) as $batchDocuments) {
116  $documentsId = array_column($batchDocuments, 'id');
117  $this->connection->delete($this->getTableName($dataType, $dimensions), ['id' => $documentsId]);
118  }
119  }
120  }
121 
125  public function cleanIndex($dimensions)
126  {
127  $this->indexStructure->delete($this->getIndexName(), $dimensions);
128  $this->indexStructure->create($this->getIndexName(), $this->fields, $dimensions);
129  }
130 
134  public function isAvailable($dimensions = [])
135  {
136  return true;
137  }
138 
146  protected function getTableName($dataType, $dimensions)
147  {
148  return $this->scopeResolvers[$dataType]->resolve($this->getIndexName(), $dimensions);
149  }
150 
156  protected function getIndexName()
157  {
158  return $this->data['indexer_id'];
159  }
160 
168  private function insertDocumentsForSearchable(array $documents, array $dimensions)
169  {
170  $this->connection->insertOnDuplicate(
171  $this->getTableName($this->dataTypes[0], $dimensions),
172  $this->prepareSearchableFields($documents),
173  ['data_index']
174  );
175  }
176 
184  protected function insertDocumentsForFilterable(array $documents, array $dimensions)
185  {
186  $onDuplicate = [];
187  foreach ($this->fields as $field) {
188  if ($field['type'] === $this->dataTypes[1]) {
189  $onDuplicate[] = $field['name'];
190  }
191  }
192 
193  $this->connection->insertOnDuplicate(
194  $this->getTableName($this->dataTypes[1], $dimensions),
195  $this->prepareFilterableFields($documents),
196  $onDuplicate
197  );
198  }
199 
206  protected function prepareFilterableFields(array $documents)
207  {
208  $insertDocuments = [];
209  foreach ($documents as $entityId => $document) {
210  $documentFlat = ['entity_id' => $entityId];
211  foreach ($this->fields as $field) {
212  if ($field['type'] == $this->dataTypes[1]) {
213  $documentFlat[$field['name']] = $document[$field['name']];
214  }
215  }
216  $insertDocuments[] = $documentFlat;
217  }
218  return $insertDocuments;
219  }
220 
227  private function prepareSearchableFields(array $documents)
228  {
229  $insertDocuments = [];
230  foreach ($documents as $entityId => $document) {
231  foreach ($this->fields as $field) {
232  if ($field['type'] === $this->dataTypes[0]) {
233  $insertDocuments[] = [
234  'entity_id' => $entityId,
235  'attribute_id' => $field['name'],
236  'data_index' => $document[$field['name']],
237  ];
238  }
239  }
240  }
241 
242  return $insertDocuments;
243  }
244 
250  private function prepareFields()
251  {
252  foreach ($this->data['fieldsets'] as $fieldset) {
253  $this->fields = array_merge($this->fields, array_values($fieldset['fields']));
254  }
255  }
256 }
saveIndex($dimensions, \Traversable $documents)
deleteIndex($dimensions, \Traversable $documents)
insertDocumentsForFilterable(array $documents, array $dimensions)
__construct(IndexStructureInterface $indexStructure, ResourceConnection $resource, Batch $batch, IndexScopeResolver $indexScopeResolver, FlatScopeResolver $flatScopeResolver, array $data, $batchSize=100)