Created
October 26, 2026 10:38
-
-
Save xlplugins/ea88e315722eea62dff85614d5c5cce8 to your computer and use it in GitHub Desktop.
FunnelKit phone trace (temporary). Logs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * FunnelKit phone trace (temporary). Logs, for express wallet orders only, the billing/shipping phone | |
| * at each step from the wallet to WooCommerce's validation, with every digit masked as "9". | |
| * Log: WooCommerce > Status > Logs > source "fk-phone-trace". | |
| */ | |
| add_action( 'woocommerce_before_checkout_process', function () { | |
| if ( empty( $_POST['payment_request_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| return; // Not an express wallet order. | |
| } | |
| $mask = function ( $v ) { | |
| $v = preg_replace( '/[0-9]/', '9', (string) $v ); | |
| return '"' . $v . '" hex ' . bin2hex( $v ); | |
| }; | |
| $log = function ( $msg ) { | |
| wc_get_logger()->info( $msg, array( 'source' => 'fk-phone-trace' ) ); | |
| }; | |
| $who = function ( $hook ) { | |
| global $wp_filter; | |
| $out = array(); | |
| if ( empty( $wp_filter[ $hook ] ) ) { | |
| return 'none'; | |
| } | |
| foreach ( $wp_filter[ $hook ]->callbacks as $prio => $cbs ) { | |
| foreach ( $cbs as $cb ) { | |
| try { | |
| $f = $cb['function']; | |
| $ref = is_array( $f ) ? new ReflectionMethod( $f[0], $f[1] ) : new ReflectionFunction( $f ); | |
| $out[] = $prio . ' ' . str_replace( ABSPATH, '', $ref->getFileName() ) . ':' . $ref->getStartLine(); | |
| } catch ( Throwable $e ) { | |
| $out[] = $prio . ' ?'; | |
| } | |
| } | |
| } | |
| return implode( ' | ', $out ); | |
| }; | |
| // 1. Exactly what the wallet sent. | |
| $log( sprintf( '1 wallet: type=%s billing=%s shipping=%s ua=%s', | |
| sanitize_text_field( wp_unslash( $_POST['payment_request_type'] ) ), // phpcs:ignore | |
| $mask( wp_unslash( $_POST['billing_phone'] ?? '' ) ), // phpcs:ignore | |
| $mask( wp_unslash( $_POST['shipping_phone'] ?? '' ) ), // phpcs:ignore | |
| sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ?? '' ) ) | |
| ) ); | |
| // 2. Who can change or reject the phone on this site. | |
| foreach ( array( 'woocommerce_process_checkout_field_billing_phone', 'woocommerce_process_checkout_tel_field', 'woocommerce_checkout_posted_data', 'woocommerce_validate_phone' ) as $hook ) { | |
| $log( '2 hooked on ' . $hook . ': ' . $who( $hook ) ); | |
| } | |
| // 3. The phone right before your own filter (priority 5) runs. | |
| add_filter( 'woocommerce_checkout_posted_data', function ( $data ) use ( $log, $mask ) { | |
| $log( '3 before your filter: billing=' . $mask( $data['billing_phone'] ?? '' ) ); | |
| return $data; | |
| }, 4 ); | |
| // 4. The phone after every filter, i.e. what WooCommerce validates. | |
| add_filter( 'woocommerce_checkout_posted_data', function ( $data ) use ( $log, $mask ) { | |
| $log( '4 after all filters: billing=' . $mask( $data['billing_phone'] ?? '' ) ); | |
| return $data; | |
| }, PHP_INT_MAX ); | |
| // 5. WooCommerce's verdict: format check alone vs. final result after other plugins. | |
| add_filter( 'woocommerce_validate_phone', function ( $valid, $phone ) use ( $log, $mask ) { | |
| $log( sprintf( '5 validate: phone=%s format_ok=%s final=%s', $mask( $phone ), WC_Validation::is_phone_format( $phone ) ? 'yes' : 'no', $valid ? 'valid' : 'INVALID' ) ); | |
| return $valid; | |
| }, PHP_INT_MAX, 2 ); | |
| }, 1 ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment