Maslosoft Manganel API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
<?php
/**
* This software package is licensed under `AGPL, Commercial` license[s].
*
* @package maslosoft/manganel
* @license AGPL, Commercial
*
* @copyright Copyright (c) Peter Maselkowski <pmaselkowski@gmail.com>
* @link https://maslosoft.com/manganel/
*/
namespace Maslosoft\Manganel\Decorators\QueryBuilder\QueryString;
use Maslosoft\Mangan\Criteria\ConditionDecorator;
use Maslosoft\Manganel\Interfaces\QueryBuilder\QueryStringDecoratorInterface;
use Maslosoft\Manganel\Meta\ManganelMeta;
use Maslosoft\Manganel\SearchCriteria;
use UnexpectedValueException;
/**
* BoostDecorator
*
* @author Piotr Maselkowski <pmaselkowski at gmail.com>
*/
class BoostDecorator implements QueryStringDecoratorInterface
{
public function decorate(&$queryStringParams, SearchCriteria $criteria)
{
$fields = [];
$model = $criteria->getModel();
// when no model provided could not determine boosting
if (empty($model))
{
return;
}
$meta = ManganelMeta::create($model);
$boosted = $meta->properties('searchBoost');
/* @var $boosted float[] */
foreach ($boosted as $fieldName => $boost)
{
if ($boost !== 1.0)
{
// Decorate fields, so for instance i18n fields
// will map boosting to `title.en` etc.
$cd = new ConditionDecorator($model);
$name = key($cd->decorate($fieldName));
$fields[$name] = $this->unify($name, $boost, $fields);
}
}
// No custom boost, ignore
if (empty($fields))
{
return;
}
$boosts = [];
foreach ($fields as $name => $boost)
{
$boosts[] = sprintf('%s^%f', $name, $boost);
}
// Add also _all or it would search only boosted fields
$boosts[] = '_all';
$queryStringParams['fields'] = $boosts;
}
/**
* Unify boost value if using multi model search with different boost
* values for field with same name.
* @param string $field
* @param float $boost
* @param float[] $fields
* @return float
*/
private function unify($field, $boost, $fields)
{
if (!array_key_exists($field, $fields))
{
// No boost set yet, simply set value
return $boost;
}
// There are already some boost set, decide whether to use maximum
// or minimum value
$current = $fields[$field];
switch (true)
{
// Choose minimal boost out of all
case $current < 1 && $boost < 1:
$boost = min($current, $boost);
break;
// Choose maximum boost out of all
case $current > 1 && $boost > 1:
$boost = max($current, $boost);
break;
// Choose average, as there is no way to decide whether boost should
// be above one or below
default:
$boost = ($current + $boost) / 2;
}
return $boost;
}
}
API documentation generated by ApiGen