Files
nabeh/backend/app/Models/DriverOcrData.php
2026-05-22 21:52:51 +03:00

145 lines
4.9 KiB
PHP

<?php
namespace App\Models;
use App\Core\Database;
use App\Core\Security;
/**
* DriverOcrData Model
* Manages collected driver documents and OCR results with binary field encryption.
*/
class DriverOcrData extends BaseModel
{
protected static string $table = 'driver_ocr_data';
/**
* Find decrypted record for a company and contact phone
*/
public static function findByPhone(int $companyId, string $phone): ?array
{
self::ensureTableExists();
$hash = Security::blindIndex($phone);
$record = Database::selectOne(
"SELECT * FROM " . static::$table . " WHERE company_id = ? AND (phone_hash = ? OR phone = ?) LIMIT 1",
[$companyId, $hash, $phone]
);
return self::decryptRecord($record);
}
/**
* Save or update driver registration OCR state securely
*/
public static function saveSecure(array $data): string
{
self::ensureTableExists();
$data = self::encryptRecord($data);
$existing = Database::selectOne(
"SELECT id FROM " . static::$table . " WHERE company_id = ? AND phone_hash = ? LIMIT 1",
[$data['company_id'], $data['phone_hash']]
);
if ($existing) {
self::update($existing['id'], $data);
return $existing['id'];
} else {
return self::create($data);
}
}
/**
* Helper to encrypt sensitive fields in a record (simplified to plain text)
*/
public static function encryptRecord(array $data): array
{
if (!empty($data['phone'])) {
$data['phone_hash'] = Security::blindIndex($data['phone']);
}
$ocrFields = [
'id_front_ocr', 'id_back_ocr',
'driving_license_front_ocr', 'driving_license_back_ocr',
'vehicle_license_front_ocr', 'vehicle_license_back_ocr'
];
foreach ($ocrFields as $field) {
if (isset($data[$field])) {
if (is_array($data[$field])) {
$jsonStr = json_encode($data[$field], JSON_UNESCAPED_UNICODE);
} else {
$jsonStr = $data[$field];
}
$data[$field] = $jsonStr ?: null;
}
}
return $data;
}
/**
* Helper to decrypt sensitive fields in a record (simplified to plain text)
*/
public static function decryptRecord(?array $record): ?array
{
if (!$record) return null;
$ocrFields = [
'id_front_ocr', 'id_back_ocr',
'driving_license_front_ocr', 'driving_license_back_ocr',
'vehicle_license_front_ocr', 'vehicle_license_back_ocr'
];
foreach ($ocrFields as $field) {
if (!empty($record[$field])) {
$record[$field] = json_decode($record[$field], true);
}
}
return $record;
}
/**
* Ensure the driver_ocr_data table exists dynamically
*/
public static function ensureTableExists(): void
{
static $checked = false;
if ($checked) return;
try {
Database::execute("
CREATE TABLE IF NOT EXISTS `driver_ocr_data` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`company_id` INT NOT NULL,
`phone` VARCHAR(512) NOT NULL,
`phone_hash` VARCHAR(64) NOT NULL,
`name` VARCHAR(512) NOT NULL,
`id_front_url` VARCHAR(512) DEFAULT NULL,
`id_front_ocr` TEXT DEFAULT NULL,
`id_back_url` VARCHAR(512) DEFAULT NULL,
`id_back_ocr` TEXT DEFAULT NULL,
`driving_license_front_url` VARCHAR(512) DEFAULT NULL,
`driving_license_front_ocr` TEXT DEFAULT NULL,
`driving_license_back_url` VARCHAR(512) DEFAULT NULL,
`driving_license_back_ocr` TEXT DEFAULT NULL,
`vehicle_license_front_url` VARCHAR(512) DEFAULT NULL,
`vehicle_license_front_ocr` TEXT DEFAULT NULL,
`vehicle_license_back_url` VARCHAR(512) DEFAULT NULL,
`vehicle_license_back_ocr` TEXT DEFAULT NULL,
`criminal_record_url` VARCHAR(512) DEFAULT NULL,
`status` VARCHAR(50) NOT NULL DEFAULT 'pending',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY `unique_company_driver_phone` (`company_id`, `phone_hash`),
FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
");
$checked = true;
} catch (\Exception $e) {
error_log("Failed to ensure driver_ocr_data table: " . $e->getMessage());
}
}
}