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