HEX
Server: Apache/2.4.68 (Debian)
System: Linux as-cs-widget-demo-us-central1 6.1.0-44-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.164-1 (2026-03-09) x86_64
User: root (0)
PHP: 8.2.32
Disabled: NONE
Upload Files
File: /var/www/html/wp-content/plugins/wp-recipe-maker/assets/js/shared/AjaxWrapper.js
/**
 * Wrapper for WordPress AJAX endpoints using form-urlencoded format.
 * Provides consistent error handling similar to ApiWrapper.
 */
export default {
    /**
     * Call a WordPress AJAX endpoint.
     *
     * @param {string} action The AJAX action name (e.g., 'wprm_create_post_for_recipe').
     * @param {Object} params Additional parameters to send in the request body.
     * @returns {Promise} Promise that resolves with the response data or false on error.
     */
    call(action, params = {}) {
        // Get nonce from admin settings.
        const nonce = wprm_admin.nonce;

        // Build form-urlencoded body.
        const bodyParams = new URLSearchParams({
            action: action,
            security: nonce,
            ...params,
        });

        const args = {
            method: 'POST',
            credentials: 'same-origin',
            headers: {
                'Accept': 'application/json, text/plain, */*',
                'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
                // Don't cache AJAX calls.
                'Cache-Control': 'no-cache, no-store, must-revalidate',
                'Pragma': 'no-cache',
                'Expires': 0,
            },
            body: bodyParams.toString(),
        };

        return fetch(wprm_admin.ajax_url, args).then(function (response) {
            if (response.ok) {
                return response.json().then(function (json) {
                    if (json.success) {
                        // Return data if available, otherwise return true to indicate success.
                        // wp_send_json_success() without data returns {"success": true} without a data property.
                        return json.data !== undefined ? json.data : true;
                    } else {
                        // Handle WordPress AJAX error response.
                        showAjaxErrorMessage(action, args, response, json);
                        return false;
                    }
                }).catch(function (jsonError) {
                    // Handle JSON parsing errors.
                    console.error('Failed to parse JSON response:', action, jsonError);
                    showAjaxErrorMessage(action, args, response, null, jsonError);
                    return false;
                });
            } else {
                // Handle HTTP error response.
                showAjaxErrorMessage(action, args, response);
                return false;
            }
        }).catch(function (error) {
            // Handle network errors or other fetch failures.
            console.error('AJAX request failed:', action, error);
            showAjaxErrorMessage(action, args, null, null, error);
            return false;
        });
    },
};

/**
 * Show error message for AJAX endpoint failures.
 *
 * @param {string} action The AJAX action that failed.
 * @param {Object} args The fetch arguments used.
 * @param {Response|null} response The response object, if available.
 * @param {Object|null} json The parsed JSON response, if available.
 * @param {Error|null} error The error object, if available.
 */
async function showAjaxErrorMessage(action, args, response, json = null, error = null) {
    // Log errors in console and try to get as much debug information as possible.
    console.log('AJAX Error:', action, args);
    if (response) {
        console.log('Response:', response);
    }
    if (json) {
        console.log('JSON:', json);
    }
    if (error) {
        console.log('Error:', error);
    }

    let message = '';

    // Handle different error scenarios.
    if (error) {
        // Network error or fetch failure.
        message = 'Network error occurred. Please check your internet connection and try again.\r\n\r\n';
        message += `Error: ${error.message || error}`;
    } else if (response) {
        // HTTP error response.
        const status = parseInt(response.status);
        let hint = false;

        if (300 <= status && status <= 399) {
            hint = 'A redirection is breaking the AJAX endpoint. Are any redirections set up in the .htaccess file or using a plugin?';
        } else if (401 === status || 403 === status) {
            hint = 'Something is blocking access. Are you or your webhost using a firewall like Cloudflare WAF or Sucuri? Try whitelisting your own IP address or this specific action.';
        } else if (404 === status) {
            hint = 'The AJAX endpoint could not be found. This might be a plugin conflict or server configuration issue.';
        } else if (500 <= status && status <= 599) {
            hint = 'The server is throwing an error. It could be hitting a memory or execution limit. Check with your webhost what the exact error is in the logs.';
        }

        if (hint) {
            message += `${hint}\r\n\r\n`;
        }

        // Response details.
        const responseDetails = `${response.url} ${response.redirected ? '(redirected)' : ''}- ${response.status} - ${response.statusText}`;
        message += `Response: ${responseDetails}`;
    }

    // Handle WordPress AJAX error response format.
    if (json && json.data && json.data.message) {
        message += `\r\n\r\nServer message: ${json.data.message}`;
    } else if (json && json.message) {
        message += `\r\n\r\nServer message: ${json.message}`;
    }

    // Check for nonce/session errors.
    let showAlert = true;
    if (json && json.data && json.data.message) {
        const errorMessage = json.data.message.toLowerCase();
        if (-1 !== errorMessage.indexOf('permission') || -1 !== errorMessage.indexOf('nonce') || -1 !== errorMessage.indexOf('logged out') || -1 !== errorMessage.indexOf('session')) {
            alert('You got logged out or your session expired. Please try logging out of WordPress and back in again.');
            showAlert = false;
        }
    }

    if (showAlert) {
        message += '\r\n\r\nPress OK to contact support@bootstrapped.ventures for support (opens an email popup).';

        if (confirm(message)) {
            const email = 'support@bootstrapped.ventures';
            const subject = 'WP Recipe Maker AJAX Error Message';
            const body = `I received the error message below at ${window.location.href}\r\n\r\nAction: ${action}\r\n\r\n${message}`;

            window.open(`mailto:${encodeURIComponent(email)}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`);
        }
    }
}