The functionality works like this:
1. First we add checkbox to the registration form asking the user if he has a loyalty code if he checks the checkbox we display an input field for the code.
2. Second we validate the input field and check if the code contains only numbers.
3. Third after the user is registered we display the code in the my account page (edit account section) with an option to edit or delete the code.
4. Fourth we apply automatically a 10% discount to the user orders but only for products with regular price. The discount is not applied for products with sale price and it is removed completely if a coupon is applied to the order.
```php
/* Add the loyalty code field to the registration form */
add_action( 'woocommerce_register_form', 'add_loyalty_code_field' );
function add_loyalty_code_field() {
?>
<p class="woocommerce-form-row form-row form-row-wide">
<label for="has_loyalty_code">
<input type="checkbox" id="has_loyalty_code" name="has_loyalty_code" value="yes" <?php checked( isset( $_POST['has_loyalty_code'] ), true ); ?> />
<?php esc_html_e( 'Do you have a loyalty code?' ); ?>
</label>
</p>
<p class="woocommerce-form-row form-row form-row-wide" id="loyalty_code_field" style="display: none;">
<label for="loyalty_code"><?php esc_html_e( 'Your loyalty code (Numbers Only)' ); ?></label>
<input type="number" class="input-text" name="loyalty_code" id="loyalty_code" value="<?php if ( ! empty( $_POST['loyalty_code'] ) ) echo esc_attr( $_POST['loyalty_code'] ); ?>" />
</p>
<script type="text/javascript">
(function($) {
$('#has_loyalty_code').change(function() {
if ($(this).is(':checked')) {
$('#loyalty_code_field').show();
} else {
$('#loyalty_code_field').hide();
}
});
})(jQuery);
</script>
<?php
}
/* Validate the loyalty code field */
add_action( 'woocommerce_register_post', 'validate_loyalty_code_field', 10, 3 );
function validate_loyalty_code_field( $username, $email, $validation_errors ) {
if ( isset( $_POST['loyalty_code'] ) && ! is_numeric( $_POST['loyalty_code'] ) ) {
$validation_errors->add( 'loyalty_code_error', __( 'Loyalty code must be a numeric value.' ) );
}
}
/* Save the loyalty code field value */
add_action( 'woocommerce_created_customer', 'save_loyalty_code_field' );
function save_loyalty_code_field( $customer_id ) {
if ( isset( $_POST['has_loyalty_code'] ) && $_POST['has_loyalty_code'] === 'yes' ) {
if ( empty( $_POST['loyalty_code'] ) ) {
$validation_errors->add( 'loyalty_code_error', __( 'Please enter your loyalty code.', 'woocommerce' ) );
} elseif ( ! is_numeric( $_POST['loyalty_code'] ) ) {
$validation_errors->add( 'loyalty_code_error', __( 'Loyalty code must be a numeric value.', 'woocommerce' ) );
}
}
}
/* Add the loyalty code field to the edit account form */
add_action( 'woocommerce_edit_account_form', 'add_loyalty_code_to_edit_account' );
function add_loyalty_code_to_edit_account() {
$user_id = get_current_user_id();
$loyalty_code = get_user_meta( $user_id, 'loyalty_code', true );
?>
<p class="woocommerce-form-row form-row form-row-wide">
<label for="loyalty_code"><?php esc_html_e( 'Your loyalty code' ); ?></label>
<input type="number" class="input-text" name="loyalty_code" id="loyalty_code" value="<?php echo esc_attr( $loyalty_code ); ?>" />
<span class="description"><?php esc_html_e( 'You can update or remove your loyalty code by leaving this field empty.' ); ?></span>
</p>
<?php
}
/* Save the loyalty code when the user updates their account */
add_action( 'woocommerce_save_account_details', 'save_loyalty_code_on_account_update' );
function save_loyalty_code_on_account_update( $user_id ) {
if ( isset( $_POST['loyalty_code'] ) ) {
$loyalty_code = sanitize_text_field( $_POST['loyalty_code'] );
if ( ! empty( $loyalty_code ) && ! is_numeric( $loyalty_code ) ) {
wc_add_notice( __( 'Loyalty code must be a numeric value.', 'woocommerce' ), 'error' );
} else {
// Save or delete the loyalty code based on the field's value
if ( empty( $loyalty_code ) ) {
delete_user_meta( $user_id, 'loyalty_code' );
} else {
update_user_meta( $user_id, 'loyalty_code', $loyalty_code );
}
}
}
}
/* Apply the loyalty discount */
add_action( 'woocommerce_cart_calculate_fees', 'apply_loyalty_discount' );
function apply_loyalty_discount( $cart ) {
$currentlang = get_bloginfo('language');
// Stop execution in the admin or during AJAX requests
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( ! is_user_logged_in() ) return;
$user_id = get_current_user_id();
$loyalty_code = get_user_meta( $user_id, 'loyalty_code', true );
// Only proceed if the user has a loyalty code
if ( $loyalty_code ) {
// Check if any coupons are applied
if ( $cart->has_discount() ) {
return; // Skip the discount if a coupon is applied
}
$discount = 0;
// Loop through cart items to calculate discount
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
// Skip products with a sale price
if ( ! $product->is_on_sale() ) {
$product_price = $product->get_regular_price();
$quantity = $cart_item['quantity'];
// Add 10% of the regular price multiplied by quantity to the discount
$discount += $product_price * $quantity * 0.10;
}
}
// Apply the discount if greater than 0
if ( $discount > 0 ) {
$cart->add_fee( __( 'Loyalty Discount' ), -$discount, false );
}
}
}
```