options)) { return 0; } $like = $wpdb->esc_like((string) $prefix) . '%'; $deleted = $wpdb->query( $wpdb->prepare("DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", $like) ); return is_numeric($deleted) ? (int) $deleted : 0; } } if (!function_exists('matewa_test_reset_remote_wipe')) { function matewa_test_reset_remote_wipe($context) { $endpoint = defined('MATEWA_TEST_RESET_REMOTE_ENDPOINT') ? trim((string) MATEWA_TEST_RESET_REMOTE_ENDPOINT) : ''; $secret = defined('MATEWA_TEST_RESET_REMOTE_SECRET') ? trim((string) MATEWA_TEST_RESET_REMOTE_SECRET) : ''; if ('' === $endpoint) { return [ 'attempted' => false, 'ok' => false, 'code' => 'remote_not_configured', 'message' => 'Remote registry reset endpoint is not configured for this test build.', ]; } if ('' === $secret) { return [ 'attempted' => false, 'ok' => false, 'code' => 'remote_secret_missing', 'message' => 'Remote registry reset secret is not configured for this test build.', ]; } $payload = [ 'action' => 'matewa_test_clean_install_reset', 'site_url' => esc_url_raw($context['site_url'] ?? site_url('/')), 'home_url' => esc_url_raw($context['home_url'] ?? home_url('/')), 'host' => sanitize_text_field($context['host'] ?? matewa_test_reset_get_site_host()), 'timestamp' => time(), ]; $payload_json = wp_json_encode($payload); $signature = hash_hmac('sha256', (string) $payload_json, $secret); $response = wp_remote_post( $endpoint, [ 'timeout' => 12, 'headers' => [ 'Content-Type' => 'application/json; charset=utf-8', 'X-MateWA-Signature' => $signature, ], 'body' => $payload_json, ] ); if (is_wp_error($response)) { return [ 'attempted' => true, 'ok' => false, 'code' => 'remote_request_failed', 'message' => $response->get_error_message(), ]; } $status_code = (int) wp_remote_retrieve_response_code($response); $body = (string) wp_remote_retrieve_body($response); $decoded = json_decode($body, true); $decoded = is_array($decoded) ? $decoded : []; return [ 'attempted' => true, 'ok' => $status_code >= 200 && $status_code < 300, 'code' => sanitize_key((string) ($decoded['code'] ?? ('http_' . $status_code))), 'message' => sanitize_text_field((string) ($decoded['message'] ?? ('Remote reset HTTP ' . $status_code))), 'http_code' => $status_code, ]; } } if (!function_exists('matewa_test_reset_run_clean_install')) { function matewa_test_reset_run_clean_install() { global $wpdb; $context = [ 'site_url' => site_url('/'), 'home_url' => home_url('/'), 'host' => matewa_test_reset_get_site_host(), ]; $deleted = [ 'matewa_options' => matewa_test_reset_delete_options_like('matewa_'), 'matewa_transients' => matewa_test_reset_delete_options_like('_transient_matewa_'), 'matewa_transient_times' => matewa_test_reset_delete_options_like('_transient_timeout_matewa_'), 'matewa_site_transients' => matewa_test_reset_delete_options_like('_site_transient_matewa_'), 'matewa_site_times' => matewa_test_reset_delete_options_like('_site_transient_timeout_matewa_'), ]; if (isset($wpdb->sitemeta)) { $site_like = $wpdb->esc_like('_site_transient_matewa_') . '%'; $time_like = $wpdb->esc_like('_site_transient_timeout_matewa_') . '%'; $deleted['matewa_network_site_transients'] = (int) $wpdb->query( $wpdb->prepare("DELETE FROM {$wpdb->sitemeta} WHERE meta_key LIKE %s OR meta_key LIKE %s", $site_like, $time_like) ); } if (function_exists('wp_cache_delete')) { wp_cache_delete('alloptions', 'options'); } $remote = matewa_test_reset_remote_wipe($context); $result = [ 'ran_at' => time(), 'host' => $context['host'], 'deleted' => $deleted, 'remote' => $remote, ]; update_option('matewa_test_reset_last_result', $result, false); return $result; } } if (!function_exists('matewa_handle_test_reset_request')) { function matewa_handle_test_reset_request() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } if (empty($_POST['matewa_test_reset_action'])) { return; } check_admin_referer('matewa_test_reset_nonce', 'matewa_test_reset_nonce'); if (!matewa_test_reset_is_available()) { wp_safe_redirect(matewa_admin_redirect_url(['matewa_test_reset_notice' => 'not_available'], 'setup')); exit; } $enabled = !empty($_POST['matewa_test_reset_enabled_confirm']); if (!$enabled) { wp_safe_redirect(matewa_admin_redirect_url(['matewa_test_reset_notice' => 'toggle_required'], 'setup')); exit; } $expected_host = matewa_test_reset_get_site_host(); $posted_host = isset($_POST['matewa_test_reset_host_confirm']) ? strtolower(trim(sanitize_text_field(wp_unslash($_POST['matewa_test_reset_host_confirm'])))) : ''; $posted_host = preg_replace('/^www\./', '', $posted_host); if ('' === $posted_host || !hash_equals($expected_host, $posted_host)) { wp_safe_redirect(matewa_admin_redirect_url(['matewa_test_reset_notice' => 'host_required'], 'setup')); exit; } $confirm_phrase = isset($_POST['matewa_test_reset_phrase']) ? strtoupper(trim(sanitize_text_field(wp_unslash($_POST['matewa_test_reset_phrase'])))) : ''; if ('RESET 247CHATMATE' !== $confirm_phrase) { wp_safe_redirect(matewa_admin_redirect_url(['matewa_test_reset_notice' => 'phrase_required'], 'setup')); exit; } $password = isset($_POST['matewa_test_reset_password']) ? sanitize_text_field(wp_unslash($_POST['matewa_test_reset_password'])) : ''; if (!matewa_test_reset_password_matches($password)) { wp_safe_redirect(matewa_admin_redirect_url(['matewa_test_reset_notice' => 'password_required'], 'setup')); exit; } $result = matewa_test_reset_run_clean_install(); $remote = is_array($result['remote'] ?? null) ? $result['remote'] : []; $remote_code = sanitize_key((string) ($remote['code'] ?? 'remote_unknown')); wp_safe_redirect( matewa_admin_redirect_url( [ 'matewa_test_reset_notice' => 'clean_install_reset', 'matewa_test_reset_remote' => $remote_code, ], 'setup' ) ); exit; } } add_action('admin_init', 'matewa_handle_test_reset_request', 4); if (!function_exists('matewa_test_reset_notice_message')) { function matewa_test_reset_notice_message($notice) { $notice = sanitize_key((string) $notice); $messages = [ 'clean_install_reset' => ['success', 'Clean install reset completed. Local 247ChatMate options, MateWA transients and browser admin state have been cleared for this test site.'], 'toggle_required' => ['warning', 'Turn the test reset toggle on before running a clean install reset.'], 'host_required' => ['warning', 'Type this site domain exactly to confirm the clean install reset.'], 'phrase_required' => ['warning', 'Type RESET 247CHATMATE to confirm the clean install reset.'], 'password_required' => ['error', 'Enter the temporary test reset password or the master password.'], 'not_available' => ['error', 'Test reset is not available on this site.'], ]; return $messages[$notice] ?? ['', '']; } } if (!function_exists('matewa_test_reset_browser_state_clearer')) { function matewa_test_reset_browser_state_clearer() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } $notice = isset($_GET['matewa_test_reset_notice']) ? sanitize_key(wp_unslash($_GET['matewa_test_reset_notice'])) : ''; if ('clean_install_reset' !== $notice) { return; } ?>