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.

Nastavení pluginu

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:

    1. $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 tabulce wp_sdmon_details), jen je nanejvýš vhodné, aby to pole bylo plně kvalifikováno – tzn. ne jen název_pole, ale radši jméno_tabulky.název_pole. Kromě toho je třeba, aby pole bylo vedeno jako 32bitové číslo, ne jako řetězec ve tvaru A.B.C.D jako obvykle. Naštěstí lze v MySQL použít funkci INET_ATON, která z A.B.C.D to číslo udělá. Příklad použití je výše.

    2. $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 do Subselect pošlete, nemůže uživatel nijak ovlivnit! Pokud připustíte možnost, aby uživatel parametry Subselect 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 do Subselect 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

Podobné příspěvky:

4 Responses to “IP-to-Country pro WordPress”

  1. avatar pepak napsal:

    Verze 0.06: Srbochorvatský překlad od Andrijany Nikolic. Opravena varování ve WordPressu 3.5.

  2. avatar pepak napsal:

    Verze 0.05: Rumunský překlad od Alexandra Ovsova.

  3. avatar pepak napsal:

    Verze 0.04: Zobrazované vlajky mají v atributu Title název země, které patří.

  4. avatar pepak napsal:

    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.

Leave a Reply

Themocracy iconWordPress Themes

css.php