is_test_mode(); $new_state = ! $current_state; $new_value = $new_state ? 'yes' : 'no'; $result = update_option( self::OPTION_KEY, $new_value ); // Verify the option was actually updated. $verified_state = $this->is_test_mode(); if ( ! $result || $verified_state !== $new_state ) { return array( 'success' => false, 'new_state' => $current_state, 'message' => __( 'Failed to update test mode. Please try again.', 'carticy-ai-checkout-for-woocommerce' ), ); } if ( $new_state ) { do_action( 'carticy_ai_checkout_test_mode_enabled' ); } else { do_action( 'carticy_ai_checkout_test_mode_disabled' ); } return array( 'success' => true, 'new_state' => $new_state, 'message' => '', ); } /** * Get test mode status string * * @return string 'test' or 'production'. */ public function get_mode(): string { return $this->is_test_mode() ? 'test' : 'production'; } /** * Get prefixed transient key for test mode * * @param string $key Base transient key. * @return string Prefixed key if in test mode, original key otherwise. */ public function get_transient_key( string $key ): string { return $this->is_test_mode() ? self::TEST_PREFIX . $key : $key; } /** * Get prefixed option key for test mode * * @param string $key Base option key. * @return string Prefixed key if in test mode, original key otherwise. */ public function get_option_key( string $key ): string { return $this->is_test_mode() ? self::TEST_PREFIX . $key : $key; } /** * Get Stripe API mode * * @return string 'test' or 'live'. */ public function get_stripe_mode(): string { return $this->is_test_mode() ? 'test' : 'live'; } /** * Should bypass IP allowlist in test mode * * @return bool True to bypass IP allowlist, false otherwise. */ public function should_bypass_ip_allowlist(): bool { $bypass_enabled = get_option( 'carticy_ai_checkout_test_bypass_ip', true ); return $this->is_test_mode() && $bypass_enabled; } /** * Get test mode indicator HTML * * @return string HTML for admin bar indicator. */ public function get_admin_bar_indicator(): string { if ( ! $this->is_test_mode() ) { return ''; } return sprintf( '
⚠️ %s
', esc_html__( 'TEST MODE ACTIVE - Using Test Stripe Keys', 'carticy-ai-checkout-for-woocommerce' ) ); } /** * Get test mode label for admin UI * * @return string Label text. */ public function get_mode_label(): string { if ( $this->is_test_mode() ) { return __( 'Test Mode', 'carticy-ai-checkout-for-woocommerce' ); } return __( 'Production Mode', 'carticy-ai-checkout-for-woocommerce' ); } /** * Get test mode badge HTML * * @return string HTML badge. */ public function get_mode_badge(): string { $is_test = $this->is_test_mode(); $class = $is_test ? 'test-mode' : 'production-mode'; $label = $is_test ? __( 'TEST', 'carticy-ai-checkout-for-woocommerce' ) : __( 'LIVE', 'carticy-ai-checkout-for-woocommerce' ); $color = $is_test ? '#f0ad4e' : '#5cb85c'; return sprintf( '%s', esc_attr( $class ), esc_attr( $color ), esc_html( $label ) ); } /** * Clean up test data * * Removes all test transients and options. * * @return int Number of items cleaned up. */ public function cleanup_test_data(): int { global $wpdb; $count = 0; // Clean up test transients. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $transient_keys = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s", '_transient_' . self::TEST_PREFIX . '%', '_transient_timeout_' . self::TEST_PREFIX . '%' ) ); foreach ( $transient_keys as $key ) { if ( str_starts_with( $key, '_transient_timeout_' ) ) { $transient_name = str_replace( '_transient_timeout_', '', $key ); } else { $transient_name = str_replace( '_transient_', '', $key ); } if ( delete_transient( $transient_name ) ) { ++$count; } } // Clean up test options. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $option_keys = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s AND option_name != %s", self::TEST_PREFIX . '%', self::OPTION_KEY ) ); foreach ( $option_keys as $key ) { if ( delete_option( $key ) ) { ++$count; } } do_action( 'carticy_ai_checkout_test_data_cleaned', $count ); return $count; } /** * Get test data statistics * * @return array{transients: int, options: int, sessions: int} */ public function get_test_data_stats(): array { global $wpdb; // Count test transients. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $transient_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE %s", '_transient_' . self::TEST_PREFIX . '%' ) ); // Count test options. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $option_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE %s AND option_name != %s", self::TEST_PREFIX . '%', self::OPTION_KEY ) ); // Count test sessions. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $session_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE %s", '_transient_' . self::TEST_PREFIX . 'carticy_ai_checkout_session_%' ) ); return array( 'transients' => $transient_count, 'options' => $option_count, 'sessions' => $session_count, ); } }