[ 'name' => 'Gemini', 'docs_url' => 'https://docs.coolplugins.net/doc/generate-gemini-api-key/?utm_source=atfp_plugin&utm_medium=inside&utm_campaign=docs&utm_content=settings_gemini_pro' ], 'openai' => [ 'name' => 'OpenAI', 'docs_url' => 'https://docs.coolplugins.net/doc/generate-open-ai-api-key/?utm_source=atfp_plugin&utm_medium=inside&utm_campaign=docs&utm_content=settings_openai_pro' ], 'deepl' => [ 'name' => 'DeepL', 'docs_url' => 'https://locoaddon.com/docs/how-to-generate-deepl-api-key/' ], 'context_aware' => [ 'name' => 'Context Aware', 'option_key' => 'atfp_context_aware', ], 'atfpp_bulk_post_status' => [ 'name' => 'Bulk Translation default Post Status', 'option_key' => 'atfp_bulk_post_status', 'options' => [ 'publish' => 'Published', 'draft' => 'Draft', ], 'value' => get_option('atfp_bulk_post_status', 'draft') ], 'atfp_slug_translation_option' => [ 'name' => 'Slug Translation Settings', 'option_key' => 'atfp_slug_translation_option', 'options' => [ 'title_translate' => 'Use Translated Title', 'slug_translate' => 'Translate Original Slug', 'slug_keep' => 'Keep Original Slug', ], 'value' => get_option('atfp_slug_translation_option', 'title_translate') ], 'atfp_ai_request_token_per_request' => [ 'name' => 'AI Token Per Request', 'option_key' => 'atfp_ai_request_token_per_request', 'value' => get_option('atfp_ai_request_token_per_request', 500) ], 'atfp_ai_request_batch_size' => [ 'name' => 'AI Batch Size', 'option_key' => 'atfp_ai_request_batch_size', 'value' => get_option('atfp_ai_request_batch_size', 5) ], 'atfp_ai_request_timeout' => [ 'name' => 'AI Timeout', 'option_key' => 'atfp_ai_request_timeout', 'value' => get_option('atfp_ai_request_timeout', 120) ] ]; ?>

' . esc_html__('license key', $text_domain) . '') ?>

$api): if ($key === 'context_aware'): ?>
$option_value): ?> disabled>
$option_value): ?> disabled>

', ''); ?>

', ''); ?>

', ''); ?>


' . esc_html__('Click Here', $text_domain) . '', esc_html($api['name']) ); endif; endforeach; ?>

Rate Limits of Free Gemini API Key

