Completed
Push — master ( f83339...b71f7d )
by Konstantin
02:22
created

GeoFixer::findKladrStreets()   B

Complexity

Conditions 6
Paths 13

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 6.027

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 37
ccs 20
cts 22
cp 0.9091
rs 8.439
cc 6
eloc 23
nc 13
nop 2
crap 6.027
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 23
    public function findSimilarWord($word, $search_array)
33
    {
34 23
        if (in_array($word, $search_array)) {
35 7
            return $word;
36
        }
37
38 19
        $word = $this->wordTranslit($word);
39
40 19
        $translited_words = $this->arrayTranslit($search_array);
41
42 19
        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 9
            $result = $this->findBestMatch($word, $translited_words);
44 9
            return $result;
45
        }
46
47 10
        $result = key($this->findMostSimilarWords($word, $translited_words));
48
49 10
        return $result ? $result : false;
50
    }
51
52
    /**
53
     * @param $region
54
     *
55
     * @return bool|mixed
56
     */
57 8
    public function findFiasRegion($region)
58
    {
59 8
        $regions = new RegionsDatabaseQuery();
60 8
        $regions = $regions->getRegions();
61
62 8
        if (is_integer($this->first_letters)) {
63 2
            $regions = $regions->firstLetters(substr($region, 0, $this->first_letters));
64
        }
65
66 8
        $regions = $regions->findAll();
67
68 8
        $titles = [];
69 8
        $regions_with_codes = [];
70
71 8
        foreach ($regions as $v) {
72 8
            $regions_with_codes[$v['title']] = $v['code'];
73 8
            $titles[] = $v['title'];
74
        }
75
76 8
        $result = $this->findSimilarWord($region, $titles);
77
78 8
        return $result ? $regions_with_codes[$result] : false;
79
    }
80
81
    /**
82
     * @param $city
83
     * @param $region_code
84
     *
85
     * @return bool|mixed
86
     */
87 4 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 4
        $settlements = new SettlementsDatabaseQuery();
90 4
        $settlements = $settlements->getSettlements()->regionCode($region_code)->addressLevel();
91
92 4
        if (is_integer($this->first_letters)) {
93 1
            $settlements = $settlements->firstLetters(substr($city, 0, $this->first_letters));
94
        }
95
96 4
        $settlements = $settlements->findAll();
97
98 4
        $titles = [];
99 4
        $settlements_with_id = [];
100
101 4
        foreach ($settlements as $v) {
102 4
            $settlements_with_id[$v['title']] = $v['address_id'];
103 4
            $titles[] = $v['title'];
104
        }
105
106 4
        $result = $this->findSimilarWord($city, $titles);
107
108 4
        return $result ? $settlements_with_id[$result] : false;
109
    }
110
111
    /**
112
     * @param $city
113
     * @param $region_code
114
     *
115
     * @return bool|mixed
116
     */
117 4
    public function findKladrSettlements($city, $region_code)
118
    {
119 4
        $settlements = new SettlementsDatabaseQuery();
120 4
        $settlements = $settlements->getSettlements()->regionCode($region_code)->addressLevel();
121
122 4
        if (is_integer($this->first_letters)) {
123 1
            $settlements = $settlements->firstLetters(substr($city, 0, $this->first_letters));
124
        }
125
126 4
        $settlements = $settlements->findAll();
127
128 4
        $titles = [];
129 4
        $settlements_with_id = [];
130
131 4
        foreach ($settlements as $v) {
132 4
            $settlements_with_id[$v['title']] = $v['code'];
133 4
            $titles[] = $v['title'];
134
        }
135
136 4
        $result = $this->findSimilarWord($city, $titles);
137
138 4
        if (!$result) {
139 1
            return false;
140
        }
141 3
        if (is_null($settlements_with_id[$result])) {
142
            return false;
143
        }
144
145 3
        return $settlements_with_id[$result];
146
    }
