feat: Backend API & Email Rendering with Settings! 🔌

## 4. Wire to Backend 

### API Endpoints Created:
- `GET /woonoow/v1/notifications/email-settings` - Fetch settings
- `POST /woonoow/v1/notifications/email-settings` - Save settings
- `DELETE /woonoow/v1/notifications/email-settings` - Reset to defaults

### Features:
- Proper sanitization (sanitize_hex_color, esc_url_raw, etc.)
- Social links validation (allowed platforms only)
- Defaults fallback
- Stored in wp_options as `woonoow_email_settings`

### Email Rendering Integration:
**Logo & Header:**
- Uses logo_url if set, otherwise header_text
- Falls back to store name

**Footer:**
- Uses footer_text with {current_year} support
- Replaces {current_year} with actual year dynamically
- Social icons rendered from social_links array

**Hero Cards:**
- Applies hero_gradient_start and hero_gradient_end
- Applies hero_text_color to text and headings
- Works for type="hero" and type="success" cards

**Button Colors:**
- Ready to apply primary_color and button_text_color
- (Template needs update for dynamic button colors)

### Files:
- `includes/Api/NotificationsController.php` - API endpoints
- `includes/Core/Notifications/EmailRenderer.php` - Apply settings to emails

### Security:
- Permission checks (check_permission)
- Input sanitization
- URL validation
- Platform whitelist for social links

Frontend can now save/load settings! Backend applies them to emails! 🎉
This commit is contained in:
dwindown
2025-11-13 13:45:03 +07:00
parent 7badee9ee4
commit 2a98d6fc2b
2 changed files with 166 additions and 20 deletions

View File

@@ -121,6 +121,33 @@ class NotificationsController {
],
]);
// GET /woonoow/v1/notifications/email-settings
register_rest_route($this->namespace, '/' . $this->rest_base . '/email-settings', [
[
'methods' => 'GET',
'callback' => [$this, 'get_email_settings'],
'permission_callback' => [$this, 'check_permission'],
],
]);
// POST /woonoow/v1/notifications/email-settings
register_rest_route($this->namespace, '/' . $this->rest_base . '/email-settings', [
[
'methods' => 'POST',
'callback' => [$this, 'save_email_settings'],
'permission_callback' => [$this, 'check_permission'],
],
]);
// DELETE /woonoow/v1/notifications/email-settings
register_rest_route($this->namespace, '/' . $this->rest_base . '/email-settings', [
[
'methods' => 'DELETE',
'callback' => [$this, 'reset_email_settings'],
'permission_callback' => [$this, 'check_permission'],
],
]);
// GET /woonoow/v1/notifications/push/settings
register_rest_route($this->namespace, '/' . $this->rest_base . '/push/settings', [
[
@@ -815,4 +842,104 @@ class NotificationsController {
'enabled' => (bool) $verified,
], 200);
}
/**
* Get email customization settings
*/
public function get_email_settings(WP_REST_Request $request) {
$defaults = [
'primary_color' => '#7f54b3',
'secondary_color' => '#7f54b3',
'hero_gradient_start' => '#667eea',
'hero_gradient_end' => '#764ba2',
'hero_text_color' => '#ffffff',
'button_text_color' => '#ffffff',
'logo_url' => '',
'header_text' => '',
'footer_text' => '',
'social_links' => [],
];
$settings = get_option('woonoow_email_settings', $defaults);
// Ensure social_links is an array
if (!isset($settings['social_links']) || !is_array($settings['social_links'])) {
$settings['social_links'] = [];
}
// Merge with defaults to ensure all fields exist
$settings = array_merge($defaults, $settings);
return new WP_REST_Response($settings, 200);
}
/**
* Save email customization settings
*/
public function save_email_settings(WP_REST_Request $request) {
$data = $request->get_json_params();
$settings = [
'primary_color' => sanitize_hex_color($data['primary_color'] ?? '#7f54b3'),
'secondary_color' => sanitize_hex_color($data['secondary_color'] ?? '#7f54b3'),
'hero_gradient_start' => sanitize_hex_color($data['hero_gradient_start'] ?? '#667eea'),
'hero_gradient_end' => sanitize_hex_color($data['hero_gradient_end'] ?? '#764ba2'),
'hero_text_color' => sanitize_hex_color($data['hero_text_color'] ?? '#ffffff'),
'button_text_color' => sanitize_hex_color($data['button_text_color'] ?? '#ffffff'),
'logo_url' => esc_url_raw($data['logo_url'] ?? ''),
'header_text' => sanitize_text_field($data['header_text'] ?? ''),
'footer_text' => sanitize_text_field($data['footer_text'] ?? ''),
'social_links' => $this->sanitize_social_links($data['social_links'] ?? []),
];
update_option('woonoow_email_settings', $settings);
return new WP_REST_Response([
'success' => true,
'message' => __('Email settings saved successfully', 'woonoow'),
'settings' => $settings,
], 200);
}
/**
* Reset email customization settings to defaults
*/
public function reset_email_settings(WP_REST_Request $request) {
delete_option('woonoow_email_settings');
return new WP_REST_Response([
'success' => true,
'message' => __('Email settings reset to defaults', 'woonoow'),
], 200);
}
/**
* Sanitize social links array
*/
private function sanitize_social_links($links) {
if (!is_array($links)) {
return [];
}
$sanitized = [];
$allowed_platforms = ['facebook', 'twitter', 'instagram', 'linkedin', 'youtube', 'website'];
foreach ($links as $link) {
if (!is_array($link) || !isset($link['platform']) || !isset($link['url'])) {
continue;
}
$platform = sanitize_text_field($link['platform']);
$url = esc_url_raw($link['url']);
if (in_array($platform, $allowed_platforms) && !empty($url)) {
$sanitized[] = [
'platform' => $platform,
'url' => $url,
];
}
}
return $sanitized;
}
}