Город посетителя по адресу - определение, проверка, запасной вариант
Определяем город посетителя по сетевому адресу, чтобы предложить его при первом заходе: фасад геолокации, проверка ответа и обязательный запасной вариант.
Решение
Геолокация в платформе собрана за одним общим фасадом ядра. Он опрашивает настроенные обработчики по очереди, а прикладной код не знает, какой именно источник ответил.
Берём одно поле:
use Bitrix\Main\Service\GeoIp\Manager;
$city = Manager::getCityName(); // адрес текущего посетителя определяется сам// на неудачу метод возвращает пустую строку, а не ошибку// вторым аргументом задают язык названий, если он важенДля одного значения вполне хватает короткого метода самого фасада. Пустая строка в ответе - штатная ситуация: адрес мог оказаться неизвестным источнику или посетитель пришёл через посредника.
Берём несколько полей сразу:
$result = Manager::getDataResult('92.50.195.50', 'ru', ['countryName', 'cityName', 'latitude', 'longitude']);
if ($result && $result->isSuccess()) { $data = $result->getGeoData(); printf("%s, %s\n", $data->countryName, $data->cityName);}// результат бывает пустым: ни один обработчик не смог ответитьПроверка результата обязательна до чтения любых его данных. Метод возвращает пустое значение, когда ни один источник не ответил, и обращение к полям в этом случае роняет страницу.
Передаём чужой адрес явно:
$result = Manager::getDataResult($order->getField('USER_IP'), 'ru', ['cityName']);// в фоновом задании и при разборе вебхука текущего посетителя нет// адрес заказа сохраняют при оформлении, чтобы разобрать его позжеПустой адрес означает «текущий посетитель» и годится только для обычной страницы. В фоновом задании, обработчике вебхука и при разборе старого заказа адрес передают явно.
Даём человеку выбрать город:
$suggested = Manager::getCityName();$city = $request->getCookie('CITY_CODE') ?: mapCity($suggested) ?: 'msk';// выбор посетителя всегда сильнее автоматического определения// при неудачном определении подставляют город по умолчаниюОпределение города по адресу - это подсказка, а не решение. Сохранённый выбор посетителя имеет приоритет, а при неудачном определении подставляют город по умолчанию.
Отладку включают отдельным признаком, а не разбором внутренностей самих обработчиков. Прикладной код при этом остаётся прежним и обращается всё к тому же фасаду.
Отдельный вопрос - что делать с кэшем страниц при региональных различиях. Цены и склады, зависящие от города, требуют либо города в ключе кэша, либо отдельных адресов страниц под каждый регион.
Типичные проблемы
Все посетители определяются как один город.
Сайт стоит за прокси, и обработчик видит только адрес посредника. Реальный адрес посетителя возвращают отдельной настройкой веб-сервера.
Страница падает при обращении к данным геолокации.
Результат геолокации не проверен перед чтением его полей. Метод возвращает пустое значение, когда ни один источник так и не ответил.
В фоновом задании город определяется неверно.
Адрес не передан явно, и фасад берёт адрес из текущего запроса. У фонового задания текущего посетителя попросту нет.
Выбор города сбрасывается при каждом заходе.
Определение по адресу перекрывает уже сохранённый выбор человека. Приоритет всегда остаётся у того, что выбрал сам человек.
Определение работает медленно.
Настроен облачный источник, и на каждый запрос уходит отдельное обращение по сети. Для скорости берут локальную базу адресов или кэшируют результат.
Частые вопросы
Какой источник геолокации выбрать?
Локальная база быстрее и не зависит от сети, облачный сервис точнее и знает больше языков. Порядок источников настраивается, и фасад опрашивает их по очереди.
Насколько точно определяется город?
До города - обычно да, до района или улицы - нет. Мобильный интернет и корпоративные сети дают заметные промахи, поэтому выбор всегда оставляют человеку.
Можно ли по адресу подставлять цены и склады?
Только как предложение с явной возможностью сменить город. Молчаливая подмена цен по определению адреса приводит к спорам с покупателями.
Что делать, если источник не ответил?
Подставить город по умолчанию и показать выбор. Пустой ответ - обычная ситуация, и сценарий должен работать без геолокации вовсе.
Нужно ли кэшировать результат?
Платформа кэширует ответы источников сама, но выбор города всё равно сохраняют у посетителя. Так страница не зависит от геолокации при каждом заходе.
Смежное
- Каталог товаров - оглавление подтемы
- Региональность магазина: выбор города, цены и склады - что меняется вместе с городом
- Состояние посетителя в куках: запись, чтение, защищённая кука - где хранится выбор города
- Местоположения: импорт, свойство заказа, доставки и индекс - города в оформлении заказа
- Окружение за прокси и в облаке: адреса, протокол, доступ наружу - почему адрес посетителя один на всех
- Кэш не срабатывает: страница собирается заново каждый раз - кэш и региональные различия
- Подсистемы ядра D7: логирование, валидация, GeoIP, Stepper - устройство подсистемы целиком
- Каталог: комплекты, скидки, склады, доступность - устройство каталога целиком