Доброго всем дня.
Продолжаю делиться своими наработками...
Итак, у меня есть задача: Для БУС под редакцией "Старт" необходимо выводить в инфоблоке в зависимости от страны пользователя разные поля.
Для этого воспользовался модулем:
Для этого выкачиваем вот файлы:
- Readme - чтоб почитать, как же оно все работает;
- geoip.inc - файл с основным набором функций для работы модуля
- GeoIP.dat - база данных IP адресов (Обновляется не на столько часто, чтобы переживать, что когда-нибудь наш
скрипт не сможет определить страну пользователя... А раз в год этот файлик можно и заменить....)
Закидываем 2 последних файла в корень сайта и тут же создаем тестовый файлик (geo.php) который нам покажет, что механизм определения страны все-таки работает...
Содержимое файла приблизительно такое:
include("geoip.inc");
function getRealIpAddr() // Функция, определяющая реальный ИП пользователя
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
$realip = getRealIpAddr();
$gi = geoip_open("GeoIP.dat", GEOIP_STANDARD);
echo $value = geoip_country_code_by_addr($gi, getRealIpAddr());
//покажет код страны пользователя
geoip_close($gi);
С непосредственным определением страны закончили.
Теперь нужно это применить к разработке.
Для этого, в php_interface/init.php создаем обработчик события :
// файл /bitrix/php_interface/init.php
function GetUserCountry()
{
global $USER;
$USER->SetParam("UserCountry", "UA"); //работает только для авторизованных
}
AddEventHandler("main", "OnBeforeProlog", "GetUserCountry", 50);
Таким образом, получаем параметр пользователя, со значением кода страны, который в последствии сможем использовать на сайте.
Теперь нужно перенести определение страны пользователя из тестового файла "geo.php" в init.php.
Подключаем файлик с функциями:
include($_SERVER["DOCUMENT_ROOT"]."/geoip.inc");
Переносим функцию реального ИП пользователя (не знаю на сколько она 100%-но рабочая - нашел ее на одном из форумов. Думаю профессиональные пользователи ее все-таки обойдут, но сайт на таких не рассчитан, так что вполне пойдет):
function getRealIpAddr()
{
if (!empty($_SERVER['HTTP_CLIENT_IP']))
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
Добавляем определение кода страны в функцию обработчика. Код страны запишем в сесиию:
$_SESSION['UserCountry']=$value;
В результате файл init.php будет иметь вид:
// файл /bitrix/php_interface/init.php
include($_SERVER["DOCUMENT_ROOT"] . "/geoip.inc");
function GetUserCountry()
{
$realip = getRealIpAddr();
$IPDBPATH = $_SERVER['DOCUMENT_ROOT'] . '/GeoIP.dat'; //задаем путь к базе
$gi = geoip_open($IPDBPATH, GEOIP_STANDARD); //получаем данные из базы
$value = geoip_country_code_by_addr($gi, getRealIpAddr()); //получаем данные для ИП пользователя
geoip_close($gi); //закрываем файл с базой
global $USER;
$USER->SetParam("UserCountry", $value);
$_SESSION['UserCountry'] = $value;
}
function getRealIpAddr()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
AddEventHandler("main", "OnBeforeProlog", "GetUserCountry", 50);
В итоге, для любого авторизованного пользователя в свойстве "UserCountry" будет код его страны. А для всех остальных - данные берем из сессии (в принципе хватит и сесии, но оставлю, вдруг кому пригодится использовать разные данные для авторизованных и для гостей...).
Дальше в коде, в шаблонах компонентов или на страницах, где нужно получать данное значение вставляем нечто похожее на:
global $USER;
if ($USER->IsAuthorized()){
$COUNTRYCODE=$USER->GetParam("UserCountry";
} else {
$COUNTRYCODE=$_SESSION["SESS_AUTH"]["UserCountry"];
}
В итоге в переменной $COUNTRYCODE будет код страны посетителя сайта...
Тестовый файлик определения страны (geo.php) в принципе можно уже и удалить...
Вот такой вот механизм получился. Я на 100% уверен, что все это можно еще оптимизировать. Может быть в следующий раз этим и займусь...
Update 2015-09-04.
Для своего сайта воспользовался хорошей сборкой с Marketplace.