WooCommerce Points and Rewards –
2 Custom Snippets

Last Updated on: 5th January 2024, 04:51 pm

I have done some custom development recently for the WooCommerce Points and Rewards plugin. There were two scenarios we solved with custom code and I thought I share them here, in case anybody runs into a similar scenario:

  1. Limit Points for First Review Only.
  2. Allocate Points in Bulk.

Limit Points for First Review Only.

WooCommerce Points and Rewards offers an option to receive points for writing a review, but this applies to every time the customer leaves a review. Here is a way to alter it, so points will only be rewarded for their first product review. This is to prevent people from leaving reviews on every product without having purchased the product in order to farm points.

<?php
/**
 * Plugin Name: Limit Points for First Review Only
 * Description: Adjusts WooCommerce Points and Rewards to only award points for the first product review by a customer, with nonce verification for security.
 * Author: Your Name
 * Version: 1.0
 */
// Add a nonce field to the product review form
add_action('comment_form_logged_in_after', 'add_review_nonce_to_form');
add_action('comment_form_after_fields', 'add_review_nonce_to_form');
function add_review_nonce_to_form() {
    if (get_post_type() === 'product') {
        wp_nonce_field('add_product_review_nonce', 'product_review_nonce');
    }
}
// Hook into the 'comment_post' action which is triggered when a new comment is created.
add_action('comment_post', 'limit_review_points_to_first', 10, 3);
function limit_review_points_to_first($comment_ID, $comment_approved, $commentdata) {
    if ('product' !== get_post_type($commentdata['comment_post_ID'])) {
        return;
    }
    // Verify the nonce. If it's not set or is invalid, bail out.
    if (!isset($_POST['product_review_nonce']) || !wp_verify_nonce($_POST['product_review_nonce'], 'add_product_review_nonce')) {
        wp_die('Security check failed.');
    }
    if (empty($commentdata['user_id'])) {
        return;
    }
    // Check if user has already made a review and received points.
    $user_id = $commentdata['user_id'];
    $has_reviewed = get_user_meta($user_id, '_has_reviewed', true);
    if ('1' === $has_reviewed) {
        // User has already made a review and should not receive points again.
        remove_action('woocommerce_review_order_before_cart_contents', ['WC_Points_Rewards_Product_Review', 'maybe_add_review_points']);
    } else {
        // Mark that the user has reviewed a product.
        update_user_meta($user_id, '_has_reviewed', '1');
    }
}

As always ​test this plugin on a staging site to verify that it works as expected before deploying it to your live site.

Allocate Points in Bulk.

To apply points for existing account customers there is no bulk upload option besides the option to apply points to previous orders. For example when you raise the amount of signup points you may want to grant everyone this amount that is already a customer. Here is a function to do this. Remember to comment out the last line to actually run the function.

function allocate_signup_points_to_existing_users() {
    $args = array(
        'role'    => 'customer',
        'orderby' => 'user_registered',
        'order'   => 'ASC',
        'fields' => 'all_with_meta',
    );
   
    $users = get_users($args);
    foreach ($users as $user) {
        $signup_points = 100; // Replace with the number of points you want to allocate.
        WC_Points_Rewards_Manager::increase_points($user->ID, $signup_points, 'signup-bonus');
    }
}

// Run this function only once, then remove it or comment it out to prevent it from running again.
// allocate_signup_points_to_existing_users();

I like using https://wordpress.org/plugins/wp-console/ to execute the above. Remember to back up all the things prior to running any custom code.

Happy customising.

Leave a Reply

Your email address will not be published. Required fields are marked *

Con Schneider