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

GeoFixer   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 261
Duplicated Lines 17.62 %

Coupling/Cohesion

Components 2
Dependencies 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 34
c 1
b 0
f 0
lcom 2
cbo 6
dl 46
loc 261
rs 9.2

10 Methods

Rating   Name   Duplication   Size   Complexity  
A findSimilarWord() 0 19 4
B findFiasRegion() 0 23 4
B findFiasSettlements() 23 23 4
B findKladrSettlements() 0 30 5
B findFiasStreets() 23 23 4
B findKladrStreets() 0 37 6
A findFiasHouses() 0 13 3
A isStrict() 0 4 1
A isFirstLetters() 0 6 2
A isFullSettlements() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace GeoFixer\models;
4
5
use GeoFixer\models\queries\RegionsDatabaseQuery;
6
use GeoFixer\models\queries\SettlementsDatabaseQuery;
7
use GeoFixer\models\queries\StreetsDatabaseQuery;
8
use GeoFixer\models\queries\HousesDatabaseQuery;
9
use GeoFixer\traits\TranslitTrait;
10
use GeoFixer\traits\LevenshteinAlgorithmTrait;
11
12
/**
13
 * Class GeoFixer
14
 *
15
 * @package GeoFixer\models
16
 */
17
class GeoFixer
18
{
19
    use TranslitTrait;
20
    use LevenshteinAlgorithmTrait;
21
22
    protected $strict = false;
23
    protected $first_letters = false;
24
    protected $full_settlements = false;
25
26
    /**
27
     * @param $word
28
     * @param $search_array
29
     *
30
     * @return string
31
     */
32
    public function findSimilarWord($word, $search_array)
33
    {
34
        if (in_array($word, $search_array)) {
35
            return $word;
36
        }
37
38
        $word = $this->wordTranslit($word);
39
40
        $translited_words = $this->arrayTranslit($search_array);
41
42
        if ($this->strict == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
43
            $result = $this->findBestMatch($word, $translited_words);
44
            return $result;
45
        }
46
47
        $result = key($this->findMostSimilarWords($word, $translited_words));
48
49
        return $result ? $result : false;
50
    }
51
52
    /**
53
     * @param $region
54
     *
55
     * @return bool|mixed
56
     */
57
    public function findFiasRegion($region)
58
    {
59
        $regions = new RegionsDatabaseQuery();
60
        $regions = $regions->getRegions();
61
62
        if (is_integer($this->first_letters)) {
63
            $regions = $regions->firstLetters(substr($region, 0, $this->first_letters));
64
        }
65
66
        $regions = $regions->findAll();
67
68
        $titles = [];
69
        $regions_with_codes = [];
70
71
        foreach ($regions as $v) {
72
            $regions_with_codes[$v['title']] = $v['code'];
73
            $titles[] = $v['title'];
74
        }
75
76
        $result = $this->findSimilarWord($region, $titles);
77
78
        return $result ? $regions_with_codes[$result] : false;
79
    }
80
81
    /**
82
     * @param $city
83
     * @param $region_code
84
     *
85
     * @return bool|mixed
86
     */
87 View Code Duplication
    public function findFiasSettlements($city, $region_code)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
88
    {
89
        $settlements = new SettlementsDatabaseQuery();
90
        $settlements = $settlements->getSettlements()->regionCode($region_code)->addressLevel();
91
92
        if (is_integer($this->first_letters)) {
93
            $settlements = $settlements->firstLetters(substr($city, 0, $this->first_letters));
94
        }
95
96
        $settlements = $settlements->findAll();
97
98
        $titles = [];
99
        $settlements_with_id = [];
100
101
        foreach ($settlements as $v) {
102
            $settlements_with_id[$v['title']] = $v['address_id'];
103
            $titles[] = $v['title'];
104
        }
105
106
        $result = $this->findSimilarWord($city, $titles);
107
108
        return $result ? $settlements_with_id[$result] : false;
109
    }
110
111
    /**
112
     * @param $city
113
     * @param $region_code
114
     *
115
     * @return bool|mixed
116
     */
117
    public function findKladrSettlements($city, $region_code)
118
    {
119
        $settlements = new SettlementsDatabaseQuery();
120
        $settlements = $settlements->getSettlements()->regionCode($region_code)->addressLevel();
121
122
        if (is_integer($this->first_letters)) {
123
            $settlements = $settlements->firstLetters(substr($city, 0, $this->first_letters));
124
        }
125
126
        $settlements = $settlements->findAll();
127
128
        $titles = [];
129
        $settlements_with_id = [];
130
131
        foreach ($settlements as $v) {
132
            $settlements_with_id[$v['title']] = $v['code'];
133
            $titles[] = $v['title'];
134
        }
135
136
        $result = $this->findSimilarWord($city, $titles);
137
138
        if (!$result) {
139
            return false;
140
        }
141
        if (is_null($settlements_with_id[$result])) {
142
            return false;
143
        }
144
145
        return $settlements_with_id[$result];
146
    }
147
148
    /**
149
     * @param $street
150
     * @param $city_id
151
     *
152
     * @return bool|mixed
153
     */
154 View Code Duplication
    public function findFiasStreets($street, $city_id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
    {
156
        $streets = new StreetsDatabaseQuery();
157
        $streets = $streets->getStreets()->parentId($city_id)->addressLevel();
158
159
        if (is_integer($this->first_letters)) {
160
            $streets = $streets->firstLetters(substr($street, 0, $this->first_letters));
161
        }
162
163
        $streets = $streets->findAll();
164
165
        $titles = [];
166
        $streets_with_id = [];
167
168
        foreach ($streets as $v) {
169
            $streets_with_id[$v['title']] = $v['address_id'];
170
            $titles[] = $v['title'];
171
        }
172
173
        $result = $this->findSimilarWord($street, $titles);
174
175
        return $result ? $streets_with_id[$result] : false;
176
    }
177
178
    /**
179
     * @param $street
180
     * @param $city_code
181
     *
182
     * @return bool|mixed
183
     */
184
    public function findKladrStreets($street, $city_code)
185
    {
186
        $streets = new StreetsDatabaseQuery();
187
        $city = new SettlementsDatabaseQuery();
188
        $city_id = $city->getSettlements()->addressLevel(true)->kladrCode($city_code)->findOne();
189
        if ($city_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $city_id of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
190
            $city_id = $city_id['address_id'];
191
        } else {
192
            return false;
193
        }
194
        $streets = $streets->getStreets()->parentId($city_id)->addressLevel();
195
196
        if (is_integer($this->first_letters)) {
197
            $streets = $streets->firstLetters(substr($street, 0, $this->first_letters));
198
        }
199
200
        $streets = $streets->findAll();
201
202
        $titles = [];
203
        $streets_with_id = [];
204
205
        foreach ($streets as $v) {
206
            $streets_with_id[$v['title']] = $v['code'];
207
            $titles[] = $v['title'];
208
        }
209
210
        $result = $this->findSimilarWord($street, $titles);
211
212
        if (!$result) {
213
            return false;
214
        }
215
        if (is_null($streets_with_id[$result])) {
216
            return false;
217
        }
218
219
        return $streets_with_id[$result];
220
    }
221
222
    /**
223
     * @param $house
224
     * @param $street_id
225
     *
226
     * @return bool
227
     */
228
    public function findFiasHouses($house, $street_id, $building = false)
229
    {
230
        $house_id = new HousesDatabaseQuery();
231
        $house_id = $house_id->getHouses()->addressId($street_id)->houseNumber($house);
232
233
        if ($building != false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
234
            $house_id = $house_id->building($building);
235
        }
236
237
        $house_id = $house_id->findOne();
238
239
        return $house_id ? $house_id['house_id'] : false;
240
    }
241
242
    /**
243
     * Включаем строгий режим поиска
244
     *
245
     * @param bool $strict
246
     */
247
    public function isStrict($strict = false)
248
    {
249
        $this->strict = $strict;
250
    }
251
252
253
    /**
254
     * Сколько первых букв должны совпадать при поиске по базам ФИАС
255
     *
256
     * (теоретически, снизит кол-во слов, которые придется обрабатывать алгоритмом и тем самым увеличит скорость работы, но может не найти слово, если первые буквы не совпадают
257
     * из-за опечатки или префиксов)
258
     *
259
     * @param bool $count
260
     */
261
    public function isFirstLetters($count = false)
262
    {
263
        if (is_int($count)) {
264
            $this->first_letters = $count;
0 ignored issues
show
Documentation Bug introduced by
The property $first_letters was declared of type boolean, but $count is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
265
        }
266
    }
267
268
    /**
269
     * Только города, или города и поселения
270
     *
271
     * @param bool $is_full
272
     */
273
    public function isFullSettlements($is_full = false)
274
    {
275
        $this->full_settlements = $is_full;
276
    }
277
}
278