generated from jric11/baseProject
ChatGPT's update to harden software and run db updates.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/** Same authorized query feeds the count and bounded rows. */
|
||||
final class BoundedList {
|
||||
public static array $pages=[];
|
||||
public static bool $exporting=false;
|
||||
public static function page(string $scope): int {
|
||||
$raw=$_GET[$scope.'_page']??'1';$page=filter_var($raw,FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);
|
||||
if($page===false)throw new AppException('Choose a valid page.');return $page;
|
||||
}
|
||||
public static function rows(PDO $db,string $sql,array $args,?int $page,string $scope): array {
|
||||
if($page!==null){
|
||||
$stmt=$db->prepare('SELECT COUNT(*) FROM ('.$sql.') scoped_rows');$stmt->execute($args);$count=(int)$stmt->fetchColumn();
|
||||
$paging=Pagination::calculate($count,25,$page);self::$pages[$scope]=$paging+['count'=>$count,'pages'=>max(1,(int)ceil($count/25))];
|
||||
$sql.=' LIMIT '.$paging['size'].' OFFSET '.$paging['offset'];
|
||||
}
|
||||
if($page===null&&self::$exporting)$sql.=' LIMIT '.(self::exportLimit()+1);
|
||||
$stmt=$db->prepare($sql);$stmt->execute($args);$rows=$stmt->fetchAll();
|
||||
if(self::$exporting&&count($rows)>self::exportLimit())throw new AppException('This export exceeds the configured row limit.',422);
|
||||
return $rows;
|
||||
}
|
||||
public static function navigation(string $scope,?string $action=null): string {
|
||||
$p=self::$pages[$scope]??null;if(!$p)return '';
|
||||
$h=static fn($v)=>htmlspecialchars((string)$v,ENT_QUOTES,'UTF-8');$html='<nav aria-label="'.$h($scope).' pages"><p>'.$p['count'].' records. Page '.$p['page'].' of '.$p['pages'].'.</p>';
|
||||
foreach(['First'=>1,'Previous'=>$p['page']-1,'Next'=>$p['page']+1,'Last'=>$p['pages']] as $label=>$page){
|
||||
if($page<1||$page>$p['pages']||$page===$p['page'])continue;
|
||||
$args=$_GET;unset($args['action']);$args['Xaction']=$action??$args['Xaction']??'Roster.workspace';$args[$scope.'_page']=$page;
|
||||
$html.='<a class="btn btn-outline-primary me-2" href="'.$h('main.php?'.http_build_query($args)).'">'.$label.'</a>';
|
||||
}
|
||||
return $html.'</nav>';
|
||||
}
|
||||
public static function exportLimit(): int {
|
||||
$value=getenv('HCR_EXPORT_MAX_ROWS');$limit=$value===false?1000:filter_var($value,FILTER_VALIDATE_INT,['options'=>['min_range'=>1,'max_range'=>5000]]);
|
||||
if($limit===false)throw new RuntimeException('Invalid export row limit.');return $limit;
|
||||
}
|
||||
public static function exportGuard(PDO $db,string $sql,array $args): void {
|
||||
$stmt=$db->prepare($sql);$stmt->execute($args);
|
||||
if((int)$stmt->fetchColumn()>self::exportLimit())throw new AppException('This export exceeds the configured row limit. Contact support for a large export.',422);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user