Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
AMP_Analytics
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 5
342
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 maybe_load_hooks
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
56
 amp_add_to_cart
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
6
 amp_after_purchase
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
12
 amp_send_ga_events
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2/**
3 * Add support for Google Analytics e-commerce events for AMP pages.
4 *
5 * @package automattic/jetpack-google-analytics
6 */
7
8namespace Automattic\Jetpack\Google_Analytics;
9
10/**
11 * AMP_Analytics class.
12 *
13 * @phan-constructor-used-for-side-effects
14 */
15class AMP_Analytics {
16    /**
17     * Constructor method.
18     */
19    public function __construct() {
20        $this->maybe_load_hooks();
21    }
22
23    /**
24     * Maybe load the hooks.
25     * Checks if its AMP request, if WooCommerce is available, if DNT is disabled, if there's tracking code and if tracking is enabled.
26     */
27    public function maybe_load_hooks() {
28        // @phan-suppress-next-line PhanUndeclaredClassMethod
29        if ( ! class_exists( 'Jetpack_AMP_Support' ) || ! \Jetpack_AMP_Support::is_amp_request() ) {
30            return;
31        }
32
33        if ( ! class_exists( 'WooCommerce' ) ) {
34            return;
35        }
36
37        if ( ! Options::has_tracking_code() ) {
38            return;
39        }
40
41        if ( Utils::is_dnt_enabled() ) {
42            return;
43        }
44
45        if ( ! Options::track_add_to_cart_is_enabled() ) {
46            return;
47        }
48
49        add_action( 'woocommerce_add_to_cart', array( $this, 'amp_add_to_cart' ), 10, 6 );
50        add_action( 'woocommerce_thankyou', array( $this, 'amp_after_purchase' ), 10, 1 );
51        add_action( 'wp_footer', array( $this, 'amp_send_ga_events' ) );
52    }
53
54    /**
55     * Generate a GA event when adding an item to the cart.
56     *
57     * @param string $cart_item_key Cart item key.
58     * @param string $product_id Product ID.
59     * @param int    $quantity Product quantity.
60     * @param int    $variation_id Product variation ID.
61     * @param object $variation Product variation.
62     * @param object $cart_item_data Cart item data.
63     */
64    public function amp_add_to_cart( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
65        // @phan-suppress-next-line PhanUndeclaredFunction
66        $product = \wc_get_product( $product_id );
67        if ( $product ) {
68            $product_sku  = Utils::get_product_sku_or_id( $product );
69            $product_name = $product->get_name();
70
71            // @phan-suppress-next-line PhanUndeclaredFunction
72            $events   = \WC()->session->get( 'wc_ga_events' );
73            $events[] = array(
74                'type'      => 'add',
75                'ga_params' => array(
76                    'pa'    => 'add',
77                    'pr1id' => sanitize_text_field( $product_sku ),
78                    'pr1nm' => sanitize_text_field( $product_name ),
79                    'pr1qt' => absint( $quantity ),
80                ),
81            );
82            // @phan-suppress-next-line PhanUndeclaredFunction
83            \WC()->session->set( 'wc_ga_events', $events );
84        }
85    }
86
87    /**
88     * Generate a GA event when removing an item to the cart.
89     *
90     * @param int $order_id The Order ID.
91     */
92    public function amp_after_purchase( $order_id ) {
93        // @phan-suppress-next-line PhanUndeclaredFunction
94        $events = \WC()->session->get( 'wc_ga_events' );
95        // @phan-suppress-next-line PhanUndeclaredFunction
96        $order       = \wc_get_order( $order_id );
97        $order_total = $order->get_total();
98        $order_tax   = $order->get_total_tax();
99
100        $i     = 1;
101        $event = array(
102            'type'      => 'purchase',
103            'ga_params' => array(
104                'pa' => 'purchase',
105                'ti' => absint( $order_id ),
106                'tr' => (float) $order_total,
107                'tt' => (float) $order_tax,
108            ),
109        );
110        foreach ( $order->get_items() as $item ) {
111            $product = $item->get_product();
112            if ( $product ) {
113                $event['ga_params'][ 'pr' . $i . 'id' ] = sanitize_text_field( Utils::get_product_sku_or_id( $product ) );
114                $event['ga_params'][ 'pr' . $i . 'nm' ] = sanitize_text_field( $item->get_name() );
115                $event['ga_params'][ 'pr' . $i . 'qt' ] = absint( $item->get_quantity() );
116                ++$i;
117            }
118        }
119
120        $events[] = $event;
121        // @phan-suppress-next-line PhanUndeclaredFunction
122        \WC()->session->set( 'wc_ga_events', $events );
123    }
124
125    /**
126     * Send the stored events to GA.
127     */
128    public function amp_send_ga_events() {
129        if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || 'GET' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- Simple comparison
130            return;
131        }
132
133        // @phan-suppress-next-line PhanUndeclaredFunction
134        $events = \WC()->session->get( 'wc_ga_events' );
135        if ( ! is_array( $events ) ) {
136            return;
137        }
138
139        foreach ( $events as $event ) {
140            ?>
141            <amp-analytics type='googleanalytics'>
142                <script type='application/json'>
143                    {
144                        "vars": {
145                            "account": "<?php echo esc_html( Options::get_tracking_code() ); ?>"
146                    },
147                    "triggers": {
148                        "trackPageview": {
149                            "on": "visible",
150                            "request": "pageview",
151                            "extraUrlParams": <?php echo wp_json_encode( $event['ga_params'], JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?>
152                    }
153                }
154            }
155                </script>
156            </amp-analytics>
157            <?php
158
159            array_shift( $events );
160        }
161        // @phan-suppress-next-line PhanUndeclaredFunction
162        \WC()->session->set( 'wc_ga_events', $events );
163    }
164}