Completed
Pull Request — develop (#25)
by
unknown
01:52
created

Query::convertBiasing()   C

Complexity

Conditions 7
Paths 34

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 29
rs 6.7272
cc 7
eloc 17
nc 34
nop 1
1
<?php
2
3
namespace GroupByInc\API;
4
5
use GroupByInc\API\Model\Bias as MBias;
6
use GroupByInc\API\Model\Biasing as MBiasing;
7
use GroupByInc\API\Model\CustomUrlParam;
8
use GroupByInc\API\Model\MatchStrategy as MMatchStrategy;
9
use GroupByInc\API\Model\Navigation;
10
use GroupByInc\API\Model\NumericBoost as MNumericBoost;
11
use GroupByInc\API\Model\PartialMatchRule as MPartialMatchRule;
12
use GroupByInc\API\Model\Refinement;
13
use GroupByInc\API\Model\Refinement\Type;
14
use GroupByInc\API\Model\RefinementRange;
15
use GroupByInc\API\Model\RefinementValue;
16
use GroupByInc\API\Model\Sort as MSort;
17
use GroupByInc\API\Request\Bias;
18
use GroupByInc\API\Request\Biasing;
19
use GroupByInc\API\Request\MatchStrategy as RMatchStrategy;
20
use GroupByInc\API\Request\NumericBoost as RNumericBoost;
21
use GroupByInc\API\Request\PartialMatchRule as RPartialMatchRule;
22
use GroupByInc\API\Request\RefinementsRequest;
23
use GroupByInc\API\Request\Request;
24
use GroupByInc\API\Request\RestrictNavigation;
25
use GroupByInc\API\Request\SelectedRefinement;
26
use GroupByInc\API\Request\SelectedRefinementRange;
27
use GroupByInc\API\Request\SelectedRefinementValue;
28
use GroupByInc\API\Request\Sort as RSort;
29
use GroupByInc\API\Util\SerializerFactory;
30
use GroupByInc\API\Util\StringBuilder;
31
use GroupByInc\API\Util\StringUtils;
32
use JMS\Serializer\Serializer;
33
use RuntimeException;
34
35
class Symbol
36
{
37
  const TILDE = "~";
38
  const DOT = ".";
39
  const DOUBLE_DOT = "..";
40
  const EQUAL = "=";
41
  const COLON = ":";
42
  const AMPERSAND = "&";
43
  const SLASH = "/";
44
}
45
46
class Query
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
47
{
48
  /** @var string */
49
  private $userId;
50
  /** @var string */
51
  private $query;
52
  /** @var int */
53
  private $skip = 0;
54
  /** @var int */
55
  private $pageSize = 10;
56
  /** @var string */
57
  private $collection;
58
  /** @var string */
59
  private $area;
60
  /** @var string */
61
  private $biasingProfile;
62
  /** @var string */
63
  private $language;
64
  /** @var MSort[] */
65
  private $sort;
66
  /** @var CustomUrlParam[] */
67
  private $customUrlParams = array();
68
  /** @var Navigation[] */
69
  private $navigations = array();
70
  /** @var string[] */
71
  private $includedNavigations = array();
72
  /** @var string[] */
73
  private $excludedNavigations = array();
74
  /** @var string[] */
75
  private $fields = array();
76
  /** @var string[] */
77
  private $orFields = array();
78
  /** @var bool */
79
  private $pruneRefinements = true;
80
  /** @var bool */
81
  private $disableAutocorrection = false;
82
  /** @var bool */
83
  private $wildcardSearchEnabled = false;
84
  // Removed until CBOR support for serialization / de-serialization improves
85
//    /** @var bool */
86
//    private $returnBinary = false;
87
  /** @var RestrictNavigation */
88
  private $restrictNavigation;
89
  /** @var MBiasing */
90
  private $biasing;
91
92
  /** @var Serializer */
93
  private $serializer;
94
95
  const TILDE_REGEX = "/~((?=[\\w]*[=:]))/";
96
97
  /**
98
   * @param mixed $request
99
   *
100
   * @return string
101
   */
102
  private function requestToJson($request)
103
  {
104
    $jsonRequest = null;
105
    try {
106
      $jsonRequest = $this->serializer->serialize($request, 'json');
107
    } catch (RuntimeException $e) {
108
      throw new RuntimeException('Unable to serialize request ' . var_dump($request));
0 ignored issues
show
Security Debugging Code introduced by
var_dump($request); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
109
    }
110
111
    return $jsonRequest;
112
  }
113
114
  /**
115
   * @param string $clientKey Your client key.
116
   *
117
   * @return string JSON representation of request to Bridge.
118
   */
119
  public function getBridgeJson($clientKey)
120
  {
121
    $data = $this->populateRequest($clientKey);
122
    return $this->requestToJson($data);
123
  }
124
125
  /**
126
   * @param string $clientKey      Your client key.
127
   * @param string $navigationName Name of the navigation to get refinements for
128
   *
129
   * @return string JSON representation of request to Bridge.
130
   */
131
  public function getBridgeRefinementsJson($clientKey, $navigationName)
132
  {
133
    $data = new RefinementsRequest();
134
    $data->originalQuery = $this->populateRequest($clientKey);
135
    $data->navigationName = $navigationName;
136
    return $this->requestToJson($data);
137
  }
138
139
  /**
140
   * @param string $clientKey
141
   *
142
   * @return Request
143
   */
144
  private function populateRequest($clientKey)
145
  {
146
    $request = new Request();
147
    $request->clientKey = $clientKey;
148
    $request->area = $this->area;
149
    $request->collection = $this->collection;
150
    $request->userId = $this->userId;
151
    $request->query = $this->query;
152
    $request->fields = $this->fields;
153
    $request->orFields = $this->orFields;
154
    $request->language = $this->language;
155
    $request->biasingProfile = $this->biasingProfile;
156
    $request->pageSize = $this->pageSize;
157
    $request->skip = $this->skip;
158
    $request->customUrlParams = $this->customUrlParams;
159
    $request->refinements = $this->generateSelectedRefinements($this->navigations);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->generateSelectedR...nts($this->navigations) of type array<integer,object<Gro...\API\Model\Refinement>> is incompatible with the declared type array<integer,object<Gro...st\SelectedRefinement>> of property $refinements.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
160
    $request->restrictNavigation = $this->restrictNavigation;
161
162
    if (!empty($this->biasing)) {
163
      $request->biasing = self::convertBiasing($this->biasing);
164
    }
165
166
    if (!empty($this->includedNavigations)) {
167
      $request->includedNavigations = $this->includedNavigations;
168
    }
169
170
    if (!empty($this->excludedNavigations)) {
171
      $request->excludedNavigations = $this->excludedNavigations;
172
    }
173
174
    $pruneRefinements = $this->pruneRefinements;
175
    if (isset($pruneRefinements) && $pruneRefinements === false) {
176
      $request->pruneRefinements = false;
177
    }
178
179
    $disableAutocorrection = $this->disableAutocorrection;
180
    if (isset($disableAutocorrection) && $disableAutocorrection === true) {
181
      $request->disableAutocorrection = true;
182
    }
183
184
    $wildcardSearchEnabled = $this->wildcardSearchEnabled;
185
    if (isset($wildcardSearchEnabled) && $wildcardSearchEnabled === true) {
186
      $request->wildcardSearchEnabled = true;
187
    }
188
189
    if (!empty($this->sort)) {
190
      foreach ($this->sort as $s) {
191
        array_push($request->sort, $this->convertSort($s));
192
      }
193
    }
194
195
//        $returnBinary = $this->returnBinary;
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
196
//        if (isset($returnBinary) && $returnBinary === true) {
197
//            $request->returnBinary = true;
198
//        }
199
200
    return $request;
201
  }
202
203
  /**
204
   * @param Navigation[] $navigations
205
   *
206
   * @return Refinement[]
207
   */
208
  private function generateSelectedRefinements($navigations)
209
  {
210
    $refinements = [];
211
    foreach ($navigations as $key => $navigation) {
212
      foreach ($navigation->getRefinements() as $refinement) {
213
        switch ($refinement->getType()) {
214
          case Type::Range: {
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
215
            /** @var RefinementRange $rr */
216
            $rr = $refinement;
217
            $selectedRefinementRange = new SelectedRefinementRange();
218
            $selectedRefinementRange
219
                ->setNavigationName($navigation->getName())
220
                ->setLow($rr->getLow())
221
                ->setHigh($rr->getHigh())
222
                ->setExclude($rr->isExclude());
223
224
            array_push($refinements, $selectedRefinementRange);
225
            break;
226
          }
227
          case Type::Value: {
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
228
            /** @var RefinementValue $rv */
229
            $rv = $refinement;
230
            $selectedRefinementValue = new SelectedRefinementValue();
231
            $selectedRefinementValue
232
                ->setNavigationName($navigation->getName())
233
                ->setValue($rv->getValue())
234
                ->setExclude($rv->isExclude());
235
236
            array_push($refinements, $selectedRefinementValue);
237
            break;
238
          }
239
        }
240
      }
241
    }
242
    return $refinements;
243
  }
244
245
  /**
246
   * @param string $clientKey Your client key.
247
   *
248
   * @return string JSON representation of request to Bridge.
249
   */
250
  public function getBridgeJsonRefinementSearch($clientKey)
251
  {
252
    $data = new Request();
253
    $data->clientKey = $clientKey;
254
    $data->collection = $this->collection;
255
    $data->area = $this->area;
256
    $data->refinementQuery = $this->query;
257
258
    $wildcardSearchEnabled = $this->wildcardSearchEnabled;
259
    if (isset($wildcardSearchEnabled) && $wildcardSearchEnabled === true) {
260
      $data->wildcardSearchEnabled = true;
261
    }
262
263
    return $this->requestToJson($data);
264
  }
265
266
  public function __construct()
267
  {
268
    $this->serializer = SerializerFactory::build();
269
  }
270
271
  /**
272
   * @return string The current search string.
273
   */
274
  public function getQuery()
275
  {
276
    return $this->query;
277
  }
278
279
  /**
280
   * @param string $query The search string.
281
   */
282
  public function setQuery($query)
283
  {
284
    $this->query = $query;
285
  }
286
287
  /**
288
   * @return string The data sub-collection.
289
   */
290
  public function getCollection()
291
  {
292
    return $this->collection;
293
  }
294
295
  /**
296
   * @param string $collection The string representation of a collection query.
297
   */
298
  public function setCollection($collection)
299
  {
300
    $this->collection = $collection;
301
  }
302
303
  /**
304
   * @return string The area name.
305
   */
306
  public function getArea()
307
  {
308
    return $this->area;
309
  }
310
311
  /**
312
   * @param string $area The area name.
313
   */
314
  public function setArea($area)
315
  {
316
    $this->area = $area;
317
  }
318
319
  /**
320
   * @return string[] A list of metadata fields that will be returned by the search engine.
321
   */
322
  public function getFields()
323
  {
324
    return $this->fields;
325
  }
326
327
  /**
328
   * @return string[] A list of the fields that the search service will treat as OR'able.
329
   */
330
  public function getOrFields()
331
  {
332
    return $this->orFields;
333
  }
334
335
  /**
336
   * @param string[] $fields A list of case-sensitive names of the attributes to return.
337
   */
338
  public function addFields($fields)
339
  {
340
    $this->fields = array_merge($this->fields, $fields);
341
  }
342
343
  /**
344
   * @return string[] A list of which navigations to return from the bridge.
345
   */
346
  public function getIncludedNavigations()
347
  {
348
    return $this->includedNavigations;
349
  }
350
351
  /**
352
   * @param string[] $navigations A list of which navigations to return from the bridge.
353
   */
354
  public function addIncludedNavigations($navigations)
355
  {
356
    $this->includedNavigations = array_merge($this->includedNavigations, $navigations);
357
  }
358
359
  /**
360
   * @return string[] A list of which navigations to not return from the bridge.
361
   */
362
  public function getExcludedNavigations()
363
  {
364
    return $this->excludedNavigations;
365
  }
366
367
  /**
368
   * @param string[] $navigations A list of which navigations to not return from the bridge.
369
   */
370
  public function addExcludedNavigations($navigations)
371
  {
372
    $this->excludedNavigations = array_merge($this->excludedNavigations, $navigations);
373
  }
374
375
  /**
376
   * @return Navigation[]
377
   */
378
  public function &getNavigations()
379
  {
380
    return $this->navigations;
381
  }
382
383
  /**
384
   * @param Navigation[] $navigations
385
   */
386
  public function setNavigations($navigations)
387
  {
388
    $this->navigations = $navigations;
389
  }
390
391
  /**
392
   * @param string $name The case-sensitive name of the attribute to return.
393
   */
394
  public function addField($name)
395
  {
396
    array_push($this->fields, $name);
397
  }
398
399
  /**
400
   * @param string $name Field that should be treated as OR.
401
   */
402
  public function addOrField($name)
403
  {
404
    array_push($this->orFields, $name);
405
  }
406
407
  /**
408
   * @param string[] $fields A list of fields that should be treated as OR.
409
   */
410
  public function addOrFields($fields)
411
  {
412
    $this->orFields = array_merge($this->orFields, $fields);
413
  }
414
415
  /**
416
   * @param string $name  The parameter name.
417
   * @param string $value The parameter value.
418
   */
419
  public function addCustomUrlParamByName($name, $value)
420
  {
421
    $param = new CustomUrlParam();
422
    $this->addCustomUrlParam($param->setKey($name)->setValue($value));
423
  }
424
425
  /**
426
   * @param CustomUrlParam $param Set an additional parameter that can be used to trigger rules.
427
   */
428
  public function addCustomUrlParam($param)
429
  {
430
    array_push($this->customUrlParams, $param);
431
  }
432
433
  public function splitRefinements($refinementString)
434
  {
435
    if (StringUtils::isNotBlank($refinementString)) {
436
      return preg_split(self::TILDE_REGEX, $refinementString, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
437
    }
438
    return [];
439
  }
440
441
  /**
442
   * @param string $refinementString A tilde separated list of refinements.
443
   */
444
  public function addRefinementsByString($refinementString)
445
  {
446
    if ($refinementString == null) {
447
      return;
448
    }
449
450
    $refinementStrings = self::splitRefinements($refinementString);
451
    foreach ($refinementStrings as $refinementString) {
452
      if (empty($refinementString) || "=" == $refinementString) {
453
        continue;
454
      }
455
      $colon = strpos($refinementString, Symbol::COLON);
456
      $equals = strpos($refinementString, Symbol::EQUAL);
457
      //when === false, it means it did not find the substring in the string
458
      $isRange = !($colon === false) && ($equals === false);
459
460
      $refinement = null;
0 ignored issues
show
Unused Code introduced by
$refinement is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
461
      if ($isRange) {
462
        $nameValue = explode(Symbol::COLON, $refinementString, 2);
463
        $refinement = new RefinementRange();
464
        if (StringUtils::endsWith($nameValue[1], Symbol::DOUBLE_DOT)) {
465
          $value = explode(Symbol::DOUBLE_DOT, $nameValue[1]);
466
          $refinement->setLow($value[0]);
467
          $refinement->setHigh("");
468
        } else if (StringUtils::startsWith($nameValue[1], Symbol::DOUBLE_DOT)) {
469
          $refinement->setLow("");
470
          $value = explode(Symbol::DOUBLE_DOT, $nameValue[1]);
471
          $refinement->setHigh($value[1]);
472
        } else {
473
          $lowHigh = explode(Symbol::DOUBLE_DOT, $nameValue[1]);
474
          $refinement->setLow($lowHigh[0]);
475
          $refinement->setHigh($lowHigh[1]);
476
        }
477
      } else {
478
        $nameValue = explode(Symbol::EQUAL, $refinementString, 2);
479
        $refinement = new RefinementValue();
480
        $refinement->setValue($nameValue[1]);
481
      }
482
      if (!empty($nameValue[0])) {
483
        $this->addRefinement($nameValue[0], $refinement);
484
      }
485
    }
486
  }
487
488
  /**
489
   * @param string     $navigationName The name of the Navigation.
490
   * @param Refinement $refinement     A RefinementRange or RefinementValue object.
491
   */
492
  public function addRefinement($navigationName, $refinement)
493
  {
494
    $navigation = null;
0 ignored issues
show
Unused Code introduced by
$navigation is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
495
    if (array_key_exists($navigationName, $this->navigations)) {
496
      $navigation = $this->navigations[$navigationName];
497
    } else {
498
      $navigation = new Navigation();
499
      $navigation->setName($navigationName)->setRange($refinement instanceof SelectedRefinementRange);
500
      $this->navigations[$navigationName] = $navigation;
501
    }
502
    $refinements = $navigation->getRefinements();
503
    array_push($refinements, $refinement);
504
    $navigation->setRefinements($refinements);
505
  }
506
507
  /**
508
   * @param string $navigationName The name of the refinement.
509
   * @param mixed  $low            The low value.
510
   * @param mixed  $high           The high value.
511
   * @param bool   $exclude        True if the results should exclude this range refinement, false otherwise.
512
   */
513
  public function addRangeRefinement($navigationName, $low, $high, $exclude = false)
514
  {
515
    $refinement = new RefinementRange();
516
    $this->addRefinement($navigationName, $refinement->setLow($low)->setHigh($high)->setExclude($exclude));
517
  }
518
519
  /**
520
   * @param string $navigationName The name of the refinement.
521
   * @param mixed  $value          The refinement value.
522
   * @param bool   $exclude        True if the results should exclude this value refinement, false otherwise.
523
   */
524
  public function addValueRefinement($navigationName, $value, $exclude = false)
525
  {
526
    $refinement = new RefinementValue();;
527
    $this->addRefinement($navigationName, $refinement->setValue($value)->setExclude($exclude));
528
  }
529
530
  /**
531
   * @return bool Are refinements with zero counts being removed.
532
   */
533
  public function isPruneRefinements()
534
  {
535
    return $this->pruneRefinements;
536
  }
537
538
  /**
539
   * @param bool $pruneRefinements Specifies whether refinements should be pruned.
540
   */
541
  public function setPruneRefinements($pruneRefinements)
542
  {
543
    $this->pruneRefinements = $pruneRefinements;
544
  }
545
546
  /**
547
   * @return MSort[] The current list of sort parameters.
548
   */
549
  public function &getSort()
550
  {
551
    return $this->sort;
552
  }
553
554
  /**
555
   * @param MSort[] $sort Any number of sort criteria.
556
   */
557
  public function setSort($sort)
558
  {
559
    $this->sort = $sort;
560
  }
561
562
  /**
563
   * @return int The number of documents to skip.
564
   */
565
  public function getSkip()
566
  {
567
    return $this->skip;
568
  }
569
570
  /**
571
   * @param int $skip The number of documents to skip.
572
   */
573
  public function setSkip($skip)
574
  {
575
    $this->skip = $skip;
576
  }
577
578
  /**
579
   * @return CustomUrlParam[] A list of custom url params.
580
   */
581
  public function getCustomUrlParams()
582
  {
583
    return $this->customUrlParams;
584
  }
585
586
  /**
587
   * @param CustomUrlParam[] $customUrlParams Set the custom url params.
588
   */
589
  public function setCustomUrlParams($customUrlParams)
590
  {
591
    $this->customUrlParams = $customUrlParams;
592
  }
593
594
//    /**
595
//     * @return bool Is return JSON set to true.
596
//     */
597
//    public function isReturnBinary()
598
//    {
599
//        return $this->returnBinary;
600
//    }
601
//
602
//    /**
603
//     * @param bool $returnBinary Whether to tell the bridge to return binary data rather than JSON.
604
//     */
605
//    public function setReturnBinary($returnBinary)
606
//    {
607
//        $this->returnBinary = $returnBinary;
608
//    }
609
610
  /**
611
   * @return string The current language restrict value.
612
   */
613
  public function getLanguage()
614
  {
615
    return $this->language;
616
  }
617
618
  /**
619
   * @param string $language The value for language restrict.
620
   */
621
  public function setLanguage($language)
622
  {
623
    $this->language = $language;
624
  }
625
626
  /**
627
   * @return string The current biasing profile name.
628
   */
629
  public function getBiasingProfile()
630
  {
631
    return $this->biasingProfile;
632
  }
633
634
  /**
635
   * @param string $biasingProfile Override the biasing profile used for this query.
636
   */
637
  public function setBiasingProfile($biasingProfile)
638
  {
639
    $this->biasingProfile = $biasingProfile;
640
  }
641
642
  /**
643
   * @return int The current page size.
644
   */
645
  public function getPageSize()
646
  {
647
    return $this->pageSize;
648
  }
649
650
  /**
651
   * @param int $pageSize The number of records to return with the query.
652
   */
653
  public function setPageSize($pageSize)
654
  {
655
    $this->pageSize = $pageSize;
656
  }
657
658
  /**
659
   * @return boolean
660
   */
661
  public function isDisableAutocorrection()
662
  {
663
    return $this->disableAutocorrection;
664
  }
665
666
  /**
667
   * @param boolean $disableAutocorrection Specifies whether the auto-correction behavior should be disabled.
668
   *                                       By default, when no results are returned for the given query (and there is
669
   *                                       a did-you-mean available), the first did-you-mean is automatically queried
670
   *                                       instead.
671
   */
672
  public function setDisableAutocorrection($disableAutocorrection)
673
  {
674
    $this->disableAutocorrection = $disableAutocorrection;
675
  }
676
677
  /**
678
   * @return boolean
679
   */
680
  public function isWildcardSearchEnabled()
681
  {
682
    return $this->wildcardSearchEnabled;
683
  }
684
685
  /**
686
   * @param boolean $wildcardSearchEnabled Indicate if the *(star) character in the search string should be treated
687
   *                                       as a wildcard prefix search. For example, `sta*` will match `star` and
688
   *                                       `start`.
689
   */
690
  public function setWildcardSearchEnabled($wildcardSearchEnabled)
691
  {
692
    $this->wildcardSearchEnabled = $wildcardSearchEnabled;
693
  }
694
695
  /**
696
   * <b>Warning</b>  This will count as two queries against your search index.
697
   *
698
   * Typically, this feature is used when you have a large number of navigation items that will overwhelm the end
699
   * user. It works by using one of the existing navigation items to decide what the query is about and fires a second
700
   * query to restrict the navigation to the most relevant set of navigation items for this search term.
701
   *
702
   * For example, if you pass in a search of `paper` and a restrict navigation of `category:2`
703
   *
704
   * The bridge will find the category navigation refinements in the first query and fire a second query for the top 2
705
   * most populous categories.  Therefore, a search for something generic like "paper" will bring back top category
706
   * matches like copy paper (1,030), paper pads (567).  The bridge will fire off the second query with the search
707
   * term, plus an OR refinement with the most likely categories.  The navigation items in the first query are
708
   * entirely replaced with the navigation items in the second query, except for the navigation that was used for the
709
   * restriction so that users still have the ability to navigate by all category types.
710
   *
711
   * @param RestrictNavigation $restrictNavigation Restriction criteria
712
   */
713
  public function setRestrictNavigation($restrictNavigation)
714
  {
715
    $this->restrictNavigation = $restrictNavigation;
716
  }
717
718
  /** @return RestrictNavigation */
719
  public function getRestrictNavigation()
720
  {
721
    return $this->restrictNavigation;
722
  }
723
724
  /**
725
   * @return MBiasing
726
   */
727
  public function getBiasing()
728
  {
729
    return $this->biasing;
730
  }
731
732
  /**
733
   * Add a biasing profile, which is defined at query time.
734
   *
735
   * @param MBiasing $biasing
736
   */
737
  public function setBiasing($biasing)
738
  {
739
    $this->biasing = $biasing;
740
  }
741
742
  /**
743
   * @param string[] $bringToTop
744
   */
745
  public function setBringToTop($bringToTop)
746
  {
747
    if (empty($this->biasing)) {
748
      $this->biasing = new MBiasing();
749
    }
750
    $this->biasing->setBringToTop($bringToTop);
751
  }
752
753
  /**
754
   * @param boolean $augment
755
   */
756
  public function setBiasingAugment($augment)
757
  {
758
    if (empty($this->biasing)) {
759
      $this->biasing = new MBiasing();
760
    }
761
    $this->biasing->setAugmentbiases($augment);
762
  }
763
764
  /**
765
   * @param float $influence
766
   */
767
  public function setInfluence($influence)
768
  {
769
    if (empty($this->biasing)) {
770
      $this->biasing = new MBiasing();
771
    }
772
    $this->biasing->setInfluence($influence);
773
  }
774
775
  /**
776
   * @return string A string representation of all of the currently set refinements.
777
   */
778 View Code Duplication
  public function getRefinementString()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
779
  {
780
    if (!empty($this->navigations)) {
781
      $builder = new StringBuilder();
782
      foreach ($this->navigations as $n) {
783
        foreach ($n->getRefinements() as $r) {
784
          $builder->append(Symbol::TILDE)->append($n->getName())->append($r->toTildeString());
785
        }
786
      }
787
      if ($builder->length() > 0) {
788
        return $builder->__toString();
789
      }
790
    }
791
    return null;
792
  }
793
794
  /**
795
   * @return string A string representation of all of the currently set custom url parameters.
796
   */
797 View Code Duplication
  public function getCustomUrlParamsString()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
798
  {
799
    if (!empty($this->customUrlParams)) {
800
      $builder = new StringBuilder();
801
      foreach ($this->customUrlParams as $c) {
802
        $builder->append(Symbol::TILDE)->append($c->getKey())->append(Symbol::EQUAL)->append($c->getValue());
803
      }
804
      if ($builder->length() > 0) {
805
        return $builder->__toString();
806
      }
807
    }
808
    return null;
809
  }
810
811
  /**
812
   * @param MSort $sort
813
   *
814
   * @return RSort
815
   */
816
  protected static function convertSort($sort)
817
  {
818
    /** @var RSort $convertedSort */
819
    $convertedSort = null;
820
    if (!empty($sort)) {
821
      $convertedSort = new RSort();
822
      $convertedSort->setField($sort->getField());
823
      switch ($sort->getOrder()) {
824
        case MSort\Order::Ascending:
825
          $convertedSort->setOrder(RSort\Order::Ascending);
826
          break;
827
        case MSort\Order::Descending:
828
          $convertedSort->setOrder(RSort\Order::Descending);
829
          break;
830
      }
831
    }
832
    return $convertedSort;
833
  }
834
835
  /**
836
   * @param MMatchStrategy $strategy
837
   *
838
   * @return RMatchStrategy
839
   */
840
  protected static function convertPartialMatchStrategy($strategy)
841
  {
842
    /** @var RMatchStrategy $convertedStrategy */
843
    $convertedStrategy = null;
844
    if (!empty($strategy)) {
845
      $rules = $strategy->getRules();
846
      if (!empty($rules)) {
847
        $convertedStrategy = new RMatchStrategy();
848
        /** @var MPartialMatchRule $r */
849
        foreach ($rules as $r) {
850
          array_push($rules, Query::convertPartialMatchRule($r));
851
        }
852
        $strategy->setRules($rules);
853
      }
854
    }
855
    return $convertedStrategy;
856
  }
857
858
  /**
859
   * @param MPartialMatchRule $rule
860
   *
861
   * @return RPartialMatchRule
862
   */
863
  protected static function convertPartialMatchRule($rule)
864
  {
865
    /** @var RPartialMatchRule $convertedRule */
866
    $convertedRule = null;
867
    if (!empty($rule)) {
868
      $convertedRule = new RPartialMatchRule();
869
      $convertedRule->setTerms($rule->getTerms())
870
          ->setTermsGreaterThan($rule->getTermsGreaterThan())
871
          ->setMustMatch($rule->getMustMatch())
872
          ->setPercentage($rule->isPercentage());
873
    }
874
    return $convertedRule;
875
  }
876
877
  /**
878
   * @param MBias $bias
879
   *
880
   * @return Bias
881
   */
882
  protected static function convertBias($bias)
883
  {
884
    return (new Bias())->setName($bias->getName())->setContent($bias->getContent())->setStrength($bias->getStrength());
885
  }
886
887
  /**
888
   * @param MBias[] $biases
889
   *
890
   * @return Bias[]
891
   */
892
  protected static function convertBiases($biases)
893
  {
894
    return array_map('self::convertBias', $biases);
895
  }
896
897
  /**
898
   * @param MNumericBoost $boost
899
   *
900
   * @return RNumericBoost
901
   */
902
  protected static function convertNumericBoost($boost) {
903
    return (new RNumericBoost())->setName($boost->getName())->setStrength($boost->getStrength())->setInverted($boost->isInverted());
904
  }
905
906
  /**
907
   * @param MNumericBoost[] $boosts
908
   *
909
   * @return RNumericBoost[]
910
   */
911
  protected static function convertNumericBoosts($boosts) {
912
    return array_map('self::convertNumericBoost', $boosts);
913
  }
914
915
  /**
916
   * @param MBiasing $biasing
917
   *
918
   * @return Biasing
919
   */
920
  protected static function convertBiasing($biasing)
921
  {
922
    /** @var Biasing $convertedBiasing */
923
    $convertedBiasing = new Biasing();
924
925
    /** @var  $hasData */
926
    $hasData = false;
927
928
    if (!empty($biasing)) {
929
      // != must be used because empty() only accepts variables in PHP 5.4
930
      if ($biasing->getBringToTop() != array()) {
931
        $convertedBiasing->setBringToTop($biasing->getBringToTop());
932
        $hasData = true;
933
      }
934
      if ($biasing->getBiases() != array()) {
935
        $convertedBiasing->setBiases(self::convertBiases($biasing->getBiases()));
936
        $convertedBiasing->setAugmentBiases($biasing->isAugmentBiases());
937
        $hasData = true;
938
      }
939
      if ($biasing->getNumericBoosts() != array()) {
940
        $convertedBiasing->setNumericBoosts(self::convertNumericBoosts($biasing->getNumericBoosts()));
941
      }
942
      if ($biasing->getInfluence() !== null) {
943
        $convertedBiasing->setInfluence($biasing->getInfluence());
944
        $hasData = true;
945
      }
946
    }
947
    return $hasData ? $convertedBiasing : null;
948
  }
949
950
  /**
951
   * @return string
952
   */
953
  public function getUserId()
954
  {
955
    return $this->userId;
956
  }
957
958
  /**
959
   * @param string $userId
960
   *
961
   * @return Query
962
   */
963
  public function setUserId($userId)
964
  {
965
    $this->userId = $userId;
966
    return $this;
967
  }
968
969
}
970