Files
assetmgt/includes/version_access.php
“VeLiTi” 9673d9be7b Implement Software Upgrade Management API and Frontend Functionality
- Added software.php for managing software versions, including download and purchase actions.
- Created upgrade_paths.php for handling upgrade paths management.
- Developed user_licenses.php for managing user licenses.
- Introduced version_access_rules.php for managing access rules for software versions.
- Implemented frontend functions in functions.js for interacting with the software upgrade API.
- Added version_access.php for user access validation and license management.
- Created upgrades.php for displaying available upgrades and handling user interactions.
- Enhanced UI with responsive design and progress indicators for downloads and purchases.
2025-12-11 15:32:18 +01:00

282 lines
8.3 KiB
PHP

<?php
function getUserOwnedVersions($userId) {
global $pdo;
$stmt = $pdo->prepare("
SELECT sv.*, ul.license_key, ul.purchased_at
FROM user_licenses ul
JOIN software_versions sv ON ul.version_id = sv.id
WHERE ul.user_id = ? AND ul.status = 'active'
ORDER BY sv.major_version DESC, sv.minor_version DESC
");
$stmt->execute([$userId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function getLatestOwnedVersion($userId) {
$versions = getUserOwnedVersions($userId);
return !empty($versions) ? $versions[0] : null;
}
function checkVersionAccess($userId, $versionId) {
global $pdo;
// Get version and its access rules
$stmt = $pdo->prepare("
SELECT sv.*, var.access_type, var.requires_base_version, var.price
FROM software_versions sv
JOIN version_access_rules var ON sv.id = var.version_id
WHERE sv.id = ?
");
$stmt->execute([$versionId]);
$version = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$version) {
return ['accessible' => false, 'reason' => 'Version not found'];
}
switch ($version['access_type']) {
case 'free_all':
// Free for everyone (like v0.99)
return [
'accessible' => true,
'reason' => 'free_for_all',
'price' => 0.00,
'requires_payment' => false
];
case 'free_for_owners':
// Free for owners of required base version (like v1.1 for v1.0 owners)
if ($version['requires_base_version']) {
$hasBaseVersion = userOwnsVersion($userId, $version['requires_base_version']);
if ($hasBaseVersion) {
return [
'accessible' => true,
'reason' => 'free_upgrade',
'price' => 0.00,
'requires_payment' => false
];
} else {
return [
'accessible' => false,
'reason' => 'requires_base_version',
'required_version' => $version['requires_base_version'],
'price' => $version['price'],
'requires_payment' => true
];
}
}
return ['accessible' => false, 'reason' => 'invalid_access_rule'];
case 'paid':
case 'paid_upgrade':
// Check if user already owns this version
if (userOwnsVersionById($userId, $versionId)) {
return [
'accessible' => true,
'reason' => 'already_owned',
'price' => 0.00,
'requires_payment' => false
];
}
// Check for upgrade pricing
$upgradeInfo = getUpgradePrice($userId, $versionId);
return [
'accessible' => false,
'reason' => 'requires_purchase',
'price' => $upgradeInfo['price'],
'original_price' => $version['price'],
'is_upgrade' => $upgradeInfo['is_upgrade'],
'requires_payment' => true
];
default:
return ['accessible' => false, 'reason' => 'unknown_access_type'];
}
}
function userOwnsVersion($userId, $version) {
global $pdo;
$stmt = $pdo->prepare("
SELECT COUNT(*)
FROM user_licenses ul
JOIN software_versions sv ON ul.version_id = sv.id
WHERE ul.user_id = ? AND sv.version = ? AND ul.status = 'active'
");
$stmt->execute([$userId, $version]);
return $stmt->fetchColumn() > 0;
}
function userOwnsVersionById($userId, $versionId) {
global $pdo;
$stmt = $pdo->prepare("
SELECT COUNT(*)
FROM user_licenses
WHERE user_id = ? AND version_id = ? AND status = 'active'
");
$stmt->execute([$userId, $versionId]);
return $stmt->fetchColumn() > 0;
}
function getUpgradePrice($userId, $targetVersionId) {
global $pdo;
// Get user's owned versions
$ownedVersions = getUserOwnedVersions($userId);
if (empty($ownedVersions)) {
// No owned versions, return full price
$stmt = $pdo->prepare("
SELECT var.price
FROM version_access_rules var
WHERE var.version_id = ?
");
$stmt->execute([$targetVersionId]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return [
'price' => $result['price'] ?? 0.00,
'is_upgrade' => false
];
}
// Check for upgrade paths
$bestUpgradePrice = null;
$fromVersion = null;
foreach ($ownedVersions as $ownedVersion) {
$stmt = $pdo->prepare("
SELECT upgrade_price, is_free
FROM upgrade_paths
WHERE from_version_id = ? AND to_version_id = ?
");
$stmt->execute([$ownedVersion['id'], $targetVersionId]);
$upgrade = $stmt->fetch(PDO::FETCH_ASSOC);
if ($upgrade) {
if ($upgrade['is_free']) {
return [
'price' => 0.00,
'is_upgrade' => true,
'from_version' => $ownedVersion['version']
];
}
if ($bestUpgradePrice === null || $upgrade['upgrade_price'] < $bestUpgradePrice) {
$bestUpgradePrice = $upgrade['upgrade_price'];
$fromVersion = $ownedVersion['version'];
}
}
}
if ($bestUpgradePrice !== null) {
return [
'price' => $bestUpgradePrice,
'is_upgrade' => true,
'from_version' => $fromVersion
];
}
// No upgrade path, return full price
$stmt = $pdo->prepare("
SELECT var.price
FROM version_access_rules var
WHERE var.version_id = ?
");
$stmt->execute([$targetVersionId]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return [
'price' => $result['price'] ?? 0.00,
'is_upgrade' => false
];
}
function grantLicense($pdo, $userId, $versionId, $transactionId = null) {
// Generate unique license key
$licenseKey = generateLicenseKey($userId, $versionId);
$stmt = $pdo->prepare("
INSERT INTO user_licenses (user_id, version_id, license_key, transaction_id, status)
VALUES (?, ?, ?, ?, 'active')
ON DUPLICATE KEY UPDATE status = 'active', license_key = ?
");
return $stmt->execute([$userId, $versionId, $licenseKey, $transactionId, $licenseKey]);
}
function generateLicenseKey($userId, $versionId) {
// Generate a unique license key
$data = $userId . '-' . $versionId . '-' . time() . '-' . bin2hex(random_bytes(8));
return strtoupper(substr(hash('sha256', $data), 0, 29)); // Format: XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
}
function generateSecureDownloadToken($pdo, $userId, $versionId) {
// Generate random token
$token = bin2hex(random_bytes(32));
// Store token with expiration (5 minutes)
$expiresAt = date('Y-m-d H:i:s', time() + 300);
$stmt = $pdo->prepare(
"INSERT INTO download_tokens (token, user_id, version_id, expires_at, used)
VALUES (?, ?, ?, ?, 0)"
);
$stmt->execute([$token, $userId, $versionId, $expiresAt]);
return $token;
}
function validateUserAccess($userId, $versionId) {
global $pdo;
// Check if version requires payment
$stmt = $pdo->prepare("
SELECT var.access_type
FROM version_access_rules var
WHERE var.version_id = ?
");
$stmt->execute([$versionId]);
$accessRule = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$accessRule) {
return false;
}
if ($accessRule['access_type'] === 'free_all') {
return true; // Free for everyone
}
// Check if user has valid license
$stmt = $pdo->prepare(
"SELECT COUNT(*) FROM user_licenses
WHERE user_id = ? AND version_id = ? AND status = 'active'"
);
$stmt->execute([$userId, $versionId]);
return $stmt->fetchColumn() > 0;
}
function logDownload($pdo, $userId, $versionId) {
$stmt = $pdo->prepare("
INSERT INTO download_logs (user_id, version_id, ip_address, user_agent, downloaded_at)
VALUES (?, ?, ?, ?, NOW())
");
$stmt->execute([
$userId,
$versionId,
$_SERVER['REMOTE_ADDR'] ?? '',
$_SERVER['HTTP_USER_AGENT'] ?? ''
]);
}
?>