- Add CampaignManager.php with CPT registration, CRUD, batch sending - Add CampaignsController.php with 8 REST endpoints (list, create, get, update, delete, send, test, preview) - Register newsletter_campaign event in EventRegistry for email template - Initialize CampaignManager in Bootstrap.php - Register routes in Routes.php
321 lines
10 KiB
PHP
321 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* Campaigns REST Controller
|
|
*
|
|
* REST API endpoints for newsletter campaigns
|
|
*
|
|
* @package WooNooW\API
|
|
*/
|
|
|
|
namespace WooNooW\API;
|
|
|
|
use WP_REST_Request;
|
|
use WP_REST_Response;
|
|
use WP_Error;
|
|
use WooNooW\Core\Campaigns\CampaignManager;
|
|
|
|
class CampaignsController {
|
|
|
|
const API_NAMESPACE = 'woonoow/v1';
|
|
|
|
/**
|
|
* Register REST routes
|
|
*/
|
|
public static function register_routes() {
|
|
// List campaigns
|
|
register_rest_route(self::API_NAMESPACE, '/campaigns', [
|
|
'methods' => 'GET',
|
|
'callback' => [__CLASS__, 'get_campaigns'],
|
|
'permission_callback' => [__CLASS__, 'check_admin_permission'],
|
|
]);
|
|
|
|
// Create campaign
|
|
register_rest_route(self::API_NAMESPACE, '/campaigns', [
|
|
'methods' => 'POST',
|
|
'callback' => [__CLASS__, 'create_campaign'],
|
|
'permission_callback' => [__CLASS__, 'check_admin_permission'],
|
|
]);
|
|
|
|
// Get single campaign
|
|
register_rest_route(self::API_NAMESPACE, '/campaigns/(?P<id>\d+)', [
|
|
'methods' => 'GET',
|
|
'callback' => [__CLASS__, 'get_campaign'],
|
|
'permission_callback' => [__CLASS__, 'check_admin_permission'],
|
|
]);
|
|
|
|
// Update campaign
|
|
register_rest_route(self::API_NAMESPACE, '/campaigns/(?P<id>\d+)', [
|
|
'methods' => 'PUT',
|
|
'callback' => [__CLASS__, 'update_campaign'],
|
|
'permission_callback' => [__CLASS__, 'check_admin_permission'],
|
|
]);
|
|
|
|
// Delete campaign
|
|
register_rest_route(self::API_NAMESPACE, '/campaigns/(?P<id>\d+)', [
|
|
'methods' => 'DELETE',
|
|
'callback' => [__CLASS__, 'delete_campaign'],
|
|
'permission_callback' => [__CLASS__, 'check_admin_permission'],
|
|
]);
|
|
|
|
// Send campaign
|
|
register_rest_route(self::API_NAMESPACE, '/campaigns/(?P<id>\d+)/send', [
|
|
'methods' => 'POST',
|
|
'callback' => [__CLASS__, 'send_campaign'],
|
|
'permission_callback' => [__CLASS__, 'check_admin_permission'],
|
|
]);
|
|
|
|
// Send test email
|
|
register_rest_route(self::API_NAMESPACE, '/campaigns/(?P<id>\d+)/test', [
|
|
'methods' => 'POST',
|
|
'callback' => [__CLASS__, 'send_test_email'],
|
|
'permission_callback' => [__CLASS__, 'check_admin_permission'],
|
|
]);
|
|
|
|
// Preview campaign
|
|
register_rest_route(self::API_NAMESPACE, '/campaigns/(?P<id>\d+)/preview', [
|
|
'methods' => 'GET',
|
|
'callback' => [__CLASS__, 'preview_campaign'],
|
|
'permission_callback' => [__CLASS__, 'check_admin_permission'],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Check admin permission
|
|
*/
|
|
public static function check_admin_permission() {
|
|
return current_user_can('manage_options');
|
|
}
|
|
|
|
/**
|
|
* Get all campaigns
|
|
*/
|
|
public static function get_campaigns(WP_REST_Request $request) {
|
|
$campaigns = CampaignManager::get_all();
|
|
|
|
return new WP_REST_Response([
|
|
'success' => true,
|
|
'data' => $campaigns,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Create campaign
|
|
*/
|
|
public static function create_campaign(WP_REST_Request $request) {
|
|
$data = [
|
|
'title' => $request->get_param('title'),
|
|
'subject' => $request->get_param('subject'),
|
|
'content' => $request->get_param('content'),
|
|
'status' => $request->get_param('status') ?: 'draft',
|
|
'scheduled_at' => $request->get_param('scheduled_at'),
|
|
];
|
|
|
|
$campaign_id = CampaignManager::create($data);
|
|
|
|
if (is_wp_error($campaign_id)) {
|
|
return new WP_REST_Response([
|
|
'success' => false,
|
|
'error' => $campaign_id->get_error_message(),
|
|
], 400);
|
|
}
|
|
|
|
$campaign = CampaignManager::get($campaign_id);
|
|
|
|
return new WP_REST_Response([
|
|
'success' => true,
|
|
'data' => $campaign,
|
|
], 201);
|
|
}
|
|
|
|
/**
|
|
* Get single campaign
|
|
*/
|
|
public static function get_campaign(WP_REST_Request $request) {
|
|
$campaign_id = (int) $request->get_param('id');
|
|
$campaign = CampaignManager::get($campaign_id);
|
|
|
|
if (!$campaign) {
|
|
return new WP_REST_Response([
|
|
'success' => false,
|
|
'error' => __('Campaign not found', 'woonoow'),
|
|
], 404);
|
|
}
|
|
|
|
return new WP_REST_Response([
|
|
'success' => true,
|
|
'data' => $campaign,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Update campaign
|
|
*/
|
|
public static function update_campaign(WP_REST_Request $request) {
|
|
$campaign_id = (int) $request->get_param('id');
|
|
|
|
$data = [];
|
|
|
|
if ($request->has_param('title')) {
|
|
$data['title'] = $request->get_param('title');
|
|
}
|
|
if ($request->has_param('subject')) {
|
|
$data['subject'] = $request->get_param('subject');
|
|
}
|
|
if ($request->has_param('content')) {
|
|
$data['content'] = $request->get_param('content');
|
|
}
|
|
if ($request->has_param('status')) {
|
|
$data['status'] = $request->get_param('status');
|
|
}
|
|
if ($request->has_param('scheduled_at')) {
|
|
$data['scheduled_at'] = $request->get_param('scheduled_at');
|
|
}
|
|
|
|
$result = CampaignManager::update($campaign_id, $data);
|
|
|
|
if (is_wp_error($result)) {
|
|
return new WP_REST_Response([
|
|
'success' => false,
|
|
'error' => $result->get_error_message(),
|
|
], 400);
|
|
}
|
|
|
|
$campaign = CampaignManager::get($campaign_id);
|
|
|
|
return new WP_REST_Response([
|
|
'success' => true,
|
|
'data' => $campaign,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Delete campaign
|
|
*/
|
|
public static function delete_campaign(WP_REST_Request $request) {
|
|
$campaign_id = (int) $request->get_param('id');
|
|
|
|
$result = CampaignManager::delete($campaign_id);
|
|
|
|
if (!$result) {
|
|
return new WP_REST_Response([
|
|
'success' => false,
|
|
'error' => __('Failed to delete campaign', 'woonoow'),
|
|
], 400);
|
|
}
|
|
|
|
return new WP_REST_Response([
|
|
'success' => true,
|
|
'message' => __('Campaign deleted', 'woonoow'),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Send campaign
|
|
*/
|
|
public static function send_campaign(WP_REST_Request $request) {
|
|
$campaign_id = (int) $request->get_param('id');
|
|
|
|
$result = CampaignManager::send($campaign_id);
|
|
|
|
if (!$result['success']) {
|
|
return new WP_REST_Response([
|
|
'success' => false,
|
|
'error' => $result['error'],
|
|
], 400);
|
|
}
|
|
|
|
return new WP_REST_Response([
|
|
'success' => true,
|
|
'message' => sprintf(
|
|
__('Campaign sent to %d recipients (%d failed)', 'woonoow'),
|
|
$result['sent'],
|
|
$result['failed']
|
|
),
|
|
'sent' => $result['sent'],
|
|
'failed' => $result['failed'],
|
|
'total' => $result['total'],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Send test email
|
|
*/
|
|
public static function send_test_email(WP_REST_Request $request) {
|
|
$campaign_id = (int) $request->get_param('id');
|
|
$email = sanitize_email($request->get_param('email'));
|
|
|
|
if (!is_email($email)) {
|
|
return new WP_REST_Response([
|
|
'success' => false,
|
|
'error' => __('Invalid email address', 'woonoow'),
|
|
], 400);
|
|
}
|
|
|
|
$result = CampaignManager::send_test($campaign_id, $email);
|
|
|
|
if (!$result) {
|
|
return new WP_REST_Response([
|
|
'success' => false,
|
|
'error' => __('Failed to send test email', 'woonoow'),
|
|
], 400);
|
|
}
|
|
|
|
return new WP_REST_Response([
|
|
'success' => true,
|
|
'message' => sprintf(__('Test email sent to %s', 'woonoow'), $email),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Preview campaign
|
|
*/
|
|
public static function preview_campaign(WP_REST_Request $request) {
|
|
$campaign_id = (int) $request->get_param('id');
|
|
$campaign = CampaignManager::get($campaign_id);
|
|
|
|
if (!$campaign) {
|
|
return new WP_REST_Response([
|
|
'success' => false,
|
|
'error' => __('Campaign not found', 'woonoow'),
|
|
], 404);
|
|
}
|
|
|
|
// Use reflection to call private render method or make it public
|
|
// For now, return a simple preview
|
|
$renderer = \WooNooW\Core\Notifications\EmailRenderer::instance();
|
|
$template = $renderer->get_template_settings('newsletter_campaign', 'customer');
|
|
|
|
$content = $campaign['content'];
|
|
$subject = $campaign['subject'] ?: $campaign['title'];
|
|
|
|
if ($template) {
|
|
$content = str_replace('{content}', $campaign['content'], $template['body']);
|
|
$content = str_replace('{campaign_title}', $campaign['title'], $content);
|
|
}
|
|
|
|
// Replace placeholders
|
|
$site_name = get_bloginfo('name');
|
|
$content = str_replace(['{site_name}', '{store_name}'], $site_name, $content);
|
|
$content = str_replace('{site_url}', home_url(), $content);
|
|
$content = str_replace('{subscriber_email}', 'subscriber@example.com', $content);
|
|
$content = str_replace('{unsubscribe_url}', '#unsubscribe', $content);
|
|
$content = str_replace('{current_date}', date_i18n(get_option('date_format')), $content);
|
|
$content = str_replace('{current_year}', date('Y'), $content);
|
|
|
|
// Render with design template
|
|
$design_path = $renderer->get_design_template();
|
|
if (file_exists($design_path)) {
|
|
$content = $renderer->render_html($design_path, $content, $subject, [
|
|
'site_name' => $site_name,
|
|
'site_url' => home_url(),
|
|
]);
|
|
}
|
|
|
|
return new WP_REST_Response([
|
|
'success' => true,
|
|
'subject' => $subject,
|
|
'html' => $content,
|
|
]);
|
|
}
|
|
}
|