Enhanced the order items functionality to include a related item ID. This involved adding a new property, updating methods to handle the related item ID, and ensuring appropriate validation and sanitation in the API routes. Also improved input sanitization for motorapi lookups to prevent SQL injection risks.
143 lines
4.5 KiB
PHP
143 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace objects;
|
|
|
|
use classes\db;
|
|
use classes\object_property;
|
|
use Exception;
|
|
use traits\db_object_t;
|
|
|
|
class motorapi_lookups_o extends db
|
|
{
|
|
use db_object_t;
|
|
|
|
public object_property $license_plate;
|
|
public object_property $result;
|
|
public object_property $endpoint;
|
|
public object_property $created_at;
|
|
|
|
|
|
public function structure(): void
|
|
{
|
|
$this->setTable('motorapi_lookups');
|
|
}
|
|
|
|
/**
|
|
* Add a motorapi lookup
|
|
* @param string $license_plate
|
|
* @param string $result
|
|
* @param string $endpoint
|
|
* @return void
|
|
* @throws Exception If the object was not created successfully
|
|
*/
|
|
public function add(string $license_plate, string $result, string $endpoint): void
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
// Sanitize the input
|
|
$license_plate = $db->escape_string($license_plate);
|
|
$result = $db->escape_string($result);
|
|
$endpoint = $db->escape_string($endpoint);
|
|
// Add the object
|
|
$tmp_id = self::add_object([
|
|
'license_plate' => $license_plate,
|
|
'result' => $result,
|
|
'endpoint' => $endpoint
|
|
]);
|
|
$this->id = $tmp_id;
|
|
self::getObjectProperties();
|
|
self::objectChanged();
|
|
}
|
|
|
|
public function getObjectProperties(): void
|
|
{
|
|
$this->license_plate = new object_property($this->table, $this->id, 'license_plate', '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 motorapi lookups created 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,
|
|
'license_plate' => (string)$this->license_plate->value(),
|
|
'result' => (string)$this->result->value(),
|
|
'endpoint' => (string)$this->endpoint->value(),
|
|
'created_at' => (string)$this->created_at->value(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Is the license plate in the cache?
|
|
* @param string $license_plate
|
|
* @return bool
|
|
* @throws Exception If the license plate is not valid
|
|
*/
|
|
public function isCached(string $license_plate): bool
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
if (!self::validateLicensePlateFormat($license_plate)) {
|
|
throw new Exception('The license plate is not valid.');
|
|
}
|
|
$sql = 'SELECT COUNT(*) FROM ' . $this->table . ' WHERE license_plate = "' . $db->escape_string($license_plate) . '"';
|
|
$result = $db->query($sql);
|
|
return (bool)$result->fetch_row()[0];
|
|
}
|
|
|
|
/**
|
|
* Validate the format of a license plate
|
|
* @note This simply checks if the license plate is in the format of two letters followed by four or five numbers.
|
|
* @note This does not check if the license plate is actually valid.
|
|
* @param string $license_plate
|
|
* @return bool
|
|
*/
|
|
public static function validateLicensePlateFormat(string $license_plate): bool
|
|
{
|
|
return (bool)preg_match('/^[A-Z]{2}[0-9]{4,5}$/', $license_plate);
|
|
}
|
|
|
|
/**
|
|
* Get the (latest) cached result for a license plate
|
|
* @param string $license_plate
|
|
* @return object
|
|
* @throws Exception If the license plate is not valid or the response is not cached
|
|
*/
|
|
public function getCachedResult(string $license_plate): object
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
if (!self::validateLicensePlateFormat($license_plate)) {
|
|
throw new Exception('The license plate is not valid.');
|
|
}
|
|
$result = self::getFieldsWhere(['license_plate' => $license_plate], ['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;
|
|
}
|
|
|
|
} |