Completed
Push — master ( 2eeacf...293b4d )
by Konstantin
02:45
created

GeoFixer   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 245
Duplicated Lines 24.49 %

Coupling/Cohesion

Components 2
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 8
Bugs 1 Features 1
Metric Value
wmc 25
c 8
b 1
f 1
lcom 2
cbo 6
dl 60
loc 245
ccs 92
cts 92
cp 1
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A findFiasRegion() 15 15 2
A findSimilarWord() 0 16 3
A findFiasSettlements() 15 15 2
A findKladrSettlements() 15 15 2
A findFiasStreets() 15 15 2
A findKladrStreets() 0 23 3
A findFiasHouses() 0 13 3
A isStrict() 0 4 1
A isFirstLetters() 0 6 2
A isFullSettlements() 0 4 1
A geoDataHandler() 0 5 1
A getResult() 0 8 2

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