Changeset 3252605
- Timestamp:
- 03/08/2025 06:53:26 PM (13 months ago)
- Location:
- snap-pixel
- Files:
-
- 7 edited
-
tags/1.8.0/README.md (modified) (1 diff)
-
tags/1.8.0/admin/admin-display.php (modified) (1 diff)
-
tags/1.8.0/admin/partials/edd-tab.php (modified) (1 diff)
-
tags/1.8.0/includes/class-snap-pixel-admin.php (modified) (5 diffs)
-
tags/1.8.0/includes/class-snap-pixel-core.php (modified) (7 diffs)
-
tags/1.8.0/readme.txt (modified) (2 diffs)
-
trunk/readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
snap-pixel/tags/1.8.0/README.md
r3252591 r3252605 29 29 - Filter events by date range and type 30 30 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) 54 32 55 33 Specialized 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 28 28 $ajax_addtocart = isset( $settings['ajax_addtocart'] ) ? $settings['ajax_addtocart'] : ''; 29 29 30 // Get current tab 30 // Get current tab - this is just for UI display, not processing form data, so nonce verification is not needed 31 31 $current_tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : 'general'; 32 32 -
snap-pixel/tags/1.8.0/admin/partials/edd-tab.php
r3252591 r3252605 18 18 19 19 // 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'; 24 24 ?> 25 25 -
snap-pixel/tags/1.8.0/includes/class-snap-pixel-admin.php
r3252591 r3252605 252 252 */ 253 253 private function display_edd_tab() { 254 // Process form submission255 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 setting261 $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 settings265 $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 message269 add_settings_error( 'snap-pixel', 'settings_updated', esc_html__( 'EDD settings saved successfully.', 'snap-pixel' ), 'success' );270 }271 272 254 // EDD settings 273 255 $edd_active = class_exists( 'Easy_Digital_Downloads' ); … … 289 271 */ 290 272 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 294 274 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 ); 300 285 } 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' ); 303 330 } 304 331 … … 306 333 if ( isset( $_POST['snapchat_pixel_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['snapchat_pixel_nonce'] ) ), 'snapchat_pixel_security' ) ) { 307 334 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'] ) ); 309 337 310 338 // Get existing settings to preserve WooCommerce settings … … 338 366 } 339 367 } 340 341 // Process WooCommerce settings - improved handling342 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 settings349 $existing_settings = get_option( 'snapchat_pixel_code', array() );350 $sanitized_data = $existing_settings;351 352 // Update WooCommerce activation status353 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 settings361 if ( 'yes' === $woo_activate ) {362 // WooCommerce is enabled, process settings363 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 settings368 $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 unchecked377 $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 settings385 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 }405 368 } 406 369 … … 419 382 420 383 /** 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 /** 421 432 * Register settings. 422 433 */ 423 434 public function register_settings() { 424 435 // Register general settings 436 // The sanitize_general_settings method properly sanitizes all fields in the snapchat_pixel_code option 425 437 register_setting( 'snap-pixel-general', 'snapchat_pixel_code', array( $this, 'sanitize_general_settings' ) ); 426 438 427 439 // 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' ) ); 430 442 431 443 // 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; 434 481 } 435 482 } -
snap-pixel/tags/1.8.0/includes/class-snap-pixel-core.php
r3252591 r3252605 158 158 159 159 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 160 162 if ( ! isset( $_GET['key'] ) && 'checked' === $this->settings['checkout'] ) { 161 163 add_action( 'wp_footer', array( $this, 'output_checkout_pixel_code' ) ); … … 401 403 global $woocommerce; 402 404 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 404 416 $order_id = $this->get_order_id_by_key( $key ); 405 417 … … 420 432 $product_ids = array(); 421 433 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 423 438 if ( $product_id ) { 424 439 $product_ids[] = $product_id; … … 426 441 } 427 442 if(count($product_ids) > 0){ 428 $content_ids_string = implode(',', $product_ids);443 $content_ids_string = $product_ids; 429 444 } else { 430 445 $content_ids_string = $order_id; … … 438 453 'price': <?php echo esc_js( $order_total ); ?>, 439 454 'transaction_id': "<?php echo esc_js( $order_id ); ?>", 440 'item_ids': ["<?php echo esc_js( $content_ids_string ); ?>"]455 'item_ids': content_ids_string 441 456 }); 442 457 … … 450 465 'price' => $order_total, 451 466 'transaction_id' => $order_id, 452 'item_ids' => array($content_ids_string)467 'item_ids' => $content_ids_string 453 468 ); 454 469 do_action( 'snap_pixel_event_fired', 'PURCHASE', $event_data ); … … 559 574 */ 560 575 private function get_order_id_by_key( $key ) { 561 global $wpdb;562 563 576 if ( empty( $key ) ) { 564 577 return false; 565 578 } 566 579 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 ); 573 596 574 597 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 575 600 return $result->post_id; 576 601 } 577 602 603 // Cache the negative result as well 604 wp_cache_set( $cache_key, 0, 'snap_pixel', 3600 ); // Cache for 1 hour 578 605 return false; 579 606 } -
snap-pixel/tags/1.8.0/readme.txt
r3252591 r3252605 4 4 Plugin URI: https://wordpress.org/plugins/snap-pixel 5 5 Donate link: https://paypal.me/coresol 6 Tags: snapchat, snap pixel, snapchat pixel, snapchat tracking, snapchat ads, ecommerce tracking,woocommerce6 Tags: snapchat, snap pixel, snapchat pixel, snapchat tracking, woocommerce 7 7 Requires at least: 5.0 8 Tested up to: 6. 6.28 Tested up to: 6.7.2 9 9 Requires PHP: 5.6 10 10 Stable tag: 1.8.0 … … 44 44 * Filter events by date range and type 45 45 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)** 69 47 70 48 Specialized tracking for membership sites and subscription-based businesses using popular plugins like MemberPress, WooCommerce Subscriptions, and more. -
snap-pixel/trunk/readme.txt
r3252591 r3252605 4 4 Plugin URI: https://wordpress.org/plugins/snap-pixel 5 5 Donate link: https://paypal.me/coresol 6 Tags: snapchat, snap pixel, snapchat pixel, snapchat tracking, snapchat ads, ecommerce tracking,woocommerce6 Tags: snapchat, snap pixel, snapchat pixel, snapchat tracking, woocommerce 7 7 Requires at least: 5.0 8 8 Tested up to: 6.7.2
Note: See TracChangeset
for help on using the changeset viewer.