 Maslosoft Manganel API
	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
