Files
WP-LIT-MCP/src/Limits.php
T
janniclas.loosenandClaude Opus 5.5 d2c5e82d63 refactor: narrow over-exposed API (L2)
Composer::autoLabel is private (tested through compose()); the
DiviComposition getters used only by tests are marked @internal;
Limits::snapshotCount is documented as reserved; the ShortformWriter test
seam is named $modulesForTests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-26 18:31:51 +02:00

90 lines
2.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace LIT\MCP;
/**
* Admin-configurable limits (settings tab "Limits", spec §8.4).
*/
final class Limits
{
public const OPTION = 'lit_mcp_limits';
public const DEFAULTS = ['upload_mb' => 5, 'log_retention_days' => 90, 'snapshot_count' => 20];
/**
* Hard cap for transfers held in memory as a whole and passed through the MCP response or
* request as Base64 (lit-media-download, lit/media-upload): above it, PHP memory and the
* JSON payload become the problem, whatever upload_mb says. URL imports stream to disk
* and only use upload_mb.
*/
public const INLINE_MAX_MB = 10;
private const BOUNDS = ['upload_mb' => [1, 32], 'log_retention_days' => [1, 3650], 'snapshot_count' => [1, 100]];
public function uploadBytes(): int
{
return $this->uploadMegabytes() * 1024 * 1024;
}
public function uploadMegabytes(): int
{
return $this->all()['upload_mb'];
}
/** Limit for Base64 transfers: the upload limit, at most INLINE_MAX_MB. */
public function inlineBytes(): int
{
return $this->inlineMegabytes() * 1024 * 1024;
}
public function inlineMegabytes(): int
{
return min($this->uploadMegabytes(), self::INLINE_MAX_MB);
}
public function logRetentionDays(): int
{
return $this->all()['log_retention_days'];
}
/** Reserved for design-system snapshots (Etappe 3); LimitsTab keeps the field hidden until then. */
public function snapshotCount(): int
{
return $this->all()['snapshot_count'];
}
/** @return array{upload_mb: int, log_retention_days: int, snapshot_count: int} */
public function all(): array
{
return self::sanitize(get_option(self::OPTION, []));
}
/**
* The [min, max] each field is clamped to by sanitize() – for admin UI form attributes,
* so they can't drift from the actual bounds.
*
* @return array<string, array{int, int}>
*/
public static function bounds(): array
{
return self::BOUNDS;
}
/**
* Settings API sanitize callback: always returns all keys, clamped to their bounds.
*
* @return array{upload_mb: int, log_retention_days: int, snapshot_count: int}
*/
public static function sanitize(mixed $input): array
{
$input = is_array($input) ? $input : [];
$clean = self::DEFAULTS;
foreach (self::BOUNDS as $key => [$min, $max]) {
if (isset($input[$key]) && is_numeric($input[$key])) {
$clean[$key] = max($min, min($max, (int) $input[$key]));
}
}
return $clean;
}
}