Completed
Push — master ( b71f7d...42978d )
by Konstantin
02:00
created

GeoFixer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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