Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Mapper.php
Go to the documentation of this file.
1 <?php
8 
12 
18 class Mapper
19 {
23  private $rootQuery;
24 
28  private $queries;
29 
33  private $filters;
34 
38  private $mappedQueries;
39 
43  private $mappedFilters;
44 
48  private $aggregations;
49 
53  private $objectManager;
54 
58  private $rootQueryName;
59 
70  public function __construct(
71  \Magento\Framework\ObjectManagerInterface $objectManager,
72  array $queries,
73  $rootQueryName,
74  array $aggregations = [],
75  array $filters = []
76  ) {
77  $this->objectManager = $objectManager;
78  $this->queries = $queries;
79  $this->aggregations = $aggregations;
80  $this->filters = $filters;
81  $this->rootQueryName = $rootQueryName;
82  }
83 
92  public function getRootQuery()
93  {
94  if (!$this->rootQuery) {
95  $this->mappedQueries = [];
96  $this->mappedFilters = [];
97  $this->rootQuery = $this->mapQuery($this->rootQueryName);
98  $this->validate();
99  }
100  return $this->rootQuery;
101  }
102 
113  private function mapQuery($queryName)
114  {
115  if (!isset($this->queries[$queryName])) {
116  throw new \Exception('Query ' . $queryName . ' does not exist');
117  } elseif (in_array($queryName, $this->mappedQueries)) {
118  throw new StateException(
119  new Phrase('A cycle was found. The "%1" query is already used in the request hierarchy.', [$queryName])
120  );
121  }
122  $this->mappedQueries[] = $queryName;
123  $query = $this->queries[$queryName];
124  switch ($query['type']) {
126  $query = $this->objectManager->create(
127  \Magento\Framework\Search\Request\Query\Match::class,
128  [
129  'name' => $query['name'],
130  'value' => $query['value'],
131  'boost' => isset($query['boost']) ? $query['boost'] : 1,
132  'matches' => $query['match']
133  ]
134  );
135  break;
137  if (isset($query['queryReference'][0])) {
138  $reference = $this->mapQuery($query['queryReference'][0]['ref']);
139  $referenceType = Filter::REFERENCE_QUERY;
140  } elseif (isset($query['filterReference'][0])) {
141  $reference = $this->mapFilter($query['filterReference'][0]['ref']);
142  $referenceType = Filter::REFERENCE_FILTER;
143  } else {
144  throw new \Exception('Reference is not provided');
145  }
146  $query = $this->objectManager->create(
147  \Magento\Framework\Search\Request\Query\Filter::class,
148  [
149  'name' => $query['name'],
150  'boost' => isset($query['boost']) ? $query['boost'] : 1,
151  'reference' => $reference,
152  'referenceType' => $referenceType
153  ]
154  );
155  break;
157  $aggregatedByType = $this->aggregateQueriesByType($query['queryReference']);
158  $query = $this->objectManager->create(
159  \Magento\Framework\Search\Request\Query\BoolExpression::class,
160  array_merge(
161  ['name' => $query['name'], 'boost' => isset($query['boost']) ? $query['boost'] : 1],
162  $aggregatedByType
163  )
164  );
165  break;
166  default:
167  throw new \InvalidArgumentException('Invalid query type');
168  }
169  return $query;
170  }
171 
182  private function mapFilter($filterName)
183  {
184  if (!isset($this->filters[$filterName])) {
185  throw new \Exception('Filter ' . $filterName . ' does not exist');
186  } elseif (in_array($filterName, $this->mappedFilters)) {
187  throw new StateException(
188  new Phrase(
189  'A cycle was found. The "%1" filter is already used in the request hierarchy.',
190  [$filterName]
191  )
192  );
193  }
194  $this->mappedFilters[] = $filterName;
195  $filter = $this->filters[$filterName];
196  switch ($filter['type']) {
198  $filter = $this->objectManager->create(
199  \Magento\Framework\Search\Request\Filter\Term::class,
200  [
201  'name' => $filter['name'],
202  'field' => $filter['field'],
203  'value' => $filter['value']
204  ]
205  );
206  break;
208  $filter = $this->objectManager->create(
209  \Magento\Framework\Search\Request\Filter\Range::class,
210  [
211  'name' => $filter['name'],
212  'field' => $filter['field'],
213  'from' => isset($filter['from']) ? $filter['from'] : null,
214  'to' => isset($filter['to']) ? $filter['to'] : null
215  ]
216  );
217  break;
219  $filter = $this->objectManager->create(
220  \Magento\Framework\Search\Request\Filter\Wildcard::class,
221  [
222  'name' => $filter['name'],
223  'field' => $filter['field'],
224  'value' => $filter['value']
225  ]
226  );
227  break;
229  $aggregatedByType = $this->aggregateFiltersByType($filter['filterReference']);
230  $filter = $this->objectManager->create(
231  \Magento\Framework\Search\Request\Filter\BoolExpression::class,
232  array_merge(
233  ['name' => $filter['name']],
234  $aggregatedByType
235  )
236  );
237  break;
238  default:
239  throw new \InvalidArgumentException('Invalid filter type');
240  }
241  return $filter;
242  }
243 
250  private function aggregateFiltersByType($data)
251  {
252  $list = [];
253  foreach ($data as $value) {
254  $list[$value['clause']][$value['ref']] = $this->mapFilter($value['ref']);
255  }
256  return $list;
257  }
258 
265  private function aggregateQueriesByType($data)
266  {
267  $list = [];
268  foreach ($data as $value) {
269  $list[$value['clause']][$value['ref']] = $this->mapQuery($value['ref']);
270  }
271  return $list;
272  }
273 
278  private function validate()
279  {
280  $this->validateQueries();
281  $this->validateFilters();
282  }
283 
288  private function validateQueries()
289  {
290  $this->validateNotUsed($this->queries, $this->mappedQueries, 'Query %1 is not used in request hierarchy');
291  }
292 
300  private function validateNotUsed($elements, $mappedElements, $errorMessage)
301  {
302  $allElements = array_keys($elements);
303  $notUsedElements = implode(', ', array_diff($allElements, $mappedElements));
304  if (!empty($notUsedElements)) {
305  throw new StateException(new Phrase($errorMessage, [$notUsedElements]));
306  }
307  }
308 
313  private function validateFilters()
314  {
315  $this->validateNotUsed($this->filters, $this->mappedFilters, 'Filter %1 is not used in request hierarchy');
316  }
317 
324  public function getBuckets()
325  {
326  $buckets = [];
327  foreach ($this->aggregations as $bucketData) {
328  $arguments = [
329  'name' => $bucketData['name'],
330  'field' => $bucketData['field'],
331  'metrics' => $this->mapMetrics($bucketData),
332  ];
333  switch ($bucketData['type']) {
335  $bucket = $this->objectManager->create(
336  \Magento\Framework\Search\Request\Aggregation\TermBucket::class,
337  $arguments
338  );
339  break;
341  $bucket = $this->objectManager->create(
342  \Magento\Framework\Search\Request\Aggregation\RangeBucket::class,
343  array_merge(
344  $arguments,
345  ['ranges' => $this->mapRanges($bucketData)]
346  )
347  );
348  break;
350  $bucket = $this->objectManager->create(
351  \Magento\Framework\Search\Request\Aggregation\DynamicBucket::class,
352  array_merge(
353  $arguments,
354  ['method' => $bucketData['method']]
355  )
356  );
357  break;
358  default:
359  throw new StateException(new Phrase('The bucket type is invalid. Verify and try again.'));
360  break;
361  }
362  $buckets[] = $bucket;
363  }
364  return $buckets;
365  }
366 
373  private function mapMetrics(array $bucketData)
374  {
375  $metricObjects = [];
376  if (isset($bucketData['metric'])) {
377  $metrics = $bucketData['metric'];
378  foreach ($metrics as $metric) {
379  $metricObjects[] = $this->objectManager->create(
380  \Magento\Framework\Search\Request\Aggregation\Metric::class,
381  [
382  'type' => $metric['type']
383  ]
384  );
385  }
386  }
387  return $metricObjects;
388  }
389 
396  private function mapRanges(array $bucketData)
397  {
398  $rangeObjects = [];
399  if (isset($bucketData['range'])) {
400  $ranges = $bucketData['range'];
401  foreach ($ranges as $range) {
402  $rangeObjects[] = $this->objectManager->create(
403  \Magento\Framework\Search\Request\Aggregation\Range::class,
404  [
405  'from' => $range['from'],
406  'to' => $range['to']
407  ]
408  );
409  }
410  }
411  return $rangeObjects;
412  }
413 }
__construct(\Magento\Framework\ObjectManagerInterface $objectManager, array $queries, $rootQueryName, array $aggregations=[], array $filters=[])
Definition: Mapper.php:70
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$objectManager
Definition: bootstrap.php:17
$value
Definition: gender.phtml:16
$arguments