- Fix: Marketing events now display in Staff notifications tab - Reorganize: Move Coupons to Marketing/Coupons for better organization - Add: Comprehensive email/phone validation with extensible filter hooks - Email validation with regex pattern (xxxx@xxxx.xx) - Phone validation with WhatsApp verification support - Filter hooks for external API integration (QuickEmailVerification, etc.) - Fix: Newsletter template routes now use centralized notification email builder - Add: Validation.php class for reusable validation logic - Add: VALIDATION_HOOKS.md documentation with integration examples - Add: NEWSLETTER_CAMPAIGN_PLAN.md architecture for future campaign system - Fix: API delete method call in Newsletter.tsx (delete -> del) - Remove: Duplicate EmailTemplates.tsx (using notification system instead) - Update: Newsletter controller to use centralized Validation class Breaking changes: - Coupons routes moved from /routes/Coupons to /routes/Marketing/Coupons - Legacy /coupons routes maintained for backward compatibility
8.3 KiB
8.3 KiB
Validation Filter Hooks
WooNooW provides extensible validation filter hooks that allow addons to integrate external validation services for emails and phone numbers.
Email Validation
Filter: woonoow/validate_email
Validates email addresses with support for external API integration.
Parameters:
$is_valid(bool|WP_Error): Initial validation state (default: true)$email(string): The email address to validate$context(string): Context of validation (e.g., 'newsletter_subscribe', 'checkout', 'registration')
Returns: true if valid, WP_Error if invalid
Built-in Validation:
- WordPress
is_email()check - Regex pattern validation:
xxxx@xxxx.xxformat - Extensible via filter hook
Example: QuickEmailVerification.com Integration
add_filter('woonoow/validate_email', function($is_valid, $email, $context) {
// Only validate for newsletter subscriptions
if ($context !== 'newsletter_subscribe') {
return $is_valid;
}
$api_key = get_option('my_addon_quickemail_api_key');
if (!$api_key) {
return $is_valid; // Skip if no API key configured
}
// Call QuickEmailVerification API
$response = wp_remote_get(
"https://api.quickemailverification.com/v1/verify?email={$email}&apikey={$api_key}",
['timeout' => 5]
);
if (is_wp_error($response)) {
// Fallback to basic validation on API error
return $is_valid;
}
$data = json_decode(wp_remote_retrieve_body($response), true);
// Check validation result
if (isset($data['result']) && $data['result'] !== 'valid') {
return new WP_Error(
'email_verification_failed',
sprintf('Email verification failed: %s', $data['reason'] ?? 'Unknown'),
['status' => 400]
);
}
return true;
}, 10, 3);
Example: Hunter.io Email Verification
add_filter('woonoow/validate_email', function($is_valid, $email, $context) {
$api_key = get_option('my_addon_hunter_api_key');
if (!$api_key) return $is_valid;
$response = wp_remote_get(
"https://api.hunter.io/v2/email-verifier?email={$email}&api_key={$api_key}"
);
if (is_wp_error($response)) return $is_valid;
$data = json_decode(wp_remote_retrieve_body($response), true);
if ($data['data']['status'] !== 'valid') {
return new WP_Error('email_invalid', 'Email address is not deliverable');
}
return true;
}, 10, 3);
Phone Validation
Filter: woonoow/validate_phone
Validates phone numbers with support for external API integration and WhatsApp verification.
Parameters:
$is_valid(bool|WP_Error): Initial validation state (default: true)$phone(string): The phone number to validate (cleaned, no formatting)$context(string): Context of validation (e.g., 'checkout', 'registration', 'shipping')$country_code(string): Country code if available (e.g., 'ID', 'US')
Returns: true if valid, WP_Error if invalid
Built-in Validation:
- Format check: 8-15 digits, optional
+prefix - Removes common formatting characters
- Extensible via filter hook
Example: WhatsApp Number Verification
add_filter('woonoow/validate_phone', function($is_valid, $phone, $context, $country_code) {
// Only validate for checkout
if ($context !== 'checkout') {
return $is_valid;
}
$api_token = get_option('my_addon_whatsapp_api_token');
if (!$api_token) return $is_valid;
// Check if number is registered on WhatsApp
$response = wp_remote_post('https://api.whatsapp.com/v1/contacts', [
'headers' => [
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json',
],
'body' => json_encode([
'blocking' => 'wait',
'contacts' => [$phone],
]),
'timeout' => 10,
]);
if (is_wp_error($response)) {
return $is_valid; // Fallback on API error
}
$data = json_decode(wp_remote_retrieve_body($response), true);
// Check if WhatsApp ID exists
if (!isset($data['contacts'][0]['wa_id'])) {
return new WP_Error(
'phone_not_whatsapp',
'Phone number must be registered on WhatsApp for order notifications',
['status' => 400]
);
}
return true;
}, 10, 4);
Example: Numverify Phone Validation
add_filter('woonoow/validate_phone', function($is_valid, $phone, $context, $country_code) {
$api_key = get_option('my_addon_numverify_api_key');
if (!$api_key) return $is_valid;
$url = sprintf(
'http://apilayer.net/api/validate?access_key=%s&number=%s&country_code=%s',
$api_key,
urlencode($phone),
urlencode($country_code)
);
$response = wp_remote_get($url, ['timeout' => 5]);
if (is_wp_error($response)) return $is_valid;
$data = json_decode(wp_remote_retrieve_body($response), true);
if (!$data['valid']) {
return new WP_Error(
'phone_invalid',
sprintf('Invalid phone number: %s', $data['error'] ?? 'Unknown error')
);
}
// Store carrier info for later use
update_post_meta(get_current_user_id(), '_phone_carrier', $data['carrier'] ?? '');
return true;
}, 10, 4);
Filter: woonoow/validate_phone_whatsapp
Convenience filter specifically for WhatsApp registration checks.
Parameters:
$is_registered(bool|WP_Error): Initial state (default: true)$phone(string): The phone number (cleaned)$context(string): Context of validation$country_code(string): Country code if available
Returns: true if registered on WhatsApp, WP_Error if not
Usage in Code
Email Validation
use WooNooW\Core\Validation;
// Validate email for newsletter
$result = Validation::validate_email('user@example.com', 'newsletter_subscribe');
if (is_wp_error($result)) {
// Handle error
echo $result->get_error_message();
} else {
// Email is valid
// Proceed with subscription
}
Phone Validation
use WooNooW\Core\Validation;
// Validate phone for checkout
$result = Validation::validate_phone('+628123456789', 'checkout', 'ID');
if (is_wp_error($result)) {
// Handle error
echo $result->get_error_message();
} else {
// Phone is valid
// Proceed with order
}
Phone + WhatsApp Validation
use WooNooW\Core\Validation;
// Validate phone and check WhatsApp registration
$result = Validation::validate_phone_whatsapp('+628123456789', 'checkout', 'ID');
if (is_wp_error($result)) {
// Phone invalid or not registered on WhatsApp
echo $result->get_error_message();
} else {
// Phone is valid and registered on WhatsApp
// Proceed with order
}
Validation Contexts
Common contexts used throughout WooNooW:
newsletter_subscribe- Newsletter subscription formcheckout- Checkout processregistration- User registrationshipping- Shipping address validationbilling- Billing address validationgeneral- General validation (default)
Addons can filter based on context to apply different validation rules for different scenarios.
Best Practices
- Always fallback gracefully - If external API fails, return
$is_validto use basic validation - Use timeouts - Set reasonable timeouts (5-10 seconds) for API calls
- Cache results - Cache validation results to avoid repeated API calls
- Provide clear error messages - Return descriptive WP_Error messages
- Check context - Only apply validation where needed to avoid unnecessary API calls
- Handle API keys securely - Store API keys in options, never hardcode
- Log errors - Log API errors for debugging without blocking users
Error Codes
Email Validation Errors
invalid_email- Basic format validation failedinvalid_email_format- Regex pattern validation failedemail_verification_failed- External API verification failedemail_validation_failed- Generic validation failure
Phone Validation Errors
invalid_phone- Basic format validation failedphone_not_whatsapp- Phone not registered on WhatsAppphone_invalid- External API validation failedphone_validation_failed- Generic validation failure