GeoIP на сайте. Реализация в Битрикс

Иногда на сайте требуется реализовать что-то вроде такого функционала:

head

Город при посещении сайта должен быть выбран в соответствии с тем, откуда пользователь зашёл на сайт. Если из Санкт-Петербурга — то должен быть отображён Санкт-Петербург.

Реализовать определение города можно с помощью замечательного модуля «Определение местоположения по IP-адресу». Качаем его из маркетплейса отсюда.

Приступим к реализации:

Данные о том, из какого города к нам зашёл посетитель, будем хранить в сессии, а сами города и им соответствующие номера телефонов — в инфоблоке. Напишем несколько функций, которые помогут нам вытащить из инфоблока данные о городе (его название, id и номер телефона):

/*
 * возвращает текущий город, его id и телефон по GeoIP
 */
function get_current_city_by_geo(){
    $ret = false;
    CModule::IncludeModule("iblock");
    if (CModule::IncludeModule("altasib.geoip")) {
        $arData = ALX_GeoIP::GetAddr();
        $res = CIBlockElement::GetList(Array(), array("IBLOCK_ID" => 1, "ACTIVE" => "Y", "NAME" => $arData['city']), false, false, array("NAME", "ID", "PROPERTY_PHONE"))->GetNext();
        if ($res){
            $ret['ID'] = $res['ID']; 
            $ret['NAME'] = $res['NAME'];
            $ret['PHONE'] = $res['PROPERTY_PHONE_VALUE'];
        }
        else{
           $ret = false; 
        }
    }
    return $ret;
}

/*
 * возвращает текущий город, его id и телефон по $_SESSION['city']
 */
function get_current_city_by_session(){
    $ret = false;
    CModule::IncludeModule("iblock");
    if (CModule::IncludeModule("altasib.geoip")) {
        $arData = ALX_GeoIP::GetAddr();
        $res = CIBlockElement::GetList(Array(), array("IBLOCK_ID" => 1, "ACTIVE" => "Y", "NAME" => $_SESSION['city']), false, false, array("NAME", "ID", "PROPERTY_PHONE"))->GetNext();
        if ($res){
            $ret['ID'] = $res['ID']; 
            $ret['NAME'] = $res['NAME'];
            $ret['PHONE'] = $res['PROPERTY_PHONE_VALUE'];
        }
        else{
           $ret = false; 
        }
    }
    return $ret;
}

Добавим эти функции в init.php (чтобы к ним был доступ из header.php)

Теперь опишем саму логику определения города (этот код можно использовать в header.php):

if (isset($_SESSION['city'])){
 $city = get_current_city_by_session(); 
}
else{
  $city = get_current_city_by_geo();
  if ($city){
	  $_SESSION['city'] = $city['NAME'];
  }
  else{
	  $_SESSION['city'] = 'Санкт-Петербург';
	  $city = get_current_city_by_session();
  }
}

Пояснения: Если в сессии уже задан город, то в $city будут записаны данные о нём. Если нет — то определим этот город по GeoIP и попытаемся получить о нём данные из инфоблока. Если в инфоблоке такого города нет — то получим данные о городе «Санкт-Петербург» (пусть это будет город по умолчанию).

Далее уже можно приступать к отображению. Телефон и наименование города можно получить так:

// название города
echo $city['NAME'];
// телефон этого города
echo $city['PHONE'];