= $min && strlen( $national ) <= $max; // Mobile prefixes are a store-country rule; customers from other countries are not held to it. $prefixes = codg_list( 'phone_prefixes' ); if ( $valid && $prefixes && $country === codg_store_country() ) { $valid = false; foreach ( $prefixes as $prefix ) { if ( 0 === strpos( ltrim( $national, '0' ), ltrim( preg_replace( '/\D+/', '', $prefix ), '0' ) ) ) { $valid = true; break; } } } if ( ! $valid ) { $errors->add( 'codg_phone', codg_opt( 'phone_message', __( 'Please enter a valid mobile phone number so we can confirm your order.', 'orderproof' ) ) ); return $errors; } // 2. Blacklist. $phones = array_map( function ( $p ) use ( $country ) { return codg_normalize_phone( $p, $country ); }, codg_list( 'blacklist_phones' ) ); $emails = array_map( 'strtolower', codg_list( 'blacklist_emails' ) ); $ips = codg_list( 'blacklist_ips' ); if ( in_array( $intl, $phones, true ) || ( $email && in_array( $email, $emails, true ) ) || ( $ip && in_array( $ip, $ips, true ) ) ) { $errors->add( 'codg_blacklisted', $blocked ); return $errors; } // 3. Too many orders from the same phone. $limit = (int) codg_opt( 'limit_orders', 2 ); $hours = max( 1, (int) codg_opt( 'limit_hours', 24 ) ); if ( $limit > 0 ) { $recent = wc_get_orders( array( 'limit' => $limit, 'return' => 'ids', 'status' => array_keys( wc_get_order_statuses() ), 'date_created' => '>' . ( time() - $hours * HOUR_IN_SECONDS ), ) + codg_phone_query_args( $intl ) ); if ( count( $recent ) >= $limit ) { $errors->add( 'codg_limit', codg_opt( 'limit_message', __( 'You already placed an order recently. We will contact you shortly to confirm it.', 'orderproof' ) ) ); return $errors; } } /** * Let add-ons (and Pro) add more checks. */ return apply_filters( 'codg_validate', $errors, $intl, $email, $ip ); } public static function classic_validation( $data, $wc_errors ) { if ( $wc_errors->has_errors() ) { return; // Let WooCommerce show its own errors first. } $phone = isset( $data['billing_phone'] ) ? $data['billing_phone'] : ''; $result = self::validate( $phone, isset( $data['billing_email'] ) ? $data['billing_email'] : '', isset( $data['payment_method'] ) ? $data['payment_method'] : '', isset( $data['billing_country'] ) ? $data['billing_country'] : '' ); foreach ( $result->get_error_codes() as $code ) { $wc_errors->add( $code, $result->get_error_message( $code ) ); } self::log_block( $result, $phone ); } public static function blocks_validation( $order, $request ) { $result = self::validate( $order->get_billing_phone(), $order->get_billing_email(), $request['payment_method'], $order->get_billing_country() ); if ( $result->has_errors() ) { self::log_block( $result, $order->get_billing_phone() ); throw new \Automattic\WooCommerce\StoreApi\Exceptions\RouteException( esc_html( $result->get_error_code() ), esc_html( $result->get_error_message() ), 400 ); } } public static function store_phone_classic( $order_id, $posted, $order ) { self::store_phone( $order ); } /** * Save the normalized phone so orders can be matched later. */ public static function store_phone( $order ) { if ( ! $order instanceof WC_Order ) { return; } $order->update_meta_data( '_codg_phone', codg_normalize_phone( $order->get_billing_phone(), $order->get_billing_country() ) ); $order->save(); } /** * Count blocked orders (shown on the settings page). */ private static function log_block( WP_Error $result, $phone ) { if ( ! $result->has_errors() ) { return; } update_option( 'codg_blocked_count', (int) get_option( 'codg_blocked_count', 0 ) + 1, false ); do_action( 'codg_order_blocked', $result, $phone ); } }