Integrated a new fxratesapi module to handle currency conversions, including API configurations, rate conversion actions, and request logging. Added support for module settings such as enablement status, API key, and daily request limits. New routes, database interactions, and object handling were implemented to facilitate the module's operations.
176 lines
6.1 KiB
PHP
176 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace objects;
|
|
|
|
use classes\db;
|
|
use classes\object_property;
|
|
use Exception;
|
|
use traits\db_object_t;
|
|
|
|
class fxratesapi_conversion_rates_o extends db
|
|
{
|
|
use db_object_t;
|
|
|
|
public object_property $base;
|
|
public object_property $target;
|
|
public object_property $result;
|
|
public object_property $endpoint;
|
|
public object_property $created_at;
|
|
|
|
|
|
public function structure(): void
|
|
{
|
|
$this->setTable('fxratesapi_conversion_rates');
|
|
}
|
|
|
|
/**
|
|
* Add a new object to the database
|
|
* @param string $base The base currency to use (e.g. "DKK")
|
|
* @param string $target The target currency, (e.g. "EUR")
|
|
* @param string $result
|
|
* @param string $endpoint
|
|
* @return void
|
|
* @throws Exception If the object was not created successfully
|
|
*/
|
|
public function add(string $base, string $target, string $result, string $endpoint): void
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
// Sanitize the input
|
|
$base = $db->escape_string($base);
|
|
$target = $db->escape_string($target);
|
|
$result = $db->escape_string($result);
|
|
$endpoint = $db->escape_string($endpoint);
|
|
// Add the object
|
|
$tmp_id = self::add_object([
|
|
'base' => $base,
|
|
'target' => $target,
|
|
'result' => $result,
|
|
'endpoint' => $endpoint
|
|
]);
|
|
$this->id = $tmp_id;
|
|
self::getObjectProperties();
|
|
self::objectChanged();
|
|
}
|
|
|
|
public function getObjectProperties(): void
|
|
{
|
|
$this->base = new object_property($this->table, $this->id, 'base', 'string', false);
|
|
$this->target = new object_property($this->table, $this->id, 'target', 'string', false);
|
|
$this->result = new object_property($this->table, $this->id, 'result', 'string', false);
|
|
$this->endpoint = new object_property($this->table, $this->id, 'endpoint', 'string', false);
|
|
$this->created_at = new object_property($this->table, $this->id, 'created_at', 'datetime', false);
|
|
}
|
|
|
|
public function objectChanged(): void
|
|
{
|
|
//TODO: Add cache invalidation
|
|
}
|
|
|
|
/**
|
|
* Get the amount of requests made today
|
|
* @return int
|
|
*/
|
|
public function getTodayCount(): int
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
$sql = 'SELECT COUNT(*) FROM ' . $this->table . ' WHERE DATE(created_at) = CURDATE()';
|
|
$result = $db->query($sql);
|
|
return (int)$result->fetch_row()[0];
|
|
}
|
|
|
|
public function asArray(): array
|
|
{
|
|
return [
|
|
'id' => (int)$this->id,
|
|
'base' => (string)$this->base->value(),
|
|
'target' => (string)$this->target->value(),
|
|
'result' => (string)$this->result->value(),
|
|
'endpoint' => (string)$this->endpoint->value(),
|
|
'created_at' => (string)$this->created_at->value(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Is the conversion rate cached within the last 10 minutes?
|
|
* @param string $base The base currency to check
|
|
* @param string $target The target currency to check
|
|
* @return bool
|
|
* @throws Exception If the base or target currency is not valid
|
|
*/
|
|
public function isCached(string $base, string $target): bool
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
if (!self::validateCurrencyFormat($base) || !self::validateCurrencyFormat($target)) {
|
|
throw new Exception('The base or target currency is not valid.');
|
|
}
|
|
$sql = 'SELECT COUNT(*) FROM ' . $this->table . ' WHERE base = "' . $db->escape_string($base) . '" AND target = "' . $db->escape_string($target) . '" AND created_at > DATE_SUB(NOW(), INTERVAL 10 MINUTE)';
|
|
$result = $db->query($sql);
|
|
return (bool)$result->fetch_row()[0];
|
|
}
|
|
|
|
/**
|
|
* Validate the format of a currency
|
|
* @note This simply checks if the currency is in the format of three uppercase letters.
|
|
* @note This does not check if the currency is actually valid.
|
|
* @param string $currency
|
|
* @return bool
|
|
*/
|
|
public static function validateCurrencyFormat(string $currency): bool
|
|
{
|
|
return (bool)preg_match('/^[A-Z]{3}$/', $currency);
|
|
}
|
|
|
|
/**
|
|
* Get the (latest) cached result for a conversion rate
|
|
* @param string $base The base currency to check
|
|
* @param string $target The target currency to check
|
|
* @return object
|
|
* @throws Exception If the base or target currency is not valid or the response is not cached
|
|
*/
|
|
public function getCachedResult(string $base, string $target): object
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
if (!self::validateCurrencyFormat($base) || !self::validateCurrencyFormat($target)) {
|
|
throw new Exception('The base or target currency is not valid.');
|
|
}
|
|
$result = self::getFieldsWhere(['base' => $base, 'target' => $target], ['id', 'result', 'endpoint', 'created_at']);
|
|
if (!$result) {
|
|
throw new Exception('The response is not cached.');
|
|
}
|
|
// Get the latest result
|
|
$latest = array_pop($result);
|
|
$this->id = $latest['id'];
|
|
self::getObjectProperties();
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get the (latest) cached response for a conversion rate
|
|
* @param string $base The base currency to check
|
|
* @param string $target The target currency to check
|
|
* @return object
|
|
* @throws Exception If the base or target currency is not valid or the response is not cached
|
|
* @note This is a wrapper for getCachedResult
|
|
*/
|
|
public function getCachedResponse(string $base, string $target): object
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
if (!self::validateCurrencyFormat($base) || !self::validateCurrencyFormat($target)) {
|
|
throw new Exception('The base or target currency is not valid.');
|
|
}
|
|
$result = self::getFieldsWhere(['base' => $base, 'target' => $target], ['id', 'result', 'endpoint', 'created_at']);
|
|
if (!$result) {
|
|
throw new Exception('The response is not cached.');
|
|
}
|
|
// Get the latest result
|
|
$latest = array_pop($result);
|
|
$this->id = $latest['id'];
|
|
self::getObjectProperties();
|
|
return json_decode($latest['result']);
|
|
}
|
|
} |