452 lines
19 KiB
PHP
452 lines
19 KiB
PHP
<?php
|
|
defined($security_key) or exit;
|
|
ini_set('display_errors', '1');
|
|
ini_set('display_startup_errors', '1');
|
|
error_reporting(E_ALL);
|
|
//------------------------------------------
|
|
// Software Available Check API
|
|
// Returns boolean indicating if software updates are available
|
|
//------------------------------------------
|
|
|
|
//Connect to DB
|
|
$pdo = dbConnect($dbname);
|
|
|
|
//NEW ARRAY
|
|
$criterias = [];
|
|
$clause = '';
|
|
$debug = [];
|
|
|
|
//Check for $_GET variables and build up clause
|
|
if(isset($get_content) && $get_content!=''){
|
|
//GET VARIABLES FROM URL
|
|
$requests = explode("&", $get_content);
|
|
//Check for keys and values
|
|
foreach ($requests as $y){
|
|
$v = explode("=", $y);
|
|
//INCLUDE VARIABLES IN ARRAY
|
|
$criterias[$v[0]] = $v[1];
|
|
}
|
|
}
|
|
|
|
if (debug) {
|
|
$debug['request_parameters'] = $criterias;
|
|
$debug['timestamp'] = date('Y-m-d H:i:s');
|
|
}
|
|
|
|
// IF SN IS PROVIDED, CHECK FOR AVAILABLE UPGRADES
|
|
if (isset($criterias['sn']) && $criterias['sn'] != ''){
|
|
|
|
//default response
|
|
$software_available = "no";
|
|
|
|
//check if current version is send and update the equipment record
|
|
if(isset($criterias['version']) && $criterias['version'] !=''){
|
|
$sql = 'UPDATE equipment SET sw_version = ?, updatedby = ? WHERE serialnumber = ? ';
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([$criterias['version'],$username,$criterias['sn']]);
|
|
}
|
|
|
|
//check if current hw_version is send and update the equipment record
|
|
if(isset($criterias['hw_version']) && $criterias['hw_version'] !=''){
|
|
// Translate hardware version to standardized format
|
|
$translated_hw_version = translateDeviceHardwareVersion($criterias['hw_version']);
|
|
$sql = 'UPDATE equipment SET hw_version = ?, updatedby = ? WHERE serialnumber = ? ';
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([$translated_hw_version,$username,$criterias['sn']]);
|
|
}
|
|
|
|
//GET EQUIPMENT AND PRODUCT DATA BASED ON SERIAL NUMBER
|
|
$sql = 'SELECT
|
|
p.rowID as product_rowid,
|
|
p.productcode,
|
|
e.sw_version as current_sw_version,
|
|
e.hw_version,
|
|
e.sw_version_license,
|
|
e.sw_version_upgrade,
|
|
e.rowID as equipment_rowid
|
|
FROM equipment e
|
|
JOIN products p ON e.productrowid = p.rowID
|
|
WHERE e.serialnumber = ?';
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([$criterias['sn']]);
|
|
$equipment_data = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$equipment_data) {
|
|
$messages = ["error" => "No equipment found for serialnumber"];
|
|
} else {
|
|
$product_rowid = $equipment_data['product_rowid'];
|
|
$productcode = $equipment_data['productcode'];
|
|
$current_sw_version = $equipment_data['current_sw_version'];
|
|
$hw_version = $equipment_data['hw_version'];
|
|
$sw_version_license = $equipment_data['sw_version_license'];
|
|
$sw_version_upgrade = $equipment_data['sw_version_upgrade'];
|
|
$equipment_rowid = $equipment_data['equipment_rowid'];
|
|
|
|
if (debug) {
|
|
$debug['equipment_data'] = [
|
|
'product_rowid' => $product_rowid,
|
|
'productcode' => $productcode,
|
|
'current_sw_version_raw' => $current_sw_version,
|
|
'hw_version' => $hw_version,
|
|
'sw_version_upgrade' => $sw_version_upgrade
|
|
];
|
|
}
|
|
|
|
// Normalize software version for comparison (lowercase, trim leading zeros)
|
|
$current_sw_version = strtolower(ltrim($current_sw_version, '0'));
|
|
|
|
// Translate incoming hw_version parameter for comparison if provided
|
|
$comparison_hw_version = $hw_version;
|
|
$hw_version_from_request = null;
|
|
if(isset($criterias['hw_version']) && $criterias['hw_version'] !=''){
|
|
$hw_version_from_request = $criterias['hw_version'];
|
|
$comparison_hw_version = translateDeviceHardwareVersion($criterias['hw_version']);
|
|
}
|
|
|
|
if (debug) {
|
|
$debug['normalized_data'] = [
|
|
'current_sw_version' => $current_sw_version,
|
|
'hw_version_from_request' => $hw_version_from_request,
|
|
'comparison_hw_version' => $comparison_hw_version,
|
|
'hw_version_valid' => ($comparison_hw_version !== '')
|
|
];
|
|
}
|
|
|
|
// Check if hardware version is invalid (all zeros)
|
|
if ($hw_version_from_request && $comparison_hw_version === '') {
|
|
$messages = ["software_available" => "error", "error" => "Invalid hardware version (000000) - device may not be properly initialized"];
|
|
if (debug) {
|
|
$messages['debug'] = $debug;
|
|
}
|
|
echo json_encode($messages, JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
// Check if sw_version_upgrade is set - this overrides normal availability check
|
|
if (!empty($sw_version_upgrade)) {
|
|
if (debug) {
|
|
$debug['sw_version_upgrade_check'] = [
|
|
'sw_version_upgrade_id' => $sw_version_upgrade,
|
|
'checking_override' => true
|
|
];
|
|
}
|
|
|
|
// Check if this version exists and is active
|
|
$sql = 'SELECT
|
|
psv.rowID as version_id,
|
|
psv.version,
|
|
psv.name,
|
|
psv.description,
|
|
psv.mandatory,
|
|
psv.latest,
|
|
psv.hw_version,
|
|
psv.file_path,
|
|
psv.status
|
|
FROM products_software_versions psv
|
|
WHERE psv.rowID = ?';
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([$sw_version_upgrade]);
|
|
$upgrade_version = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($upgrade_version && $upgrade_version['status'] == 1) {
|
|
// Valid override found - check if different from current version
|
|
$normalized_upgrade_version = strtolower(ltrim($upgrade_version['version'], '0'));
|
|
|
|
if (debug) {
|
|
$debug['sw_version_upgrade_check']['found_version'] = [
|
|
'version' => $upgrade_version['version'],
|
|
'name' => $upgrade_version['name'],
|
|
'normalized' => $normalized_upgrade_version,
|
|
'status' => $upgrade_version['status'],
|
|
'is_different_from_current' => ($current_sw_version != $normalized_upgrade_version)
|
|
];
|
|
}
|
|
|
|
if ($current_sw_version && $normalized_upgrade_version == $current_sw_version) {
|
|
// Override version is same as current - no upgrade available
|
|
$software_available = "no";
|
|
if (debug) {
|
|
$debug['sw_version_upgrade_check']['decision'] = 'Override version is same as current version';
|
|
}
|
|
} else {
|
|
// Override version is different - upgrade is available
|
|
$software_available = "yes";
|
|
if (debug) {
|
|
$debug['sw_version_upgrade_check']['decision'] = 'Override version is available';
|
|
}
|
|
}
|
|
|
|
$messages = ["software_available" => $software_available];
|
|
|
|
if (debug) {
|
|
debuglog(json_encode($debug));
|
|
}
|
|
|
|
echo json_encode($messages, JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
} else {
|
|
// Override version not found or inactive - fall back to standard check
|
|
if (debug) {
|
|
$debug['sw_version_upgrade_check']['found_version'] = $upgrade_version ? 'found but inactive' : 'not found';
|
|
$debug['sw_version_upgrade_check']['decision'] = 'Falling back to standard check';
|
|
}
|
|
}
|
|
}
|
|
|
|
//GET ALL ACTIVE SOFTWARE ASSIGNMENTS for this product with matching HW version
|
|
$sql = 'SELECT
|
|
psv.rowID as version_id,
|
|
psv.version,
|
|
psv.name,
|
|
psv.description,
|
|
psv.mandatory,
|
|
psv.latest,
|
|
psv.hw_version,
|
|
psv.file_path
|
|
FROM products_software_assignment psa
|
|
JOIN products_software_versions psv ON psa.software_version_id = psv.rowID
|
|
WHERE psa.product_id = ?
|
|
AND psa.status = 1
|
|
AND (psv.hw_version = ? OR psv.hw_version IS NULL OR psv.hw_version = "")';
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([$product_rowid, $comparison_hw_version]);
|
|
$versions = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
if (debug) {
|
|
$debug['active_assignments'] = [
|
|
'count' => count($versions),
|
|
'versions' => array_map(function($v) {
|
|
return [
|
|
'version_id' => $v['version_id'],
|
|
'version' => $v['version'],
|
|
'name' => $v['name'],
|
|
'hw_version' => $v['hw_version'],
|
|
'latest' => $v['latest']
|
|
];
|
|
}, $versions)
|
|
];
|
|
}
|
|
|
|
if (empty($versions)) {
|
|
// No versions available
|
|
$software_available = "no";
|
|
if (debug) {
|
|
$debug['decision'] = 'No active software assignments found';
|
|
}
|
|
} else {
|
|
$available_upgrades = 0;
|
|
$has_priced_options = false;
|
|
$has_latest_version_different = false;
|
|
$version_details = []; // Track version details for downgrade prevention
|
|
|
|
if (debug) {
|
|
$debug['version_checks'] = [];
|
|
}
|
|
|
|
foreach ($versions as $version) {
|
|
//Normalize version for comparison (lowercase, trim leading zeros)
|
|
$normalized_version = strtolower(ltrim($version['version'], '0'));
|
|
|
|
//Skip if this is the current version
|
|
if ($current_sw_version && $normalized_version == $current_sw_version) {
|
|
continue;
|
|
}
|
|
|
|
//Check if this version should be shown (same logic as software_update)
|
|
$show_version = false;
|
|
$final_price = '0.00';
|
|
$decision_reason = '';
|
|
|
|
if (debug) {
|
|
$version_check = [
|
|
'version' => $version['version'],
|
|
'name' => $version['name'],
|
|
'normalized' => $normalized_version,
|
|
'is_current' => ($current_sw_version && $normalized_version == $current_sw_version)
|
|
];
|
|
}
|
|
|
|
if (!$current_sw_version || $current_sw_version == '') {
|
|
//No current version - show all
|
|
$show_version = true;
|
|
$decision_reason = 'No current version - showing all';
|
|
} else {
|
|
//Check if this version is part of ANY upgrade path system (either FROM or TO)
|
|
$sql = 'SELECT COUNT(*) as path_count
|
|
FROM products_software_upgrade_paths
|
|
WHERE (to_version_id = ? OR from_version_id = ?) AND is_active = 1';
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([$version['version_id'], $version['version_id']]);
|
|
$path_check = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (debug) {
|
|
$version_check['path_count'] = $path_check['path_count'];
|
|
}
|
|
|
|
if ($path_check['path_count'] == 0) {
|
|
//Not part of any upgrade path system - show as free upgrade
|
|
$show_version = true;
|
|
$decision_reason = 'No upgrade paths defined - showing as free';
|
|
} else {
|
|
//Part of an upgrade path system
|
|
//Only show if there's an explicit path FROM current version TO this version
|
|
$sql = 'SELECT pup.price, pup.currency
|
|
FROM products_software_upgrade_paths pup
|
|
JOIN products_software_versions from_ver ON pup.from_version_id = from_ver.rowID
|
|
WHERE pup.to_version_id = ?
|
|
AND (LOWER(TRIM(LEADING "0" FROM from_ver.version)) = ?
|
|
OR pup.from_version_id = 9999999)
|
|
AND pup.is_active = 1';
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([$version['version_id'], $current_sw_version]);
|
|
$upgrade_path = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($upgrade_path) {
|
|
//Valid upgrade path found FROM current version
|
|
$show_version = true;
|
|
$final_price = $upgrade_path['price'] ?? '0.00';
|
|
$decision_reason = 'Found upgrade path from current with price: ' . $final_price;
|
|
} else {
|
|
$decision_reason = 'Has upgrade paths but none from current version';
|
|
}
|
|
}
|
|
}
|
|
|
|
if (debug) {
|
|
$version_check['show_version'] = $show_version;
|
|
$version_check['reason'] = $decision_reason;
|
|
}
|
|
|
|
if ($show_version) {
|
|
$available_upgrades++;
|
|
|
|
//Check if there's a valid license for this upgrade
|
|
if ($final_price > 0 && $sw_version_license) {
|
|
//Check if the license is valid
|
|
$sql = 'SELECT status, starts_at, expires_at
|
|
FROM products_software_licenses
|
|
WHERE license_key = ?';
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([$sw_version_license]);
|
|
$license = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($license && $license['status'] == 1) {
|
|
$now = date('Y-m-d H:i:s');
|
|
$start_at = $license['starts_at'];
|
|
$expires_at = $license['expires_at'];
|
|
|
|
//Check if license is within valid date range
|
|
if ((!$start_at || $start_at <= $now) && (!$expires_at || $expires_at >= $now)) {
|
|
$final_price = '0.00';
|
|
}
|
|
}
|
|
}
|
|
|
|
// Store version details for downgrade prevention check (after license application)
|
|
$version_details[] = [
|
|
'show_version' => true,
|
|
'final_price' => $final_price
|
|
];
|
|
|
|
// Check for priced options
|
|
if ($final_price > 0) {
|
|
$has_priced_options = true;
|
|
}
|
|
|
|
// Check if there's a "latest" flagged version that's different from current
|
|
if ($version['latest'] == 1 && $normalized_version != $current_sw_version) {
|
|
$has_latest_version_different = true;
|
|
}
|
|
|
|
if (debug) {
|
|
$version_check['final_price'] = $final_price;
|
|
$version_check['has_priced_option'] = ($final_price > 0);
|
|
$version_check['is_latest_different'] = ($version['latest'] == 1 && $normalized_version != $current_sw_version);
|
|
}
|
|
}
|
|
|
|
if (debug) {
|
|
$debug['version_checks'][] = $version_check;
|
|
}
|
|
}
|
|
|
|
//PREVENT DOWNGRADE FROM PAID VERSION TO FREE VERSION (if config enabled)
|
|
if (defined('PREVENT_PAID_VERSION_DOWNGRADE') && PREVENT_PAID_VERSION_DOWNGRADE && $current_sw_version) {
|
|
// Check if user is currently on a paid version (check if there was a paid upgrade path TO current version)
|
|
$sql = 'SELECT COUNT(*) as paid_to_current
|
|
FROM products_software_upgrade_paths pup
|
|
JOIN products_software_versions to_ver ON pup.to_version_id = to_ver.rowID
|
|
WHERE LOWER(TRIM(LEADING "0" FROM to_ver.version)) = ?
|
|
AND pup.price > 0
|
|
AND pup.is_active = 1';
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([$current_sw_version]);
|
|
$paid_check = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
$is_current_paid_version = ($paid_check['paid_to_current'] > 0);
|
|
|
|
if (debug) {
|
|
$debug['downgrade_prevention'] = [
|
|
'enabled' => true,
|
|
'current_version' => $current_sw_version,
|
|
'is_current_paid_version' => $is_current_paid_version
|
|
];
|
|
}
|
|
|
|
// If current version is paid, recalculate available_upgrades excluding free versions
|
|
if ($is_current_paid_version) {
|
|
$available_upgrades_before = $available_upgrades;
|
|
$available_upgrades = 0;
|
|
|
|
// Recount only paid upgrades (exclude free versions)
|
|
foreach ($version_details as $detail) {
|
|
if ($detail['show_version'] && floatval($detail['final_price']) > 0) {
|
|
$available_upgrades++;
|
|
}
|
|
}
|
|
|
|
if (debug) {
|
|
$debug['downgrade_prevention']['available_upgrades_before'] = $available_upgrades_before;
|
|
$debug['downgrade_prevention']['available_upgrades_after'] = $available_upgrades;
|
|
$debug['downgrade_prevention']['message'] = 'Excluded free versions to prevent downgrade from paid version';
|
|
}
|
|
}
|
|
}
|
|
|
|
// Simple logic: if any upgrades are available to show, return "yes"
|
|
if ($available_upgrades > 0) {
|
|
$software_available = "yes";
|
|
$availability_reason = "Software upgrades available";
|
|
} else {
|
|
$software_available = "no";
|
|
$availability_reason = "No upgrades available";
|
|
}
|
|
|
|
if (debug) {
|
|
$debug['final_decision'] = [
|
|
'available_upgrades' => $available_upgrades,
|
|
'has_priced_options' => $has_priced_options,
|
|
'has_latest_version_different' => $has_latest_version_different,
|
|
'software_available' => $software_available,
|
|
'reason' => $availability_reason
|
|
];
|
|
}
|
|
}
|
|
|
|
$messages = ["software_available" => $software_available];
|
|
|
|
if (debug) {
|
|
debuglog(json_encode($debug));
|
|
}
|
|
}
|
|
} else {
|
|
$messages = ["error" => "No serialnumber found"];
|
|
}
|
|
|
|
//Encrypt results
|
|
$messages = json_encode($messages, JSON_UNESCAPED_UNICODE);
|
|
|
|
//Send results
|
|
echo $messages;
|
|
|
|
?>
|