[ 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json', ], 'body' => json_encode([ 'model' => $text_model, 'messages' => [ ['role' => 'user', 'content' => $outline_prompt] ], ]), 'timeout' => 1000 ]); if (is_wp_error($response)) { error_log('Ошибка при запросе outline: ' . $response->get_error_message()); return 'No outline generated'; } $result = json_decode(wp_remote_retrieve_body($response), true); return $result['choices'][0]['message']['content'] ?? 'No outline generated'; } } /** * Запрос к API OpenAI для генерации финального контента статьи. */ if (!function_exists('request_content_generation')) { function request_content_generation($api_key, $text_model, $prompt_article) { $response = wp_remote_post('https://api.openai.com/v1/chat/completions', [ 'headers' => [ 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json', ], 'body' => json_encode([ 'model' => $text_model, 'messages' => [['role' => 'user', 'content' => $prompt_article]], ]), 'timeout' => 1000 ]); if (is_wp_error($response)) { error_log('Ошибка при запросе генерации контента: ' . $response->get_error_message()); return 'No content generated'; } $result = json_decode(wp_remote_retrieve_body($response), true); return $result['choices'][0]['message']['content'] ?? 'No content generated'; } } /** * Основная функция для генерации статьи с учётом outline, внешних ссылок и контроля плотности ключевого слова. */ function generate_article_content( $post_topic, $category_name, $selected_language, $keyword, $format, $text_length, $site_type, $writing_style, $target_audience, $custom_theme, $additional_requests, $single_post_additional_request, $related_articles_context, $api_key, $text_model, $target_region ) { // Приводим $text_length к диапазону [500..10000] слов if ($text_length < 500) { $text_length = 500; } elseif ($text_length > 10000) { $text_length = 10000; } // Рассчитываем, сколько будет основных и дополнительных секций исходя из объёма $factor = ($text_length - 500) / (10000 - 500); // 0..1 if ($factor < 0) $factor = 0; if ($factor > 1) $factor = 1; // При небольшом объёме статей делаем меньше секций, при большом — больше $main_sections_min = round(2 + (4 - 2) * $factor); // от 2 до 4 $main_sections_max = round(4 + (6 - 4) * $factor); // от 4 до 6 $subsections_min = round(1 + (2 - 1) * $factor); // от 1 до 2 $subsections_max = round(2 + (3 - 2) * $factor); // от 2 до 3 // Получаем «полное» название языка $language_full_name = get_full_language_name($selected_language); /* * Шаг 1: Генерируем план (outline) статьи */ $outline_prompt = " You are an expert researcher and professional writer. Create a concise outline (table of contents) for an in-depth article in '{$language_full_name}' on the topic: '{$post_topic}', appropriate for the '{$category_name}' category. The article should be aimed at '{$target_audience}' in '{$target_region}', with a target length of approximately {$text_length} words. Organize the outline into {$main_sections_min} to {$main_sections_max} main sections, each with {$subsections_min} to {$subsections_max} subsections. Incorporate the keyword '{$keyword}' where relevant, and provide clear, structured points for each section. Do not generate the full article here — ONLY the outline (like a table of contents)."; // Генерируем outline $outline = request_article_outline($api_key, $text_model, $outline_prompt); // Логируем outline, чтобы видеть какой он сформировался и при каком объёме //error_log('[openai_generate_content] Generated outline for topic "' . $post_topic . '" at length ' . $text_length . ' words:'); //error_log($outline); /* * Шаг 2: Формируем окончательный промпт для генерации всей статьи */ $final_prompt = " Using the following outline: ------------------------------ {$outline} ------------------------------ Write a complete, detailed, SEO-optimized '{$format}' in '{$language_full_name}' about '{$post_topic}', suitable for the '{$category_name}' category. Ensure the content is approximately {$text_length} words long, thoroughly covering each section from the outline without adding or removing major points. Requirements: 1. Use
tags and contain at least three sentences. 4. Use only unordered lists (
и в начале и конце статьи
$article_content = preg_replace('/^(.*?<\/pre>|.*?<\/code>)/si', '', $article_content);
$article_content = preg_replace('/(.*?<\/pre>|.*?<\/code>)$/si', '', $article_content);
// 5) Удаление всех возможных вариантов «```html» и пр. в начале
$article_content = preg_replace('/^(\s*((\{){1,3}|\'{1,3}|"{1,3})html\s*)+/i', '', $article_content);
// 6) Удаление кавычек/фигурных скобок в конце
$article_content = preg_replace('/(\s*((\{){1,3}|\'{1,3}|"{1,3})\s*)+$/m', '', $article_content);
$article_content = preg_replace('/(\s*((\{){1,3}|\'{1,3}|"{1,3})\s*)+(\r?\n|\r)?$/m', '', $article_content);
// 7) Удаляем «мета-комментарии» модели (I generated..., This content was created..., etc.)
$article_content = preg_replace('/\b(This (HTML structure|article|content|section|review)|I (generated|created)).*$/mi', '', $article_content);
return $article_content;
}