[ 'name' => 'Gemini', 'option_key' => 'Atfpp_Ai_Translate_google_api_key', 'docs_url' => 'https://docs.coolplugins.net/doc/generate-gemini-api-key/?utm_source=atfp_plugin&utm_medium=inside&utm_campaign=docs&utm_content=settings_gemini_pro', 'value' => get_option('Atfpp_Ai_Translate_google_api_key', '') ], 'openai' => [ 'name' => 'OpenAI', 'option_key' => 'Atfpp_Ai_Translate_openai_api_key', 'docs_url' => 'https://docs.coolplugins.net/doc/generate-open-ai-api-key/?utm_source=atfp_plugin&utm_medium=inside&utm_campaign=docs&utm_content=settings_openai_pro', 'value' => get_option('Atfpp_Ai_Translate_openai_api_key', '') ], // 'openrouter' => [ // 'name' => 'Openrouter', // 'option_key' => 'Atfpp_Ai_Translate_openrouter_api_key', // 'docs_url' => 'https://locoaddon.com/docs/how-to-generate-open-api-key/', // 'value' => get_option('Atfpp_Ai_Translate_openrouter_api_key', '') // ], 'deepl' => [ 'name' => 'DeepL', 'option_key' => 'Atfpp_Ai_Translate_deepl_api_key', 'docs_url' => 'https://locoaddon.com/docs/how-to-generate-deepl-api-key/', 'value' => get_option('Atfpp_Ai_Translate_deepl_api_key', '') ], 'context_aware' => [ 'name' => 'Context Aware', 'option_key' => 'atfp_context_aware', 'value' => get_option('atfp_context_aware', '') ], 'atfpp_bulk_post_status' => [ 'name' => 'Bulk Translation default Post Status', 'option_key' => 'atfp_bulk_post_status', 'value' => get_option('atfp_bulk_post_status', 'draft'), 'options' => [ 'publish' => 'Published', 'draft' => 'Draft', ] ], 'atfp_slug_translation_option' => [ 'name' => 'Slug Translation Settings', 'option_key' => 'atfp_slug_translation_option', 'value' => get_option('atfp_slug_translation_option', 'title_translate'), 'options' => [ 'title_translate' => 'Use Translated Title', 'slug_translate' => 'Translate Original Slug', 'slug_keep' => 'Keep Original Slug', ] ], 'atfp_ai_request_token_per_request' => [ 'name' => 'Token Limit', 'option_key' => 'atfp_ai_request_token_per_request', 'value' => get_option('atfp_ai_request_token_per_request', 500) ], 'atfp_ai_request_batch_size' => [ 'name' => 'Batch Size', 'option_key' => 'atfp_ai_request_batch_size', 'value' => get_option('atfp_ai_request_batch_size', 5) ], 'atfp_ai_request_timeout' => [ 'name' => 'Timeout Duration', 'option_key' => 'atfp_ai_request_timeout', 'value' => get_option('atfp_ai_request_timeout', 120) ] ]; } function atfpp_check_form_submission() { return isset($_POST['nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'api_keys') && current_user_can('manage_options') && $_SERVER['REQUEST_METHOD'] === 'POST'; } function atfpp_validate_google_api_key($key) { if (empty($key)) return false; if (!preg_match('/^AIza[0-9A-Za-z\-_]{35}$/', $key)) { atfpp_show_admin_notice('error', 'Invalid Gemini API Key.'); return false; } $response = wp_remote_get( 'https://generativelanguage.googleapis.com/v1beta/models?key=' . $key, [ 'headers' => ['Content-Type' => 'application/json'], 'timeout' => 30, ] ); if (is_wp_error($response)) { atfpp_show_admin_notice('error', 'API request failed: ' . $response->get_error_message()); return false; } $body = json_decode(wp_remote_retrieve_body($response), true); if (!isset($body['models']) || empty($body['models'])) { atfpp_show_admin_notice('error', 'Invalid or unauthorized Gemini API Key.'); return false; } $text_models = []; foreach ($body['models'] as $model) { if ( empty($model['name']) || empty($model['supportedGenerationMethods']) || !is_array($model['supportedGenerationMethods']) || !in_array('generateContent', $model['supportedGenerationMethods'], true) ) { continue; } $model_name = $model['name']; if ( (isset($model['state']) && $model['state'] !== 'ACTIVE') || preg_match('/(tts|image|vision)/i', $model_name) ) { continue; } $clean_name = str_replace('models/', '', $model_name); $text_models[] = $clean_name; } update_option('atfpp_google_models', $text_models); return true; } function atfpp_validate_openai_api_key( $key ) { if (empty($key)) return false; $response = wp_remote_get('https://api.openai.com/v1/models', [ 'headers' => [ 'Authorization' => 'Bearer ' . $key, ], ]); if (is_wp_error($response)) { atfpp_show_admin_notice('error', 'Unable to connect to OpenAI API.'); return false; } $response_data = json_decode(wp_remote_retrieve_body($response), true); if (!empty($response_data['error'])) { $error_message = $response_data['error']['message'] ?? 'Invalid OpenAI API Key.'; atfpp_show_admin_notice('error', str_replace('request('GET', $url, [ 'headers' => [ 'Authorization' => 'DeepL-Auth-Key ' . $key, ], ]); $statusCode = $response->getStatusCode(); $reason = $response->getReasonPhrase(); // short HTTP reason like "Unauthorized" if($statusCode === 200){ return true; }else{ atfpp_show_admin_notice('error', str_replace('hasResponse()) { // Extract error details from response body $errorBody = (string) $e->getResponse()->getBody(); // Decode JSON response to array $errorData = json_decode($errorBody, true); // Get error message if available $errorMessage = $errorData['message'] ?? $errorBody; } else { // Use exception message if no response body is available $errorMessage = $e->getMessage(); } atfpp_show_admin_notice('error', str_replace(' [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $key, 'HTTP-Referer' => site_url(), 'X-Title' => 'Polylang Addon', 'X-Organization-ID' => site_url(), ], 'body' => wp_json_encode([ 'model' => 'meta-llama/llama-4-maverick:free', 'messages' => [ [ 'role' => 'user', 'content' => [ [ 'type' => 'text', 'text' => 'Test message' ] ] ] ] ]), 'method' => 'POST', 'timeout' => 60, ]); if (is_wp_error($response)) { atfpp_show_admin_notice('error', 'Invalid OpenRouter API Key.'); return false; } $response_data = json_decode(wp_remote_retrieve_body($response), true); if (!empty($response_data['error'])) { $error_message = $response_data['error']['message'] ?? 'Invalid OpenRouter API Key.'; atfpp_show_admin_notice('error', str_replace(' ['href' => [], 'target' => [], 'rel' => []]]) )); return false; } return true; } function atfpp_show_admin_notice($type, $message) { if (!isset($GLOBALS['atfpp_admin_notices'])) { $GLOBALS['atfpp_admin_notices'] = array(); } $GLOBALS['atfpp_admin_notices'][] = wp_kses('

