Plugin Directory

Changeset 3252605


Ignore:
Timestamp:
03/08/2025 06:53:26 PM (13 months ago)
Author:
creativehassan
Message:

Complete revamp of the plugin with fixes

Location:
snap-pixel
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • snap-pixel/tags/1.8.0/README.md

    r3252591 r3252605  
    2929- Filter events by date range and type
    3030
    31 ### 2. Snap Pixel Advanced E-commerce
    32 
    33 Take your WooCommerce tracking to the next level with advanced e-commerce features designed to maximize your Snapchat advertising ROI.
    34 
    35 **Features:**
    36 - Enhanced product data tracking
    37 - Cart abandonment tracking
    38 - Product category and collection tracking
    39 - Customer lifetime value insights
    40 - Cross-sell and upsell event tracking
    41 
    42 ### 3. Snap Pixel Conversion API
    43 
    44 Implement server-side tracking for more reliable conversion data, especially in environments with ad blockers or privacy restrictions.
    45 
    46 **Features:**
    47 - Server-side event tracking
    48 - Improved tracking reliability
    49 - Better handling of ad blockers
    50 - Enhanced privacy compliance
    51 - Dual tracking (browser + server) capabilities
    52 
    53 ### 4. Snap Pixel for Membership Sites
     31### 2. Snap Pixel for Membership Sites (Future)
    5432
    5533Specialized tracking for membership sites and subscription-based businesses using popular plugins like MemberPress, WooCommerce Subscriptions, and more.
  • snap-pixel/tags/1.8.0/admin/admin-display.php

    r3252591 r3252605  
    2828$ajax_addtocart = isset( $settings['ajax_addtocart'] ) ? $settings['ajax_addtocart'] : '';
    2929
    30 // Get current tab
     30// Get current tab - this is just for UI display, not processing form data, so nonce verification is not needed
    3131$current_tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : 'general';
    3232
  • snap-pixel/tags/1.8.0/admin/partials/edd-tab.php

    r3252591 r3252605  
    1818
    1919// Default values
    20 $view_content = isset( $edd_settings['view_content'] ) ? $edd_settings['view_content'] : 'yes';
    21 $add_cart = isset( $edd_settings['add_cart'] ) ? $edd_settings['add_cart'] : 'yes';
    22 $checkout = isset( $edd_settings['checkout'] ) ? $edd_settings['checkout'] : 'yes';
    23 $purchase = isset( $edd_settings['purchase'] ) ? $edd_settings['purchase'] : 'yes';
     20$view_content = isset( $edd_settings['view_content'] ) ? $edd_settings['view_content'] : 'no';
     21$add_cart = isset( $edd_settings['add_cart'] ) ? $edd_settings['add_cart'] : 'no';
     22$checkout = isset( $edd_settings['checkout'] ) ? $edd_settings['checkout'] : 'no';
     23$purchase = isset( $edd_settings['purchase'] ) ? $edd_settings['purchase'] : 'no';
    2424?>
    2525
  • snap-pixel/tags/1.8.0/includes/class-snap-pixel-admin.php

    r3252591 r3252605  
    252252     */
    253253    private function display_edd_tab() {
    254         // Process form submission
    255         if ( isset( $_POST['save_snapchat_pixel_edd'] ) && '1' === $_POST['save_snapchat_pixel_edd'] ) {
    256             if ( ! isset( $_POST['snapchat_pixel_edd_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['snapchat_pixel_edd_nonce'] ) ), 'snapchat_pixel_edd_security' ) ) {
    257                 wp_die( esc_html__( 'Security check failed. Please try again.', 'snap-pixel' ) );
    258             }
    259            
    260             // Save EDD access setting
    261             $edd_access = isset( $_POST['edd_activate'] ) ? sanitize_text_field( wp_unslash( $_POST['edd_activate'] ) ) : 'no';
    262             update_option( 'snapchat_pixel_edd_access', $edd_access );
    263            
    264             // Save EDD settings
    265             $edd_settings = isset( $_POST['snapchat_pixel_edd'] ) ? map_deep( wp_unslash( $_POST['snapchat_pixel_edd'] ), 'sanitize_text_field' ) : array();
    266             update_option( 'snapchat_pixel_edd', $edd_settings );
    267            
    268             // Show success message
    269             add_settings_error( 'snap-pixel', 'settings_updated', esc_html__( 'EDD settings saved successfully.', 'snap-pixel' ), 'success' );
    270         }
    271        
    272254        // EDD settings
    273255        $edd_active = class_exists( 'Easy_Digital_Downloads' );
     
    289271     */
    290272    private function process_form_submission() {
    291         // Debug information - more detailed
    292         error_log('Form submission detected - POST data: ' . print_r($_POST, true));
    293        
     273        // Process WooCommerce settings
    294274        if ( isset( $_POST['save_snapchat_pixel_woo'] ) ) {
    295             // Log submission to error log
    296             error_log( 'WooCommerce form submitted' );
    297             error_log( 'WooCommerce activation: ' . ( isset( $_POST['woo_activate'] ) ? $_POST['woo_activate'] : 'not set' ) );
    298             if ( isset( $_POST['snapchat_pixel_code'] ) ) {
    299                 error_log( 'WooCommerce settings: ' . print_r( $_POST['snapchat_pixel_code'], true ) );
     275            // Verify nonce
     276            if ( ! isset( $_POST['snapchat_pixel_woo_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['snapchat_pixel_woo_nonce'] ) ), 'snapchat_pixel_woo_security' ) ) {
     277                add_settings_error( 'snap-pixel-woocommerce', 'snap-pixel-woo-error', __( 'Security check failed. Please try again.', 'snap-pixel' ), 'error' );
     278                return;
     279            }
     280           
     281            // Save WooCommerce access setting
     282            if ( isset( $_POST['woo_activate'] ) ) {
     283                $woo_activate = sanitize_text_field( wp_unslash( $_POST['woo_activate'] ) );
     284                update_option( 'snapchat_pixel_wooacces', $woo_activate );
    300285            } else {
    301                 error_log( 'WooCommerce settings not in form data' );
    302             }
     286                update_option( 'snapchat_pixel_wooacces', 'no' );
     287            }
     288           
     289            // Save WooCommerce settings
     290            if ( isset( $_POST['snapchat_pixel_code'] ) && is_array( $_POST['snapchat_pixel_code'] ) ) {
     291                // Get existing settings
     292                $existing_settings = get_option( 'snapchat_pixel_code', array() );
     293               
     294                // Sanitize the WooCommerce settings
     295                $woo_settings = array();
     296                $raw_data = wp_unslash( $_POST['snapchat_pixel_code'] );
     297               
     298                // Process checkbox fields
     299                $checkbox_fields = array( 'viewcart', 'checkout', 'paymentinfo', 'addtocart', 'ajax_addtocart' );
     300                foreach ( $checkbox_fields as $field ) {
     301                    $existing_settings[$field] = isset( $raw_data[$field] ) && 'checked' === $raw_data[$field] ? 'checked' : '';
     302                }
     303               
     304                // Update the option
     305                update_option( 'snapchat_pixel_code', $existing_settings );
     306            }
     307           
     308            add_settings_error( 'snap-pixel-woocommerce', 'snap-pixel-woo-updated', __( 'WooCommerce settings updated.', 'snap-pixel' ), 'success' );
     309        }
     310       
     311        // Process EDD settings
     312        if ( isset( $_POST['save_snapchat_pixel_edd'] ) && '1' === $_POST['save_snapchat_pixel_edd'] ) {
     313           
     314            if ( ! isset( $_POST['snapchat_pixel_edd_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['snapchat_pixel_edd_nonce'] ) ), 'snapchat_pixel_edd_security' ) ) {
     315                add_settings_error( 'snap-pixel-edd', 'snap-pixel-edd-error', __( 'Security check failed. Please try again.', 'snap-pixel' ), 'error' );
     316                return;
     317            }
     318           
     319            // Save EDD access setting
     320            $edd_access = isset( $_POST['edd_activate'] ) ? sanitize_text_field( wp_unslash( $_POST['edd_activate'] ) ) : 'no';
     321            update_option( 'snapchat_pixel_edd_access', $edd_access );
     322           
     323            // Save EDD settings
     324            if ( isset( $_POST['snapchat_pixel_edd'] ) && is_array( $_POST['snapchat_pixel_edd'] ) ) {
     325                $edd_settings = array_map( 'sanitize_text_field', wp_unslash( $_POST['snapchat_pixel_edd'] ) );
     326                update_option( 'snapchat_pixel_edd', $edd_settings );
     327            }
     328           
     329            add_settings_error( 'snap-pixel-edd', 'snap-pixel-edd-updated', __( 'EDD settings updated.', 'snap-pixel' ), 'success' );
    303330        }
    304331       
     
    306333        if ( isset( $_POST['snapchat_pixel_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['snapchat_pixel_nonce'] ) ), 'snapchat_pixel_security' ) ) {
    307334            if ( isset( $_POST['snapchat_pixel_code'] ) && current_user_can( 'manage_options' ) ) {
    308                 $raw_data = wp_unslash( $_POST['snapchat_pixel_code'] );
     335                // Sanitize the entire array using array_map
     336                $raw_data = array_map( 'sanitize_text_field', wp_unslash( $_POST['snapchat_pixel_code'] ) );
    309337               
    310338                // Get existing settings to preserve WooCommerce settings
     
    338366            }
    339367        }
    340 
    341         // Process WooCommerce settings - improved handling
    342         if ( isset( $_POST['snapchat_pixel_woo_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['snapchat_pixel_woo_nonce'] ) ), 'snapchat_pixel_woo_security' ) ) {
    343             error_log('WooCommerce nonce verified');
    344            
    345             if ( current_user_can( 'manage_options' ) ) {
    346                 error_log('User has manage_options capability');
    347                
    348                 // Get existing settings
    349                 $existing_settings = get_option( 'snapchat_pixel_code', array() );
    350                 $sanitized_data = $existing_settings;
    351                
    352                 // Update WooCommerce activation status
    353                 if ( isset( $_POST['woo_activate'] ) ) {
    354                     $woo_activate = sanitize_text_field( wp_unslash( $_POST['woo_activate'] ) );
    355                     $woo_activate = 'yes' === $woo_activate ? 'yes' : 'no';
    356                    
    357                     error_log('Updating WooCommerce activation to: ' . $woo_activate);
    358                     update_option( 'snapchat_pixel_wooacces', $woo_activate );
    359                    
    360                     // Process WooCommerce settings
    361                     if ( 'yes' === $woo_activate ) {
    362                         // WooCommerce is enabled, process settings
    363                         if ( isset( $_POST['snapchat_pixel_code'] ) ) {
    364                             $raw_data = wp_unslash( $_POST['snapchat_pixel_code'] );
    365                             error_log('Processing WooCommerce settings: ' . print_r($raw_data, true));
    366                            
    367                             // Update WooCommerce settings
    368                             $sanitized_data['viewcart'] = isset( $raw_data['viewcart'] ) && 'checked' === $raw_data['viewcart'] ? 'checked' : '';
    369                             $sanitized_data['checkout'] = isset( $raw_data['checkout'] ) && 'checked' === $raw_data['checkout'] ? 'checked' : '';
    370                             $sanitized_data['paymentinfo'] = isset( $raw_data['paymentinfo'] ) && 'checked' === $raw_data['paymentinfo'] ? 'checked' : '';
    371                             $sanitized_data['addtocart'] = isset( $raw_data['addtocart'] ) && 'checked' === $raw_data['addtocart'] ? 'checked' : '';
    372                             $sanitized_data['ajax_addtocart'] = isset( $raw_data['ajax_addtocart'] ) && 'checked' === $raw_data['ajax_addtocart'] ? 'checked' : '';
    373                         } else {
    374                             error_log('No WooCommerce settings in form data, but WooCommerce is enabled');
    375                             // If no settings are in the form but WooCommerce is enabled,
    376                             // this means all checkboxes were unchecked
    377                             $sanitized_data['viewcart'] = '';
    378                             $sanitized_data['checkout'] = '';
    379                             $sanitized_data['paymentinfo'] = '';
    380                             $sanitized_data['addtocart'] = '';
    381                             $sanitized_data['ajax_addtocart'] = '';
    382                         }
    383                     } else {
    384                         // WooCommerce is disabled, clear all WooCommerce settings
    385                         error_log('WooCommerce is disabled, clearing all settings');
    386                         $sanitized_data['viewcart'] = '';
    387                         $sanitized_data['checkout'] = '';
    388                         $sanitized_data['paymentinfo'] = '';
    389                         $sanitized_data['addtocart'] = '';
    390                         $sanitized_data['ajax_addtocart'] = '';
    391                     }
    392                    
    393                     error_log('Updating snapchat_pixel_code with: ' . print_r($sanitized_data, true));
    394                     update_option( 'snapchat_pixel_code', $sanitized_data );
    395                    
    396                     add_settings_error(
    397                         'snap-pixel',
    398                         'woo_settings_updated',
    399                         __( 'WooCommerce settings updated.', 'snap-pixel' ),
    400                         'updated'
    401                     );
    402                 }
    403             }
    404         }
    405368    }
    406369
     
    419382
    420383    /**
     384     * Sanitize general settings.
     385     *
     386     * @param array $input The settings to sanitize.
     387     * @return array Sanitized settings.
     388     */
     389    public function sanitize_general_settings( $input ) {
     390        if ( ! is_array( $input ) ) {
     391            return array();
     392        }
     393       
     394        $sanitized = array();
     395       
     396        // Sanitize pixel ID
     397        $sanitized['pixel_id'] = isset( $input['pixel_id'] ) ? $this->sanitize_pixel_id( $input['pixel_id'] ) : '';
     398       
     399        // Sanitize user email
     400        $sanitized['user_email'] = isset( $input['user_email'] ) ? sanitize_email( $input['user_email'] ) : '';
     401       
     402        // Sanitize checkboxes
     403        $checkbox_fields = array(
     404            'homepage',
     405            'pages',
     406            'posts',
     407            'search',
     408            'categories',
     409            'tags',
     410            'viewcart',
     411            'checkout',
     412            'paymentinfo',
     413            'addtocart',
     414            'ajax_addtocart'
     415        );
     416       
     417        foreach ( $checkbox_fields as $field ) {
     418            $sanitized[$field] = isset( $input[$field] ) && 'checked' === $input[$field] ? 'checked' : '';
     419        }
     420       
     421        // Preserve any other fields that might be set by add-ons
     422        foreach ( $input as $key => $value ) {
     423            if ( ! isset( $sanitized[$key] ) ) {
     424                $sanitized[$key] = sanitize_text_field( $value );
     425            }
     426        }
     427       
     428        return $sanitized;
     429    }
     430
     431    /**
    421432     * Register settings.
    422433     */
    423434    public function register_settings() {
    424435        // Register general settings
     436        // The sanitize_general_settings method properly sanitizes all fields in the snapchat_pixel_code option
    425437        register_setting( 'snap-pixel-general', 'snapchat_pixel_code', array( $this, 'sanitize_general_settings' ) );
    426438       
    427439        // Register WooCommerce settings
    428         register_setting( 'snap-pixel-woocommerce', 'snapchat_pixel_wooacces' );
    429         register_setting( 'snap-pixel-woocommerce', 'snapchat_pixel_woo' );
     440        // The sanitize_checkbox method ensures the value is either 'yes' or 'no'
     441        register_setting( 'snap-pixel-woocommerce', 'snapchat_pixel_wooacces', array( $this, 'sanitize_checkbox' ) );
    430442       
    431443        // Register EDD settings
    432         register_setting( 'snap-pixel-edd', 'snapchat_pixel_edd_access' );
    433         register_setting( 'snap-pixel-edd', 'snapchat_pixel_edd' );
     444        // The sanitize_checkbox method ensures the value is either 'yes' or 'no'
     445        register_setting( 'snap-pixel-edd', 'snapchat_pixel_edd_access', array( $this, 'sanitize_checkbox' ) );
     446        register_setting( 'snap-pixel-edd', 'snapchat_pixel_edd', array( $this, 'sanitize_edd_settings' ) );
     447    }
     448   
     449    /**
     450     * Sanitize checkbox value.
     451     *
     452     * @param string $value The value to sanitize.
     453     * @return string Sanitized value.
     454     */
     455    public function sanitize_checkbox( $value ) {
     456        return ( 'yes' === $value ) ? 'yes' : 'no';
     457    }
     458   
     459    /**
     460     * Sanitize EDD settings.
     461     *
     462     * @param array $settings The settings to sanitize.
     463     * @return array Sanitized settings.
     464     */
     465    public function sanitize_edd_settings( $settings ) {
     466        if ( ! is_array( $settings ) ) {
     467            return array();
     468        }
     469       
     470        $sanitized = array();
     471       
     472        foreach ( $settings as $key => $value ) {
     473            if ( in_array( $key, array( 'view_content', 'add_cart', 'checkout', 'purchase' ), true ) ) {
     474                $sanitized[ $key ] = ( 'yes' === $value ) ? 'yes' : 'no';
     475            } else {
     476                $sanitized[ $key ] = sanitize_text_field( $value );
     477            }
     478        }
     479       
     480        return $sanitized;
    434481    }
    435482}
  • snap-pixel/tags/1.8.0/includes/class-snap-pixel-core.php

    r3252591 r3252605  
    158158               
    159159                if ( 'checkout' === $page_slug ) {
     160                    // This is checking for the existence of a URL parameter, not processing form data,
     161                    // so nonce verification is not applicable here
    160162                    if ( ! isset( $_GET['key'] ) && 'checked' === $this->settings['checkout'] ) {
    161163                        add_action( 'wp_footer', array( $this, 'output_checkout_pixel_code' ) );
     
    401403        global $woocommerce;
    402404       
    403         $key = isset( $_GET['key'] ) ? sanitize_text_field( wp_unslash( $_GET['key'] ) ) : '';
     405        // Check if key exists and verify nonce if it's from a form submission
     406        if ( isset( $_GET['key'] ) ) {
     407            $key = sanitize_text_field( wp_unslash( $_GET['key'] ) );
     408           
     409            // For WooCommerce order-received endpoint, the key is part of the URL and not from a form submission
     410            // so we don't need to verify a nonce in this specific case. This is a standard WooCommerce URL parameter
     411            // used for order identification and not for processing form submissions.
     412        } else {
     413            $key = '';
     414        }
     415       
    404416        $order_id = $this->get_order_id_by_key( $key );
    405417       
     
    420432        $product_ids = array();
    421433        foreach ( $order->get_items() as $item ) {
    422             $product_id = $item->get_product_id();
     434            // Access product_id directly from the item data
     435            $item_data = $item->get_data();
     436            $product_id = isset( $item_data['product_id'] ) ? $item_data['product_id'] : 0;
     437           
    423438            if ( $product_id ) {
    424439                $product_ids[] = $product_id;
     
    426441        }
    427442        if(count($product_ids) > 0){
    428             $content_ids_string = implode(',', $product_ids);
     443            $content_ids_string = $product_ids;
    429444        } else {
    430445            $content_ids_string = $order_id;
     
    438453                'price': <?php echo esc_js( $order_total ); ?>,
    439454                'transaction_id': "<?php echo esc_js( $order_id ); ?>",
    440                 'item_ids': ["<?php echo esc_js( $content_ids_string ); ?>"]
     455                'item_ids': content_ids_string
    441456            });
    442457           
     
    450465            'price' => $order_total,
    451466            'transaction_id' => $order_id,
    452             'item_ids' => array($content_ids_string)
     467            'item_ids' => $content_ids_string
    453468        );
    454469        do_action( 'snap_pixel_event_fired', 'PURCHASE', $event_data );
     
    559574     */
    560575    private function get_order_id_by_key( $key ) {
    561         global $wpdb;
    562        
    563576        if ( empty( $key ) ) {
    564577            return false;
    565578        }
    566579       
    567         $query = $wpdb->prepare(
    568             "SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key='_order_key' AND meta_value=%s ORDER BY meta_id DESC LIMIT 1",
    569             $key
    570         );
    571        
    572         $result = $wpdb->get_row( $query );
     580        // Check cache first
     581        $cache_key = 'snap_pixel_order_' . md5($key);
     582        $order_id = wp_cache_get( $cache_key, 'snap_pixel' );
     583       
     584        if ( false !== $order_id ) {
     585            return $order_id;
     586        }
     587       
     588        global $wpdb;
     589       
     590        $result = $wpdb->get_row(
     591            $wpdb->prepare(
     592                "SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key='_order_key' AND meta_value=%s ORDER BY meta_id DESC LIMIT 1",
     593                $key
     594            )
     595        );
    573596       
    574597        if ( $result ) {
     598            // Cache the result for future use
     599            wp_cache_set( $cache_key, $result->post_id, 'snap_pixel', 3600 ); // Cache for 1 hour
    575600            return $result->post_id;
    576601        }
    577602       
     603        // Cache the negative result as well
     604        wp_cache_set( $cache_key, 0, 'snap_pixel', 3600 ); // Cache for 1 hour
    578605        return false;
    579606    }
  • snap-pixel/tags/1.8.0/readme.txt

    r3252591 r3252605  
    44Plugin URI: https://wordpress.org/plugins/snap-pixel
    55Donate link: https://paypal.me/coresol
    6 Tags: snapchat, snap pixel, snapchat pixel, snapchat tracking, snapchat ads, ecommerce tracking, woocommerce
     6Tags: snapchat, snap pixel, snapchat pixel, snapchat tracking, woocommerce
    77Requires at least: 5.0
    8 Tested up to: 6.6.2
     8Tested up to: 6.7.2
    99Requires PHP: 5.6
    1010Stable tag: 1.8.0
     
    4444* Filter events by date range and type
    4545
    46 **2. Snap Pixel Advanced E-commerce**
    47 
    48 Take your WooCommerce tracking to the next level with advanced e-commerce features designed to maximize your Snapchat advertising ROI.
    49 
    50 Features:
    51 * Enhanced product data tracking
    52 * Cart abandonment tracking
    53 * Product category and collection tracking
    54 * Customer lifetime value insights
    55 * Cross-sell and upsell event tracking
    56 
    57 **3. Snap Pixel Conversion API**
    58 
    59 Implement server-side tracking for more reliable conversion data, especially in environments with ad blockers or privacy restrictions.
    60 
    61 Features:
    62 * Server-side event tracking
    63 * Improved tracking reliability
    64 * Better handling of ad blockers
    65 * Enhanced privacy compliance
    66 * Dual tracking (browser + server) capabilities
    67 
    68 **4. Snap Pixel for Membership Sites**
     46**2. Snap Pixel for Membership Sites (Future)**
    6947
    7048Specialized tracking for membership sites and subscription-based businesses using popular plugins like MemberPress, WooCommerce Subscriptions, and more.
  • snap-pixel/trunk/readme.txt

    r3252591 r3252605  
    44Plugin URI: https://wordpress.org/plugins/snap-pixel
    55Donate link: https://paypal.me/coresol
    6 Tags: snapchat, snap pixel, snapchat pixel, snapchat tracking, snapchat ads, ecommerce tracking, woocommerce
     6Tags: snapchat, snap pixel, snapchat pixel, snapchat tracking, woocommerce
    77Requires at least: 5.0
    88Tested up to: 6.7.2
Note: See TracChangeset for help on using the changeset viewer.