📜 ⬆️ ⬇️

Geo-targeting by city (region, country) for WordPress

Reasons for creating


Recently asked to do geo-targeting by city for a wordpress site. Having reviewed existing geo-targeting plug-ins (including paid ones), I didn’t find more than one working with cities (only countries). Therefore, I decided to make my own, using some existing base for determining the location by IP address. First I started by developing the function in the template, but then I decided to create a plugin and put it on github, because I think it might be useful to someone else.

Base selection


The first step was to choose a base. And this is probably one of the most difficult problems. In the development process I tried many options, even made CURL requests for sites that determine the location of ip, and parsil them. But all of them were not accurate, for example, one Moscow IP was defined as Moscow, the other - just Russia. It was also necessary for the plugin to work not only with Russia, but also with Belarus and Ukraine. Having tried a lot of bases, I stopped at Sypex Geo. They have conditionally paid and free versions of databases. Conditionally-paid uses REST API and returns data in the form of xml, json and jsonp. Free can be downloaded as a file, you can also download a class to work with it. The conditionally paid version is more accurate, but provides only 10,000 requests for free. The free version is also quite accurate and updated on the site.

Functional


As I already wrote, I started to do not with the plugin, but with the function in the template. At first I was thinking only about the conditionally paid version of the database, but the number of free requests ended in a day or two. Therefore, I switched to a free one, using a ready-made class for working with a database file.

When developing the plugin, I decided to make a choice between the local database and the REST API. In the future I plan to make the button automatically update the database.
')
Also from the database you can return the Russian and English names of cities (countries, regions). In this regard, made the choice of language.
Still faced with the fact that you need to include a list of several cities, or vice versa, to exclude some.


Configure the plugin in the admin panel

Implementation


Since I rarely work with Wordpress (as with all CMS) and never wrote plug-ins for it, I began to read how to write them and see how the existing ones are arranged. The idea of ​​implementation took from existing geo-plugins. I thought for a long time to write functionally or object-oriented. I decided functionally, since the plugin is not big.

Briefly describe his work.

When activating the plugin, we initiate two options: the type of database and the language in which we will enter the names.

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

Further
  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'); 
call function
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; } 
In which comes the current content. Depending on the type of database, the function is called to get the data. Then it searches for special tags in the template and compares them with the location data. If the data matches, the construction is replaced with the content from the tags, if not, it is deleted.

Using


To specify a list of countries:
 [GeoCountry in=Belarus,Russia] Belarus,Russia![/GeoCountry] 

To specify a list of regions:
 [GeoRegion in=Moscow] Moscow Region![/GeoRegion] 

To specify a list of cities:
 [GeoCity in=,] ,![/GeoCity] 

If you want to select countries (regions, cities) with the exception of those specified, use "out":
 [GeoRegion out=Minsk,Brest] ,  Minsk,Brest![/GeoRegion] 


Example of use in the template:

Welcome to WordPress. This is your first post. Edit or delete it, then start blogging! Our contacts: [GeoCity in = Minsk] +375295552255 [/ GeoCity] [GeoCity out = Minsk] +375475552255 [/ GeoCity]

Conclusion


I hope my plugin is useful to someone. If you have any questions or suggestions - write. Also, if someone thinks that you need to use another database (geoservice or something else), suggest, I will add, or you can add.

Link to plugin: wp-sypexgeo

Source: https://habr.com/ru/post/258705/


All Articles