Files
WooNooW/VALIDATION_HOOKS.md
Dwindi Ramadhana 0b2c8a56d6 feat: Newsletter system improvements and validation framework
- 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
2025-12-26 10:59:48 +07:00

294 lines
8.3 KiB
Markdown

# 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:**
1. WordPress `is_email()` check
2. Regex pattern validation: `xxxx@xxxx.xx` format
3. Extensible via filter hook
### Example: QuickEmailVerification.com Integration
```php
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
```php
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:**
1. Format check: 8-15 digits, optional `+` prefix
2. Removes common formatting characters
3. Extensible via filter hook
### Example: WhatsApp Number Verification
```php
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
```php
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
```php
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
```php
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
```php
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 form
- `checkout` - Checkout process
- `registration` - User registration
- `shipping` - Shipping address validation
- `billing` - Billing address validation
- `general` - General validation (default)
Addons can filter based on context to apply different validation rules for different scenarios.
---
## Best Practices
1. **Always fallback gracefully** - If external API fails, return `$is_valid` to use basic validation
2. **Use timeouts** - Set reasonable timeouts (5-10 seconds) for API calls
3. **Cache results** - Cache validation results to avoid repeated API calls
4. **Provide clear error messages** - Return descriptive WP_Error messages
5. **Check context** - Only apply validation where needed to avoid unnecessary API calls
6. **Handle API keys securely** - Store API keys in options, never hardcode
7. **Log errors** - Log API errors for debugging without blocking users
---
## Error Codes
### Email Validation Errors
- `invalid_email` - Basic format validation failed
- `invalid_email_format` - Regex pattern validation failed
- `email_verification_failed` - External API verification failed
- `email_validation_failed` - Generic validation failure
### Phone Validation Errors
- `invalid_phone` - Basic format validation failed
- `phone_not_whatsapp` - Phone not registered on WhatsApp
- `phone_invalid` - External API validation failed
- `phone_validation_failed` - Generic validation failure