sanitize_text_field($_POST['email_subject']), 'message' => wp_kses_post($_POST['email_message']), 'users' => sanitize_text_field($_POST['target_users']), 'include_wishlist' => isset($_POST['include_wishlist']), 'discount_code' => sanitize_text_field($_POST['discount_code']), ); // First check if promotional emails are enabled using the new settings system global $aicoso_wishlist_settings; if (!$aicoso_wishlist_settings) { require_once AICOSO_WISHLIST_PLUGIN_DIR . 'admin/class-aicoso-wishlist-standalone-settings.php'; $aicoso_wishlist_settings = new Aicoso_Wishlist_Standalone_Settings(); } if ($aicoso_wishlist_settings->get('promotional_emails', 'no') !== 'yes') { return array( 'type' => 'error', 'message' => __('Promotional emails are disabled. Please enable them in settings first.', 'aicoso-wishlist-for-woocommerce') ); } $emails = Aicoso_Wishlist_Emails::get_instance(); $result = $emails->send_promotional_email($args); if ($result && is_array($result)) { if ($result['sent'] > 0) { return array( 'type' => 'success', 'message' => sprintf(__('Email campaign completed! Sent: %d, Failed: %d, Total: %d', 'aicoso-wishlist-for-woocommerce'), $result['sent'], $result['failed'], $result['total']) ); } else { return array( 'type' => 'error', 'message' => __('Email campaign failed. No emails were sent. Check the email log for details.', 'aicoso-wishlist-for-woocommerce') ); } } else { return array( 'type' => 'warning', 'message' => __('Email campaign processed. Check the email log for details.', 'aicoso-wishlist-for-woocommerce') ); } } public function display_email_log() { $email_log = Aicoso_Wishlist_Emails::get_email_log(); if (empty($email_log)) { echo '

' . __('No email events logged yet.', 'aicoso-wishlist-for-woocommerce') . '

'; return; } // Handle clear log if (isset($_POST['clear_email_log']) && wp_verify_nonce($_POST['_wpnonce'], 'clear_email_log')) { Aicoso_Wishlist_Emails::clear_email_log(); echo '

' . __('Email log cleared successfully.', 'aicoso-wishlist-for-woocommerce') . '

'; $email_log = array(); } if (!empty($email_log)) { echo '
'; // Show most recent entries at the top usort($email_log, function($a, $b) { $time_a = isset($a['time']) ? strtotime($a['time']) : 0; $time_b = isset($b['time']) ? strtotime($b['time']) : 0; return $time_b - $time_a; }); $count = 0; foreach ($email_log as $entry) { if ($count >= 50) break; // Show only last 50 entries $style = 'padding: 10px; margin: 5px 0; border-left: 3px solid '; if (strpos($entry['event'], 'failed') !== false || strpos($entry['event'], 'error') !== false) { $style .= '#dc3232;'; } elseif (strpos($entry['event'], 'success') !== false || strpos($entry['event'], 'sent') !== false || strpos($entry['event'], 'completed') !== false) { $style .= '#46b450;'; } else { $style .= '#ddd;'; } echo '
'; echo '[' . esc_html($entry['time']) . '] ' . esc_html($entry['event']); if (!empty($entry['data']) && is_array($entry['data'])) { $details = array(); foreach ($entry['data'] as $k => $v) { if (is_scalar($v) && $v !== '') { $label = ucwords(str_replace('_', ' ', $k)); $details[] = '' . esc_html($label) . ': ' . esc_html($v); } } if (!empty($details)) { echo '
' . implode(' • ', $details) . '
'; } } elseif (!empty($entry['data']) && is_string($entry['data'])) { echo '
' . esc_html($entry['data']) . '
'; } echo '
'; $count++; } echo '
'; echo '
'; wp_nonce_field('clear_email_log'); echo ''; echo '
'; } } private function display_email_stats() { global $wpdb; $table_wishlists = $wpdb->prefix . 'aicoso_wishlists'; $total_users = $wpdb->get_var(" SELECT COUNT(DISTINCT user_id) FROM {$table_wishlists} WHERE user_id IS NOT NULL AND user_id > 0 "); $active_users = $wpdb->get_var(" SELECT COUNT(DISTINCT user_id) FROM {$table_wishlists} WHERE user_id IS NOT NULL AND user_id > 0 AND date_modified > DATE_SUB(NOW(), INTERVAL 30 DAY) "); ?>

