Files
API-KTA/app/Helpers/device_helper.php
2026-04-25 04:41:23 +07:00

335 lines
12 KiB
PHP

<?php
use Detection\MobileDetect;
if (!function_exists('detectDeviceInfo')) {
/**
* Deteksi informasi device menggunakan Mobile Detect Library
*
* @param string|null $userAgent User agent string (opsional)
* @return array Device information
*/
function detectDeviceInfo($userAgent = null)
{
$detect = new MobileDetect();
if ($userAgent !== null) {
$detect->setUserAgent($userAgent);
}
$ua = $detect->getUserAgent();
// === DETECT BRAND ===
$brand = 'Unknown';
// CEK BRAND SPESIFIK DULU
if (preg_match('/POCO/i', $ua)) {
$brand = 'POCO';
} elseif (preg_match('/Redmi/i', $ua)) {
$brand = 'Redmi';
} elseif (preg_match('/Infinix/i', $ua)) {
$brand = 'Infinix';
} elseif (preg_match('/Samsung|SM-|GT-|SCH-/i', $ua)) {
$brand = 'Samsung';
} elseif (preg_match('/OPPO|CPH/i', $ua)) {
$brand = 'Oppo';
} elseif (preg_match('/vivo|V\d{4}/i', $ua)) {
$brand = 'Vivo';
} elseif (preg_match('/Realme|RMX/i', $ua)) {
$brand = 'Realme';
} else {
$androidBrands = [
'Xiaomi', 'Huawei', 'OnePlus', 'Asus', 'Nokia', 'Sony',
'Motorola', 'LG', 'Lenovo', 'Tecno',
'Google', 'HTC', 'Meizu', 'ZTE'
];
foreach ($androidBrands as $b) {
if ($detect->is($b)) {
$brand = $b;
break;
}
}
}
// Detect iPhone & iPad
if ($detect->isiOS() && !$detect->isTablet()) {
$brand = 'iPhone';
} elseif ($detect->isiOS() && $detect->isTablet()) {
$brand = 'iPad';
}
// === DETECT MODEL ===
$model = 'Unknown';
// Samsung models
if ($brand === 'Samsung') {
if (preg_match('/(SM-[A-Z]\d{3,4}[A-Z]?|GT-[A-Z0-9]+|SCH-[A-Z0-9]+)/i', $ua, $matches)) {
$model = $matches[1];
}
}
// ⭐ FIX: POCO models - bisa berupa nama atau kode angka
elseif ($brand === 'POCO') {
// Cari pattern: POCO [nama model] atau kode angka (contoh: 21121210G)
if (preg_match('/POCO\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
$model = 'POCO ' . trim($matches[1]);
}
// Jika tidak ada nama POCO, cari kode angka Xiaomi
elseif (preg_match('/\s([0-9]{8,9}[A-Z]?)(?:\s+Build)/i', $ua, $matches)) {
$model = $matches[1] . ' (POCO)';
}
}
// Redmi models
elseif ($brand === 'Redmi') {
if (preg_match('/Redmi\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
$model = 'Redmi ' . trim($matches[1]);
}
// Fallback: kode angka
elseif (preg_match('/\s([0-9]{8,9}[A-Z]?)(?:\s+Build)/i', $ua, $matches)) {
$model = $matches[1] . ' (Redmi)';
}
}
// Xiaomi models
elseif ($brand === 'Xiaomi') {
if (preg_match('/Mi\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
$model = 'Mi ' . trim($matches[1]);
}
// Fallback: kode angka
elseif (preg_match('/\s([0-9]{8,9}[A-Z]?)(?:\s+Build)/i', $ua, $matches)) {
$model = $matches[1] . ' (Xiaomi)';
}
}
// Infinix models
elseif ($brand === 'Infinix') {
if (preg_match('/Infinix\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
$model = 'Infinix ' . trim($matches[1]);
}
elseif (preg_match('/(X\d{3,4}[A-Z]?)/i', $ua, $matches)) {
$model = $matches[1];
}
}
// Oppo models
elseif ($brand === 'Oppo') {
if (preg_match('/(CPH\d+|PBAM\d+|PBEM\d+)/i', $ua, $matches)) {
$model = $matches[1];
}
elseif (preg_match('/OPPO\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
$model = 'OPPO ' . trim($matches[1]);
}
}
// Vivo models
elseif ($brand === 'Vivo') {
if (preg_match('/(V\d{4})/i', $ua, $matches)) {
$model = $matches[1];
}
elseif (preg_match('/vivo\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
$model = 'vivo ' . trim($matches[1]);
}
}
// Realme models
elseif ($brand === 'Realme') {
if (preg_match('/(RMX\d+)/i', $ua, $matches)) {
$model = $matches[1];
}
elseif (preg_match('/Realme\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
$model = 'Realme ' . trim($matches[1]);
}
}
// iPhone models
elseif ($brand === 'iPhone') {
if (preg_match('/iPhone(\d+[,\d]*)?/i', $ua, $matches)) {
$model = 'iPhone' . ($matches[1] ? ' ' . str_replace(',', '.', $matches[1]) : '');
} else {
$model = 'iPhone';
}
}
// iPad models
elseif ($brand === 'iPad') {
if (preg_match('/iPad[\d,]*;/i', $ua, $matches)) {
$model = trim(str_replace(';', '', $matches[0]));
}
}
// === DETECT OS & VERSION ===
$os = 'Unknown';
$osVersion = 'Unknown';
if ($detect->isiOS()) {
$os = 'iOS';
$osVersion = $detect->version('iOS') ?: 'Unknown';
} elseif ($detect->isAndroidOS()) {
$os = 'Android';
$osVersion = $detect->version('Android') ?: 'Unknown';
} elseif (preg_match('/Windows/i', $ua)) {
$os = 'Windows';
if (preg_match('/Windows NT ([0-9\.]+)/i', $ua, $matches)) {
$osVersion = $matches[1];
}
}
// === DETECT BROWSER ===
$browser = 'Unknown';
$browserVersion = 'Unknown';
// Chrome
if (preg_match('/Chrome\/([0-9\.]+)/i', $ua, $matches)) {
$browser = 'Chrome';
$browserVersion = $matches[1];
}
// Safari (non-Chrome)
elseif (preg_match('/Safari\/([0-9\.]+)/i', $ua, $matches) && !preg_match('/Chrome/i', $ua)) {
$browser = 'Safari';
if (preg_match('/Version\/([0-9\.]+)/i', $ua, $vMatches)) {
$browserVersion = $vMatches[1];
}
}
// Firefox
elseif (preg_match('/Firefox\/([0-9\.]+)/i', $ua, $matches)) {
$browser = 'Firefox';
$browserVersion = $matches[1];
}
// === DEVICE TYPE ===
$deviceType = 'desktop';
if ($detect->isTablet()) {
$deviceType = 'tablet';
} elseif ($detect->isMobile()) {
$deviceType = 'phone';
}
return [
'brand' => $brand,
'model' => $model,
'os' => $os,
'os_version' => $osVersion,
'browser' => $browser,
'browser_version' => $browserVersion,
'device_type' => $deviceType,
'is_mobile' => $detect->isMobile(),
'is_tablet' => $detect->isTablet(),
'is_phone' => $detect->isMobile() && !$detect->isTablet(),
'user_agent' => $ua
];
}
}
if (!function_exists('getCameraVersionSupport')) {
/**
* Get camera version support untuk device tertentu
*
* @param string $deviceBrand Brand device (Samsung, POCO, dll)
* @param string $deviceModel Model device (SM-S931B, POCO X5, dll)
* @return array Camera version support info
*/
function getCameraVersionSupport($deviceBrand, $deviceModel)
{
$db = \Config\Database::connect();
// Cek apakah ada mapping SPESIFIK untuk model ini
$compatibility = $db->table('device_camera_compatibility')
->where('device_brand', $deviceBrand)
->where('device_model', $deviceModel)
->where('is_active', true)
->get()
->getRow();
// Jika tidak ada, cek mapping untuk BRAND (device_model = NULL)
if (!$compatibility) {
$compatibility = $db->table('device_camera_compatibility')
->where('device_brand', $deviceBrand)
->where('device_model', null)
->where('is_active', true)
->get()
->getRow();
}
// JIKA TIDAK ADA DI DATABASE = SUPPORT SEMUA VERSI (DEFAULT)
if (!$compatibility) {
return [
'support_version_1' => true,
'support_version_2' => true,
'support_version_3' => true,
'recommended_version' => 3, // Recommend versi tertinggi
'available_versions' => [1, 2, 3],
'notes' => 'Device tidak ada limitasi - support semua versi kamera',
'is_default' => true // Flag untuk tahu ini default behavior
];
}
// Build available versions array
$availableVersions = [];
if ($compatibility->support_version_1) $availableVersions[] = 1;
if ($compatibility->support_version_2) $availableVersions[] = 2;
if ($compatibility->support_version_3) $availableVersions[] = 3;
return [
'support_version_1' => (bool)$compatibility->support_version_1,
'support_version_2' => (bool)$compatibility->support_version_2,
'support_version_3' => (bool)$compatibility->support_version_3,
'recommended_version' => $compatibility->recommended_version,
'available_versions' => $availableVersions,
'notes' => $compatibility->notes,
'is_default' => false // Ini bukan default, ada di database
];
}
}
if (!function_exists('getDeviceFingerprint')) {
function getDeviceFingerprint($userAgent, $ipAddress)
{
return md5($userAgent . '|' . $ipAddress);
}
}
if (!function_exists('isDeviceTrusted')) {
/**
* Cek apakah device sudah dipercaya
*
* @param string $deviceFingerprint
* @param string $superUserId
* @return bool
*/
function isDeviceTrusted($deviceFingerprint, $superUserId)
{
$db = \Config\Database::connect();
$device = $db->table('user_devices')
->where('device_fingerprint', $deviceFingerprint)
->where('super_user_id', $superUserId)
->where('is_trusted', true)
->where('is_blocked', false)
->get()
->getRow();
return $device !== null;
}
}
if (!function_exists('isDeviceBlocked')) {
/**
* Cek apakah device diblokir
*
* @param string $deviceFingerprint
* @return array|null Device info if blocked, null otherwise
*/
function isDeviceBlocked($deviceFingerprint)
{
$db = \Config\Database::connect();
$device = $db->table('user_devices')
->where('device_fingerprint', $deviceFingerprint)
->where('is_blocked', true)
->get()
->getRow();
if ($device) {
return [
'is_blocked' => true,
'reason' => $device->blocked_reason,
'blocked_at' => $device->blocked_at
];
}
return null;
}
}