diff --git a/includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php b/includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php index 0cbb9453761..5c92e897259 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php @@ -257,7 +257,7 @@ class WC_Meta_Box_Coupon_Data { 'id' => 'customer_email', 'label' => __( 'Email restrictions', 'woocommerce' ), 'placeholder' => __( 'No restrictions', 'woocommerce' ), - 'description' => __( 'List of allowed emails to check against the customer billing email when an order is placed. Separate email addresses with commas.', 'woocommerce' ), + 'description' => __( 'List of allowed emails to check against the customer billing email when an order is placed. Separate email addresses with commas. You can also use an asterisk (*) to match parts of an email. For example "*@gmail.com" would match all gmail addresses.', 'woocommerce' ), 'value' => implode( ', ', (array) $coupon->get_email_restrictions() ), 'desc_tip' => true, 'type' => 'email', diff --git a/includes/class-wc-cart.php b/includes/class-wc-cart.php index a9f4cc2b76a..3de50c12bef 100644 --- a/includes/class-wc-cart.php +++ b/includes/class-wc-cart.php @@ -1451,7 +1451,7 @@ class WC_Cart extends WC_Legacy_Cart { // Limit to defined email addresses. $restrictions = $coupon->get_email_restrictions(); - if ( is_array( $restrictions ) && 0 < count( $restrictions ) && 0 === count( array_intersect( $check_emails, $restrictions ) ) ) { + if ( is_array( $restrictions ) && 0 < count( $restrictions ) && ! $this->is_coupon_emails_allowed( $check_emails, $restrictions ) ) { $coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_NOT_YOURS_REMOVED ); $this->remove_coupon( $code ); } @@ -1498,6 +1498,37 @@ class WC_Cart extends WC_Legacy_Cart { } } + /** + * Checks if the given email address(es) matches the ones specified on the coupon. + * + * @param array $check_emails Array of customer email addresses. + * @param array $restrictions Array of allowed email addresses. + * @return bool + */ + public function email_is_accepted( $check_emails, $restrictions ){ + + foreach ( $check_emails as $check_email ) { + // With a direct match we return true. + if ( in_array( $check_email, $restrictions ) ) { + return true; + } + + // Go through the allowed emails and return true if the email matches a wildcard. + foreach ( $restrictions as $restriction ) { + // Convert to PHP-regex syntax. + $regex = '/' . str_replace( '*', '(.+)?', $restriction ) . '/'; + preg_match( $regex, $check_email, $match ); + if ( ! empty( $match ) ) { + return true; + } + } + } + + // No matches, this one isn't allowed. + return false; + } + + /** * Returns whether or not a discount has been applied. *