'Bearer ' . $openai_api_key, 'Content-Type' => 'application/json' ]; $body = [ 'model' => $text_model, 'messages' => [ ['role' => 'user', 'content' => $request_prompt] ] ]; $response = wp_remote_post('https://api.openai.com/v1/chat/completions', [ 'headers' => $headers, 'body' => json_encode($body), 'timeout' => 600 ]); if (is_wp_error($response)) { error_log('Error generating thumbnail prompt: ' . $response->get_error_message()); // Если произошла ошибка, возвращаем промт по умолчанию return "Create a vibrant, attention-grabbing cover image for the article titled '{$article_title}'. The image should creatively reflect the essence of the article."; } $body_response = json_decode(wp_remote_retrieve_body($response), true); $generated_prompt = $body_response['choices'][0]['message']['content'] ?? ''; $generated_prompt = trim($generated_prompt); if (empty($generated_prompt)) { $generated_prompt = "Create a vibrant, attention-grabbing cover image for the article titled '{$article_title}'. The image should creatively reflect the essence of the article."; } return $generated_prompt; } /** * Генерирует изображение для статьи. * * @param string $article_title Заголовок статьи. * @param string $article_content Контент статьи. * @param string $image_model Выбранная модель (будет приведена к DALL‑E). * @param array $size_options Массив опций размеров. * @param array $quality_options Массив опций качества. * @param string $keyword Ключевое слово. * @param int $category_id Идентификатор категории. * @param string $custom_prompt Дополнительный промт. * @param string $prompt_specification Спецификация промта. * * @return array Массив с данными изображения: url, file_name, alt_text и стоимость. */ function ai_content_wizard_generate_image($article_title, $article_content, $image_model, $size_options, $quality_options, $keyword, $category_id, $custom_prompt = '', $prompt_specification = '') { $global_image_generation = ai_content_wizard_get_setting('ai_content_wizard_enable_image_generation', 1); $use_global_settings = ai_content_wizard_get_setting('category-' . $category_id . '_use_global_settings', 1); $category_image_generation = $use_global_settings ? $global_image_generation : ai_content_wizard_get_setting('category-' . $category_id . '_enable_image_generation', null); if ($category_image_generation === null) { error_log("Image generation not defined for category $category_id"); } $generate_image = $category_image_generation ?? $global_image_generation; if ($generate_image == 0) { return ['url' => '', 'file_name' => '', 'alt_text' => '', 'cost' => 0]; } // Используем только API ключ DALL‑E (через OpenAI API) $openai_api_key = ai_content_wizard_get_setting('ai_content_wizard_api_key'); // Принудительно используем модель DALL‑E, так как в lite-версии доступны только модели DALL‑E $image_model = 'dall-e-3'; $article_title = mb_convert_encoding($article_title, 'UTF-8', 'auto'); $article_content = strip_tags($article_content); $content_snippet = mb_substr($article_content, 0, 500); $file_name = strtolower(str_replace(' ', '_', $keyword)) . ".png"; $alt_text = "Illustration for the article: " . $keyword; // Получаем prompt_specification из настроек, если он не передан if (!$prompt_specification) { $prompt_specification = ai_content_wizard_get_setting('ai_content_wizard_prompt_specification', ''); } // Генерируем финальный промт для создания обложки $final_prompt = ai_content_wizard_generate_thumbnail_prompt($article_title, $article_content, $keyword, $custom_prompt, $prompt_specification); $params = [ 'prompt' => $final_prompt, 'api_key' => $openai_api_key, 'size_options' => $size_options, 'quality_options' => $quality_options, 'keyword' => $keyword, 'file_name' => $file_name, 'alt_text' => $alt_text, 'cleaned_content_for_prompt' => $content_snippet ]; // Так как доступны только DALL‑E, вызываем функцию генерации изображения через OpenAI if (strpos($image_model, 'dall-e') !== false) { $result = ai_content_wizard_generate_image_openai($params); } else { error_log("Ошибка: Неизвестная модель изображения - $image_model."); return ['url' => '', 'file_name' => '', 'alt_text' => '', 'cost' => 0]; } if (empty($result['url'])) { error_log("Не удалось сгенерировать изображение для миниатюры."); } // Считаем стоимость $cost = isset($result['cost']) ? (float)$result['cost'] : 0; if ($cost == 0 && !empty($result['url'])) { $cost = calculate_image_generation_cost($image_model, $quality_options, $size_options); } return [ 'url' => isset($result['url']) ? $result['url'] : '', 'file_name' => isset($params['file_name']) ? $params['file_name'] : '', 'alt_text' => isset($params['alt_text']) ? $params['alt_text'] : '', 'cost' => $cost ]; } /** * Обрабатывает загруженное изображение (скачивает и загружает в медиа библиотеку). * В lite-версии водяные знаки и оптимизация не используются. * * @param string $image_url URL изображения. * @param string $filename Имя файла. * * @return mixed Идентификатор вложения или false при ошибке. */ function ai_content_wizard_process_image($image_url, $filename) { require_once(ABSPATH . 'wp-admin/includes/image.php'); require_once(ABSPATH . 'wp-admin/includes/file.php'); require_once(ABSPATH . 'wp-admin/includes/media.php'); // В lite-версии оптимизация не используется, поэтому просто загружаем изображение $filename = $filename ? strtolower(str_replace(' ', '_', $filename)) : 'default_image_name'; // Определяем расширение файла по URL $extension = pathinfo($image_url, PATHINFO_EXTENSION); if (empty($extension)) { $extension = 'png'; } $filename .= '.' . $extension; $tmp = download_url($image_url); if (is_wp_error($tmp)) { error_log('Error downloading image: ' . $tmp->get_error_message()); return false; } $file_array = ['name' => $filename, 'tmp_name' => $tmp]; $attachment_id = media_handle_sideload($file_array, 0); if (is_wp_error($attachment_id)) { @unlink($file_array['tmp_name']); error_log('Error uploading image: ' . $attachment_id->get_error_message()); return false; } // В lite-версии водяной знак не применяется // ai_content_wizard_apply_watermark($attachment_id); return $attachment_id; } /** * Генерирует ALT-текст для изображения через OpenAI. * * @param int $post_id Идентификатор поста. * @param string $keyword Ключевое слово. * @param string $selected_language Выбранный язык. * * @return array Массив с alt-текстом и стоимостью генерации. */ function ai_content_wizard_generate_image_alt_text($post_id, $keyword, $selected_language) { $api_key = ai_content_wizard_get_setting('ai_content_wizard_api_key'); $text_model = ai_content_wizard_get_setting('ai_content_wizard_text_model', 'gpt-4o-mini'); $language_full_name = get_full_language_name($selected_language); $article_title = get_post_field('post_title', $post_id); $article_content = get_post_field('post_content', $post_id); $prompt = "Generate a short (3-5 words), descriptive, and SEO-optimized alt text for an image related to the article titled '$article_title' in '$language_full_name'. Include the primary keyword '$keyword' directly in the alt text."; $input_tokens = str_word_count($prompt); $headers = [ 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json' ]; $response = wp_remote_post('https://api.openai.com/v1/chat/completions', [ 'headers' => $headers, 'body' => json_encode([ 'model' => $text_model, 'messages' => [['role' => 'user', 'content' => $prompt]] ]), 'timeout' => 600 ]); if (is_wp_error($response)) { error_log('Error making request: ' . $response->get_error_message()); return ['alt_text' => 'Image related to ' . $article_title, 'cost' => 0]; } $body = json_decode(wp_remote_retrieve_body($response), true); $alt_text = $body['choices'][0]['message']['content'] ?? 'Image related to ' . $article_title; $alt_text = trim(str_replace(["\n", "\r", "\t"], ' ', $alt_text)); $alt_text = preg_replace('/\s+/', ' ', $alt_text); $alt_text = str_replace(['"', "'"], '', $alt_text); $output_tokens = str_word_count($alt_text); $alt_cost = calculate_text_generation_cost($text_model, $input_tokens, $output_tokens); return ['alt_text' => $alt_text, 'cost' => $alt_cost]; }