- Implemented PayPal webhook for handling payment notifications, including signature verification and transaction updates. - Created invoice generation and license management for software upgrades upon successful payment. - Added comprehensive logging for debugging purposes. - Introduced new CSS styles for the marketing file management system, including layout, toolbar, breadcrumb navigation, search filters, and file management UI components.
476 lines
21 KiB
PHP
476 lines
21 KiB
PHP
<?php
|
|
defined($security_key) or exit;
|
|
ini_set('display_errors', '1');
|
|
ini_set('display_startup_errors', '1');
|
|
error_reporting(E_ALL);
|
|
//------------------------------------------
|
|
// Products Software Upgrades API
|
|
//------------------------------------------
|
|
|
|
//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, HANDLE UPGRADE OPTIONS
|
|
if (isset($criterias['sn']) && $criterias['sn'] != ''){
|
|
|
|
//default output (array of options)
|
|
$output = [];
|
|
|
|
//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_license' => $sw_version_license,
|
|
'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 = ["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 || $current_sw_version == '' || $normalized_upgrade_version != $current_sw_version) {
|
|
// Override version is different from current (or no current) - return only this upgrade
|
|
$output[] = [
|
|
"productcode" => $productcode,
|
|
"name" => $upgrade_version['name'] ?? '',
|
|
"version" => $upgrade_version['version'],
|
|
"version_id" => $upgrade_version['version_id'],
|
|
"description" => $upgrade_version['description'] ?? '',
|
|
"hw_version" => $upgrade_version['hw_version'] ?? '',
|
|
"mandatory" => $upgrade_version['mandatory'] ?? '',
|
|
"latest" => $upgrade_version['latest'] ?? '',
|
|
"software" => $upgrade_version['file_path'] ?? '',
|
|
"source" => '',
|
|
"source_type" => '',
|
|
"price" => '0.00',
|
|
"currency" => '',
|
|
"is_current" => false
|
|
];
|
|
|
|
// Generate download token
|
|
$download_token = create_download_url_token($criterias['sn'], $upgrade_version['version_id']);
|
|
$download_url = 'https://'.$_SERVER['SERVER_NAME'].'/api.php/v2/software_download?token='.$download_token;
|
|
$output[0]['source'] = $download_url;
|
|
$output[0]['source_type'] = 'token_url';
|
|
|
|
if (debug) {
|
|
$debug['sw_version_upgrade_check']['decision'] = 'Override version returned as only upgrade';
|
|
$output[0]['_debug'] = $debug;
|
|
}
|
|
} else {
|
|
// Override version is same as current - no upgrades
|
|
if (debug) {
|
|
$debug['sw_version_upgrade_check']['decision'] = 'Override version is same as current version - no upgrades';
|
|
$output = ['message' => 'No upgrades available', 'debug' => $debug];
|
|
}
|
|
}
|
|
|
|
$messages = $output;
|
|
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.latest = 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)) {
|
|
$messages = ["error" => "No active software assignments found for product"];
|
|
if (debug) {
|
|
$messages['debug'] = $debug;
|
|
}
|
|
} else {
|
|
// First check if current version has paid upgrade paths FROM it
|
|
$has_paid_upgrade_from_current = false;
|
|
if ($current_sw_version) {
|
|
$sql = 'SELECT COUNT(*) as paid_count
|
|
FROM products_software_upgrade_paths pup
|
|
JOIN products_software_versions from_ver ON pup.from_version_id = from_ver.rowID
|
|
WHERE LOWER(TRIM(LEADING "0" FROM from_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);
|
|
$has_paid_upgrade_from_current = ($paid_check['paid_count'] > 0);
|
|
}
|
|
|
|
if (debug) {
|
|
$debug['has_paid_upgrade_from_current'] = $has_paid_upgrade_from_current;
|
|
$debug['version_decisions'] = [];
|
|
}
|
|
|
|
foreach ($versions as $version) {
|
|
//Normalize version for comparison (lowercase, trim leading zeros)
|
|
$normalized_version = strtolower(ltrim($version['version'], '0'));
|
|
|
|
$is_current_version = ($current_sw_version && $normalized_version == $current_sw_version);
|
|
|
|
//All versions with matching HW are potential upgrades
|
|
$show_version = false;
|
|
$final_price = '0.00';
|
|
$final_currency = '';
|
|
$is_current = false;
|
|
$decision_reason = '';
|
|
|
|
if (debug) {
|
|
$version_debug = [
|
|
'version' => $version['version'],
|
|
'name' => $version['name'],
|
|
'normalized_version' => $normalized_version,
|
|
'is_current_version' => $is_current_version,
|
|
'latest' => $version['latest']
|
|
];
|
|
}
|
|
|
|
if (!$current_sw_version || $current_sw_version == '') {
|
|
//No current version - show all as free upgrades
|
|
if (!$is_current_version) {
|
|
$show_version = true;
|
|
$decision_reason = 'No current version stored - showing as free upgrade';
|
|
} else {
|
|
$decision_reason = 'Skipped - is current version but no upgrades scenario';
|
|
}
|
|
} else {
|
|
//Check if this is the current version - always show it
|
|
if ($is_current_version) {
|
|
$show_version = true;
|
|
$is_current = true;
|
|
$final_price = '0.00';
|
|
$final_currency = '';
|
|
$decision_reason = 'Showing as CURRENT - always show current version';
|
|
} else if (!$is_current_version) {
|
|
//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_debug['upgrade_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 = 'Showing as FREE - no upgrade paths defined for this version';
|
|
} 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)) = ?
|
|
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';
|
|
$final_currency = $upgrade_path['currency'] ?? '';
|
|
$decision_reason = 'Showing - found upgrade path FROM current (' . $current_sw_version . ') with price: ' . $final_price . ' ' . $final_currency;
|
|
} else {
|
|
$decision_reason = 'Skipped - has upgrade paths but none FROM current version (' . $current_sw_version . ')';
|
|
}
|
|
//If no path from current version exists, don't show (show_version stays false)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (debug) {
|
|
$version_debug['decision'] = [
|
|
'show_version' => $show_version,
|
|
'is_current' => $is_current,
|
|
'final_price' => $final_price,
|
|
'final_currency' => $final_currency,
|
|
'reason' => $decision_reason
|
|
];
|
|
}
|
|
|
|
if ($show_version) {
|
|
//Check if there's a valid license for this upgrade
|
|
$license_applied = false;
|
|
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)) {
|
|
$original_price = $final_price;
|
|
$final_price = '0.00';
|
|
$license_applied = true;
|
|
|
|
if (debug) {
|
|
$version_debug['license_applied'] = [
|
|
'license_key' => $sw_version_license,
|
|
'original_price' => $original_price,
|
|
'new_price' => $final_price
|
|
];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$output[] = [
|
|
"productcode" => $productcode,
|
|
"name" => $version['name'] ?? '',
|
|
"version" => $version['version'],
|
|
"version_id" => $version['version_id'],
|
|
"description" => $version['description'] ?? '',
|
|
"hw_version" => $version['hw_version'] ?? '',
|
|
"mandatory" => $version['mandatory'] ?? '',
|
|
"latest" => $version['latest'] ?? '',
|
|
"software" => $version['file_path'] ?? '',
|
|
"source" => '',
|
|
"source_type" => '',
|
|
"price" => $final_price,
|
|
"currency" => $final_currency,
|
|
"is_current" => $is_current
|
|
];
|
|
}
|
|
|
|
if (debug) {
|
|
$debug['version_decisions'][] = $version_debug;
|
|
}
|
|
}
|
|
|
|
//GENERATE DOWNLOAD TOKENS FOR EACH OPTION
|
|
foreach ($output as &$option) {
|
|
// Generate time-based download token
|
|
$download_token = create_download_url_token($criterias['sn'], $option['version_id']);
|
|
|
|
// Create secure download URL
|
|
$download_url = 'https://'.$_SERVER['SERVER_NAME'].'/api.php/v2/software_download?token='.$download_token;
|
|
|
|
// Set source as download URL
|
|
$option['source'] = $download_url;
|
|
$option['source_type'] = 'token_url';
|
|
}
|
|
|
|
if (debug) {
|
|
$debug['final_output'] = [
|
|
'total_versions_shown' => count($output),
|
|
'versions' => array_map(function($o) {
|
|
return [
|
|
'name' => $o['name'],
|
|
'version' => $o['version'],
|
|
'price' => $o['price'],
|
|
'is_current' => $o['is_current']
|
|
];
|
|
}, $output)
|
|
];
|
|
}
|
|
|
|
$messages = $output;
|
|
|
|
if (debug && !empty($output)) {
|
|
// Add debug as separate field in response
|
|
foreach ($messages as &$msg) {
|
|
$msg['_debug'] = $debug;
|
|
break; // Only add to first item
|
|
}
|
|
} elseif (debug && empty($output)) {
|
|
$messages = ['message' => 'No upgrades available', 'debug' => $debug];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$messages = ["error" => "No serialnumber found"];
|
|
}
|
|
//Encrypt results
|
|
$messages = json_encode($messages, JSON_UNESCAPED_UNICODE);
|
|
|
|
//Send results
|
|
echo $messages;
|
|
|
|
?>
|