' . wp_kses($message, ['a' => ['href' => [], 'target' => []]]) . '

', ['div' => ['class' => true], 'p' => [], 'a' => ['href' => [], 'target' => []]]); } function atfpp_handle_api_key_submission() { if ( ! current_user_can('manage_options') ) { atfpp_show_admin_notice('error', 'You are not allowed to perform this action.'); return false; } // Clear any existing notices at the start $GLOBALS['atfpp_admin_notices'] = array(); if (isset($_POST['reset_google_api_key'])) { delete_option('Atfpp_Ai_Translate_google_api_key'); delete_option('atfpp_google_models'); delete_option('atfpp_selected_google_model'); atfpp_show_admin_notice('success', 'Gemini API Key has been removed.'); return true; } if (isset($_POST['reset_openai_api_key'])) { delete_option('Atfpp_Ai_Translate_openai_api_key'); delete_option('atfpp_openai_models'); delete_option('atfpp_selected_openai_model'); atfpp_show_admin_notice('success', 'OpenAI API Key has been removed.'); return true; } if (isset($_POST['reset_openrouter_api_key'])) { delete_option('Atfpp_Ai_Translate_openrouter_api_key'); atfpp_show_admin_notice('success', 'OpenRouter API Key has been removed.'); return true; } if (isset($_POST['reset_deepl_api_key'])) { delete_option('atfp_deepl_api_key_type'); delete_option('Atfpp_Ai_Translate_deepl_api_key'); atfpp_show_admin_notice('success', 'DeepL API Key has been removed.'); return true; } if (isset($_POST['submit_api_keys'])) { return atfpp_handle_api_key_save(); } return false; } function atfpp_handle_api_key_save() { if ( ! current_user_can('manage_options') ) { atfpp_show_admin_notice('error', 'You are not allowed to perform this action.'); return false; } $success = false; $any_validation_attempted = false; $has_error = false; // Handle Context Aware textarea if (isset($_POST['atfp_context_aware'])) { $context_aware = sanitize_textarea_field(wp_unslash($_POST['atfp_context_aware'])); update_option('atfp_context_aware', $context_aware); // Store the new value in a global variable to use in the render function $GLOBALS['current_context_aware'] = $context_aware; $success = true; } $current_openai_model = get_option('atfpp_selected_openai_model', ''); $current_google_model = get_option('atfpp_selected_google_model', ''); // Save selected OpenAI model if set and validate if (isset($_POST['atfpp_selected_openai_model']) && $_POST['atfpp_selected_openai_model'] !== $current_openai_model) { $selected_model = sanitize_text_field($_POST['atfpp_selected_openai_model']); $openai_key = get_option('Atfpp_Ai_Translate_openai_api_key', ''); $is_valid = false; $error_message = ''; if ($selected_model === '') { update_option('atfpp_selected_openai_model', ''); atfpp_show_admin_notice('success', 'OpenAI model selection has been cleared.'); } else { if ($openai_key && $selected_model) { $response = wp_remote_post('https://api.openai.com/v1/chat/completions', [ 'headers' => [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $openai_key, ], 'body' => wp_json_encode([ 'model' => $selected_model, 'messages' => [['role' => 'user', 'content' => 'Test']], 'max_completion_tokens' => 20 ]), 'timeout' => 20, ]); if (is_wp_error($response)) { $error_message = $response->get_error_message(); } else { $body = json_decode(wp_remote_retrieve_body($response), true); if (empty($body['error'])) { $is_valid = true; } else { $error_message = $body['error']['message'] ?? 'Unknown error from OpenAI.'; } } } if ($is_valid) { update_option('atfpp_selected_openai_model', $selected_model); atfpp_show_admin_notice('success', 'The OpenAI model has been successfully validated and saved.'); } else { atfpp_show_admin_notice('error', 'OpenAI API Error: ' . esc_html($error_message)); } } } if (isset($_POST['atfpp_selected_google_model']) && $_POST['atfpp_selected_google_model'] !== $current_google_model) { $selected_model = sanitize_text_field($_POST['atfpp_selected_google_model']); $google_key = get_option('Atfpp_Ai_Translate_google_api_key', ''); $is_valid = false; $error_message = ''; if ($selected_model === '') { delete_option('atfpp_selected_google_model'); atfpp_show_admin_notice('success', 'The Google Gemini model selection has been cleared.'); } else { if ($google_key && $selected_model) { $response = wp_remote_post( 'https://generativelanguage.googleapis.com/v1beta/models/' . $selected_model . ':generateContent?key=' . $google_key, [ 'headers' => ['Content-Type' => 'application/json'], 'body' => json_encode([ 'contents' => [[ 'parts' => [['text' => 'Test']] ]] ]), 'timeout' => 60, ] ); if (!is_wp_error($response)) { $body = json_decode(wp_remote_retrieve_body($response), true); if (empty($body['error'])) { $is_valid = true; } else if (!empty($body['error']['message'])) { $error_message = $body['error']['message']; } } else { $error_message = $response->get_error_message(); } } if ($is_valid) { update_option('atfpp_selected_google_model', $selected_model); atfpp_show_admin_notice('success', 'The Gemini model has been successfully validated and saved.'); } else { $notice = $error_message ? $error_message : 'The selected Gemini model is not valid or not accessible with your API key.'; atfpp_show_admin_notice('error', $notice); } } } // Handle feedback checkbox $feedback_opt_in = null; if (get_option('cpfm_opt_in_choice_cool_translations')) { $feedback_opt_in = isset($_POST['atfpp-dashboard-feedback-checkbox']) ? 'yes' : 'no'; update_option('atfp_feedback_opt_in', $feedback_opt_in); } // If user opted out, remove the cron job if ($feedback_opt_in === 'no' && wp_next_scheduled('atfpp_extra_data_update')) { wp_clear_scheduled_hook('atfpp_extra_data_update'); } if ($feedback_opt_in === 'yes' && !wp_next_scheduled('atfpp_extra_data_update')) { wp_schedule_event(time(), 'every_30_days', 'atfpp_extra_data_update'); } if (isset($_POST['atfp_bulk_post_status'])) { $bulk_post_status = sanitize_text_field($_POST['atfp_bulk_post_status']); update_option('atfp_bulk_post_status', $bulk_post_status); $success = true; } if (isset($_POST['atfp_slug_translation_option'])) { $slug_translation_option = sanitize_text_field($_POST['atfp_slug_translation_option']); update_option('atfp_slug_translation_option', $slug_translation_option); $success = true; } if (isset($_POST['atfp_ai_request_token_per_request'])) { $ai_token_per_request = sanitize_text_field($_POST['atfp_ai_request_token_per_request']); if($ai_token_per_request < 100 || $ai_token_per_request > 10000 || empty($ai_token_per_request) ) { atfpp_show_admin_notice('error', 'AI Token Per Request must be between 100 and 10000.'); return false; } update_option('atfp_ai_request_token_per_request', $ai_token_per_request); $success = true; } if (isset($_POST['atfp_ai_request_batch_size'])) { $ai_batch_size = sanitize_text_field($_POST['atfp_ai_request_batch_size']); if($ai_batch_size < 1 || $ai_batch_size > 10 || empty($ai_batch_size) ) { atfpp_show_admin_notice('error', 'AI Batch Size must be between 1 and 10.'); return false; } update_option('atfp_ai_request_batch_size', $ai_batch_size); $success = true; } if (isset($_POST['atfp_ai_request_timeout'])) { $ai_timeout = sanitize_text_field($_POST['atfp_ai_request_timeout']); if($ai_timeout < 10 || $ai_timeout > 1200 || empty($ai_timeout) ) { atfpp_show_admin_notice('error', 'AI Timeout must be between 10 and 1200.'); return false; } update_option('atfp_ai_request_timeout', $ai_timeout); $success = true; } // Validate all API keys first before saving any $valid_keys = []; if (!empty($_POST['Atfpp_Ai_Translate_google_api_key'])) { $new_google_key = sanitize_text_field($_POST['Atfpp_Ai_Translate_google_api_key']); $any_validation_attempted = true; if (atfpp_validate_google_api_key($new_google_key)) { $valid_keys['google'] = $new_google_key; } else { $has_error = true; } } if (!empty($_POST['Atfpp_Ai_Translate_openai_api_key'])) { $new_openai_key = sanitize_text_field($_POST['Atfpp_Ai_Translate_openai_api_key']); $any_validation_attempted = true; if (atfpp_validate_openai_api_key($new_openai_key)) { $valid_keys['openai'] = $new_openai_key; } else { $has_error = true; } } if (!empty($_POST['Atfpp_Ai_Translate_deepl_api_key'])) { $new_deepl_key = sanitize_text_field($_POST['Atfpp_Ai_Translate_deepl_api_key']); $any_validation_attempted = true; if (atfpp_validate_deepl_api_key($new_deepl_key)) { $valid_keys['deepl'] = $new_deepl_key; } else { $has_error = true; } } if (!empty($_POST['Atfpp_Ai_Translate_openrouter_api_key'])) { $new_openrouter_key = sanitize_text_field($_POST['Atfpp_Ai_Translate_openrouter_api_key']); $any_validation_attempted = true; if (atfpp_validate_openrouter_api_key($new_openrouter_key)) { $valid_keys['openrouter'] = $new_openrouter_key; } else { $has_error = true; } } // Only save and show success if there were no errors if (!$has_error && !empty($valid_keys)) { foreach ($valid_keys as $key => $value) { update_option("Atfpp_Ai_Translate_{$key}_api_key", $value); } atfpp_show_admin_notice('success', 'Settings saved successfully.'); return true; } elseif ($any_validation_attempted && !isset($GLOBALS['atfpp_admin_notices'])) { atfpp_show_admin_notice('error', 'Please enter valid values.'); } return false; } function atfpp_render_settings_page_html($apis, $text_domain) { // Process form submission before rendering $form_processed = false; if (atfpp_check_form_submission()) { $form_processed = atfpp_handle_api_key_submission(); } // Refresh API values after form processing if ($form_processed) { $apis = atfpp_get_api_configurations(); } // Update the context aware value if it was just saved if (isset($GLOBALS['current_context_aware'])) { $apis['context_aware']['value'] = $GLOBALS['current_context_aware']; } if(isset($apis['atfpp_bulk_post_status']['value'])){ $apis['atfpp_bulk_post_status']['value'] = get_option('atfp_bulk_post_status', 'draft'); } if(isset($apis['atfp_slug_translation_option']['value'])){ $apis['atfp_slug_translation_option']['value'] = get_option('atfp_slug_translation_option', 'title_translate'); } if(isset($apis['atfp_ai_request_token_per_request']['value'])){ $apis['atfp_ai_request_token_per_request']['value'] = get_option('atfp_ai_request_token_per_request', 500); } if(isset($apis['atfp_ai_request_batch_size']['value'])){ $apis['atfp_ai_request_batch_size']['value'] = get_option('atfp_ai_request_batch_size', 5); } if(isset($apis['atfp_ai_request_timeout']['value'])){ $apis['atfp_ai_request_timeout']['value'] = get_option('atfp_ai_request_timeout', 120); } $openai_models = get_option('atfpp_openai_models', []); $current_openai_model = get_option('atfpp_selected_openai_model', ''); $google_models = get_option('atfpp_google_models', []); $current_google_model = get_option('atfpp_selected_google_model', ''); ?>

Rate Limits of Free Gemini API Key