FuzzySearchHelper::strictSimilarityCallback()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
ccs 7
cts 7
cp 1
rs 9.4285
cc 3
eloc 4
nc 3
nop 3
crap 3
1
<?php
2
3
namespace GeoFixer\helpers;
4
5
/**
6
 * Class FuzzySearchHelper
7
 *
8
 * @package GeoFixer\helpers
9
 */
10
class FuzzySearchHelper
11
{
12
    public $max_similarity;
13
    public $meta_similarity;
14
    public $min_levenshtein;
15
    public $meta_min_levenshtein;
16
17
    public $result_array = [];
18
    public $words_array = [];
19
20
    /**
21
     * Строгий поиск
22
     *
23
     * @param $word
24
     * @param $translited_words
25
     *
26
     * @return bool|mixed
27
     */
28 9
    public function findBestMatch($word, $translited_words)
29
    {
30 9
        $this->refreshVariables();
31
32 9
        array_walk($translited_words, array($this, 'strictWordsLevenshteinHandlerCallback'), $word);
33 9
        $most_similar = $this->findMostSimilarWords($word, $this->words_array);
34 9
        array_walk($most_similar, array($this, 'findFinalSimilirityAndLevenshtein'), $word);
35 9
        array_walk($most_similar, array($this, 'strictSimilarityCallback'), $word);
36
37 9
        return is_null(key($this->result_array)) ? false : key($this->result_array);
38
    }
39
40
    /**
41
     * Нестрогий поиск
42
     *
43
     * @param $word
44
     * @param $words_array
45
     * @return array
46
     */
47 19
    public function findMostSimilarWords($word, $words_array)
48
    {
49 19
        $this->refreshVariables();
50
51 19
        array_walk($words_array, array($this, 'similarityCallback'), $word);
52
53 19
        return $this->result_array;
54
    }
55
56
    /**
57
     * Вспомогательный метод для findBestMatch
58
     *
59
     * @param $item
60
     * @param $key
61
     * @param $word
62
     */
63 2
    private function findFinalSimilirityAndLevenshtein($item, $key, $word)
64
    {
65 2
        $this->meta_min_levenshtein = min($this->meta_min_levenshtein, levenshtein(metaphone($item), metaphone($word)));
66 2
        if (levenshtein($item, $word) == $this->meta_min_levenshtein) {
67 2
            $this->meta_similarity = max($this->meta_similarity, similar_text(metaphone($item), metaphone($word)));
68 2
        }
69 2
    }
70
71
    /**
72
     * Вспомогательный метод для findBestMatch
73
     *
74
     * @param $latin
75
     * @param $russian
76
     * @param $word
77
     */
78 2
    private function strictSimilarityCallback($latin, $russian, $word)
79
    {
80 2
        if (levenshtein(metaphone($latin), metaphone($word)) <= $this->meta_min_levenshtein) {
81 2
            if (similar_text(metaphone($latin), metaphone($word)) >= $this->meta_similarity) {
82 2
                $this->result_array[$russian] = $latin;
83 2
            }
84 2
        }
85 2
    }
86
87
    /**
88
     * Вспомогательный метод для findBestMatch
89
     *
90
     * @param $translit
91
     * @param $russian
92
     * @param $word
93
     */
94 9
    private function strictWordsLevenshteinHandlerCallback($translit, $russian, $word)
95
    {
96 9
        if (levenshtein(metaphone($word), metaphone($translit)) < mb_strlen(metaphone($word)) / 2) {
97 2
            if (levenshtein($word, $translit) < mb_strlen($word) / 2) {
98 2
                $this->words_array[$russian] = $translit;
99 2
            }
100 2
        }
101 9
    }
102
103
    /**
104
     * Вспомогательный метод для findMostSimilarWords
105
     *
106
     * @param $translit
107
     * @param $russian
108
     * @param $word
109
     */
110 12
    private function similarityCallback($translit, $russian, $word)
111
    {
112 12
        if (levenshtein($translit, $word) <= $this->min_levenshtein) {
113 12
            if (similar_text($translit, $word) >= $this->max_similarity) {
114 12
                $this->result_array = [];
115 12
                $this->min_levenshtein = levenshtein($translit, $word);
116 12
                $this->max_similarity = similar_text($translit, $word);
117 12
                $this->result_array[$russian] = $translit;
118 12
            }
119 12
        }
120 12
    }
121
122
    /**
123
     * Refresh variables
124
     */
125 19
    private function refreshVariables()
126
    {
127 19
        $this->max_similarity = 0;
128 19
        $this->meta_similarity = 0;
129 19
        $this->min_levenshtein = 1000;
130 19
        $this->meta_min_levenshtein = 1000;
131 19
    }
132
133
}
134