176 lines
4.1 KiB
PHP
176 lines
4.1 KiB
PHP
<?php
|
|
/**
|
|
* @package Plumrocket_GeoIPLookup
|
|
* @copyright Copyright (c) 2024 Plumrocket Inc. (https://plumrocket.com)
|
|
* @license https://plumrocket.com/license/ End-user License Agreement
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Plumrocket\GeoIPLookup\Model;
|
|
|
|
use Exception;
|
|
use Magento\Framework\App\Filesystem\DirectoryList;
|
|
use Magento\Framework\Exception\InvalidArgumentException;
|
|
use Magento\Framework\Filesystem;
|
|
use Plumrocket\GeoIPLookup\Helper\Config;
|
|
use Plumrocket\GeoIPLookup\Library\Mmdb\Reader;
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
class MmdbReader
|
|
{
|
|
/**
|
|
* @var \Magento\Framework\Filesystem
|
|
*/
|
|
private $filesystem;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $fileName;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $databaseName;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $fieldsMap;
|
|
|
|
/**
|
|
* @var \Plumrocket\GeoIPLookup\Library\Mmdb\Reader
|
|
*/
|
|
private $readerApi;
|
|
|
|
/**
|
|
* @var bool
|
|
*/
|
|
private $isDatabaseExists;
|
|
|
|
/**
|
|
* @param \Magento\Framework\Filesystem $filesystem
|
|
* @param string $fileName
|
|
* @param string $databaseName
|
|
* @param array $fieldsMap
|
|
* @throws \Magento\Framework\Exception\InvalidArgumentException
|
|
*/
|
|
public function __construct(
|
|
Filesystem $filesystem,
|
|
string $fileName = '',
|
|
string $databaseName = '',
|
|
array $fieldsMap = []
|
|
) {
|
|
if (!$fileName) {
|
|
throw new InvalidArgumentException(
|
|
__('Missing database. Use virtualType for set up database file.')
|
|
);
|
|
}
|
|
|
|
$this->filesystem = $filesystem;
|
|
$this->fileName = $fileName;
|
|
$this->databaseName = $databaseName;
|
|
$this->fieldsMap = $fieldsMap;
|
|
|
|
$this->createReader();
|
|
}
|
|
|
|
/**
|
|
* @param string $ipAddress
|
|
* @return array
|
|
* @throws \Plumrocket\GeoIPLookup\Library\Mmdb\Reader\InvalidDatabaseException
|
|
*/
|
|
public function get(string $ipAddress): array
|
|
{
|
|
if (!$this->isDatabaseExists) {
|
|
return [];
|
|
}
|
|
|
|
return $this->mapFields($this->readerApi->get($ipAddress));
|
|
}
|
|
|
|
/**
|
|
* @return array|null
|
|
*/
|
|
public function metadata(): ?array
|
|
{
|
|
if (!$this->isDatabaseExists) {
|
|
return null;
|
|
}
|
|
|
|
$metadata = $this->readerApi->metadata();
|
|
|
|
return [
|
|
'databaseType' => $metadata->databaseType,
|
|
'buildDate' => date('F d, Y', $metadata->buildEpoch)
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return MmdbReader
|
|
*/
|
|
public function refresh(): MmdbReader
|
|
{
|
|
$this->createReader();
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
private function createReader(): void
|
|
{
|
|
$database = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)
|
|
->getAbsolutePath(Config::LOCAL_PATH) . $this->fileName;
|
|
|
|
try {
|
|
$this->readerApi = new Reader($database);
|
|
$this->isDatabaseExists = true;
|
|
} catch (Exception $e) {
|
|
$this->isDatabaseExists = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array|null $ipData
|
|
* @return array[]|null
|
|
*/
|
|
private function mapFields(?array $ipData): ?array
|
|
{
|
|
if (! $ipData) {
|
|
return $ipData;
|
|
}
|
|
|
|
$result = ! $this->fieldsMap ? $ipData : [];
|
|
foreach ($this->fieldsMap as $resultFieldKey => $map) {
|
|
$mapPath = explode('.', $map);
|
|
$tmpValue = $ipData;
|
|
$i = 0;
|
|
|
|
do {
|
|
if (isset($tmpValue[$mapPath[$i]])) {
|
|
if (is_array($tmpValue[$mapPath[$i]])) {
|
|
$tmpValue = $tmpValue[$mapPath[$i]];
|
|
$i++;
|
|
continue;
|
|
}
|
|
|
|
$result[$resultFieldKey] = $tmpValue[$mapPath[$i]];
|
|
} else {
|
|
$result[$resultFieldKey] = '';
|
|
}
|
|
|
|
$i++;
|
|
} while (isset($mapPath[$i], $tmpValue[$mapPath[$i]]) && ! isset($result[$resultFieldKey]));
|
|
}
|
|
|
|
$result['database_name'] = $this->databaseName;
|
|
|
|
return $result;
|
|
}
|
|
}
|