Геотаргетинг по городам (регионам, странам) для WordPress

от автора


Причины создания

Недавно попросили сделать геотаргетинг по городам для сайта на wordpress. Пересмотрев существующие геотаргетинг-плагины (в том числе платные), не нашёл не одного работающего с городами (только страны). Поэтому решил сделать свой, используя какую-нибудь существующую базу для определения местоположения по IP-адресу. Сначала начал с разработки функции в шаблоне, но потом решил создать плагин и выложить на github, так как думаю, что он может пригодиться кому-нибудь ещё.

Выбор базы

Первым делом нужно было выбрать базу. И это, наверное, одна из самых сложных проблем. В процессе разработки пробовал много вариантов, даже делал CURL-запросы на сайты, определяющие местоположение по ip, и парсил их. Но все они были не точны, к примеру, один Московский IP определяло как Москву, другой — просто Россия. Также нужно было, чтобы плагин работал не только с Россией, но и с Беларусью и Украиной. Перепробовав кучу множество баз, я остановился на Sypex Geo. У них есть условно-платная и бесплатная версии баз. Условно-платная использует REST API и возвращает данные в виде xml, json и jsonp. Бесплатную можно скачать в виде файла, также можно скачать класс для работы с ней. Условно-платная версия более точная, но бесплатно предоставляет только 10 000 запросов. Бесплатная версия тоже достаточно точна и обновляется на сайте.

Функционал

Как я уже писал, начинал я делать не с плагина, а с функции в шаблоне. Сначала думал только об условно-платной версии базы, но количество бесплатных запросов закончилось за день-два. Поэтому перешёл на бесплатную, используя готовый класс для работы с файлом базы.

При разработке плагина я решил сделать выбор между локальной базой и REST API. В будущем планирую сделать кнопку автоматического обновления базы.

Также из базы можно вернуть русские и английские имена городов (стран, регионов). В связи с этим сделал выбор языка.
Ещё столкнулся с тем, что нужно включить список несколько городов или наоборот исключить какой-то.


Настройка плагина в админке

Реализация

Так как с WordPress я работаю редко (как и со всеми CMS) и написанием плагинов для него никогда не занимался, начал читать, как их писать и смотреть, как устроены существующие. Идею реализации взял с существующих гео-плагинов. Ещё долго думал писать функционально или объектно-ориентированно. Решил функционально, так как плагин не большой.

Вкратце опишу его работу.

При активации плагина инициируем две опции: тип бд и язык на котором будем вводить названия.

register_activation_hook(__FILE__, 'wp_sypexgeo_activation'); function wp_sypexgeo_activation() { 	update_option('sgeo_language', 'en'); 	update_option('sgeo_dbase', 'loc'); } 

Далее

    add_filter('the_content', 'geotargeting_filter'); 	add_filter('the_content_rss', 'geotargeting_filter'); 	add_filter('the_excerpt', 'geotargeting_filter'); 	add_filter('the_excerpt_rss', 'geotargeting_filter'); 

вызывают функцию

geotargeting_filter

function geotargeting_filter($s) { 		//parse Country 		preg_match_all("#\[" . GEOTARGETING_COUNTY . "\s*(in|out)=([^\]]+)\](.*?)\[/" . GEOTARGETING_COUNTY . "\]#isu", $s, $country); 		//parse Country 		preg_match_all("#\[" . GEOTARGETING_REGION . "\s*(in|out)=([^\]]+)\](.*?)\[/" . GEOTARGETING_REGION . "\]#isu", $s, $region); 		//parse Country 		preg_match_all("#\[" . GEOTARGETING_CITY . "\s*(in|out)=([^\]]+)\](.*?)\[/" . GEOTARGETING_CITY . "\]#isu", $s, $city); 		if (empty($country) && empty($region) && empty($city)) { 			return $s; 		} 		$base_type = get_option('sgeo_dbase'); 		if ($base_type == 'loc') { 			$ipdata = getLocInfo(); 		} elseif ($base_type == 'rm') { 			$ipdata = getRemInfo(); 		} 		if (!empty($country)) { 			foreach ($country[0] as $i => $raw) { 				$type = strtolower($country[1][$i]); 				$countries = strtolower(trim(str_replace(array("\"", "'", "\n", "\r", "\t", " "), "", $country[2][$i]))); 				$content = $country[3][$i]; 				$countries = explode(",", $countries); 				$replacement = ""; 				if ((($type == "in") && in_array($ipdata['country'], $countries)) || (($type == "out") && !in_array($ipdata['country'], $countries))) { 					$replacement = $content; 				} 				$s = str_replace($raw, $replacement, $s); 			} 		} 		if (!empty($region)) { 			foreach ($region[0] as $i => $raw) { 				$type = strtolower($region[1][$i]); 				$regions = strtolower(trim(str_replace(array("\"", "'", "\n", "\r", "\t"), "", $region[2][$i]))); 				$content = $region[3][$i]; 				$regions = explode(",", $regions); 				$replacement = ""; 				if ((($type == "in") && in_array($ipdata['region'], $regions)) || (($type == "out") && !in_array($ipdata['region'], $regions))) { 					$replacement = $content; 				} 				$s = str_replace($raw, $replacement, $s); 			} 		} 		if (!empty($city)) { 			foreach ($city[0] as $i => $raw) { 				$type = strtolower($city[1][$i]); 				$cities = strtolower(trim(str_replace(array("\"", "'", "\n", "\r", "\t", " "), "", $city[2][$i]))); 				$content = $city[3][$i]; 				$cities = explode(",", $cities); 				$replacement = ""; 				if ((($type == "in") && in_array($ipdata['city'], $cities)) || (($type == "out") && !in_array($ipdata['city'], $cities))) { 					$replacement = $content; 				} 				$s = str_replace($raw, $replacement, $s); 			} 		} 		return $s; 	}

В которую приходит текущий контент. В зависимости от типа базы вызывается функция для получения данных. Затем идёт поиск специальных тегов в шаблоне и сверка их с данными о местоположении. Если данные совпадают то конструкция заменяется на содержимое из тегов, если нет — она удаляется.

Использование

Для указания списка стран:

[GeoCountry in=Belarus,Russia]Привет Belarus,Russia![/GeoCountry]

Для указания списка регионов:

[GeoRegion in=Moscow]Привет Moscow Region![/GeoRegion]

Для указания списка городов:

[GeoCity in=Минск,Брест]Привет Минск,Брест![/GeoCity]

Если вы хотите выбрать страны (регионы, города) за исключением указанных, используйте «out»:

[GeoRegion out=Minsk,Brest]Привет всем, кроме Minsk,Brest![/GeoRegion]

Пример использования в шаблоне:

Добро пожаловать в WordPress. Это ваша первая запись. Отредактируйте или удалите её, затем пишите! Наши контакты: [GeoCity in=Minsk]+375295552255[/GeoCity][GeoCity out=Minsk]+375475552255[/GeoCity]

Заключение

Надеюсь мой плагин кому-нибудь пригодится. Если есть вопросы или предложение — пишите. Также, если кто-то считает что нужно использовать другую базу (геосервис или ещё что-нибудь) предлагайте, я добавлю или можете добавить сами.

Ссылка на плагин: wp-sypexgeo

ссылка на оригинал статьи http://habrahabr.ru/post/258705/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *