Completed
Push — master ( 06a9c4...74d951 )
by Konstantin
04:28
created

GeoFixer::findFiasSettlements()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 19
Code Lines 10

Duplication

Lines 19
Ratio 100 %

Code Coverage

Tests 10
CRAP Score 3

Importance

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