Completed
Pull Request — develop (#25)
by
unknown
03:54 queued 01:46
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
  /** @var MMatchStrategy */
92
  private $matchStrategy;
93
94
  /** @var Serializer */
95
  private $serializer;
96
97
  const TILDE_REGEX = "/~((?=[\\w]*[=:]))/";
98
99
  /**
100
   * @param mixed $request
101
   *
102
   * @return string
103
   */
104
  private function requestToJson($request)
105
  {
106
    $jsonRequest = null;
107
    try {
108
      $jsonRequest = $this->serializer->serialize($request, 'json');
109
    } catch (RuntimeException $e) {
110
      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...
111
    }
112
113
    return $jsonRequest;
114
  }
115
116
  /**
117
   * @param string $clientKey Your client key.
118
   *
119
   * @return string JSON representation of request to Bridge.
120
   */
121
  public function getBridgeJson($clientKey)
122
  {
123
    $data = $this->populateRequest($clientKey);
124
    return $this->requestToJson($data);
125
  }
126
127
  /**
128
   * @param string $clientKey      Your client key.
129
   * @param string $navigationName Name of the navigation to get refinements for
130
   *
131
   * @return string JSON representation of request to Bridge.
132
   */
133
  public function getBridgeRefinementsJson($clientKey, $navigationName)
134
  {
135
    $data = new RefinementsRequest();
136
    $data->originalQuery = $this->populateRequest($clientKey);
137
    $data->navigationName = $navigationName;
138
    return $this->requestToJson($data);
139
  }
140
141
  /**
142
   * @param string $clientKey
143
   *
144
   * @return Request
145
   */
146
  private function populateRequest($clientKey)
147
  {
148
    $request = new Request();
149
    $request->clientKey = $clientKey;
150
    $request->area = $this->area;
151
    $request->collection = $this->collection;
152
    $request->userId = $this->userId;
153
    $request->query = $this->query;
154
    $request->fields = $this->fields;
155
    $request->orFields = $this->orFields;
156
    $request->language = $this->language;
157
    $request->biasingProfile = $this->biasingProfile;
158
    $request->pageSize = $this->pageSize;
159
    $request->skip = $this->skip;
160
    $request->customUrlParams = $this->customUrlParams;
161
    $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...
162
    $request->restrictNavigation = $this->restrictNavigation;
163
164
    if (!empty($this->biasing)) {
165
      $request->biasing = self::convertBiasing($this->biasing);
166
    }
167
168
    if (!empty($this->includedNavigations)) {
169
      $request->includedNavigations = $this->includedNavigations;
170
    }
171
172
    if (!empty($this->excludedNavigations)) {
173
      $request->excludedNavigations = $this->excludedNavigations;
174
    }
175
176
    $pruneRefinements = $this->pruneRefinements;
177
    if (isset($pruneRefinements) && $pruneRefinements === false) {
178
      $request->pruneRefinements = false;
179
    }
180
181
    $disableAutocorrection = $this->disableAutocorrection;
182
    if (isset($disableAutocorrection) && $disableAutocorrection === true) {
183
      $request->disableAutocorrection = true;
184
    }
185
186
    $wildcardSearchEnabled = $this->wildcardSearchEnabled;
187
    if (isset($wildcardSearchEnabled) && $wildcardSearchEnabled === true) {
188
      $request->wildcardSearchEnabled = true;
189
    }
190
191
    if (!empty($this->sort)) {
192
      foreach ($this->sort as $s) {
193
        array_push($request->sort, $this->convertSort($s));
194
      }
195
    }
196
197
    if (!empty($this->matchStrategy)) {
198
      $request->matchStrategy = self::convertPartialMatchStrategy($this->matchStrategy);
199
    }
200
201
//        $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...
202
//        if (isset($returnBinary) && $returnBinary === true) {
203
//            $request->returnBinary = true;
204
//        }
205
206
    return $request;
207
  }
208
209
  /**
210
   * @param Navigation[] $navigations
211
   *
212
   * @return Refinement[]
213
   */
214
  private function generateSelectedRefinements($navigations)
215
  {
216
    $refinements = [];
217
    foreach ($navigations as $key => $navigation) {
218
      foreach ($navigation->getRefinements() as $refinement) {
219
        switch ($refinement->getType()) {
220
          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...
221
            /** @var RefinementRange $rr */
222
            $rr = $refinement;
223
            $selectedRefinementRange = new SelectedRefinementRange();
224
            $selectedRefinementRange
225
                ->setNavigationName($navigation->getName())
226
                ->setLow($rr->getLow())
227
                ->setHigh($rr->getHigh())
228
                ->setExclude($rr->isExclude());
229
230
            array_push($refinements, $selectedRefinementRange);
231
            break;
232
          }
233
          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...
234
            /** @var RefinementValue $rv */
235
            $rv = $refinement;
236
            $selectedRefinementValue = new SelectedRefinementValue();
237
            $selectedRefinementValue
238
                ->setNavigationName($navigation->getName())
239
                ->setValue($rv->getValue())
240
                ->setExclude($rv->isExclude());
241
242
            array_push($refinements, $selectedRefinementValue);
243
            break;
244
          }
245
        }
246
      }
247
    }
