Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
geoip.php
1<?php
2
4
9
10class GeoIp
11{
17 public static function getLocationId($ip = '', $lang = LANGUAGE_ID)
18 {
19 $fields = array();
20 $geoData = self::getData($ip, $lang);
21
22 if($geoData)
23 $fields = self::getLocationFields($geoData, $lang);
24
25 return intval($fields['ID']) > 0 ? intval($fields['ID']) : 0;
26 }
27
33 public static function getLocationCode($ip = '', $lang = LANGUAGE_ID)
34 {
35 $fields = array();
36 $geoData = self::getData($ip, $lang);
37
38 if ($geoData)
39 {
40 $fields = self::getLocationFields($geoData, $lang);
41 }
42
43 return isset($fields['CODE']) && $fields['CODE'] !== '' ? $fields['CODE'] : '';
44 }
45
51 public static function getZipCode($ip, $lang = LANGUAGE_ID)
52 {
53 $data = self::getData($ip, $lang);
54
55 if(!$data)
56 $result = '';
57 else
58 $result = $data->getGeoData()->zipCode <> '' ? $data->getGeoData()->zipCode : '';
59
60 return $result;
61 }
62
68 protected static function getData($ip, $lang)
69 {
70 return Manager::getDataResult($ip, $lang, array('cityName'));
71 }
72
78 protected static function getLocationFields(Result $geoIpData, $lang = LANGUAGE_ID)
79 {
80 if(!$geoIpData->isSuccess())
81 {
82 return [];
83 }
84
85 $geoData = $geoIpData->getGeoData();
86
87 if($geoData->cityName == null)
88 {
89 return [];
90 }
91
92 $res = LocationTable::getList([
93 'filter' => [
94 '=NAME.NAME_UPPER' => ToUpper($geoData->cityName),
95 '=NAME.LANGUAGE_ID' => $lang
96 ],
97 'select' => ['ID', 'CODE', 'LEFT_MARGIN', 'RIGHT_MARGIN']
98 ]);
99
100 $locations = [];
101
102 while($loc = $res->fetch())
103 {
104 $locations[$loc['ID']] = $loc;
105 }
106
107 $result = [];
108 $locationsCount = count($locations);
109
110 if($locationsCount == 1)
111 {
112 $result = current($locations);
113 }
114 elseif($locationsCount > 1)
115 {
116 $result = self::specifyLocationByParents($geoData, $locations, $lang);
117 }
118
119 return $result;
120 }
121
122 protected static function isParentsEmpty(Data $geoData)
123 {
124 return empty($geoData->countryName) && empty($geoData->subRegionName) && empty($geoData->regionName);
125 }
126
127 protected static function specifyLocationByParents(Data $geoData, array $locations, $lang)
128 {
129 if(empty($locations))
130 {
131 return [];
132 }
133
134 if(self::isParentsEmpty($geoData))
135 {
136 reset($locations);
137 return current($locations);
138 }
139
140 $marginConditions = [
141 'LOGIC' => 'OR'
142 ];
143
144 foreach($locations as $location)
145 {
146 $marginConditions[] = [
147 'LOGIC' => 'AND',
148 '<LEFT_MARGIN' => $location['LEFT_MARGIN'],
149 '>RIGHT_MARGIN' => $location['RIGHT_MARGIN']
150 ];
151 }
152
153 $params = [
154 'filter' => [
155 $marginConditions,
156 'NAME.LANGUAGE_ID' => $lang,
157 ],
158 'select' => [
159 'ID', 'LEFT_MARGIN', 'RIGHT_MARGIN',
160 'LOCATION_NAME_UPPER' => 'NAME.NAME_UPPER'
161 ]
162 ];
163
164 $res = \Bitrix\Sale\Location\LocationTable::getList($params);
165 $weight = [];
166 $result = [];
167 $normalizer = self::getNameNormalizer($lang);
168 $country = $normalizer->normalize($geoData->countryName);
169 $region = $normalizer->normalize($geoData->regionName);
170 $subRegion = $normalizer->normalize($geoData->subRegionName);
171
172 while($loc = $res->fetch())
173 {
174 $isNameMatched = self::isNormalizedNamesMatched(
175 $normalizer->normalize($loc['LOCATION_NAME_UPPER']),
176 $country,
177 $region,
178 $subRegion
179 );
180
181 if($isNameMatched)
182 {
183 $locationIds = self::getLocationIdsByMargins($locations, $loc['LEFT_MARGIN'], $loc['RIGHT_MARGIN']);
184
185 foreach($locationIds as $locationId)
186 {
187 if(!isset($locationId))
188 {
189 $weight[$locationId] = 0;
190 }
191
192 $weight[$locationId]++;
193 }
194 }
195 }
196
197 if(!empty($weight))
198 {
199 arsort($weight);
200 reset($weight);
201 $id = key($weight);
202
203 if(isset($locations[$id]))
204 {
205 $result = $locations[$id];
206 }
207 }
208
209 return $result;
210 }
211
212 protected static function getLocationIdsByMargins(array $locations, $leftMargin, $rightMargin)
213 {
214 $result = [];
215
216 foreach($locations as $locationId => $location)
217 {
218 if($location['LEFT_MARGIN'] >= $leftMargin && $location['RIGHT_MARGIN'] <= $rightMargin)
219 {
220 $result[] = $location['ID'];
221 }
222 }
223
224 return $result;
225 }
226
231 protected static function getNameNormalizer($lang)
232 {
233 return Builder::build($lang);
234 }
235
242 protected static function isNameMatched(Data $geoData, $name, $lang)
243 {
244 static $normalizer = null;
245
246 if($normalizer === null)
247 {
248 $normalizer = self::getNameNormalizer($lang);
249 }
250
251 $name = $normalizer->normalize($name);
252
253 return $normalizer->normalize($geoData->countryName) == $name
254 || $normalizer->normalize($geoData->regionName) == $name
255 || $normalizer->normalize($geoData->subRegionName) == $name;
256 }
257
267 protected static function isNormalizedNamesMatched($name, $country, $region, $subregion)
268 {
269 if($name == '')
270 {
271 return true;
272 }
273
274 if($country == '' && $region == '' && $subregion == '')
275 {
276 return true;
277 }
278
279 $result = true;
280 $checked = false;
281
282 if($country !== '')
283 {
284 $result = $country === $name;
285 $checked = true;
286 }
287
288 if((!$checked || !$result) && $region !== '')
289 {
290 $result = $region === $name;
291 $checked = true;
292 }
293
294 if((!$checked || !$result) && $subregion !== '')
295 {
296 $result = $subregion === $name;
297 }
298
299 return $result;
300 }
301}
static getDataResult($ip='', $lang='', array $required=[])
Definition manager.php:191
static getLocationFields(Result $geoIpData, $lang=LANGUAGE_ID)
Definition geoip.php:78
static isNameMatched(Data $geoData, $name, $lang)
Definition geoip.php:242
static getNameNormalizer($lang)
Definition geoip.php:231
static specifyLocationByParents(Data $geoData, array $locations, $lang)
Definition geoip.php:127
static getData($ip, $lang)
Definition geoip.php:68
static isParentsEmpty(Data $geoData)
Definition geoip.php:122
static isNormalizedNamesMatched($name, $country, $region, $subregion)
Definition geoip.php:267
static getLocationIdsByMargins(array $locations, $leftMargin, $rightMargin)
Definition geoip.php:212
static getLocationCode($ip='', $lang=LANGUAGE_ID)
Definition geoip.php:33
static getLocationId($ip='', $lang=LANGUAGE_ID)
Definition geoip.php:17
static getZipCode($ip, $lang=LANGUAGE_ID)
Definition geoip.php:51