This developer documentation covers the latest version of OneClick Variations Grabber v1.1.0 and how it inherits the codebase of the OneClick Chat to Order plugin.
Table of Contents
- Overview
- Architecture
- WordPress Hooks & Filters
- JavaScript Events & Customization
- Custom Filters
- Action Hooks
- Data Structures
- Extending Functionality
- Best Practices
- Code Examples
Overview
OneClick Variations Grabber is built with extensibility in mind, providing numerous hooks, filters, and customization points for developers. This documentation covers all available developer APIs, hooks, and integration methods.
Key Developer Features
- Extensive Filter System: Modify behavior without touching core files
- Action Hooks: Hook into key plugin events
- JavaScript Events: Frontend customization capabilities
- Modular Architecture: Clean, extensible codebase
- Translation Ready: Full internationalization support
Architecture
File Structure
oneclick-variations-grabber/
├── inc/ # Core functionality
│ ├── simple.php # Simple product handling
│ ├── variable.php # Variable product handling
│ ├── grouped.php # Grouped product handling
│ └── subscription.php # Subscription product handling
├── admin/ # Admin interface
│ ├── inc/settings.php # Settings management
│ └── inc/tabs/ # Admin tab files
└── public/js/ # Frontend JavaScript
├── oneclickvg-variable-product.js
├── oneclickvg-grouped-product.js
├── oneclickvg-subscription.js
└── oneclick-simple-product.js
Core Classes
OCVGCore
: Main plugin initialization and core functionality
WordPress Hooks & Filters
Core OneClick Chat to Order Filters
These filters are inherited from the main OneClick Chat to Order plugin and can be used to customize the Variations Grabber behavior:
wa_order_filter_phone_number
Purpose: Modify the WhatsApp phone number
Parameters: $phone_number
, $product_id
Usage:
add_filter('wa_order_filter_phone_number', 'custom_phone_number', 10, 2);
function custom_phone_number($phone_number, $product_id) {
// Custom logic to modify phone number
return $phone_number;
}
wa_order_filter_product_url
Purpose: Modify the product URL included in WhatsApp message
Parameters: $product_url
, $product
Usage:
add_filter('wa_order_filter_product_url', 'custom_product_url', 10, 2);
function custom_product_url($product_url, $product) {
// Add UTM parameters or modify URL
return add_query_arg(['utm_source' => 'whatsapp'], $product_url);
}
wa_order_filter_product_title
Purpose: Modify the product title in WhatsApp message
Parameters: $title
, $product
Usage:
add_filter('wa_order_filter_product_title', 'custom_product_title', 10, 2);
function custom_product_title($title, $product) {
// Add prefix or modify title
return '[SPECIAL] ' . $title;
}
wa_order_filter_button_html
Purpose: Modify the WhatsApp button HTML (used by all product types)
Parameters: $button_html
, $button_url
, $button_text
, $product
Priority:
- Simple products: 10
- Variable products: 10
- Grouped products: 12
- Subscription products: 15
Usage:
add_filter('wa_order_filter_button_html', 'custom_button_html', 20, 4);
function custom_button_html($button_html, $button_url, $button_text, $product) {
// Completely customize button appearance
return '<a href="' . esc_url($button_url) . '" class="custom-whatsapp-btn">' . esc_html($button_text) . '</a>';
}
wa_order_filter_button_text
Purpose: Modify the button text
Parameters: $button_text
, $product
Usage:
add_filter('wa_order_filter_button_text', 'custom_button_text', 10, 2);
function custom_button_text($button_text, $product) {
if ($product->get_type() === 'subscription') {
return 'Subscribe via WhatsApp';
}
return $button_text;
}
wa_order_filter_link_type
Purpose: Modify the link type (link/button)
Parameters: $link_type
Usage:
add_filter('wa_order_filter_link_type', 'force_button_type');
function force_button_type($link_type) {
return 'button'; // Force button style
}
wa_order_filter_button_position
Purpose: Modify button position
Parameters: $button_position
Usage:
add_filter('wa_order_filter_button_position', 'custom_button_position');
function custom_button_position($position) {
return 'before_atc'; // Show before Add to Cart
}
wa_order_filter_force_wa_me
Purpose: Force use of wa.me links
Parameters: $force_wa_me
Usage:
add_filter('wa_order_filter_force_wa_me', '__return_true');
wa_order_filter_force_fullwidth
Purpose: Force full-width buttons
Parameters: $force_fullwidth
Usage:
add_filter('wa_order_filter_force_fullwidth', '__return_true');
wa_order_filter_button_target
Purpose: Modify link target (_blank, _self, etc.)
Parameters: $target
Usage:
add_filter('wa_order_filter_button_target', 'custom_link_target');
function custom_link_target($target) {
return '_self'; // Open in same window
}
wa_order_filter_gdpr_status
Purpose: Modify GDPR compliance status
Parameters: $gdpr_status
Usage:
add_filter('wa_order_filter_gdpr_status', 'force_gdpr_enabled');
function force_gdpr_enabled($status) {
return 'yes'; // Always enable GDPR
}
wa_order_filter_gdpr_message
Purpose: Modify GDPR compliance message
Parameters: $gdpr_message
Usage:
add_filter('wa_order_filter_gdpr_message', 'custom_gdpr_message');
function custom_gdpr_message($message) {
return 'I agree to share my data via WhatsApp';
}
Subscription-Specific Filters
Subscription Data Filters
// Modify subscription sign-up fee
apply_filters('wcs_product_sign_up_fee', $sign_up_fee, $product);
// Modify subscription price
apply_filters('wcs_product_price_string', $price_string, $product);
// Modify subscription period
apply_filters('wcs_product_period', $period, $product);
// Modify subscription interval
apply_filters('wcs_product_period_interval', $interval, $product);
// Modify trial period
apply_filters('wcs_product_trial_period', $trial_period, $product);
Custom Plugin Filters
oneclickvg_filter_subscription_trial
Purpose: Modify subscription trial period display
Parameters: $trial
, $post_id
Usage:
add_filter('oneclickvg_filter_subscription_trial', 'custom_trial_display', 10, 2);
function custom_trial_display($trial, $post_id) {
// Custom trial period formatting
return $trial;
}
Action Hooks
Core WordPress Actions
wp_enqueue_scripts
Purpose: Enqueue frontend scripts for each product type
Functions:
oneclickvg_enqueue_script_simple_product
oneclickvg_enqueue_script_variable_product
oneclickvg_enqueue_script_grouped_product
oneclickvg_enqueue_script_subscription_product
Usage:
add_action('wp_enqueue_scripts', 'custom_script_enqueue', 20);
function custom_script_enqueue() {
if (is_product()) {
wp_enqueue_script('custom-variations-script', 'path/to/script.js', ['jquery'], '1.0.0', true);
}
}
admin_enqueue_scripts
Purpose: Enqueue admin scripts
Function: oneclickvg_enqueue_admin_script
admin_menu
Purpose: Register admin menus
Functions:
oneclickvg_register_submenu
admin_init
Purpose: Initialize admin functionality
Functions:
oneclickvg_register_settings
admin_notices
Purpose: Display admin notices
Functions:
oneclickvg_admin_notice_missing_plugins
ocvg_required_plugin_notice
plugins_loaded
Purpose: Initialize plugin after all plugins are loaded
Functions:
oneclickvg_init
Custom Action Hooks
Plugin Initialization Actions
// Plugin initialization
add_action('plugins_loaded', 'oneclickvg_init');
// Admin initialization
add_action('admin_init', 'oneclickvg_register_settings');
JavaScript Events & Customization
Variable Products JavaScript
Events
// Variation selection event
$('.variations_form').on('show_variation', function(event, variation) {
// Handle variation selection
});
// Variation reset event
$('.variations_form').on('reset_data', function() {
// Handle variation reset
});
// GDPR checkbox change
$('#gdprChkbx').on('change', function() {
// Handle GDPR compliance
});
Global Variables
// Available in oneclickvg-variable-product.js
wa_order_settings = {
number_decimals: '2',
decimal_separator: '.',
thousand_separator: ',',
currency_symbol: '$',
include_quantity: 'yes',
include_tax: 'yes',
tax_rate_percent: '10',
tax_label: 'Tax',
subtotal_label: 'Subtotal',
total_amount_label: 'Total Amount',
product_title: 'Product Name',
custom_message: 'Hello, I want to order:',
// ... more settings
};
Subscription Products JavaScript
Global Variables
// Available in oneclickvg-subscription.js
wa_order_subscription_settings = {
subscription_type: 'simple-subscription',
product_price_excl_tax_value: '10.00',
product_price_incl_tax_value: '11.00',
tax_amount_value: '1.00',
is_taxable: 'yes',
prices_include_tax: 'no',
// ... subscription-specific settings
};
Grouped Products JavaScript
Global Variables
// Available in oneclickvg-grouped-product.js
wa_order_settings_grouped = {
grouped_products: [
{
id: 123,
name: 'Product Name',
price_excl_tax: '10.00',
tax_amount: '1.00'
}
// ... more products
],
// ... other settings
};
Custom JavaScript Events
Hooking into Message Construction
// Override message construction for variable products
jQuery(document).ready(function($) {
// Wait for plugin to load
setTimeout(function() {
if (typeof constructMessage === 'function') {
var originalConstructMessage = constructMessage;
constructMessage = function() {
// Custom logic before
var result = originalConstructMessage.apply(this, arguments);
// Custom logic after
return result;
};
}
}, 100);
});
Data Structures
Product Data Structure
// Simple Product Data
$product_data = [
'id' => $product->get_id(),
'name' => $product->get_name(),
'price' => $product->get_price(),
'type' => $product->get_type(),
'url' => get_permalink($product->get_id())
];
// Variable Product Data
$variation_data = [
'variation_id' => $variation->get_id(),
'parent_id' => $variation->get_parent_id(),
'attributes' => $variation->get_variation_attributes(),
'price' => $variation->get_price(),
'display_price' => $variation->get_display_price()
];
// Subscription Product Data
$subscription_data = [
'sign_up_fee' => WC_Subscriptions_Product::get_sign_up_fee($product),
'subscription_price' => WC_Subscriptions_Product::get_price($product),
'subscription_period' => WC_Subscriptions_Product::get_period($product),
'subscription_interval' => WC_Subscriptions_Product::get_interval($product),
'trial_period' => WC_Subscriptions_Product::get_trial_period($product)
];
Settings Data Structure
// Plugin Settings
$settings = [
// Simple Products
'oneclickvg_simple_enable' => 'yes',
'oneclickvg_simple_include_quantity' => 'yes',
'oneclickvg_simple_include_tax' => 'yes',
// Variable Products
'oneclickvg_variable_enable' => 'yes',
'oneclickvg_variable_include_quantity' => 'yes',
'oneclickvg_variable_include_tax' => 'yes',
// Grouped Products
'oneclickvg_grouped_enable' => 'yes',
'oneclickvg_grouped_include_quantity' => 'yes',
'oneclickvg_grouped_include_tax' => 'yes',
// Subscription Products
'oneclickvg_subscription_enable' => 'yes',
'oneclickvg_subscription_include_quantity' => 'yes',
'oneclickvg_subscription_include_tax' => 'yes',
'oneclickvg_subscription_include_price_summary' => 'no',
'oneclickvg_subscription_price_summary_label' => 'Summary',
'oneclickvg_subscription_details_include_details' => 'no',
'oneclickvg_subscription_details_label' => 'Subscription Details',
// ... more subscription settings
];
Extending Functionality
Creating Custom Product Type Support
// 1. Create new product type handler
function custom_product_type_handler() {
// Check if custom product type exists
if (!class_exists('Custom_Product_Type')) return;
// Enqueue scripts
add_action('wp_enqueue_scripts', 'enqueue_custom_product_script');
// Add button filter
add_filter('wa_order_filter_button_html', 'custom_product_button_html', 20, 4);
}
// 2. Enqueue custom script
function enqueue_custom_product_script() {
if (!is_product()) return;
global $product;
if ($product->get_type() !== 'custom_type') return;
wp_enqueue_script(
'custom-product-whatsapp',
plugin_dir_url(__FILE__) . 'js/custom-product.js',
['jquery'],
'1.0.0',
true
);
// Localize script with data
wp_localize_script('custom-product-whatsapp', 'custom_product_settings', [
'product_id' => $product->get_id(),
'product_name' => $product->get_name(),
// ... custom data
]);
}
// 3. Custom button HTML
function custom_product_button_html($button_html, $button_url, $button_text, $product) {
if ($product->get_type() !== 'custom_type') {
return $button_html;
}
// Return custom button for your product type
return '<button id="custom-whatsapp-button" data-url="' . esc_attr($button_url) . '">' . esc_html($button_text) . '</button>';
}
// Initialize
add_action('plugins_loaded', 'custom_product_type_handler');
Adding Custom Message Templates
// Add custom message template filter
add_filter('wa_order_filter_custom_message', 'add_custom_message_template', 10, 3);
function add_custom_message_template($message, $product, $data) {
// Check if custom template should be used
$use_custom = get_post_meta($product->get_id(), '_use_custom_template', true);
if ($use_custom === 'yes') {
$template = get_post_meta($product->get_id(), '_custom_message_template', true);
// Replace placeholders
$message = str_replace([
'{product_name}',
'{product_price}',
'{product_url}'
], [
$product->get_name(),
wc_price($product->get_price()),
get_permalink($product->get_id())
], $template);
}
return $message;
}
Custom Tax Calculation
// Override tax calculation
add_filter('oneclickvg_calculate_tax', 'custom_tax_calculation', 10, 3);
function custom_tax_calculation($tax_amount, $price, $product) {
// Custom tax logic
$custom_tax_rate = get_post_meta($product->get_id(), '_custom_tax_rate', true);
if ($custom_tax_rate) {
return $price * ($custom_tax_rate / 100);
}
return $tax_amount;
}
Best Practices
1. Hook Priority Management
// Use appropriate priorities to ensure correct execution order
add_filter('wa_order_filter_button_html', 'early_modification', 5, 4);
add_filter('wa_order_filter_button_html', 'late_modification', 25, 4);
2. Conditional Loading
// Only load functionality when needed
function conditional_functionality() {
// Check if on product page
if (!is_product()) return;
// Check product type
global $product;
if ($product->get_type() !== 'target_type') return;
// Load functionality
}
add_action('wp', 'conditional_functionality');
3. Data Sanitization
// Always sanitize data
function safe_data_handling($data) {
return [
'product_name' => sanitize_text_field($data['product_name']),
'product_price' => floatval($data['product_price']),
'product_url' => esc_url($data['product_url'])
];
}
4. Error Handling
// Implement proper error handling
function safe_function_call() {
try {
// Risky operation
$result = some_operation();
return $result;
} catch (Exception $e) {
error_log('OneClick Variations Grabber Error: ' . $e->getMessage());
return false;
}
}
5. Performance Optimization
// Cache expensive operations
function get_cached_data($product_id) {
$cache_key = 'ocvg_data_' . $product_id;
$cached = wp_cache_get($cache_key);
if ($cached === false) {
$data = expensive_operation($product_id);
wp_cache_set($cache_key, $data, '', 3600); // Cache for 1 hour
return $data;
}
return $cached;
}
Code Examples
Example 1: Custom Button Styling
// Add custom CSS class to WhatsApp buttons
add_filter('wa_order_filter_button_html', 'add_custom_button_class', 10, 4);
function add_custom_button_class($button_html, $button_url, $button_text, $product) {
// Add custom class based on product type
$custom_class = 'whatsapp-btn-' . $product->get_type();
// Modify button HTML to include custom class
$button_html = str_replace('class="', 'class="' . $custom_class . ' ', $button_html);
return $button_html;
}
// Enqueue custom CSS
add_action('wp_enqueue_scripts', 'enqueue_custom_button_styles');
function enqueue_custom_button_styles() {
if (is_product()) {
wp_add_inline_style('woocommerce-general', '
.whatsapp-btn-variable { background-color: #25D366; }
.whatsapp-btn-subscription { background-color: #128C7E; }
.whatsapp-btn-grouped { background-color: #075E54; }
');
}
}
Example 2: Custom Message Format
// Modify WhatsApp message format for specific products
add_action('wp_enqueue_scripts', 'custom_message_format');
function custom_message_format() {
if (!is_product()) return;
global $product;
$custom_format = get_post_meta($product->get_id(), '_custom_whatsapp_format', true);
if ($custom_format) {
wp_add_inline_script('jquery', '
jQuery(document).ready(function($) {
// Override message construction
if (typeof constructMessage === "function") {
var originalConstruct = constructMessage;
constructMessage = function() {
var customMessage = "' . esc_js($custom_format) . '";
// Process custom format
return customMessage;
};
}
});
');
}
}
Example 3: Integration with Third-Party Plugins
// Integration with a membership plugin
add_filter('wa_order_filter_phone_number', 'membership_phone_routing', 10, 2);
function membership_phone_routing($phone_number, $product_id) {
// Check if user has membership
if (function_exists('check_membership_status')) {
$user_id = get_current_user_id();
$membership_level = check_membership_status($user_id);
// Route to different phone numbers based on membership
switch ($membership_level) {
case 'premium':
return '+1234567890'; // Premium support line
case 'vip':
return '+1234567891'; // VIP support line
default:
return $phone_number; // Default number
}
}
return $phone_number;
}
Example 4: Custom Admin Settings
// Add custom settings section
add_action('admin_init', 'register_custom_settings');
function register_custom_settings() {
// Register new setting
register_setting('oneclickvg_settings', 'oneclickvg_custom_feature');
// Add settings section
add_settings_section(
'oneclickvg_custom_section',
'Custom Features',
'custom_section_callback',
'oneclickvg_settings'
);
// Add settings field
add_settings_field(
'oneclickvg_custom_feature',
'Enable Custom Feature',
'custom_feature_callback',
'oneclickvg_settings',
'oneclickvg_custom_section'
);
}
function custom_section_callback() {
echo '<p>Configure custom features for OneClick Variations Grabber.</p>';
}
function custom_feature_callback() {
$value = get_option('oneclickvg_custom_feature', 'no');
echo '<input type="checkbox" name="oneclickvg_custom_feature" value="yes" ' . checked($value, 'yes', false) . ' />';
echo '<label>Enable this custom feature</label>';
}
Example 5: AJAX Integration
// Add AJAX handler for custom functionality
add_action('wp_ajax_ocvg_custom_action', 'handle_custom_ajax');
add_action('wp_ajax_nopriv_ocvg_custom_action', 'handle_custom_ajax');
function handle_custom_ajax() {
// Verify nonce
if (!wp_verify_nonce($_POST['nonce'], 'ocvg_custom_nonce')) {
wp_die('Security check failed');
}
// Process request
$product_id = intval($_POST['product_id']);
$custom_data = sanitize_text_field($_POST['custom_data']);
// Perform custom logic
$result = process_custom_data($product_id, $custom_data);
// Return JSON response
wp_send_json_success($result);
}
// Enqueue AJAX script
add_action('wp_enqueue_scripts', 'enqueue_custom_ajax_script');
function enqueue_custom_ajax_script() {
if (is_product()) {
wp_enqueue_script('ocvg-custom-ajax', plugin_dir_url(__FILE__) . 'js/custom-ajax.js', ['jquery'], '1.0.0', true);
wp_localize_script('ocvg-custom-ajax', 'ocvg_ajax', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('ocvg_custom_nonce')
]);
}
}
Debugging & Development
Enable Debug Mode
// Add to wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('SCRIPT_DEBUG', true);
// Plugin-specific debugging
define('OCVG_DEBUG', true);
Debug Functions
// Debug helper function
function ocvg_debug_log($message, $data = null) {
if (defined('OCVG_DEBUG') && OCVG_DEBUG) {
$log_message = '[OCVG Debug] ' . $message;
if ($data !== null) {
$log_message .= ' | Data: ' . print_r($data, true);
}
error_log($log_message);
}
}
// Usage
ocvg_debug_log('Product type detected', $product->get_type());
ocvg_debug_log('Settings loaded', $settings_array);
JavaScript Debugging
// Add to your custom JavaScript
if (typeof console !== 'undefined' && console.log) {
console.log('OCVG Debug: Variable product script loaded');
console.log('OCVG Settings:', wa_order_settings);
}
Version Compatibility
OneClick Chat to Order Compatibility
// Check version compatibility
if (defined('OCTO_VERSION')) {
if (version_compare(OCTO_VERSION, '1.0.8', '>=')) {
// Use v1.0.8+ features
$options_manager = wa_order_get_options_manager();
} else {
// Fallback for older versions
$options_manager = null;
}
}
WooCommerce Compatibility
// Check WooCommerce version
if (defined('WC_VERSION')) {
if (version_compare(WC_VERSION, '3.0', '>=')) {
// Use WC 3.0+ methods
$product_id = $product->get_id();
} else {
// Fallback for older versions
$product_id = $product->id;
}
}
Support & Resources
Getting Help
- Documentation: This developer guide
- Code Examples: See examples section above
- Support: Contact [email protected]
- Updates: Check plugin admin area for updates
Contributing
- Follow WordPress coding standards
- Test with multiple WooCommerce versions
- Ensure OneClick Chat to Order compatibility
- Document any new hooks or filters