Version Description
Download this release
Release Info
Developer | wokamoto |
Plugin | Crazy Bone |
Version | 0.1.1 |
Comparing to | |
See all releases |
Version 0.1.1
- css/user_login_log.css +0 -0
- images/browsers/android.png +0 -0
- images/browsers/anonymouse.png +0 -0
- images/browsers/au.png +0 -0
- images/browsers/avantbrowser.png +0 -0
- images/browsers/bitwave.png +0 -0
- images/browsers/blackberry.png +0 -0
- images/browsers/blazer.png +0 -0
- images/browsers/buzzurl.png +0 -0
- images/browsers/camino.png +0 -0
- images/browsers/chrome.png +0 -0
- images/browsers/danger.png +0 -0
- images/browsers/debian.png +0 -0
- images/browsers/delicious.png +0 -0
- images/browsers/dillo.png +0 -0
- images/browsers/docomo.png +0 -0
- images/browsers/dopod.png +0 -0
- images/browsers/drupal.png +0 -0
- images/browsers/epiphany.png +0 -0
- images/browsers/fc2.png +0 -0
- images/browsers/fedora.png +0 -0
- images/browsers/firefox.png +0 -0
- images/browsers/flock.png +0 -0
- images/browsers/freebsd.png +0 -0
- images/browsers/friendfeed.png +0 -0
- images/browsers/galeon.png +0 -0
- images/browsers/gentoo.png +0 -0
- images/browsers/gooblog.png +0 -0
- images/browsers/googleplus.png +0 -0
- images/browsers/habari.png +0 -0
- images/browsers/hatena.png +0 -0
- images/browsers/hatena_bookmark.png +0 -0
- images/browsers/hatena_diary.png +0 -0
- images/browsers/ibisbrowser.png +0 -0
- images/browsers/icab.png +0 -0
- images/browsers/ie.png +0 -0
- images/browsers/iemobile.png +0 -0
- images/browsers/ipad.png +0 -0
- images/browsers/iphone.png +0 -0
- images/browsers/ipod.png +0 -0
- images/browsers/j2me.png +0 -0
- images/browsers/jakarta-apache.png +0 -0
- images/browsers/java.png +0 -0
- images/browsers/jig.png +0 -0
- images/browsers/jugem.png +0 -0
- images/browsers/kazehakase.png +0 -0
- images/browsers/kmeleon.png +0 -0
- images/browsers/konqueror.png +0 -0
- images/browsers/lg.png +0 -0
- images/browsers/libwww-perl.png +0 -0
- images/browsers/linux.png +0 -0
- images/browsers/livedoor.png +0 -0
- images/browsers/livedoor_clip.png +0 -0
- images/browsers/lovelog.png +0 -0
- images/browsers/lunascape.png +0 -0
- images/browsers/lynx.png +0 -0
- images/browsers/macos.png +0 -0
- images/browsers/mandrake.png +0 -0
- images/browsers/motorola.png +0 -0
- images/browsers/mozilla.png +0 -0
- images/browsers/mt.png +0 -0
- images/browsers/netbsd.png +0 -0
- images/browsers/netfront.png +0 -0
- images/browsers/netnewswire.png +0 -0
- images/browsers/netpositive.png +0 -0
- images/browsers/netscape.png +0 -0
- images/browsers/nintendo-ds.png +0 -0
- images/browsers/nintendo-gb.png +0 -0
- images/browsers/nintendo-wii.png +0 -0
- images/browsers/nokia.png +0 -0
- images/browsers/novell.png +0 -0
- images/browsers/o2.png +0 -0
- images/browsers/omniweb.png +0 -0
- images/browsers/openbsd.png +0 -0
- images/browsers/openwave.png +0 -0
- images/browsers/opera.png +0 -0
- images/browsers/orange.png +0 -0
- images/browsers/others.png +0 -0
- images/browsers/palm.png +0 -0
- images/browsers/pear.png +0 -0
- images/browsers/php.png +0 -0
- images/browsers/plone.png +0 -0
- images/browsers/pukiwiki.png +0 -0
- images/browsers/redhat.png +0 -0
- images/browsers/safari.png +0 -0
- images/browsers/samsung.png +0 -0
- images/browsers/seamonkey.png +0 -0
- images/browsers/seesaa.png +0 -0
- images/browsers/shiira.png +0 -0
- images/browsers/siemens.png +0 -0
- images/browsers/slackware.png +0 -0
- images/browsers/sleipnir.png +0 -0
- images/browsers/softbank.png +0 -0
- images/browsers/sony-ps.png +0 -0
- images/browsers/sony-psp.png +0 -0
- images/browsers/sonyericsson.png +0 -0
- images/browsers/sun.png +0 -0
- images/browsers/suse.png +0 -0
- images/browsers/symbian.png +0 -0
- images/browsers/tweet.png +0 -0
- images/browsers/typepad.png +0 -0
- images/browsers/ubuntu.png +0 -0
- images/browsers/universe.png +0 -0
- images/browsers/unknown.png +0 -0
- images/browsers/w3m.png +0 -0
- images/browsers/webpro.png +0 -0
- images/browsers/willcom.png +0 -0
- images/browsers/windows.png +0 -0
- images/browsers/windows_phone.png +0 -0
- images/browsers/wp.png +0 -0
- images/browsers/xiino.png +0 -0
- images/browsers/xoops.png +0 -0
- images/browsers/zope.png +0 -0
- images/flags/ad.png +0 -0
- images/flags/ae.png +0 -0
- images/flags/af.png +0 -0
- images/flags/ag.png +0 -0
- images/flags/ai.png +0 -0
- images/flags/al.png +0 -0
- images/flags/am.png +0 -0
- images/flags/an.png +0 -0
- images/flags/ao.png +0 -0
- images/flags/ar.png +0 -0
- images/flags/as.png +0 -0
- images/flags/at.png +0 -0
- images/flags/au.png +0 -0
- images/flags/aw.png +0 -0
- images/flags/ax.png +0 -0
- images/flags/az.png +0 -0
- images/flags/ba.png +0 -0
- images/flags/bb.png +0 -0
- images/flags/bd.png +0 -0
- images/flags/be.png +0 -0
- images/flags/bf.png +0 -0
- images/flags/bg.png +0 -0
- images/flags/bh.png +0 -0
- images/flags/bi.png +0 -0
- images/flags/bj.png +0 -0
- images/flags/bm.png +0 -0
- images/flags/bn.png +0 -0
- images/flags/bo.png +0 -0
- images/flags/br.png +0 -0
- images/flags/bs.png +0 -0
- images/flags/bt.png +0 -0
- images/flags/bv.png +0 -0
- images/flags/bw.png +0 -0
- images/flags/by.png +0 -0
- images/flags/bz.png +0 -0
- images/flags/ca.png +0 -0
- images/flags/catalonia.png +0 -0
- images/flags/cc.png +0 -0
- images/flags/cd.png +0 -0
- images/flags/cf.png +0 -0
- images/flags/cg.png +0 -0
- images/flags/ch.png +0 -0
- images/flags/ci.png +0 -0
- images/flags/ck.png +0 -0
- images/flags/cl.png +0 -0
- images/flags/cm.png +0 -0
- images/flags/cn.png +0 -0
- images/flags/co.png +0 -0
- images/flags/cr.png +0 -0
- images/flags/cs.png +0 -0
- images/flags/cu.png +0 -0
- images/flags/cv.png +0 -0
- images/flags/cx.png +0 -0
- images/flags/cy.png +0 -0
- images/flags/cz.png +0 -0
- images/flags/de.png +0 -0
- images/flags/dj.png +0 -0
- images/flags/dk.png +0 -0
- images/flags/dm.png +0 -0
- images/flags/do.png +0 -0
- images/flags/dz.png +0 -0
- images/flags/ec.png +0 -0
- images/flags/ee.png +0 -0
- images/flags/eg.png +0 -0
- images/flags/eh.png +0 -0
- images/flags/england.png +0 -0
- images/flags/er.png +0 -0
- images/flags/es.png +0 -0
- images/flags/et.png +0 -0
- images/flags/eu.png +0 -0
- images/flags/fam.png +0 -0
- images/flags/fi.png +0 -0
- images/flags/fj.png +0 -0
- images/flags/fk.png +0 -0
- images/flags/fm.png +0 -0
- images/flags/fo.png +0 -0
- images/flags/fr.png +0 -0
- images/flags/ga.png +0 -0
- images/flags/gb.png +0 -0
- images/flags/gd.png +0 -0
- images/flags/ge.png +0 -0
- images/flags/gf.png +0 -0
- images/flags/gh.png +0 -0
- images/flags/gi.png +0 -0
- images/flags/gl.png +0 -0
- images/flags/gm.png +0 -0
- images/flags/gn.png +0 -0
- images/flags/gp.png +0 -0
- images/flags/gq.png +0 -0
- images/flags/gr.png +0 -0
- images/flags/gs.png +0 -0
- images/flags/gt.png +0 -0
- images/flags/gu.png +0 -0
- images/flags/gw.png +0 -0
- images/flags/gy.png +0 -0
- images/flags/hk.png +0 -0
- images/flags/hm.png +0 -0
- images/flags/hn.png +0 -0
- images/flags/hr.png +0 -0
- images/flags/ht.png +0 -0
- images/flags/hu.png +0 -0
- images/flags/id.png +0 -0
- images/flags/ie.png +0 -0
- images/flags/il.png +0 -0
- images/flags/in.png +0 -0
- images/flags/io.png +0 -0
- images/flags/iq.png +0 -0
- images/flags/ir.png +0 -0
- images/flags/is.png +0 -0
- images/flags/it.png +0 -0
- images/flags/jm.png +0 -0
- images/flags/jo.png +0 -0
- images/flags/jp.png +0 -0
- images/flags/ke.png +0 -0
- images/flags/kg.png +0 -0
- images/flags/kh.png +0 -0
- images/flags/ki.png +0 -0
- images/flags/km.png +0 -0
- images/flags/kn.png +0 -0
- images/flags/kp.png +0 -0
- images/flags/kr.png +0 -0
- images/flags/kw.png +0 -0
- images/flags/ky.png +0 -0
- images/flags/kz.png +0 -0
- images/flags/la.png +0 -0
- images/flags/lb.png +0 -0
- images/flags/lc.png +0 -0
- images/flags/li.png +0 -0
- images/flags/lk.png +0 -0
- images/flags/lr.png +0 -0
- images/flags/ls.png +0 -0
- images/flags/lt.png +0 -0
- images/flags/lu.png +0 -0
- images/flags/lv.png +0 -0
- images/flags/ly.png +0 -0
- images/flags/ma.png +0 -0
- images/flags/mc.png +0 -0
- images/flags/md.png +0 -0
- images/flags/me.png +0 -0
- images/flags/mg.png +0 -0
- images/flags/mh.png +0 -0
- images/flags/mk.png +0 -0
- images/flags/ml.png +0 -0
- images/flags/mm.png +0 -0
- images/flags/mn.png +0 -0
- images/flags/mo.png +0 -0
- images/flags/mp.png +0 -0
- images/flags/mq.png +0 -0
- images/flags/mr.png +0 -0
- images/flags/ms.png +0 -0
- images/flags/mt.png +0 -0
- images/flags/mu.png +0 -0
- images/flags/mv.png +0 -0
- images/flags/mw.png +0 -0
- images/flags/mx.png +0 -0
- images/flags/my.png +0 -0
- images/flags/mz.png +0 -0
- images/flags/na.png +0 -0
- images/flags/nc.png +0 -0
- images/flags/ne.png +0 -0
- images/flags/nf.png +0 -0
- images/flags/ng.png +0 -0
- images/flags/ni.png +0 -0
- images/flags/nl.png +0 -0
- images/flags/no.png +0 -0
- images/flags/np.png +0 -0
- images/flags/nr.png +0 -0
- images/flags/nu.png +0 -0
- images/flags/nz.png +0 -0
- images/flags/om.png +0 -0
- images/flags/pa.png +0 -0
- images/flags/pe.png +0 -0
- images/flags/pf.png +0 -0
- images/flags/pg.png +0 -0
- images/flags/ph.png +0 -0
- images/flags/pk.png +0 -0
- images/flags/pl.png +0 -0
- images/flags/pm.png +0 -0
- images/flags/pn.png +0 -0
- images/flags/pr.png +0 -0
- images/flags/ps.png +0 -0
- images/flags/pt.png +0 -0
- images/flags/pw.png +0 -0
- images/flags/py.png +0 -0
- images/flags/qa.png +0 -0
- images/flags/re.png +0 -0
- images/flags/readme.txt +8 -0
- images/flags/ro.png +0 -0
- images/flags/rs.png +0 -0
- images/flags/ru.png +0 -0
- images/flags/rw.png +0 -0
- images/flags/sa.png +0 -0
- images/flags/sb.png +0 -0
- images/flags/sc.png +0 -0
- images/flags/scotland.png +0 -0
- images/flags/sd.png +0 -0
- images/flags/se.png +0 -0
- images/flags/sg.png +0 -0
- images/flags/sh.png +0 -0
- images/flags/si.png +0 -0
- images/flags/sj.png +0 -0
- images/flags/sk.png +0 -0
- images/flags/sl.png +0 -0
- images/flags/sm.png +0 -0
- images/flags/sn.png +0 -0
- images/flags/so.png +0 -0
- images/flags/sr.png +0 -0
- images/flags/st.png +0 -0
- images/flags/sv.png +0 -0
- images/flags/sy.png +0 -0
- images/flags/sz.png +0 -0
- images/flags/tc.png +0 -0
- images/flags/td.png +0 -0
- images/flags/tf.png +0 -0
- images/flags/tg.png +0 -0
- images/flags/th.png +0 -0
- images/flags/tj.png +0 -0
- images/flags/tk.png +0 -0
- images/flags/tl.png +0 -0
- images/flags/tm.png +0 -0
- images/flags/tn.png +0 -0
- images/flags/to.png +0 -0
- images/flags/tr.png +0 -0
- images/flags/tt.png +0 -0
- images/flags/tv.png +0 -0
- images/flags/tw.png +0 -0
- images/flags/tz.png +0 -0
- images/flags/ua.png +0 -0
- images/flags/ug.png +0 -0
- images/flags/um.png +0 -0
- images/flags/unknown.png +0 -0
- images/flags/us.png +0 -0
- images/flags/uy.png +0 -0
- images/flags/uz.png +0 -0
- images/flags/va.png +0 -0
- images/flags/vc.png +0 -0
- images/flags/ve.png +0 -0
- images/flags/vg.png +0 -0
- images/flags/vi.png +0 -0
- images/flags/vn.png +0 -0
- images/flags/vu.png +0 -0
- images/flags/wales.png +0 -0
- images/flags/wf.png +0 -0
- images/flags/ws.png +0 -0
- images/flags/ye.png +0 -0
- images/flags/yt.png +0 -0
- images/flags/za.png +0 -0
- images/flags/zm.png +0 -0
- images/flags/zw.png +0 -0
- includes/class-detect-browsers.php +1082 -0
- includes/detect_browsers.php +64 -0
- includes/detect_countries.php +66 -0
- includes/ip2c/GPL_V2 +341 -0
- includes/ip2c/README +81 -0
- includes/ip2c/benchmark.php +73 -0
- includes/ip2c/db.version +1 -0
- includes/ip2c/ip-to-country.bin +0 -0
- includes/ip2c/ip2c.jar +0 -0
- includes/ip2c/ip2c.php +376 -0
- includes/ip2c/ip2c_test.php +132 -0
- includes/ip2c/test-ip.php +20 -0
- languages/user-login-log-ja.mo +0 -0
- languages/user-login-log-ja.po +135 -0
- languages/user-login-log.pot +126 -0
- plugin.php +598 -0
- readme.txt +38 -0
- uninstall.php +12 -0
css/user_login_log.css
ADDED
File without changes
|
images/browsers/android.png
ADDED
Binary file
|
images/browsers/anonymouse.png
ADDED
Binary file
|
images/browsers/au.png
ADDED
Binary file
|
images/browsers/avantbrowser.png
ADDED
Binary file
|
images/browsers/bitwave.png
ADDED
Binary file
|
images/browsers/blackberry.png
ADDED
Binary file
|
images/browsers/blazer.png
ADDED
Binary file
|
images/browsers/buzzurl.png
ADDED
Binary file
|
images/browsers/camino.png
ADDED
Binary file
|
images/browsers/chrome.png
ADDED
Binary file
|
images/browsers/danger.png
ADDED
Binary file
|
images/browsers/debian.png
ADDED
Binary file
|
images/browsers/delicious.png
ADDED
Binary file
|
images/browsers/dillo.png
ADDED
Binary file
|
images/browsers/docomo.png
ADDED
Binary file
|
images/browsers/dopod.png
ADDED
Binary file
|
images/browsers/drupal.png
ADDED
Binary file
|
images/browsers/epiphany.png
ADDED
Binary file
|
images/browsers/fc2.png
ADDED
Binary file
|
images/browsers/fedora.png
ADDED
Binary file
|
images/browsers/firefox.png
ADDED
Binary file
|
images/browsers/flock.png
ADDED
Binary file
|
images/browsers/freebsd.png
ADDED
Binary file
|
images/browsers/friendfeed.png
ADDED
Binary file
|
images/browsers/galeon.png
ADDED
Binary file
|
images/browsers/gentoo.png
ADDED
Binary file
|
images/browsers/gooblog.png
ADDED
Binary file
|
images/browsers/googleplus.png
ADDED
Binary file
|
images/browsers/habari.png
ADDED
Binary file
|
images/browsers/hatena.png
ADDED
Binary file
|
images/browsers/hatena_bookmark.png
ADDED
Binary file
|
images/browsers/hatena_diary.png
ADDED
Binary file
|
images/browsers/ibisbrowser.png
ADDED
Binary file
|
images/browsers/icab.png
ADDED
Binary file
|
images/browsers/ie.png
ADDED
Binary file
|
images/browsers/iemobile.png
ADDED
Binary file
|
images/browsers/ipad.png
ADDED
Binary file
|
images/browsers/iphone.png
ADDED
Binary file
|
images/browsers/ipod.png
ADDED
Binary file
|
images/browsers/j2me.png
ADDED
Binary file
|
images/browsers/jakarta-apache.png
ADDED
Binary file
|
images/browsers/java.png
ADDED
Binary file
|
images/browsers/jig.png
ADDED
Binary file
|
images/browsers/jugem.png
ADDED
Binary file
|
images/browsers/kazehakase.png
ADDED
Binary file
|
images/browsers/kmeleon.png
ADDED
Binary file
|
images/browsers/konqueror.png
ADDED
Binary file
|
images/browsers/lg.png
ADDED
Binary file
|
images/browsers/libwww-perl.png
ADDED
Binary file
|
images/browsers/linux.png
ADDED
Binary file
|
images/browsers/livedoor.png
ADDED
Binary file
|
images/browsers/livedoor_clip.png
ADDED
Binary file
|
images/browsers/lovelog.png
ADDED
Binary file
|
images/browsers/lunascape.png
ADDED
Binary file
|
images/browsers/lynx.png
ADDED
Binary file
|
images/browsers/macos.png
ADDED
Binary file
|
images/browsers/mandrake.png
ADDED
Binary file
|
images/browsers/motorola.png
ADDED
Binary file
|
images/browsers/mozilla.png
ADDED
Binary file
|
images/browsers/mt.png
ADDED
Binary file
|
images/browsers/netbsd.png
ADDED
Binary file
|
images/browsers/netfront.png
ADDED
Binary file
|
images/browsers/netnewswire.png
ADDED
Binary file
|
images/browsers/netpositive.png
ADDED
Binary file
|
images/browsers/netscape.png
ADDED
Binary file
|
images/browsers/nintendo-ds.png
ADDED
Binary file
|
images/browsers/nintendo-gb.png
ADDED
Binary file
|
images/browsers/nintendo-wii.png
ADDED
Binary file
|
images/browsers/nokia.png
ADDED
Binary file
|
images/browsers/novell.png
ADDED
Binary file
|
images/browsers/o2.png
ADDED
Binary file
|
images/browsers/omniweb.png
ADDED
Binary file
|
images/browsers/openbsd.png
ADDED
Binary file
|
images/browsers/openwave.png
ADDED
Binary file
|
images/browsers/opera.png
ADDED
Binary file
|
images/browsers/orange.png
ADDED
Binary file
|
images/browsers/others.png
ADDED
Binary file
|
images/browsers/palm.png
ADDED
Binary file
|
images/browsers/pear.png
ADDED
Binary file
|
images/browsers/php.png
ADDED
Binary file
|
images/browsers/plone.png
ADDED
Binary file
|
images/browsers/pukiwiki.png
ADDED
Binary file
|
images/browsers/redhat.png
ADDED
Binary file
|
images/browsers/safari.png
ADDED
Binary file
|
images/browsers/samsung.png
ADDED
Binary file
|
images/browsers/seamonkey.png
ADDED
Binary file
|
images/browsers/seesaa.png
ADDED
Binary file
|
images/browsers/shiira.png
ADDED
Binary file
|
images/browsers/siemens.png
ADDED
Binary file
|
images/browsers/slackware.png
ADDED
Binary file
|
images/browsers/sleipnir.png
ADDED
Binary file
|
images/browsers/softbank.png
ADDED
Binary file
|
images/browsers/sony-ps.png
ADDED
Binary file
|
images/browsers/sony-psp.png
ADDED
Binary file
|
images/browsers/sonyericsson.png
ADDED
Binary file
|
images/browsers/sun.png
ADDED
Binary file
|
images/browsers/suse.png
ADDED
Binary file
|
images/browsers/symbian.png
ADDED
Binary file
|
images/browsers/tweet.png
ADDED
Binary file
|
images/browsers/typepad.png
ADDED
Binary file
|
images/browsers/ubuntu.png
ADDED
Binary file
|
images/browsers/universe.png
ADDED
Binary file
|
images/browsers/unknown.png
ADDED
Binary file
|
images/browsers/w3m.png
ADDED
Binary file
|
images/browsers/webpro.png
ADDED
Binary file
|
images/browsers/willcom.png
ADDED
Binary file
|
images/browsers/windows.png
ADDED
Binary file
|
images/browsers/windows_phone.png
ADDED
Binary file
|
images/browsers/wp.png
ADDED
Binary file
|
images/browsers/xiino.png
ADDED
Binary file
|
images/browsers/xoops.png
ADDED
Binary file
|
images/browsers/zope.png
ADDED
Binary file
|
images/flags/ad.png
ADDED
Binary file
|
images/flags/ae.png
ADDED
Binary file
|
images/flags/af.png
ADDED
Binary file
|
images/flags/ag.png
ADDED
Binary file
|
images/flags/ai.png
ADDED
Binary file
|
images/flags/al.png
ADDED
Binary file
|
images/flags/am.png
ADDED
Binary file
|
images/flags/an.png
ADDED
Binary file
|
images/flags/ao.png
ADDED
Binary file
|
images/flags/ar.png
ADDED
Binary file
|
images/flags/as.png
ADDED
Binary file
|
images/flags/at.png
ADDED
Binary file
|
images/flags/au.png
ADDED
Binary file
|
images/flags/aw.png
ADDED
Binary file
|
images/flags/ax.png
ADDED
Binary file
|
images/flags/az.png
ADDED
Binary file
|
images/flags/ba.png
ADDED
Binary file
|
images/flags/bb.png
ADDED
Binary file
|
images/flags/bd.png
ADDED
Binary file
|
images/flags/be.png
ADDED
Binary file
|
images/flags/bf.png
ADDED
Binary file
|
images/flags/bg.png
ADDED
Binary file
|
images/flags/bh.png
ADDED
Binary file
|
images/flags/bi.png
ADDED
Binary file
|
images/flags/bj.png
ADDED
Binary file
|
images/flags/bm.png
ADDED
Binary file
|
images/flags/bn.png
ADDED
Binary file
|
images/flags/bo.png
ADDED
Binary file
|
images/flags/br.png
ADDED
Binary file
|
images/flags/bs.png
ADDED
Binary file
|
images/flags/bt.png
ADDED
Binary file
|
images/flags/bv.png
ADDED
Binary file
|
images/flags/bw.png
ADDED
Binary file
|
images/flags/by.png
ADDED
Binary file
|
images/flags/bz.png
ADDED
Binary file
|
images/flags/ca.png
ADDED
Binary file
|
images/flags/catalonia.png
ADDED
Binary file
|
images/flags/cc.png
ADDED
Binary file
|
images/flags/cd.png
ADDED
Binary file
|
images/flags/cf.png
ADDED
Binary file
|
images/flags/cg.png
ADDED
Binary file
|
images/flags/ch.png
ADDED
Binary file
|
images/flags/ci.png
ADDED
Binary file
|
images/flags/ck.png
ADDED
Binary file
|
images/flags/cl.png
ADDED
Binary file
|
images/flags/cm.png
ADDED
Binary file
|
images/flags/cn.png
ADDED
Binary file
|
images/flags/co.png
ADDED
Binary file
|
images/flags/cr.png
ADDED
Binary file
|
images/flags/cs.png
ADDED
Binary file
|
images/flags/cu.png
ADDED
Binary file
|
images/flags/cv.png
ADDED
Binary file
|
images/flags/cx.png
ADDED
Binary file
|
images/flags/cy.png
ADDED
Binary file
|
images/flags/cz.png
ADDED
Binary file
|
images/flags/de.png
ADDED
Binary file
|
images/flags/dj.png
ADDED
Binary file
|
images/flags/dk.png
ADDED
Binary file
|
images/flags/dm.png
ADDED
Binary file
|
images/flags/do.png
ADDED
Binary file
|
images/flags/dz.png
ADDED
Binary file
|
images/flags/ec.png
ADDED
Binary file
|
images/flags/ee.png
ADDED
Binary file
|
images/flags/eg.png
ADDED
Binary file
|
images/flags/eh.png
ADDED
Binary file
|
images/flags/england.png
ADDED
Binary file
|
images/flags/er.png
ADDED
Binary file
|
images/flags/es.png
ADDED
Binary file
|
images/flags/et.png
ADDED
Binary file
|
images/flags/eu.png
ADDED
Binary file
|
images/flags/fam.png
ADDED
Binary file
|
images/flags/fi.png
ADDED
Binary file
|
images/flags/fj.png
ADDED
Binary file
|
images/flags/fk.png
ADDED
Binary file
|
images/flags/fm.png
ADDED
Binary file
|
images/flags/fo.png
ADDED
Binary file
|
images/flags/fr.png
ADDED
Binary file
|
images/flags/ga.png
ADDED
Binary file
|
images/flags/gb.png
ADDED
Binary file
|
images/flags/gd.png
ADDED
Binary file
|
images/flags/ge.png
ADDED
Binary file
|
images/flags/gf.png
ADDED
Binary file
|
images/flags/gh.png
ADDED
Binary file
|
images/flags/gi.png
ADDED
Binary file
|
images/flags/gl.png
ADDED
Binary file
|
images/flags/gm.png
ADDED
Binary file
|
images/flags/gn.png
ADDED
Binary file
|
images/flags/gp.png
ADDED
Binary file
|
images/flags/gq.png
ADDED
Binary file
|
images/flags/gr.png
ADDED
Binary file
|
images/flags/gs.png
ADDED
Binary file
|
images/flags/gt.png
ADDED
Binary file
|
images/flags/gu.png
ADDED
Binary file
|
images/flags/gw.png
ADDED
Binary file
|
images/flags/gy.png
ADDED
Binary file
|
images/flags/hk.png
ADDED
Binary file
|
images/flags/hm.png
ADDED
Binary file
|
images/flags/hn.png
ADDED
Binary file
|
images/flags/hr.png
ADDED
Binary file
|
images/flags/ht.png
ADDED
Binary file
|
images/flags/hu.png
ADDED
Binary file
|
images/flags/id.png
ADDED
Binary file
|
images/flags/ie.png
ADDED
Binary file
|
images/flags/il.png
ADDED
Binary file
|
images/flags/in.png
ADDED
Binary file
|
images/flags/io.png
ADDED
Binary file
|
images/flags/iq.png
ADDED
Binary file
|
images/flags/ir.png
ADDED
Binary file
|
images/flags/is.png
ADDED
Binary file
|
images/flags/it.png
ADDED
Binary file
|
images/flags/jm.png
ADDED
Binary file
|
images/flags/jo.png
ADDED
Binary file
|
images/flags/jp.png
ADDED
Binary file
|
images/flags/ke.png
ADDED
Binary file
|
images/flags/kg.png
ADDED
Binary file
|
images/flags/kh.png
ADDED
Binary file
|
images/flags/ki.png
ADDED
Binary file
|
images/flags/km.png
ADDED
Binary file
|
images/flags/kn.png
ADDED
Binary file
|
images/flags/kp.png
ADDED
Binary file
|
images/flags/kr.png
ADDED
Binary file
|
images/flags/kw.png
ADDED
Binary file
|
images/flags/ky.png
ADDED
Binary file
|
images/flags/kz.png
ADDED
Binary file
|
images/flags/la.png
ADDED
Binary file
|
images/flags/lb.png
ADDED
Binary file
|
images/flags/lc.png
ADDED
Binary file
|
images/flags/li.png
ADDED
Binary file
|
images/flags/lk.png
ADDED
Binary file
|
images/flags/lr.png
ADDED
Binary file
|
images/flags/ls.png
ADDED
Binary file
|
images/flags/lt.png
ADDED
Binary file
|
images/flags/lu.png
ADDED
Binary file
|
images/flags/lv.png
ADDED
Binary file
|
images/flags/ly.png
ADDED
Binary file
|
images/flags/ma.png
ADDED
Binary file
|
images/flags/mc.png
ADDED
Binary file
|
images/flags/md.png
ADDED
Binary file
|
images/flags/me.png
ADDED
Binary file
|
images/flags/mg.png
ADDED
Binary file
|
images/flags/mh.png
ADDED
Binary file
|
images/flags/mk.png
ADDED
Binary file
|
images/flags/ml.png
ADDED
Binary file
|
images/flags/mm.png
ADDED
Binary file
|
images/flags/mn.png
ADDED
Binary file
|
images/flags/mo.png
ADDED
Binary file
|
images/flags/mp.png
ADDED
Binary file
|
images/flags/mq.png
ADDED
Binary file
|
images/flags/mr.png
ADDED
Binary file
|
images/flags/ms.png
ADDED
Binary file
|
images/flags/mt.png
ADDED
Binary file
|
images/flags/mu.png
ADDED
Binary file
|
images/flags/mv.png
ADDED
Binary file
|
images/flags/mw.png
ADDED
Binary file
|
images/flags/mx.png
ADDED
Binary file
|
images/flags/my.png
ADDED
Binary file
|
images/flags/mz.png
ADDED
Binary file
|
images/flags/na.png
ADDED
Binary file
|
images/flags/nc.png
ADDED
Binary file
|
images/flags/ne.png
ADDED
Binary file
|
images/flags/nf.png
ADDED
Binary file
|
images/flags/ng.png
ADDED
Binary file
|
images/flags/ni.png
ADDED
Binary file
|
images/flags/nl.png
ADDED
Binary file
|
images/flags/no.png
ADDED
Binary file
|
images/flags/np.png
ADDED
Binary file
|
images/flags/nr.png
ADDED
Binary file
|
images/flags/nu.png
ADDED
Binary file
|
images/flags/nz.png
ADDED
Binary file
|
images/flags/om.png
ADDED
Binary file
|
images/flags/pa.png
ADDED
Binary file
|
images/flags/pe.png
ADDED
Binary file
|
images/flags/pf.png
ADDED
Binary file
|
images/flags/pg.png
ADDED
Binary file
|
images/flags/ph.png
ADDED
Binary file
|
images/flags/pk.png
ADDED
Binary file
|
images/flags/pl.png
ADDED
Binary file
|
images/flags/pm.png
ADDED
Binary file
|
images/flags/pn.png
ADDED
Binary file
|
images/flags/pr.png
ADDED
Binary file
|
images/flags/ps.png
ADDED
Binary file
|
images/flags/pt.png
ADDED
Binary file
|
images/flags/pw.png
ADDED
Binary file
|
images/flags/py.png
ADDED
Binary file
|
images/flags/qa.png
ADDED
Binary file
|
images/flags/re.png
ADDED
Binary file
|
images/flags/readme.txt
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
flag icons - famfamfam.com
|
2 |
+
|
3 |
+
Free for any use. If you use these flags in your software or
|
4 |
+
on your website, an email with a link or a screenshot would be nice. :)
|
5 |
+
|
6 |
+
- Thanks to Christian Cook for splitting it all up into separate images
|
7 |
+
|
8 |
+
Contact: mjames@gmail.com
|
images/flags/ro.png
ADDED
Binary file
|
images/flags/rs.png
ADDED
Binary file
|
images/flags/ru.png
ADDED
Binary file
|
images/flags/rw.png
ADDED
Binary file
|
images/flags/sa.png
ADDED
Binary file
|
images/flags/sb.png
ADDED
Binary file
|
images/flags/sc.png
ADDED
Binary file
|
images/flags/scotland.png
ADDED
Binary file
|
images/flags/sd.png
ADDED
Binary file
|
images/flags/se.png
ADDED
Binary file
|
images/flags/sg.png
ADDED
Binary file
|
images/flags/sh.png
ADDED
Binary file
|
images/flags/si.png
ADDED
Binary file
|
images/flags/sj.png
ADDED
Binary file
|
images/flags/sk.png
ADDED
Binary file
|
images/flags/sl.png
ADDED
Binary file
|
images/flags/sm.png
ADDED
Binary file
|
images/flags/sn.png
ADDED
Binary file
|
images/flags/so.png
ADDED
Binary file
|
images/flags/sr.png
ADDED
Binary file
|
images/flags/st.png
ADDED
Binary file
|
images/flags/sv.png
ADDED
Binary file
|
images/flags/sy.png
ADDED
Binary file
|
images/flags/sz.png
ADDED
Binary file
|
images/flags/tc.png
ADDED
Binary file
|
images/flags/td.png
ADDED
Binary file
|
images/flags/tf.png
ADDED
Binary file
|
images/flags/tg.png
ADDED
Binary file
|
images/flags/th.png
ADDED
Binary file
|
images/flags/tj.png
ADDED
Binary file
|
images/flags/tk.png
ADDED
Binary file
|
images/flags/tl.png
ADDED
Binary file
|
images/flags/tm.png
ADDED
Binary file
|
images/flags/tn.png
ADDED
Binary file
|
images/flags/to.png
ADDED
Binary file
|
images/flags/tr.png
ADDED
Binary file
|
images/flags/tt.png
ADDED
Binary file
|
images/flags/tv.png
ADDED
Binary file
|
images/flags/tw.png
ADDED
Binary file
|
images/flags/tz.png
ADDED
Binary file
|
images/flags/ua.png
ADDED
Binary file
|
images/flags/ug.png
ADDED
Binary file
|
images/flags/um.png
ADDED
Binary file
|
images/flags/unknown.png
ADDED
Binary file
|
images/flags/us.png
ADDED
Binary file
|
images/flags/uy.png
ADDED
Binary file
|
images/flags/uz.png
ADDED
Binary file
|
images/flags/va.png
ADDED
Binary file
|
images/flags/vc.png
ADDED
Binary file
|
images/flags/ve.png
ADDED
Binary file
|
images/flags/vg.png
ADDED
Binary file
|
images/flags/vi.png
ADDED
Binary file
|
images/flags/vn.png
ADDED
Binary file
|
images/flags/vu.png
ADDED
Binary file
|
images/flags/wales.png
ADDED
Binary file
|
images/flags/wf.png
ADDED
Binary file
|
images/flags/ws.png
ADDED
Binary file
|
images/flags/ye.png
ADDED
Binary file
|
images/flags/yt.png
ADDED
Binary file
|
images/flags/za.png
ADDED
Binary file
|
images/flags/zm.png
ADDED
Binary file
|
images/flags/zw.png
ADDED
Binary file
|
includes/class-detect-browsers.php
ADDED
@@ -0,0 +1,1082 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Detect browser
|
4 |
+
based on a wordpress plugin by Iman Nurchyo (http://priyadi.net/)
|
5 |
+
which is available at http://priyadi.net/archives/2005/03/29/wordpress-browser-detection-plugin/
|
6 |
+
|
7 |
+
License:
|
8 |
+
Released under the GPL license
|
9 |
+
http://www.gnu.org/copyleft/gpl.html
|
10 |
+
|
11 |
+
Copyright 2009 - 2011 wokamoto http://dogmap.jp/ (email : wokamoto1973@gmail.com)
|
12 |
+
|
13 |
+
This program is free software; you can redistribute it and/or modify
|
14 |
+
it under the terms of the GNU General Public License as published by
|
15 |
+
the Free Software Foundation; either version 2 of the License, or
|
16 |
+
(at your option) any later version.
|
17 |
+
|
18 |
+
This program is distributed in the hope that it will be useful,
|
19 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
21 |
+
GNU General Public License for more details.
|
22 |
+
|
23 |
+
You should have received a copy of the GNU General Public License
|
24 |
+
along with this program; if not, write to the Free Software
|
25 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
26 |
+
*/
|
27 |
+
|
28 |
+
class DetectBrowsers {
|
29 |
+
/**********************************************************
|
30 |
+
* is PC ?
|
31 |
+
***********************************************************/
|
32 |
+
static public function is_pc($ua = '') {
|
33 |
+
$result = FALSE;
|
34 |
+
|
35 |
+
if (!is_array($ua))
|
36 |
+
$ua = self::get_info($ua);
|
37 |
+
|
38 |
+
if (isset($ua['os'])) {
|
39 |
+
switch($ua['os']['code']) {
|
40 |
+
case 'windows':
|
41 |
+
case 'macos':
|
42 |
+
case 'linux':
|
43 |
+
case 'debian':
|
44 |
+
case 'mandrake':
|
45 |
+
case 'suse':
|
46 |
+
case 'novell':
|
47 |
+
case 'ubuntu':
|
48 |
+
case 'redhat':
|
49 |
+
case 'gentoo':
|
50 |
+
case 'fedora':
|
51 |
+
case 'slackware':
|
52 |
+
case 'freebsd':
|
53 |
+
case 'netbsd':
|
54 |
+
case 'openbsd':
|
55 |
+
case 'sgi':
|
56 |
+
case 'sun':
|
57 |
+
case 'unix':
|
58 |
+
$result = TRUE;
|
59 |
+
break;
|
60 |
+
default:
|
61 |
+
$result = FALSE;
|
62 |
+
break;
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
return $result;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**********************************************************
|
70 |
+
* is smartphone ?
|
71 |
+
***********************************************************/
|
72 |
+
static public function is_smartphone($ua = '') {
|
73 |
+
$result = FALSE;
|
74 |
+
|
75 |
+
if (!is_array($ua))
|
76 |
+
$ua = self::get_info($ua);
|
77 |
+
|
78 |
+
if (isset($ua['pda'])) {
|
79 |
+
switch($ua['pda']['code']) {
|
80 |
+
case 'iphone':
|
81 |
+
case 'android':
|
82 |
+
case 'blackberry':
|
83 |
+
case 'windows_phone':
|
84 |
+
case 'ipod':
|
85 |
+
$result = ! self::is_pc($ua);
|
86 |
+
break;
|
87 |
+
default:
|
88 |
+
$result = FALSE;
|
89 |
+
break;
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
return $result;
|
94 |
+
}
|
95 |
+
|
96 |
+
/**********************************************************
|
97 |
+
* is ktai ?
|
98 |
+
***********************************************************/
|
99 |
+
static public function is_ktai($ua = '') {
|
100 |
+
$result = FALSE;
|
101 |
+
|
102 |
+
if (!is_array($ua))
|
103 |
+
$ua = self::get_info($ua);
|
104 |
+
|
105 |
+
if (isset($ua['pda'])) {
|
106 |
+
switch($ua['pda']['code']) {
|
107 |
+
case 'docomo':
|
108 |
+
case 'au':
|
109 |
+
case 'softbank':
|
110 |
+
case 'willcom':
|
111 |
+
$result = ! self::is_smartphone($ua);
|
112 |
+
break;
|
113 |
+
default:
|
114 |
+
$result = ( $ua['os']['code'] === 'symbian' ? TRUE : FALSE );
|
115 |
+
break;
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
return $result;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**********************************************************
|
123 |
+
* Get Information from user agent
|
124 |
+
***********************************************************/
|
125 |
+
static public function get_info($ua = '') {
|
126 |
+
if ( empty($ua) && isset($_SERVER['HTTP_USER_AGENT']) )
|
127 |
+
$ua = $_SERVER['HTTP_USER_AGENT'];
|
128 |
+
|
129 |
+
$ua = preg_replace("/FunWebProducts/i", "", $ua);
|
130 |
+
|
131 |
+
$browser_name = $browser_code = $browser_ver = $os_name = $os_code = $os_ver = $pda_name = $pda_code = $pda_ver = null;
|
132 |
+
|
133 |
+
if ( empty($browser_name) ) {
|
134 |
+
if (preg_match('/(movabletype|wordpress|typepad|livedoortrackback|fc2|blogserver|hatena diary trackback agent|gooblog|lovelogtrackback|bitwave\.trackbackping|libwww-perl|jakarta commons-httpclient|java|xoops news\+trackback ver)[ \/]([a-z0-9\.]+)/i', $ua, $matches)) {
|
135 |
+
$browser_name = $matches[1];
|
136 |
+
$browser_code = strtolower(trim($browser_name));
|
137 |
+
$browser_ver = $matches[2];
|
138 |
+
$os_name = FALSE;
|
139 |
+
$pda_name = FALSE;
|
140 |
+
switch (strtolower($browser_code)) {
|
141 |
+
case 'movabletype':
|
142 |
+
$browser_name = 'MovableType';
|
143 |
+
$browser_code = 'mt';
|
144 |
+
break;
|
145 |
+
case 'wordpress':
|
146 |
+
$browser_name = 'WordPress';
|
147 |
+
$browser_code = 'wp';
|
148 |
+
break;
|
149 |
+
case 'typepad':
|
150 |
+
$browser_name = 'TypePad';
|
151 |
+
$browser_code = 'typepad';
|
152 |
+
break;
|
153 |
+
case 'livedoortrackback':
|
154 |
+
$browser_name = 'livedoor blog';
|
155 |
+
$browser_code = 'livedoor';
|
156 |
+
break;
|
157 |
+
case 'fc2':
|
158 |
+
$browser_name = 'FC2 blog';
|
159 |
+
$browser_code = 'fc2';
|
160 |
+
break;
|
161 |
+
case 'lovelogtrackback':
|
162 |
+
$browser_name = 'LOVELOG';
|
163 |
+
$browser_code = 'lovelog';
|
164 |
+
break;
|
165 |
+
case 'blogserver':
|
166 |
+
$browser_name = 'Seesaa blog';
|
167 |
+
$browser_code = 'seesaa';
|
168 |
+
break;
|
169 |
+
case 'hatena diary trackback agent':
|
170 |
+
$browser_name = 'Hatena Diary';
|
171 |
+
$browser_code = 'hatena';
|
172 |
+
break;
|
173 |
+
case 'gooblog':
|
174 |
+
$browser_name = 'goo blog';
|
175 |
+
$browser_code = 'gooblog';
|
176 |
+
break;
|
177 |
+
case 'bitwave.trackbackping':
|
178 |
+
$browser_name = 'Bitwave.jp';
|
179 |
+
$browser_code = 'bitwave';
|
180 |
+
break;
|
181 |
+
case 'libwww-perl':
|
182 |
+
$browser_name = 'libwww-perl';
|
183 |
+
$browser_code = 'libwww-perl';
|
184 |
+
break;
|
185 |
+
case 'jakarta commons-httpclient':
|
186 |
+
$browser_name = 'Jakarta Commons-HttpClient';
|
187 |
+
$browser_code = 'jakarta-apache';
|
188 |
+
break;
|
189 |
+
case 'java':
|
190 |
+
$browser_name = 'Java';
|
191 |
+
$browser_code = 'java';
|
192 |
+
break;
|
193 |
+
case 'xoops news+trackback ver':
|
194 |
+
$browser_name = 'XOOPS News+TrackBack';
|
195 |
+
$browser_code = 'xoops';
|
196 |
+
break;
|
197 |
+
}
|
198 |
+
} else if (preg_match('/(drupal|habari|pukiwiki|seesaa|jugem|avantbrowser.com|danger hiptop|anonymouse|pear http_request|coreblog2?)/i', $ua, $matches)) {
|
199 |
+
$browser_name = $matches[1];
|
200 |
+
$browser_code = strtolower(trim($browser_name));
|
201 |
+
$os_name = FALSE;
|
202 |
+
$pda_name = FALSE;
|
203 |
+
switch (strtolower($browser_code)) {
|
204 |
+
case 'drupal':
|
205 |
+
$browser_name = 'Drupal';
|
206 |
+
$browser_code = 'drupal';
|
207 |
+
break;
|
208 |
+
case 'habari':
|
209 |
+
$browser_name = 'Habari';
|
210 |
+
$browser_code = 'habari';
|
211 |
+
break;
|
212 |
+
case 'pukiwiki':
|
213 |
+
$browser_name = 'PukiWiki';
|
214 |
+
$browser_code = 'pukiwiki';
|
215 |
+
break;
|
216 |
+
case 'seesaa':
|
217 |
+
$browser_name = 'Seesaa blog';
|
218 |
+
$browser_code = 'seesaa';
|
219 |
+
break;
|
220 |
+
case 'jugem':
|
221 |
+
$browser_name = 'JUGEM blog';
|
222 |
+
$browser_code = 'jugem';
|
223 |
+
break;
|
224 |
+
case 'avantbrowser.com':
|
225 |
+
$browser_name = 'Avant Browser';
|
226 |
+
$browser_code = 'avantbrowser';
|
227 |
+
break;
|
228 |
+
case 'danger hiptop':
|
229 |
+
$browser_name = 'Danger HipTop';
|
230 |
+
$browser_code = 'danger';
|
231 |
+
break;
|
232 |
+
case 'anonymouse':
|
233 |
+
$browser_name = 'Anonymouse';
|
234 |
+
$browser_code = 'anonymouse';
|
235 |
+
break;
|
236 |
+
case 'pear http_request':
|
237 |
+
$browser_name = 'PEAR HTTP_Request';
|
238 |
+
$browser_code = 'pear';
|
239 |
+
break;
|
240 |
+
case 'coreblog':
|
241 |
+
$browser_name = 'COREBlog (Blog on Zope)';
|
242 |
+
$browser_code = 'zope';
|
243 |
+
break;
|
244 |
+
case 'coreblog2':
|
245 |
+
$browser_name = 'COREBlog2 (Blog on Plone)';
|
246 |
+
$browser_code = 'plone';
|
247 |
+
break;
|
248 |
+
}
|
249 |
+
} else if (preg_match('/trackback/i', $ua)) {
|
250 |
+
$browser_name = 'Trackback';
|
251 |
+
$browser_name = '';
|
252 |
+
$os_name = FALSE;
|
253 |
+
$pda_name = FALSE;
|
254 |
+
} else if (preg_match('/symbianos\/([a-z0-9\.]+)/i', $ua, $matches)) {
|
255 |
+
$os_name = 'SymbianOS';
|
256 |
+
$os_code = 'symbian';
|
257 |
+
$os_ver = $matches[1];
|
258 |
+
$pda_name = FALSE;
|
259 |
+
} else if (preg_match('/(docomo|up\.browser|j-phone|vodafone|softbank)/i', $ua, $matches)) {
|
260 |
+
$os_name = FALSE;
|
261 |
+
list($pda_name, $pda_code, $pda_ver) = self::_pda($ua);
|
262 |
+
} else if (preg_match('/wp\-(iphone|android|blackberry)/i', $ua, $matches)) {
|
263 |
+
$os_name = FALSE;
|
264 |
+
list($pda_name, $pda_code, $pda_ver) = self::_pda($ua);
|
265 |
+
$browser_name = 'WordPress';
|
266 |
+
switch ($pda_code) {
|
267 |
+
case 'iphone':
|
268 |
+
$browser_name .= ' for iPhone';
|
269 |
+
break;
|
270 |
+
case 'android':
|
271 |
+
$browser_name .= ' for Android';
|
272 |
+
break;
|
273 |
+
case 'blackberry':
|
274 |
+
$browser_name .= ' for BlackBerry';
|
275 |
+
break;
|
276 |
+
}
|
277 |
+
$browser_code = 'wp';
|
278 |
+
$browser_ver = $pda_ver;
|
279 |
+
} else if (preg_match('/(blackberry[0-9]+|\(ip(od|ad|hone);|ddipocket|willcom)/i', $ua, $matches)) {
|
280 |
+
$os_name = FALSE;
|
281 |
+
list($pda_name, $pda_code, $pda_ver) = self::_pda($ua);
|
282 |
+
switch ($pda_code) {
|
283 |
+
case 'blackberry':
|
284 |
+
if (preg_match('/(j2me|midp)[ \/\-]?([a-z0-9\.]+)?/i', $ua, $matches)) {
|
285 |
+
$browser_name = "J2ME/MIDP Browser";
|
286 |
+
$browser_code = "j2me";
|
287 |
+
$browser_ver = $matches[2];
|
288 |
+
}
|
289 |
+
break;
|
290 |
+
case 'ipod':
|
291 |
+
case 'ipad':
|
292 |
+
case 'iphone':
|
293 |
+
if (preg_match('/Version\/([a-z0-9\.]+)/', $ua, $matches))
|
294 |
+
$pda_ver = $matches[1];
|
295 |
+
if (preg_match('/Safari\/([a-z0-9\.]+)/i', $ua, $matches)) {
|
296 |
+
$browser_name = 'Safari';
|
297 |
+
$browser_code = 'safari';
|
298 |
+
$browser_ver = $matches[1];
|
299 |
+
}
|
300 |
+
break;
|
301 |
+
case 'willcom':
|
302 |
+
if (preg_match('/(netfront|opera)[ \/]([a-z0-9\.]+)/i', $ua, $matches)) {
|
303 |
+
$browser_name = $matches[1];
|
304 |
+
$browser_code = strtolower(trim($browser_name));
|
305 |
+
$browser_ver = $matches[2];
|
306 |
+
switch ($browser_code) {
|
307 |
+
case 'netfront':
|
308 |
+
$browser_name = 'Netfront';
|
309 |
+
$browser_code = 'netfront';
|
310 |
+
break;
|
311 |
+
case 'opera':
|
312 |
+
$browser_name = 'Opera';
|
313 |
+
$browser_code = 'opera';
|
314 |
+
break;
|
315 |
+
}
|
316 |
+
}
|
317 |
+
break;
|
318 |
+
}
|
319 |
+
} else if (preg_match('/ibisbrowser/i', $ua)) {
|
320 |
+
$browser_name = 'ibisBrowser';
|
321 |
+
$browser_code = 'ibisbrowser';
|
322 |
+
$os_name = FALSE;
|
323 |
+
} else if (preg_match('/jig browser ?([a-z0-9\.]+)?/i', $ua, $matches)) {
|
324 |
+
$browser_name = 'jig browser';
|
325 |
+
$browser_code = 'jig';
|
326 |
+
$browser_ver = $matches[1];
|
327 |
+
$os_name = FALSE;
|
328 |
+
} else if (preg_match('/(chrome|opera mini|camino|chimera|shiira|lunascape|sleipnir|konqueror|netnewswire|dillo|epiphany|seamonkey|kazehakase|flock|minimo|multizilla|galeon|icab|k-meleon|lynx|elinks|netpositive|omniweb|webpro|netfront|xiino|kunststofftraumte|w3m)[ \/]([a-z0-9\.]+)/i', $ua, $matches)) {
|
329 |
+
$browser_name = $matches[1];
|
330 |
+
$browser_code = strtolower(trim($browser_name));
|
331 |
+
$browser_ver = $matches[2];
|
332 |
+
$pda_name = FALSE;
|
333 |
+
switch ($browser_code) {
|
334 |
+
case 'chrome':
|
335 |
+
$browser_name = 'Google Chrome';
|
336 |
+
$browser_code = 'chrome';
|
337 |
+
break;
|
338 |
+
case 'opera mini':
|
339 |
+
$browser_name = 'Opera Mini';
|
340 |
+
$browser_code = 'opera';
|
341 |
+
if (preg_match('/Opera\/([a-z0-9\.]+)/i', $ua, $matches))
|
342 |
+
$browser_ver = $matches[1];
|
343 |
+
list($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::_os_pda($ua);
|
344 |
+
break;
|
345 |
+
break;
|
346 |
+
case 'camino':
|
347 |
+
case 'chimera':
|
348 |
+
$browser_name = 'Camino';
|
349 |
+
$browser_code = 'camino';
|
350 |
+
$os_name = "Mac OS";
|
351 |
+
$os_code = "macos";
|
352 |
+
$os_ver = "X";
|
353 |
+
break;
|
354 |
+
case 'shiira':
|
355 |
+
$browser_name = 'Shiira';
|
356 |
+
$browser_code = 'shiira';
|
357 |
+
$os_name = "Mac OS";
|
358 |
+
$os_code = "macos";
|
359 |
+
$os_ver = "X";
|
360 |
+
break;
|
361 |
+
case 'lunascape':
|
362 |
+
$browser_name = 'Lunascape';
|
363 |
+
$browser_code = 'lunascape';
|
364 |
+
break;
|
365 |
+
case 'sleipnir':
|
366 |
+
$browser_name = 'Sleipnir';
|
367 |
+
$browser_code = 'sleipnir';
|
368 |
+
break;
|
369 |
+
case 'konqueror':
|
370 |
+
$browser_name = 'Konqueror';
|
371 |
+
$browser_code = 'konqueror';
|
372 |
+
list($os_name, $os_code, $os_ver) = self::_os_unix($ua);
|
373 |
+
if (!$os_name)
|
374 |
+
list($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::_os_pda($ua);
|
375 |
+
break;
|
376 |
+
case 'netnewswire':
|
377 |
+
$browser_name = 'NetNewsWire';
|
378 |
+
$browser_code = 'netnewswire';
|
379 |
+
$os_name = "Mac OS";
|
380 |
+
$os_code = "macos";
|
381 |
+
$os_ver = "X";
|
382 |
+
break;
|
383 |
+
case 'dillo':
|
384 |
+
$browser_name = 'Dillo';
|
385 |
+
$browser_code = 'dillo';
|
386 |
+
$os_name = FALSE;
|
387 |
+
break;
|
388 |
+
case 'epiphany':
|
389 |
+
$browser_name = 'Epiphany';
|
390 |
+
$browser_code = 'epiphany';
|
391 |
+
list($os_name, $os_code, $os_ver) = self::_os_unix($ua);
|
392 |
+
break;
|
393 |
+
case 'seamonkey':
|
394 |
+
$browser_name = 'Mozilla SeaMonkey';
|
395 |
+
$browser_code = 'seamonkey';
|
396 |
+
break;
|
397 |
+
case 'kazehakase':
|
398 |
+
$browser_name = 'Kazehakase';
|
399 |
+
$browser_code = 'kazehakase';
|
400 |
+
break;
|
401 |
+
case 'flock':
|
402 |
+
$browser_name = 'Flock';
|
403 |
+
$browser_code = 'flock';
|
404 |
+
break;
|
405 |
+
case 'minimo':
|
406 |
+
$browser_name = 'Minimo';
|
407 |
+
$browser_code = 'mozilla';
|
408 |
+
break;
|
409 |
+
case 'multizilla':
|
410 |
+
$browser_name = 'MultiZilla';
|
411 |
+
$browser_code = 'mozilla';
|
412 |
+
break;
|
413 |
+
case 'galeon':
|
414 |
+
$browser_name = 'Galeon';
|
415 |
+
$browser_code = 'galeon';
|
416 |
+
list($os_name, $os_code, $os_ver) = self::_os_unix($ua);
|
417 |
+
break;
|
418 |
+
case 'icab':
|
419 |
+
$browser_name = 'iCab';
|
420 |
+
$browser_code = 'icab';
|
421 |
+
list($os_name, $os_code, $os_ver) = self::_os_mac($ua);
|
422 |
+
break;
|
423 |
+
case 'k-meleon':
|
424 |
+
$browser_name = 'K-Meleon';
|
425 |
+
$browser_code = 'kmeleon';
|
426 |
+
break;
|
427 |
+
case 'lynx':
|
428 |
+
$browser_name = 'Lynx';
|
429 |
+
$browser_code = 'lynx';
|
430 |
+
list($os_name, $os_code, $os_ver) = self::_os_unix($ua);
|
431 |
+
break;
|
432 |
+
case 'elinks':
|
433 |
+
$browser_name = 'ELinks';
|
434 |
+
$browser_code = 'lynx';
|
435 |
+
list($os_name, $os_code, $os_ver) = self::_os_unix($ua);
|
436 |
+
break;
|
437 |
+
case 'netpositive':
|
438 |
+
$browser_name = 'NetPositive';
|
439 |
+
$browser_code = 'netpositive';
|
440 |
+
$os_name = "BeOS";
|
441 |
+
$os_code = "beos";
|
442 |
+
break;
|
443 |
+
case 'omniweb':
|
444 |
+
$browser_name = 'OmniWeb';
|
445 |
+
$browser_code = 'omniweb';
|
446 |
+
$os_name = "Mac OS";
|
447 |
+
$os_code = "macos";
|
448 |
+
$os_ver = "X";
|
449 |
+
break;
|
450 |
+
case 'webpro':
|
451 |
+
$browser_name = 'WebPro';
|
452 |
+
$browser_code = 'webpro';
|
453 |
+
$browser_ver = $matches[1];
|
454 |
+
$os_name = "PalmOS";
|
455 |
+
$os_code = "palmos";
|
456 |
+
break;
|
457 |
+
case 'netfront':
|
458 |
+
$browser_name = 'Netfront';
|
459 |
+
$browser_code = 'netfront';
|
460 |
+
list($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::_os_pda($ua);
|
461 |
+
break;
|
462 |
+
case 'xiino':
|
463 |
+
$browser_name = 'Xiino';
|
464 |
+
$browser_code = 'xiino';
|
465 |
+
$os_name = FALSE;
|
466 |
+
break;
|
467 |
+
case 'kunststofftraumte':
|
468 |
+
$browser_name = 'Kunststoff Traumte';
|
469 |
+
$browser_code = '';
|
470 |
+
$os_name = FALSE;
|
471 |
+
break;
|
472 |
+
case 'w3m':
|
473 |
+
$browser_name = 'W3M';
|
474 |
+
$browser_code = 'w3m';
|
475 |
+
list($os_name, $os_code, $os_ver) = self::_os_unix($ua);
|
476 |
+
break;
|
477 |
+
}
|
478 |
+
} else if (preg_match('/(webpro|blazer|j2me|midp)[ \/\-]?([a-z0-9\.]+)?/i', $ua, $matches)) {
|
479 |
+
$browser_name = $matches[1];
|
480 |
+
$browser_code = strtolower(trim($browser_name));
|
481 |
+
$browser_ver = $matches[2];
|
482 |
+
$os_name = "PalmOS";
|
483 |
+
$os_code = "palmos";
|
484 |
+
switch ($browser_code) {
|
485 |
+
case 'webpro':
|
486 |
+
$browser_name = 'WebPro';
|
487 |
+
$browser_code = 'webpro';
|
488 |
+
$pda_name = FALSE;
|
489 |
+
break;
|
490 |
+
case 'blazer':
|
491 |
+
$browser_name = "Blazer";
|
492 |
+
$browser_code = "blazer";
|
493 |
+
$pda_name = FALSE;
|
494 |
+
break;
|
495 |
+
case 'j2me':
|
496 |
+
case 'midp':
|
497 |
+
$browser_name = "J2ME/MIDP Browser";
|
498 |
+
$browser_code = "j2me";
|
499 |
+
$os_name = FALSE;
|
500 |
+
$os_code = null;
|
501 |
+
break;
|
502 |
+
}
|
503 |
+
} else if (preg_match('/(opera|safari|firefox|shiretoko|firebird|phoenix|bonecho|granparadiso|minefield|iceweasel)[ \/]([a-z0-9\.]+)/i', $ua, $matches)) {
|
504 |
+
$browser_name = $matches[1];
|
505 |
+
$browser_code = strtolower(trim($browser_name));
|
506 |
+
$browser_ver = $matches[2];
|
507 |
+
$pda_name = FALSE;
|
508 |
+
switch ($browser_code) {
|
509 |
+
case 'safari':
|
510 |
+
$browser_name = 'Safari';
|
511 |
+
$browser_code = 'safari';
|
512 |
+
list($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::_os($ua);
|
513 |
+
break;
|
514 |
+
case 'firefox':
|
515 |
+
case 'shiretoko':
|
516 |
+
case 'firebird':
|
517 |
+
case 'phoenix':
|
518 |
+
case 'bonecho':
|
519 |
+
case 'granparadiso':
|
520 |
+
case 'minefield':
|
521 |
+
case 'iceweasel':
|
522 |
+
$browser_name = 'Mozilla Firefox';
|
523 |
+
$browser_code = 'firefox';
|
524 |
+
list($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::_os($ua);
|
525 |
+
$pda_name = FALSE;
|
526 |
+
break;
|
527 |
+
case 'opera':
|
528 |
+
$browser_name = 'Opera';
|
529 |
+
$browser_code = 'opera';
|
530 |
+
$browser_ver = $matches[1];
|
531 |
+
list($os_name, $os_code, $os_ver) = self::_os_win($ua);
|
532 |
+
if (!$os_name)
|
533 |
+
list($os_name, $os_code, $os_ver) = self::_os_unix($ua);
|
534 |
+
if (!$os_name)
|
535 |
+
list($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::_os_pda($ua);
|
536 |
+
if (!$os_name) {
|
537 |
+
if ( preg_match('/Wii/i', $ua) ) {
|
538 |
+
$os_name = "Nintendo Wii";
|
539 |
+
$os_code = "nintendo-wii";
|
540 |
+
} else if ( preg_match('/Nitro/i', $ua) ) {
|
541 |
+
$os_name = "Nintendo DS";
|
542 |
+
$os_code = "nintendo-ds";
|
543 |
+
}
|
544 |
+
}
|
545 |
+
// Windows CE
|
546 |
+
if ( $os_code == "windows" && $os_ver == "CE" )
|
547 |
+
list($pda_name, $pda_code, $pda_ver) = self::_pda($ua);
|
548 |
+
break;
|
549 |
+
}
|
550 |
+
} else if (preg_match('/(e?links \(|php\/)([a-z0-9\.]+)/i', $ua, $matches)) {
|
551 |
+
$browser_name = $matches[1];
|
552 |
+
$browser_code = strtolower(trim($browser_name));
|
553 |
+
$browser_ver = $matches[2];
|
554 |
+
$pda_name = FALSE;
|
555 |
+
switch ($browser_code) {
|
556 |
+
case 'links (':
|
557 |
+
$browser_name = 'Links';
|
558 |
+
$browser_code = 'lynx';
|
559 |
+
break;
|
560 |
+
case 'elinks (':
|
561 |
+
$browser_name = 'ELinks';
|
562 |
+
$browser_code = 'lynx';
|
563 |
+
break;
|
564 |
+
case 'php/':
|
565 |
+
$browser_name = 'PHP';
|
566 |
+
$browser_code = 'php';
|
567 |
+
break;
|
568 |
+
}
|
569 |
+
list($os_name, $os_code, $os_ver) = self::_os_unix($ua);
|
570 |
+
} else if (preg_match('/(nintendo gameboy)/i', $ua, $matches)) {
|
571 |
+
$os_name = FALSE;
|
572 |
+
$pda_name = $matches[1];
|
573 |
+
$pda_code = strtolower(trim($pda_name));
|
574 |
+
switch ($pda_code) {
|
575 |
+
case 'nintendo gameboy':
|
576 |
+
$pda_name = "Nintendo GameBoy";
|
577 |
+
$pda_code = "nintendo-gb";
|
578 |
+
if (preg_match('/Mech.Mozilla\/([a-z0-9\.]+)/i', $ua, $matches))
|
579 |
+
$pda_ver = $matches[1];
|
580 |
+
break;
|
581 |
+
}
|
582 |
+
} else if (preg_match('/(psp \(playstation portable\)\; |ps2; playstation bb navigator |playstation 3; |spv |nokia ?|sonyericsson ?|lge-|mot-|sie-|sec-|samsung-)([a-z0-9\.\-]+)/i', $ua, $matches)) {
|
583 |
+
$os_name = FALSE;
|
584 |
+
$pda_name = $matches[1];
|
585 |
+
$pda_code = strtolower(trim($pda_name));
|
586 |
+
$pda_ver = $matches[2];
|
587 |
+
switch ($pda_code) {
|
588 |
+
case 'psp (playstation portable);':
|
589 |
+
$pda_name = "Sony PSP";
|
590 |
+
$pda_code = "sony-psp";
|
591 |
+
break;
|
592 |
+
case 'ps2; playstation bb navigator':
|
593 |
+
$pda_name = "Sony PLAYSTATION 2";
|
594 |
+
$pda_code = "sony-ps";
|
595 |
+
break;
|
596 |
+
case 'playstation 3;':
|
597 |
+
$pda_name = "Sony PLAYSTATION 3";
|
598 |
+
$pda_code = "sony-ps";
|
599 |
+
break;
|
600 |
+
case 'spv':
|
601 |
+
$pda_name = "Orange SPV";
|
602 |
+
$pda_code = "orange";
|
603 |
+
break;
|
604 |
+
case 'nokia':
|
605 |
+
$pda_name = "Nokia";
|
606 |
+
$pda_code = "nokia";
|
607 |
+
break;
|
608 |
+
case 'sonyericsson':
|
609 |
+
$pda_name = "SonyEricsson";
|
610 |
+
$pda_code = "sonyericsson";
|
611 |
+
break;
|
612 |
+
case 'lge-':
|
613 |
+
$pda_name = "LG";
|
614 |
+
$pda_code = "lg";
|
615 |
+
break;
|
616 |
+
case 'mot-':
|
617 |
+
$pda_name = "Motorola";
|
618 |
+
$pda_code = "motorola";
|
619 |
+
break;
|
620 |
+
case 'sie-':
|
621 |
+
$pda_name = "Siemens";
|
622 |
+
$pda_code = "siemens";
|
623 |
+
break;
|
624 |
+
case 'sec-':
|
625 |
+
case 'samsung-':
|
626 |
+
$pda_name = "Samsung";
|
627 |
+
$pda_code = "samsung";
|
628 |
+
break;
|
629 |
+
}
|
630 |
+
} else if (preg_match('/IEMobile[ \/]([0-9\.]+):/', $ua, $matches)) {
|
631 |
+
$browser_name = 'Internet Explorer Mobile';
|
632 |
+
$browser_code = 'iemobile';
|
633 |
+
$browser_ver = $matches[1];
|
634 |
+
} else if (preg_match('/MSIE ([a-z0-9\.]+)/', $ua, $matches)) {
|
635 |
+
$browser_name = 'Internet Explorer';
|
636 |
+
$browser_code = 'ie';
|
637 |
+
$browser_ver = $matches[1];
|
638 |
+
if ( preg_match('/win64/i', $ua) )
|
639 |
+
$browser_ver .= ' (64bit)';
|
640 |
+
} else if (preg_match('/universe\/([0-9\.]+)/i', $ua, $matches)) {
|
641 |
+
$browser_name = 'Universe';
|
642 |
+
$browser_code = 'universe';
|
643 |
+
$browser_ver = $matches[1];
|
644 |
+
list($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::_os_pda($ua);
|
645 |
+
}else if (preg_match('/netscape[0-9]?\/([a-z0-9\.]+)/i', $ua, $matches)) {
|
646 |
+
$browser_name = 'Netscape';
|
647 |
+
$browser_code = 'netscape';
|
648 |
+
$browser_ver = $matches[1];
|
649 |
+
} else if (preg_match('/^Mozilla\/5\.0/', $ua) && preg_match('#rv:([a-z0-9\.]+)#i', $ua, $matches)) {
|
650 |
+
$browser_name = 'Mozilla';
|
651 |
+
$browser_code = 'mozilla';
|
652 |
+
$browser_ver = $matches[1];
|
653 |
+
} else if (preg_match('/^Mozilla\/([a-z0-9\.]+)/', $ua, $matches)) {
|
654 |
+
$browser_name = 'Netscape Navigator';
|
655 |
+
$browser_code = 'netscape';
|
656 |
+
$browser_ver = $matches[1];
|
657 |
+
}
|
658 |
+
}
|
659 |
+
|
660 |
+
// Get OS Information
|
661 |
+
if ( empty($os_name) && $os_name !== FALSE )
|
662 |
+
list($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::_os($ua);
|
663 |
+
if ( $os_name === FALSE )
|
664 |
+
$os_name = $os_code = $os_ver = null;
|
665 |
+
|
666 |
+
// Get PDA Plathome
|
667 |
+
if ( empty($pda_name) && $pda_name !== FALSE )
|
668 |
+
list($pda_name, $pda_code, $pda_ver) = self::_pda($ua);
|
669 |
+
if ( $pda_name === FALSE )
|
670 |
+
$pda_name = $pda_code = $pda_ver = null;
|
671 |
+
|
672 |
+
return array(
|
673 |
+
'browser' => array(
|
674 |
+
'name' => $browser_name ,
|
675 |
+
'code' => $browser_code ,
|
676 |
+
'version' => $browser_ver ,
|
677 |
+
),
|
678 |
+
'os' => array(
|
679 |
+
'name' => $os_name ,
|
680 |
+
'code' => $os_code ,
|
681 |
+
'version' => $os_ver ,
|
682 |
+
),
|
683 |
+
'pda' => array(
|
684 |
+
'name' => $pda_name ,
|
685 |
+
'code' => $pda_code ,
|
686 |
+
'version' => $pda_ver ,
|
687 |
+
),
|
688 |
+
);
|
689 |
+
}
|
690 |
+
|
691 |
+
static private function _os($ua) {
|
692 |
+
$os_name = $os_code = $os_ver = $pda_name = $pda_code = $pda_ver = null;
|
693 |
+
|
694 |
+
list($os_name, $os_code, $os_ver) = (preg_match('/win(dows)?/i', $ua)
|
695 |
+
? self::_os_win($ua)
|
696 |
+
: self::_os_unix($ua)
|
697 |
+
);
|
698 |
+
|
699 |
+
// Windows CE
|
700 |
+
if ( $os_code == "windows" && ( $os_ver == "CE" || empty($os_ver) ) )
|
701 |
+
list($pda_name, $pda_code, $pda_ver) = self::_pda($ua);
|
702 |
+
|
703 |
+
// Windows Phone
|
704 |
+
if ( $os_code == "windows_phone" )
|
705 |
+
list($pda_name, $pda_code, $pda_ver) = self::_pda($ua);
|
706 |
+
|
707 |
+
return array($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver);
|
708 |
+
}
|
709 |
+
|
710 |
+
static private function _os_win($ua) {
|
711 |
+
$os_name = $os_code = $os_ver = null;
|
712 |
+
|
713 |
+
if (preg_match('/mac_powerpc/i', $ua)) {
|
714 |
+
$os_name = "Mac OS";
|
715 |
+
$os_code = "macos";
|
716 |
+
} else if (preg_match('/win(dows)?[ \.]?(9[58]|9x 4\.90|[cm]e|2000|nt ?[456]\.0|nt ?5\.[12])/i', $ua, $matches)) {
|
717 |
+
$os_name = "Windows";
|
718 |
+
$os_code = "windows";
|
719 |
+
$os_ver = strtoupper(trim($matches[2]));
|
720 |
+
switch ($os_ver) {
|
721 |
+
case '95':
|
722 |
+
$os_ver = "95";
|
723 |
+
break;
|
724 |
+
case '9X 4.90';
|
725 |
+
case 'ME';
|
726 |
+
$os_ver = "ME";
|
727 |
+
break;
|
728 |
+
case 'NT4.0';
|
729 |
+
case 'NT 4.0';
|
730 |
+
$os_ver = "NT 4.0";
|
731 |
+
break;
|
732 |
+
case '2000':
|
733 |
+
case 'NT 5.0':
|
734 |
+
$os_ver = "2000";
|
735 |
+
break;
|
736 |
+
case 'NT 5.1':
|
737 |
+
$os_ver = "XP";
|
738 |
+
break;
|
739 |
+
case 'NT 5.2':
|
740 |
+
$os_ver = ( preg_match('/(win|wow)64/i', $ua) ? "XP (64bit)" : "Server 2003" );
|
741 |
+
break;
|
742 |
+
case 'NT 6.0':
|
743 |
+
$os_ver = "Vista" . ( preg_match('/(win|wow)64/i', $ua) ? " (64bit)" : "" );
|
744 |
+
break;
|
745 |
+
case 'NT 6.1':
|
746 |
+
$os_ver = "7" . ( preg_match('/(win|wow)64/i', $ua) ? " (64bit)" : "" );
|
747 |
+
break;
|
748 |
+
case 'CE';
|
749 |
+
$os_name = "Windows";
|
750 |
+
$os_code = "windows";
|
751 |
+
$os_ver = "CE";
|
752 |
+
if (preg_match('/ppc/i', $ua)) {
|
753 |
+
$os_name = "Microsoft PocketPC";
|
754 |
+
$os_code = "windows";
|
755 |
+
$os_ver = '';
|
756 |
+
}
|
757 |
+
if (preg_match('/smartphone/i', $ua)) {
|
758 |
+
$os_name = "Microsoft Smartphone";
|
759 |
+
$os_code = "windows";
|
760 |
+
$os_ver = '';
|
761 |
+
}
|
762 |
+
break;
|
763 |
+
}
|
764 |
+
} else if (preg_match('/win(dows)? phone os ([0-9\.]+)/i', $ua, $matches)) {
|
765 |
+
$os_name = "Windows Phone";
|
766 |
+
$os_code = "windows_phone";
|
767 |
+
$os_ver = strtoupper(trim($matches[2]));
|
768 |
+
} else if (preg_match('/win(dows )?nt/i', $ua)) {
|
769 |
+
$os_name = "Windows";
|
770 |
+
$os_code = "windows";
|
771 |
+
$os_ver = "NT";
|
772 |
+
}
|
773 |
+
|
774 |
+
return array($os_name, $os_code, $os_ver);
|
775 |
+
}
|
776 |
+
|
777 |
+
static private function _os_unix($ua) {
|
778 |
+
$os_name = $os_code = $os_ver = null;
|
779 |
+
|
780 |
+
if (preg_match('/linux/i', $ua)) {
|
781 |
+
$os_name = "Linux";
|
782 |
+
$os_code = "linux";
|
783 |
+
if (preg_match('/(android|debian|mandrake|suse|novell|ubuntu|red ?hat|gentoo|fedora|mepis|knoppix|slackware|xandros|kanotix)/i', $ua, $matches)) {
|
784 |
+
$os_code = strtolower(trim($matches[1]));
|
785 |
+
switch ($os_code) {
|
786 |
+
case 'android':
|
787 |
+
$os_name = "Android";
|
788 |
+
$os_code = "android";
|
789 |
+
break;
|
790 |
+
case 'debian':
|
791 |
+
$os_name = "Debian GNU/Linux";
|
792 |
+
$os_code = "debian";
|
793 |
+
break;
|
794 |
+
case 'mandrake':
|
795 |
+
$os_name = "Mandrake Linux";
|
796 |
+
$os_code = "mandrake";
|
797 |
+
break;
|
798 |
+
case 'suse':
|
799 |
+
$os_name = "SuSE Linux";
|
800 |
+
$os_code = "suse";
|
801 |
+
break;
|
802 |
+
case 'novell':
|
803 |
+
$os_name = "Novell Linux";
|
804 |
+
$os_code = "novell";
|
805 |
+
break;
|
806 |
+
case 'ubuntu':
|
807 |
+
$os_name = "Ubuntu Linux";
|
808 |
+
$os_code = "ubuntu";
|
809 |
+
break;
|
810 |
+
case 'redhat':
|
811 |
+
case 'red hat':
|
812 |
+
$os_name = "RedHat Linux";
|
813 |
+
$os_code = "redhat";
|
814 |
+
break;
|
815 |
+
case 'gentoo':
|
816 |
+
$os_name = "Gentoo Linux";
|
817 |
+
$os_code = "gentoo";
|
818 |
+
break;
|
819 |
+
case 'fedora':
|
820 |
+
$os_name = "Fedora Linux";
|
821 |
+
$os_code = "fedora";
|
822 |
+
break;
|
823 |
+
case 'mepis':
|
824 |
+
$os_name = "MEPIS Linux";
|
825 |
+
$os_code = "linux";
|
826 |
+
break;
|
827 |
+
case 'knoppix':
|
828 |
+
$os_name = "Knoppix Linux";
|
829 |
+
$os_code = "linux";
|
830 |
+
break;
|
831 |
+
case 'slackware':
|
832 |
+
$os_name = "Slackware Linux";
|
833 |
+
$os_code = "slackware";
|
834 |
+
break;
|
835 |
+
case 'xandros':
|
836 |
+
$os_name = "Xandros Linux";
|
837 |
+
$os_code = "linux";
|
838 |
+
break;
|
839 |
+
case 'kanotix':
|
840 |
+
$os_name = "Kanotix Linux";
|
841 |
+
$os_code = "linux";
|
842 |
+
break;
|
843 |
+
}
|
844 |
+
}
|
845 |
+
} else if (preg_match('/((free|net|open)bsd|irix|sunos|mac( os x|intosh|_powerpc))/i', $ua, $matches)) {
|
846 |
+
$os_name = trim($matches[1]);
|
847 |
+
$os_code = strtolower($os_name);
|
848 |
+
switch ($os_code) {
|
849 |
+
case 'freebsd':
|
850 |
+
$os_name = "FreeBSD";
|
851 |
+
$os_code = "freebsd";
|
852 |
+
break;
|
853 |
+
case 'netbsd':
|
854 |
+
$os_name = "NetBSD";
|
855 |
+
$os_code = "netbsd";
|
856 |
+
break;
|
857 |
+
case 'openbsd':
|
858 |
+
$os_name = "OpenBSD";
|
859 |
+
$os_code = "openbsd";
|
860 |
+
break;
|
861 |
+
case 'irix':
|
862 |
+
$os_name = "SGI IRIX";
|
863 |
+
$os_code = "sgi";
|
864 |
+
break;
|
865 |
+
case 'sunos':
|
866 |
+
$os_name = "Solaris";
|
867 |
+
$os_code = "sun";
|
868 |
+
break;
|
869 |
+
case 'mac os x':
|
870 |
+
$os_name = "Mac OS";
|
871 |
+
$os_code = "macos";
|
872 |
+
$os_ver = "X";
|
873 |
+
break;
|
874 |
+
case 'macintosh':
|
875 |
+
case 'mac_powerpc':
|
876 |
+
$os_name = "Mac OS";
|
877 |
+
$os_code = "macos";
|
878 |
+
break;
|
879 |
+
}
|
880 |
+
} else if (preg_match('/unix/i', $ua)) {
|
881 |
+
$os_name = "UNIX";
|
882 |
+
$os_code = "unix";
|
883 |
+
}
|
884 |
+
|
885 |
+
return array($os_name, $os_code, $os_ver);
|
886 |
+
}
|
887 |
+
|
888 |
+
static private function _os_mac($ua) {
|
889 |
+
$os_name = $os_code = $os_ver = null;
|
890 |
+
|
891 |
+
if (preg_match('/(mac( os x|intosh|_powerpc))/i', $ua, $matches)) {
|
892 |
+
$os_name = trim($matches[1]);
|
893 |
+
$os_code = strtolower($os_name);
|
894 |
+
switch ($os_code) {
|
895 |
+
case 'mac os x':
|
896 |
+
$os_name = "Mac OS";
|
897 |
+
$os_code = "macos";
|
898 |
+
$os_ver = "X";
|
899 |
+
break;
|
900 |
+
case 'macintosh':
|
901 |
+
case 'mac_powerpc':
|
902 |
+
$os_name = "Mac OS";
|
903 |
+
$os_code = "macos";
|
904 |
+
break;
|
905 |
+
}
|
906 |
+
}
|
907 |
+
|
908 |
+
return array($os_name, $os_code, $os_ver);
|
909 |
+
}
|
910 |
+
|
911 |
+
static private function _os_pda($ua) {
|
912 |
+
$os_name = $os_code = $os_ver = $pda_name = $pda_code = $pda_ver = null;
|
913 |
+
|
914 |
+
if (preg_match('/(palmos|windows ce|windows phone|qtembedded|zaurus|symbian)/i', $ua, $matches)) {
|
915 |
+
$os_name = $matches[1];
|
916 |
+
$os_code = strtolower($os_name);
|
917 |
+
switch ($os_code) {
|
918 |
+
case 'palmos':
|
919 |
+
$os_name = "Palm OS";
|
920 |
+
$os_code = "palm";
|
921 |
+
break;
|
922 |
+
case 'windows ce':
|
923 |
+
$os_name = "Windows CE";
|
924 |
+
$os_code = "windows";
|
925 |
+
break;
|
926 |
+
case 'windows phone':
|
927 |
+
$os_name = "Windows Phone";
|
928 |
+
$os_code = "windows";
|
929 |
+
break;
|
930 |
+
case 'qtembedded':
|
931 |
+
$os_name = "Qtopia";
|
932 |
+
$os_code = "linux";
|
933 |
+
break;
|
934 |
+
case 'zaurus':
|
935 |
+
$os_name = "Zaurus";
|
936 |
+
$os_code = "linux";
|
937 |
+
break;
|
938 |
+
case 'symbian':
|
939 |
+
$os_name = "Symbian OS";
|
940 |
+
$os_code = "symbian";
|
941 |
+
break;
|
942 |
+
}
|
943 |
+
}
|
944 |
+
list($pda_name, $pda_code, $pda_ver) = self::_pda($ua);
|
945 |
+
|
946 |
+
return array($os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver);
|
947 |
+
}
|
948 |
+
|
949 |
+
static private function _pda($ua) {
|
950 |
+
$pda_name = $pda_code = $pda_ver = null;
|
951 |
+
|
952 |
+
if (preg_match('/docomo\/([a-z0-9\.]+)/i', $ua, $matches)) {
|
953 |
+
$pda_name = 'DoCoMo';
|
954 |
+
$pda_code = 'docomo';
|
955 |
+
$pda_ver = $matches[1];
|
956 |
+
if ($pda_ver == '1.0' && preg_match('/docomo\/([a-z0-9\.]+)\/([a-z0-9\.]+)/i', $ua, $matches)) {
|
957 |
+
$pda_ver = $matches[2];
|
958 |
+
} else if ($pda_ver == '2.0' && preg_match('/docomo\/([a-z0-9\.]+) ([a-z0-9\.]+)/i', $ua, $matches)) {
|
959 |
+
$pda_ver = $matches[2];
|
960 |
+
}
|
961 |
+
} else if (preg_match('/up\.browser\/[a-z0-9\.]+/i', $ua)) {
|
962 |
+
$pda_name = 'au';
|
963 |
+
$pda_code = 'au';
|
964 |
+
if (preg_match('/kddi-([a-z0-9\.]+) up\.browser\/[a-z0-9\.]+/i', $ua, $matches)) {
|
965 |
+
$pda_ver = $matches[1];
|
966 |
+
} else if (preg_match('/up\.browser\/([a-z0-9\.]+)-([a-z0-9\.]+)/i', $ua, $matches)) {
|
967 |
+
$pda_ver = $matches[2];
|
968 |
+
}
|
969 |
+
} else if (preg_match('/^mozilla\/5\.0 \(([a-z0-9\.\-]+);softbank/i', $ua, $matches)) {
|
970 |
+
$pda_name = 'SoftBank';
|
971 |
+
$pda_code = 'softbank';
|
972 |
+
$pda_ver = $matches[1];
|
973 |
+
} else if (preg_match('/(j-phone|vodafone|softbank)\/[a-z0-9\.]+\/([a-z0-9\.\-]+)/i', $ua, $matches)) {
|
974 |
+
$pda_name = 'SoftBank';
|
975 |
+
$pda_code = 'softbank';
|
976 |
+
$pda_ver = $matches[2];
|
977 |
+
} else if (preg_match('/(ddipocket|willcom);[a-z0-9\.]+\/([a-z0-9\.\-]+)/i', $ua, $matches)) {
|
978 |
+
$os_name = FALSE;
|
979 |
+
$pda_name = 'WILLCOM';
|
980 |
+
$pda_code = 'willcom';
|
981 |
+
$pda_ver = $matches[2];
|
982 |
+
} else if (preg_match('/palmos\/sony\/model/i', $ua)) {
|
983 |
+
$pda_name = "Sony Clie";
|
984 |
+
$pda_code = "sony";
|
985 |
+
} else if (preg_match('/wp\-(iphone|android|blackberry)\/([0-9\.]+)/i', $ua, $matches)) {
|
986 |
+
$pda_name = trim($matches[1]);
|
987 |
+
$pda_code = strtolower($pda_name);
|
988 |
+
$pda_ver = $matches[2];
|
989 |
+
switch ($pda_code) {
|
990 |
+
case 'iphone':
|
991 |
+
$pda_name = "WordPress for iPhone";
|
992 |
+
$pda_code = "iphone";
|
993 |
+
$pda_ver = $matches[2];
|
994 |
+
break;
|
995 |
+
case 'android':
|
996 |
+
$pda_name = "WordPress for Android";
|
997 |
+
$pda_code = "android";
|
998 |
+
$pda_ver = $matches[2];
|
999 |
+
break;
|
1000 |
+
case 'blackberry':
|
1001 |
+
$pda_name = "WordPress for BlackBerry";
|
1002 |
+
$pda_code = "blackberry";
|
1003 |
+
$pda_ver = $matches[2];
|
1004 |
+
break;
|
1005 |
+
}
|
1006 |
+
} else if (preg_match('/(blackberry|\(ip(od|ad|hone);|series |nokia |windows phone os )([0-9\.]+)?/i', $ua, $matches)) {
|
1007 |
+
$pda_name = trim($matches[1]);
|
1008 |
+
$pda_code = strtolower($pda_name);
|
1009 |
+
$pda_ver = $matches[2];
|
1010 |
+
switch ($pda_code) {
|
1011 |
+
case 'blackberry':
|
1012 |
+
$pda_name = trim("BlackBerry " . $matches[2]);
|
1013 |
+
$pda_code = "blackberry";
|
1014 |
+
$pda_ver = null;
|
1015 |
+
break;
|
1016 |
+
case '(ipod;':
|
1017 |
+
$pda_name = "iPod touch";
|
1018 |
+
$pda_code = "ipod";
|
1019 |
+
if (preg_match('/Version\/([a-z0-9\.]+)/', $ua, $matches))
|
1020 |
+
$pda_ver = $matches[1];
|
1021 |
+
break;
|
1022 |
+
case '(ipad;':
|
1023 |
+
$pda_name = "iPad";
|
1024 |
+
$pda_code = "ipad";
|
1025 |
+
if (preg_match('/Version\/([a-z0-9\.]+)/', $ua, $matches))
|
1026 |
+
$pda_ver = $matches[1];
|
1027 |
+
break;
|
1028 |
+
case '(iphone;':
|
1029 |
+
$pda_name = "iPhone";
|
1030 |
+
$pda_code = "iphone";
|
1031 |
+
if (preg_match('/Version\/([a-z0-9\.]+)/', $ua, $matches))
|
1032 |
+
$pda_ver = $matches[1];
|
1033 |
+
break;
|
1034 |
+
case 'series':
|
1035 |
+
$pda_name = "Series";
|
1036 |
+
$pda_code = "nokia";
|
1037 |
+
break;
|
1038 |
+
case 'nokia':
|
1039 |
+
$pda_name = "Nokia";
|
1040 |
+
$pda_code = "nokia";
|
1041 |
+
break;
|
1042 |
+
case 'windows phone os':
|
1043 |
+
$pda_name = "Windows Phone";
|
1044 |
+
$pda_code = "windows_phone";
|
1045 |
+
break;
|
1046 |
+
}
|
1047 |
+
} else if (preg_match('/(zaurus|sie-|dopod|o2 xda |sec-|sonyericsson ?)([a-z0-9\.]+)?/i', $ua, $matches)) {
|
1048 |
+
$pda_name = trim($matches[1]);
|
1049 |
+
$pda_code = strtolower($pda_name);
|
1050 |
+
$pda_ver = $matches[1];
|
1051 |
+
switch ($pda_code) {
|
1052 |
+
case 'zaurus':
|
1053 |
+
$pda_name = "Sharp Zaurus " . $matches[1];
|
1054 |
+
$pda_code = "zaurus";
|
1055 |
+
$pda_ver = null;
|
1056 |
+
break;
|
1057 |
+
case 'sie-':
|
1058 |
+
$pda_name = "Siemens";
|
1059 |
+
$pda_code = "siemens";
|
1060 |
+
break;
|
1061 |
+
case 'dopod':
|
1062 |
+
$pda_name = "Dopod";
|
1063 |
+
$pda_code = "dopod";
|
1064 |
+
break;
|
1065 |
+
case 'o2 xda':
|
1066 |
+
$pda_name = "O2 XDA";
|
1067 |
+
$pda_code = "o2";
|
1068 |
+
break;
|
1069 |
+
case 'sec-':
|
1070 |
+
$pda_name = "Samsung";
|
1071 |
+
$pda_code = "samsung";
|
1072 |
+
break;
|
1073 |
+
case 'sonyericsson':
|
1074 |
+
$pda_name = "SonyEricsson";
|
1075 |
+
$pda_code = "sonyericsson";
|
1076 |
+
break;
|
1077 |
+
}
|
1078 |
+
}
|
1079 |
+
|
1080 |
+
return array($pda_name, $pda_code, $pda_ver);
|
1081 |
+
}
|
1082 |
+
}
|
includes/detect_browsers.php
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Detect browser
|
4 |
+
based on a wordpress plugin by Iman Nurchyo (http://priyadi.net/)
|
5 |
+
which is available at http://priyadi.net/archives/2005/03/29/wordpress-browser-detection-plugin/
|
6 |
+
|
7 |
+
License:
|
8 |
+
Released under the GPL license
|
9 |
+
http://www.gnu.org/copyleft/gpl.html
|
10 |
+
|
11 |
+
Copyright 2009 - 2010 wokamoto http://dogmap.jp/ (email : wokamoto1973@gmail.com)
|
12 |
+
|
13 |
+
This program is free software; you can redistribute it and/or modify
|
14 |
+
it under the terms of the GNU General Public License as published by
|
15 |
+
the Free Software Foundation; either version 2 of the License, or
|
16 |
+
(at your option) any later version.
|
17 |
+
|
18 |
+
This program is distributed in the hope that it will be useful,
|
19 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
21 |
+
GNU General Public License for more details.
|
22 |
+
|
23 |
+
You should have received a copy of the GNU General Public License
|
24 |
+
along with this program; if not, write to the Free Software
|
25 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
26 |
+
*/
|
27 |
+
|
28 |
+
class DetectBrowsersController {
|
29 |
+
var $_ua_cache = array();
|
30 |
+
|
31 |
+
/**********************************************************
|
32 |
+
* Constructor
|
33 |
+
***********************************************************/
|
34 |
+
function DetectBrowsersController() {
|
35 |
+
$this->__construct();
|
36 |
+
}
|
37 |
+
function __construct() {
|
38 |
+
if (!class_exists('DetectBrowsers'))
|
39 |
+
require_once 'class-detect-browsers.php';
|
40 |
+
}
|
41 |
+
|
42 |
+
/**********************************************************
|
43 |
+
* Get Information from user agent
|
44 |
+
***********************************************************/
|
45 |
+
function get_info($ua) {
|
46 |
+
if ( isset($this->_ua_cache[$ua]) )
|
47 |
+
return $this->_ua_cache[$ua];
|
48 |
+
|
49 |
+
$info = DetectBrowsers::get_info($ua);
|
50 |
+
$this->_ua_cache[$ua] = array(
|
51 |
+
$info['browser']['name'] ,
|
52 |
+
$info['browser']['code'] ,
|
53 |
+
$info['browser']['version'] ,
|
54 |
+
$info['os']['name'] ,
|
55 |
+
$info['os']['code'] ,
|
56 |
+
$info['os']['version'] ,
|
57 |
+
$info['pda']['name'] ,
|
58 |
+
$info['pda']['code'] ,
|
59 |
+
$info['pda']['version'] ,
|
60 |
+
);
|
61 |
+
|
62 |
+
return $this->_ua_cache[$ua];
|
63 |
+
}
|
64 |
+
}
|
includes/detect_countries.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Detect Country
|
4 |
+
Require IP2C - Copyright (C) 2006 Omry Yadan (omry@yadan.net), all rights reserved
|
5 |
+
|
6 |
+
License:
|
7 |
+
Released under the GPL license
|
8 |
+
http://www.gnu.org/copyleft/gpl.html
|
9 |
+
|
10 |
+
Copyright 2009 wokamoto http://dogmap.jp/ (email : wokamoto1973@gmail.com)
|
11 |
+
|
12 |
+
This program is free software; you can redistribute it and/or modify
|
13 |
+
it under the terms of the GNU General Public License as published by
|
14 |
+
the Free Software Foundation; either version 2 of the License, or
|
15 |
+
(at your option) any later version.
|
16 |
+
|
17 |
+
This program is distributed in the hope that it will be useful,
|
18 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
20 |
+
GNU General Public License for more details.
|
21 |
+
|
22 |
+
You should have received a copy of the GNU General Public License
|
23 |
+
along with this program; if not, write to the Free Software
|
24 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
25 |
+
*/
|
26 |
+
|
27 |
+
if ( !class_exists('ip2country') )
|
28 |
+
require_once( dirname(__FILE__) . '/ip2c/ip2c.php' );
|
29 |
+
|
30 |
+
class DetectCountriesController {
|
31 |
+
private $ip2c;
|
32 |
+
private $ip2c_dir;
|
33 |
+
|
34 |
+
const IP2C_BIN_FILE = 'ip-to-country.bin';
|
35 |
+
const IP2C_VER_FILE = 'db.version';
|
36 |
+
|
37 |
+
|
38 |
+
/**********************************************************
|
39 |
+
* Constructor
|
40 |
+
***********************************************************/
|
41 |
+
function __construct() {
|
42 |
+
// Check ip-to-country.bin file
|
43 |
+
$ip2c_bin_file = dirname(__FILE__) . '/ip2c/' .self::IP2C_BIN_FILE;
|
44 |
+
if ( !file_exists($ip2c_bin_file) ) {
|
45 |
+
$ip2c_bin_file = null;
|
46 |
+
}
|
47 |
+
$this->ip2c = new ip2country($ip2c_bin_file);
|
48 |
+
}
|
49 |
+
|
50 |
+
public function get_info($ip) {
|
51 |
+
$res = $this->ip2c->get_country($ip);
|
52 |
+
$ccode = $res != false ? $res['id2'] : null;
|
53 |
+
unset($res);
|
54 |
+
|
55 |
+
return array(
|
56 |
+
$ccode ? $this->get_country_name($ccode) : null,
|
57 |
+
$ccode
|
58 |
+
);
|
59 |
+
}
|
60 |
+
|
61 |
+
// Get country name
|
62 |
+
private function get_country_name($country_code) {
|
63 |
+
$res = $this->ip2c->find_country($country_code);
|
64 |
+
return (isset($res['name']) ? $res['name'] : '');
|
65 |
+
}
|
66 |
+
}
|
includes/ip2c/GPL_V2
ADDED
@@ -0,0 +1,341 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
+
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
5 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
6 |
+
Everyone is permitted to copy and distribute verbatim copies
|
7 |
+
of this license document, but changing it is not allowed.
|
8 |
+
|
9 |
+
Preamble
|
10 |
+
|
11 |
+
The licenses for most software are designed to take away your
|
12 |
+
freedom to share and change it. By contrast, the GNU General Public
|
13 |
+
License is intended to guarantee your freedom to share and change free
|
14 |
+
software--to make sure the software is free for all its users. This
|
15 |
+
General Public License applies to most of the Free Software
|
16 |
+
Foundation's software and to any other program whose authors commit to
|
17 |
+
using it. (Some other Free Software Foundation software is covered by
|
18 |
+
the GNU Library General Public License instead.) You can apply it to
|
19 |
+
your programs, too.
|
20 |
+
|
21 |
+
When we speak of free software, we are referring to freedom, not
|
22 |
+
price. Our General Public Licenses are designed to make sure that you
|
23 |
+
have the freedom to distribute copies of free software (and charge for
|
24 |
+
this service if you wish), that you receive source code or can get it
|
25 |
+
if you want it, that you can change the software or use pieces of it
|
26 |
+
in new free programs; and that you know you can do these things.
|
27 |
+
|
28 |
+
To protect your rights, we need to make restrictions that forbid
|
29 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
30 |
+
These restrictions translate to certain responsibilities for you if you
|
31 |
+
distribute copies of the software, or if you modify it.
|
32 |
+
|
33 |
+
For example, if you distribute copies of such a program, whether
|
34 |
+
gratis or for a fee, you must give the recipients all the rights that
|
35 |
+
you have. You must make sure that they, too, receive or can get the
|
36 |
+
source code. And you must show them these terms so they know their
|
37 |
+
rights.
|
38 |
+
|
39 |
+
We protect your rights with two steps: (1) copyright the software, and
|
40 |
+
(2) offer you this license which gives you legal permission to copy,
|
41 |
+
distribute and/or modify the software.
|
42 |
+
|
43 |
+
Also, for each author's protection and ours, we want to make certain
|
44 |
+
that everyone understands that there is no warranty for this free
|
45 |
+
software. If the software is modified by someone else and passed on, we
|
46 |
+
want its recipients to know that what they have is not the original, so
|
47 |
+
that any problems introduced by others will not reflect on the original
|
48 |
+
authors' reputations.
|
49 |
+
|
50 |
+
Finally, any free program is threatened constantly by software
|
51 |
+
patents. We wish to avoid the danger that redistributors of a free
|
52 |
+
program will individually obtain patent licenses, in effect making the
|
53 |
+
program proprietary. To prevent this, we have made it clear that any
|
54 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
55 |
+
|
56 |
+
The precise terms and conditions for copying, distribution and
|
57 |
+
modification follow.
|
58 |
+
|
59 |
+
GNU GENERAL PUBLIC LICENSE
|
60 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61 |
+
|
62 |
+
0. This License applies to any program or other work which contains
|
63 |
+
a notice placed by the copyright holder saying it may be distributed
|
64 |
+
under the terms of this General Public License. The "Program", below,
|
65 |
+
refers to any such program or work, and a "work based on the Program"
|
66 |
+
means either the Program or any derivative work under copyright law:
|
67 |
+
that is to say, a work containing the Program or a portion of it,
|
68 |
+
either verbatim or with modifications and/or translated into another
|
69 |
+
language. (Hereinafter, translation is included without limitation in
|
70 |
+
the term "modification".) Each licensee is addressed as "you".
|
71 |
+
|
72 |
+
Activities other than copying, distribution and modification are not
|
73 |
+
covered by this License; they are outside its scope. The act of
|
74 |
+
running the Program is not restricted, and the output from the Program
|
75 |
+
is covered only if its contents constitute a work based on the
|
76 |
+
Program (independent of having been made by running the Program).
|
77 |
+
Whether that is true depends on what the Program does.
|
78 |
+
|
79 |
+
1. You may copy and distribute verbatim copies of the Program's
|
80 |
+
source code as you receive it, in any medium, provided that you
|
81 |
+
conspicuously and appropriately publish on each copy an appropriate
|
82 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
83 |
+
notices that refer to this License and to the absence of any warranty;
|
84 |
+
and give any other recipients of the Program a copy of this License
|
85 |
+
along with the Program.
|
86 |
+
|
87 |
+
You may charge a fee for the physical act of transferring a copy, and
|
88 |
+
you may at your option offer warranty protection in exchange for a fee.
|
89 |
+
|
90 |
+
2. You may modify your copy or copies of the Program or any portion
|
91 |
+
of it, thus forming a work based on the Program, and copy and
|
92 |
+
distribute such modifications or work under the terms of Section 1
|
93 |
+
above, provided that you also meet all of these conditions:
|
94 |
+
|
95 |
+
a) You must cause the modified files to carry prominent notices
|
96 |
+
stating that you changed the files and the date of any change.
|
97 |
+
|
98 |
+
b) You must cause any work that you distribute or publish, that in
|
99 |
+
whole or in part contains or is derived from the Program or any
|
100 |
+
part thereof, to be licensed as a whole at no charge to all third
|
101 |
+
parties under the terms of this License.
|
102 |
+
|
103 |
+
c) If the modified program normally reads commands interactively
|
104 |
+
when run, you must cause it, when started running for such
|
105 |
+
interactive use in the most ordinary way, to print or display an
|
106 |
+
announcement including an appropriate copyright notice and a
|
107 |
+
notice that there is no warranty (or else, saying that you provide
|
108 |
+
a warranty) and that users may redistribute the program under
|
109 |
+
these conditions, and telling the user how to view a copy of this
|
110 |
+
License. (Exception: if the Program itself is interactive but
|
111 |
+
does not normally print such an announcement, your work based on
|
112 |
+
the Program is not required to print an announcement.)
|
113 |
+
|
114 |
+
These requirements apply to the modified work as a whole. If
|
115 |
+
identifiable sections of that work are not derived from the Program,
|
116 |
+
and can be reasonably considered independent and separate works in
|
117 |
+
themselves, then this License, and its terms, do not apply to those
|
118 |
+
sections when you distribute them as separate works. But when you
|
119 |
+
distribute the same sections as part of a whole which is a work based
|
120 |
+
on the Program, the distribution of the whole must be on the terms of
|
121 |
+
this License, whose permissions for other licensees extend to the
|
122 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
123 |
+
|
124 |
+
Thus, it is not the intent of this section to claim rights or contest
|
125 |
+
your rights to work written entirely by you; rather, the intent is to
|
126 |
+
exercise the right to control the distribution of derivative or
|
127 |
+
collective works based on the Program.
|
128 |
+
|
129 |
+
In addition, mere aggregation of another work not based on the Program
|
130 |
+
with the Program (or with a work based on the Program) on a volume of
|
131 |
+
a storage or distribution medium does not bring the other work under
|
132 |
+
the scope of this License.
|
133 |
+
|
134 |
+
3. You may copy and distribute the Program (or a work based on it,
|
135 |
+
under Section 2) in object code or executable form under the terms of
|
136 |
+
Sections 1 and 2 above provided that you also do one of the following:
|
137 |
+
|
138 |
+
a) Accompany it with the complete corresponding machine-readable
|
139 |
+
source code, which must be distributed under the terms of Sections
|
140 |
+
1 and 2 above on a medium customarily used for software interchange; or,
|
141 |
+
|
142 |
+
b) Accompany it with a written offer, valid for at least three
|
143 |
+
years, to give any third party, for a charge no more than your
|
144 |
+
cost of physically performing source distribution, a complete
|
145 |
+
machine-readable copy of the corresponding source code, to be
|
146 |
+
distributed under the terms of Sections 1 and 2 above on a medium
|
147 |
+
customarily used for software interchange; or,
|
148 |
+
|
149 |
+
c) Accompany it with the information you received as to the offer
|
150 |
+
to distribute corresponding source code. (This alternative is
|
151 |
+
allowed only for noncommercial distribution and only if you
|
152 |
+
received the program in object code or executable form with such
|
153 |
+
an offer, in accord with Subsection b above.)
|
154 |
+
|
155 |
+
The source code for a work means the preferred form of the work for
|
156 |
+
making modifications to it. For an executable work, complete source
|
157 |
+
code means all the source code for all modules it contains, plus any
|
158 |
+
associated interface definition files, plus the scripts used to
|
159 |
+
control compilation and installation of the executable. However, as a
|
160 |
+
special exception, the source code distributed need not include
|
161 |
+
anything that is normally distributed (in either source or binary
|
162 |
+
form) with the major components (compiler, kernel, and so on) of the
|
163 |
+
operating system on which the executable runs, unless that component
|
164 |
+
itself accompanies the executable.
|
165 |
+
|
166 |
+
If distribution of executable or object code is made by offering
|
167 |
+
access to copy from a designated place, then offering equivalent
|
168 |
+
access to copy the source code from the same place counts as
|
169 |
+
distribution of the source code, even though third parties are not
|
170 |
+
compelled to copy the source along with the object code.
|
171 |
+
|
172 |
+
4. You may not copy, modify, sublicense, or distribute the Program
|
173 |
+
except as expressly provided under this License. Any attempt
|
174 |
+
otherwise to copy, modify, sublicense or distribute the Program is
|
175 |
+
void, and will automatically terminate your rights under this License.
|
176 |
+
However, parties who have received copies, or rights, from you under
|
177 |
+
this License will not have their licenses terminated so long as such
|
178 |
+
parties remain in full compliance.
|
179 |
+
|
180 |
+
5. You are not required to accept this License, since you have not
|
181 |
+
signed it. However, nothing else grants you permission to modify or
|
182 |
+
distribute the Program or its derivative works. These actions are
|
183 |
+
prohibited by law if you do not accept this License. Therefore, by
|
184 |
+
modifying or distributing the Program (or any work based on the
|
185 |
+
Program), you indicate your acceptance of this License to do so, and
|
186 |
+
all its terms and conditions for copying, distributing or modifying
|
187 |
+
the Program or works based on it.
|
188 |
+
|
189 |
+
6. Each time you redistribute the Program (or any work based on the
|
190 |
+
Program), the recipient automatically receives a license from the
|
191 |
+
original licensor to copy, distribute or modify the Program subject to
|
192 |
+
these terms and conditions. You may not impose any further
|
193 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
194 |
+
You are not responsible for enforcing compliance by third parties to
|
195 |
+
this License.
|
196 |
+
|
197 |
+
7. If, as a consequence of a court judgment or allegation of patent
|
198 |
+
infringement or for any other reason (not limited to patent issues),
|
199 |
+
conditions are imposed on you (whether by court order, agreement or
|
200 |
+
otherwise) that contradict the conditions of this License, they do not
|
201 |
+
excuse you from the conditions of this License. If you cannot
|
202 |
+
distribute so as to satisfy simultaneously your obligations under this
|
203 |
+
License and any other pertinent obligations, then as a consequence you
|
204 |
+
may not distribute the Program at all. For example, if a patent
|
205 |
+
license would not permit royalty-free redistribution of the Program by
|
206 |
+
all those who receive copies directly or indirectly through you, then
|
207 |
+
the only way you could satisfy both it and this License would be to
|
208 |
+
refrain entirely from distribution of the Program.
|
209 |
+
|
210 |
+
If any portion of this section is held invalid or unenforceable under
|
211 |
+
any particular circumstance, the balance of the section is intended to
|
212 |
+
apply and the section as a whole is intended to apply in other
|
213 |
+
circumstances.
|
214 |
+
|
215 |
+
It is not the purpose of this section to induce you to infringe any
|
216 |
+
patents or other property right claims or to contest validity of any
|
217 |
+
such claims; this section has the sole purpose of protecting the
|
218 |
+
integrity of the free software distribution system, which is
|
219 |
+
implemented by public license practices. Many people have made
|
220 |
+
generous contributions to the wide range of software distributed
|
221 |
+
through that system in reliance on consistent application of that
|
222 |
+
system; it is up to the author/donor to decide if he or she is willing
|
223 |
+
to distribute software through any other system and a licensee cannot
|
224 |
+
impose that choice.
|
225 |
+
|
226 |
+
This section is intended to make thoroughly clear what is believed to
|
227 |
+
be a consequence of the rest of this License.
|
228 |
+
|
229 |
+
8. If the distribution and/or use of the Program is restricted in
|
230 |
+
certain countries either by patents or by copyrighted interfaces, the
|
231 |
+
original copyright holder who places the Program under this License
|
232 |
+
may add an explicit geographical distribution limitation excluding
|
233 |
+
those countries, so that distribution is permitted only in or among
|
234 |
+
countries not thus excluded. In such case, this License incorporates
|
235 |
+
the limitation as if written in the body of this License.
|
236 |
+
|
237 |
+
9. The Free Software Foundation may publish revised and/or new versions
|
238 |
+
of the General Public License from time to time. Such new versions will
|
239 |
+
be similar in spirit to the present version, but may differ in detail to
|
240 |
+
address new problems or concerns.
|
241 |
+
|
242 |
+
Each version is given a distinguishing version number. If the Program
|
243 |
+
specifies a version number of this License which applies to it and "any
|
244 |
+
later version", you have the option of following the terms and conditions
|
245 |
+
either of that version or of any later version published by the Free
|
246 |
+
Software Foundation. If the Program does not specify a version number of
|
247 |
+
this License, you may choose any version ever published by the Free Software
|
248 |
+
Foundation.
|
249 |
+
|
250 |
+
10. If you wish to incorporate parts of the Program into other free
|
251 |
+
programs whose distribution conditions are different, write to the author
|
252 |
+
to ask for permission. For software which is copyrighted by the Free
|
253 |
+
Software Foundation, write to the Free Software Foundation; we sometimes
|
254 |
+
make exceptions for this. Our decision will be guided by the two goals
|
255 |
+
of preserving the free status of all derivatives of our free software and
|
256 |
+
of promoting the sharing and reuse of software generally.
|
257 |
+
|
258 |
+
NO WARRANTY
|
259 |
+
|
260 |
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
+
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
262 |
+
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
263 |
+
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
264 |
+
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
265 |
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
266 |
+
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
267 |
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
268 |
+
REPAIR OR CORRECTION.
|
269 |
+
|
270 |
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
271 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
272 |
+
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
273 |
+
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
274 |
+
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
275 |
+
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
276 |
+
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
277 |
+
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
+
POSSIBILITY OF SUCH DAMAGES.
|
279 |
+
|
280 |
+
END OF TERMS AND CONDITIONS
|
281 |
+
|
282 |
+
|
283 |
+
How to Apply These Terms to Your New Programs
|
284 |
+
|
285 |
+
If you develop a new program, and you want it to be of the greatest
|
286 |
+
possible use to the public, the best way to achieve this is to make it
|
287 |
+
free software which everyone can redistribute and change under these terms.
|
288 |
+
|
289 |
+
To do so, attach the following notices to the program. It is safest
|
290 |
+
to attach them to the start of each source file to most effectively
|
291 |
+
convey the exclusion of warranty; and each file should have at least
|
292 |
+
the "copyright" line and a pointer to where the full notice is found.
|
293 |
+
|
294 |
+
<one line to give the program's name and a brief idea of what it does.>
|
295 |
+
Copyright (C) 19yy <name of author>
|
296 |
+
|
297 |
+
This program is free software; you can redistribute it and/or modify
|
298 |
+
it under the terms of the GNU General Public License as published by
|
299 |
+
the Free Software Foundation; either version 2 of the License, or
|
300 |
+
(at your option) any later version.
|
301 |
+
|
302 |
+
This program is distributed in the hope that it will be useful,
|
303 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
304 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
305 |
+
GNU General Public License for more details.
|
306 |
+
|
307 |
+
You should have received a copy of the GNU General Public License
|
308 |
+
along with this program; if not, write to the Free Software
|
309 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
310 |
+
|
311 |
+
|
312 |
+
Also add information on how to contact you by electronic and paper mail.
|
313 |
+
|
314 |
+
If the program is interactive, make it output a short notice like this
|
315 |
+
when it starts in an interactive mode:
|
316 |
+
|
317 |
+
Gnomovision version 69, Copyright (C) 19yy name of author
|
318 |
+
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
319 |
+
This is free software, and you are welcome to redistribute it
|
320 |
+
under certain conditions; type `show c' for details.
|
321 |
+
|
322 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
323 |
+
parts of the General Public License. Of course, the commands you use may
|
324 |
+
be called something other than `show w' and `show c'; they could even be
|
325 |
+
mouse-clicks or menu items--whatever suits your program.
|
326 |
+
|
327 |
+
You should also get your employer (if you work as a programmer) or your
|
328 |
+
school, if any, to sign a "copyright disclaimer" for the program, if
|
329 |
+
necessary. Here is a sample; alter the names:
|
330 |
+
|
331 |
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
332 |
+
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
333 |
+
|
334 |
+
<signature of Ty Coon>, 1 April 1989
|
335 |
+
Ty Coon, President of Vice
|
336 |
+
|
337 |
+
This General Public License does not permit incorporating your program into
|
338 |
+
proprietary programs. If your program is a subroutine library, you may
|
339 |
+
consider it more useful to permit linking proprietary applications with the
|
340 |
+
library. If this is what you want to do, use the GNU Library General
|
341 |
+
Public License instead of this License.
|
includes/ip2c/README
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
IP2C 2.0.0 - Copyright (C) 2006 Omry Yadan (omry@yadan.net), all rights reserved
|
2 |
+
--------------------------------------------------------------------------------------------------
|
3 |
+
IP2C is an efficient library that resolves the country of an IP address based on a binary database.
|
4 |
+
Two database sources are supported:
|
5 |
+
Webhosting.info : http://ip-to-country.webhosting.info/
|
6 |
+
Software77 : http://software77.net/cgi-bin/ip-country/geo-ip.pl
|
7 |
+
|
8 |
+
Currently, IP2C is shipped with a database from Webhosting.info.
|
9 |
+
|
10 |
+
Home page:
|
11 |
+
http://firestats.cc/wiki/ip2c
|
12 |
+
|
13 |
+
== Supports ==
|
14 |
+
* Command line
|
15 |
+
* Java
|
16 |
+
* PHP
|
17 |
+
|
18 |
+
== Command line (requires java in path) ==
|
19 |
+
Usage :
|
20 |
+
To resolve an IP address:
|
21 |
+
java -jar ip2c.jar -r ip-address
|
22 |
+
Output format:
|
23 |
+
if not found:
|
24 |
+
UNKNOWN
|
25 |
+
|
26 |
+
if found:
|
27 |
+
2C 3C NAME
|
28 |
+
|
29 |
+
Example:
|
30 |
+
java -jar ip2c.jar 85.64.225.159
|
31 |
+
Outputs:
|
32 |
+
IL ISR ISRAEL
|
33 |
+
|
34 |
+
|
35 |
+
To build binary file from CSV:
|
36 |
+
java -jar ip2c -c csv_file [bin_file]
|
37 |
+
|
38 |
+
bin_file is optional, if not specified, file.csv will be converted to file.bin.
|
39 |
+
|
40 |
+
== Java code ==
|
41 |
+
String ip = 85.64.225.159;
|
42 |
+
int caching1 = IP2Country.NO_CACHE; // Straight on file, Fastest startup, slowest queries
|
43 |
+
int caching2 = IP2Country.MEMORY_MAPPED; // Memory mapped file, fast startup, fast quries.
|
44 |
+
int caching3 = IP2Country.MEMORY_CACHE; // load file into memory, slowerst startup, fastest queries
|
45 |
+
IP2Country ip2c = new IP2Country(caching1);
|
46 |
+
Country c = ip2c.getCountry(ip);
|
47 |
+
if (c == null)
|
48 |
+
{
|
49 |
+
System.out.println("UNKNOWN");
|
50 |
+
}
|
51 |
+
else
|
52 |
+
{
|
53 |
+
// will output IL ISR ISRAEL
|
54 |
+
System.out.println(c.get2cStr() + " " + c.get3cStr() + " " + c.getName());
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
== PHP ==
|
59 |
+
Install the ip2c.php and the binary file in the same directroy.
|
60 |
+
|
61 |
+
<?php
|
62 |
+
require_once('ip2c.php');
|
63 |
+
|
64 |
+
$ip2c = new ip2country();
|
65 |
+
$res = $ip2c->get_country("85.64.225.159");
|
66 |
+
if ($res == false)
|
67 |
+
echo "not found";
|
68 |
+
else
|
69 |
+
{
|
70 |
+
$o2c = $res['id2'];
|
71 |
+
$o3c = $res['id3'];
|
72 |
+
$oname = $res['name'];
|
73 |
+
echo "$o2c $o3c $oname"; // will output IL ISR ISRAEL
|
74 |
+
}
|
75 |
+
?>
|
76 |
+
|
77 |
+
|
78 |
+
== Acknowledgment ==
|
79 |
+
IP2C uses the IP-to-Country Database
|
80 |
+
provided by WebHosting.Info (http://www.webhosting.info),
|
81 |
+
available from http://ip-to-country.webhosting.info.
|
includes/ip2c/benchmark.php
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once('ip2c.php');
|
4 |
+
set_time_limit(0);
|
5 |
+
function is_cmd()
|
6 |
+
{
|
7 |
+
return (php_sapi_name() == "cli");
|
8 |
+
}
|
9 |
+
|
10 |
+
if (!is_cmd())
|
11 |
+
{
|
12 |
+
die("ip2c test should be executed from the command line (php -f)");
|
13 |
+
}
|
14 |
+
|
15 |
+
|
16 |
+
function println($msg = "")
|
17 |
+
{
|
18 |
+
if (is_cmd()) echo $msg . "\n";
|
19 |
+
else echo $msg . "<br/>";
|
20 |
+
}
|
21 |
+
|
22 |
+
$bin_name = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : "";
|
23 |
+
|
24 |
+
if (!$bin_name) $bin_name = "../ip-to-country.bin";
|
25 |
+
|
26 |
+
$ips = array();
|
27 |
+
$len = 100000;
|
28 |
+
println("Generating $len random IP addresses....");
|
29 |
+
flush();
|
30 |
+
for ($i = 0;$i<$len;$i++)
|
31 |
+
{
|
32 |
+
$ips[$i] = mt_rand(0,255) . "." . mt_rand(0,255) . "." . mt_rand(0,255) . "." . mt_rand(0,255);
|
33 |
+
}
|
34 |
+
|
35 |
+
println("Warm up done");
|
36 |
+
println("Resolving addresses:");
|
37 |
+
println();
|
38 |
+
println("Testing bin file : $bin_name");
|
39 |
+
println("----------- NO CACHING ---------------");
|
40 |
+
$ip2c = new ip2country($bin_name);
|
41 |
+
runBenchmark($ip2c, $ips, $len);
|
42 |
+
println("------------------------------------");
|
43 |
+
println();
|
44 |
+
println();
|
45 |
+
println("----------- CACHING ------------------");
|
46 |
+
$ip2c = new ip2country("$bin_name", true);
|
47 |
+
runBenchmark($ip2c, $ips, $len);
|
48 |
+
println("------------------------------------");
|
49 |
+
|
50 |
+
function runBenchmark($ip2c, $ips, $len) {
|
51 |
+
$now = microtime_float();
|
52 |
+
$progress = $len / 20;
|
53 |
+
|
54 |
+
for ($i = 0; $i < $len; $i++)
|
55 |
+
{
|
56 |
+
if ($i % $progress == 0 && $i != 0)
|
57 |
+
{
|
58 |
+
echo ".";
|
59 |
+
flush();
|
60 |
+
}
|
61 |
+
$ip2c->get_country($ips[$i]);
|
62 |
+
}
|
63 |
+
$t = microtime_float() - $now;
|
64 |
+
println();
|
65 |
+
println($t . " ms for $len searches (".($len / $t) ." searches/sec)");
|
66 |
+
}
|
67 |
+
|
68 |
+
function microtime_float()
|
69 |
+
{
|
70 |
+
list($usec, $sec) = explode(" ", microtime());
|
71 |
+
return ((float)$usec + (float)$sec);
|
72 |
+
}
|
73 |
+
?>
|
includes/ip2c/db.version
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
2013.02.18
|
includes/ip2c/ip-to-country.bin
ADDED
Binary file
|
includes/ip2c/ip2c.jar
ADDED
Binary file
|
includes/ip2c/ip2c.php
ADDED
@@ -0,0 +1,376 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
define('IP2C_MAX_INT',0x7fffffff);
|
3 |
+
class ip2country
|
4 |
+
{
|
5 |
+
var $m_active = false;
|
6 |
+
var $m_file;
|
7 |
+
var $m_firstTableOffset;
|
8 |
+
var $m_numRangesFirstTable;
|
9 |
+
var $m_secondTableOffset;
|
10 |
+
var $m_numRangesSecondTable;
|
11 |
+
var $m_countriesOffset;
|
12 |
+
var $m_numCountries;
|
13 |
+
var $bin_file = './ip-to-country.bin';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* ip2country(String $file) will NOT USE caching and specifies the country database $file
|
17 |
+
* ip2country(String $file, true) will USE caching with default file location
|
18 |
+
* ip2country(Boolean true) will USE caching with default file location
|
19 |
+
*/
|
20 |
+
function ip2country($bin_file = './ip-to-country.bin', $caching = false)
|
21 |
+
{
|
22 |
+
if (is_bool($bin_file)) {
|
23 |
+
// use $bin_file as caching indicator
|
24 |
+
$caching = $bin_file;
|
25 |
+
// default the bin file to the class variable
|
26 |
+
$bin_file = $this->bin_file;
|
27 |
+
}
|
28 |
+
|
29 |
+
$this->caching = $caching;
|
30 |
+
|
31 |
+
$this->m_file = fopen($bin_file, "rb");
|
32 |
+
if (!$this->m_file)
|
33 |
+
{
|
34 |
+
trigger_error('Error loading '.$bin_file);
|
35 |
+
if (defined('UNIT_TEST')) exit(1);
|
36 |
+
return;
|
37 |
+
}
|
38 |
+
|
39 |
+
if ($this->caching) {
|
40 |
+
$this->initCache($bin_file);
|
41 |
+
}
|
42 |
+
|
43 |
+
$f = $this->m_file;
|
44 |
+
if ($this->caching) {
|
45 |
+
$sig = $this->mem[$this->offset++]
|
46 |
+
.$this->mem[$this->offset++]
|
47 |
+
.$this->mem[$this->offset++]
|
48 |
+
.$this->mem[$this->offset++];
|
49 |
+
}
|
50 |
+
else {
|
51 |
+
$sig = fread($f, 4);
|
52 |
+
}
|
53 |
+
|
54 |
+
if ($sig != 'ip2c')
|
55 |
+
{
|
56 |
+
trigger_error("file $bin_file has incorrect signature");
|
57 |
+
if (defined('UNIT_TEST')) exit(1);
|
58 |
+
return;
|
59 |
+
}
|
60 |
+
$v = $this->readInt();
|
61 |
+
if ($v != 2)
|
62 |
+
{
|
63 |
+
trigger_error("file $bin_file has incorrect format version ($v)");
|
64 |
+
if (defined('UNIT_TEST')) exit(1);
|
65 |
+
return;
|
66 |
+
}
|
67 |
+
|
68 |
+
$this->m_firstTableOffset = $this->readInt();
|
69 |
+
$this->m_numRangesFirstTable = $this->readInt();
|
70 |
+
$this->m_secondTableOffset = $this->readInt();
|
71 |
+
$this->m_numRangesSecondTable = $this->readInt();
|
72 |
+
$this->m_countriesOffset = $this->readInt();
|
73 |
+
$this->m_numCountries = $this->readInt();
|
74 |
+
$this->m_active = true;
|
75 |
+
}
|
76 |
+
|
77 |
+
function initCache($fileName) {
|
78 |
+
$this->offset = 0;
|
79 |
+
$fp = fopen($fileName, "rb");
|
80 |
+
$this->mem = fread($fp, filesize($fileName));
|
81 |
+
if ($this->mem === FALSE)
|
82 |
+
$this->caching = FALSE;
|
83 |
+
fclose($fp);
|
84 |
+
}
|
85 |
+
|
86 |
+
function get_country($ip)
|
87 |
+
{
|
88 |
+
if (!$this->m_active) return false;
|
89 |
+
|
90 |
+
$int_ip = ip2long($ip);
|
91 |
+
|
92 |
+
// happens on 64bit systems
|
93 |
+
if ($int_ip > IP2C_MAX_INT)
|
94 |
+
{
|
95 |
+
// shift to signed int32 value
|
96 |
+
$int_ip -= IP2C_MAX_INT;
|
97 |
+
$int_ip -= IP2C_MAX_INT;
|
98 |
+
$int_ip -= 2;
|
99 |
+
}
|
100 |
+
|
101 |
+
if ($int_ip >= 0)
|
102 |
+
{
|
103 |
+
$key = $this->find_country_code($int_ip, 0, $this->m_numRangesFirstTable, true);
|
104 |
+
}
|
105 |
+
else
|
106 |
+
{
|
107 |
+
$nip = (int)($int_ip + IP2C_MAX_INT + 2); // the + 2 is a bit wierd, but required.
|
108 |
+
$key = $this->find_country_code($nip, 0, $this->m_numRangesSecondTable, false);
|
109 |
+
}
|
110 |
+
if ($key == false || $key == 0)
|
111 |
+
{
|
112 |
+
return false;
|
113 |
+
}
|
114 |
+
else
|
115 |
+
{
|
116 |
+
return $this->find_country_key($key,0, $this->m_numCountries);
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
function find_country_code($ip, $startIndex, $endIndex, $firstTable, $d = 0)
|
121 |
+
{
|
122 |
+
while(1) {
|
123 |
+
$middle = (int)(($startIndex + $endIndex) / 2);
|
124 |
+
$mp = $this->getPair($middle, $firstTable);
|
125 |
+
$mip = $mp['ip'];
|
126 |
+
//echo "#$d find_country_code : [code=$ip, start=$startIndex, middle=$middle, end=$endIndex, mip=$mip]<br/>";
|
127 |
+
|
128 |
+
if ($ip < $mip)
|
129 |
+
{
|
130 |
+
if ($startIndex + 1 == $endIndex) return false; // not found
|
131 |
+
$endIndex = $middle;
|
132 |
+
continue;
|
133 |
+
//return $this->find_country_code($ip, $startIndex, $middle, $firstTable, ++$d);
|
134 |
+
}
|
135 |
+
else
|
136 |
+
if ($ip > $mip)
|
137 |
+
{
|
138 |
+
$np = $this->getPair($middle+1, $firstTable);
|
139 |
+
if ($ip < $np['ip'])
|
140 |
+
{
|
141 |
+
return $mp['key'];
|
142 |
+
}
|
143 |
+
else
|
144 |
+
{
|
145 |
+
if ($startIndex + 1 == $endIndex) return false; // not found
|
146 |
+
$startIndex = $middle;
|
147 |
+
continue;
|
148 |
+
//return $this->find_country_code($ip, $middle, $endIndex, $firstTable, ++$d);
|
149 |
+
}
|
150 |
+
}
|
151 |
+
else // ip == mip
|
152 |
+
{
|
153 |
+
return $mp['key'];
|
154 |
+
}
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
function find_country($code)
|
159 |
+
{
|
160 |
+
if (!$this->m_active) return false;
|
161 |
+
$c = strtoupper($code);
|
162 |
+
$c1 = $c[0];
|
163 |
+
$c2 = $c[1];
|
164 |
+
$key = ord($c1) * 256 + ord($c2);
|
165 |
+
return $this->find_country_key($key, 0, $this->m_numCountries);
|
166 |
+
}
|
167 |
+
|
168 |
+
|
169 |
+
function find_country_key($code, $startIndex, $endIndex)
|
170 |
+
{
|
171 |
+
$d = 0;
|
172 |
+
while(1) {
|
173 |
+
if ($d > 20)
|
174 |
+
{
|
175 |
+
trigger_error("IP2Country : Internal error - endless loop detected, code = $code");
|
176 |
+
return false;
|
177 |
+
}
|
178 |
+
|
179 |
+
$d++;
|
180 |
+
$middle = (int)(($startIndex + $endIndex) / 2);
|
181 |
+
$mc = $this->get_country_code($middle);
|
182 |
+
//echo "#$d find_country : [$startIndex, $endIndex, mc=$mc, code=$code]<br/>";
|
183 |
+
|
184 |
+
if ($mc == $code)
|
185 |
+
{
|
186 |
+
// found.
|
187 |
+
return $this->load_country($middle);
|
188 |
+
}
|
189 |
+
else
|
190 |
+
if ($code > $mc)
|
191 |
+
{
|
192 |
+
if ($middle + 1 == $endIndex)
|
193 |
+
{
|
194 |
+
$nc = $this->get_country_code($middle);
|
195 |
+
if ($nc == $code) return $this->load_country($middle);
|
196 |
+
else return false;
|
197 |
+
}
|
198 |
+
$startIndex = $middle;
|
199 |
+
continue;
|
200 |
+
//return $this->find_country_key($code, $middle, $endIndex, ++$d);
|
201 |
+
}
|
202 |
+
else // $code < $mc
|
203 |
+
{
|
204 |
+
if ($startIndex + 1 == $middle)
|
205 |
+
{
|
206 |
+
$nc = $this->get_country_code($startIndex);
|
207 |
+
if ($nc == $code) return $this->load_country($startIndex);
|
208 |
+
else return false;
|
209 |
+
}
|
210 |
+
$endIndex = $middle;
|
211 |
+
continue;
|
212 |
+
//return $this->find_country_key($code, $startIndex, $middle, ++$d);
|
213 |
+
}
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
|
218 |
+
function load_country($index)
|
219 |
+
{
|
220 |
+
$offset = $this->m_countriesOffset + $index * 10;
|
221 |
+
|
222 |
+
if ($this->caching)
|
223 |
+
{
|
224 |
+
$this->offset = $offset;
|
225 |
+
}
|
226 |
+
else
|
227 |
+
fseek($this->m_file, $offset);
|
228 |
+
|
229 |
+
$id2c = $this->readCountryKey();
|
230 |
+
$id3c = $this->read3cCode();
|
231 |
+
$nameOffset = $this->readInt();
|
232 |
+
|
233 |
+
if ($this->caching)
|
234 |
+
{
|
235 |
+
$this->offset = $nameOffset;
|
236 |
+
}
|
237 |
+
else
|
238 |
+
fseek($this->m_file, $nameOffset);
|
239 |
+
|
240 |
+
$len = $this->readShort();
|
241 |
+
$name = '';
|
242 |
+
if ($len != 0)
|
243 |
+
{
|
244 |
+
if ($this->caching)
|
245 |
+
{
|
246 |
+
for($i = 0;$i<$len;$i++)
|
247 |
+
{
|
248 |
+
$name.=$this->mem[$this->offset++];
|
249 |
+
}
|
250 |
+
}
|
251 |
+
else
|
252 |
+
$name = fread($this->m_file, $len);
|
253 |
+
}
|
254 |
+
return array("id2"=>$id2c,"id3"=>$id3c,"name"=>$name);
|
255 |
+
}
|
256 |
+
|
257 |
+
function get_country_code($index)
|
258 |
+
{
|
259 |
+
$offset = $this->m_countriesOffset + $index * 10;
|
260 |
+
|
261 |
+
if ($this->caching)
|
262 |
+
{
|
263 |
+
$this->offset = $offset;
|
264 |
+
$a = unpack('n', $this->mem[$this->offset++]
|
265 |
+
.$this->mem[$this->offset++]);
|
266 |
+
}
|
267 |
+
else {
|
268 |
+
fseek($this->m_file, $offset);
|
269 |
+
$a = unpack('n', fread($this->m_file, 2));
|
270 |
+
}
|
271 |
+
|
272 |
+
return $a[1];
|
273 |
+
}
|
274 |
+
|
275 |
+
|
276 |
+
|
277 |
+
function getPair($index, $firstTable)
|
278 |
+
{
|
279 |
+
$offset = 0;
|
280 |
+
if ($firstTable)
|
281 |
+
{
|
282 |
+
if ($index > $this->m_numRangesFirstTable)
|
283 |
+
{
|
284 |
+
return array('key'=>false,'ip'=>0);
|
285 |
+
}
|
286 |
+
$offset = $this->m_firstTableOffset + $index * 6;
|
287 |
+
}
|
288 |
+
else
|
289 |
+
{
|
290 |
+
if ($index > $this->m_numRangesSecondTable)
|
291 |
+
{
|
292 |
+
return array('key'=>false,'ip'=>0);
|
293 |
+
}
|
294 |
+
$offset = $this->m_secondTableOffset + $index * 6;
|
295 |
+
|
296 |
+
}
|
297 |
+
|
298 |
+
if ($this->caching)
|
299 |
+
{
|
300 |
+
$this->offset = $offset;
|
301 |
+
$p = unpack('Nip/nkey', $this->mem[$this->offset++]
|
302 |
+
.$this->mem[$this->offset++]
|
303 |
+
.$this->mem[$this->offset++]
|
304 |
+
.$this->mem[$this->offset++]
|
305 |
+
.$this->mem[$this->offset++]
|
306 |
+
.$this->mem[$this->offset++]);
|
307 |
+
}
|
308 |
+
else
|
309 |
+
{
|
310 |
+
fseek($this->m_file, $offset);
|
311 |
+
$p =unpack('Nip/nkey', fread($this->m_file, 6));
|
312 |
+
}
|
313 |
+
|
314 |
+
return $p;
|
315 |
+
|
316 |
+
}
|
317 |
+
|
318 |
+
function readShort()
|
319 |
+
{
|
320 |
+
if ($this->caching)
|
321 |
+
{
|
322 |
+
$a = unpack('n', $this->mem[$this->offset++]
|
323 |
+
.$this->mem[$this->offset++]);
|
324 |
+
}
|
325 |
+
else
|
326 |
+
$a = unpack('n', fread($this->m_file, 2));
|
327 |
+
|
328 |
+
return $a[1];
|
329 |
+
}
|
330 |
+
|
331 |
+
function read3cCode()
|
332 |
+
{
|
333 |
+
if ($this->caching)
|
334 |
+
{
|
335 |
+
$this->offset++;
|
336 |
+
$d = $this->mem[$this->offset++]
|
337 |
+
.$this->mem[$this->offset++]
|
338 |
+
.$this->mem[$this->offset++];
|
339 |
+
}
|
340 |
+
else
|
341 |
+
{
|
342 |
+
fread($this->m_file, 1);
|
343 |
+
$d = fread($this->m_file, 3);
|
344 |
+
}
|
345 |
+
|
346 |
+
return $d != ' ' ? $d : '';
|
347 |
+
}
|
348 |
+
|
349 |
+
function readCountryKey()
|
350 |
+
{
|
351 |
+
if ($this->caching)
|
352 |
+
{
|
353 |
+
return $this->mem[$this->offset++].$this->mem[$this->offset++];
|
354 |
+
}
|
355 |
+
else
|
356 |
+
{
|
357 |
+
return fread($this->m_file, 2);
|
358 |
+
}
|
359 |
+
}
|
360 |
+
|
361 |
+
function readInt()
|
362 |
+
{
|
363 |
+
if ($this->caching)
|
364 |
+
{
|
365 |
+
$a = unpack('N', $this->mem[$this->offset++]
|
366 |
+
.$this->mem[$this->offset++]
|
367 |
+
.$this->mem[$this->offset++]
|
368 |
+
.$this->mem[$this->offset++]);
|
369 |
+
}
|
370 |
+
else
|
371 |
+
$a =unpack('N', fread($this->m_file, 4));
|
372 |
+
|
373 |
+
return $a[1];
|
374 |
+
}
|
375 |
+
}
|
376 |
+
?>
|
includes/ip2c/ip2c_test.php
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
require_once('ip2c.php');
|
3 |
+
define ('UNIT_TEST',true);
|
4 |
+
set_time_limit(0);
|
5 |
+
|
6 |
+
function is_cmd()
|
7 |
+
{
|
8 |
+
return (php_sapi_name() == "cli");
|
9 |
+
}
|
10 |
+
|
11 |
+
if (!is_cmd())
|
12 |
+
{
|
13 |
+
die("ip2c test should be executed from the command line (php -f)");
|
14 |
+
}
|
15 |
+
|
16 |
+
function println($msg = "")
|
17 |
+
{
|
18 |
+
if (is_cmd()) echo $msg . "\n";
|
19 |
+
else echo $msg . "<br/>";
|
20 |
+
}
|
21 |
+
|
22 |
+
$csv_name = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : "";
|
23 |
+
if (!$csv_name) $csv_name = "../ip-to-country.csv";
|
24 |
+
$bin_name = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : "";
|
25 |
+
if (!$bin_name) $bin_name = "../ip-to-country.bin";
|
26 |
+
println();
|
27 |
+
println("Unit testing csv $csv_name against bin $bin_name");
|
28 |
+
println();
|
29 |
+
println();
|
30 |
+
|
31 |
+
println("----------- NO CACHING ------------------");
|
32 |
+
$ip2c = new ip2country($bin_name);
|
33 |
+
run_test($ip2c,$csv_name);
|
34 |
+
// this one caused problems before
|
35 |
+
$ip2c->get_country('10.0.0.1');
|
36 |
+
$ip2c->get_country('192.116.192.9');
|
37 |
+
println("------------------------------------");
|
38 |
+
println();
|
39 |
+
println();
|
40 |
+
|
41 |
+
println("----------- CACHING ------------------");
|
42 |
+
$ip2c = new ip2country($bin_name, true);
|
43 |
+
run_test($ip2c,$csv_name);
|
44 |
+
// this one caused problems before
|
45 |
+
$ip2c->get_country('10.0.0.1');
|
46 |
+
$ip2c->get_country('192.116.192.9');
|
47 |
+
println("------------------------------------");
|
48 |
+
|
49 |
+
function run_test($ip2c, $csvFile)
|
50 |
+
{
|
51 |
+
global $num;
|
52 |
+
global $total;
|
53 |
+
$num = 0;$total = 0;
|
54 |
+
|
55 |
+
$csv = fopen(dirname(__FILE__)."/$csvFile", "r");
|
56 |
+
if (!$csv)
|
57 |
+
{
|
58 |
+
ip2c_die("Error opening $csvfile");
|
59 |
+
}
|
60 |
+
|
61 |
+
$row = 0;
|
62 |
+
$count = 0;
|
63 |
+
|
64 |
+
while (($expected = fgetcsv($csv, 1000, ",")) !== FALSE)
|
65 |
+
{
|
66 |
+
if (isset($expected[0][0]) && $expected[0][0] == '#') continue; // skip comments
|
67 |
+
$row++;
|
68 |
+
if ($row % 10 != 0) continue; // only test every 10th row.
|
69 |
+
$count++;
|
70 |
+
$start = $expected[0];
|
71 |
+
$end = $expected[1];
|
72 |
+
|
73 |
+
test($ip2c, $expected, $start);
|
74 |
+
if ($end - $start > 1)
|
75 |
+
test($ip2c, $expected, $start+1);
|
76 |
+
if ($end < IP2C_MAX_INT * 2)
|
77 |
+
test($ip2c, $expected, $end);
|
78 |
+
if ($end - $start > 1 && ($end-1) < IP2C_MAX_INT * 2)
|
79 |
+
test($ip2c, $expected, $end-1);
|
80 |
+
test($ip2c, $expected, ($start+$end)/2);
|
81 |
+
if ($count % 1000 == 0) println("Tested $count ranges");
|
82 |
+
flush();
|
83 |
+
}
|
84 |
+
$t2 = $total * 1000;
|
85 |
+
println("Test passed");
|
86 |
+
|
87 |
+
fclose($csv);
|
88 |
+
}
|
89 |
+
|
90 |
+
|
91 |
+
function test($ip2c, $expected, $ip)
|
92 |
+
{
|
93 |
+
$ips = long2ip($ip);
|
94 |
+
$country = $ip2c->get_country($ips);
|
95 |
+
|
96 |
+
if ($expected == false && $country == false) return;
|
97 |
+
if ($expected == false && $country != false) ip2c_die("Expected " . var_export($expected, true) . ", got " . var_export($country, true) . " ||| $ip $ips");
|
98 |
+
if ($expected != false && $country == false) ip2c_die("IP ($ip $ips) Not found, Expected :\n" . var_export($expected, true));
|
99 |
+
if (count($expected) == 5) // webhosting
|
100 |
+
{
|
101 |
+
$id2c = $expected[2];
|
102 |
+
$id3c = $expected[3];
|
103 |
+
$name = $expected[4];
|
104 |
+
}
|
105 |
+
else
|
106 |
+
if (count($expected) == 7) // software77
|
107 |
+
{
|
108 |
+
$id2c = $expected[4];
|
109 |
+
$id3c = $expected[5];
|
110 |
+
$name = $expected[6];
|
111 |
+
}
|
112 |
+
|
113 |
+
$o2c = $country['id2'];
|
114 |
+
$o3c = trim($country['id3']); // there is at least one case of a 3c code which has only 2 chars: EU. to avoid stupid errors from the unit test, trim.
|
115 |
+
$oname = $country['name'];
|
116 |
+
|
117 |
+
if (strcmp($id2c,$o2c) != 0 ||
|
118 |
+
strcmp($id3c,$o3c) != 0 ||
|
119 |
+
strcmp($name,$oname) != 0)
|
120 |
+
{
|
121 |
+
println("in 3c ".strlen($id3c));
|
122 |
+
println("out 3c ".strlen($o3c));
|
123 |
+
ip2c_die("Expected :\n2c = '$id2c', 3c = '$id3c' , name = '$name'\ngot:\n2c = '$o2c', 3c = '$o3c' , name = '$oname'\nIP address: $ip\n");
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
function ip2c_die($msg)
|
128 |
+
{
|
129 |
+
println($msg);
|
130 |
+
exit(1);
|
131 |
+
}
|
132 |
+
?>
|
includes/ip2c/test-ip.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
error_reporting(E_ALL | (defined('E_STRICT')? E_STRICT : 0));
|
3 |
+
require_once('ip2c.php');
|
4 |
+
|
5 |
+
$ip = htmlentities(isset($_GET['ip']) ? $_GET['ip'] : $_SERVER['REMOTE_ADDR']);
|
6 |
+
$ip2c = new ip2country("../ip-to-country.bin");
|
7 |
+
var_dump($ip2c->find_country_impl(16981,0, $ip2c->m_numCountries));
|
8 |
+
return;
|
9 |
+
$res = $ip2c->get_country($ip);
|
10 |
+
if ($res == false)
|
11 |
+
echo "$ip => not found";
|
12 |
+
else
|
13 |
+
{
|
14 |
+
$o2c = $res['id2'];
|
15 |
+
$o3c = $res['id3'];
|
16 |
+
$oname = $res['name'];
|
17 |
+
echo "$ip => $o2c $o3c $oname";
|
18 |
+
}
|
19 |
+
|
20 |
+
?>
|
languages/user-login-log-ja.mo
ADDED
Binary file
|
languages/user-login-log-ja.po
ADDED
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: user-login-log\n"
|
4 |
+
"Report-Msgid-Bugs-To: \n"
|
5 |
+
"POT-Creation-Date: 2013-05-10 10:07+0900\n"
|
6 |
+
"PO-Revision-Date: 2013-05-10 12:25+0900\n"
|
7 |
+
"Last-Translator: wokamoto <wokamoto1973@gmail.com>\n"
|
8 |
+
"Language-Team: JAPANESE <http://wppluginsj.sourceforge.jp/>\n"
|
9 |
+
"Language: ja_JP\n"
|
10 |
+
"MIME-Version: 1.0\n"
|
11 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
12 |
+
"Content-Transfer-Encoding: 8bit\n"
|
13 |
+
"X-Poedit-SourceCharset: utf-8\n"
|
14 |
+
"X-Poedit-KeywordsList: __;_e\n"
|
15 |
+
"X-Poedit-Basepath: .\n"
|
16 |
+
"X-Poedit-SearchPath-0: ..\n"
|
17 |
+
|
18 |
+
msgid "Crazy Bone"
|
19 |
+
msgstr "Crazy Bone (狂骨)"
|
20 |
+
|
21 |
+
msgid "Tracks user name, time of login, IP address and browser user agent."
|
22 |
+
msgstr ""
|
23 |
+
"このプラグインは、ログイン・ログアウト時のユーザー名、日時、IPアドレス、ユー"
|
24 |
+
"ザーエージェントを記録します。"
|
25 |
+
|
26 |
+
#: ../plugin.php:148
|
27 |
+
#, php-format
|
28 |
+
msgid "Last login: %s%s%s"
|
29 |
+
msgstr "最終ログイン: %s%s%s"
|
30 |
+
|
31 |
+
#: ../plugin.php:273 ../plugin.php:490
|
32 |
+
msgid "Login Log"
|
33 |
+
msgstr "ログイン履歴"
|
34 |
+
|
35 |
+
#: ../plugin.php:308 ../plugin.php:429
|
36 |
+
msgid "UNKNOWN"
|
37 |
+
msgstr "不明"
|
38 |
+
|
39 |
+
#: ../plugin.php:313
|
40 |
+
msgid "Unknown"
|
41 |
+
msgstr "不明"
|
42 |
+
|
43 |
+
#: ../plugin.php:358
|
44 |
+
#, php-format
|
45 |
+
msgid "%d years"
|
46 |
+
msgstr "%d年"
|
47 |
+
|
48 |
+
#: ../plugin.php:361
|
49 |
+
msgid "one year"
|
50 |
+
msgstr "1年"
|
51 |
+
|
52 |
+
#: ../plugin.php:367
|
53 |
+
#, php-format
|
54 |
+
msgid "%d months"
|
55 |
+
msgstr "%dヶ月"
|
56 |
+
|
57 |
+
#: ../plugin.php:370
|
58 |
+
msgid "one month"
|
59 |
+
msgstr "1ヶ月"
|
60 |
+
|
61 |
+
#: ../plugin.php:376
|
62 |
+
#, php-format
|
63 |
+
msgid "%d days"
|
64 |
+
msgstr "%d日"
|
65 |
+
|
66 |
+
#: ../plugin.php:379
|
67 |
+
msgid "one day"
|
68 |
+
msgstr "1日"
|
69 |
+
|
70 |
+
#: ../plugin.php:385
|
71 |
+
#, php-format
|
72 |
+
msgid "%d hours"
|
73 |
+
msgstr "%d時間"
|
74 |
+
|
75 |
+
#: ../plugin.php:388
|
76 |
+
msgid "one hour"
|
77 |
+
msgstr "1時間"
|
78 |
+
|
79 |
+
#: ../plugin.php:394
|
80 |
+
#, php-format
|
81 |
+
msgid "%d minutes"
|
82 |
+
msgstr "%d分"
|
83 |
+
|
84 |
+
#: ../plugin.php:396
|
85 |
+
msgid "one minute"
|
86 |
+
msgstr "1分"
|
87 |
+
|
88 |
+
#: ../plugin.php:399
|
89 |
+
msgid "Just now!"
|
90 |
+
msgstr "たった今"
|
91 |
+
|
92 |
+
#: ../plugin.php:399
|
93 |
+
#, php-format
|
94 |
+
msgid "%s ago."
|
95 |
+
msgstr "%s前"
|
96 |
+
|
97 |
+
#: ../plugin.php:404
|
98 |
+
#, php-format
|
99 |
+
msgid "<img src=\"%1$s\" alt=\"%2$s\" title=\"%3$s\" style=\"%4$s\" %5$s/>"
|
100 |
+
msgstr "<img src=\"%1$s\" alt=\"%2$s\" title=\"%3$s\" style=\"%4$s\" %5$s/>"
|
101 |
+
|
102 |
+
#: ../plugin.php:468
|
103 |
+
msgid "«"
|
104 |
+
msgstr "«"
|
105 |
+
|
106 |
+
#: ../plugin.php:469
|
107 |
+
msgid "»"
|
108 |
+
msgstr "»"
|
109 |
+
|
110 |
+
#: ../plugin.php:505 ../plugin.php:517
|
111 |
+
msgid "User Name"
|
112 |
+
msgstr "ユーザー名"
|
113 |
+
|
114 |
+
#: ../plugin.php:507 ../plugin.php:519
|
115 |
+
msgid "Date"
|
116 |
+
msgstr "日時"
|
117 |
+
|
118 |
+
#: ../plugin.php:508 ../plugin.php:520
|
119 |
+
msgid "Status"
|
120 |
+
msgstr "ステータス"
|
121 |
+
|
122 |
+
#: ../plugin.php:509 ../plugin.php:521
|
123 |
+
msgid "IP"
|
124 |
+
msgstr "IP アドレス"
|
125 |
+
|
126 |
+
#: ../plugin.php:510 ../plugin.php:522
|
127 |
+
msgid "User Agent"
|
128 |
+
msgstr "ユーザーエージェント"
|
129 |
+
|
130 |
+
#: ../plugin.php:511 ../plugin.php:523
|
131 |
+
msgid "Errors"
|
132 |
+
msgstr "エラー"
|
133 |
+
|
134 |
+
msgid "All Users"
|
135 |
+
msgstr "全て"
|
languages/user-login-log.pot
ADDED
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: user-login-log\n"
|
4 |
+
"Report-Msgid-Bugs-To: \n"
|
5 |
+
"POT-Creation-Date: 2013-05-09 17:31+0900\n"
|
6 |
+
"Language: ja_JP\n"
|
7 |
+
"MIME-Version: 1.0\n"
|
8 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
9 |
+
"Content-Transfer-Encoding: 8bit\n"
|
10 |
+
|
11 |
+
msgid "Crazy Bone"
|
12 |
+
msgstr ""
|
13 |
+
|
14 |
+
msgid "Tracks user name, time of login, IP address and browser user agent."
|
15 |
+
msgstr ""
|
16 |
+
|
17 |
+
#: ../plugin.php:148
|
18 |
+
#, php-format
|
19 |
+
msgid "Last login: %s%s%s"
|
20 |
+
msgstr ""
|
21 |
+
|
22 |
+
#: ../plugin.php:273 ../plugin.php:490
|
23 |
+
msgid "Login Log"
|
24 |
+
msgstr ""
|
25 |
+
|
26 |
+
#: ../plugin.php:308 ../plugin.php:429
|
27 |
+
msgid "UNKNOWN"
|
28 |
+
msgstr ""
|
29 |
+
|
30 |
+
#: ../plugin.php:313
|
31 |
+
msgid "Unknown"
|
32 |
+
msgstr ""
|
33 |
+
|
34 |
+
#: ../plugin.php:358
|
35 |
+
#, php-format
|
36 |
+
msgid "%d years"
|
37 |
+
msgstr ""
|
38 |
+
|
39 |
+
#: ../plugin.php:361
|
40 |
+
msgid "one year"
|
41 |
+
msgstr ""
|
42 |
+
|
43 |
+
#: ../plugin.php:367
|
44 |
+
#, php-format
|
45 |
+
msgid "%d months"
|
46 |
+
msgstr ""
|
47 |
+
|
48 |
+
#: ../plugin.php:370
|
49 |
+
msgid "one month"
|
50 |
+
msgstr ""
|
51 |
+
|
52 |
+
#: ../plugin.php:376
|
53 |
+
#, php-format
|
54 |
+
msgid "%d days"
|
55 |
+
msgstr ""
|
56 |
+
|
57 |
+
#: ../plugin.php:379
|
58 |
+
msgid "one day"
|
59 |
+
msgstr ""
|
60 |
+
|
61 |
+
#: ../plugin.php:385
|
62 |
+
#, php-format
|
63 |
+
msgid "%d hours"
|
64 |
+
msgstr ""
|
65 |
+
|
66 |
+
#: ../plugin.php:388
|
67 |
+
msgid "one hour"
|
68 |
+
msgstr ""
|
69 |
+
|
70 |
+
#: ../plugin.php:394
|
71 |
+
#, php-format
|
72 |
+
msgid "%d minutes"
|
73 |
+
msgstr ""
|
74 |
+
|
75 |
+
#: ../plugin.php:396
|
76 |
+
msgid "one minute"
|
77 |
+
msgstr ""
|
78 |
+
|
79 |
+
#: ../plugin.php:399
|
80 |
+
msgid "Just now!"
|
81 |
+
msgstr ""
|
82 |
+
|
83 |
+
#: ../plugin.php:399
|
84 |
+
#, php-format
|
85 |
+
msgid "%s ago."
|
86 |
+
msgstr ""
|
87 |
+
|
88 |
+
#: ../plugin.php:404
|
89 |
+
#, php-format
|
90 |
+
msgid "<img src=\"%1$s\" alt=\"%2$s\" title=\"%3$s\" style=\"%4$s\" %5$s/>"
|
91 |
+
msgstr ""
|
92 |
+
|
93 |
+
#: ../plugin.php:468
|
94 |
+
msgid "«"
|
95 |
+
msgstr ""
|
96 |
+
|
97 |
+
#: ../plugin.php:469
|
98 |
+
msgid "»"
|
99 |
+
msgstr ""
|
100 |
+
|
101 |
+
#: ../plugin.php:505 ../plugin.php:517
|
102 |
+
msgid "User Name"
|
103 |
+
msgstr ""
|
104 |
+
|
105 |
+
#: ../plugin.php:507 ../plugin.php:519
|
106 |
+
msgid "Date"
|
107 |
+
msgstr ""
|
108 |
+
|
109 |
+
#: ../plugin.php:508 ../plugin.php:520
|
110 |
+
msgid "Status"
|
111 |
+
msgstr ""
|
112 |
+
|
113 |
+
#: ../plugin.php:509 ../plugin.php:521
|
114 |
+
msgid "IP"
|
115 |
+
msgstr ""
|
116 |
+
|
117 |
+
#: ../plugin.php:510 ../plugin.php:522
|
118 |
+
msgid "User Agent"
|
119 |
+
msgstr ""
|
120 |
+
|
121 |
+
#: ../plugin.php:511 ../plugin.php:523
|
122 |
+
msgid "Errors"
|
123 |
+
msgstr ""
|
124 |
+
|
125 |
+
msgid "All Users"
|
126 |
+
msgstr ""
|
plugin.php
ADDED
@@ -0,0 +1,598 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Crazy Bone
|
4 |
+
Plugin URI:
|
5 |
+
Description: Tracks user name, time of login, IP address and browser user agent.
|
6 |
+
Author: wokamoto
|
7 |
+
Version: 0.1.1
|
8 |
+
Author URI: http://dogmap.jp/
|
9 |
+
Text Domain: user-login-log
|
10 |
+
Domain Path: /languages/
|
11 |
+
|
12 |
+
License:
|
13 |
+
Released under the GPL license
|
14 |
+
http://www.gnu.org/copyleft/gpl.html
|
15 |
+
|
16 |
+
Copyright 2012 (email : wokamoto1973@gmail.com)
|
17 |
+
|
18 |
+
This program is free software; you can redistribute it and/or modify
|
19 |
+
it under the terms of the GNU General Public License as published by
|
20 |
+
the Free Software Foundation; either version 2 of the License, or
|
21 |
+
(at your option) any later version.
|
22 |
+
|
23 |
+
This program is distributed in the hope that it will be useful,
|
24 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
25 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
26 |
+
GNU General Public License for more details.
|
27 |
+
|
28 |
+
You should have received a copy of the GNU General Public License
|
29 |
+
along with this program; if not, write to the Free Software
|
30 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
31 |
+
*/
|
32 |
+
if (!class_exists('DetectBrowsersController'))
|
33 |
+
require_once( dirname(__FILE__) . '/includes/detect_browsers.php' );
|
34 |
+
if (!class_exists('DetectCountriesController'))
|
35 |
+
require_once( dirname(__FILE__) . '/includes/detect_countries.php' );
|
36 |
+
|
37 |
+
load_plugin_textdomain(user_login_log::TEXT_DOMAIN, false, dirname(plugin_basename(__FILE__)) . '/languages/');
|
38 |
+
|
39 |
+
class user_login_log {
|
40 |
+
const USER_META_KEY = 'user_login_log';
|
41 |
+
const DEBUG_MODE = true;
|
42 |
+
const TEXT_DOMAIN = 'user-login-log';
|
43 |
+
const LIST_PER_PAGE = 20;
|
44 |
+
|
45 |
+
const SEC_MINUITE = 60;
|
46 |
+
const SEC_HOUR = 3600;
|
47 |
+
const SEC_DAY = 86400;
|
48 |
+
const SEC_MONTH = 2592000;
|
49 |
+
const SEC_YEAR = 31536000;
|
50 |
+
|
51 |
+
private $ull_table = 'user_login_log';
|
52 |
+
private $admin_action;
|
53 |
+
|
54 |
+
function __construct(){
|
55 |
+
global $wpdb;
|
56 |
+
|
57 |
+
$this->ull_table = $wpdb->prefix.$this->ull_table;
|
58 |
+
|
59 |
+
add_action('wp_login', array(&$this, 'user_login_log'), 10, 2);
|
60 |
+
add_action('wp_authenticate', array(&$this, 'wp_authenticate_log'), 10, 2);
|
61 |
+
add_action('login_form_logout', array(&$this, 'user_logout_log'));
|
62 |
+
|
63 |
+
add_action('admin_bar_init', array(&$this, 'admin_bar_init'), 9999);
|
64 |
+
add_action('wp_enqueue_scripts', array(&$this, 'enqueue_scripts'));
|
65 |
+
add_action('admin_menu', array(&$this,'add_admin_menu'));
|
66 |
+
|
67 |
+
add_action('wp_ajax_ull_info', array(&$this, 'ajax_info'));
|
68 |
+
add_action('wp_ajax_nopriv_ull_info', array(&$this, 'ajax_info'));
|
69 |
+
|
70 |
+
register_activation_hook(__FILE__, array(&$this, 'activate'));
|
71 |
+
register_deactivation_hook(__FILE__, array(&$this, 'deactivate'));
|
72 |
+
}
|
73 |
+
|
74 |
+
public function activate(){
|
75 |
+
global $wpdb;
|
76 |
+
|
77 |
+
if ($wpdb->get_var("show tables like '{$this->ull_table}'") != $this->ull_table)
|
78 |
+
$this->create_table();
|
79 |
+
}
|
80 |
+
|
81 |
+
public function deactivate(){
|
82 |
+
}
|
83 |
+
|
84 |
+
private function create_table(){
|
85 |
+
global $wpdb;
|
86 |
+
|
87 |
+
if ($wpdb->get_var("show tables like '{$this->ull_table}'") != $this->ull_table) {
|
88 |
+
$wpdb->query("
|
89 |
+
CREATE TABLE `{$this->ull_table}` (
|
90 |
+
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
91 |
+
`user_id` bigint(20) unsigned NOT NULL DEFAULT 0,
|
92 |
+
`activity_status` varchar(255) NOT NULL,
|
93 |
+
`activity_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
94 |
+
`activity_agent` varchar(255) NOT NULL,
|
95 |
+
`activity_IP` varchar(100) NOT NULL,
|
96 |
+
`activity_errors` text NULL,
|
97 |
+
`country_name` varchar(100) NULL,
|
98 |
+
`country_code` varchar(10) NULL,
|
99 |
+
PRIMARY KEY (`ID`),
|
100 |
+
KEY `user_id` (`user_id`),
|
101 |
+
KEY `activity_status` (`activity_status`),
|
102 |
+
KEY `activity_date` (`activity_date`),
|
103 |
+
KEY `country_code` (`country_code`)
|
104 |
+
)");
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
public function admin_bar_init() {
|
109 |
+
add_action('admin_bar_menu', array(&$this, 'customize_admin_bar_menu'), 9999);
|
110 |
+
wp_enqueue_style('user_login_log', plugins_url('css/user_login_log.css', __FILE__), array(), '20130508');
|
111 |
+
wp_enqueue_script('jquery');
|
112 |
+
}
|
113 |
+
|
114 |
+
public function enqueue_scripts(){
|
115 |
+
wp_enqueue_script('jquery');
|
116 |
+
}
|
117 |
+
|
118 |
+
public function customize_admin_bar_menu($wp_admin_bar){
|
119 |
+
$title = $this->login_info();
|
120 |
+
if ($title === false)
|
121 |
+
return;
|
122 |
+
|
123 |
+
$wp_admin_bar->add_menu(array(
|
124 |
+
'id' => 'user-login-log',
|
125 |
+
'parent' => 'my-account',
|
126 |
+
'title' => $title,
|
127 |
+
'meta' => array(),
|
128 |
+
'href' => $this->admin_action,
|
129 |
+
));
|
130 |
+
|
131 |
+
add_action('admin_footer', array(&$this, 'footer_js'));
|
132 |
+
add_action('wp_footer', array(&$this, 'footer_js'));
|
133 |
+
}
|
134 |
+
|
135 |
+
private function login_info() {
|
136 |
+
$user = wp_get_current_user();
|
137 |
+
if (is_wp_error($user))
|
138 |
+
return false;
|
139 |
+
|
140 |
+
$login_log = get_user_meta($user->ID, self::USER_META_KEY . '-login', true);
|
141 |
+
if (!$login_log)
|
142 |
+
$login_log = $this->logging($user->ID, 'login');
|
143 |
+
|
144 |
+
$date = isset($login_log['Date']) ? strtotime($login_log['Date']) : time();
|
145 |
+
$ip = isset($login_log['IP']) ? $login_log['IP'] : '';
|
146 |
+
$ua = isset($login_log['User Agent']) ? $login_log['User Agent'] : '';
|
147 |
+
|
148 |
+
list($browser_name, $browser_code, $browser_ver, $os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = $this->detect_browser($ua);
|
149 |
+
list($country_name, $country_code) = $this->detect_country($ip);
|
150 |
+
|
151 |
+
$title = trim(sprintf(
|
152 |
+
__('Last login: %s%s%s', self::TEXT_DOMAIN),
|
153 |
+
$this->nice_time($date),
|
154 |
+
!empty($ip) ? ' '.$this->get_country_flag($ip) : '',
|
155 |
+
!empty($ua) ? ' '.$this->get_browser_icon($ua) : ''
|
156 |
+
));
|
157 |
+
return $title;
|
158 |
+
}
|
159 |
+
|
160 |
+
public function user_login_log($user_login, $user) {
|
161 |
+
$this->logging($user->ID, 'login');
|
162 |
+
}
|
163 |
+
|
164 |
+
function wp_authenticate_log($user_login, $user_password) {
|
165 |
+
if (empty($user_login))
|
166 |
+
return;
|
167 |
+
$user = wp_authenticate($user_login, $user_password);
|
168 |
+
if (!is_wp_error($user))
|
169 |
+
return;
|
170 |
+
$errors = $user->errors;
|
171 |
+
if (array_key_exists('invalid_username', $errors)) {
|
172 |
+
$user_id = 0;
|
173 |
+
} else {
|
174 |
+
$user = get_user_by('login', $user_login);
|
175 |
+
$user_id = isset($user->ID) ? $user->ID : 0;
|
176 |
+
}
|
177 |
+
$this->logging($user_id, 'login_error', array(
|
178 |
+
'errors' => $errors,
|
179 |
+
'user_login' => $user_login,
|
180 |
+
'user_password' => $user_password,
|
181 |
+
));
|
182 |
+
}
|
183 |
+
|
184 |
+
public function user_logout_log() {
|
185 |
+
$user = wp_get_current_user();
|
186 |
+
if (is_wp_error($user))
|
187 |
+
return;
|
188 |
+
$this->logging($user->ID, 'logout');
|
189 |
+
}
|
190 |
+
|
191 |
+
private function logging($user_id, $status, $args = array()) {
|
192 |
+
global $wpdb;
|
193 |
+
|
194 |
+
$activity_date = $this->time();
|
195 |
+
$activity_agent = $this->ua();
|
196 |
+
$activity_IP = $this->ip();
|
197 |
+
list($country_name, $country_code) = self::detect_country($activity_IP);
|
198 |
+
if ($user_id != 0) {
|
199 |
+
$meta_value = array_merge(array(
|
200 |
+
'status' => $status,
|
201 |
+
'Date' => $activity_date,
|
202 |
+
'User Agent' => $activity_agent,
|
203 |
+
'IP' => $activity_IP,
|
204 |
+
'Country Name' => $country_name,
|
205 |
+
'Country Code' => $country_code,
|
206 |
+
), (array)$args);
|
207 |
+
update_user_meta($user_id, self::USER_META_KEY . "-{$status}", $meta_value);
|
208 |
+
}
|
209 |
+
|
210 |
+
if ($status === 'login_error') {
|
211 |
+
$sql = $wpdb->prepare(
|
212 |
+
"insert into {$this->ull_table}
|
213 |
+
(`user_id`, `activity_status`, `activity_date`, `activity_agent`, `activity_IP`, `activity_errors`, `country_name`, `country_code`)
|
214 |
+
values (%d, %s, %s, %s, %s, %s, %s, %s)",
|
215 |
+
$user_id,
|
216 |
+
$status,
|
217 |
+
$activity_date,
|
218 |
+
$activity_agent,
|
219 |
+
$activity_IP,
|
220 |
+
serialize($args),
|
221 |
+
$country_name,
|
222 |
+
$country_code
|
223 |
+
);
|
224 |
+
} else {
|
225 |
+
$sql = $wpdb->prepare(
|
226 |
+
"insert into {$this->ull_table}
|
227 |
+
(`user_id`, `activity_status`, `activity_date`, `activity_agent`, `activity_IP`, `country_name`, `country_code`)
|
228 |
+
values (%d, %s, %s, %s, %s, %s, %s)",
|
229 |
+
$user_id,
|
230 |
+
$status,
|
231 |
+
$activity_date,
|
232 |
+
$activity_agent,
|
233 |
+
$activity_IP,
|
234 |
+
$country_name,
|
235 |
+
$country_code
|
236 |
+
);
|
237 |
+
}
|
238 |
+
$wpdb->query($sql);
|
239 |
+
|
240 |
+
return $meta_value;
|
241 |
+
}
|
242 |
+
|
243 |
+
public function ajax_info(){
|
244 |
+
$content = $this->login_info();
|
245 |
+
if ($content === false)
|
246 |
+
wp_die('Not logged in.');
|
247 |
+
|
248 |
+
header('Content-Type: application/json; charset='.get_option('blog_charset'));
|
249 |
+
echo json_encode(array('content' => $content));
|
250 |
+
die();
|
251 |
+
}
|
252 |
+
|
253 |
+
public function footer_js(){
|
254 |
+
if (!is_user_logged_in())
|
255 |
+
return;
|
256 |
+
?>
|
257 |
+
<script type="text/javascript">
|
258 |
+
function get_ull_info() {
|
259 |
+
jQuery.ajax('<?php echo admin_url('admin-ajax.php'); ?>',{
|
260 |
+
data: {action: 'ull_info'},
|
261 |
+
cache: false,
|
262 |
+
dataType: 'json',
|
263 |
+
type: 'POST',
|
264 |
+
success: function(response){
|
265 |
+
<?php if (self::DEBUG_MODE) echo "console.log(response);\n" ?>
|
266 |
+
jQuery('#wp-admin-bar-user-login-log a').html(response.content);
|
267 |
+
setTimeout('get_ull_info()', 30000);
|
268 |
+
},
|
269 |
+
error: function(){
|
270 |
+
setTimeout('get_ull_info()', 10000);
|
271 |
+
}
|
272 |
+
});
|
273 |
+
}
|
274 |
+
jQuery(function(){setTimeout('get_ull_info()', 30000);});
|
275 |
+
</script>
|
276 |
+
<?php
|
277 |
+
}
|
278 |
+
|
279 |
+
// Add Admin Menu
|
280 |
+
public function add_admin_menu() {
|
281 |
+
$parent = 'profile.php';
|
282 |
+
$page_title = __('Login Log', self::TEXT_DOMAIN);
|
283 |
+
$menu_title = $page_title;
|
284 |
+
$file = plugin_basename(__FILE__);
|
285 |
+
$this->admin_action = admin_url($parent) . '?page=' . plugin_basename(__FILE__);
|
286 |
+
$this->add_submenu_page(
|
287 |
+
$parent,
|
288 |
+
$page_title,
|
289 |
+
array($this,'option_page'),
|
290 |
+
'level_0',
|
291 |
+
$menu_title,
|
292 |
+
$file
|
293 |
+
);
|
294 |
+
}
|
295 |
+
private function add_submenu_page($parent, $page_title, $function, $capability = 'administrator', $menu_title = '', $file = '') {
|
296 |
+
if ($menu_title == '')
|
297 |
+
$menu_title = $page_title;
|
298 |
+
if ($file == '')
|
299 |
+
$file = $this->plugin_file;
|
300 |
+
add_submenu_page($parent, $page_title, $menu_title, $capability, $file, $function);
|
301 |
+
}
|
302 |
+
|
303 |
+
private function ip(){
|
304 |
+
$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1';
|
305 |
+
if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) ) {
|
306 |
+
$x_forwarded_for = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
|
307 |
+
$ip = trim($x_forwarded_for[0]);
|
308 |
+
}
|
309 |
+
return preg_replace('/[^0-9a-fA-F:., ]/', '', $ip);
|
310 |
+
}
|
311 |
+
|
312 |
+
// Detect Country
|
313 |
+
public static function detect_country($ip) {
|
314 |
+
$detect_countries = new DetectCountriesController();
|
315 |
+
list($country_name, $country_code) = $detect_countries->get_info($ip);
|
316 |
+
if ( empty($country_code) )
|
317 |
+
$country_code = __('UNKNOWN', self::TEXT_DOMAIN);
|
318 |
+
return array($country_name, $country_code);
|
319 |
+
}
|
320 |
+
|
321 |
+
private function ua(){
|
322 |
+
$ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : __('Unknown', self::TEXT_DOMAIN);
|
323 |
+
return substr($ua, 0, 254);
|
324 |
+
}
|
325 |
+
|
326 |
+
// Detect Browser
|
327 |
+
public static function detect_browser($ua) {
|
328 |
+
$detect_browsers = new DetectBrowsersController();
|
329 |
+
list($browser_name, $browser_code, $browser_ver, $os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = $detect_browsers->get_info($ua);
|
330 |
+
if (empty($os_code)) {
|
331 |
+
$os_name = !empty($pda_code) ? $pda_name : $browser_name;
|
332 |
+
$os_code = !empty($pda_code) ? $pda_code : $browser_code;
|
333 |
+
$os_ver = !empty($pda_code) ? $pda_ver : $browser_ver ;
|
334 |
+
}
|
335 |
+
if (empty($browser_code)) {
|
336 |
+
$browser_name = $os_name;
|
337 |
+
$browser_code = $os_code;
|
338 |
+
$browser_ver = $os_ver ;
|
339 |
+
}
|
340 |
+
|
341 |
+
if (empty($browser_name))
|
342 |
+
$browser_name = $ua;
|
343 |
+
if (empty($browser_code))
|
344 |
+
$browser_code = 'unknown';
|
345 |
+
|
346 |
+
if (empty($os_name))
|
347 |
+
$os_name = $ua;
|
348 |
+
if (empty($os_code))
|
349 |
+
$os_code = 'unknown';
|
350 |
+
|
351 |
+
return array($browser_name, $browser_code, $browser_ver, $os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver);
|
352 |
+
}
|
353 |
+
|
354 |
+
public static function time(){
|
355 |
+
$time = current_time('mysql');
|
356 |
+
return $time;
|
357 |
+
}
|
358 |
+
|
359 |
+
private function nice_time($dest) {
|
360 |
+
$dest = intval($dest);
|
361 |
+
$sour = intval(func_num_args() == 1 ? strtotime($this->time()) : func_get_arg(1));
|
362 |
+
$nicetime = '';
|
363 |
+
|
364 |
+
$tt = $dest - $sour;
|
365 |
+
|
366 |
+
$year = intval($tt / self::SEC_YEAR);
|
367 |
+
if ($year < -1) {
|
368 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . sprintf(__('%d years', self::TEXT_DOMAIN), abs($year));
|
369 |
+
} else if ($year == -1) {
|
370 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . __('one year', self::TEXT_DOMAIN);
|
371 |
+
}
|
372 |
+
|
373 |
+
$month = intval($tt / self::SEC_MONTH);
|
374 |
+
if ($month < -1) {
|
375 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . sprintf(__('%d months', self::TEXT_DOMAIN), abs($month));
|
376 |
+
$tt = ($dest + abs($year) * self::SEC_MONTH) - $sour;
|
377 |
+
} else if ($month == -1) {
|
378 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . __('one month', self::TEXT_DOMAIN);
|
379 |
+
$tt = ($dest + self::SEC_MONTH) - $sour;
|
380 |
+
}
|
381 |
+
|
382 |
+
$day = intval($tt / self::SEC_DAY);
|
383 |
+
if ($day < -1) {
|
384 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . sprintf(__('%d days', self::TEXT_DOMAIN), abs($day));
|
385 |
+
} else if ($day == -1) {
|
386 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . __('one day', self::TEXT_DOMAIN);
|
387 |
+
}
|
388 |
+
|
389 |
+
$hour = intval($tt / self::SEC_HOUR);
|
390 |
+
if ($hour < -1) {
|
391 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . sprintf(__('%d hours', self::TEXT_DOMAIN), abs($hour));
|
392 |
+
$tt = ($dest + abs($hour) * self::SEC_HOUR) - $sour;
|
393 |
+
} else if ($hour == -1) {
|
394 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . __('one hour', self::TEXT_DOMAIN);
|
395 |
+
$tt = ($dest + self::SEC_HOUR) - $sour;
|
396 |
+
}
|
397 |
+
|
398 |
+
$minute = intval($tt / self::SEC_MINUITE);
|
399 |
+
if ($minute < -1) {
|
400 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . sprintf(__('%d minutes', self::TEXT_DOMAIN), abs($minute));
|
401 |
+
} else if ($minute == -1) {
|
402 |
+
$nicetime .= (!empty($nicetime) ? ' ' : '' ) . __('one minute', self::TEXT_DOMAIN);
|
403 |
+
}
|
404 |
+
|
405 |
+
return empty($nicetime) ? __('Just now!', self::TEXT_DOMAIN) : sprintf(__('%s ago.', self::TEXT_DOMAIN), $nicetime);
|
406 |
+
}
|
407 |
+
|
408 |
+
public static function icon_img_tag($src, $alt, $title, $style = 'width:16px;height:16px;', $class = '') {
|
409 |
+
return sprintf(
|
410 |
+
__('<img src="%1$s" alt="%2$s" title="%3$s" style="%4$s" %5$s/>', self::TEXT_DOMAIN),
|
411 |
+
$src,
|
412 |
+
esc_attr($alt),
|
413 |
+
esc_attr($title),
|
414 |
+
$style,
|
415 |
+
!empty($class) ? 'class="'.$class.'" ' : '');
|
416 |
+
}
|
417 |
+
|
418 |
+
// Get country flag
|
419 |
+
public static function get_country_flag($ip, $class = '') {
|
420 |
+
list($country_name, $country_code) = self::detect_country($ip);
|
421 |
+
|
422 |
+
$icon_dir = plugins_url('images/flags/', __FILE__);
|
423 |
+
$style = 'width:16px;height:11px;';
|
424 |
+
|
425 |
+
return self::icon_img_tag($icon_dir.strtolower($country_code).'.png', "{$country_name} ({$ip})", "{$country_name} ({$ip})", $style, $class);
|
426 |
+
}
|
427 |
+
|
428 |
+
// Get browser icon
|
429 |
+
public static function get_browser_icon($ua, $show_ver = true, $separator = ' ', $class = '') {
|
430 |
+
list($browser_name, $browser_code, $browser_ver, $os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::detect_browser($ua);
|
431 |
+
|
432 |
+
$os_info = trim($os_name . ( $show_ver ? ' ' . $os_ver : '' ));
|
433 |
+
$pda_info = trim($pda_name . ( $show_ver ? ' ' . $pda_ver : '' ));
|
434 |
+
$browser_info = trim($browser_name . ( $show_ver ? ' ' . $browser_ver : '' ));
|
435 |
+
$unknown_info = $show_ver ? $ua : __('UNKNOWN', self::TEXT_DOMAIN);
|
436 |
+
|
437 |
+
$icon_dir = plugins_url('images/browsers/', __FILE__);
|
438 |
+
$style = 'width:16px;height:16px;';
|
439 |
+
|
440 |
+
$browser_icon = '';
|
441 |
+
if ( !empty($os_info) )
|
442 |
+
$browser_icon .= self::icon_img_tag($icon_dir.$os_code.'.png', $os_info, $os_info, $style, $class) . $separator;
|
443 |
+
if ( !empty($pda_info) && $pda_code !== $os_code )
|
444 |
+
$browser_icon .= self::icon_img_tag($icon_dir.$pda_code.'.png', $pda_info, $pda_info, $style, $class) . $separator;
|
445 |
+
if ( !empty($browser_info) && $browser_code !== $os_code )
|
446 |
+
$browser_icon .= self::icon_img_tag($icon_dir.$browser_code.'.png', $browser_info, $browser_info, $style, $class);
|
447 |
+
if ( empty($browser_icon) )
|
448 |
+
$browser_icon .= self::icon_img_tag($icon_dir.'unknown.png', $unknown_info, $unknown_info, $style, $class);
|
449 |
+
|
450 |
+
return $browser_icon;
|
451 |
+
}
|
452 |
+
|
453 |
+
public function option_page() {
|
454 |
+
global $wpdb;
|
455 |
+
|
456 |
+
$page = abs(intval(isset($_GET['apage']) ? $_GET['apage'] : 1));
|
457 |
+
$per_page = self::LIST_PER_PAGE;
|
458 |
+
$start = ($page - 1) * $per_page;
|
459 |
+
|
460 |
+
$user_id = 0;
|
461 |
+
if (current_user_can('create_users') && isset($_GET['user_id'])) {
|
462 |
+
$user_id = intval($_GET['user_id']);
|
463 |
+
} else {
|
464 |
+
$user = wp_get_current_user();
|
465 |
+
if (is_wp_error($user))
|
466 |
+
return;
|
467 |
+
$user_id = intval($user->ID);
|
468 |
+
}
|
469 |
+
|
470 |
+
$sql = " from `{$this->ull_table}` left join `{$wpdb->users}` on `{$this->ull_table}`.`user_id` = `{$wpdb->users}`.`ID`";
|
471 |
+
if ($user_id >= 0)
|
472 |
+
$sql .= $wpdb->prepare(" where `user_id` = %d", $user_id);
|
473 |
+
$total = intval($wpdb->get_var("select count(`{$this->ull_table}`.`ID`)".$sql));
|
474 |
+
$page_links = paginate_links( array(
|
475 |
+
'base' => add_query_arg( 'apage', '%#%' ) ,
|
476 |
+
'format' => '' ,
|
477 |
+
'prev_text' => __('«') ,
|
478 |
+
'next_text' => __('»') ,
|
479 |
+
'total' => ceil($total / $per_page) ,
|
480 |
+
'current' => $page
|
481 |
+
));
|
482 |
+
|
483 |
+
$page_links_text = sprintf( '<span class="displaying-num">' . __( 'Displaying %s–%s of %s' ) . '</span>%s',
|
484 |
+
number_format_i18n( $start + 1 ),
|
485 |
+
number_format_i18n( min( $page * $per_page, $total ) ),
|
486 |
+
number_format_i18n( $total ),
|
487 |
+
$page_links
|
488 |
+
);
|
489 |
+
|
490 |
+
$sql = 'select `user_login`, `activity_date`, `activity_status`, `activity_IP`, `activity_agent`, `activity_errors`'.
|
491 |
+
$sql.' order by `activity_date` DESC'.
|
492 |
+
' limit '.$start.','.self::LIST_PER_PAGE;
|
493 |
+
|
494 |
+
$ull = $wpdb->get_results($sql);
|
495 |
+
$row_num = 0;
|
496 |
+
?>
|
497 |
+
<div class="wrap">
|
498 |
+
<div id="icon-profile" class="icon32"></div>
|
499 |
+
<h2><?php _e('Login Log', self::TEXT_DOMAIN); ?></h2>
|
500 |
+
|
501 |
+
<div class="tablenav">
|
502 |
+
<?php if (current_user_can('create_users')) { ?>
|
503 |
+
<div class="alignleft actions">
|
504 |
+
<form action="" method="get">
|
505 |
+
<input type="hidden" name="page" value="<?php echo plugin_basename(__FILE__); ?>" />
|
506 |
+
<select name="user_id">
|
507 |
+
<option value="-1"<?php if ($user_id == -1) echo ' selected="selected"';?>><?php _e('All Users', self::TEXT_DOMAIN); ?></option>
|
508 |
+
<option value="0"<?php if ($user_id == 0) echo ' selected="selected"';?>><?php _e('Unknown', self::TEXT_DOMAIN); ?></option>
|
509 |
+
<?php
|
510 |
+
$users = $wpdb->get_results("select ID, user_login from `{$wpdb->users}` order by ID");
|
511 |
+
foreach((array)$users as $user) {
|
512 |
+
printf("<option value=\"%d\"%s>%s</option>\n", $user->ID, $user->ID == $user_id ? ' selected="selected"' : '', $user->user_login);
|
513 |
+
}
|
514 |
+
?>
|
515 |
+
</select>
|
516 |
+
<?php submit_button( __( 'Apply Filters' ), 'action', false, false, array( 'id' => "doaction" ) );?>
|
517 |
+
</form>
|
518 |
+
</div>
|
519 |
+
<?php } ?>
|
520 |
+
<div class="alignright actions">
|
521 |
+
<?php echo $page_links_text; ?>
|
522 |
+
</div>
|
523 |
+
<br class="clear" />
|
524 |
+
</div>
|
525 |
+
|
526 |
+
<div class="clear"></div>
|
527 |
+
|
528 |
+
<table class="widefat comments fixed" cellspacing="0">
|
529 |
+
<thead>
|
530 |
+
<tr>
|
531 |
+
<?php if ($user_id <= 0) { ?>
|
532 |
+
<th scope="col" class="manage-column column-username"><?php _e('User Name', self::TEXT_DOMAIN); ?></th>
|
533 |
+
<?php } ?>
|
534 |
+
<th scope="col" class="manage-column column-date"><?php _e('Date', self::TEXT_DOMAIN); ?></th>
|
535 |
+
<th scope="col" class="manage-column column-status"><?php _e('Status', self::TEXT_DOMAIN); ?></th>
|
536 |
+
<th scope="col" class="manage-column column-ip"><?php _e('IP', self::TEXT_DOMAIN); ?></th>
|
537 |
+
<th scope="col" class="manage-column column-agent"><?php _e('User Agent', self::TEXT_DOMAIN); ?></th>
|
538 |
+
<th scope="col" class="manage-column column-errors" style=""><?php _e('Errors', self::TEXT_DOMAIN); ?></th>
|
539 |
+
</tr>
|
540 |
+
</thead>
|
541 |
+
<tfoot>
|
542 |
+
<tr>
|
543 |
+
<?php if ($user_id <= 0) { ?>
|
544 |
+
<th scope="col" class="manage-column column-username"><?php _e('User Name', self::TEXT_DOMAIN); ?></th>
|
545 |
+
<?php } ?>
|
546 |
+
<th scope="col" class="manage-column column-date"><?php _e('Date', self::TEXT_DOMAIN); ?></th>
|
547 |
+
<th scope="col" class="manage-column column-status"><?php _e('Status', self::TEXT_DOMAIN); ?></th>
|
548 |
+
<th scope="col" class="manage-column column-ip"><?php _e('IP', self::TEXT_DOMAIN); ?></th>
|
549 |
+
<th scope="col" class="manage-column column-agent"><?php _e('User Agent', self::TEXT_DOMAIN); ?></th>
|
550 |
+
<th scope="col" class="manage-column column-errors" style=""><?php _e('Errors', self::TEXT_DOMAIN); ?></th>
|
551 |
+
</tr>
|
552 |
+
</tfoot>
|
553 |
+
|
554 |
+
<tbody id="user-login-log">
|
555 |
+
<?php foreach($ull as $row) {?>
|
556 |
+
<?php
|
557 |
+
list($browser_name, $browser_code, $browser_ver, $os_name, $os_code, $os_ver, $pda_name, $pda_code, $pda_ver) = self::detect_browser($row->activity_agent);
|
558 |
+
$ua = trim("$os_name $os_ver");
|
559 |
+
$ua .= $browser_code !== $os_code ? (empty($ua) ? '' : ' / ')."$browser_name $browser_ver" : '';
|
560 |
+
$ua = trim($ua);
|
561 |
+
|
562 |
+
$errors = unserialize($row->activity_errors);
|
563 |
+
$user_login =
|
564 |
+
(is_array($errors) && isset($errors['user_login']))
|
565 |
+
? $errors['user_login']
|
566 |
+
: $row->user_login;
|
567 |
+
$errors =
|
568 |
+
(is_array($errors) && isset($errors['errors']))
|
569 |
+
? implode(', ', array_keys($errors['errors']))
|
570 |
+
: '';
|
571 |
+
?>
|
572 |
+
<tr id="log-<?php echo $row_num ?>">
|
573 |
+
<?php if ($user_id <= 0) { ?>
|
574 |
+
<td class="username column-username"><?php echo $user_login; ?></td>
|
575 |
+
<?php } ?>
|
576 |
+
<td class="date column-date"><?php echo $row->activity_date; ?></td>
|
577 |
+
<td class="status column-status"><?php echo $row->activity_status; ?></td>
|
578 |
+
<td class="ip column-ip"><?php echo trim(self::get_country_flag($row->activity_IP) . '<br>' . $row->activity_IP); ?></td>
|
579 |
+
<td class="agent column-agent"><?php echo trim(self::get_browser_icon($row->activity_agent) . '<br>' . $ua); ?></td>
|
580 |
+
<td class="errors column-errors"><?php echo $errors; ?></td>
|
581 |
+
</tr>
|
582 |
+
<?php $row_num++; }?>
|
583 |
+
</tbody>
|
584 |
+
</table>
|
585 |
+
|
586 |
+
<div class="tablenav">
|
587 |
+
<div class="alignright actions">
|
588 |
+
<?php echo $page_links_text; ?>
|
589 |
+
</div>
|
590 |
+
<br class="clear" />
|
591 |
+
</div>
|
592 |
+
|
593 |
+
</div>
|
594 |
+
<?php
|
595 |
+
}
|
596 |
+
}
|
597 |
+
|
598 |
+
new user_login_log();
|
readme.txt
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Crazy Bone ===
|
2 |
+
Contributors: wokamoto, megumithemes
|
3 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=9S8AJCY7XB8F4&lc=JP&item_name=WordPress%20Plugins&item_number=wp%2dplugins¤cy_code=JPY&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted
|
4 |
+
Tags: log, login, users
|
5 |
+
Requires at least: 3.5
|
6 |
+
Tested up to: 3.5.1
|
7 |
+
Stable tag: 0.1.1
|
8 |
+
|
9 |
+
Tracks user name, time of login, IP address and browser user agent.
|
10 |
+
|
11 |
+
== Description ==
|
12 |
+
|
13 |
+
Tracks user name, time of login, IP address and browser user agent.
|
14 |
+
|
15 |
+
= Localization =
|
16 |
+
"Crazy Bone" has been translated into languages. Our thanks and appreciation must go to the following for their contributions:
|
17 |
+
|
18 |
+
* Japanese (ja) - [OKAMOTO Wataru](http://dogmap.jp/ "dogmap.jp") (plugin author)
|
19 |
+
|
20 |
+
If you have translated into your language, please let me know.
|
21 |
+
|
22 |
+
== Installation ==
|
23 |
+
|
24 |
+
1. Upload the entire `crazy-bone` folder to the `/wp-content/plugins/` directory.
|
25 |
+
2. Activate the plugin through the 'Plugins' menu in WordPress.
|
26 |
+
|
27 |
+
== Frequently Asked Questions ==
|
28 |
+
|
29 |
+
none
|
30 |
+
|
31 |
+
== Screenshots ==
|
32 |
+
|
33 |
+
1. The admin page
|
34 |
+
|
35 |
+
== Changelog ==
|
36 |
+
|
37 |
+
**0.1.0 - May 10, 2013**
|
38 |
+
Initial release.
|
uninstall.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( !defined('ABSPATH') && !defined('WP_UNINSTALL_PLUGIN') )
|
4 |
+
exit();
|
5 |
+
|
6 |
+
|
7 |
+
global $wpdb;
|
8 |
+
$wpdb->query("delete from {$wpdb->usermeta} where meta_key like 'user_login_log%';");
|
9 |
+
|
10 |
+
$ull_table = $wpdb->prefix.'user_login_log';
|
11 |
+
if ($wpdb->get_var("show tables like '{$ull_table}'") != $ull_table)
|
12 |
+
$wpdb->query("DROP TABLE `{$ull_table}`");
|