payfrit-api/api/grants/_grantUtils.php
John Mizerek 1f81d98c52 Initial PHP API migration from CFML
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.
2026-03-14 14:26:59 -07:00

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;
}
}