Completed
Push — master ( 74d951...d5b4b1 )
by Konstantin
01:45
created

FuzzySearchHelper::refreshVariables()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 9.4285
cc 1
eloc 5
nc 1
nop 0
crap 1
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
        if (is_null(key($this->result_array))) {
38 7
            return false;
39
        }
40
41 2
        return key($this->result_array);
42
    }
43
44
    /**
45
     * Нестрогий поиск
46
     *
47
     * @param $word
48
     * @param $words_array
49
     * @return array
50
     */
51 19
    public function findMostSimilarWords($word, $words_array)
52
    {
53 19
        $this->refreshVariables();
54
55 19
        array_walk($words_array, array($this, 'similarityCallback'), $word);
56
57 19
        return $this->result_array;
58
    }
59
60
    /**
61
     * Вспомогательный метод для findBestMatch
62
     *
63
     * @param $item
64
     * @param $key
65
     * @param $word
66
     */
67 2
    private function findFinalSimilirityAndLevenshtein($item, $key, $word)
68
    {
69 2
        $this->meta_min_levenshtein = min($this->meta_min_levenshtein, levenshtein(metaphone($item), metaphone($word)));
70 2
        if (levenshtein($item, $word) == $this->meta_min_levenshtein) {
71 2
            $this->meta_similarity = max($this->meta_similarity, similar_text(metaphone($item), metaphone($word)));
72
        }
73 2
    }
74
75
    /**
76
     * Вспомогательный метод для findBestMatch
77
     *
78
     * @param $latin
79
     * @param $russian
80
     * @param $word
81
     */
82 2
    private function strictSimilarityCallback($latin, $russian, $word)
83
    {
84 2
        if (levenshtein(metaphone($latin), metaphone($word)) <= $this->meta_min_levenshtein) {
85 2
            if (similar_text(metaphone($latin), metaphone($word)) >= $this->meta_similarity) {
86 2
                $this->result_array[$russian] = $latin;
87
            }
88
        }
89 2
    }
90
91
    /**
92
     * Вспомогательный метод для findBestMatch
93
     *
94
     * @param $translit
95
     * @param $russian
96
     * @param $word
97
     */
98 9
    private function strictWordsLevenshteinHandlerCallback($translit, $russian, $word)
99
    {
100 9
        if (levenshtein(metaphone($word), metaphone($translit)) < mb_strlen(metaphone($word)) / 2) {
101 2
            if (levenshtein($word, $translit) < mb_strlen($word) / 2) {
102 2
                $this->words_array[$russian] = $translit;
103
            }
104
        }
105 9
    }
106
107
    /**
108
     * Вспомогательный метод для findMostSimilarWords
109
     *
110
     * @param $translit
111
     * @param $russian
112
     * @param $word
113
     */
114 12
    private function similarityCallback($translit, $russian, $word)
115
    {
116 12
        if (levenshtein($translit, $word) <= $this->min_levenshtein) {
117 12
            if (similar_text($translit, $word) >= $this->max_similarity) {
118 12
                $this->result_array = [];
119 12
                $this->min_levenshtein = levenshtein($translit, $word);
120 12
                $this->max_similarity = similar_text($translit, $word);
121 12
                $this->result_array[$russian] = $translit;
122
            }
123
        }
124 12
    }
125
126
    /**
127
     * Refresh variables
128
     */
129 19
    private function refreshVariables()
130
    {
131 19
        $this->max_similarity = 0;
132 19
        $this->meta_similarity = 0;
133 19
        $this->min_levenshtein = 1000;
134 19
        $this->meta_min_levenshtein = 1000;
135 19
    }
136
137
}
138