Automattic / woocommerce-payments

Accept payments via credit card. Manage transactions within WordPress.
https://wordpress.org/plugins/woocommerce-payments/
Other
173 stars 69 forks source link

Refactor WooPay Tracker class #9320

Open malithsen opened 1 month ago

malithsen commented 1 month ago

Description

The class-woopay-tracker.php file is currently responsible for tracking various events, including WooPay events, shopper-originated events, and certain admin events. The file and class name no longer accurately reflect its current functionality as it now extends beyond tracking only the WooPay events. We need to rename the file and consider refactoring it to better align with its multiple responsibilities.

Acceptance criteria

ssanaullahrais commented 4 days ago

Hi!

I have fixed this issue.

Request Method:POST Status Code: 404 Not Found Remote Address: 141.193.213.11:443 Referrer Policy: strict-origin-when-cross-origin tracksNonce: undefined

  1. action: platform_tracks
  2. tracksEventName: product_page_view
  3. tracksEventProp: {"theme_type":"short_code","record_event_data":{"is_admin_event":false,"track_on_all_stores":true}}

In class-woopay-tracker.php please replace with function with this.

    /**
     * Add front-end tracks scripts to prevent cache break.
     *
     * @return void
     */
     public function add_frontend_tracks_scripts() {
         $frontend_tracks = apply_filters( 'wcpay_frontend_tracks', [] );

         if ( count( $frontend_tracks ) === 0 ) {
             return;
         }

         WC_Payments::register_script_with_dependencies( 'wcpay-frontend-tracks', 'dist/frontend-tracks' );

         wp_enqueue_script( 'wcpay-frontend-tracks' );

         wp_localize_script(
             'wcpay-frontend-tracks',
             'wcPayFrontendTracks',
             array(
                 'ajax_url' => admin_url( 'admin-ajax.php' ),
                 'nonce' => wp_create_nonce( 'platform_tracks_nonce' ),
                 'tracks' => $frontend_tracks
             )
         );
     }

dist/frontend-tracker.js - Update complete code

(() => {
    // Utility function to get global object
    const getGlobalObject = () => {
        if (typeof globalThis === "object") return globalThis;
        try {
            return this || new Function("return this")();
        } catch (e) {
            if (typeof window === "object") return window;
        }
    };

    const global = getGlobalObject();

    // Set up public path
    const setPublicPath = () => {
        let scriptSrc = '';
        if (global.document) {
            const doc = global.document;
            if (doc.currentScript) {
                scriptSrc = doc.currentScript.src;
            } else {
                const scripts = doc.getElementsByTagName("script");
                for (let i = scripts.length - 1; i >= 0; i--) {
                    const src = scripts[i].src;
                    if (src && /^http(s?):/.test(src)) {
                        scriptSrc = src;
                        break;
                    }
                }
            }
        }
        if (!scriptSrc) {
            console.warn("Automatic publicPath is not supported in this browser");
            return '';
        }
        return scriptSrc.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
    };

    const publicPath = global.wcpayAssets ? global.wcpayAssets.url : setPublicPath();

    // Configuration getters
    const getConfig = (key) => {
        if (typeof global.wcpayConfig !== "undefined") {
            return global.wcpayConfig[key];
        }
        return getUPEConfig(key);
    };

    const getUPEConfig = (key) => {
        let config = null;
        if (typeof global.wcpay_upe_config !== "undefined") {
            config = global.wcpay_upe_config;
        } else if (typeof global.wc === "object" && global.wc.wcSettings) {
            config = global.wc.wcSettings.getSetting("woocommerce_payments_data") || {};
        }
        return config ? config[key] : null;
    };

    const getParamConfig = (key) => {
        if (typeof global.wcpayExpressCheckoutParams === "object" && global.wcpayExpressCheckoutParams.hasOwnProperty(key)) {
            return global.wcpayExpressCheckoutParams[key];
        }
        if (typeof global.wcpayPaymentRequestParams === "object" && global.wcpayPaymentRequestParams.hasOwnProperty(key)) {
            return global.wcpayPaymentRequestParams[key];
        }
        return null;
    };

    // Tracking function
    const trackEvent = (eventName, properties = {}) => {
        const nonce = getConfig("platformTrackerNonce") || getParamConfig("nonce")?.platform_tracker;
        const ajaxUrl = getConfig("ajaxUrl") || getParamConfig("ajax_url") || '/wp-admin/admin-ajax.php';

        if (!nonce || !ajaxUrl) {
            console.error('WCPay tracking error: Missing nonce or AJAX URL');
            return;
        }

        const formData = new FormData();
        formData.append("tracksNonce", nonce);
        formData.append("action", "platform_tracks");
        formData.append("tracksEventName", eventName);
        formData.append("tracksEventProp", JSON.stringify(properties));

        fetch(ajaxUrl, {
            method: "POST",
            body: formData
        })
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
        })
        .then(data => console.log('WCPay tracking success:', data))
        .catch(error => console.error('WCPay tracking error:', error));
    };

    // Process queued tracks
    if (global.wcPayFrontendTracks && Array.isArray(global.wcPayFrontendTracks)) {
        global.wcPayFrontendTracks.forEach(track => {
            trackEvent(track.event, track.properties);
        });
        global.wcPayFrontendTracks = [];
    }

    // Expose tracking function globally
    global.wcpayTrackEvent = trackEvent;
})();