IP-to-Country pro WordPress
Pro WordPress existuje celá řada pluginů pro geolokaci uživatele (to méně vznešenými slovy znamená, že k dané IP adrese přiřazuji stát a v lepším případě i město). Jak jsem však zjistil, všechny mají jeden zásadní nedostatek: jsou určeny pro uživatele WordPressu, ne pro jeho programátory. Pokusil jsem se tento nedostatek napravit pluginem IP-to-Country, který neposkytuje absolutně žádný vizuální výstup, ale soustředí se na vytvoření rozhraní, které by mohli využít další programátoři ve svých pluginech. A hned jsem to také udělal ve svém pluginu Simple Download Manager.
Instalace a aktualizace pluginu
Instalace pluginu probíhá standardními WordPressovskými postupy: stáhnete distribuční archív (viz konec článku), rozbalíte ho do nějakého adresáře a pak v administraci WordPressu plugin aktivujete.
Aktualizace může probíhat úplně stejně, podporována je i automatická aktualizace z administračního rozhraní.
Naplnění daty
Geolokace je ve své nejobvyklejší podobě řešena prostým seznamem IP adres a k nim přiřazeným oblastem. I můj plugin potřebuje nějaký zdroj dat. Na výběr je mnoho možností, já jsem se na základě „důkladné analýzy“ (tzn. položil jsem dotaz Googlu a vzal to první, co vypadlo) rozhodl pro ip-to-country.webhosting.info, která na jedné stabilní adrese poskytuje dobře zpracovatelný seznam adres: jde o standardní CSV soubor s pěti sloupečky: počáteční IP adresa, koncová IP adresa (obě stanovují interval, který patří do stejného území), dvouznakový ISO kód země, tříznakový ISO kód země, ISO název země. Sloupečky jsou uzavřeny do uvozovek a odděleny čárkou, oddělovačem řádků je znak LF
(ASCII kód 10
, v PHP \n
). Vypadá to takhle:
"100663296","121195295","US","USA","UNITED STATES" "121195296","121195327","IT","ITA","ITALY" "121195328","134693119","US","USA","UNITED STATES" "134693120","134693375","CA","CAN","CANADA"
Pokud vás zarazila podoba IP adres, žádný strach – jsou to klasické IP adresy, jen vyjádřené jedním 32bitovým číslem místo obvyklého vyjádření v podobě čtyř 8bitových číslic; převod lze v PHP provádět funkcí ip2long (ze čtveřice na číslo) resp. long2ip (zpět).Případně si to můžete spočítat ručně – z adresy A.B.C.D
se na adresu EEEE
dostanete pomocí vztahu EEEE = 2563*A + 2562*B + 2561*C + 2560*D = 16777216*A + 65536*B + 256*C + D
.
Vlastní naplnění databáze geolokačními daty je velice jednoduché – v konfiguraci pluginu jsem připravil rozhraní, ve kterém si můžete vybrat zdroj dat („oficiální“ URL, vaše vlastní URL nebo soubor přímo na disku počítače) a jedním kliknutím nechat data nahrát. Nemělo by to mít žádné zvláštní nároky na vybavení webserveru ani databázového serveru, i rychlostně by to mělo být v pohodě; jediné omezení je, že pro použití „oficálního URL“ potřebujete mít ve svém PHP zapnuté rozšíření php_zip
.
Používání
Ve své první verzi nabízí plugin programátorům jen nejzákladnější funkčnost, počítám ale s tím, že ji budu dále rozšiřovat podle požadavků. Co lze zatím udělat:
-
Zjistit, jestli je plugin aktivní: Pokud je plugin aktivní, je nadefinována třída
PepakIpToCountry
:if (class_exists('PepakIpToCountry')) echo "Geolokační funkce jsou k dispozici"; else echo "Aktivujte plugin Ip-to-Country";
-
Zjistit k dané adrese stát: Pokud je plugin aktivní, je nadefinovaných pět statických metod třídy, které mají všechny stejné parametry a liší se jen tím, co vrací:
$stat = PepakIpToCountry::IP_to_Country_Full('8.8.8.8'); // $stat = 'UNITED STATES'; $stat2 = PepakIpToCountry::IP_to_Country_XX('8.8.8.8'); $stat2a = PepakIpToCountry::IP_to_Country('8.8.8.8'); // $stat2 = $stat2a == 'US'; $stat3 = PepakIpToCountry::IP_to_Country_XXX('8.8.8.8'); // $stat3 = 'USA'; $statX = PepakIpToCountry::IP_to_Country_Info('8.8.8.8'); // $statX = Array('iso_name'=>'UNITED STATES', 'iso_code2'=>'US', 'iso_code3'=>'USA')`;
Všechny dotazy jsou cachované, takže je čistě jen na vás, jestli si vyzvednete všechny údaje najednou v poli (poslední funkce) nebo postupně po jednotlivých stringách. Adresu v závorce, která je očekávána v obvyklém tečkovaném tvaru, není třeba uvádět, pokud vám stačí IP adresa uživatele, který váš skript vyvolal:
echo "Vítejte, uživateli ze státu " . PepakIpToCountry::IP_to_Country_Full();
Tyto funkce se hodí v případě, že máte ve skriptu IP adresu získanou z nějakého zdroje a potřebujete k ní přiřadit stát.
-
Přidat zjištění státu do databázového dotazu: Pokud je plugin aktivní, je nadefinovaná statická metoda
PepakIpToCountry::Subselect(...)
, pomocí které lze do (skoro) libovolného SQL dotazu jednoduše přidat informaci o státu k dané adrese v databázi. Řekněme, že máte následující dotaz (převzatý ze Simple Download Monitoru):$sql = "SELECT id, download_date, ip, referer, userid, username FROM wp_sdmon_details WHERE download=123 ORDER BY download_date DESC LIMIT 20";
Dotazovat se na stát ke každé IP adrese zvlášť by bylo zbytečně náročné pro databázový server. Metodou
Subselect
přidáte políčko přímo do dotazu:if (class_exists('PepakIpToCountry')) $zeme2 = PepakIpToCountry::Subselect('INET_ATON(wp_sdmon_details.ip)', 'iso_code2'); else $zeme2 = 'NULL'; $sql = "SELECT id, download_date, ip, referer, userid, username, $zeme2 zeme2 FROM wp_sdmon_details WHERE download=123 ORDER BY download_date DESC LIMIT 20";
Metoda
PepakIpToCountry::SubSelect($field, $resultfield)
má dva parametry:-
$field
určuje pole, ze kterého se vezme IP adresa. Může to být libovolné pole z vašeho dotazu (v mém případěip
v tabulcewp_sdmon_details
), jen je nanejvýš vhodné, aby to pole bylo plně kvalifikováno – tzn. ne jennázev_pole
, ale radšijméno_tabulky.název_pole
. Kromě toho je třeba, aby pole bylo vedeno jako 32bitové číslo, ne jako řetězec ve tvaruA.B.C.D
jako obvykle. Naštěstí lze v MySQL použít funkciINET_ATON
, která zA.B.C.D
to číslo udělá. Příklad použití je výše. -
$resultfield
udává jméno políčko z tabulek pluginu, které má být vráceno – jeden subselect jde použít pro vrácení pouze jednoho pole! Hodnota může být jedna z tohoto seznamu:iso_name
(vrátí celé jméno země, např. „UNITED STATES“),iso_code2
(vrátí dvouznakový kód země, např. „US“),iso_code3
(vrátí tříznakový kód země, např. „USA“).
Důležité bezpečností upozornění: metoda
Subselect
principielně nemůže kontrolovat vstupní údaje na SQL injection (tedy,$resultfield
by kontrolovat mohla, protože tam dává smysl jen jeden z několika málo konkrétních řetězců, ale$field
kontrolovat nejde). Je naprosto nezbytné zajistit, že to, co doSubselect
pošlete, nemůže uživatel nijak ovlivnit! Pokud připustíte možnost, aby uživatel parametrySubselect
ovlivnit žádným způsobem nemohl, dáte mu potenciálně přístup k celé své databázi, aby si s ní dělal, co chce. Doporučuji doSubselect
posílat jen natvrdo zapsané řetězce nebo konstanty. -
K dispozici je i několik funkcí pro vstup dat, ty ale nejspíš nebudou příliš používané – a kdo bude mít potřebu je použít, jistě si je dokáže ve zdrojovém kódu sám dohledat.
Pokud máte nějaké upřesňující dotazy nebo byste potřebovali další funkčnost, stačí napsat, buď přímo do komentářů nebo do diskusního fóra.
Download
-
IP-to-Country v0.08 (2014-06-24, 193 KB). Ukrajinský překlad od Michaela Yunata.
-
IP-to-Country v0.06 (2013-08-17, 202 KB). Opravena varování ve WordPressu 3.5. Srbochorvatský překlad od Andrijany Nikolic. Andrijana také vytvořila stránku s návodem k použití v srbochorvatštině.
-
IP-to-Country v0.05 (2012-03-31, 194 KB). Rumunský překlad od Alexandra Ovsova.
-
IP-to-Country v0.04 (2012-01-06, 210 KB). Zobrazované vlajky mají v atributu Title název země, které patří.
-
IP-to-Country v0.03 (2010-08-14, 213 KB). Opravena potenciální chyba s IPv4 adresami. Podpora pro IPv6. Plugin rovnou obsahuje obrázky vlajek, takže si je používající pluginy nemusí nést s sebou.
-
IP-to-Country v0.02 (2010-03-28, 18 KB). První funkční veřejná verze.
Verze 0.06: Srbochorvatský překlad od Andrijany Nikolic. Opravena varování ve WordPressu 3.5.
Verze 0.05: Rumunský překlad od Alexandra Ovsova.
Verze 0.04: Zobrazované vlajky mají v atributu Title název země, které patří.
Opravena potenciální chyba s IPv4 adresami. Podpora pro IPv6. Plugin rovnou obsahuje obrázky vlajek, takže si je používající pluginy nemusí nést s sebou.