Complete port of all 163 API endpoints from Lucee/CFML to PHP 8.3. Shared helpers in api/helpers.php (DB, auth, request/response, security). PDO prepared statements throughout. Same JSON response shapes as CFML.
103 lines
3.6 KiB
PHP
103 lines
3.6 KiB
PHP
<?php
|
|
/**
|
|
* Grant utility functions for SP-SM enforcement.
|
|
* Include this file where grant time/eligibility checks are needed.
|
|
*/
|
|
|
|
/**
|
|
* Check if a grant's time policy is currently active.
|
|
*/
|
|
function isGrantTimeActive(string $timePolicyType, $timePolicyData = ''): bool {
|
|
if ($timePolicyType === 'always') return true;
|
|
|
|
$policy = [];
|
|
if (is_string($timePolicyData) && trim($timePolicyData) !== '') {
|
|
$policy = json_decode($timePolicyData, true);
|
|
if (!is_array($policy)) return false;
|
|
} elseif (is_array($timePolicyData)) {
|
|
$policy = $timePolicyData;
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
$now = new DateTime('now', new DateTimeZone('UTC'));
|
|
|
|
switch ($timePolicyType) {
|
|
case 'schedule':
|
|
// policy: { days: [1,2,3,4,5], startTime: "09:00", endTime: "17:00" }
|
|
// days: 1=Sunday, 2=Monday, ... 7=Saturday (CF dayOfWeek convention)
|
|
if (!isset($policy['days']) || !is_array($policy['days'])) return false;
|
|
// PHP: Sunday=0, CF: Sunday=1. Convert PHP dow to CF convention.
|
|
$todayDow = (int) $now->format('w') + 1; // 1=Sunday .. 7=Saturday
|
|
if (!in_array($todayDow, $policy['days'])) return false;
|
|
if (isset($policy['startTime'], $policy['endTime'])) {
|
|
$currentTime = $now->format('H:i');
|
|
if ($currentTime < $policy['startTime'] || $currentTime > $policy['endTime']) return false;
|
|
}
|
|
return true;
|
|
|
|
case 'date_range':
|
|
// policy: { start: "2026-03-01", end: "2026-06-30" }
|
|
if (!isset($policy['start'], $policy['end'])) return false;
|
|
$today = $now->format('Y-m-d');
|
|
return ($today >= $policy['start'] && $today <= $policy['end']);
|
|
|
|
case 'event':
|
|
// policy: { name: "...", start: "2026-07-04 10:00", end: "2026-07-04 22:00" }
|
|
if (!isset($policy['start'], $policy['end'])) return false;
|
|
$nowStr = $now->format('Y-m-d H:i');
|
|
return ($nowStr >= $policy['start'] && $nowStr <= $policy['end']);
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Record a grant history entry.
|
|
*/
|
|
function recordGrantHistory(
|
|
int $grantID,
|
|
string $action,
|
|
int $actorUserID,
|
|
int $actorBusinessID,
|
|
array $previousData = [],
|
|
array $newData = []
|
|
): void {
|
|
queryTimed(
|
|
"INSERT INTO ServicePointGrantHistory (GrantID, Action, ActorUserID, ActorBusinessID, PreviousData, NewData, CreatedOn)
|
|
VALUES (?, ?, ?, ?, ?, ?, NOW())",
|
|
[
|
|
$grantID,
|
|
$action,
|
|
$actorUserID,
|
|
$actorBusinessID,
|
|
!empty($previousData) ? json_encode($previousData) : null,
|
|
!empty($newData) ? json_encode($newData) : null,
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if a user meets the eligibility scope for a grant.
|
|
*/
|
|
function checkGrantEligibility(string $eligibilityScope, int $userID, int $ownerBusinessID, int $guestBusinessID): bool {
|
|
if ($eligibilityScope === 'public') return true;
|
|
|
|
$isGuestEmployee = (bool) queryOne(
|
|
"SELECT 1 FROM Employees WHERE BusinessID = ? AND UserID = ? AND IsActive = 1 LIMIT 1",
|
|
[$guestBusinessID, $userID]
|
|
);
|
|
|
|
$isOwnerEmployee = (bool) queryOne(
|
|
"SELECT 1 FROM Employees WHERE BusinessID = ? AND UserID = ? AND IsActive = 1 LIMIT 1",
|
|
[$ownerBusinessID, $userID]
|
|
);
|
|
|
|
switch ($eligibilityScope) {
|
|
case 'employees': return $isGuestEmployee;
|
|
case 'guests': return (!$isGuestEmployee && !$isOwnerEmployee);
|
|
case 'internal': return $isOwnerEmployee;
|
|
default: return false;
|
|
}
|
|
}
|