248
    return $refinements;
249
  }
250
251
  /**
252
   * @param string $clientKey Your client key.
253
   *
254
   * @return string JSON representation of request to Bridge.
255
   */
256
  public function getBridgeJsonRefinementSearch($clientKey)
257
  {
258
    $data = new Request();
259
    $data->clientKey = $clientKey;
260
    $data->collection = $this->collection;
261
    $data->area = $this->area;
262
    $data->refinementQuery = $this->query;
263
264
    $wildcardSearchEnabled = $this->wildcardSearchEnabled;
265
    if (isset($wildcardSearchEnabled) && $wildcardSearchEnabled === true) {
266
      $data->wildcardSearchEnabled = true;
267
    }
268
269
    return $this->requestToJson($data);
270
  }
271
272
  public function __construct()
273
  {
274
    $this->serializer = SerializerFactory::build();
275
  }
276
277
  /**
278
   * @return string The current search string.
279
   */
280
  public function getQuery()
281
  {
282
    return $this->query;
283
  }
284
285
  /**
286
   * @param string $query The search string.
287
   */
288
  public function setQuery($query)
289
  {
290
    $this->query = $query;
291
  }
292
293
  /**
294
   * @return string The data sub-collection.
295
   */
296
  public function getCollection()
297
  {
298
    return $this->collection;
299
  }
300
301
  /**
302
   * @param string $collection The string representation of a collection query.
303
   */
304
  public function setCollection($collection)
305
  {
306
    $this->collection = $collection;
307
  }
308
309
  /**
310
   * @return string The area name.
311
   */
312
  public function getArea()
313
  {
314
    return $this->area;
315
  }
316
317
  /**
318
   * @param string $area The area name.
319
   */
320
  public function setArea($area)
321
  {
322
    $this->area = $area;
323
  }
324
325
  /**
326
   * @return string[] A list of metadata fields that will be returned by the search engine.
327
   */
328
  public function getFields()
329
  {
330
    return $this->fields;
331
  }
332
333
  /**
334
   * @return string[] A list of the fields that the search service will treat as OR'able.
335
   */
336
  public function getOrFields()
337
  {
338
    return $this->orFields;
339
  }
340
341
  /**
342
   * @param string[] $fields A list of case-sensitive names of the attributes to return.
343
   */
344
  public function addFields($fields)
345
  {
346
    $this->fields = array_merge($this->fields, $fields);
347
  }
348
349
  /**
350
   * @return string[] A list of which navigations to return from the bridge.
351
   */
352
  public function getIncludedNavigations()
353
  {
354
    return $this->includedNavigations;
355
  }
356
357
  /**
358
   * @param string[] $navigations A list of which navigations to return from the bridge.
359
   */
