1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
externallocationmap.php
См. документацию.
1<?php
2namespace Bitrix\Sale\Delivery;
3
4use Bitrix\Main\Error;
5use Bitrix\Sale\Result;
6use Bitrix\Main\Text\Encoding;
7use Bitrix\Main\SystemException;
8use Bitrix\Sale\Location\Comparator;
9use Bitrix\Main\ArgumentNullException;
10use Bitrix\Sale\Location\ExternalTable;
11use Bitrix\Sale\Location\LocationTable;
12use Bitrix\Sale\Location\ExternalServiceTable;
13
20{
21 //Dlivery idtifyer, stored in \Bitrix\Sale\Location\ExternalServiceTable : CODE
23 //Path to file (if exist) were we can get prepared locations map
24 const CSV_FILE_PATH = '';
25 const CITY_NAME_IDX = 0;
26 const REGION_NAME_IDX = 1;
27 const CITY_XML_ID_IDX = 2;
28
35 protected static function getAllLocations()
36 {
37 throw new SystemException('Must be impemented!');
38 }
39
45 public static function getInternalId($externalCode)
46 {
47 if($externalCode == '')
48 return 0;
49
50 $srvId = static::getExternalServiceId();
51
52 if($srvId <= 0)
53 return 0;
54
55 $res = ExternalTable::getList(array(
56 'filter' => array(
57 '=XML_ID' => $externalCode,
58 '=SERVICE_ID' => $srvId
59 )
60 ));
61
62 if($loc = $res->fetch())
63 return $loc['ID'];
64
65 return 0;
66 }
67
73 public static function getExternalId($locationId)
74 {
75 if($locationId == '')
76 return '';
77
78 $srvId = static::getExternalServiceId();
79
80 if($srvId <= 0)
81 return 0;
82
83 $res = LocationTable::getList(array(
84 'filter' => array(
85 array(
86 'LOGIC' => 'OR',
87 '=CODE' => $locationId,
88 '=ID' => $locationId
89 ),
90 '=EXTERNAL.SERVICE_ID' => $srvId
91 ),
92 'select' => array(
93 'ID', 'CODE',
94 'XML_ID' => 'EXTERNAL.XML_ID'
95 )
96 ));
97
98 $result = '';
99
100 if($loc = $res->fetch())
101 $result = $loc['XML_ID'];
102
103 if($result == '')
104 $result = self::getUpperCityExternalId($locationId, $srvId);
105
106 return $result;
107 }
108
109 protected static function getUpperCityExternalId($locationId, $srvId)
110 {
111 $result = '';
112
113 $res = LocationTable::getList(array(
114 'filter' => array(
115 array(
116 'LOGIC' => 'OR',
117 '=CODE' => $locationId,
118 '=ID' => $locationId
119 ),
120 ),
121 'select' => array(
122 'ID', 'CODE', 'LEFT_MARGIN', 'RIGHT_MARGIN',
123 'TYPE_CODE' => 'TYPE.CODE'
124 )
125 ));
126
127 if(!$loc = $res->fetch())
128 return '';
129
130 if($loc['TYPE_CODE'] == 'CITY')
131 return '';
132
133 $res = LocationTable::getList(array(
134 'filter' => array(
135 '<LEFT_MARGIN' => $loc['LEFT_MARGIN'],
136 '>RIGHT_MARGIN' => $loc['RIGHT_MARGIN'],
137 'TYPE.CODE' => 'CITY',
138 '=EXTERNAL.SERVICE_ID' => $srvId
139 ),
140 'select' => array(
141 'ID', 'CODE', 'LEFT_MARGIN', 'RIGHT_MARGIN',
142 'XML_ID' => 'EXTERNAL.XML_ID'
143 )
144 ));
145
146 if($locParent = $res->fetch())
147 return $locParent['XML_ID'];
148
149 return $result;
150 }
151
157 public static function getCityId($locationId)
158 {
159 if($locationId == '')
160 return 0;
161
162 $res = LocationTable::getList(array(
163 'filter' => array(
164 array(
165 'LOGIC' => 'OR',
166 '=CODE' => $locationId,
167 '=ID' => $locationId,
168 ),
169 array(
170 '=TYPE.CODE' => 'CITY',
171 '=PARENTS.TYPE.CODE' => 'CITY'
172 ),
173 ),
174 'select' => array(
175 'ID', 'CODE',
176 'TYPE_CODE' => 'TYPE.CODE',
177 'PID' => 'PARENTS.ID',
178 )
179 ));
180
181 if($loc = $res->fetch())
182 {
183 return $loc['PID'];
184 }
185
186 return 0;
187 }
188
189
194 public static function install()
195 {
196 $result = new Result();
197
198 if(static::isInstalled())
199 return $result;
200
201 $imported = static::importFromCsv($_SERVER['DOCUMENT_ROOT'].static::CSV_FILE_PATH);
202
203 if(intval($imported) <= 0)
204 $result = static::refresh();
205
206 return $result;
207 }
208
214 public static function unInstall()
215 {
216 $result = new Result();
217
218 if(!static::isInstalled())
219 return $result;
220
222 $sqlHelper = $con->getSqlHelper();
223 $srvId = $sqlHelper->forSql(static::getExternalServiceId());
224 $con->queryExecute("DELETE FROM b_sale_loc_ext WHERE SERVICE_ID=".$srvId);
225 ExternalServiceTable::delete($srvId);
226 return $result;
227 }
228
233 public static function isInstalled()
234 {
235 static $result = null;
236
237 if($result === null)
238 {
239 $result = false;
240 $res = ExternalServiceTable::getList(array(
241 'filter' => array(
242 '=CODE' => static::EXTERNAL_SERVICE_CODE,
243 '!=EXTERNAL.ID' => false
244 )
245 ));
246
247 if($res->fetch())
248 $result = true;
249 }
250
251 return $result;
252 }
253
259 public static function refresh()
260 {
261 set_time_limit(0);
262 $result = new Result();
263 $res = static::getAllLocations();
264
265 if($res->isSuccess())
266 {
267 $locations = $res->getData();
268
269 if(is_array($locations) && !empty($locations))
270 {
271 $res = static::setMap($locations);
272
273 if(!$res->isSuccess())
274 $result->addErrors($res->getErrors());
275 }
276 }
277 else
278 {
279 $result->addErrors($res->getErrors());
280 }
281
282 return new Result();
283 }
284
292 public static function importFromCsv($path)
293 {
294 set_time_limit(0);
295
296 if($path == '')
297 return 0;
298
299 if(!\Bitrix\Main\IO\File::isFileExists($path))
300 return 0;
301
303
304 if($content === false)
305 return 0;
306
308
309 if(intval($srvId) < 0)
310 return 0;
311
312 $lines = explode("\n", $content);
313
314 if(!is_array($lines))
315 return array();
316
317 $result = 0;
318
319 foreach($lines as $line)
320 {
321 $columns = explode(';', $line);
322
323 if(!is_array($columns) || count($columns) != 2)
324 continue;
325
326 $res = LocationTable::getList(array(
327 'filter' => array(
328 '=CODE' => $columns[0],
329 ),
330 'select' => array('ID')
331 ));
332
333 if($loc = $res->fetch())
334 if(self::setExternalLocation($srvId, $loc['ID'], $columns[1]))
335 $result++;
336 }
337
338 return $result;
339 }
340
346 public static function exportToCsv($path)
347 {
348 set_time_limit(0);
349 $srvId = static::getExternalServiceId();
350
351 if($srvId <= 0)
352 return false;
353
354 $res = LocationTable::getList(array(
355 'filter' => array(
356 '=EXTERNAL.SERVICE_ID' => $srvId
357 ),
358 'select' => array(
359 'CODE',
360 'XML_ID' => 'EXTERNAL.XML_ID'
361 )
362 ));
363
364 $content = '';
365
366 while($row = $res->fetch())
367 if($row['CODE'] <> '')
368 $content .= $row['CODE'].";".$row['XML_ID']."\n";
369
370 return \Bitrix\Main\IO\File::putFileContents($path, $content);
371 }
372
378 public static function getExternalServiceId()
379 {
380 if(static::EXTERNAL_SERVICE_CODE == '')
381 throw new SystemException('EXTERNAL_SERVICE_CODE must be defined!');
382
383 static $result = null;
384
385 if($result !== null)
386 return $result;
387
388 $res = ExternalServiceTable::getList(array(
389 'filter' => array('=CODE' => static::EXTERNAL_SERVICE_CODE)
390 ));
391
392 if($srv = $res->fetch())
393 {
394 $result = $srv['ID'];
395 return $result;
396 }
397
398 $res = ExternalServiceTable::add(array('CODE' => static::EXTERNAL_SERVICE_CODE));
399
400 if(!$res->isSuccess())
401 {
402 $result = 0;
403 return $result;
404 }
405
406 $result = $res->getId();
407 return $result;
408 }
409
418 protected static function setMap(array $cities)
419 {
420 $result = new Result();
421
422 if(empty($cities))
423 throw new ArgumentNullException('cities');
424
425 $xmlIdExist = array();
426 $locationIdExist = array();
427 $xmlIds = array_keys($cities);
428 $srvId = static::getExternalServiceId();
429
430 $res = ExternalTable::getList(array(
431 'filter' => array(
432 '=SERVICE_ID' => $srvId
433 )
434 ));
435
436 while($map = $res->fetch())
437 {
438 $xmlIdExist[] = $map['XML_ID'];
439 $locationIdExist[] = $map['LOCATION_ID'];
440
441 //we already have this location
442 if(in_array($map['XML_ID'], $xmlIds))
443 unset($cities[$map['XML_ID']]);
444 }
445
446 //nothing to import
447 if(empty($cities))
448 return $result;
449
450 foreach($cities as $city)
451 {
452 $xmlId = $city[self::CITY_XML_ID_IDX];
453 $locId = static::getLocationIdByNames($city[static::CITY_NAME_IDX], '', '', $city[static::REGION_NAME_IDX]);
454
455 if(intval($locId) > 0 && !in_array($xmlId, $xmlIdExist) && !in_array($locId, $locationIdExist))
456 {
457 ExternalTable::add(array(
458 'SERVICE_ID' => $srvId,
459 'LOCATION_ID' => $locId,
460 'XML_ID' => $xmlId
461 ));
462
463 $xmlIdExist[] = $xmlId;
464 $locationIdExist[] = $locId;
465 }
466
467 unset($cities[$xmlId]);
468 }
469
470 return $result;
471 }
472
483 public static function setExternalLocation2($srvId, $locationId, $xmlId, $updateExist = false)
484 {
485 if($xmlId == '')
486 throw new ArgumentNullException('code');
487
488 if($srvId == '')
489 throw new ArgumentNullException('srvId');
490
491 if(intval($locationId) <= 0)
492 throw new ArgumentNullException('locationId');
493
494 static $locCache = array();
495
496 if(!isset($locCache[$srvId]))
497 {
498 $locCache[$srvId] = array();
499
500 $eRes = ExternalTable::getList(array(
501 'filter' => array(
502 '=SERVICE_ID' => $srvId,
503 ),
504 'select' => array('ID', 'SERVICE_ID', 'LOCATION_ID', 'XML_ID')
505 ));
506
507 while($loc = $eRes->fetch())
508 $locCache[$srvId][$loc['LOCATION_ID'].'##'.$loc['XML_ID']] = $loc['ID'];
509 }
510
511 if(!empty($locCache[$srvId][$locationId.'##'.$xmlId]))
512 {
513 if($updateExist)
514 {
515 $res = ExternalTable::update(
516 $locCache[$srvId][$locationId.'##'.$xmlId],
517 array(
518 'SERVICE_ID' => $srvId,
519 'XML_ID' => $xmlId,
520 'LOCATION_ID' => $locationId
521 ));
522
523 return $res;
524 }
525 else
526 {
527 $result = new \Bitrix\Main\Entity\UpdateResult();
528 $result->addError(new Error('External location already exists', 'EXTERNAL_LOCATION_EXISTS'));
529 return $result;
530 }
531 }
532 else
533 {
534 $res = ExternalTable::add(array(
535 'SERVICE_ID' => $srvId,
536 'XML_ID' => $xmlId,
537 'LOCATION_ID' => $locationId
538 ));
539
540 $locCache[$srvId][$locationId.'##'.$xmlId] = $res->getId();
541 return $res;
542 }
543 }
544
555 public static function setExternalLocation($srvId, $locationId, $xmlId, $updateExist = false)
556 {
557 $result = self::setExternalLocation2($srvId, $locationId, $xmlId, $updateExist);
558 return $result->isSuccess();
559 }
560
561 protected static function isNormalizedTableFilled()
562 {
563 $count = 0;
565 $res = $con->query("SELECT COUNT(1) AS COUNT FROM b_sale_hdaln");
566
567 if($row = $res->fetch())
568 $count = intval($row['COUNT']);
569
570 return $count > 0;
571 }
572
580 public static function fillNormalizedTable($startId = false, $timeout = 0)
581 {
582 set_time_limit(0);
583 $startTime = mktime(true);
584 $lastProcessedId = 0;
586 $sqlHelper = $con->getSqlHelper();
587
588 if(intval($startId) <= 0)
589 $con->queryExecute("DELETE FROM b_sale_hdaln");
590
591 $query = "
592 SELECT
593 L.ID,
594 L.LEFT_MARGIN,
595 L.RIGHT_MARGIN,
596 N.NAME_UPPER
597 FROM
598 b_sale_location AS L
599 INNER JOIN b_sale_loc_name AS N ON L.ID = N.LOCATION_ID
600 INNER JOIN b_sale_loc_type AS T ON L.TYPE_ID = T.ID
601 WHERE
602 N.LANGUAGE_ID = 'ru'
603 AND (T.CODE = 'VILLAGE' OR T.CODE = 'CITY')
604 ";
605
606 if($startId !== false)
607 $query .= " AND L.ID > ".strval(intval($startId));
608
609 $query .= " ORDER BY ID ASC";
610 $res = $con->query($query);
611
612 while($loc = $res->fetch())
613 {
614 $con->queryExecute("
615 INSERT INTO
616 b_sale_hdaln (LOCATION_ID, LEFT_MARGIN, RIGHT_MARGIN, NAME)
617 VALUES(
618 ".intval($loc['ID']).",
619 ".intval($loc['LEFT_MARGIN']).",
620 ".intval($loc['RIGHT_MARGIN']).",
621 '".$sqlHelper->forSql(
622 preg_replace(
623 '/\s*(\‍(.*\‍))/iu',
624 '',
625 \Bitrix\Sale\Location\Comparator::flatten($loc['NAME_UPPER']))
626 )."'
627 )
628 ");
629
630 $lastProcessedId = $loc['ID'];
631
632 if($timeout > 0 && (mktime(true)-$startTime) >= $timeout)
633 break;
634 }
635
636 return $lastProcessedId;
637 }
638
650 public static function getLocationIdByNames($name, $city, $subregion, $region, $country = '', $exactOnly = false)
651 {
652 $nameNorm = Comparator::normalizeEntity($name, 'LOCALITY');
653 $subregionNorm = null;
654 $regionNorm = null;
655 $cityNorm = null;
656 $searchNames = array($name);
657
658 if(!$exactOnly)
659 $searchNames = array_merge($searchNames, \Bitrix\Sale\Location\Comparator::getLocalityNamesArray($nameNorm['NAME'], $nameNorm['TYPE']));
660
661 $searchNames = array_map(array('\Bitrix\Sale\Location\Comparator', 'flatten'), $searchNames);
662 $searchNames = array_map(function($name){return "'".$name."'";}, $searchNames);
663
664 if(empty($searchNames))
665 return 0;
666
668 $sqlHelper = $con->getSqlHelper();
669 $margins = array();
670 $res = $con->query("
671 SELECT
672 N.LOCATION_ID AS LOCATION_ID,
673 N.LEFT_MARGIN AS LEFT_MARGIN,
674 N.RIGHT_MARGIN AS RIGHT_MARGIN,
675 N.NAME AS NAME
676 FROM
677 b_sale_hdaln AS N
678 LEFT JOIN b_sale_loc_ext AS E
679 ON N.LOCATION_ID = E.LOCATION_ID AND E.SERVICE_ID = ".$sqlHelper->forSql(self::getExternalServiceId())."
680 WHERE
681 E.LOCATION_ID IS NULL
682 AND NAME IN (".implode(', ', $searchNames).")");
683
684 $results = array();
685 $exact = array();
686
687 while($loc = $res->fetch())
688 {
689 if(Comparator::isEntityEqual($loc['NAME'], $nameNorm, 'LOCALITY'))
690 {
691 $margins[] = array($loc['LOCATION_ID'], $loc['LEFT_MARGIN'], $loc['RIGHT_MARGIN'], $loc['NAME']);
692 $results[$loc['LOCATION_ID']] = array('NAME' => true);
693
694 if($loc['NAME'] == $nameNorm["NAME"])
695 $exact[] = $loc['LOCATION_ID'];
696 }
697 }
698
699 if(empty($margins))
700 return 0;
701
702 $marginFilter = array('LOGIC' => 'OR');
703
704 foreach($margins as $v)
705 $marginFilter[] = array('<LEFT_MARGIN' => $v[1], '>RIGHT_MARGIN' => $v[2]);
706
707 $res = LocationTable::getList(array(
708 'filter' => array(
709 '=NAME.LANGUAGE_ID' => LANGUAGE_ID,
710 '=TYPE.CODE' => array('SUBREGION', 'REGION', 'CITY'),
711 $marginFilter
712 ),
713 'select' => array(
714 'ID',
715 'PARENTS_NAME_UPPER' => 'NAME.NAME_UPPER',
716 'PARENTS_TYPE_CODE' => 'TYPE.CODE',
717 'LEFT_MARGIN', 'RIGHT_MARGIN'
718 )
719 ));
720
721 while($loc = $res->fetch())
722 {
723 $ids = self::getIdByMargin($loc['LEFT_MARGIN'], $loc['RIGHT_MARGIN'], $margins);
724
725 foreach($ids as $id)
726 {
727 if(in_array(false, $results[$id], true))
728 continue;
729
730 $found = null;
731
732 if($loc['PARENTS_TYPE_CODE'] == 'REGION' && $region <> '')
733 {
734 if(!is_array($regionNorm))
735 $regionNorm = Comparator::normalizeEntity($region, 'REGION');
736
737 $found = Comparator::isEntityEqual($loc['PARENTS_NAME_UPPER'], $regionNorm, 'REGION');
738 }
739 elseif($subregion <> '' && $loc['PARENTS_TYPE_CODE'] == 'SUBREGION')
740 {
741 if(!is_array($subregionNorm))
742 $subregionNorm = Comparator::normalizeEntity($subregion, 'SUBREGION');
743
744 $found = Comparator::isEntityEqual($loc['PARENTS_NAME_UPPER'], $subregionNorm, 'SUBREGION');
745 }
746 elseif($city <> '' && $loc['PARENTS_TYPE_CODE'] == 'CITY')
747 {
748 if(!is_array($cityNorm))
749 $subregionNorm = Comparator::normalizeEntity($city, 'LOCALITY');
750
751 $found = Comparator::isEntityEqual($loc['PARENTS_NAME_UPPER'], $cityNorm, 'LOCALITY');
752 }
753
754 if($found !== null)
755 {
756 $isInExact = in_array($id, $exact);
757 $results[$id][$loc['PARENTS_TYPE_CODE']] = $found;
758
759 if($results[$id]['REGION'] === true && $results[$id]['SUBREGION'] === true && $isInExact)
760 return $id;
761
762 if($found === false && $isInExact)
763 {
764 $key = array_search($id, $exact);
765
766 if($key !== false)
767 unset($exact[$key]);
768 }
769 }
770 }
771 }
772
773 if(!empty($exact))
774 foreach($exact as $e)
775 if(!in_array(false, $results[$e], true))
776 return $e;
777
778 $resCandidates = array();
779
780 foreach($results as $id => $result)
781 {
782 if(!in_array(false, $result, true))
783 {
784 $resCandidates[$id] = count($result);
785 }
786 }
787
788 if(empty($resCandidates))
789 return 0;
790
791 if(count($resCandidates) > 1)
792 {
793 arsort($resCandidates);
794 reset($resCandidates);
795 }
796
797 return key($resCandidates);
798 }
799
800 protected static function getIdByMargin($parentLeft, $parentRight, $lMargins)
801 {
802 $result = array();
803
804 foreach($lMargins as $m)
805 {
806 if($m[1] > $parentLeft && $m[2] < $parentRight)
807 $result[] = $m[0];
808 }
809
810 return $result;
811 }
812
813 protected static function getNameByMargin($parentLeft, $parentRight, $lMargins)
814 {
815 foreach($lMargins as $m)
816 {
817 if($m[1] > $parentLeft && $m[2] < $parentRight)
818 return $m[3];
819 }
820
821 return 0;
822 }
823}
$path
Определения access_edit.php:21
$con
Определения admin_tab.php:7
$count
Определения admin_tab.php:4
static getConnection($name="")
Определения application.php:638
Определения error.php:15
static getFileContents($path)
Определения file.php:255
static getCityId($locationId)
Определения externallocationmap.php:157
static getNameByMargin($parentLeft, $parentRight, $lMargins)
Определения externallocationmap.php:813
static setExternalLocation($srvId, $locationId, $xmlId, $updateExist=false)
Определения externallocationmap.php:555
static setExternalLocation2($srvId, $locationId, $xmlId, $updateExist=false)
Определения externallocationmap.php:483
static getIdByMargin($parentLeft, $parentRight, $lMargins)
Определения externallocationmap.php:800
static getInternalId($externalCode)
Определения externallocationmap.php:45
static getUpperCityExternalId($locationId, $srvId)
Определения externallocationmap.php:109
static getLocationIdByNames($name, $city, $subregion, $region, $country='', $exactOnly=false)
Определения externallocationmap.php:650
static fillNormalizedTable($startId=false, $timeout=0)
Определения externallocationmap.php:580
static getExternalId($locationId)
Определения externallocationmap.php:73
static setMap(array $cities)
Определения externallocationmap.php:418
$startTime
Определения sync.php:69
$content
Определения commerceml.php:144
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
$query
Определения get_search.php:11
$region
Определения .description.php:13
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
$name
Определения menu_edit.php:35
$map
Определения config.php:5
Определения directory.php:3
$country
Определения payment.php:59
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936