Files
huntingclubroster/classes/ClubResources.php

17 lines
1.3 KiB
PHP

<?php
/** Atomic shared club budgets, independent of the member who submits work. */
class ClubResources extends Base {
public function consume(int $club,string $resource): void {
$defaults=['email'=>100,'ticket'=>100,'reply'=>1000,'export'=>20];
if(!isset($defaults[$resource]))throw new LogicException('Unknown club resource.');
(new RosterService())->club($club);
$raw=getenv('HCR_CLUB_'.strtoupper($resource).'_HOURLY');
$limit=$raw===false?$defaults[$resource]:filter_var($raw,FILTER_VALIDATE_INT,['options'=>['min_range'=>1,'max_range'=>100000]]);
if($limit===false)throw new RuntimeException('Invalid club resource limit.');
$db=$this->connect();
$stmt=$db->prepare("INSERT INTO club_resource_usage(club_serial,resource_name,window_started,used_count) VALUES(?,?,UTC_TIMESTAMP(),LAST_INSERT_ID(1)) ON DUPLICATE KEY UPDATE used_count=LAST_INSERT_ID(IF(window_started<=DATE_SUB(UTC_TIMESTAMP(),INTERVAL 1 HOUR),1,LEAST(used_count+1,100001))),window_started=IF(window_started<=DATE_SUB(UTC_TIMESTAMP(),INTERVAL 1 HOUR),UTC_TIMESTAMP(),window_started)");$stmt->execute([$club,$resource]);
$stmt=$db->query('SELECT LAST_INSERT_ID()');
if((int)$stmt->fetchColumn()>$limit)throw new AppException('This club has reached its hourly '.$resource.' limit. Try again later.',429);
}
}