Groups (use group/role discounts), by itthinx
Groups by itthinx is a popular WordPress plugin for managing user groups and access control. Unlike WordPress’s native role system, Groups creates and manages its own group memberships stored in custom database tables — meaning standard WordPress role-based conditions in Advanced Dynamic Pricing for WooCommerce cannot detect them out of the box.
This article explains how to bridge the two plugins using two filter hooks that expose Groups memberships to Advanced Dynamic Pricing’s rule engine — enabling you to create group-based discount rules just like role-based ones, targeting specific customer groups with tailored pricing.
Required Settings Before Adding the Code
Two plugin settings must be configured correctly before applying the compatibility code. Without these, group-based pricing rules will not fire correctly.
In Advanced Dynamic Pricing → Settings → Calculation:
| Setting | Required value |
|---|---|
| Use prices modified by other plugins | ✅ Must be ON |
In Advanced Dynamic Pricing → Settings → System:
| Setting | Required value |
|---|---|
| Suppress other pricing plugins in frontend | ❌ Must be OFF |
⚠️ Save both settings pages before applying the code snippet below.
Code Sample
Add the following snippet to your child theme’s functions.php or the Code Snippets plugin:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
add_filter( 'wdp_preloaded_list_user_roles', function ( $list ) { $groups = array(); if ( function_exists( '_groups_get_tablename' ) ) { global $wpdb; $groups_table = _groups_get_tablename( 'group' ); $groups = $wpdb->get_results( "SELECT * FROM $groups_table ORDER BY name" ); } $groups = is_array( $groups ) ? $groups : array(); foreach ( $groups as $group ) { $list[] = array( 'id' => '(group)' . strtolower( $group->name ), 'text' => '(group) ' . $group->name, ); } return $list; } ); add_filter( 'wdp_current_user_roles', function ( $roles ) { $groups = array(); $current_user_id = get_current_user_id(); if ( function_exists( '_groups_get_tablename' ) && $current_user_id ) { global $wpdb; $groups_table = _groups_get_tablename( 'group' ); $user_group_table = _groups_get_tablename( 'user_group' ); $groups = $wpdb->get_results( "SELECT * FROM {$groups_table} WHERE {$groups_table}.group_id IN (SELECT group_id FROM {$user_group_table} WHERE {$user_group_table}.user_id = {$current_user_id} ) ORDER BY name" ); } $groups = is_array( $groups ) ? $groups : array(); foreach ( $groups as $group ) { $roles[] = '(group)' . strtolower( $group->name ); } return $roles; } ); |
Code Explained (for Developers)
The snippet provides two complementary filters. The first populates the admin rule builder with your Groups groups. The second tells the pricing rule engine which groups the currently logged-in customer belongs to at runtime.
Filter 1 — wdp_preloaded_list_user_roles
This filter populates the role/group dropdown in the Advanced Dynamic Pricing rule editor so that your Groups groups appear alongside standard WordPress roles when creating conditions.
| Element | Description |
|---|---|
wdp_preloaded_list_user_roles | An Advanced Dynamic Pricing filter that provides the list of available roles and groups shown in the rule builder’s user role/group condition selector. |
$list | An array of existing entries, each with an 'id' and 'text' key. WordPress roles are already present here; this filter appends Groups groups to the same array. |
function_exists( '_groups_get_tablename' ) | Safety check — confirms the Groups plugin is active and its internal functions are available before attempting any database queries. Prevents PHP fatal errors if Groups is deactivated. |
_groups_get_tablename( 'group' ) | Groups plugin internal function that returns the correct prefixed database table name for the groups table (e.g. wp_groups_group). |
$wpdb->get_results(...) | Fetches all groups from the Groups database table, ordered alphabetically by name. |
'id' => '(group)' . strtolower( $group->name ) | Constructs a unique identifier for each group using the (group) prefix followed by the lowercase group name. This prefix distinguishes Groups entries from standard WordPress role IDs in the rule engine. |
'text' => '(group) ' . $group->name | The human-readable label displayed in the rule builder dropdown, showing the (group) prefix and the original group name with its original casing. |
Result: After applying this filter, when you create or edit a pricing rule in Advanced Dynamic Pricing and add a User Role condition, your Groups groups will appear in the dropdown prefixed with
(group)— for example:(group) wholesalers,(group) vip customers.
Filter 2 — wdp_current_user_roles
This filter injects the current user’s group memberships into the pricing rule engine at runtime, so rules that target specific groups are evaluated correctly for each customer.
| Element | Description |
|---|---|
wdp_current_user_roles | An Advanced Dynamic Pricing filter that provides the list of role/group identifiers for the currently logged-in user. The rule engine compares this list against the conditions defined in each rule to determine which rules apply. |
$roles | The existing array of role identifiers for the current user — standard WordPress roles are already present. This filter appends the user’s Groups memberships. |
get_current_user_id() | Returns the WordPress user ID of the currently logged-in customer. Returns 0 for guests — the database query is skipped in that case since guests have no group memberships. |
_groups_get_tablename( 'user_group' ) | Returns the correct prefixed name of the Groups user-group relationship table (e.g. wp_groups_user_group), which maps user IDs to group IDs. |
| Subquery | SELECT group_id FROM {$user_group_table} WHERE user_id = {$current_user_id} retrieves all group IDs the current user belongs to. The outer query then fetches the full group records for those IDs. |
$roles[] = '(group)' . strtolower( $group->name ) | Appends each group membership as a role identifier using the same (group) prefix pattern used in Filter 1. This ensures the IDs match correctly when the rule engine evaluates conditions. |
Result: When a logged-in customer views a product or adds an item to the cart, Advanced Dynamic Pricing checks their group memberships via this filter and applies any rules that target their group(s) — exactly as it would for standard WordPress role-based rules.
How It Works Together
The two filters work as a matched pair:
| Filter | Purpose | When it fires |
|---|---|---|
wdp_preloaded_list_user_roles | Populates the admin rule builder dropdown with Groups groups | When editing a pricing rule in the WordPress admin |
wdp_current_user_roles | Tells the rule engine which groups the current customer belongs to | On every product page, shop page, cart, and checkout load |
Without Filter 1, you cannot select a group as a rule condition in the admin. Without Filter 2, the rule engine would not know the customer is in a group even if a rule exists for it. Both must be active.
Creating a Group-Based Pricing Rule
Once the snippet is in place:
- Go to Advanced Dynamic Pricing → Rules → Add New Rule.
- In the Cart Conditions or Product Filters section, add a User Role condition.
- In the role selector dropdown, look for entries prefixed with
(group)— these are your Groups groups. - Select the target group (e.g.
(group) wholesalers). - Configure your discount (percentage, fixed amount, bulk tiers, etc.).
- Save the rule.
- Log in as a user who is a member of that group and verify the discount is applied.
How to Apply This Code
- Open Advanced Dynamic Pricing → Settings → Calculation and enable “Use prices modified by other plugins”.
- Open Advanced Dynamic Pricing → Settings → System and disable “Suppress other pricing plugins in frontend”.
- Save both settings pages.
- Open Appearance → Theme File Editor or the Code Snippets plugin.
- Paste the full snippet into your child theme’s
functions.phpor create a dedicated snippet. - Save and go to Advanced Dynamic Pricing → Rules to verify that your Groups groups now appear in the User Role condition selector.
⚠️ Always use a child theme or Code Snippets — editing the parent theme’s
functions.phpdirectly will be overwritten on theme updates.