prefix . AICOSO_WISHLIST_TABLE_WISHLISTS; // Check if table exists first $table_exists = $wpdb->get_var("SHOW TABLES LIKE '{$table}'"); if ($table_exists != $table) { ?>

get_results("SELECT * FROM {$table} ORDER BY date_created DESC LIMIT 100"); ?>

get_db(); $items = $db->get_items($wishlist->id); $item_count = count($items); if ($wishlist->user_id) { $user = get_user_by('id', $wishlist->user_id); $user_display = $user ? $user->display_name : __('Deleted User', 'aicoso-wishlist-for-woocommerce'); } else { $user_display = __('Guest', 'aicoso-wishlist-for-woocommerce'); } ?>
id); ?> wishlist_name); ?> is_default): ?> privacy)); ?> date_created))); ?>
prefix . 'aicoso_wishlist_items'; $table_exists = $wpdb->get_var("SHOW TABLES LIKE '{$items_table}'"); if ($table_exists != $items_table) { ?>

get_db(); $popular_products = $db->get_popular_products(10, 30); ?>

product_id); if (!$product) continue; ?>
get_name()); ?> count); ?>
__('General Settings', 'aicoso-wishlist-for-woocommerce'), 'type' => 'title', 'id' => 'aicoso_wishlist_general_settings' ), array( 'title' => __('Enable for Guests', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Allow guest users to create wishlists', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_enable_for_guests', 'default' => 'yes', 'type' => 'checkbox' ), array( 'title' => __('Guest Cookie Expiration', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Number of days before guest wishlists expire', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_cookie_expiration', 'default' => '30', 'type' => 'number', 'custom_attributes' => array( 'min' => 1, 'max' => 365 ) ), array( 'title' => __('Default Privacy', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Default privacy setting for new wishlists', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_default_privacy', 'default' => 'public', 'type' => 'select', 'options' => array( 'public' => __('Public', 'aicoso-wishlist-for-woocommerce'), 'shared' => __('Shared', 'aicoso-wishlist-for-woocommerce'), 'private' => __('Private', 'aicoso-wishlist-for-woocommerce') ) ), array( 'title' => __('Remove on Purchase', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Remove items from wishlist after purchase', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_remove_on_purchase', 'default' => 'yes', 'type' => 'checkbox' ), array( 'type' => 'sectionend', 'id' => 'aicoso_wishlist_general_settings' ), array( 'title' => __('Display Settings', 'aicoso-wishlist-for-woocommerce'), 'type' => 'title', 'id' => 'aicoso_wishlist_display_settings' ), array( 'title' => __('Button Position', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Where to display the wishlist button on product pages', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_button_position', 'default' => 'after_add_to_cart', 'type' => 'select', 'options' => array( 'before_add_to_cart' => __('Before Add to Cart', 'aicoso-wishlist-for-woocommerce'), 'after_add_to_cart' => __('After Add to Cart', 'aicoso-wishlist-for-woocommerce'), 'after_thumbnail' => __('After Thumbnail', 'aicoso-wishlist-for-woocommerce'), 'after_summary' => __('After Summary', 'aicoso-wishlist-for-woocommerce') ) ), array( 'title' => __('Button Text', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Text to display on the wishlist button', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_button_text', 'default' => __('Add to Wishlist', 'aicoso-wishlist-for-woocommerce'), 'type' => 'text' ), array( 'title' => __('Button Icon', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Icon to display on the wishlist button', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_button_icon', 'default' => 'heart', 'type' => 'select', 'options' => array( 'heart' => __('Heart', 'aicoso-wishlist-for-woocommerce'), 'star' => __('Star', 'aicoso-wishlist-for-woocommerce'), 'bookmark' => __('Bookmark', 'aicoso-wishlist-for-woocommerce'), 'none' => __('No Icon', 'aicoso-wishlist-for-woocommerce') ) ), array( 'title' => __('Show on Product Loop', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Display wishlist button on shop/category pages', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_show_on_loop', 'default' => 'yes', 'type' => 'checkbox' ), array( 'title' => __('Loop Position', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Where to display the button on shop pages', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_loop_position', 'default' => 'after_add_to_cart', 'type' => 'select', 'options' => array( 'before_add_to_cart' => __('Before Add to Cart', 'aicoso-wishlist-for-woocommerce'), 'after_add_to_cart' => __('After Add to Cart', 'aicoso-wishlist-for-woocommerce') ) ), array( 'title' => __('Redirect After Add', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Redirect to wishlist page after adding product', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_redirect_after_add', 'default' => 'no', 'type' => 'checkbox' ), array( 'type' => 'sectionend', 'id' => 'aicoso_wishlist_display_settings' ), array( 'title' => __('Social Sharing', 'aicoso-wishlist-for-woocommerce'), 'type' => 'title', 'id' => 'aicoso_wishlist_social_settings' ), array( 'title' => __('Enable Social Sharing', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Allow users to share wishlists on social media', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_enable_share', 'default' => 'yes', 'type' => 'checkbox' ), array( 'title' => __('Facebook', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Enable Facebook sharing', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_share_facebook', 'default' => 'yes', 'type' => 'checkbox' ), array( 'title' => __('Twitter', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Enable Twitter sharing', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_share_twitter', 'default' => 'yes', 'type' => 'checkbox' ), array( 'title' => __('Pinterest', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Enable Pinterest sharing', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_share_pinterest', 'default' => 'yes', 'type' => 'checkbox' ), array( 'title' => __('WhatsApp', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Enable WhatsApp sharing', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_share_whatsapp', 'default' => 'yes', 'type' => 'checkbox' ), array( 'title' => __('Email', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Enable Email sharing', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_share_email', 'default' => 'yes', 'type' => 'checkbox' ), array( 'type' => 'sectionend', 'id' => 'aicoso_wishlist_social_settings' ), array( 'title' => __('Advanced Settings', 'aicoso-wishlist-for-woocommerce'), 'type' => 'title', 'id' => 'aicoso_wishlist_advanced_settings' ), array( 'title' => __('Enable AJAX', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Use AJAX for wishlist operations', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_enable_ajax', 'default' => 'yes', 'type' => 'checkbox' ), array( 'title' => __('Custom CSS', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Add custom CSS styles', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_custom_css', 'default' => '', 'type' => 'textarea', 'css' => 'width: 100%; height: 200px;' ), array( 'title' => __('Remove Data on Uninstall', 'aicoso-wishlist-for-woocommerce'), 'desc' => __('Remove all plugin data when uninstalling', 'aicoso-wishlist-for-woocommerce'), 'id' => 'aicoso_wishlist_remove_data_on_uninstall', 'default' => 'no', 'type' => 'checkbox' ), array( 'type' => 'sectionend', 'id' => 'aicoso_wishlist_advanced_settings' ) ); // Note: These settings are for display purposes only // The actual settings are managed by class-aicoso-wishlist-settings.php return $settings; } /** * Enqueue admin assets */ public function enqueue_admin_assets($hook) { // Debug: Uncomment to see the hook value // error_log('Aicoso Wishlist Hook: ' . $hook); // Only load on our plugin pages // Check for all our admin pages (WordPress converts hyphens to underscores in hook names) $plugin_pages = array( 'aicoso-wishlist', 'aicoso_wishlist', 'toplevel_page_aicoso-wishlist-for-woocommerce', '_page_aicoso-wishlist-settings', '_page_aicoso-wishlist-analytics', '_page_aicoso-wishlist-emails', '_page_aicoso-wishlist-database' ); $is_plugin_page = false; foreach ($plugin_pages as $page) { if (strpos($hook, $page) !== false) { $is_plugin_page = true; break; } } if (!$is_plugin_page) { return; } // Always enqueue base dashboard styles for consistent layout across all pages wp_enqueue_style( 'aicoso-wishlist-admin-dashboard', AICOSO_WISHLIST_PLUGIN_URL . 'admin/css/admin-dashboard.css', array(), AICOSO_WISHLIST_VERSION ); // Enqueue notices CSS wp_enqueue_style( 'aicoso-wishlist-admin-notices', AICOSO_WISHLIST_PLUGIN_URL . 'admin/css/admin-notices.css', array(), AICOSO_WISHLIST_VERSION ); // Enqueue settings page CSS if on settings page if (strpos($hook, 'aicoso-wishlist-settings') !== false) { // Enqueue WordPress color picker wp_enqueue_style('wp-color-picker'); wp_enqueue_script('wp-color-picker'); wp_enqueue_style( 'aicoso-wishlist-admin-settings', AICOSO_WISHLIST_PLUGIN_URL . 'admin/css/admin-settings.css', array('aicoso-wishlist-admin-dashboard', 'wp-color-picker'), AICOSO_WISHLIST_VERSION ); wp_enqueue_script( 'aicoso-wishlist-admin-settings', AICOSO_WISHLIST_PLUGIN_URL . 'admin/js/admin-settings.js', array('jquery', 'wp-color-picker'), AICOSO_WISHLIST_VERSION, true ); // Localize admin settings script wp_localize_script('aicoso-wishlist-admin-settings', 'aicosoWishlistSettings', array( 'i18n' => array( 'colorsReset' => __('Colors Reset!', 'aicoso-wishlist-for-woocommerce'), 'resetToDefaultColors' => __('Reset to Default Colors', 'aicoso-wishlist-for-woocommerce'), 'resetComplete' => __('Reset Complete!', 'aicoso-wishlist-for-woocommerce') ) )); } // Enqueue analytics page CSS and JS if (strpos($hook, 'aicoso-wishlist-analytics') !== false) { wp_enqueue_style( 'aicoso-wishlist-admin-analytics', AICOSO_WISHLIST_PLUGIN_URL . 'admin/css/admin-analytics.css', array('aicoso-wishlist-admin-dashboard'), AICOSO_WISHLIST_VERSION ); // Enqueue Chart.js locally wp_enqueue_script( 'chart-js', AICOSO_WISHLIST_PLUGIN_URL . 'admin/js/chart.min.js', array(), '3.9.1', true ); wp_enqueue_script( 'aicoso-wishlist-admin-analytics', AICOSO_WISHLIST_PLUGIN_URL . 'admin/js/admin-analytics.js', array('jquery', 'chart-js'), AICOSO_WISHLIST_VERSION, true ); } // Enqueue email campaigns page CSS and JS if (strpos($hook, 'aicoso-wishlist-emails') !== false) { wp_enqueue_style( 'aicoso-wishlist-admin-email-campaigns', AICOSO_WISHLIST_PLUGIN_URL . 'admin/css/admin-email-campaigns.css', array('aicoso-wishlist-admin-dashboard'), AICOSO_WISHLIST_VERSION ); wp_enqueue_script( 'aicoso-wishlist-admin-email-campaigns', AICOSO_WISHLIST_PLUGIN_URL . 'admin/js/admin-email-campaigns.js', array('jquery'), AICOSO_WISHLIST_VERSION, true ); } // Enqueue scripts wp_enqueue_script( 'aicoso-wishlist-admin-dashboard', AICOSO_WISHLIST_PLUGIN_URL . 'admin/js/admin-dashboard.js', array('jquery'), AICOSO_WISHLIST_VERSION, true ); // Enqueue admin tables JS for table creation functionality wp_enqueue_script( 'aicoso-wishlist-admin-tables', AICOSO_WISHLIST_PLUGIN_URL . 'admin/js/admin-tables.js', array('jquery'), AICOSO_WISHLIST_VERSION, true ); // Enqueue settings script on settings page if (strpos($hook, 'aicoso-wishlist-settings') !== false) { wp_enqueue_script( 'aicoso-wishlist-admin-settings', AICOSO_WISHLIST_PLUGIN_URL . 'admin/js/admin-settings.js', array('jquery'), AICOSO_WISHLIST_VERSION, true ); } // Localize script wp_localize_script('aicoso-wishlist-admin-dashboard', 'aicoso_admin', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('aicoso_admin_nonce'), 'export_nonce' => wp_create_nonce('aicoso_export_wishlists') )); // Localize admin tables script wp_localize_script('aicoso-wishlist-admin-tables', 'aicosoAdmin', array( 'nonce' => wp_create_nonce('aicoso_admin_nonce') )); } /** * AJAX handler for bulk actions */ public function ajax_bulk_action() { // Check nonce if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'aicoso_admin_nonce')) { wp_send_json_error('Security check failed'); } // Check permissions if (!current_user_can('manage_woocommerce')) { wp_send_json_error('Insufficient permissions'); } $action = sanitize_text_field($_POST['bulk_action']); $items = array_map('absint', $_POST['items']); if (empty($items)) { wp_send_json_error('No items selected'); } global $wpdb; $table_wishlists = $wpdb->prefix . 'aicoso_wishlists'; $table_items = $wpdb->prefix . 'aicoso_wishlist_items'; // Create placeholders for SQL query $placeholders = implode(',', array_fill(0, count($items), '%d')); if ($action === 'delete') { // Delete wishlists and their items // Delete items first $wpdb->query($wpdb->prepare(" DELETE FROM {$table_items} WHERE wishlist_id IN ({$placeholders}) ", $items)); // Then delete wishlists $deleted = $wpdb->query($wpdb->prepare(" DELETE FROM {$table_wishlists} WHERE id IN ({$placeholders}) ", $items)); if ($deleted !== false) { wp_send_json_success(array( 'message' => sprintf(__('%d wishlists deleted', 'aicoso-wishlist-for-woocommerce'), $deleted) )); } else { wp_send_json_error('Failed to delete wishlists'); } } elseif ($action === 'export') { // Generate export data $wishlists = $wpdb->get_results($wpdb->prepare(" SELECT * FROM {$table_wishlists} WHERE id IN ({$placeholders}) ", $items)); if (empty($wishlists)) { wp_send_json_error(__('No wishlists found to export', 'aicoso-wishlist-for-woocommerce')); } // Create CSV content $csv_content = "ID,Name,User,Privacy,Items,Created\n"; foreach ($wishlists as $wishlist) { $item_count = $wpdb->get_var($wpdb->prepare(" SELECT COUNT(*) FROM {$table_items} WHERE wishlist_id = %d ", $wishlist->id)); // Safely get user name $user_name = 'Guest'; if ($wishlist->user_id) { $user_data = get_userdata($wishlist->user_id); if ($user_data) { $user_name = $user_data->display_name; } else { $user_name = 'User #' . $wishlist->user_id; } } $csv_content .= sprintf('"%s","%s","%s","%s","%s","%s"' . "\n", esc_html($wishlist->id), str_replace('"', '""', $wishlist->wishlist_name), // Escape quotes in CSV str_replace('"', '""', $user_name), esc_html($wishlist->privacy), esc_html($item_count), esc_html($wishlist->date_created) ); } // Store export in transient $export_key = 'aicoso_export_' . wp_generate_password(12, false); set_transient($export_key, $csv_content, 300); // 5 minutes wp_send_json_success(array( 'message' => sprintf(__('%d wishlists ready for export', 'aicoso-wishlist-for-woocommerce'), count($wishlists)), 'download_url' => admin_url('admin-ajax.php?action=aicoso_download_export&key=' . $export_key) )); } else { wp_send_json_error(__('Invalid bulk action', 'aicoso-wishlist-for-woocommerce')); } } /** * AJAX handler for downloading bulk export */ public function ajax_download_export() { // Check if key is provided if (!isset($_GET['key'])) { wp_die(__('Invalid export key', 'aicoso-wishlist-for-woocommerce')); } $export_key = sanitize_text_field($_GET['key']); // Get export data from transient $csv_content = get_transient($export_key); if ($csv_content === false) { wp_die(__('Export expired or not found. Please try again.', 'aicoso-wishlist-for-woocommerce')); } // Delete the transient delete_transient($export_key); // Set headers for CSV download $filename = 'wishlists-export-' . date('Y-m-d-His') . '.csv'; header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename=' . $filename); header('Pragma: no-cache'); header('Expires: 0'); // Add BOM for UTF-8 compatibility echo "\xEF\xBB\xBF"; // Output CSV content echo $csv_content; exit; } /** * AJAX handler for exporting wishlists */ public function ajax_export_wishlists() { // Check nonce if (!isset($_GET['nonce']) || !wp_verify_nonce($_GET['nonce'], 'aicoso_export_wishlists')) { wp_die('Security check failed'); } // Check permissions if (!current_user_can('manage_woocommerce')) { wp_die('Insufficient permissions'); } $format = sanitize_text_field($_GET['format']); $filter = sanitize_text_field($_GET['filter']); global $wpdb; $table_wishlists = $wpdb->prefix . 'aicoso_wishlists'; $table_items = $wpdb->prefix . 'aicoso_wishlist_items'; // Build query based on filter $where_clause = "WHERE 1=1"; if ($filter === 'active') { $where_clause .= " AND date_modified > DATE_SUB(NOW(), INTERVAL 30 DAY)"; } elseif ($filter === 'registered') { $where_clause .= " AND user_id IS NOT NULL AND user_id > 0"; } elseif ($filter === 'guest') { $where_clause .= " AND (user_id IS NULL OR user_id = 0)"; } $wishlists = $wpdb->get_results("SELECT * FROM {$table_wishlists} {$where_clause}"); if ($format === 'csv') { header('Content-Type: text/csv'); header('Content-Disposition: attachment; filename="wishlists-' . date('Y-m-d') . '.csv"'); $output = fopen('php://output', 'w'); fputcsv($output, array('ID', 'Name', 'User', 'Privacy', 'Items', 'Created', 'Modified')); foreach ($wishlists as $wishlist) { $item_count = $wpdb->get_var($wpdb->prepare(" SELECT COUNT(*) FROM {$table_items} WHERE wishlist_id = %d ", $wishlist->id)); $user_name = $wishlist->user_id ? get_userdata($wishlist->user_id)->display_name : 'Guest'; fputcsv($output, array( $wishlist->id, $wishlist->wishlist_name, $user_name, $wishlist->privacy, $item_count, $wishlist->date_created, $wishlist->date_modified )); } fclose($output); exit; } elseif ($format === 'json') { header('Content-Type: application/json'); header('Content-Disposition: attachment; filename="wishlists-' . date('Y-m-d') . '.json"'); $export_data = array(); foreach ($wishlists as $wishlist) { $items = $wpdb->get_results($wpdb->prepare(" SELECT * FROM {$table_items} WHERE wishlist_id = %d ", $wishlist->id)); $export_data[] = array( 'id' => $wishlist->id, 'name' => $wishlist->wishlist_name, 'user_id' => $wishlist->user_id, 'privacy' => $wishlist->privacy, 'items' => $items, 'created' => $wishlist->date_created, 'modified' => $wishlist->date_modified ); } echo json_encode($export_data, JSON_PRETTY_PRINT); exit; } } /** * AJAX handler for sending promotional emails */ public function ajax_send_promotional_email() { // Check nonce if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'aicoso_admin_nonce')) { wp_send_json_error('Security check failed'); } // Check permissions if (!current_user_can('manage_options')) { wp_send_json_error('Insufficient permissions'); } $args = array( 'subject' => sanitize_text_field($_POST['email_subject']), 'message' => wp_kses_post($_POST['email_message']), 'users' => sanitize_text_field($_POST['target_users']), 'include_wishlist' => isset($_POST['include_wishlist']), 'discount_code' => sanitize_text_field($_POST['discount_code']), ); // Check if promotional emails are enabled global $aicoso_wishlist_settings; if ($aicoso_wishlist_settings->get('promotional_emails') !== 'yes') { wp_send_json_error(__('Promotional emails are disabled. Please enable them in settings first.', 'aicoso-wishlist-for-woocommerce')); } require_once AICOSO_WISHLIST_PLUGIN_DIR . 'includes/class-aicoso-wishlist-emails.php'; $emails = Aicoso_Wishlist_Emails::get_instance(); $result = $emails->send_promotional_email($args); if ($result && is_array($result)) { if ($result['sent'] > 0) { wp_send_json_success(array( 'message' => sprintf(__('Email campaign completed! Sent: %d, Failed: %d, Total: %d', 'aicoso-wishlist-for-woocommerce'), $result['sent'], $result['failed'], $result['total']) )); } else { wp_send_json_error(__('Email campaign failed. No emails were sent.', 'aicoso-wishlist-for-woocommerce')); } } else { wp_send_json_error(__('Email campaign processing failed.', 'aicoso-wishlist-for-woocommerce')); } } /** * AJAX handler for creating database tables */ public function ajax_create_tables() { // Check nonce if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'aicoso_create_tables')) { wp_send_json_error('Security check failed'); } // Check permissions if (!current_user_can('manage_options')) { wp_send_json_error('Insufficient permissions'); } // Include installer class require_once AICOSO_WISHLIST_PLUGIN_DIR . 'includes/class-aicoso-wishlist-installer.php'; // Run installer try { Aicoso_Wishlist_Installer::run(); wp_send_json_success('Tables created successfully'); } catch (Exception $e) { wp_send_json_error($e->getMessage()); } } /** * AJAX handler for analytics export */ public function ajax_export_analytics() { // Check nonce check_ajax_referer('aicoso_admin_nonce', 'nonce'); // Check permissions if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => __('Insufficient permissions', 'aicoso-wishlist-for-woocommerce'))); } $range = isset($_POST['range']) ? sanitize_text_field($_POST['range']) : '7days'; // Generate export URL $export_url = add_query_arg(array( 'action' => 'aicoso_analytics_export', 'range' => $range, '_wpnonce' => wp_create_nonce('aicoso_analytics_export') ), admin_url('admin.php')); wp_send_json_success(array( 'url' => $export_url, 'message' => __('Export started', 'aicoso-wishlist-for-woocommerce') )); } /** * Handle analytics CSV export */ public function handle_analytics_export() { if (!isset($_GET['action']) || $_GET['action'] !== 'aicoso_analytics_export') { return; } // Check nonce if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'aicoso_analytics_export')) { wp_die(__('Security check failed', 'aicoso-wishlist-for-woocommerce')); } // Check permissions if (!current_user_can('manage_options')) { wp_die(__('You do not have permission to export analytics', 'aicoso-wishlist-for-woocommerce')); } $range = isset($_GET['range']) ? sanitize_text_field($_GET['range']) : '7days'; $this->export_analytics_csv($range); exit; } /** * Export analytics data as CSV */ private function export_analytics_csv($date_range = '7days') { global $wpdb; $table_analytics = $wpdb->prefix . 'aicoso_wishlist_analytics'; $table_wishlists = $wpdb->prefix . 'aicoso_wishlists'; $table_wishlist_items = $wpdb->prefix . 'aicoso_wishlist_items'; // Build date query $analytics_date_query = ''; switch($date_range) { case '24hours': $analytics_date_query = "AND event_date > DATE_SUB(NOW(), INTERVAL 24 HOUR)"; $range_label = 'Last 24 Hours'; break; case '7days': $analytics_date_query = "AND event_date > DATE_SUB(NOW(), INTERVAL 7 DAY)"; $range_label = 'Last 7 Days'; break; case '30days': $analytics_date_query = "AND event_date > DATE_SUB(NOW(), INTERVAL 30 DAY)"; $range_label = 'Last 30 Days'; break; case '90days': $analytics_date_query = "AND event_date > DATE_SUB(NOW(), INTERVAL 90 DAY)"; $range_label = 'Last 90 Days'; break; default: $analytics_date_query = ''; $range_label = 'All Time'; } // Get top products data $top_products = $wpdb->get_results(" SELECT product_id, COUNT(*) as wishlist_count, MAX(event_date) as last_added FROM {$table_analytics} WHERE event_type = 'added' {$analytics_date_query} GROUP BY product_id ORDER BY wishlist_count DESC "); // Get daily activity data $daily_activity = $wpdb->get_results(" SELECT DATE(event_date) as activity_date, COUNT(*) as item_count FROM {$table_analytics} WHERE event_type = 'added' {$analytics_date_query} GROUP BY DATE(event_date) ORDER BY activity_date DESC "); // Get overall stats $total_wishlists = $wpdb->get_var("SELECT COUNT(*) FROM {$table_wishlists}"); $total_items = $wpdb->get_var("SELECT COUNT(*) FROM {$table_wishlist_items}"); $unique_users = $wpdb->get_var("SELECT COUNT(DISTINCT user_id) FROM {$table_wishlists} WHERE user_id > 0"); $guest_wishlists = $wpdb->get_var("SELECT COUNT(*) FROM {$table_wishlists} WHERE user_id IS NULL OR user_id = 0"); // Set headers for CSV download $filename = 'wishlist-analytics-' . sanitize_file_name($date_range) . '-' . date('Y-m-d-His') . '.csv'; header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename=' . $filename); header('Pragma: no-cache'); header('Expires: 0'); // Add BOM for UTF-8 compatibility echo "\xEF\xBB\xBF"; // Open output stream $output = fopen('php://output', 'w'); // Add summary section fputcsv($output, array('Wishlist Analytics Report')); fputcsv($output, array('Generated:', current_time('mysql'))); fputcsv($output, array('Period:', $range_label)); fputcsv($output, array('')); // Overall metrics fputcsv($output, array('Overall Metrics')); fputcsv($output, array('Metric', 'Value')); fputcsv($output, array('Total Wishlists', $total_wishlists)); fputcsv($output, array('Total Items', $total_items)); fputcsv($output, array('Registered Users', $unique_users)); fputcsv($output, array('Guest Wishlists', $guest_wishlists)); fputcsv($output, array('Average Items per Wishlist', $total_wishlists > 0 ? round($total_items / $total_wishlists, 2) : 0)); fputcsv($output, array('')); // Top Products section fputcsv($output, array('Top Wishlist Products - ' . $range_label)); fputcsv($output, array('Product ID', 'Product Name', 'Product SKU', 'Times Wishlisted', 'Last Added')); foreach ($top_products as $item) { $product = wc_get_product($item->product_id); if ($product) { fputcsv($output, array( $item->product_id, $product->get_name(), $product->get_sku() ?: 'N/A', $item->wishlist_count, $item->last_added )); } } fputcsv($output, array('')); // Daily Activity section fputcsv($output, array('Daily Activity - ' . $range_label)); fputcsv($output, array('Date', 'Items Added')); // Reverse to show oldest to newest $daily_activity_reversed = array_reverse($daily_activity); foreach ($daily_activity_reversed as $day) { fputcsv($output, array( $day->activity_date, $day->item_count )); } fclose($output); } /** * AJAX handler for paginating Top Wishlist Products in Analytics */ public function ajax_get_top_products_page() { check_ajax_referer('aicoso_analytics_nonce', 'nonce'); if (!current_user_can('manage_options') && !current_user_can('manage_woocommerce')) { wp_send_json_error(array('message' => __('Permission denied', 'aicoso-wishlist-for-woocommerce'))); } global $wpdb; $table_analytics = $wpdb->prefix . 'aicoso_wishlist_analytics'; $date_range = isset($_GET['range']) ? sanitize_text_field($_GET['range']) : '7days'; $top_per_page = isset($_GET['top_per_page']) && in_array((int)$_GET['top_per_page'], array(10, 20, 50), true) ? (int)$_GET['top_per_page'] : 10; $current_top_page = isset($_GET['top_paged']) ? max(1, absint($_GET['top_paged'])) : 1; $analytics_date_query = ''; switch($date_range) { case '24hours': $analytics_date_query = "AND event_date > DATE_SUB(NOW(), INTERVAL 24 HOUR)"; $range_label = __('Last 24 Hours', 'aicoso-wishlist-for-woocommerce'); break; case '7days': $analytics_date_query = "AND event_date > DATE_SUB(NOW(), INTERVAL 7 DAY)"; $range_label = __('Last 7 Days', 'aicoso-wishlist-for-woocommerce'); break; case '30days': $analytics_date_query = "AND event_date > DATE_SUB(NOW(), INTERVAL 30 DAY)"; $range_label = __('Last 30 Days', 'aicoso-wishlist-for-woocommerce'); break; case '90days': $analytics_date_query = "AND event_date > DATE_SUB(NOW(), INTERVAL 90 DAY)"; $range_label = __('Last 90 Days', 'aicoso-wishlist-for-woocommerce'); break; default: $analytics_date_query = ''; $range_label = __('All Time', 'aicoso-wishlist-for-woocommerce'); } $total_top_products = (int) $wpdb->get_var(" SELECT COUNT(DISTINCT product_id) FROM {$table_analytics} WHERE event_type = 'added' {$analytics_date_query} "); $total_top_pages = max(1, (int) ceil($total_top_products / $top_per_page)); if ($current_top_page > $total_top_pages && $total_top_products > 0) { $current_top_page = $total_top_pages; } $top_offset = ($current_top_page - 1) * $top_per_page; $top_products = $wpdb->get_results($wpdb->prepare(" SELECT product_id, COUNT(*) as wishlist_count, MAX(event_date) as last_added FROM {$table_analytics} WHERE event_type = 'added' {$analytics_date_query} GROUP BY product_id ORDER BY wishlist_count DESC LIMIT %d OFFSET %d ", $top_per_page, $top_offset)); ob_start(); include AICOSO_WISHLIST_PLUGIN_DIR . 'admin/partials/admin-analytics-top-products.php'; $html = ob_get_clean(); wp_send_json_success(array( 'html' => $html, 'total_items' => $total_top_products, 'total_pages' => $total_top_pages, 'current_page' => $current_top_page, 'per_page' => $top_per_page, 'range' => $date_range, )); } }