Files
WP-LIT-MCP/src/Limits.php
T
janniclas.loosenandClaude Opus 5.5 097fef2e32 fix: final review minors m-1 to m-8
- m-1: the no-change Divi result carries preview_url/edit_url too
- m-2: overview names replace-text's per-page tree_rev
- m-3: divi-shortform documents validation_failed vs not_found for unknown IDs
- m-4: DiviWriter/DiviPageLoader final (no mocks left), neutral NewDraft
  log detail, snapshots are Etappe 4
- m-5: Tested up to 7.1, changelog completed
- m-6: content-create warns when the extras changed the stored layout
- m-7: deleting a whole section outlines nothing instead of the next one
- m-8: uninstall removes the user meta lit_mcp_log_per_page; readme lists it

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

92 lines
2.7 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;
defined('ABSPATH') || exit;
/**
* 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 4, spec §12); 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;
}
}