lib/components/dataInterface/Search.php
public function searchLocal(DataItem $item, $searchParams = [])
    {
        if (empty($searchParams['searchFields'])) {
            $searchParams['searchFields'] = $this->localFields;
        }
        if (empty($searchParams['searchFields'])) {
            return;
        }
        if (!isset($searchParams['limit'])) {
            $searchParams['limit'] = 5;
        }
        $searchParams['skipForeign'] = true;
        $query = [];
        foreach ($this->foreignFields as $field) {
            if (!empty($item->foreignObject->{$field})) {
                $value = $item->foreignObject->{$field};
                if (isset($this->foreignFilter)) {
                    $value = call_user_func($this->foreignFilter, $value);
                }
                $query[] = $value;
            }
        }
        if (empty($query)) {
            return;
        }

        $localClass = $this->dataSource->localModel;
        $searchResults = $localClass::searchTerm(implode(' ', $query), $searchParams);
        $resultsLeft = $totalResults = count($searchResults);
        foreach ($searchResults as $k => $r) {
            // if ($r->descriptor === $query[0]) { continue; }
            $score = (
                ((($resultsLeft/$totalResults) * 100) * .2)
                + (StringHelper::compareStrings($r->descriptor, implode(' ', $query)) * .8)
            );
            $r->score = $score;
            if ($score < $this->threshold) {
                unset($searchResults[$k]);
            } else {
                $reverseKey = $this->dataSource->getReverseKeyTranslation($r->id);
                if (!empty($reverseKey)) {
                    unset($searchResults[$k]);
                }
            }
            $resultsLeft--;
        }
        ArrayHelper::multisort($searchResults, 'scoreSort', SORT_DESC);
        $searchResults = array_values($searchResults);
        if (empty($searchResults)) {
            return;
        } elseif (($safeResult = $this->getSafeResult($searchResults))) {
            $this->dataSource->task->addInfo('Auto-matched "'. implode(' ', $query) .'" to "'. $safeResult->descriptor .'" (Score: '.round($safeResult->score, 2).')', [
                    'query' => $query,
                    'foreignObject' => $item->foreignObject->attributes,
                    'localObject' => ['id' => $safeResult->id, 'descriptor' => $safeResult->descriptor]
            ]);
            return $safeResult->object;
        } else {
            $options = [];
            $resultsNice = [];
            $optionNumber = 1;

            $defaultOption = 'new';
            if ($searchResults[0]->score > $this->defaultOptionThreshold) {
                $defaultOption = '1';
            }
            foreach ($searchResults as $result) {
                $resultsNice['' . $optionNumber] = $result;
                $options['' . $optionNumber] = $result->descriptor . ' (' . round($result->score) . '%)';
                $optionNumber++;
            }
            $options['new'] = 'Create New Object';
            $options['selectObject'] = 'Select Object';
            $select = false;
            $interactionOptions = ['inputType' => 'select', 'options' => $options];
            $interactionOptions['details'] = $item->foreignObject->attributes;
            $interactionOptions['default'] = $defaultOption;
            $callback = [
                'callback' => function ($response) use (&$select, $options) {
                    if (empty($response)) {
                        return false;
                    }
                    if (substr($response, 0, 2) !== '*-' && !isset($options[$response])) {
                        return false;
                    }
                    $select = $response;

                    return true;
                },
            ];
            if (!$this->dataSource->action->createInteraction('Match Object (' . implode(' ', $query) . ')', $interactionOptions, $callback)) {
                return false;
            }

            if ($select === 'new') {
                $this->dataSource->task->addInfo('For "'. implode(' ', $query) .'" user chose to to create new object', [
                        'query' => $query,
                        'foreignObject' => $item->foreignObject->attributes
                ]);
                return;
            } elseif (substr($select, 0, 2) === '*-') {
                $matchedObjectId = substr($select, 2);
                $matchedObject = Registry::getObject($matchedObjectId, false);
                if (!$matchedObject) {
                    $this->dataSource->task->addWarning('For "'. implode(' ', $query) .'" user tried to match it to a different object, but object wasn\'t found! Created new object.', [
                            'query' => $query,
                            'foreignObject' => $item->foreignObject->attributes,
                            'matchedObject' => $matchedObjectId
                    ]);
                    return;
                }
                $this->dataSource->task->addInfo('For "'. implode(' ', $query) .'" matched to an existing object "'. $matchedObject->descriptor .'"', [
                        'query' => $query,
                        'foreignObject' => $item->foreignObject->attributes,
                        'matchedObject' => $matchedObject->attributes
                ]);
                return $matchedObject;
            } else {
                $this->dataSource->task->addInfo('User matched "'. implode(' ', $query) .'" to "'. $resultsNice[$select]->descriptor . '"', [
                        'query' => $query,
                        'foreignObject' => $item->foreignObject->attributes,
                        'localObject' => $resultsNice[$select]->id
                ]);
                return $resultsNice[$select]->object;
            }
        }
    }
