<?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];
}
}