From 9c6b9624a2052102b4d4054e81d4ce4d27c2f800 Mon Sep 17 00:00:00 2001 From: colorlink Date: Fri, 16 Oct 2026 02:42:36 +0000 Subject: [PATCH] =?UTF-8?q?feat(batch22):=20WP=20Rocket=20deep=20=E2=80=94?= =?UTF-8?q?=20detect,=20settings=20read/set+restore,=20purge,=20preload=20?= =?UTF-8?q?(guarded)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Q8t9GEyyLZbUQu26na1JQg --- includes/Extensions/Batch22.php | 112 ++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 includes/Extensions/Batch22.php diff --git a/includes/Extensions/Batch22.php b/includes/Extensions/Batch22.php new file mode 100644 index 0000000..b5db463 --- /dev/null +++ b/includes/Extensions/Batch22.php @@ -0,0 +1,112 @@ + 'object', 'properties' => $props]; + if ($required) $schema['required'] = $required; + return ['name' => $name, 'description' => $desc, 'scope' => $scope, + 'handler' => 'AskTamMCP\\Extensions\\Batch22::' . $method, 'inputSchema' => $schema]; + }; + + $registry->register($def('rocket_detect', 'Report WP Rocket version.', + [], [], 'read', 'detect')); + + $registry->register($def('rocket_get_settings', 'Read WP Rocket settings (the wp_rocket_settings option), optionally filtered by key substring.', + ['filter' => ['type' => 'string']], [], 'read', 'getSettings')); + + $registry->register($def('rocket_set_setting', 'Set one WP Rocket setting key inside wp_rocket_settings. value is parsed as JSON when valid. Prior settings auto-backed-up for rocket_restore_settings. Purges cache after.', + ['key' => ['type' => 'string'], 'value' => ['type' => 'string']], ['key', 'value'], 'write', 'setSetting')); + + $registry->register($def('rocket_restore_settings', 'Restore the entire WP Rocket settings to the snapshot saved before the last rocket_set_setting.', + [], [], 'write', 'restoreSettings')); + + $registry->register($def('rocket_purge', 'Purge WP Rocket cache. scope = all (default) | url. Provide url for scope=url.', + ['scope' => ['type' => 'string', 'enum' => ['all', 'url']], 'url' => ['type' => 'string']], [], 'write', 'purge')); + + $registry->register($def('rocket_preload', 'Trigger WP Rocket cache preload (rebuilds the cache). Purges first so WP Rocket repopulates.', + [], [], 'write', 'preload')); + } + + public static function detect(array $args): array { + return ['version' => WP_ROCKET_VERSION, 'settings_present' => is_array(get_option(self::OPT))]; + } + + public static function getSettings(array $args): array { + $s = get_option(self::OPT, []); + if (!is_array($s)) $s = []; + $filter = isset($args['filter']) ? (string) $args['filter'] : ''; + if ($filter !== '') { + $s = array_filter($s, fn($k) => stripos($k, $filter) !== false, ARRAY_FILTER_USE_KEY); + } + return ['count' => count($s), 'settings' => $s]; + } + + public static function setSetting(array $args): array { + $key = (string) ($args['key'] ?? ''); + if ($key === '') throw new \RuntimeException('key required.'); + $raw = (string) ($args['value'] ?? ''); + $decoded = json_decode($raw, true); + $value = (json_last_error() === JSON_ERROR_NONE && ($raw === 'null' || $decoded !== null)) ? $decoded : $raw; + + $s = get_option(self::OPT, []); + if (!is_array($s)) $s = []; + // snapshot the whole settings array once per change for clean restore + update_option(self::BACKUP, $s, false); + $had = array_key_exists($key, $s); + $s[$key] = $value; + update_option(self::OPT, $s); + if (function_exists('rocket_clean_domain')) rocket_clean_domain(); + return ['key' => $key, 'value' => $value, 'previously_set' => $had, 'backed_up' => true]; + } + + public static function restoreSettings(array $args): array { + $bak = get_option(self::BACKUP, null); + if (!is_array($bak)) throw new \RuntimeException('No WP Rocket settings backup recorded.'); + update_option(self::OPT, $bak); + if (function_exists('rocket_clean_domain')) rocket_clean_domain(); + return ['restored' => true, 'keys' => count($bak)]; + } + + public static function purge(array $args): array { + $scope = (string) ($args['scope'] ?? 'all'); + if ($scope === 'url') { + $url = (string) ($args['url'] ?? ''); + if ($url === '') throw new \RuntimeException('url required for scope=url.'); + if (!function_exists('rocket_clean_files')) throw new \RuntimeException('rocket_clean_files unavailable.'); + rocket_clean_files([$url]); + return ['scope' => 'url', 'url' => $url, 'purged' => true]; + } + if (!function_exists('rocket_clean_domain')) throw new \RuntimeException('rocket_clean_domain unavailable.'); + rocket_clean_domain(); + return ['scope' => 'all', 'purged' => true]; + } + + public static function preload(array $args): array { + $purged = false; + if (function_exists('rocket_clean_domain')) { rocket_clean_domain(); $purged = true; } + // WP Rocket repopulates via its own preload bot after a domain clean; nudge it where a hook exists. + if (has_action('rocket_preload_after_purge_cache')) do_action('rocket_preload_after_purge_cache'); + return ['purged' => $purged, 'preload' => 'triggered', + 'note' => 'WP Rocket repopulates the cache via its preload bot after a domain purge.']; + } +}