You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.4 KiB

3 weeks ago
<?php
namespace App\Support;
use App\Models\Competition;
/**
* 报名表 schema 中「文件」类型字段的扩展名与数量限制与选手端、ApplicationFileController 一致)。
*/
final class SignupFormFileRules
{
/**
* @return array<string, mixed>|null
*/
public static function fileFieldRow(?Competition $competition, string $fieldKey): ?array
{
if ($competition === null) {
return null;
}
$competition->loadMissing('formSchema');
$rows = $competition->formSchema?->schema_json;
if (! is_array($rows)) {
return null;
}
foreach ($rows as $row) {
if (! is_array($row)) {
continue;
}
if (($row['key'] ?? '') === $fieldKey && ($row['type'] ?? '') === 'file') {
return $row;
}
}
return null;
}
/**
* 有效扩展名:未配置 file_extensions 时用全局白名单;配置时与全局白名单求交集。
*
* @param array<string, mixed>|null $row
* @return list<string>
*/
public static function effectiveAllowedExtensions(?array $row): array
{
/** @var list<string> $global */
$global = array_values(array_unique(array_filter(array_map(
static fn ($x) => strtolower(ltrim(trim((string) $x), '.')),
config('contest.file_mimes', []) ?: [],
))));
$globIndex = [];
foreach ($global as $g) {
$globIndex[$g] = true;
}
$exts = is_array($row) ? ($row['file_extensions'] ?? null) : null;
if (! is_array($exts) || count($exts) === 0) {
return $global;
}
$out = [];
foreach ($exts as $e) {
$s = strtolower(ltrim(trim((string) $e), '.'));
if ($s !== '' && isset($globIndex[$s])) {
$out[] = $s;
}
}
$out = array_values(array_unique($out));
return count($out) > 0 ? $out : $global;
}
/**
* @param array<string, mixed>|null $row
*/
public static function maxCount(?array $row): ?int
{
if (! is_array($row) || ! array_key_exists('file_max_count', $row)) {
return null;
}
$n = $row['file_max_count'];
if ($n === null || $n === '') {
return null;
}
$i = (int) $n;
return $i >= 1 ? $i : null;
}
}