Completed
Push — master ( d6e5b5...111799 )
by Konstantin
01:37
created

GeoFixer::findKladrSettlements()   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 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
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|false|null
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
        $result = $this->strict === true ?
86 9
            $this->fuzzy_helper->findBestMatch($word, $translited_words) :
87 19
            key($this->fuzzy_helper->findMostSimilarWords($word, $translited_words));
88
89 19
        return $result;
90
    }
91
92
    /**
93
     * @param $city
94
     * @param $region_code
95
     *
96
     * @return bool|mixed
97
     */
98 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...
99
    {
100 4
        $this->code_name = AbstractDatabaseQuery::FIAS_CODE;
101
102 4
        $settlements = new SettlementsDatabaseQuery();
103 4
        $settlements = $settlements->getSettlements()->regionCode($region_code)->addressLevel();
104
105 4
        if (is_integer($this->first_letters)) {
106 1
            $settlements = $settlements->firstLetters(substr($city, 0, $this->first_letters));
107
        }
108
109 4
        $settlements = $settlements->findAll();
110
111 4
        array_map(array($this, 'geoDataHandler'), $settlements);
112
113 4
        $result = $this->findSimilarWord($city, $this->geo_titles);
114
115 4
        return $result ? $this->geo_with_ids[$result] : false;
116
    }
117
118
    /**
119
     * @param $city
120
     * @param $region_code
121
     *
122
     * @return bool|mixed
123
     */
124 4 View Code Duplication
    public function findKladrSettlements($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...
125
    {
126 4
        $this->code_name = AbstractDatabaseQuery::KLADR_CODE;
127
128 4
        $settlements = new SettlementsDatabaseQuery();
129 4
        $settlements = $settlements->getSettlements()->regionCode($region_code)->addressLevel();
130
131 4
        if (is_integer($this->first_letters)) {
132 1
            $settlements = $settlements->firstLetters(substr($city, 0, $this->first_letters));
133
        }
134
135 4
        $settlements = $settlements->findAll();
136
137 4
        array_map(array($this, 'geoDataHandler'), $settlements);
138
139 4
        $result = $this->findSimilarWord($city, $this->geo_titles);
140
141 4
        return $result ? $this->geo_with_ids[$result] : false;
142
    }
143
144
    /**
145
     * @param $street
146
     * @param $city_id
147
     *
148
     * @return bool|mixed
149
     */
150 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...
151
    {
152 3
        $this->code_name = AbstractDatabaseQuery::FIAS_CODE;
153
154 3
        $streets = new StreetsDatabaseQuery();
155 3
        $streets = $streets->getStreets()->parentId($city_id)->addressLevel();
156
157 3
        if (is_integer($this->first_letters)) {
158 1
            $streets = $streets->firstLetters(substr($street, 0, $this->first_letters));
159
        }
160
161 3
        $streets = $streets->findAll();
162
163 3
        array_map(array($this, 'geoDataHandler'), $streets);
164
165 3
        $result = $this->findSimilarWord($street, $this->geo_titles);
166
167 3
        return $result ? $this->geo_with_ids[$result] : false;
168
    }
169
170
    /**
171
     * @param $street
172
     * @param $city_code
173
     *
174
     * @return bool|mixed
175
     */
176 3
    public function findKladrStreets($street, $city_code)
177
    {
178 3
        $this->code_name = AbstractDatabaseQuery::KLADR_CODE;
179
180 3
        $streets = new StreetsDatabaseQuery();
181 3
        $city = new SettlementsDatabaseQuery();
182 3
        $city_id = $city->getSettlements()->addressLevel(true)->kladrCode($city_code)->findOne();
183
184 3
        if ($city_id === false) {
185
            return false;
186
        }
187
188 3
        $city_id = $city_id['address_id'];
189 3
        $streets = $streets->getStreets()->parentId($city_id)->addressLevel();
190
191 3
        if (is_integer($this->first_letters)) {
192 1
            $streets = $streets->firstLetters(substr($street, 0, $this->first_letters));
193
        }
194
195 3
        $streets = $streets->findAll();
196
197 3
        array_map(array($this, 'geoDataHandler'), $streets);
198
199 3
        $result = $this->findSimilarWord($street, $this->geo_titles);
200
201 3
        return $result ? $this->geo_with_ids[$result] : false;
202
    }
203
204
    /**
205
     * @param $house
206
     * @param $street_id
207
     *
208
     * @return bool
209
     */
210 4
    public function findFiasHouses($house, $street_id, $building = false)
211
    {
212 4
        $house_id = new HousesDatabaseQuery();
213 4
        $house_id = $house_id->getHouses()->addressId($street_id)->houseNumber($house);
214
215 4
        if ($building !== false) {
216 2
            $house_id = $house_id->building($building);
217
        }
218
219 4
        $house_id = $house_id->findOne();
220
221 4
        return $house_id ? $house_id['house_id'] : false;
222
    }
223
224
    /**
225
     * Включаем строгий режим поиска
226
     *
227
     * @param bool $strict
228
     */
229 23
    public function isStrict($strict = false)
230
    {
231 23
        $this->strict = $strict;
232 23
    }
233
234
235
    /**
236
     * Сколько первых букв должны совпадать при поиске по базам ФИАС
237
     *
238
     * (теоретически, снизит кол-во слов, которые придется обрабатывать алгоритмом и тем самым увеличит скорость работы, но может не найти слово, если первые буквы не совпадают
239
     * из-за опечатки или префиксов)
240
     *
241
     * @param int|bool $count
242
     */
243 20
    public function isFirstLetters($count = false)
244
    {
245 20
        if (is_int($count)) {
246 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...
247
        }
248 20
    }
249
250
    /**
251
     * Только города, или города и поселения
252
     *
253
     * @param bool $is_full
254
     */
255 8
    public function isFullSettlements($is_full = false)
256
    {
257 8
        $this->full_settlements = $is_full;
258 8
    }
259
260
    /**
261
     * @param $geo_array
262
     */
263 20
    protected function geoDataHandler($geo_array)
264
    {
265 20
        $this->geo_with_ids[$geo_array[$this->title_name]] = $geo_array[$this->code_name];
266 20
        $this->geo_titles[] = $geo_array[$this->title_name];
267 20
    }
268
}
269
270