360
  public function addIncludedNavigations($navigations)
361
  {
362
    $this->includedNavigations = array_merge($this->includedNavigations, $navigations);
363
  }
364
365
  /**
366
   * @return string[] A list of which navigations to not return from the bridge.
367
   */
368
  public function getExcludedNavigations()
369
  {
370
    return $this->excludedNavigations;
371
  }
372
373
  /**
374
   * @param string[] $navigations A list of which navigations to not return from the bridge.
375
   */
376
  public function addExcludedNavigations($navigations)
377
  {
378
    $this->excludedNavigations = array_merge($this->excludedNavigations, $navigations);
379
  }
380
381
  /**
382
   * @return Navigation[]
383
   */
384
  public function &getNavigations()
385
  {
386
    return $this->navigations;
387
  }
388
389
  /**
390
   * @param Navigation[] $navigations
391
   */
392
  public function setNavigations($navigations)
393
  {
394
    $this->navigations = $navigations;
395
  }
396
397
  /**
398
   * @param string $name The case-sensitive name of the attribute to return.
399
   */
400
  public function addField($name)
401
  {
402
    array_push($this->fields, $name);
403
  }
404
405
  /**
406
   * @param string $name Field that should be treated as OR.
407
   */
408
  public function addOrField($name)
409
  {
410
    array_push($this->orFields, $name);
411
  }
412
413
  /**
414
   * @param string[] $fields A list of fields that should be treated as OR.
415
   */
416
  public function addOrFields($fields)
417
  {
418
    $this->orFields = array_merge($this->orFields, $fields);
419
  }
420
421
  /**
422
   * @param string $name  The parameter name.
423
   * @param string $value The parameter value.
424
   */
425
  public function addCustomUrlParamByName($name, $value)
426
  {
427
    $param = new CustomUrlParam();
428
    $this->addCustomUrlParam($param->setKey($name)->setValue($value));
429
  }
430
431
  /**
432
   * @param CustomUrlParam $param Set an additional parameter that can be used to trigger rules.
433
   */
434
  public function addCustomUrlParam($param)
435
  {
436
    array_push($this->customUrlParams, $param);
437
  }
438
439
  public function splitRefinements($refinementString)
