Test Failed
Branch master (a0b8e2)
by Konstantin
02:59
created

LevenshteinAlgorithmTrait::findBestMatch()   C

Complexity

Conditions 8
Paths 32

Size

Total Lines 28
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 28
rs 5.3846
cc 8
eloc 13
nc 32
nop 3
1
<?php
2
3
namespace GeoFixer\traits;
4
5
/**
6
 * Class LevenshteinAlgorithmTrait
7
 *
8
 * @package GeoFixer\traits
9
 */
10
trait LevenshteinAlgorithmTrait {
11
12
    public $similarity = 0;
13
    public $meta_similarity = 0;
14
    public $min_levenshtein = 1000;
15
    public $meta_min_levenshtein = 1000;
16
17
    /**
18
     * Строгий поиск
19
     *
20
     * @param $word
21
     * @param $translited_words
22
     * @param int $n
23
     * @return bool|mixed
24
     */
25
    public function findBestMatch($word, $translited_words, $n = 2)
26
    {
27
        $words_array = [];
28
        foreach($translited_words as $russian => $translit)
29
        {
30
31
            if(levenshtein(metaphone($word), metaphone($translit)) < mb_strlen(metaphone($word))/$n) {
32
                if(levenshtein($word, $translit) < mb_strlen($word)/$n) {
33
                    $words_array[$russian] = $translit;
34
                }
35
            }
36
        }
37
38
        $most_similar = $this->findMostSimilarWords($word, $words_array);
39
        $this->findFinalSimilirityAndLevenshtein($most_similar, $word);
40
41
42
        foreach($most_similar as $russian => $latin)
43
        {
44
            if(levenshtein(metaphone($latin), metaphone($word)) <= $this->meta_min_levenshtein) {
45
                if(similar_text(metaphone($latin), metaphone($word)) >= $this->meta_similarity) {
46
                    $meta_result[$russian] = $latin;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$meta_result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $meta_result = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
47
                }
48
            }
49
        }
50
51
        return @key($meta_result) ? @key($meta_result) : false;
52
    }
53
54
    /**
55
     * Нестрогий поиск
56
     *
57
     * @param $word
58
     * @param $words_array
59
     * @return array
60
     */
61
    public function findMostSimilarWords($word, $words_array)
62
    {
63
        $this->min_levenshtein = 1000;
64
        $this->similarity = 0;
65
66
        $result = [];
67
68
        foreach($words_array as $russian => $translit)
69
        {
70
            if (levenshtein($translit, $word) <= $this->min_levenshtein) {
71
                if (similar_text($translit, $word) >= $this->similarity) {
72
                    $this->min_levenshtein = levenshtein($translit, $word);
73
                    $this->similarity = similar_text($translit, $word);
74
                    $result = [];
75
                    $result[$russian] = $translit;
76
                }
77
            }
78
        }
79
80
        return $result;
81
    }
82
83
    /**
84
     * Вспомогательный метод для findBestMatch
85
     *
86
     * @param $most_similar
87
     * @param $word
88
     */
89
    private function findFinalSimilirityAndLevenshtein($most_similar, $word)
90
    {
91
        foreach($most_similar as $item) {
92
            $this->meta_min_levenshtein = min($this->meta_min_levenshtein, levenshtein(metaphone($item), metaphone($word)));
93
        }
94
95
        foreach($most_similar as $item)
96
        {
97
            if (levenshtein($item, $word) == $this->meta_min_levenshtein) {
98
                $this->meta_similarity = max($this->meta_similarity, similar_text(metaphone($item), metaphone($word)));
99
            }
100
        }
101
    }
102
103
}