Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
location.php
1<?php
9
10use Bitrix\Main;
14
19
20Loc::loadMessages(__FILE__);
21
38final class LocationTable extends Tree
39{
40 public static function getFilePath()
41 {
42 return __FILE__;
43 }
44
45 public static function getTableName()
46 {
47 return 'b_sale_location';
48 }
49
59 public static function getByCode($code = '', $parameters = array())
60 {
61 $code = Assert::expectStringNotNull($code, '$code');
62
63 if(!is_array($parameters))
64 $parameters = array();
65
66 $parameters['filter']['=CODE'] = $code;
67 $parameters['limit'] = 1;
68
69 return self::getList($parameters);
70 }
71
72 public static function checkFields(Entity\Result $result, $primary, array $data)
73 {
74 parent::checkFields($result, $primary, $data);
75
76 foreach(static::getEntity()->getFields() as $field)
77 {
78 $error = false;
79
80 if($field->getName() == 'LATITUDE' && mb_strlen($data['LATITUDE']))
81 {
82 // latitude is set in data and not empty, it must lay between -90 and 90
83 if(!is_numeric($data['LATITUDE']))
84 $error = Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_LATITUDE_TYPE_ERROR');
85 elseif(($latitude = floatval($data['LATITUDE'])) && ($latitude < -90 || $latitude > 90))
86 $error = Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_LATITUDE_RANGE_ERROR');
87 }
88
89 if($field->getName() == 'LONGITUDE' && mb_strlen($data['LONGITUDE']))
90 {
91 // longitude is set in data and not empty, it must lay between -180 and 180
92 if(!is_numeric($data['LONGITUDE']))
93 $error = Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_LONGITUDE_TYPE_ERROR');
94 elseif(($longitude = floatval($data['LONGITUDE'])) && ($longitude < -180 || $longitude > 180))
95 $error = Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_LONGITUDE_RANGE_ERROR');
96 }
97
98 if($error !== false)
99 {
100 $result->addError(new Entity\FieldError(
101 $field,
102 $error,
103 Entity\FieldError::INVALID_VALUE
104 ));
105 }
106 }
107 }
108
109 public static function add(array $data)
110 {
111 return self::addExtended($data);
112 }
113
138 public static function addExtended(array $data, array $additional = array())
139 {
140 $resetLegacy = !isset($additional['RESET_LEGACY']) || $additional['RESET_LEGACY'] !== false;
141
142 if(isset($data['EXTERNAL']))
143 {
144 $external = $data['EXTERNAL'];
145 unset($data['EXTERNAL']);
146 }
147
148 if(isset($data['NAME']))
149 {
150 $name = $data['NAME'];
151 unset($data['NAME']);
152 }
153
154 // force code to lowercase
155 if(isset($data['CODE']))
156 $data['CODE'] = ToLower($data['CODE']);
157
158 // you are not allowed to modify tree data over LocationTable::add()
160
161 // store tree data and basic
162 $addResult = parent::addExtended($data, $additional);
163
164 // add connected data
165 if($addResult->isSuccess())
166 {
167 $primary = $addResult->getId();
168
169 // external
170 if(isset($external))
171 ExternalTable::addMultipleForOwner($primary, $external);
172
173 // names
174 if(isset($name))
175 Name\LocationTable::addMultipleForOwner($primary, $name);
176
177 if(intval($data['TYPE_ID']) > 0 && $resetLegacy)
178 self::resetLegacy(intval($data['TYPE_ID']));
179
180 Search\Finder::setIndexInvalid();
181 $GLOBALS['CACHE_MANAGER']->ClearByTag('sale-location-data');
182 }
183
184 return $addResult;
185 }
186
187 protected static function resetLegacy($typeId)
188 {
189 $type = TypeTable::getList(array('filter' => array('=ID' => $typeId), 'select' => array('CODE')))->fetch();
190 if(mb_strlen($type['CODE']) && in_array($type['CODE'], array('COUNTRY', 'REGION', 'CITY')))
191 static::resetLegacyPath();
192 }
193
194 public static function update($primary, array $data)
195 {
196 return self::updateExtended($primary, $data);
197 }
223 public static function updateExtended($primary, array $data, array $additional = array())
224 {
225 $primary = Assert::expectIntegerPositive($primary, '$primary');
226 $resetLegacy = !isset($additional['RESET_LEGACY']) || $additional['RESET_LEGACY'] !== false;
227
228 // first update parent, and if it succeed, do updates of the connected data
229
230 if(isset($data['EXTERNAL']))
231 {
232 $external = $data['EXTERNAL'];
233 unset($data['EXTERNAL']);
234 }
235
236 if(isset($data['NAME']))
237 {
238 $name = $data['NAME'];
239 unset($data['NAME']);
240 }
241
242 // force code to lowercase
243 if(isset($data['CODE']))
244 $data['CODE'] = ToLower($data['CODE']);
245
246 // you are not allowed to modify tree data over LocationTable::update()
248
249 $updResult = parent::updateExtended($primary, $data, $additional);
250
251 // update connected data
252 if($updResult->isSuccess())
253 {
254 // external
255 if(isset($external))
256 ExternalTable::updateMultipleForOwner($primary, $external);
257
258 // names
259 if(isset($name))
260 Name\LocationTable::updateMultipleForOwner($primary, $name);
261
262 if($resetLegacy && (intval($data['TYPE_ID']) > 0 || isset($data['PARENT_ID'])))
263 self::resetLegacy(intval($data['TYPE_ID']));
264
265 $GLOBALS['CACHE_MANAGER']->ClearByTag('sale-location-data');
266
267 if(isset($name) || isset($data['PARENT_ID']))
268 Search\Finder::setIndexInvalid();
269 }
270
271 return $updResult;
272 }
273
274 public static function delete($primary)
275 {
276 return self::deleteExtended($primary);
277 }
288 public static function deleteExtended($primary, array $additional = array())
289 {
290 $primary = Assert::expectIntegerPositive($primary, '$primary');
291 $resetLegacy = !isset($additional['RESET_LEGACY']) || $additional['RESET_LEGACY'] !== false;
292 $deleteSubtree = !isset($additional['DELETE_SUBTREE']) || $additional['DELETE_SUBTREE'] !== false;
293
294 // delete connected data of sub-nodes
295 if($deleteSubtree)
296 {
297 $rangeSql = parent::getSubtreeRangeSqlForNode($primary);
298 Name\LocationTable::deleteMultipleByParentRangeSql($rangeSql);
300 }
301
302 if($resetLegacy)
303 $data = static::getList(array('filter' => array('=ID' => $primary), 'select' => array('TYPE_ID')))->fetch();
304
305 $delResult = parent::deleteExtended($primary, $additional);
306
307 // delete connected data
308 if($delResult->isSuccess())
309 {
310 Name\LocationTable::deleteMultipleForOwner($primary);
312
313 if($resetLegacy && intval($data['TYPE_ID']))
314 {
315 $type = TypeTable::getList(array('filter' => array('=ID' => $data['TYPE_ID']), 'select' => array('CODE')))->fetch();
316 if(mb_strlen($type['CODE']) && in_array($type['CODE'], array('COUNTRY', 'REGION', 'CITY')))
317 static::resetLegacyPath();
318 }
319
320 $GLOBALS['CACHE_MANAGER']->ClearByTag('sale-location-data');
321 Search\Finder::setIndexInvalid();
322 }
323
324 return $delResult;
325 }
326
332 public static function getExternalData($primary, $parameters = array())
333 {
334 $primary = Assert::expectIntegerPositive($primary, '$primary');
335
336 if(!is_array($parameters) || empty($parameters))
337 $parameters = array();
338
339 $parameters['filter']['LOCATION_ID'] = $primary;
340
341 return ExternalTable::getList($parameters);
342 }
343
344 // todo: make getList with SITE_ID parameter to have an ability to filter by SITE_ID using orm (even slowly)
345
352 public static function getPathToNodeByCode($code, $parameters, $behaviour = array('SHOW_LEAF' => true))
353 {
354 $code = Assert::expectStringNotNull($code, '$code');
355
356 return self::getPathToNodeByCondition(array('=CODE' => $code), $parameters, $behaviour);
357 }
358
359 public static function checkNodeIsParentOfNode($primary, $childPrimary, $behaviour = array('ACCEPT_CODE' => false, 'CHECK_DIRECT' => false))
360 {
361 if(!$behaviour['ACCEPT_CODE'])
362 return static::checkNodeIsParentOfNodeById($primary, $childPrimary, $behaviour);
363
364 $primary = Assert::expectStringNotNull($primary, '$primary');
365 $childPrimary = Assert::expectStringNotNull($childPrimary, '$childPrimary');
366
367 return static::checkNodeIsParentOfNodeByFilters(array('=CODE' => $primary), array('=CODE' => $childPrimary), $behaviour);
368 }
369
370 public static function resetLegacyPath()
371 {
372 $dbConnection = Main\HttpApplication::getConnection();
373 $locTable = static::getTableName();
374
375 $types = array();
376 $res = TypeTable::getList(array(
377 'filter' => array('CODE' => array('COUNTRY', 'REGION', 'CITY')),
378 'select' => array('ID', 'CODE')
379 ));
380 while($item = $res->fetch())
381 $types[$item['CODE']] = $item['ID'];
382
383 if(!empty($types))
384 {
385 if(!$dbConnection->isTableExists('b_sale_loc_rebind'))
386 $dbConnection->query("create table b_sale_loc_rebind (TARGET_ID ".Helper::getSqlForDataType('int').", LOCATION_ID ".Helper::getSqlForDataType('int').")");
387 else
388 $dbConnection->query("truncate table b_sale_loc_rebind");
389
390 $sqlWhere = array();
391 foreach($types as $code => $id)
392 $sqlWhere[] = "'".intval($id)."'";
393
394 $dbConnection->query("update ".$locTable." set COUNTRY_ID = NULL, REGION_ID = NULL, CITY_ID = NULL where TYPE_ID in (".implode(', ', $sqlWhere).")");
395
396 if(intval($types['REGION']) && intval($types['COUNTRY']))
397 {
398 // countries for regions
399 $dbConnection->query("insert into b_sale_loc_rebind (TARGET_ID, LOCATION_ID) select A.ID as ONE, B.ID as TWO from ".$locTable." A inner join ".$locTable." B on A.TYPE_ID = '".intval($types['REGION'])."' and B.TYPE_ID = '".intval($types['COUNTRY'])."' and B.LEFT_MARGIN <= A.LEFT_MARGIN and B.RIGHT_MARGIN >= A.RIGHT_MARGIN");
400 Helper::mergeTables($locTable, 'b_sale_loc_rebind', array('COUNTRY_ID' => 'LOCATION_ID'), array('ID' => 'TARGET_ID'));
401 $dbConnection->query("truncate table b_sale_loc_rebind");
402 }
403
404 if(intval($types['REGION']) && intval($types['CITY']))
405 {
406 // regions for cities
407 $dbConnection->query("insert into b_sale_loc_rebind (TARGET_ID, LOCATION_ID) select A.ID as ONE, B.ID as TWO from ".$locTable." A inner join ".$locTable." B on A.TYPE_ID = '".intval($types['CITY'])."' and B.TYPE_ID = '".intval($types['REGION'])."' and B.LEFT_MARGIN <= A.LEFT_MARGIN and B.RIGHT_MARGIN >= A.RIGHT_MARGIN");
408 Helper::mergeTables($locTable, 'b_sale_loc_rebind', array('REGION_ID' => 'LOCATION_ID'), array('ID' => 'TARGET_ID'));
409 $dbConnection->query("truncate table b_sale_loc_rebind");
410 }
411
412 if(intval($types['COUNTRY']) && intval($types['CITY']))
413 {
414 // countries for cities
415 $dbConnection->query("insert into b_sale_loc_rebind (TARGET_ID, LOCATION_ID) select A.ID as ONE, B.ID as TWO from ".$locTable." A inner join ".$locTable." B on A.TYPE_ID = '".intval($types['CITY'])."' and B.TYPE_ID = '".intval($types['COUNTRY'])."' and B.LEFT_MARGIN <= A.LEFT_MARGIN and B.RIGHT_MARGIN >= A.RIGHT_MARGIN");
416 Helper::mergeTables($locTable, 'b_sale_loc_rebind', array('COUNTRY_ID' => 'LOCATION_ID'), array('ID' => 'TARGET_ID'));
417 }
418
419 Helper::dropTable('b_sale_loc_rebind');
420
421 if(intval($types['COUNTRY']))
422 $dbConnection->query("update ".$locTable." set COUNTRY_ID = ID where TYPE_ID = '".intval($types['COUNTRY'])."'");
423
424 if(intval($types['REGION']))
425 $dbConnection->query("update ".$locTable." set REGION_ID = ID where TYPE_ID = '".intval($types['REGION'])."'");
426
427 if(intval($types['CITY']))
428 $dbConnection->query("update ".$locTable." set CITY_ID = ID where TYPE_ID = '".intval($types['CITY'])."'");
429 }
430 }
431
432 public static function getCodeValidators()
433 {
434 return array(
435 new Entity\Validator\Unique(),
436 );
437 }
438
439 public static function getMap()
440 {
441 return array(
442
443 'ID' => array(
444 'data_type' => 'integer',
445 'primary' => true,
446 'autocomplete' => true,
447 'title' => 'ID'
448 ),
449 'CODE' => array(
450 'data_type' => 'string',
451 'title' => Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_CODE_FIELD'),
452 'required' => true,
453 'validation' => array(__CLASS__, 'getCodeValidators')
454 ),
455
456 'LEFT_MARGIN' => array(
457 'data_type' => 'integer',
458 ),
459 'RIGHT_MARGIN' => array(
460 'data_type' => 'integer',
461 ),
462 'DEPTH_LEVEL' => array(
463 'data_type' => 'integer',
464 ),
465 'SORT' => array(
466 'data_type' => 'integer',
467 'default_value' => 100,
468 'title' => Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_SORT_FIELD')
469 ),
470 'PARENT_ID' => array(
471 'data_type' => 'integer',
472 'default_value' => 0,
473 'title' => Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_PARENT_ID_FIELD')
474 ),
475 'TYPE_ID' => array(
476 'data_type' => 'integer',
477 'required' => true,
478 'title' => Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_TYPE_ID_FIELD')
479 ),
480 'LATITUDE' => array(
481 'data_type' => 'float',
482 'title' => Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_LATITUDE_FIELD')
483 ),
484 'LONGITUDE' => array(
485 'data_type' => 'float',
486 'title' => Loc::getMessage('SALE_LOCATION_LOCATION_ENTITY_LONGITUDE_FIELD')
487 ),
488
489 // virtual
490 'TYPE' => array(
491 'data_type' => 'Bitrix\Sale\Location\Type',
492 'reference' => array(
493 '=this.TYPE_ID' => 'ref.ID'
494 ),
495 'join_type' => "inner"
496 ),
497 'NAME' => array(
498 'data_type' => 'Bitrix\Sale\Location\Name\Location',
499 'reference' => array(
500 '=this.ID' => 'ref.LOCATION_ID'
501 ),
502 'join_type' => "inner"
503 ),
504 'PARENT' => array(
505 'data_type' => 'Bitrix\Sale\Location\Location',
506 'reference' => array(
507 '=this.PARENT_ID' => 'ref.ID'
508 )
509 ),
510 'PARENTS' => array(
511 'data_type' => 'Bitrix\Sale\Location\Location',
512 'reference' => array(
513 '<=ref.LEFT_MARGIN' => 'this.LEFT_MARGIN',
514 '>=ref.RIGHT_MARGIN' => 'this.RIGHT_MARGIN'
515 )
516 ),
517 'CHILDREN' => array(
518 'data_type' => 'Bitrix\Sale\Location\Location',
519 'reference' => array(
520 '=this.ID' => 'ref.PARENT_ID'
521 )
522 ),
523 'EXTERNAL' => array(
524 'data_type' => 'Bitrix\Sale\Location\External',
525 'reference' => array(
526 '=this.ID' => 'ref.LOCATION_ID'
527 )
528 ),
529 'DEFAULT_SITE' => array(
530 'data_type' => 'Bitrix\Sale\Location\DefaultSite',
531 'reference' => array(
532 '=this.CODE' => 'ref.LOCATION_CODE'
533 )
534 ),
535
536 'CNT' => array(
537 'data_type' => 'integer',
538 'expression' => array(
539 'count(*)'
540 )
541 ),
542 'CHILDREN_CNT' => array(
543 'data_type' => 'integer',
544 'expression' => array(
545 'count(%s)',
546 'CHILD.ID'
547 )
548 ),
549 'IS_PARENT' => array(
550 'data_type' => 'boolean',
551 'expression' => array(
552 'case when count(%s) > 0 then 1 else 0 end',
553 'CHILD.ID'
554 )
555 ),
556
557 // do not remove unless you want migrator to be dead
558 'COUNTRY_ID' => array(
559 'data_type' => 'integer',
560 ),
561 'REGION_ID' => array(
562 'data_type' => 'integer',
563 ),
564 'CITY_ID' => array(
565 'data_type' => 'integer',
566 ),
567 'LOC_DEFAULT' => array(
568 'data_type' => 'string',
569 ),
570
571 // deprecated aliases
572 'CHILD' => array(
573 'data_type' => 'Bitrix\Sale\Location\Location',
574 'reference' => array(
575 '=this.ID' => 'ref.PARENT_ID'
576 )
577 ),
578 'CHILD_CNT' => array(
579 'data_type' => 'integer',
580 'expression' => array(
581 'count(%s)',
582 'CHILD.ID'
583 )
584 ),
585 'DEFAULT_SORT' => array(
586 'data_type' => 'Bitrix\Sale\Location\DefaultSiteTable',
587 'reference' => array(
588 '=this.CODE' => 'ref.LOCATION_CODE'
589 )
590 ),
591
592 );
593 }
594
598 public static function getListFast($parameters = array())
599 {
600 // here $parameters conversion required
601
602 if(isset($parameters['filter']['NAME']))
603 {
604 $parameters['filter']['PHRASE'] = $parameters['filter']['NAME'];
605 unset($parameters['filter']['NAME']);
606 }
607
608 if(isset($parameters['filter']['LANGUAGE_ID']))
609 {
610 $parameters['filter']['NAME.LANGUAGE_ID'] = $parameters['filter']['LANGUAGE_ID'];
611 unset($parameters['filter']['LANGUAGE_ID']);
612 }
613
614 return \Bitrix\Sale\Location\Search\Finder::find($parameters, array('USE_INDEX' => false, 'USE_ORM' => false));
615 }
616}
617
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static updateMultipleForOwner($primaryOwner, $external)
Definition external.php:73
static deleteMultipleForOwner($primaryOwner)
Definition external.php:134
static addMultipleForOwner($primaryOwner, $external=array())
Definition external.php:46
static deleteMultipleByParentRangeSql($sql)
Definition external.php:155
static updateExtended($primary, array $data, array $additional=array())
Definition location.php:223
static getExternalData($primary, $parameters=array())
Definition location.php:332
static getListFast($parameters=array())
Definition location.php:598
static getByCode($code='', $parameters=array())
Definition location.php:59
static checkFields(Entity\Result $result, $primary, array $data)
Definition location.php:72
static addExtended(array $data, array $additional=array())
Definition location.php:138
static checkNodeIsParentOfNode($primary, $childPrimary, $behaviour=array('ACCEPT_CODE'=> false, 'CHECK_DIRECT'=> false))
Definition location.php:359
static deleteExtended($primary, array $additional=array())
Definition location.php:288
static update($primary, array $data)
Definition location.php:194
static getPathToNodeByCode($code, $parameters, $behaviour=array('SHOW_LEAF'=> true))
Definition location.php:352
static applyRestrictions(&$data)
Definition tree.php:981
static getPathToNodeByCondition($filter, $parameters=array(), $behaviour=array('SHOW_LEAF'=> true))
Definition tree.php:375
$GLOBALS['____1444769544']
Definition license.php:1