action = $action; } /** * Create a nonce for a specific action. * * @since 1.0.0 * @param string $specific_action Specific action name. * @return string Generated nonce. */ public function create_nonce(string $specific_action = ''): string { $action = $this->get_action_name($specific_action); return wp_create_nonce($action); } /** * Verify a nonce for a specific action. * * @since 1.0.0 * @param string $nonce Nonce to verify. * @param string $specific_action Specific action name. * @return bool True if nonce is valid, false otherwise. */ public function verify_nonce(string $nonce, string $specific_action = ''): bool { $action = $this->get_action_name($specific_action); return wp_verify_nonce($nonce, $action) !== false; } /** * Create a nonce field for forms. * * @since 1.0.0 * @param string $specific_action Specific action name. * @param string $name Nonce field name. * @param bool $referer Whether to include referer field. * @param bool $echo Whether to echo the field or return it. * @return string Nonce field HTML. */ public function create_nonce_field( string $specific_action = '', string $name = '_wpnonce', bool $referer = true, bool $echo = false ): string { $action = $this->get_action_name($specific_action); return wp_nonce_field($action, $name, $referer, $echo); } /** * Get nonce for AJAX requests. * * @since 1.0.0 * @param string $specific_action Specific action name. * @return array Nonce data for AJAX. */ public function get_ajax_nonce(string $specific_action = ''): array { return [ 'nonce' => $this->create_nonce($specific_action), 'action' => $this->get_action_name($specific_action), ]; } /** * Verify AJAX nonce. * * @since 1.0.0 * @param string $specific_action Specific action name. * @return bool True if nonce is valid, false otherwise. */ public function verify_ajax_nonce(string $specific_action = ''): bool { $nonce = $_POST['nonce'] ?? $_GET['nonce'] ?? ''; return $this->verify_nonce($nonce, $specific_action); } /** * Check AJAX referer (WordPress standard). * * @since 1.0.0 * @param string $specific_action Specific action name. * @throws \Exception If nonce verification fails. */ public function check_ajax_referer(string $specific_action = ''): void { $action = $this->get_action_name($specific_action); check_ajax_referer($action, 'nonce'); } /** * Get the full action name. * * @since 1.0.0 * @param string $specific_action Specific action name. * @return string Full action name. */ private function get_action_name(string $specific_action): string { if (empty($specific_action)) { return $this->action; } return $this->action . '_' . $specific_action; } /** * Verify nonce from REST request headers. * * @since 1.0.0 * @param \WP_REST_Request $request REST request object * @return bool True if nonce is valid, false otherwise */ public function verify_request(\WP_REST_Request $request): bool { $nonce = $request->get_header('X-WP-Nonce'); if (!is_string($nonce)) { $nonce = $request->get_param('_wpnonce') ?? ''; } // For REST API, we need to verify against 'wp_rest' action if (wp_verify_nonce((string) $nonce, 'wp_rest') === 1) { return true; } // Fallback to our custom action return wp_verify_nonce((string) $nonce, $this->action) === 1; } /** * Verify nonce with specific action (for admin-post requests). * * @since 1.0.0 * @param string $nonce Nonce to verify * @param string $specific_action Specific action name * @return bool True if nonce is valid, false otherwise */ public function verify_nonce_with_action(string $nonce, string $specific_action): bool { return wp_verify_nonce($nonce, $specific_action) === 1; } }