wfIpLocator.php
2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<?php
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/wfIpLocation.php';
use Wordfence\MmdbReader\Database;
use Wordfence\MmdbReader\Exception\MmdbThrowable;
class wfIpLocator {
const SOURCE_BUNDLED = 0;
const SOURCE_WFLOGS = 1;
const DATABASE_FILE_NAME = 'GeoLite2-Country.mmdb';
private static $instances = array();
private $database;
private $preferred;
private function __construct($database, $preferred) {
$this->database = $database;
$this->preferred = $preferred;
}
public function isPreferred() {
return $this->preferred;
}
private static function logError($message) {
if (class_exists('wfUtils'))
wfUtils::check_and_log_last_error('ip_locator', 'IP Location Error:', $message, 0);
}
public function locate($ip) {
if ($this->database !== null) {
try {
$record = $this->database->search($ip);
if ($record !== null)
return new wfIpLocation($record);
}
catch (MmdbThrowable $t) {
self::logError('Failed to locate IP address: ' . $t->getMessage());
}
}
return null;
}
public function getCountryCode($ip, $default = '') {
$record = $this->locate($ip);
if ($record !== null)
return $record->getCountryCode();
return $default;
}
public function getDatabaseVersion() {
if ($this->database !== null) {
try {
return $this->database->getMetadata()->getBuildEpoch();
}
catch (MmdbThrowable $t) {
self::logError('Failed to retrieve database version: ' . $t->getMessage());
}
}
return null;
}
private static function getDatabaseDirectory($source) {
switch ($source) {
case self::SOURCE_BUNDLED:
return WFWAF_LOG_PATH;
case self::SOURCE_BUNDLED:
default:
return __DIR__;
}
}
private static function initializeDatabase($preferredSource, &$isPreferred) {
$sources = array();
if ($preferredSource !== self::SOURCE_BUNDLED)
$sources[] = $preferredSource;
$sources[] = self::SOURCE_BUNDLED;
$isPreferred = true;
foreach ($sources as $source) {
$directory = self::getDatabaseDirectory($source);
try {
$path = $directory . '/' . self::DATABASE_FILE_NAME;
if (file_exists($path)) //Preemptive check to prevent warnings
return Database::open($path);
}
catch (MmdbThrowable $t) {
self::logError('Failed to initialize IP location database: ' . $t->getMessage());
}
$preferred = false;
}
return null;
}
public static function getInstance($preferredSource = null) {
if ($preferredSource === null)
$preferredSource = self::SOURCE_WFLOGS;
if (!array_key_exists($preferredSource, self::$instances)) {
$database = self::initializeDatabase($preferredSource, $isPreferred);
self::$instances[$preferredSource] = new wfIpLocator($database, $isPreferred);
}
return self::$instances[$preferredSource];
}
}