public function searchLocal(DataItem $item, $searchParams = [])
    {
        if (empty($searchParams['searchFields'])) {
            $searchParams['searchFields'] = $this->localFields;
        }
        if (empty($searchParams['searchFields'])) {
            return;
        }
        if (!isset($searchParams['limit'])) {
            $searchParams['limit'] = 5;
        }
        $searchParams['skipForeign'] = true;
        $query = [];
        foreach ($this->foreignFields as $field) {
            if (!empty($item->foreignObject->{$field})) {
                $value = $item->foreignObject->{$field};
                if (isset($this->foreignFilter)) {
                    $value = call_user_func($this->foreignFilter, $value);
                }
                $query[] = $value;
            }
        }
        if (empty($query)) {
            return;
        }

        $localClass = $this->dataSource->localModel;
        $searchResults = $localClass::searchTerm(implode(' ', $query), $searchParams);
        $resultsLeft = $totalResults = count($searchResults);
        foreach ($searchResults as $k => $r) {
            // if ($r->descriptor === $query[0]) { continue; }
            $score = (
                ((($resultsLeft/$totalResults) * 100) * .2)
                + (StringHelper::compareStrings($r->descriptor, implode(' ', $query)) * .8)
            );
            $r->score = $score;
            if ($score < $this->threshold) {
                unset($searchResults[$k]);
            } else {
                $reverseKey = $this->dataSource->getReverseKeyTranslation($r->id);
                if (!empty($reverseKey)) {
                    unset($searchResults[$k]);
                }
            }
            $resultsLeft--;
        }
        ArrayHelper::multisort($searchResults, 'scoreSort', SORT_DESC);
        $searchResults = array_values($searchResults);
        if (empty($searchResults)) {
            return;
        } elseif (($safeResult = $this->getSafeResult($searchResults))) {
            $this->dataSource->task->addInfo('Auto-matched "'. implode(' ', $query) .'" to "'. $safeResult->descriptor .'" (Score: '.round($safeResult->score, 2).')', [
                    'query' => $query,
                    'foreignObject' => $item->foreignObject->attributes,
                    'localObject' => ['id' => $safeResult->id, 'descriptor' => $safeResult->descriptor]
            ]);
            return $safeResult->object;
        } else {
            $options = [];
            $resultsNice = [];
            $optionNumber = 1;

            $defaultOption = 'new';
            if ($searchResults[0]->score > $this->defaultOptionThreshold) {
                $defaultOption = '1';
            }
            foreach ($searchResults as $result) {
                $resultsNice['' . $optionNumber] = $result;
                $options['' . $optionNumber] = $result->descriptor . ' (' . round($result->score) . '%)';
                $optionNumber++;
            }
            $options['new'] = 'Create New Object';
            $options['selectObject'] = 'Select Object';
            $select = false;
            $interactionOptions = ['inputType' => 'select', 'options' => $options];
            $interactionOptions['details'] = $item->foreignObject->attributes;
            $interactionOptions['default'] = $defaultOption;
            $callback = [
                'callback' => function ($response) use (&$select, $options) {
                    if (empty($response)) {
                        return false;
                    }
                    if (substr($response, 0, 2) !== '*-' && !isset($options[$response])) {
                        return false;
                    }
                    $select = $response;

                    return true;
                },
            ];
            if (!$this->dataSource->action->createInteraction('Match Object (' . implode(' ', $query) . ')', $interactionOptions, $callback)) {
                return false;
            }

            if ($select === 'new') {
                $this->dataSource->task->addInfo('For "'. implode(' ', $query) .'" user chose to to create new object', [
                        'query' => $query,
                        'foreignObject' => $item->foreignObject->attributes
                ]);
                return;
            } elseif (substr($select, 0, 2) === '*-') {
                $matchedObjectId = substr($select, 2);
                $matchedObject = Registry::getObject($matchedObjectId, false);
                if (!$matchedObject) {
                    $this->dataSource->task->addWarning('For "'. implode(' ', $query) .'" user tried to match it to a different object, but object wasn\'t found! Created new object.', [
                            'query' => $query,
                            'foreignObject' => $item->foreignObject->attributes,
                            'matchedObject' => $matchedObjectId
                    ]);
                    return;
                }
                $this->dataSource->task->addInfo('For "'. implode(' ', $query) .'" matched to an existing object "'. $matchedObject->descriptor .'"', [
                        'query' => $query,
                        'foreignObject' => $item->foreignObject->attributes,
                        'matchedObject' => $matchedObject->attributes
                ]);
                return $matchedObject;
            } else {
                $this->dataSource->task->addInfo('User matched "'. implode(' ', $query) .'" to "'. $resultsNice[$select]->descriptor . '"', [
                        'query' => $query,
                        'foreignObject' => $item->foreignObject->attributes,
                        'localObject' => $resultsNice[$select]->id
                ]);
                return $resultsNice[$select]->object;
            }
        }
    }
[[@doctodo method_description:searchLocal]].

@param cascade\components\dataInterface\DataItem $item         [[@doctodo param_description:item]]
@param array                                     $searchParams [[@doctodo param_description:searchParams]] [optional]

@return [[@doctodo return_type:searchLocal]] [[@doctodo return_description:searchLocal]]