plugin_name = $plugin_name; $this->version = $version; } /** * Register the stylesheets for the admin area. */ public function enqueue_styles() { $screen = get_current_screen(); if ($screen && strpos($screen->id, 'wpfmj') !== false) { wp_enqueue_style( $this->plugin_name, WPFMJ_PLUGIN_URL . 'admin/css/wpfmj-admin.css', array(), $this->version, 'all' ); } } /** * Register the JavaScript for the admin area. */ public function enqueue_scripts() { $screen = get_current_screen(); if ($screen && strpos($screen->id, 'wpfmj') !== false) { // Enqueue WordPress components $asset_file = include(WPFMJ_PLUGIN_DIR . 'admin/js/wpfmj-wizard.asset.php'); if (!$asset_file) { $asset_file = array( 'dependencies' => array( 'wp-element', 'wp-components', 'wp-i18n', 'wp-api-fetch', ), 'version' => $this->version ); } wp_enqueue_script( $this->plugin_name, WPFMJ_PLUGIN_URL . 'admin/js/wpfmj-wizard.js', $asset_file['dependencies'], $asset_file['version'], true ); wp_localize_script( $this->plugin_name, 'wpfmjData', array( 'restUrl' => rest_url(), 'nonce' => wp_create_nonce('wp_rest'), 'ajaxUrl' => admin_url('admin-ajax.php'), 'ajaxNonce' => wp_create_nonce('wpfmj_ajax'), 'editId' => isset($_GET['edit']) ? intval($_GET['edit']) : 0, ) ); } } /** * AJAX: Get all WPForms. */ public function ajax_get_forms() { check_ajax_referer('wpfmj_ajax', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $forms = wpforms()->form->get('', array('orderby' => 'title')); $formatted_forms = array(); foreach ($forms as $form) { $formatted_forms[] = array( 'id' => $form->ID, 'title' => $form->post_title, ); } wp_send_json_success($formatted_forms); } /** * AJAX: Get form fields. */ public function ajax_get_form_fields() { check_ajax_referer('wpfmj_ajax', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $form_id = isset($_POST['form_id']) ? intval($_POST['form_id']) : 0; if (!$form_id) { wp_send_json_error('Invalid form ID'); } $form = wpforms()->form->get($form_id); if (!$form) { wp_send_json_error('Form not found'); } $form_data = wpforms_decode($form->post_content); // Validate form_data structure if (!is_array($form_data) || !isset($form_data['fields']) || !is_array($form_data['fields'])) { wp_send_json_error('Invalid form data structure'); } $fields = array(); foreach ($form_data['fields'] as $field) { // Validate field structure if (!is_array($field) || !isset($field['type']) || !isset($field['label'])) { continue; // Skip invalid fields } $field_type = sanitize_text_field($field['type']); $field_id = isset($field['id']) ? sanitize_text_field($field['id']) : ''; $field_label = sanitize_text_field($field['label']); // Get choices for fields that have them $choices = array(); if (in_array($field_type, array('checkbox', 'radio', 'select', 'payment-checkbox', 'payment-multiple', 'payment-select'))) { if (isset($field['choices']) && is_array($field['choices'])) { foreach ($field['choices'] as $choice) { if (is_array($choice) && isset($choice['label'])) { $choices[] = array( 'label' => sanitize_text_field($choice['label']), 'value' => isset($choice['value']) ? sanitize_text_field($choice['value']) : sanitize_text_field($choice['label']), ); } } } } $fields[] = array( 'id' => $field_id, 'label' => $field_label, 'type' => $field_type, 'choices' => $choices, ); } wp_send_json_success($fields); } /** * AJAX: Test Mailjet connection. */ public function ajax_test_mailjet() { check_ajax_referer('wpfmj_ajax', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $api_key = isset($_POST['api_key']) ? sanitize_text_field($_POST['api_key']) : ''; $api_secret = isset($_POST['api_secret']) ? sanitize_text_field($_POST['api_secret']) : ''; if (empty($api_key) || empty($api_secret)) { wp_send_json_error('API credentials required'); } $api = new WPFMJ_Mailjet_API($api_key, $api_secret); $result = $api->test_connection(); if ($result) { wp_send_json_success('Connection successful'); } else { wp_send_json_error('Connection failed. Please check your credentials.'); } } /** * AJAX: Get Mailjet lists. */ public function ajax_get_mailjet_lists() { check_ajax_referer('wpfmj_ajax', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $api_key = isset($_POST['api_key']) ? sanitize_text_field($_POST['api_key']) : ''; $api_secret = isset($_POST['api_secret']) ? sanitize_text_field($_POST['api_secret']) : ''; if (empty($api_key) || empty($api_secret)) { wp_send_json_error('API credentials required'); } $api = new WPFMJ_Mailjet_API($api_key, $api_secret); $lists = $api->get_lists(); if (is_wp_error($lists)) { wp_send_json_error($lists->get_error_message()); } $formatted_lists = array(); foreach ($lists as $list) { $formatted_lists[] = array( 'id' => $list['ID'], 'name' => $list['Name'], ); } wp_send_json_success($formatted_lists); } /** * AJAX: Save automation. */ public function ajax_save_automation() { check_ajax_referer('wpfmj_ajax', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $data = isset($_POST['data']) ? $_POST['data'] : array(); $edit_id = isset($_POST['edit_id']) ? intval($_POST['edit_id']) : 0; // Validate required fields $required = array('title', 'form_id', 'field_mapping', 'trigger_field_id', 'api_key', 'api_secret', 'list_mappings', 'activate'); foreach ($required as $field) { if (!isset($data[$field]) || (is_string($data[$field]) && empty($data[$field]))) { wp_send_json_error("Missing required field: {$field}"); } } // Sanitize and validate field_mapping if (!is_array($data['field_mapping']) || !isset($data['field_mapping']['email'])) { wp_send_json_error('Invalid field mapping structure'); } $field_mapping = array( 'email' => sanitize_text_field($data['field_mapping']['email']), 'firstname' => isset($data['field_mapping']['firstname']) ? sanitize_text_field($data['field_mapping']['firstname']) : '', 'lastname' => isset($data['field_mapping']['lastname']) ? sanitize_text_field($data['field_mapping']['lastname']) : '', ); // Sanitize and validate list_mappings if (!is_array($data['list_mappings'])) { wp_send_json_error('Invalid list mappings structure'); } $list_mappings = array(); foreach ($data['list_mappings'] as $key => $value) { $list_mappings[sanitize_text_field($key)] = sanitize_text_field($value); } // Sanitize API credentials $api_key = sanitize_text_field($data['api_key']); $api_secret = sanitize_text_field($data['api_secret']); // Encrypt API credentials $encrypted_key = WPFMJ_Encryption::encrypt($api_key); $encrypted_secret = WPFMJ_Encryption::encrypt($api_secret); if (empty($encrypted_key) || empty($encrypted_secret)) { wp_send_json_error('Failed to encrypt API credentials'); } // Prepare config $config = array( 'form_id' => intval($data['form_id']), 'field_mapping' => $field_mapping, 'trigger_field_id' => sanitize_text_field($data['trigger_field_id']), 'api_key' => $encrypted_key, 'api_secret' => $encrypted_secret, 'list_mappings' => $list_mappings, ); // Create or update post $post_data = array( 'post_title' => sanitize_text_field($data['title']), 'post_type' => 'wpfmj_automation', 'post_status' => $data['activate'] ? 'publish' : 'draft', ); if ($edit_id) { $post_data['ID'] = $edit_id; $post_id = wp_update_post($post_data); } else { $post_id = wp_insert_post($post_data); } if (is_wp_error($post_id)) { wp_send_json_error($post_id->get_error_message()); } // Save config update_post_meta($post_id, '_wpfmj_config', $config); update_post_meta($post_id, '_wpfmj_form_id', $config['form_id']); wp_send_json_success(array( 'id' => $post_id, 'message' => 'Automation saved successfully', )); } /** * AJAX: Get automation. */ public function ajax_get_automation() { check_ajax_referer('wpfmj_ajax', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $id = isset($_POST['id']) ? intval($_POST['id']) : 0; if (!$id) { wp_send_json_error('Invalid ID'); } $post = get_post($id); $config = get_post_meta($id, '_wpfmj_config', true); if (!$post || !$config) { wp_send_json_error('Automation not found'); } // Decrypt API credentials $decrypted_key = WPFMJ_Encryption::decrypt($config['api_key']); $decrypted_secret = WPFMJ_Encryption::decrypt($config['api_secret']); // Check for decryption failures if ($decrypted_key === false || $decrypted_secret === false) { wp_send_json_error('Failed to decrypt API credentials. The encryption key may have changed.'); } $config['api_key'] = $decrypted_key; $config['api_secret'] = $decrypted_secret; wp_send_json_success(array( 'title' => $post->post_title, 'status' => $post->post_status, 'config' => $config, )); } /** * AJAX: Toggle automation status. */ public function ajax_toggle_automation() { check_ajax_referer('wpfmj_ajax', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $id = isset($_POST['id']) ? intval($_POST['id']) : 0; if (!$id) { wp_send_json_error('Invalid ID'); } $post = get_post($id); if (!$post) { wp_send_json_error('Automation not found'); } $new_status = $post->post_status === 'publish' ? 'draft' : 'publish'; wp_update_post(array( 'ID' => $id, 'post_status' => $new_status, )); wp_send_json_success(array( 'status' => $new_status, 'message' => 'Automation ' . ($new_status === 'publish' ? 'activated' : 'paused'), )); } /** * AJAX: Delete automation. */ public function ajax_delete_automation() { check_ajax_referer('wpfmj_ajax', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $id = isset($_POST['id']) ? intval($_POST['id']) : 0; if (!$id) { wp_send_json_error('Invalid ID'); } $result = wp_delete_post($id, true); if ($result) { wp_send_json_success('Automation deleted'); } else { wp_send_json_error('Failed to delete automation'); } } /** * AJAX: Get dashboard data. */ public function ajax_get_dashboard_data() { check_ajax_referer('wpfmj_ajax', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $automations = get_posts(array( 'post_type' => 'wpfmj_automation', 'post_status' => array('publish', 'draft'), 'posts_per_page' => -1, )); if (empty($automations)) { wp_send_json_success(array()); return; } // Pre-load all post meta to prevent N+1 queries $automation_ids = wp_list_pluck($automations, 'ID'); update_post_meta_cache($automation_ids); // Pre-load all error counts in a single query to prevent N+1 $logger = new WPFMJ_Error_Logger(); $error_counts = $logger->get_error_counts_bulk($automation_ids); $data = array(); foreach ($automations as $automation) { $config = get_post_meta($automation->ID, '_wpfmj_config', true); $form = wpforms()->form->get($config['form_id']); $data[] = array( 'id' => $automation->ID, 'title' => $automation->post_title, 'form_name' => $form ? $form->post_title : 'Unknown Form', 'status' => $automation->post_status, 'error_count' => isset($error_counts[$automation->ID]) ? $error_counts[$automation->ID] : 0, 'created' => $automation->post_date, ); } wp_send_json_success($data); } }