147
148
    /**
149
     * @param $street
150
     * @param $city_id
151
     *
152
     * @return bool|mixed
153
     */
154 3 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 3
        $streets = new StreetsDatabaseQuery();
157 3
        $streets = $streets->getStreets()->parentId($city_id)->addressLevel();
158
159 3
        if (is_integer($this->first_letters)) {
160 1
            $streets = $streets->firstLetters(substr($street, 0, $this->first_letters));
161
        }
162
163 3
        $streets = $streets->findAll();
164
165 3
        $titles = [];
166 3
        $streets_with_id = [];
167
168 3
        foreach ($streets as $v) {
169 3
            $streets_with_id[$v['title']] = $v['address_id'];
170 3
            $titles[] = $v['title'];
171
        }
172
173 3
        $result = $this->findSimilarWord($street, $titles);
174
175 3
        return $result ? $streets_with_id[$result] : false;
176
    }
177
178
    /**
179
     * @param $street
180
     * @param $city_code
181
     *
182
     * @return bool|mixed
183
     */
184 3
    public function findKladrStreets($street, $city_code)
185
    {
186 3
        $streets = new StreetsDatabaseQuery();
187 3
        $city = new SettlementsDatabaseQuery();
188 3
        $city_id = $city->getSettlements()->addressLevel(true)->kladrCode($city_code)->findOne();
189 3
        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 3
            $city_id = $city_id['address_id'];
191
        } else {
192
            return false;
193
        }
194 3
        $streets = $streets->getStreets()->parentId($city_id)->addressLevel();
195
196 3
        if (is_integer($this->first_letters)) {
197 1
            $streets = $streets->firstLetters(substr($street, 0, $this->first_letters));
198
        }
199
200 3
        $streets = $streets->findAll();
201
202 3
        $titles = [];
203 3
        $streets_with_id = [];
204
205 3
        foreach ($streets as $v) {
206 3
            $streets_with_id[$v['title']] = $v['code'];
207 3
            $titles[] = $v['title'];
208
        }
209
210 3
        $result = $this->findSimilarWord($street, $titles);
211
212 3
        if (!$result) {
213 1
            return false;
214
        }
215 2
        if (is_null($streets_with_id[$result])) {
216
            return false;
217
        }
218
219 2
        return $streets_with_id[$result];
220
    }
221
222
    /**
223
     * @param $house
224
     * @param $street_id
225
     *
226
     * @return bool
227
     */
228 4
    public function findFiasHouses($house, $street_id, $building = false)
229
    {
230 4
        $house_id = new HousesDatabaseQuery();
231 4
        $house_id = $house_id->getHouses()->addressId($street_id)->houseNumber($house);
232
233 4
        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 2
            $house_id = $house_id->building($building);
235
        }
236
237 4
        $house_id = $house_id->findOne();
238
239 4
        return $house_id ? $house_id['house_id'] : false;
240
    }
241
242
    /**
243
     * Включаем строгий режим поиска
244
     *
245
     * @param bool $strict
246
     */
247 23
    public function isStrict($strict = false)
248
    {
249 23
        $this->strict = $strict;
250 23
    }
251
252
253
    /**
254
     * Сколько первых букв должны совпадать при поиске по базам ФИАС
255
     *
256
     * (теоретически, снизит кол-во слов, которые придется обрабатывать алгоритмом и тем самым увеличит скорость работы, но может не найти слово, если первые буквы не совпадают
257
     * из-за опечатки или префиксов)
258
     *
259
     * @param bool $count
260
     */
261 20
    public function isFirstLetters($count = false)
262
    {
263 20
        if (is_int($count)) {
264 6
            $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 20
    }
267
268
    /**
269
     * Только города, или города и поселения
270
     *
271
     * @param bool $is_full
272
     */
273 8
    public function isFullSettlements($is_full = false)
274
    {
275 8
        $this->full_settlements = $is_full;
276 8
    }
277
}
278