440
  {
441
    if (StringUtils::isNotBlank($refinementString)) {
442
      return preg_split(self::TILDE_REGEX, $refinementString, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
443
    }
444
    return [];
445
  }
446
447
  /**
448
   * @param string $refinementString A tilde separated list of refinements.
449
   */
450
  public function addRefinementsByString($refinementString)
451
  {
452
    if ($refinementString == null) {
453
      return;
454
    }
455
456
    $refinementStrings = self::splitRefinements($refinementString);
457
    foreach ($refinementStrings as $refinementString) {
458
      if (empty($refinementString) || "=" == $refinementString) {
459
        continue;
460
      }
461
      $colon = strpos($refinementString, Symbol::COLON);
462
      $equals = strpos($refinementString, Symbol::EQUAL);
463
      //when === false, it means it did not find the substring in the string
464
      $isRange = !($colon === false) && ($equals === false);
465
466
      $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...
467
      if ($isRange) {
468
        $nameValue = explode(Symbol::COLON, $refinementString, 2);
469
        $refinement = new RefinementRange();
470
        if (StringUtils::endsWith($nameValue[1], Symbol::DOUBLE_DOT)) {
471
          $value = explode(Symbol::DOUBLE_DOT, $nameValue[1]);
472
          $refinement->setLow($value[0]);
473
          $refinement->setHigh("");
474
        } else if (StringUtils::startsWith($nameValue[1], Symbol::DOUBLE_DOT)) {
475
          $refinement->setLow("");
476
          $value = explode(Symbol::DOUBLE_DOT, $nameValue[1]);
477
          $refinement->setHigh($value[1]);
478
        } else {
479
          $lowHigh = explode(Symbol::DOUBLE_DOT, $nameValue[1]);
480
          $refinement->setLow($lowHigh[0]);
481
          $refinement->setHigh($lowHigh[1]);
482
        }
483
      } else {
484
        $nameValue = explode(Symbol::EQUAL, $refinementString, 2);
485
        $refinement = new RefinementValue();
486
        $refinement->setValue($nameValue[1]);
487
      }
488
      if (!empty($nameValue[0])) {
489
        $this->addRefinement($nameValue[0], $refinement);
490
      }
491
    }
492
  }
493
494
  /**
495
   * @param string     $navigationName The name of the Navigation.
496
   * @param Refinement $refinement     A RefinementRange or RefinementValue object.
497
   */
498
  public function addRefinement($navigationName, $refinement)
499
  {
500
    $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...
501
    if (array_key_exists($navigationName, $this->navigations)) {
502
      $navigation = $this->navigations[$navigationName];
503
    } else {
504
      $navigation = new Navigation();
505
      $navigation->setName($navigationName)->setRange($refinement instanceof SelectedRefinementRange);
506
      $this->navigations[$navigationName] = $navigation;
507
    }
508
    $refinements = $navigation->getRefinements();
509
    array_push($refinements, $refinement);
510
    $navigation->setRefinements($refinements);
511
  }
512
513
  /**
514
   * @param string $navigationName The name of the refinement.
515
   * @param mixed  $low            The low value.
516
   * @param mixed  $high           The high value.
517
   * @param bool   $exclude        True if the results should exclude this range refinement, false otherwise.
518
   */
519
  public function addRangeRefinement($navigationName, $low, $high, $exclude = false)
520
  {
521
    $refinement = new RefinementRange();
522
    $this->addRefinement($navigationName, $refinement->setLow($low)->setHigh($high)->setExclude($exclude));
523
  }
524
525
  /**
526
   * @param string $navigationName The name of the refinement.
527
   * @param mixed  $value          The refinement value.
528
   * @param bool   $exclude        True if the results should exclude this value refinement, false otherwise.
529
   */
530
  public function addValueRefinement($navigationName, $value, $exclude = false)
531
  {
532
    $refinement = new RefinementValue();;
533
    $this->addRefinement($navigationName, $refinement->setValue($value)->setExclude($exclude));
534
  }
535
536
  /**
537
   * @return bool Are refinements with zero counts being removed.
538
   */
539
  public function isPruneRefinements()
540
  {
541
    return $this->pruneRefinements;
542
  }
543
544
  /**
545
   * @param bool $pruneRefinements Specifies whether refinements should be pruned.
546
   */
547
  public function setPruneRefinements($pruneRefinements)
548
  {
549
    $this->pruneRefinements = $pruneRefinements;
550
  }
551
552
  /**
553
   * @return MSort[] The current list of sort parameters.
554
   */
555
  public function &getSort()
556
  {
557
    return $this->sort;
558
  }
559
560
  /**
561
   * @param MSort[] $sort Any number of sort criteria.
562
   */
563
  public function setSort($sort)
564
  {
565
    $this->sort = $sort;
566
  }
567
568
  /**
569
   * @return int The number of documents to skip.
570
   */
571
  public function getSkip()
572
  {
573
    return $this->skip;
574
  }
575
576
  /**
577
   * @param int $skip The number of documents to skip.
578
   */
579
  public function setSkip($skip)
580
  {
581
    $this->skip = $skip;
582
  }
583
584
  /**
585
   * @return CustomUrlParam[] A list of custom url params.
586
   */
587
  public function getCustomUrlParams()
588
  {
589
    return $this->customUrlParams;
590
  }
591
592
  /**
593
   * @param CustomUrlParam[] $customUrlParams Set the custom url params.
594
   */
595
  public function setCustomUrlParams($customUrlParams)
596
  {
597
    $this->customUrlParams = $customUrlParams;
598
  }
599
600
//    /**
601
//     * @return bool Is return JSON set to true.
602
//     */
603
//    public function isReturnBinary()
604
//    {
605
//        return $this->returnBinary;
606
//    }
607
//
608
//    /**
609
//     * @param bool $returnBinary Whether to tell the bridge to return binary data rather than JSON.
610
//     */
611
//    public function setReturnBinary($returnBinary)
612
//    {
613
//        $this->returnBinary = $returnBinary;
614
//    }
615
616
  /**
617
   * @return string The current language restrict value.
618
   */
619
  public function getLanguage()
620
  {
621
    return $this->language;
622
  }
623
624
  /**
625
   * @param string $language The value for language restrict.
626
   */
627
  public function setLanguage($language)
628
  {
629
    $this->language = $language;
630
  }
631
632
  /**
633
   * @return string The current biasing profile name.
634
   */
635
  public function getBiasingProfile()
636
  {
637
    return $this->biasingProfile;
638
  }
639
640
  /**
641
   * @param string $biasingProfile Override the biasing profile used for this query.
642
   */
643
  public function setBiasingProfile($biasingProfile)
644
  {
645
    $this->biasingProfile = $biasingProfile;
646
  }
647
648
  /**
649
   * @return int The current page size.
650
   */
651
  public function getPageSize()
652
  {
653
    return $this->pageSize;
654
  }
655
656
  /**
657
   * @param int $pageSize The number of records to return with the query.
658
   */
659
  public function setPageSize($pageSize)
660
  {
661
    $this->pageSize = $pageSize;
662
  }
663
664
  /**
665
   * @return boolean
666
   */
667
  public function isDisableAutocorrection()
668
  {
669
    return $this->disableAutocorrection;
670
  }
671
672
  /**
673
   * @param boolean $disableAutocorrection Specifies whether the auto-correction behavior should be disabled.
674
   *                                       By default, when no results are returned for the given query (and there is
675
   *                                       a did-you-mean available), the first did-you-mean is automatically queried
676
   *                                       instead.
677
   */
678
  public function setDisableAutocorrection($disableAutocorrection)
679
  {
680
    $this->disableAutocorrection = $disableAutocorrection;
681
  }
682
683
  /**
684
   * @return boolean
685
   */
686
  public function isWildcardSearchEnabled()
687
  {
688
    return $this->wildcardSearchEnabled;
689
  }
690
691
  /**
692
   * @param boolean $wildcardSearchEnabled Indicate if the *(star) character in the search string should be treated
693
   *                                       as a wildcard prefix search. For example, `sta*` will match `star` and
694
   *                                       `start`.
695
   */
696
  public function setWildcardSearchEnabled($wildcardSearchEnabled)
697
  {
698
    $this->wildcardSearchEnabled = $wildcardSearchEnabled;
699
  }
700
701
  /**
702
   * <b>Warning</b>  This will count as two queries against your search index.
703
   *
704
   * Typically, this feature is used when you have a large number of navigation items that will overwhelm the end
705
   * user. It works by using one of the existing navigation items to decide what the query is about and fires a second
706
   * query to restrict the navigation to the most relevant set of navigation items for this search term.
707
   *
708
   * For example, if you pass in a search of `paper` and a restrict navigation of `category:2`
709
   *
710
   * The bridge will find the category navigation refinements in the first query and fire a second query for the top 2
711
   * most populous categories.  Therefore, a search for something generic like "paper" will bring back top category
712
   * matches like copy paper (1,030), paper pads (567).  The bridge will fire off the second query with the search
713
   * term, plus an OR refinement with the most likely categories.  The navigation items in the first query are
714
   * entirely replaced with the navigation items in the second query, except for the navigation that was used for the
715
   * restriction so that users still have the ability to navigate by all category types.
716
   *
717
   * @param RestrictNavigation $restrictNavigation Restriction criteria
718
   */
719
  public function setRestrictNavigation($restrictNavigation)
720
  {
721
    $this->restrictNavigation = $restrictNavigation;
722
  }
723
724
  /** @return RestrictNavigation */
725
  public function getRestrictNavigation()
726
  {
727
    return $this->restrictNavigation;
728
  }
729
730
  /**
731
   * @return MBiasing
732
   */
733
  public function getBiasing()
734
  {
735
    return $this->biasing;
736
  }
737
738
  /**
739
   * Add a biasing profile, which is defined at query time.
740
   *
741
   * @param MBiasing $biasing
742
   */
743
  public function setBiasing($biasing)
744
  {
745
    $this->biasing = $biasing;
746
  }
747
748
  /**
749
   * @param string[] $bringToTop
750
   */
751
  public function setBringToTop($bringToTop)
752
  {
753
    if (empty($this->biasing)) {
754
      $this->biasing = new MBiasing();
755
    }
756
    $this->biasing->setBringToTop($bringToTop);
757
  }
758
759
  /**
760
   * @param boolean $augment
761
   */
762
  public function setBiasingAugment($augment)
763
  {
764
    if (empty($this->biasing)) {
765
      $this->biasing = new MBiasing();
766
    }
767
    $this->biasing->setAugmentbiases($augment);
768
  }
769
770
  /**
771
   * @param float $influence
772
   */
773
  public function setInfluence($influence)
774
  {
775
    if (empty($this->biasing)) {
776
      $this->biasing = new MBiasing();
777
    }
778
    $this->biasing->setInfluence($influence);
779
  }
780
781
  /**
782
   * @return string A string representation of all of the currently set refinements.
783
   */
784 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...
785
  {
786
    if (!empty($this->navigations)) {
787
      $builder = new StringBuilder();
788
      foreach ($this->navigations as $n) {
789
        foreach ($n->getRefinements() as $r) {
790
          $builder->append(Symbol::TILDE)->append($n->getName())->append($r->toTildeString());
791
        }
792
      }
793
      if ($builder->length() > 0) {
794
        return $builder->__toString();
795
      }
796
    }
797
    return null;
798
  }
799
800
  /**
801
   * @return string A string representation of all of the currently set custom url parameters.
802
   */
803 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...
804
  {
805
    if (!empty($this->customUrlParams)) {
806
      $builder = new StringBuilder();
807
      foreach ($this->customUrlParams as $c) {
808
        $builder->append(Symbol::TILDE)->append($c->getKey())->append(Symbol::EQUAL)->append($c->getValue());
809
      }
810
      if ($builder->length() > 0) {
811
        return $builder->__toString();
812
      }
813
    }
814
    return null;
815
  }
816
817
  /**
818
   * @return MMatchStrategy
819
   */
820
  public function getMatchStrategy() {
821
    return $this->matchStrategy;
822
  }
823
824
  /**
825
   * @param MMatchStrategy $matchStrategy
826
   */
827
  public function setMatchStrategy($matchStrategy) {
828
    $this->matchStrategy = $matchStrategy;
829
  }
830
831
  /**
832
   * @param MSort $sort
833
   *
834
   * @return RSort
835
   */
836
  protected static function convertSort($sort)
837
  {
838
    /** @var RSort $convertedSort */
839
    $convertedSort = null;
840
    if (!empty($sort)) {
841
      $convertedSort = new RSort();
842
      $convertedSort->setField($sort->getField());
843
      switch ($sort->getOrder()) {
844
        case MSort\Order::Ascending:
845
          $convertedSort->setOrder(RSort\Order::Ascending);
846
          break;
847
        case MSort\Order::Descending:
848
          $convertedSort->setOrder(RSort\Order::Descending);
849
          break;
850
      }
851
    }
852
    return $convertedSort;
853
  }
854
855
  /**
856
   * @param MMatchStrategy $strategy
857
   *
858
   * @return RMatchStrategy
859
   */
860
  protected static function convertPartialMatchStrategy($strategy)
861
  {
862
    /** @var RMatchStrategy $convertedStrategy */
863
    $convertedStrategy = null;
864
    if (!empty($strategy)) {
865
      $rules = $strategy->getRules();
866
      if (!empty($rules)) {
867
        $convertedStrategy = new RMatchStrategy();
868
        /** @var MPartialMatchRule $r */
869
        foreach ($rules as $r) {
870
          array_push($rules, Query::convertPartialMatchRule($r));
871
        }
872
        $strategy->setRules($rules);
873
      }
874
    }
875
    return $convertedStrategy;
876
  }
877
878
  /**
879
   * @param MPartialMatchRule $rule
880
   *
881
   * @return RPartialMatchRule
882
   */
883
  protected static function convertPartialMatchRule($rule)
884
  {
885
    /** @var RPartialMatchRule $convertedRule */
886
    $convertedRule = null;
887
    if (!empty($rule)) {
888
      $convertedRule = new RPartialMatchRule();
889
      $convertedRule->setTerms($rule->getTerms())
890
          ->setTermsGreaterThan($rule->getTermsGreaterThan())
891
          ->setMustMatch($rule->getMustMatch())
892
          ->setPercentage($rule->isPercentage());
893
    }
894
    return $convertedRule;
895
  }
896
897
  /**
898
   * @param MBias $bias
899
   *
900
   * @return Bias
901
   */
902
  protected static function convertBias($bias)
903
  {
904
    return (new Bias())->setName($bias->getName())->setContent($bias->getContent())->setStrength($bias->getStrength());
905
  }
906
907
  /**
908
   * @param MBias[] $biases
909
   *
910
   * @return Bias[]
911
   */
912
  protected static function convertBiases($biases)
913
  {
914
    return array_map('self::convertBias', $biases);
915
  }
916
917
  /**
918
   * @param MNumericBoost $boost
919
   *
920
   * @return RNumericBoost
921
   */
922
  protected static function convertNumericBoost($boost) {
923
    return (new RNumericBoost())->setName($boost->getName())->setStrength($boost->getStrength())->setInverted($boost->isInverted());
924
  }
925
926
  /**
927
   * @param MNumericBoost[] $boosts
928
   *
929
   * @return RNumericBoost[]
930
   */
931
  protected static function convertNumericBoosts($boosts) {
932
    return array_map('self::convertNumericBoost', $boosts);
933
  }
934
935
  /**
936
   * @param MBiasing $biasing
937
   *
938
   * @return Biasing
939
   */
940
  protected static function convertBiasing($biasing)
941
  {
942
    /** @var Biasing $convertedBiasing */
943
    $convertedBiasing = new Biasing();
944
945
    /** @var  $hasData */
946
    $hasData = false;
947
948
    if (!empty($biasing)) {
949
      // != must be used because empty() only accepts variables in PHP 5.4
950
      if ($biasing->getBringToTop() != array()) {
951
        $convertedBiasing->setBringToTop($biasing->getBringToTop());
952
        $hasData = true;
953
      }
954
      if ($biasing->getBiases() != array()) {
955
        $convertedBiasing->setBiases(self::convertBiases($biasing->getBiases()));
956
        $convertedBiasing->setAugmentBiases($biasing->isAugmentBiases());
957
        $hasData = true;
958
      }
959
      if ($biasing->getNumericBoosts() != array()) {
960
        $convertedBiasing->setNumericBoosts(self::convertNumericBoosts($biasing->getNumericBoosts()));
961
      }
962
      if ($biasing->getInfluence() !== null) {
963
        $convertedBiasing->setInfluence($biasing->getInfluence());
964
        $hasData = true;
965
      }
966
    }
967
    return $hasData ? $convertedBiasing : null;
968
  }
969
970
  /**
971
   * @return string
972
   */
973
  public function getUserId()
974
  {
975
    return $this->userId;
976
  }
977
978
  /**
979
   * @param string $userId
980
   *
981
   * @return Query
982
   */
983
  public function setUserId($userId)
984
  {
985
    $this->userId = $userId;
986
    return $this;
987
  }
988
989
}
990