$category_name, 'slug' => $category_slug, )); if ($res) { wp_send_json_success(array('status' => 'ok', 'message' => 'Category updated successfully!', 'category_id' => $category_id), 200); } else { wp_send_json_error(array('status' => 'error', 'message' => 'There was an error updating the category. Please try again.'), 500); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_delete_product_category', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $category_id = isset($_POST['category_id']) ? (int) $_POST['category_id'] : 0; $was_deleted = AFFLCategoryService::delete($category_id); if ($was_deleted) { wp_send_json_success(array('status' => 'ok', 'message' => 'Category deleted successfully!', 'category_id' => $category_id), 200); } else { wp_send_json_error(array('status' => 'error', 'message' => 'There was an error deleting the category. Please try again.'), 500); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_save_product_category', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $category_id = isset($_POST['category_id']) ? intval($_POST['category_id']) : null; $name = isset($_POST['name']) ? sanitize_text_field(wp_unslash($_POST['name'])) : ''; $slug = isset($_POST['slug']) ? sanitize_text_field(wp_unslash($_POST['slug'])) : ''; $description = isset($_POST['description']) ? sanitize_textarea_field(wp_unslash($_POST['description'])) : ''; $criteria = isset($_POST['criteria']) && is_array($_POST['criteria']) ? map_deep(wp_unslash($_POST['criteria']), 'sanitize_text_field') : array(); $criteria_to_remove = isset($_POST['criteria_to_remove']) && is_array($_POST['criteria_to_remove']) ? array_map('intval', $_POST['criteria_to_remove']) : []; if (empty($name)) { throw new Exception(__('Category name is required.', 'affililabs')); } $term_data = array( 'name' => $name, 'slug' => $slug, 'description' => $description, ); if ($category_id) { $result = wp_update_term($category_id, AFFILILABS_TAXONOMY_PRODUCT_CATEGORY, $term_data); } else { $result = wp_insert_term($name, AFFILILABS_TAXONOMY_PRODUCT_CATEGORY, $term_data); } if (is_wp_error($result)) { throw new Exception($result->get_error_message()); } $term_id = is_array($result) ? $result['term_id'] : $result; if (!empty($criteria_to_remove)) { foreach ($criteria_to_remove as $criterion_to_remove_id) { if (isset($criteria[$criterion_to_remove_id])) { unset($criteria[$criterion_to_remove_id]); } AFFLCriteriaService::unlink_criterion_from_category($criterion_to_remove_id, $term_id); } } AFFLCategoryService::save_category_meta($term_id, $criteria); $updated_criteria_groups = AFFLCriteriaService::get_criterions_by_categories([$term_id]); wp_send_json_success(array( 'status' => 'ok', 'message' => 'Category saved successfully!', 'term_id' => $term_id, 'criteria_groups' => $updated_criteria_groups ), 200); } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); // Add category via Form add_action('wp_ajax_affililabs_add_product_category', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $category_name = isset($_POST['name']) ? sanitize_text_field(wp_unslash($_POST['name'])) : ''; $category_slug = isset($_POST['slug']) ? sanitize_text_field(wp_unslash($_POST['slug'])) : ''; if (empty($category_name) || empty($category_slug)) { throw new Exception(__('Category name and slug are required.', 'affililabs')); } $term = wp_insert_term($category_name, AFFILILABS_TAXONOMY_PRODUCT_CATEGORY, array( 'slug' => $category_slug, )); if (is_wp_error($term)) { throw new Exception($term->get_error_message()); } wp_send_json_success(array( 'status' => 'ok', 'message' => 'Category created successfully.', 'term_id' => $term['term_id'], 'name' => $category_name, 'slug' => $category_slug, ), 201 ); } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_save_product', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $data = map_deep(json_decode(wp_unslash($_POST['product_data'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); AFFL_LoggerService::debug('AJAX Product Save - Sanitized data: ' . esc_html(print_r($data, true)), 'DEBUG'); if (!isset($data['criterion_values']) || !is_array($data['criterion_values'])) { AFFL_LoggerService::debug('AJAX Product Save - No criterion_values provided in request', 'DEBUG'); } else { AFFL_LoggerService::debug('AJAX Product Save - Criterion values: ' . esc_html(print_r($data['criterion_values'], true)), 'DEBUG'); } $allowed_html = affl_get_allowed_html_tags(); $product = array(); $product['id'] = isset($data['id']) ? intval($data['id']) : null; $product['name'] = sanitize_text_field($data['name'] ?? ''); $product['price'] = affl_sanitize_float_input($data['price'] ?? null); $product['price_currency'] = sanitize_text_field($data['price_currency'] ?? '$'); $product['image_url'] = esc_url_raw($data['image_url'] ?? ''); $product['image_id'] = isset($data['image_id']) ? intval($data['image_id']) : null; $product['status'] = sanitize_key($data['status'] ?? 'inactive'); $product['category'] = sanitize_text_field($data['category'] ?? ''); $product['marketplace_id'] = isset($data['marketplace_id']) ? intval($data['marketplace_id']) : null; $product['custom_fields'] = isset($data['custom_fields']) ? map_deep($data['custom_fields'], 'sanitize_text_field') : array(); $product['pros'] = wp_kses($data['pros'] ?? '', $allowed_html); $product['cons'] = wp_kses($data['cons'] ?? '', $allowed_html); $product['description'] = wp_kses($data['description'] ?? '', $allowed_html); $product['short_features'] = wp_kses($data['short_features'] ?? '', $allowed_html); $product['affiliate_link'] = esc_url_raw($data['affiliate_link'] ?? ''); $product['rating'] = affl_sanitize_float_input($data['rating'] ?? null); $product['rating_rationale'] = sanitize_textarea_field($data['rating_rationale'] ?? ''); $product['rating_sources'] = wp_kses($data['rating_sources'] ?? '', $allowed_html); $product['criterion_values'] = isset($data['criterion_values']) ? map_deep($data['criterion_values'], 'sanitize_text_field') : array(); $product['applied_template_id'] = isset($data['applied_template_id']) ? intval($data['applied_template_id']) : null; AFFL_LoggerService::debug('AJAX Product Save - Product data after processing: ' . esc_html(print_r($product, true)), 'DEBUG'); if ($product['price'] < 0) { throw new Exception(__('Invalid price provided. Price must be a non-negative number.', 'affililabs')); } if ($product['rating'] < 0 || $product['rating'] > 5) { throw new Exception(__('Invalid rating provided. Rating must be a number between 0 and 5.', 'affililabs')); } if (empty($product['name']) || empty($product['status'])) { throw new Exception(__('Product name and status are required.', 'affililabs')); } $is_new_product = empty($product['id']); $product_id = AFFLProductService::save($product); $saved_product_data = AFFLProductService::get_product_by_id($product_id); if ($is_new_product) { wp_send_json_success(array( 'status' => 'ok', 'message' => 'Product created successfully!', 'product_id' => $product_id, 'new_product_data' => $saved_product_data ), 201); } else { wp_send_json_success(array( 'status' => 'ok', 'message' => 'Product updated successfully!', 'product_id' => $product_id, 'new_product_data' => $saved_product_data ), 200); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_delete_product', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $product_id = isset($_POST['product_id']) ? intval(wp_unslash($_POST['product_id'])) : null; if (empty($product_id)) { throw new Exception(__('No product id provided (product_id)', 'affililabs')); } $was_deleted = AFFLProductService::delete($product_id); if ($was_deleted) { wp_send_json_success(array('status' => 'ok', 'message' => 'Product deleted successfully!', 'product_id' => $product_id), 200); } else { wp_send_json_error(array('status' => 'error', 'message' => 'There was an error deleting the product. Please try again.'), 500); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_save_marketplace', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $data = map_deep(json_decode(wp_unslash($_POST['marketplace_data'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); //@TODO: Or sanitize text field $marketplace = array(); $marketplace['id'] = isset($data['id']) ? intval($data['id']) : null; $marketplace['name'] = sanitize_text_field($data['name'] ?? ''); $marketplace['api_key'] = sanitize_text_field($data['api_key'] ?? ''); $marketplace['affiliate_id'] = sanitize_text_field($data['affiliate_id'] ?? ''); $marketplace['category'] = sanitize_text_field($data['category'] ?? ''); $marketplace['url'] = esc_url_raw($data['url'] ?? ''); $marketplace['image_id'] = isset($data['image_id']) ? intval($data['image_id']) : null; $marketplace['status'] = sanitize_key($data['status'] ?? 'inactive'); if (empty($marketplace['name'])) { throw new Exception(__('Marketplace name is required.', 'affililabs')); } if (!$marketplace['id']) { $marketplace_id = AFFLMarketplaceService::save($marketplace); wp_send_json_success(array('status' => 'ok', 'message' => 'Marketplace created successfully!', 'marketplace_id' => $marketplace_id), 201); } else { $marketplace_id = AFFLMarketplaceService::save($marketplace); wp_send_json_success(array('status' => 'ok', 'message' => 'Marketplace updated successfully!', 'marketplace_id' => $marketplace_id), 200); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_delete_marketplace', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $marketplace_id = isset($_POST['marketplace_id']) ? intval(wp_unslash($_POST['marketplace_id'])) : null; if (empty($marketplace_id)) { throw new Exception(__('No marketplace id provided (marketplace_id)', 'affililabs')); } $was_deleted = AFFLMarketplaceService::delete($marketplace_id); if ($was_deleted) { wp_send_json_success(array('status' => 'ok', 'message' => 'Marketplace deleted successfully!', 'marketplace_id' => $marketplace_id), 200); } else { wp_send_json_error(array('status' => 'error', 'message' => 'There was an error deleting the marketplace. Please try again.'), 500); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_create_supported_marketplace', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $marketplace_type = sanitize_text_field(wp_unslash($_POST['marketplace_type'] ?? '')); if (empty($marketplace_type)) { throw new Exception(__('Marketplace type is required.', 'affililabs')); } affl_import(AFFILILABS_SERVICE_MARKETPLACES); if (!class_exists('AFFLMarketplaceService')) { throw new Exception(__('Marketplace service not available.', 'affililabs')); } $result = AFFLMarketplaceService::create_default_marketplace($marketplace_type); AFFL_LoggerService::debug('AJAX Controller - Result from create_default_marketplace: Type: ' . esc_html(gettype($result)) . ', Value: ' . esc_html(print_r($result, true)), 'DEBUG'); if (is_wp_error($result)) { wp_send_json_error(array('status' => 'error', 'message' => $result->get_error_message()), 500); } else if ( is_int($result) ) { wp_send_json_success(array('status' => 'ok', 'message' => __('Marketplace created successfully!', 'affililabs'), 'marketplace_id' => $result), 201); } else { wp_send_json_error(array('status' => 'error', 'message' => __('Failed to create marketplace.', 'affililabs')), 500); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_fill_product_data', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $product_data = map_deep(json_decode(wp_unslash($_POST['product_data'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); if (empty($product_data)) { throw new Exception(__('No product data provided', 'affililabs')); } $product_response = AFFLProductService::fill_data($product_data); if (!$product_response) { throw new Exception(__('Product not found', 'affililabs')); } if (isset($product_response['status']) && $product_response['status'] !== 'ok') { throw new Exception($product_response['message'] ?? __('Product data could not be filled.', 'affililabs')); } wp_send_json_success(array('status' => 'ok', 'product_response' => $product_response), 200); } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_fill_product_criteria', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $product_data = map_deep(json_decode(wp_unslash($_POST['product_data'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); if (empty($product_data)) { throw new Exception(__('No product data provided', 'affililabs')); } $product_response = AFFLProductService::fill_criteria($product_data); if (!$product_response) { throw new Exception(__('Product criteria could not be filled.', 'affililabs')); } if (isset($product_response['status']) && $product_response['status'] !== 'ok') { throw new Exception($product_response['message'] ?? __('Product criteria could not be filled.', 'affililabs')); } wp_send_json_success(array('status' => 'ok', 'product_response' => $product_response), 200); } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_rate_product_with_ai', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $product_data = map_deep(json_decode(wp_unslash($_POST['product_data'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); if (empty($product_data)) { throw new Exception(__('No product data provided', 'affililabs')); } $product_response = AFFLProductService::web_rate_product($product_data); if (!$product_response) { throw new Exception(__('The product rating could not be estimated.', 'affililabs')); } if ($product_response['status'] !== 'ok') { throw new Exception($product_response['message'] ?? __('The product rating could not be estimated.', 'affililabs')); } wp_send_json_success(array('status' => 'ok', 'product_rating_response' => $product_response), 200); } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_deep_review_product_with_ai', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $product_data = map_deep(json_decode(wp_unslash($_POST['product_data'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); if (empty($product_data)) { throw new Exception(__('No product data provided', 'affililabs')); } $review_content = AFFLProductService::deep_review_product($product_data); if (!$review_content) { throw new Exception(__('The product review could not be generated.', 'affililabs')); } if (isset($review_content['status']) && $review_content['status'] !== 'ok') { throw new Exception($review_content['message'] ?? __('The product review could not be generated.', 'affililabs')); } wp_send_json_success(array('status' => 'ok', 'review_content' => $review_content), 200); } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_save_criterion', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions', 'affililabs')); } $data = map_deep(json_decode(wp_unslash($_POST['criterion_data'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); AFFL_LoggerService::debug('Sanitized Criterion data: ' . esc_html(json_encode($data)), 'DEBUG'); if (empty($data)) { throw new Exception(__('No data provided', 'affililabs')); } $criterion_data = array(); $criterion_data['id'] = $data['id'] ?? null; $criterion_data['title'] = $data['title'] ?? ''; $criterion_data['description'] = $data['description'] ?? ''; $criterion_data['fields'] = $data['fields'] ?? array(); $criterion_data['linked_products'] = $data['linked_products'] ?? array(); $criterion_data['linked_categories'] = $data['linked_categories'] ?? array(); $criterion_data['linked_product_lists'] = $data['linked_product_lists'] ?? array(); if (empty($criterion_data['title'])) { throw new Exception(__('Criterion title is required', 'affililabs')); } $criterion_id = AFFLCriteriaService::save($criterion_data); wp_send_json_success([ 'status' => 'ok', 'message' => __('Criterion saved successfully', 'affililabs'),'criterion_id' => $criterion_id, 200 ]); } catch (Exception $e) { wp_send_json_error([ 'status' => 'error', 'message' => $e->getMessage(), ]); } }); add_action('wp_ajax_affililabs_delete_criterion', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $criterion_id = isset($_POST['criterion_id']) ? intval(wp_unslash($_POST['criterion_id'])) : null; if (empty($criterion_id)) { throw new Exception(__('No criterion id provided', 'affililabs')); } $was_deleted = AFFLCriteriaService::delete($criterion_id); if ($was_deleted) { wp_send_json_success(array('status' => 'ok', 'message' => 'Criterion deleted successfully!', 'criterion_id' => $criterion_id), 200); } else { wp_send_json_error(array('status' => 'error', 'message' => 'There was an error deleting the criterion. Please try again.'), 500); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_get_criterion_fields', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions', 'affililabs')); } $criterion_id = isset($_POST['criterion_id']) ? intval($_POST['criterion_id']) : null; if (empty($criterion_id)) { throw new Exception(__('Criterion ID is required', 'affililabs')); } affl_import(AFFILILABS_SERVICE_CRITERIA_FILE); if (!class_exists('AFFLCriteriaService')) { throw new Exception(__('Criteria service not available.', 'affililabs')); } $criterion_fields = AFFLCriteriaService::get_criterion_fields($criterion_id); wp_send_json_success([ 'status' => 'ok', 'fields' => $criterion_fields, 'message' => __('Fields fetched successfully', 'affililabs'), ]); } catch (Exception $e) { wp_send_json_error([ 'status' => 'error', 'message' => $e->getMessage(), ]); } }); add_action('wp_ajax_affililabs_get_criteria_by_category', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions', 'affililabs')); } $category_slug = isset($_POST['category_slug']) ? sanitize_text_field(wp_unslash($_POST['category_slug'])) : ''; if (empty($category_slug)) { wp_send_json_success(['status' => 'ok', 'criteria' => []]); return; } affl_import(AFFILILABS_SERVICE_CRITERIA_FILE); if (!class_exists('AFFLCriteriaService')) { throw new Exception(__('Criteria service not available.', 'affililabs')); } $term = get_term_by('slug', $category_slug, AFFILILABS_TAXONOMY_PRODUCT_CATEGORY); if (!$term) { throw new Exception(__('Category not found.', 'affililabs')); } $criteria = AFFLCriteriaService::get_criterions_by_categories([$term->term_id]); wp_send_json_success([ 'status' => 'ok', 'criteria' => $criteria, 'message' => __('Criteria fetched successfully', 'affililabs'), ]); } catch (Exception $e) { wp_send_json_error([ 'status' => 'error', 'message' => $e->getMessage(), ]); } }); add_action('wp_ajax_affililabs_ai_suggest_criteria', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions', 'affililabs')); } $list_id = isset($_POST['list_id']) ? intval($_POST['list_id']) : null; $product_ids = isset($_POST['product_ids']) && is_array($_POST['product_ids']) ? array_map('intval', $_POST['product_ids']) : []; $ai_language = AFFLSettingsService::get_ai_language(); if (empty($list_id)) { throw new Exception(__('List ID is required for AI criteria suggestions.', 'affililabs')); } if (empty($product_ids)) { throw new Exception(__('No products selected for AI criteria suggestions.', 'affililabs')); } if (empty($ai_language)) { throw new Exception(__('AI language setting is missing. Please configure it in settings.', 'affililabs')); } affl_import(AFFILILABS_SERVICE_CRITERIA_FILE); if (!class_exists('AFFLCriteriaService')) { throw new Exception(__('Criteria service not available.', 'affililabs')); } $suggestions_response = AFFLCriteriaService::get_ai_suggested_criteria($list_id, $product_ids, $ai_language); if ($suggestions_response['status'] === 'ok') { wp_send_json_success([ 'status' => 'ok', 'suggestions' => $suggestions_response['suggestions'], 'message' => $suggestions_response['message'] ?? __('AI criteria suggestions fetched successfully', 'affililabs'), ]); } else { wp_send_json_error([ 'status' => 'error', 'message' => $suggestions_response['message'] ?? __('Failed to get AI criteria suggestions.', 'affililabs'), ]); } } catch (Exception $e) { wp_send_json_error([ 'status' => 'error', 'message' => $e->getMessage(), ]); } }); add_action('wp_ajax_affililabs_ai_suggest_criteria_for_category', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions', 'affililabs')); } $category_id = isset($_POST['category_id']) ? intval($_POST['category_id']) : null; $ai_language = AFFLSettingsService::get_ai_language(); if (empty($category_id)) { throw new Exception(__('Category ID is required for AI criteria suggestions.', 'affililabs')); } if (empty($ai_language)) { throw new Exception(__('AI language setting is missing. Please configure it in settings.', 'affililabs')); } affl_import(AFFILILABS_SERVICE_CRITERIA_FILE); $suggestions_response = AFFLCriteriaService::get_ai_suggested_criteria_for_category($category_id, $ai_language); if ($suggestions_response['status'] === 'ok') { wp_send_json_success([ 'status' => 'ok', 'suggestions' => $suggestions_response['suggestions'], ]); } else { wp_send_json_error([ 'status' => 'error', 'message' => $suggestions_response['message'] ?? __('Failed to get AI criteria suggestions.', 'affililabs'), ]); } } catch (Exception $e) { wp_send_json_error(['status' => 'error', 'message' => $e->getMessage()]); } }); add_action('wp_ajax_affililabs_save_ai_suggested_criteria_for_category', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions', 'affililabs')); } $category_id = isset($_POST['category_id']) ? intval($_POST['category_id']) : 0; $suggested_criterion = map_deep(json_decode(wp_unslash($_POST['suggested_criterion'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); affl_import(AFFILILABS_SERVICE_CRITERIA_FILE); $save_response = AFFLCriteriaService::create_or_update_criterion_from_suggestion_for_category($category_id, $suggested_criterion); wp_send_json_success($save_response); } catch (Exception $e) { wp_send_json_error(['status' => 'error', 'message' => $e->getMessage()]); } }); add_action('wp_ajax_affililabs_save_ai_suggested_criteria', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions', 'affililabs')); } $list_id = isset($_POST['list_id']) ? intval($_POST['list_id']) : null; $suggested_criterion = map_deep(json_decode(wp_unslash($_POST['suggested_criterion'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); if (empty($list_id) || empty($suggested_criterion)) { throw new Exception(__('List ID and suggested criterion data are required.', 'affililabs')); } affl_import(AFFILILABS_SERVICE_CRITERIA_FILE); if (!class_exists('AFFLCriteriaService')) { throw new Exception(__('Criteria service not available.', 'affililabs')); } $save_response = AFFLCriteriaService::create_or_update_criterion_from_suggestion($list_id, $suggested_criterion); if ($save_response['status'] === 'ok') { wp_send_json_success([ 'status' => 'ok', 'criterion_id' => $save_response['criterion_id'], 'message' => $save_response['message'] ?? __('Suggested criterion saved successfully', 'affililabs'), ]); } else { wp_send_json_error([ 'status' => 'error', 'message' => $save_response['message'] ?? __('Failed to save AI suggested criterion.', 'affililabs'), ]); } } catch (Exception $e) { wp_send_json_error([ 'status' => 'error', 'message' => $e->getMessage(), ]); } }); add_action('wp_ajax_affililabs_suggest_lists', 'affililabs_handle_suggest_lists'); function affililabs_handle_suggest_lists() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $products = get_posts(array( 'post_type' => AFFILILABS_CPT_PRODUCT, 'posts_per_page' => -1, 'post_status' => 'any', )); $product_data = array_map(function(WP_Post $product) { return array( 'id' => $product->ID, 'name' => $product->post_title, 'price' => get_post_meta($product->ID, AFFILILABS_META_KEY_PRICE, true), 'category' => get_the_terms($product->ID, AFFILILABS_TAXONOMY_PRODUCT_CATEGORY)[0]->slug ?? null, 'description' => $product->post_content, 'short_features' => get_post_meta($product->ID, AFFILILABS_META_KEY_SHORT_FEATURES, true), ); }, $products); affl_import(AFFILILABS_COMPARISON_TABLE_SERVICE_FILE); $all_lists = AFFLComparisonTableService::get_all(); $ai_language = AFFLSettingsService::get_ai_language(); if (empty($ai_language)) { wp_send_json_error(array('status' => 'error', 'message' => __('AI language setting is missing. Please configure it in settings.', 'affililabs')), 500); } $product_data_for_ai = array( 'all_products' => $product_data, 'all_lists' => $all_lists, 'language' => $ai_language, ); $ai_response_data = AFFLComparisonTableService::suggest_lists($product_data_for_ai); if (isset($ai_response_data['status']) && $ai_response_data['status'] !== 'ok') { throw new Exception($ai_response_data['message'] ?? __('Lists could not be suggested.', 'affililabs')); } $suggested_lists = $ai_response_data['lists_response'] ?? []; if (empty($suggested_lists)) { wp_send_json_error(array('status' => 'error', 'message' => 'No lists could be suggested.'), 500); } $product_id_to_name = array(); foreach ($product_data as $product) { $product_id_to_name[(string) $product['id']] = esc_html($product['name']); } wp_send_json_success(array( 'status' => 'ok', 'lists_response' => $suggested_lists, 'product_id_to_name' => $product_id_to_name, 'product_data_for_ai' => $product_data_for_ai ), 200); } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage(), 'data' => $e->getMessage()), 500); } } add_action('wp_ajax_affililabs_delete_comparison_table', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } $comparison_table_id = isset($_POST['comparison_table_id']) ? intval(wp_unslash($_POST['comparison_table_id'])) : null; if (empty($comparison_table_id)) { throw new Exception(__('No List ID provided (comparison_table_id)', 'affililabs')); } $post = get_post($comparison_table_id); if (!$post || $post->post_type !== AFFILILABS_CPT_COMPARISON_TABLE) { throw new Exception(__('Invalid List ID', 'affililabs')); } $was_deleted = wp_delete_post($comparison_table_id, true); if ($was_deleted) { wp_send_json_success(array('status' => 'ok', 'message' => 'List deleted successfully!', 'comparison_table_id' => $comparison_table_id), 200); } else { wp_send_json_error(array('status' => 'error', 'message' => 'There was an error deleting the list. Please try again.'), 500); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_save_comparison_table', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions', 'affililabs')); } $data = map_deep(json_decode(wp_unslash($_POST['comparison_table_data'] ?? ''), true) ?: [], function($val) { return wp_kses($val, affl_get_allowed_html_tags()); }); //@TODO: Or sanitize text field AFFL_LoggerService::debug('AJAX Save Comparison Table - Sanitized data: ' . esc_html(print_r($data, true)), 'DEBUG'); AFFL_LoggerService::debug('AJAX Save Comparison Table - Received ID: ' . esc_html($data['id'] ?? 'null'), 'DEBUG'); if (empty($data)) { throw new Exception(__('No data provided', 'affililabs')); } $comparison_table_data = array(); $comparison_table_data['id'] = $data['id'] ?? null; $comparison_table_data['title'] = $data['title'] ?? ''; $comparison_table_data['list_description'] = $data['list_description'] ?? ''; $comparison_table_data['product_ids'] = isset($data['product_ids']) && is_array($data['product_ids']) ? array_map('intval', $data['product_ids']) : []; $comparison_table_data['criteria_ids'] = isset($data['criteria_ids']) && is_array($data['criteria_ids']) ? array_map('intval', $data['criteria_ids']) : []; $comparison_table_data['applied_template_id'] = isset($data['applied_template_id']) ? intval($data['applied_template_id']) : null; $comparison_table_data['tier_best_price'] = isset($data['tier_best_price']) ? intval($data['tier_best_price']) : null; $comparison_table_data['tier_best_quality'] = isset($data['tier_best_quality']) ? intval($data['tier_best_quality']) : null; $comparison_table_data['tier_best_cost_benefit'] = isset($data['tier_best_cost_benefit']) ? intval($data['tier_best_cost_benefit']) : null; if (empty($comparison_table_data['title'])) { throw new Exception(__('List title is required', 'affililabs')); } AFFL_LoggerService::debug('AJAX Save Comparison Table - ID before status_code check: ' . esc_html($comparison_table_data['id'] ?? 'null'), 'DEBUG'); $status_code = $comparison_table_data['id'] ? 200 : 201; affl_import(AFFILILABS_COMPARISON_TABLE_SERVICE_FILE); $comparison_table_id = AFFLComparisonTableService::save($comparison_table_data); $saved_list_post = get_post($comparison_table_id); $product_count = 0; if ($saved_list_post) { $list_products = get_post_meta($comparison_table_id, AFFILILABS_META_KEY_COMPARISON_TABLE_PRODUCTS, true); $product_count = is_array($list_products) ? count($list_products) : 0; } AFFL_LoggerService::debug('AJAX Save Comparison Table - status_code before send_json_success: ' . esc_html($status_code), 'DEBUG'); wp_send_json_success([ 'status' => 'ok', 'message' => __('List saved successfully', 'affililabs'), 'comparison_table_id' => $comparison_table_id, 'list_data' => [ 'id' => $comparison_table_id, 'title' => $saved_list_post ? $saved_list_post->post_title : '', 'list_description' => $saved_list_post ? $saved_list_post->post_content : '', 'product_count' => $product_count, 'status' => $saved_list_post ? $saved_list_post->post_status : 'publish', 'edit_url' => wp_nonce_url(admin_url('admin.php?page=affililabs-list-edit&list_id=' . $comparison_table_id), 'affl_admin_nonce', 'nonce'), ], 'status_code' => $status_code ], $status_code); } catch (Exception $e) { wp_send_json_error([ 'status' => 'error', 'message' => $e->getMessage(), ]); } }); add_action('wp_ajax_affililabs_import_products', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions', 'affililabs')); } $import_type = isset($_POST['import_type']) ? sanitize_text_field(wp_unslash($_POST['import_type'])) : ''; $import_id = isset($_POST['import_id']) ? intval($_POST['import_id']) : 0; if (empty($import_type) || empty($import_id)) { throw new Exception(__('Import type and ID are required', 'affililabs')); } affl_import(AFFILILABS_COMPARISON_TABLE_SERVICE_FILE); $product_ids = []; switch ($import_type) { case 'category': $product_ids = AFFLComparisonTableService::import_products_from_category($import_id); break; case 'tag': $product_ids = AFFLComparisonTableService::import_products_from_tag($import_id); break; default: throw new Exception(__('Invalid import type', 'affililabs')); } wp_send_json_success([ 'status' => 'ok', 'message' => __('Products imported successfully', 'affililabs'), 'product_ids' => $product_ids, 200 ]); } catch (Exception $e) { wp_send_json_error([ 'status' => 'error', 'message' => $e->getMessage(), 'data' => [ 'error_code' => $e->getCode(), 'error_details' => $e->getTraceAsString() ] ]); } }); add_action('wp_ajax_affililabs_save_template', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to save templates', 'affililabs')); } if (!isset($_POST['template_data']) || !is_array($_POST['template_data'])) { throw new Exception(__('Invalid template data', 'affililabs')); } $template_data = map_deep(wp_unslash($_POST['template_data'] ?? []), 'sanitize_text_field'); $template_id = !empty($template_data['id']) ? intval($template_data['id']) : null; $template_name = sanitize_text_field($template_data['name'] ?? 'Untitled Template'); $template_type = sanitize_text_field($template_data['type'] ?? 'comparison_table'); $template_modules = isset($template_data['modules']) ? map_deep($template_data['modules'], 'sanitize_text_field') : []; $applied_table_ids = isset($template_data['applied_table_ids']) && is_array($template_data['applied_table_ids']) ? array_map('intval', $template_data['applied_table_ids']) : []; if (empty($template_name)) { throw new Exception(__('Template name is required', 'affililabs')); } $template_post = [ 'post_title' => $template_name, 'post_type' => 'affl_template', 'post_status' => 'publish', 'meta_input' => [ '_affl_template_type' => $template_type, '_affl_template_data' => $template_modules, '_affl_applied_table_ids' => $applied_table_ids, ], ]; if ($template_id) { $template_post['ID'] = $template_id; $result = wp_update_post($template_post); } else { $result = wp_insert_post($template_post); } if (is_wp_error($result)) { throw new Exception($result->get_error_message()); } else { if (is_array($applied_table_ids)) { foreach ($applied_table_ids as $table_id) { update_post_meta($table_id, AFFILILABS_META_KEY_COMPARISON_TABLE_APPLIED_TEMPLATE_ID, $template_id); } } else if (!empty($applied_table_ids)) { $applied_table_ids_array = explode(',', $applied_table_ids); foreach ($applied_table_ids_array as $table_id) { update_post_meta($table_id, AFFILILABS_META_KEY_COMPARISON_TABLE_APPLIED_TEMPLATE_ID, $template_id); } } wp_send_json_success([ 'status' => 'ok', 'template_id' => $result, 'message' => 'Template saved successfully' ]); } } catch (Exception $e) { wp_send_json_error(['status' => 'error', 'message' => $e->getMessage()]); } }); add_action('wp_ajax_affililabs_get_template', function() { try{ if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to get templates', 'affililabs')); } if (!isset($_POST['template_id']) || !intval($_POST['template_id'])) { throw new Exception(__('Invalid template ID', 'affililabs')); } $template_id = intval($_POST['template_id']); $template = get_post($template_id); if (!$template || $template->post_type !== 'affl_template') { throw new Exception( 'Template not found'); } $template_type = get_post_meta($template_id, AFFILILABS_META_KEY_TEMPLATE_TYPE, true); $template_rows = get_post_meta($template_id, AFFILILABS_META_KEY_TEMPLATE_DATA, true); wp_send_json_success([ 'status' => 'ok', 'id' => $template_id, 'title' => $template->post_title, 'type' => $template_type, 'rows' => $template_rows, 'last_updated' => $template->post_modified ]); } catch (Exception $e) { wp_send_json_error(['status' => 'error', 'message' => $e->getMessage()]); } }); add_action('wp_ajax_affililabs_delete_template', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to delete templates', 'affililabs')); } if (!isset($_POST['template_id']) || !intval($_POST['template_id'])) { throw new Exception(__('Invalid template ID', 'affililabs')); } $template_id = intval($_POST['template_id']); $template = get_post($template_id); if (!$template || $template->post_type !== 'affl_template') { throw new Exception(__('Template not found', 'affililabs')); } $result = wp_delete_post($template_id, true); if (!$result) { throw new Exception(__('Failed to delete template', 'affililabs')); } else { wp_send_json_success(['status' => 'ok', 'message' => 'Template deleted successfully']); } } catch (Exception $e) { wp_send_json_error(['status' => 'error', 'message' => $e->getMessage()]); } }); add_action('wp_ajax_affl_render_single_product_preview', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('edit_posts')) { throw new Exception(__('You do not have permission to preview products', 'affililabs')); } $product_id = isset($_POST['product_id']) ? intval($_POST['product_id']) : 0; AFFL_LoggerService::debug('AJAX Single Product Preview - Received product_id: ' . esc_html($product_id), 'DEBUG'); if ($product_id === 0) { throw new Exception(__('Invalid Product ID provided', 'affililabs')); } $current_template_modules = isset($_POST['template_modules']) && is_array($_POST['template_modules']) ? array_map('sanitize_text_field', wp_unslash($_POST['template_modules'])) : []; $template_id = isset($_POST['template_id']) ? intval($_POST['template_id']) : 0; $html = ''; foreach ($current_template_modules as $module) { $shortcode = '[affl_' . $module . ' id="' . $product_id . '"]'; $html .= do_shortcode($shortcode); } wp_send_json_success(['status' => 'ok', 'html' => $html]); } catch (Exception $e) { wp_send_json_error(['status' => 'error', 'message' => $e->getMessage()]); } }); add_action('wp_ajax_affl_render_table_preview', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('edit_posts')) { throw new Exception(__('You do not have permission to preview tables', 'affililabs')); } $table_id = isset($_POST['table_id']) ? intval($_POST['table_id']) : 0; if ($table_id <= 1) { throw new Exception(__('Invalid Table ID provided', 'affililabs')); } $current_template_modules = isset($_POST['template_modules']) && is_array($_POST['template_modules']) ? array_map('sanitize_text_field', wp_unslash($_POST['template_modules'])) : null; affl_import(AFFILILABS_COMPARISON_TABLE_SHORTCODE_PATH); if (!class_exists('AFFLComparisonTableShortcode')) { throw new Exception(__('Comparison table rendering component not found.', 'affililabs')); } $shortcode_renderer = new AFFLComparisonTableShortcode(); $shortcode_atts = ['id' => $table_id]; if ($current_template_modules !== null) { $shortcode_atts['live_template_modules'] = $current_template_modules; } $html = $shortcode_renderer->render_shortcode($shortcode_atts); wp_send_json_success(['status' => 'ok', 'html' => $html]); } catch (Exception $e) { wp_send_json_error(['status' => 'error', 'message' => $e->getMessage()]); } }); add_action('wp_ajax_affl_find_products', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to perform this action.', 'affililabs')); } $keyword = isset($_POST['keyword']) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : ''; $marketplace_id = isset($_POST['marketplace_id']) ? intval($_POST['marketplace_id']) : 0; if (empty($marketplace_id) || $marketplace_id <= 1) { throw new Exception(__('Invalid or missing marketplace selected.', 'affililabs')); } $finder = null; $digistore_option_id = get_option(AFFILILABS_DIGISTORE_MARKETPLACE_ID, null); if ($marketplace_id == $digistore_option_id) { affl_import(AFFILILABS_SERVICE_PRODUCT_FINDER_DIGISTORE_FILE); $finder = new AFFLDigistoreProductFinder(); } else { throw new Exception(__('Selected marketplace is not supported for product finding yet.', 'affililabs')); } if (!$finder) { throw new Exception(__('Could not initialize product finder for the selected marketplace.', 'affililabs')); } $currency = isset($_POST['currency']) ? sanitize_text_field(wp_unslash($_POST['currency'])) : ''; $language = isset($_POST['language']) && is_array($_POST['language']) ? array_map('sanitize_key', $_POST['language']) : []; $marketplace_category_id = isset($_POST['marketplace_category_id']) && is_array($_POST['marketplace_category_id']) ? array_map('intval', $_POST['marketplace_category_id']) : []; $sort = isset($_POST['sort']) ? sanitize_text_field(wp_unslash($_POST['sort'])) : ''; $filters = []; if (!empty($currency)) $filters['currency'] = $currency; if (!empty($language)) $filters['language'] = $language; if (!empty($marketplace_category_id)) $filters['marketplace_category_id'] = $marketplace_category_id; if (!empty($sort)) $filters['sort'] = $sort; $products = $finder->find_products($keyword, $filters); wp_send_json_success(array( 'status' => 'ok', 'products' => $products)); } catch (Exception $e) { wp_send_json_error(array('status' => 'error','message' => $e->getMessage())); } }); add_action('wp_ajax_affl_save_internal_api_key', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to save settings.', 'affililabs')); } $api_key = isset($_POST['api_key']) ? sanitize_text_field(wp_unslash($_POST['api_key'])) : ''; $saved = AFFLSettingsService::save_internal_api_key($api_key); if ($saved) { $current_api_key = AFFLSettingsService::get_internal_api_key(); $obfuscated_api_key = ''; $last_five = ''; if (!empty($current_api_key)) { $len = strlen($current_api_key); $obfuscated_api_key = str_repeat('*', max(0, $len - 5)) . substr($current_api_key, -5); $last_five = substr($current_api_key, -5); } $response_data = [ 'status' => 'ok', 'message' => __('API Key saved successfully.', 'affililabs'), 'obfuscated_key' => $obfuscated_api_key, 'last_five' => $last_five ]; wp_send_json_success($response_data); } else { throw new Exception(__('Failed to save the API Key. Please check logs.', 'affililabs')); } } catch (Exception $e) { $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affl_delete_internal_api_key', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred while deleting the key.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to delete settings.', 'affililabs')); } $deleted = AFFLSettingsService::delete_internal_api_key(); if ($deleted) { $response_data = ['status' => 'ok', 'message' => __('API Key deleted successfully.', 'affililabs')]; wp_send_json_success($response_data); } else { throw new Exception(__('Failed to delete the API Key option. It might not exist.', 'affililabs')); } } catch (Exception $e) { $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affl_save_debug_mode', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to save settings.', 'affililabs')); } $enable_debug = isset($_POST['enable_debug']) ? intval($_POST['enable_debug']) : 0; $saved = AFFLSettingsService::save_debug_mode($enable_debug); if ($saved) { $response_data = [ 'status' => 'ok', 'message' => __('Debug settings saved successfully.', 'affililabs'), ]; wp_send_json_success($response_data); } else { throw new Exception(__('Failed to save debug settings. Please check logs.', 'affililabs')); } } catch (Exception $e) { $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affl_save_product_slug', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred while saving the product slug.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to save settings.', 'affililabs')); } $product_slug = isset($_POST['product_slug']) ? sanitize_text_field(wp_unslash($_POST['product_slug'])) : ''; $sanitized_slug = sanitize_title($product_slug); if (empty($sanitized_slug)) { throw new Exception(__('Product slug cannot be empty. Please enter a valid slug.', 'affililabs')); } if (post_type_exists($sanitized_slug) && $sanitized_slug !== get_option(AFFILILABS_PRODUCT_SLUG_OPTION, AFFILILABS_CPT_PRODUCT)) { /* translators: %s: post type slug */ throw new Exception(sprintf(__('The slug "%s" conflicts with an existing post type.', 'affililabs'), $sanitized_slug)); } if (taxonomy_exists($sanitized_slug)) { /* translators: %s: taxonomy slug */ throw new Exception(sprintf(__('The slug "%s" conflicts with an existing taxonomy.', 'affililabs'), $sanitized_slug)); } if (get_page_by_path($sanitized_slug)) { /* translators: %s: page or post slug */ throw new Exception(sprintf(__('The slug "%s" conflicts with an existing page or post.', 'affililabs'), $sanitized_slug)); } if (in_array($sanitized_slug, array('attachment', 'attachment_id', 'author', 'author_name', 'calendar', 'cat', 'category', 'category_name', 'comments_per_page', 'comments_popup', 'cpage', 'day', 'debug', 'error', 'exact', 'feed', 'hour', 'link_category', 'm', 'minute', 'monthnum', 'more', 'name', 'nav_menu', 'nonce', 'nopaging', 'offset', 'order', 'orderby', 'p', 'page', 'page_id', 'paged', 'pagename', 'pb', 'perm', 'post', 'post_format', 'post_mime_type', 'post_type', 'posts', 'posts_per_archive_page', 'posts_per_page', 'preview', 'robots', 's', 'search', 'second', 'sentence', 'showposts', 'static', 'subpost', 'subpost_id', 'tag', 'tag__and', 'tag__in', 'tag__not_in', 'tag_id', 'tag_slug__and', 'tag_slug__in', 'taxonomy', 'tb', 'term', 'type', 'w', 'withcomments', 'withoutcomments', 'year'))) { /* translators: %s: reserved term */ throw new Exception(sprintf(__('The slug "%s" is a WordPress reserved term and cannot be used.', 'affililabs'), $sanitized_slug)); } $hide_product_slug = isset($_POST['hide_product_slug']) ? intval($_POST['hide_product_slug']) : 0; update_option(AFFILILABS_PRODUCT_SLUG_OPTION, $sanitized_slug, 'no'); wp_cache_delete(AFFILILABS_PRODUCT_SLUG_OPTION, 'options'); update_option(AFFILILABS_HIDE_PRODUCT_SLUG_OPTION, $hide_product_slug, 'no'); wp_cache_delete(AFFILILABS_HIDE_PRODUCT_SLUG_OPTION, 'options'); flush_rewrite_rules(); $response_data = [ 'status' => 'ok', 'message' => __('Product slug saved successfully. Please re-save your permalinks in WordPress settings if changes are not immediately visible.', 'affililabs'), ]; wp_send_json_success($response_data); } catch (Exception $e) { $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affl_save_ai_language', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred while saving AI language settings.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to save settings.', 'affililabs')); } $ai_language = isset($_POST['ai_language']) ? sanitize_text_field(wp_unslash($_POST['ai_language'])) : ''; if (empty($ai_language)) { throw new Exception(__('AI language cannot be empty.', 'affililabs')); } $saved = AFFLSettingsService::save_ai_language($ai_language); if ($saved) { $response_data = [ 'status' => 'ok', 'message' => __('AI language settings saved successfully.', 'affililabs'), ]; wp_send_json_success($response_data); } else { throw new Exception(__('Failed to save AI language settings. Please check logs.', 'affililabs')); } } catch (Exception $e) { $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affl_save_list_separator', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred while saving list separator settings.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to save settings.', 'affililabs')); } $list_separator = isset($_POST['list_separator']) ? sanitize_text_field(wp_unslash($_POST['list_separator'])) : ''; if (empty($list_separator)) { throw new Exception(__('List separator cannot be empty.', 'affililabs')); } $saved = AFFLSettingsService::save_list_separator($list_separator); if ($saved) { $response_data = [ 'status' => 'ok', 'message' => __('List separator saved successfully.', 'affililabs'), ]; wp_send_json_success($response_data); } else { throw new Exception(__('Failed to save list separator settings. Please check logs.', 'affililabs')); } } catch (Exception $e) { $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affl_save_enable_all_categories_page', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred while saving the setting.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to save settings.', 'affililabs')); } $enable_all_categories_page = isset($_POST['enable_all_categories_page']) ? intval($_POST['enable_all_categories_page']) : 0; $saved = AFFLSettingsService::save_enable_all_categories_page($enable_all_categories_page); if ($saved) { $response_data = [ 'status' => 'ok', 'message' => __('Archive page settings saved successfully.', 'affililabs'), ]; wp_send_json_success($response_data); } else { throw new Exception(__('Failed to save archive page settings. Please check logs.', 'affililabs')); } } catch (Exception $e) { $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affl_save_enable_op_global_elements', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred while saving Optimizepress elements settings.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to save settings.', 'affililabs')); } $enable_op_global_elements = isset($_POST['enable_op_global_elements']) ? intval($_POST['enable_op_global_elements']) : 0; $saved = AFFLSettingsService::save_enable_op_global_elements($enable_op_global_elements); if ($saved) { $response_data = [ 'status' => 'ok', 'message' => __('Optimizepress elements settings saved successfully.', 'affililabs'), ]; wp_send_json_success($response_data); } else { throw new Exception(__('Failed to save Optimizepress elements settings. Please check logs.', 'affililabs')); } } catch (Exception $e) { $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affililabs_add_product_category_with_criteria', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $name = isset($_POST['name']) ? sanitize_text_field(wp_unslash($_POST['name'])) : ''; $slug = isset($_POST['slug']) ? sanitize_text_field(wp_unslash($_POST['slug'])) : ''; $description = isset($_POST['description']) ? sanitize_textarea_field(wp_unslash($_POST['description'])) : ''; if (empty($name) || empty($slug)) { throw new Exception(__('Category name and slug are required.', 'affililabs')); } $term = wp_insert_term($name, AFFILILABS_TAXONOMY_PRODUCT_CATEGORY, array( 'slug' => $slug, 'description' => $description, )); if (is_wp_error($term)) { throw new Exception($term->get_error_message()); } $criterion_data = array( 'title' => $name, 'description' => '', 'fields' => [], 'linked_categories' => array($term['term_id']), ); $criterion_object_id = AFFLCriteriaService::save($criterion_data); wp_send_json_success(array( 'status' => 'ok', 'message' => __('Category and criterion created successfully.', 'affililabs'), 'term_id' => $term['term_id'], 'name' => $name, 'slug' => $slug, 'criterion_object_id' => $criterion_object_id ), 201 ); } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_add_marketplace', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $name = isset($_POST['name']) ? sanitize_text_field(wp_unslash($_POST['name'])) : ''; $description = isset($_POST['description']) ? sanitize_textarea_field(wp_unslash($_POST['description'])) : ''; if (empty($name)) { throw new Exception(__('Marketplace name is required.', 'affililabs')); } $marketplace_post = array( 'post_title' => $name, 'post_content' => $description, 'post_type' => AFFILILABS_CPT_MARKETPLACE, 'post_status' => 'publish', ); $marketplace_id = wp_insert_post($marketplace_post, true); if (is_wp_error($marketplace_id)) { throw new Exception($marketplace_id->get_error_message()); } wp_send_json_success(array( 'status' => 'ok', 'message' => __('Marketplace created successfully.', 'affililabs'), 'marketplace_id' => $marketplace_id, 'name' => $name, ), 201 ); } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affl_reset_op_global_elements', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred while resetting Optimizepress elements.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to reset Optimizepress elements.', 'affililabs')); } if (!post_type_exists('op_global_element')) { throw new Exception(__('Optimizepress Global Element post type does not exist.', 'affililabs')); } $args = [ 'post_type' => 'op_global_element', 'posts_per_page' => -1, 'post_status' => 'any', 'meta_query' => [ [ 'key' => AFFILILABS_OP_GLOBAL_ELEMENT_UNIQUE_ID, 'compare' => 'EXISTS', ], ], 'fields' => 'ids', ]; $global_elements = get_posts($args); $deleted_count = 0; foreach ($global_elements as $element_id) { $deleted = wp_delete_post($element_id, true); // true for force delete if ($deleted) { $deleted_count++; } else { AFFL_LoggerService::log('Failed to delete Optimizepress Global Element with ID: ' . esc_html($element_id), 'WARNING'); } } AFFLSettingsService::save_op_global_elements_created_flag(0); AFFLSettingsService::save_enable_op_global_elements(0); // Also disable the integration $response_data = [ 'status' => 'ok', /* translators: %d: number of deleted elements */ 'message' => sprintf(__('A total of %d Optimizepress Global Elements were deleted successfully. Integration disabled.', 'affililabs'), $deleted_count), ]; wp_send_json_success($response_data); } catch (Throwable $e) { AFFL_LoggerService::log('Error resetting Optimizepress Global Elements: ' . esc_html($e->getMessage()) . ' Stack: ' . esc_html($e->getTraceAsString()), 'ERROR'); $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affl_save_enable_custom_template', function() { $response_data = ['status' => 'error', 'message' => __('An unknown error occurred while saving the setting.', 'affililabs')]; try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have permission to save settings.', 'affililabs')); } $enable_custom_template = isset($_POST['enable_custom_template']) ? intval($_POST['enable_custom_template']) : 0; $saved = AFFLSettingsService::save_enable_custom_template($enable_custom_template); if ($saved) { $response_data = [ 'status' => 'ok', 'message' => __('Template settings saved successfully.', 'affililabs'), ]; wp_send_json_success($response_data); } else { throw new Exception(__('Failed to save template settings. Please check logs.', 'affililabs')); } } catch (Exception $e) { $response_data['message'] = $e->getMessage(); wp_send_json_error($response_data); } }); add_action('wp_ajax_affililabs_get_user_quota', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } affl_import(AFFILILABS_SERVICE_USER_FILE); if (!class_exists('AFFLUserService')) { throw new Exception(__('User service not available.', 'affililabs')); } $quota_data = AFFLUserService::get_user_quota(); if (isset($quota_data['status']) && $quota_data['status'] === 'ok' && isset($quota_data['data'])) { wp_send_json_success($quota_data['data']); } else { $additional_error_message = isset($quota_data['message']) ? $quota_data['message'] : ''; throw new Exception(__('Failed to retrieve user quota.', 'affililabs') . ' ' . $additional_error_message); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } }); add_action('wp_ajax_affililabs_save_cleanup_on_uninstall', function() { try { if (!check_ajax_referer('affl_admin_nonce', 'nonce', false)) { throw new Exception(__('Security check failed.', 'affililabs')); } if (!current_user_can('manage_options')) { throw new Exception(__('You do not have sufficient permissions.', 'affililabs')); } $cleanup_on_uninstall = isset($_POST['cleanup_on_uninstall']) ? intval($_POST['cleanup_on_uninstall']) : 0; affl_import(AFFILILABS_SERVICE_SETTINGS_FILE); if (!class_exists('AFFLSettingsService')) { throw new Exception(__('Settings service not available.', 'affililabs')); } $result = AFFLSettingsService::save_cleanup_on_uninstall($cleanup_on_uninstall); if ($result) { wp_send_json_success(array('status' => 'ok', 'message' => __('Cleanup settings saved successfully.', 'affililabs')), 200); } else { wp_send_json_error(array('status' => 'error', 'message' => __('Failed to save cleanup settings.', 'affililabs')), 500); } } catch (Exception $e) { wp_send_json_error(array('status' => 'error', 'message' => $e->getMessage()), 500); } });