Changeset 3260025
- Timestamp:
- 03/22/2025 10:46:32 AM (10 months ago)
- Location:
- easy-gpt-for-wp
- Files:
-
- 66 added
- 10 edited
-
tags/1.13 (added)
-
tags/1.13/admin (added)
-
tags/1.13/admin/admin-functions.php (added)
-
tags/1.13/admin/index.php (added)
-
tags/1.13/assets (added)
-
tags/1.13/assets/banner-1544x500.png.png (added)
-
tags/1.13/assets/banner-772x250.png (added)
-
tags/1.13/assets/icon-128x128.png (added)
-
tags/1.13/assets/icon-256x256.png (added)
-
tags/1.13/assets/screenshot-1.png (added)
-
tags/1.13/assets/screenshot-2.png (added)
-
tags/1.13/assets/screenshot-3.png (added)
-
tags/1.13/assets/screenshot-4.png (added)
-
tags/1.13/assets/screenshot-5.png (added)
-
tags/1.13/assets/screenshot-6.png (added)
-
tags/1.13/assets/screenshot-7.png (added)
-
tags/1.13/assets/screenshot-8.png (added)
-
tags/1.13/assets/screenshot-9.png (added)
-
tags/1.13/easy-gpt-for-wp.php (added)
-
tags/1.13/images (added)
-
tags/1.13/images/Logo-Pequeno-admin.png (added)
-
tags/1.13/images/accept-and-insert-article.png (added)
-
tags/1.13/images/generate-new-post.png (added)
-
tags/1.13/images/image-api.png (added)
-
tags/1.13/images/image-license.png (added)
-
tags/1.13/images/index.php (added)
-
tags/1.13/images/new-bulk-generation.png (added)
-
tags/1.13/images/tutorial-settings-post.png (added)
-
tags/1.13/images/tutorial-settings.png (added)
-
tags/1.13/images/view-bulk-generation.png (added)
-
tags/1.13/includes (added)
-
tags/1.13/includes/bulk-article-processing.php (added)
-
tags/1.13/includes/bulk-generation.php (added)
-
tags/1.13/includes/bulk-list.php (added)
-
tags/1.13/includes/comments.php (added)
-
tags/1.13/includes/cost.php (added)
-
tags/1.13/includes/easy-gpt-bulk-article-generator.php (added)
-
tags/1.13/includes/easy-gpt-options.php (added)
-
tags/1.13/includes/how-to-use.php (added)
-
tags/1.13/includes/index.php (added)
-
tags/1.13/includes/license.php (added)
-
tags/1.13/includes/metaboxes.php (added)
-
tags/1.13/includes/settings-functions.php (added)
-
tags/1.13/includes/status.php (added)
-
tags/1.13/includes/support.php (added)
-
tags/1.13/index.php (added)
-
tags/1.13/js (added)
-
tags/1.13/js/admin-script.js (added)
-
tags/1.13/js/admin-youtube.js (added)
-
tags/1.13/js/bulk-generation-another.js (added)
-
tags/1.13/js/bulk-generation.js (added)
-
tags/1.13/js/easy-gpt-bulk-list.js (added)
-
tags/1.13/js/easy-gpt-custom.js (added)
-
tags/1.13/js/how-to-use.js (added)
-
tags/1.13/public (added)
-
tags/1.13/public/index.php (added)
-
tags/1.13/public/public-functions.php (added)
-
tags/1.13/readme.txt (added)
-
tags/1.13/styles (added)
-
tags/1.13/styles/admin-style.css (added)
-
tags/1.13/styles/bulk-generation.css (added)
-
tags/1.13/styles/bulk-list.css (added)
-
tags/1.13/styles/comments-style.css (added)
-
tags/1.13/styles/how-to-use.css (added)
-
tags/1.13/styles/license.css (added)
-
tags/1.13/styles/metabox-style.css (added)
-
trunk/assets/screenshot-9.png (modified) (previous)
-
trunk/easy-gpt-for-wp.php (modified) (5 diffs)
-
trunk/includes/bulk-article-processing.php (modified) (8 diffs)
-
trunk/includes/bulk-generation.php (modified) (7 diffs)
-
trunk/includes/easy-gpt-bulk-article-generator.php (modified) (5 diffs)
-
trunk/includes/metaboxes.php (modified) (13 diffs)
-
trunk/includes/settings-functions.php (modified) (4 diffs)
-
trunk/js/bulk-generation.js (modified) (2 diffs)
-
trunk/js/easy-gpt-custom.js (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
easy-gpt-for-wp/trunk/easy-gpt-for-wp.php
r3257086 r3260025 4 4 * Plugin URI: https://easygptforwp.com/ 5 5 * Description: Integrates OpenAI GPT functionalities to automatically generate content and manage SEO in WordPress. 6 * Version: 1.1 26 * Version: 1.13 7 7 * Author: Ignacio Gil Alvarez 8 8 * Author URI: https://morris34.com/ … … 16 16 } 17 17 18 define('EASY_GPT_PLUGIN_VERSION', '1.1 0');18 define('EASY_GPT_PLUGIN_VERSION', '1.13'); 19 19 20 20 /** … … 138 138 video_position_bulk varchar(50) DEFAULT 'end', -- Nuevo campo 139 139 video_paragraph_bulk int(11) DEFAULT 3, -- Nuevo campo 140 include_citations_bulk tinyint(1) DEFAULT 0, 141 final_review_bulk tinyint(1) DEFAULT 0, 142 minutes_between_articles int(11) DEFAULT 0, 140 143 PRIMARY KEY (id) 141 144 ) $charset_collate;"; … … 183 186 $alter_queries[] = "ADD COLUMN video_paragraph_bulk int(11) DEFAULT 3"; 184 187 } 188 189 if (!in_array('include_citations_bulk', $columns)) { 190 $alter_queries[] = "ADD COLUMN include_citations_bulk tinyint(1) DEFAULT 0"; 191 } 192 if (!in_array('final_review_bulk', $columns)) { 193 $alter_queries[] = "ADD COLUMN final_review_bulk tinyint(1) DEFAULT 0"; 194 } 195 196 if (!in_array('minutes_between_articles', $columns)) { 197 $alter_queries[] = "ADD COLUMN minutes_between_articles int(11) DEFAULT 0"; 198 } 185 199 186 200 if (!empty($alter_queries)) { … … 222 236 } 223 237 add_action('admin_init', 'easy_gpt_check_for_updates'); 238 239 add_action('admin_footer-plugins.php', 'easy_gpt_deactivate_feedback_modal'); 240 241 function easy_gpt_deactivate_feedback_modal() { 242 ?> 243 <style> 244 #easy-gpt-feedback-modal { 245 position: fixed; 246 z-index: 9999; 247 top: 0; left: 0; right: 0; bottom: 0; 248 background: rgba(0,0,0,0.4); 249 display: none; 250 justify-content: center; 251 align-items: center; 252 } 253 254 #easy-gpt-feedback-modal.show { 255 display: flex !important; 256 } 257 258 #easy-gpt-feedback-box { 259 background: #fff; 260 padding: 24px; 261 border-radius: 12px; 262 width: 100%; 263 max-width: 480px; 264 box-shadow: 0 8px 24px rgba(0,0,0,0.2); 265 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; 266 position: relative; 267 animation: fadeIn 0.2s ease-in-out; 268 box-sizing: border-box; 269 } 270 271 #easy-gpt-feedback-box h2 { 272 margin-top: 0; 273 font-size: 18px; 274 margin-bottom: 16px; 275 } 276 277 .easy-gpt-feedback-btn { 278 display: block; 279 width: 100%; 280 margin: 6px 0; 281 padding: 10px 14px; 282 border: 1px solid #ccc; 283 background: #f9f9f9; 284 border-radius: 6px; 285 cursor: pointer; 286 text-align: left; 287 transition: background 0.2s ease; 288 } 289 290 .easy-gpt-feedback-btn:hover { 291 background: #eef1f5; 292 } 293 294 #easy-gpt-modal-close { 295 position: absolute; 296 top: 10px; 297 right: 12px; 298 font-size: 18px; 299 cursor: pointer; 300 color: #666; 301 } 302 303 #easy-gpt-modal-close:hover { 304 color: #000; 305 } 306 307 @keyframes fadeIn { 308 from { opacity: 0; transform: scale(0.95); } 309 to { opacity: 1; transform: scale(1); } 310 } 311 </style> 312 313 <div id="easy-gpt-feedback-modal"> 314 <div id="easy-gpt-feedback-box"> 315 <div id="easy-gpt-modal-close" title="Close">✖️</div> 316 <h2>Why are you deactivating Easy GPT for WP?</h2> 317 <p style="font-size: 14px; color: #555; margin-top: -10px; margin-bottom: 16px;"> 318 We value your feedback and may improve based on it. 319 </p> 320 <button class="easy-gpt-feedback-btn" data-reason="It's just a temporary deactivation">1️⃣ Temporary deactivation</button> 321 <button class="easy-gpt-feedback-btn" data-reason="I don't have the API">2️⃣ I don't have the API</button> 322 <button class="easy-gpt-feedback-btn" data-reason="I don't like the results">3️⃣ I don't like the results</button> 323 <button class="easy-gpt-feedback-btn" data-reason="I don't want to pay">4️⃣ I don't want to pay</button> 324 <button class="easy-gpt-feedback-btn" data-reason="It's too expensive">5️⃣ It's too expensive</button> 325 <button class="easy-gpt-feedback-btn" data-reason="The plugin is too complicated">6️⃣ Too complicated</button> 326 <button class="easy-gpt-feedback-btn" data-reason="I'm switching to another AI tool">7️⃣ Switching to another AI tool</button> 327 <button class="easy-gpt-feedback-btn" data-reason="Performance issues (slow, errors, etc.)">8️⃣ Performance issues</button> 328 <button class="easy-gpt-feedback-btn" data-reason="Other">9️⃣ Other (please specify)</button> 329 </div> 330 </div> 331 332 <script> 333 jQuery(document).ready(function($) { 334 let easyGptDeactivateHref = ''; 335 336 // Mostrar el modal al hacer clic en desactivar 337 $(document).on('click', '#deactivate-easy-gpt-for-wp', function(e) { 338 e.preventDefault(); 339 easyGptDeactivateHref = $(this).attr('href'); 340 $('#easy-gpt-feedback-modal').addClass('show'); 341 }); 342 343 // Cerrar el modal al hacer clic en ✖️ 344 $(document).on('click', '#easy-gpt-modal-close', function() { 345 $('#easy-gpt-feedback-modal').removeClass('show'); 346 }); 347 348 // Enviar feedback 349 $(document).on('click', '.easy-gpt-feedback-btn', function() { 350 let reason = $(this).data('reason'); 351 352 // Preguntar detalles para ciertas opciones 353 if (reason === 'Other') { 354 let details = prompt("Please provide more details:"); 355 if (details) { 356 reason += " - " + details; 357 } else { 358 return; 359 } 360 } 361 362 if (reason.includes("Performance issues")) { 363 let details = prompt("Could you describe the issue you experienced?"); 364 if (details) { 365 reason += " - Details: " + details; 366 } 367 } 368 369 370 $.post(ajaxurl, { 371 action: 'easy_gpt_send_uninstall_email', 372 reason: reason 373 }, function() { 374 $('#easy-gpt-feedback-modal').removeClass('show'); 375 setTimeout(function() { 376 window.location.href = easyGptDeactivateHref; 377 }, 50); 378 }); 379 }); 380 }); 381 </script> 382 <?php 383 } 384 385 386 387 add_action('wp_ajax_easy_gpt_send_uninstall_email', 'easy_gpt_send_uninstall_email'); 388 389 function easy_gpt_send_uninstall_email() { 390 if (!isset($_POST['reason'])) { 391 wp_die(); 392 } 393 394 $reason = sanitize_text_field($_POST['reason']); 395 396 // Obtener datos del usuario actual 397 $current_user = wp_get_current_user(); 398 $user_email = $current_user->user_email; 399 $user_name = $current_user->display_name ?: $current_user->user_login; 400 401 // Información del sitio 402 $site_url = get_site_url(); 403 404 // Datos del correo 405 $to = '[email protected]'; 406 $subject = "📌 Easy GPT – User feedback on plugin deactivation"; 407 $headers = array('Reply-To: ' . $user_name . ' <' . $user_email . '>'); 408 409 $message = "A user is deactivating the Easy GPT for WP plugin.\n\n"; 410 $message .= "🔹 Reason: {$reason}\n"; 411 $message .= "👤 User: {$user_name} ({$user_email})\n"; 412 $message .= "🌐 Site: {$site_url}\n"; 413 $message .= "\n📩 This message was automatically generated."; 414 415 wp_mail($to, $subject, $message, $headers); 416 417 wp_die(); 418 } 419 420 224 421 ?> -
easy-gpt-for-wp/trunk/includes/bulk-article-processing.php
r3255349 r3260025 698 698 $entity_type = ($article_params['content_type'] === 'product') ? "product" : "article"; 699 699 700 $full_prompt = "Generate an excerpt for a {$entity_type} titled '{$title}' with the following details:\n" .700 $full_prompt = "Generate an excerpt for a {$entity_type} titled '{$title}' with the following details:\n" . 701 701 "Prompt: {$prompt}\n" . 702 702 "Keywords: {$keywords}\n" . … … 706 706 "Writing Style: {$writing_style}\n" . 707 707 "Tone: {$writing_tone}\n" . 708 "Maximum Words for the excerpt: 60 words. ";708 "Maximum Words for the excerpt: 60 words. Do not include the title in the excerpt."; 709 709 710 710 $response = easy_gpt_call_openai_api_no_session($full_prompt, $model, $temperature, $api_key); … … 846 846 $writing_tone = $article_params['writing_tone']; 847 847 $api_key = get_option('easy_gpt_options')['easy_gpt_api_key']; 848 $include_citations = isset($article_params['include_citations_bulk']) ? boolval($article_params['include_citations_bulk']) : false; 849 $final_review = isset($article_params['final_review_bulk']) ? boolval($article_params['final_review_bulk']) : false; 848 850 849 851 $format_article = isset($article_params['format_article']) ? $article_params['format_article'] : false; … … 851 853 $includeLinks = isset($article_params['include_links']) ? $article_params['include_links'] : false; 852 854 853 $links_instructions = $includeLinks ? " If necessary, you can insert links using <a> tags to justify data or claims, recommendations in the middle of the text, for example, according to a study made by <a> ... </a>, if possible use the name for the link, but do not say for more information." : "";855 $links_instructions = $includeLinks ? " You can insert links using <a> tags to justify data or claims, recommendations in the middle of the text, for example, according to a study made by <a> ... </a>, if possible use the name for the link, but do not say for more information." : ""; 854 856 855 857 $bibliography_instructions = $includeBibliography … … 879 881 880 882 // Generar la introducción 881 $intro_prompt = "Generate an introduction for a {$entity_type} titled '{$title}' with the following details, formatted with <p> tags for each paragraph {$format_instructions}(only return the introduction):\n" .883 $intro_prompt = "Generate an introduction for a {$entity_type} titled '{$title}' with the following details, formatted with <p> tags for each paragraph{$format_instructions}, do not include the title in the introducction, do not use # or * and <html> tag, (only return the introduction):\n" . 882 884 "Prompt: {$prompt}\n" . 883 885 "Keywords: {$keywords}\n" . … … 924 926 } 925 927 926 $min_words_section = $min_words / max(count($h2_sections), 1); 927 $max_words_section = $max_words / max(count($h2_sections), 1); 928 928 $min_words_per_section = $min_words / max(count($h2_sections), 1); 929 $max_words_per_section = $max_words / max(count($h2_sections), 1); 930 931 $citation_instructions = $include_citations 932 ? " and blockquotes (`<i>`) (blockquotes only if necesary) with the autor name (like real) where relevant." 933 : "."; 934 935 $citation_instructions2 = $include_citations 936 ? ", blockquotes (with the person of the quote), " 937 : " "; 938 939 940 929 941 foreach ($h2_sections as $index => $h2_section) { 942 error_log("Generando..."); 943 930 944 $h2_title = array_shift($h2_section); 945 error_log($h2_title); 931 946 $h3_h4 = implode("\n", $h2_section); 932 947 if (empty($h3_h4)) { … … 934 949 } 935 950 936 937 // Generar la sección 938 $section_prompt = "Generate a detailed section for the {$entity_type} titled '{$title}'. Include the following details:\n" . 939 "Section Title: {$h2_title}\n" . 940 "Subheadings:\n{$h3_h4}\n" . 941 "Format the {$entity_type} using tags like <h2> for section title, <p> for paragraphs, <h3> <h4> for subheadings, <ul><li> for lists... {$format_instructions}. Do not write <html>.\n" . 942 "Prompt: {$prompt}\n" . 943 "Keywords: {$keywords}\n" . 944 "Specific Instructions: {$specific_instructions_content}\n" . 945 "Language: {$language}\n" . 946 "Style: {$writing_style}\n" . 947 "Tone: {$writing_tone}\n" . 948 "Note: This is a section of a larger {$entity_type}. Begin with an introduction (it is an introduction for the section, not a subheading), follow with detailed content under each subheading and do not include conclusions or summaries.\n" . 949 "Word Limit: This section should contain at least {$min_words_section} words and no more than {$max_words_section} words. Do not use the symbol #.\n" . 950 $links_instructions; 951 952 953 $response = easy_gpt_call_openai_api_no_session($section_prompt, $model, $temperature, $api_key); 951 //error_log("Contenido previo - ". $index . ": ". $previous_content); 952 $previous_content = implode("\n", $responses); // Unir todo lo generado hasta el momento 953 954 955 $section_prompt = "Continue writing the article about {$entity_type} titled '{$title}', ensuring a smooth transition from the previous sections. Avoid repeating general information already covered. 956 957 Previously written sections:\n{$previous_content}\n 958 959 Generate a detailed section with the following details: 960 961 - Section Title: {$h2_title} 962 - Subheadings: {$h3_h4} 963 - Format: Use proper HTML tags, like <h2> for section titles, <h3>, <h4> for subheadings, <p> for paragraphs, and <ul><li> for lists, and <blockquote> for quotes. {$format_instructions}. 964 - Do not use # and <html> tag. 965 - Important: In the section Apply bold <b> for key concepts, important phrases, and crucial data. 966 - Apply italics <i> to scientific terms, foreign words... 967 - Incorporate lists (`<ul><li>`){$citation_instructions} 968 - Ensure these formatting elements appear naturally throughout the entire section, not just in the introduction or conclusion. 969 - Before introducing any `<h3>` or `<h4>`, ensure there is a short introductory paragraph (2-3 sentences) explaining what will be covered in the subsection. 970 971 --- 972 973 Refining Introductions and Transitions: 974 * Vary how the section starts: Instead of beginning with a direct statement about the topic, consider alternative openings: 975 - Ask a rhetorical question to engage the reader. 976 - Use an intriguing fact or statistic to draw attention. 977 - Introduce a brief anecdote or historical reference (if relevant). 978 - Make a comparison or contrast with another related concept. 979 *Avoid starting multiple sections or paragraphs with the same noun or phrase. Instead, use synonyms, rephrase, or introduce the idea in a different way. 980 *Make transitions natural and fluid, do not use always the same, variety 981 *Ensure logical connections between subtopics, so the article flows smoothly rather than feeling fragmented. 982 983 --- 984 985 The section must begin with a short, engaging introduction that: 986 - Do not start by repeating the article’s main topic. 987 - Introduce the section in a natural and engaging way to maintain reader interest. 988 - Avoid generic phrasing—connect the section to the broader article context. 989 - You can use a rhetorical question. 990 991 Detailed Section Development 992 - Expand each subheading into 2-4 paragraphs. 993 - Use lists{$citation_instructions2}or tables when appropriate to improve readability. 994 - Introduce new insights rather than restating previous content. 995 - Add real-world examples, statistics, or historical context where relevant. 996 - {$links_instructions} 997 998 --- 999 1000 ### Enhancing Readability and Style 1001 - Avoid repetitive sentence structures (e.g., multiple paragraphs starting with the same noun or phrase). 1002 - If a keyword (singular or plural) appeared in the first 20 words of the last 3 paragraphs, avoid it in the new paragraph. 1003 - Diversify sentence structures: Mix short and long sentences, use subordinate clauses, and include comparisons or rhetorical questions. 1004 - Ensure a smooth, engaging flow that keeps the reader interested. 1005 - Use proper linking phrases for smooth transitions between subtopics. 1006 1007 --- 1008 1009 Formatting Consistency 1010 Ensure proper distribution of formatting elements: 1011 - Bold (`<b>`) should emphasize key facts, not entire sentences. 1012 - Italics (`<i>`) should highlight technical terms and foreign words. 1013 - Lists and blockquotes should naturally complement the content, rather than being forced in. 1014 - Dont use ** or *, use <b> or <i> insteed 1015 1016 --- 1017 1018 - Prompt: {$prompt} 1019 - Keywords: {$keywords} 1020 - Specific Instructions: {$specific_instructions_content} 1021 - Language: {$language} 1022 - Style: {$writing_style} 1023 - Tone: {$writing_tone} 1024 1025 - Do not forget Apply bold <b> for key concepts, important phrases, and crucial data. 1026 - Word Limit: Between {$min_words_per_section} and {$max_words_per_section} words. 1027 1028 {$links_instructions}"; 1029 1030 1031 //error_log($section_prompt); 1032 1033 $response = easy_gpt_call_openai_api_no_session($section_prompt, $model, $temperature, $api_key, $post_id); 954 1034 955 1035 if (!$response) { 956 return false; 1036 wp_send_json_error(['message' => "Failed to generate section for '{$h2_title}'"]); 1037 wp_die(); 957 1038 } 958 1039 959 1040 $responses[] = $response['text']; 960 1041 1042 // Insertar video si la opción es 'random' y esta es la sección seleccionada 961 1043 if (!empty($video_url) && $include_video && $video_position === 'random' && $index === $insert_video_after_section) { 962 1044 $responses[] .= "$video_url"; 963 1045 } 964 965 } 966 1046 } 1047 1048 // Generar la conclusión 967 1049 968 1050 if (!empty($video_url) && $include_video && $video_position === 'end') { … … 970 1052 } 971 1053 972 // Generar conclusión 973 $conclusion_prompt = "Generate a conclusion for a {$entity_type} titled '{$title}' with the following details, formatted with <p> tags for each paragraph {$format_instructions}, give it a <h2> heading:\n" . 974 "Prompt: {$prompt}\n" . 975 "Keywords: {$keywords}\n" . 976 "Language: {$language}\n" . 977 "Writing Style: {$writing_style}\n" . 978 "Tone: {$writing_tone}\n" . 979 "Maximum Words for the conclusion: 200 words.\n" . 980 $bibliography_instructions; 981 982 $conclusion_response = easy_gpt_call_openai_api_no_session($conclusion_prompt, $model, $temperature, $api_key); 1054 $previous_content = implode("\n", $responses); // Unir todo el contenido generado antes de la conclusión 1055 1056 $conclusion_prompt = "Generate a strong conclusion for a {$entity_type} titled '{$title}'. The conclusion should summarize the main insights without repeating detailed information already covered. Ensure a natural and engaging closing statement. 1057 1058 Previously written content:\n{$previous_content}\n 1059 1060 Consider the key points from this outline: {$outline}. Format the conclusion with <p> tags for each paragraph{$format_instructions}. Provide a <h2> heading that naturally summarizes the key message of the conclusion, avoiding generic titles like 'Conclusion'.\n 1061 1062 Prompt: {$prompt}\n 1063 Keywords: {$keywords}\n 1064 Language: {$language}\n 1065 Writing Style: {$writing_style}\n 1066 Tone: {$writing_tone}\n 1067 Maximum Words for the conclusion: 200 words.\n 1068 {$bibliography_instructions}"; 1069 1070 1071 $conclusion_response = easy_gpt_call_openai_api_no_session($conclusion_prompt, $model, $temperature, $api_key, $post_id); 983 1072 984 1073 if (!$conclusion_response) { 985 return false; 1074 wp_send_json_error(['message' => "Failed to generate conclusion"]); 1075 wp_die(); 986 1076 } 987 1077 988 1078 $responses[] = $conclusion_response['text']; 989 1079 990 // Manejar la opción 'after_paragraph' 991 if (!empty($video_url) && $include_video && $video_position === 'after_paragraph') { 992 $full_article = implode("", $responses); 993 // Usar preg_split para mantener las etiquetas <p> 994 $paragraphs = preg_split('/(<p\b[^>]*>.*?<\/p>)/i', $full_article, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 995 996 997 error_log("Total paragraphs found: " . count($paragraphs)); 998 error_log("After paragraph number: " . $after_paragraph); 999 1000 // Validar el número de párrafos 1001 if ($after_paragraph > 0 && $after_paragraph <= count($paragraphs)) { 1002 // Insertar el video después del párrafo especificado 1003 // $after_paragraph es 1-based, ajustar a 0-based 1004 $insert_index = $after_paragraph; // Como cada párrafo está en un índice separado 1005 if (isset($paragraphs[$insert_index])) { 1006 array_splice($paragraphs, $insert_index, 0, "\n<p>{$video_url}</p>\n"); 1007 error_log("Inserted video after paragraph {$after_paragraph}."); 1008 } else { 1009 // Fallback en caso de que no exista el índice 1010 $paragraphs[] = "\n<p>{$video_url}</p>\n"; 1011 error_log("Paragraph index {$insert_index} not found. Inserted video at the end."); 1012 } 1013 } else { 1014 // Si el número de párrafos es mayor o igual, insertar al final antes de la conclusión 1015 $paragraphs[] = "\n<p>{$video_url}</p>\n"; 1016 error_log("After paragraph number {$after_paragraph} exceeds paragraph count. Inserted video at the end."); 1017 } 1018 1019 $full_article = implode("", $paragraphs); 1020 } else { 1021 $full_article = implode("", $responses); 1022 } 1080 1081 $full_article = implode("\n", $responses); 1082 1083 if ($final_review) { 1084 // 📌 **Paso adicional: Revisar el artículo después de la conclusión pero antes del video** 1085 $review_prompt = "Here is a complete article about {$entity_type} titled '{$title}'. Review and refine it to improve coherence, eliminate redundancies, and ensure a more natural flow. 1086 1087 Previously written content:\n{$full_article}\n 1088 1089 Instructions for Refinement: 1090 - Each section (H2) must start with a short, engaging introduction (2-3 sentences) if missing. 1091 - Ensure a logical transition between sections and subheadings (H3, H4). 1092 - Avoid repetitive sentence structures: Do not start multiple paragraphs with the same noun or phrase. 1093 - Reword initial sentences to introduce variety while keeping the meaning intact. 1094 - Do not add new information—only refine and optimize existing content. 1095 - Summarize the conclusion concisely without repeating details already covered. 1096 - Use bold (`<b>`) for key concepts, important phrases, and crucial data. 1097 - Apply italics (`<i>`) to scientific terms, foreign words... 1098 - Use <a> for links 1099 - If there are ** or * change per <b> or <i> tags 1100 1101 Formatting Instructions: 1102 - Maintain proper structure using <h2> for section titles, <h3> and <h4> for subheadings, <p> for paragraphs, and <ul><li> for lists and <i> for quotes, {$format_instructions}, do not write <html> tag. 1103 - If a YouTube URL is present, leave it unchanged. 1104 1105 Only return the article 1106 1107 Article for Review: 1108 {$full_article}"; 1109 1110 1111 $review_response = easy_gpt_call_openai_api($review_prompt, $model, $temperature, $api_key, $post_id); 1112 1113 if (!$review_response) { 1114 wp_send_json_error(['message' => "Failed to review the article"]); 1115 wp_die(); 1116 } 1117 1118 // Reemplazar el contenido con la versión revisada 1119 $full_article = $review_response['text']; 1120 } 1121 1122 // 📌 **Solo ahora, insertar el video si corresponde** 1123 if (!empty($video_url) && $include_video && $video_position === 'after_paragraph') { 1124 $paragraphs = preg_split('/(<p\b[^>]*>.*?<\/p>)/i', $full_article, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 1125 1126 error_log("Total paragraphs found: " . count($paragraphs)); 1127 error_log("After paragraph number: " . $after_paragraph); 1128 1129 // Validar el número de párrafos 1130 if ($after_paragraph > 0 && $after_paragraph <= count($paragraphs)) { 1131 // Insertar el video después del párrafo especificado 1132 $insert_index = $after_paragraph; 1133 if (isset($paragraphs[$insert_index])) { 1134 array_splice($paragraphs, $insert_index, 0, "\n<p>{$video_url}</p>\n"); 1135 error_log("Inserted video after paragraph {$after_paragraph}."); 1136 } else { 1137 $paragraphs[] = "\n<p>{$video_url}</p>\n"; 1138 error_log("Paragraph index {$insert_index} not found. Inserted video at the end."); 1139 } 1140 } else { 1141 $paragraphs[] = "\n<p>{$video_url}</p>\n"; 1142 error_log("After paragraph number {$after_paragraph} exceeds paragraph count. Inserted video at the end."); 1143 } 1144 1145 $full_article = implode("", $paragraphs); 1146 } 1023 1147 1024 1148 // Combinar todas las secciones del artículo en una sola variable -
easy-gpt-for-wp/trunk/includes/bulk-generation.php
r3253315 r3260025 103 103 $video_position_bulk = isset($options['easy_gpt_video_position']) ? $options['easy_gpt_video_position'] : 'end'; 104 104 $video_paragraph_bulk = isset($options['easy_gpt_video_paragraph']) ? $options['easy_gpt_video_paragraph'] : 3; 105 $include_citations_bulk = isset($options['easy_gpt_include_citations']) ? $options['easy_gpt_include_citations'] : '0'; 106 $final_review_bulk = isset($options['easy_gpt_final_review']) ? $options['easy_gpt_final_review'] : '0'; 105 107 106 108 … … 274 276 <input type="number" id="articles_per_interval" name="articles_per_interval" min="1" value="1"> 275 277 </div> 278 <div class="easy-gpt-field" id="minutes_between_articles_container" style="display: none;"> 279 <label for="minutes_between_articles"><?php esc_html_e( 'Minutes Between Articles:', 'easy-gpt-for-wp' ); ?></label> 280 <input type="number" id="minutes_between_articles" name="minutes_between_articles" min="1" value="30"> 281 </div> 276 282 </div> 277 283 </div> … … 327 333 <small><?php esc_html_e( 'Format article with bold and italic text (e.g., bold, italic)', 'easy-gpt-for-wp' ); ?></small> 328 334 </p> 335 <p class="easy-gpt-field easy-gpt-inline-bold"> 336 <label for="easy_gpt_include_citations_bulk" class="black-label"><?php esc_html_e( 'Include Citations in Text:', 'easy-gpt-for-wp' ); ?></label> 337 <input type="checkbox" id="easy_gpt_include_citations_bulk" name="easy_gpt_include_citations_bulk" <?php checked( $include_citations_bulk, '1' ); ?> class="adjusted-checkbox"> 338 <small><?php esc_html_e( 'Insert blockquotes with author names when appropriate.', 'easy-gpt-for-wp' ); ?></small> 339 </p> 329 340 <p class="easy-gpt-field easy-gpt-inline-bold"> 330 341 <label for="easy_gpt_include_links" class="black-label"><?php esc_html_e( 'Automatically Insert Links:', 'easy-gpt-for-wp' ); ?></label> … … 374 385 <input type="checkbox" id="easy_gpt_include_excerpt" name="easy_gpt_include_excerpt" <?php checked( $include_excerpt ); ?> class="adjusted-checkbox"> 375 386 </p> 387 <p class="easy-gpt-field easy-gpt-inline-bold"> 388 <label for="easy_gpt_final_review_bulk" class="black-label"><?php esc_html_e( 'Final AI-Based Review:', 'easy-gpt-for-wp' ); ?></label> 389 <input type="checkbox" id="easy_gpt_final_review_bulk" name="easy_gpt_final_review_bulk" <?php checked( $final_review_bulk, '1' ); ?> class="adjusted-checkbox"> 390 <small><?php esc_html_e( 'Run a final AI review to improve coherence and style.', 'easy-gpt-for-wp' ); ?></small> 391 </p> 376 392 <h3><?php esc_html_e( 'Video Settings', 'easy-gpt-for-wp' ); ?></h3> 377 393 … … 513 529 $data['specific_instructions_excerpt'] = isset($_POST['specific_instructions_excerpt']) ? sanitize_textarea_field(wp_unslash($_POST['specific_instructions_excerpt'])) : ''; 514 530 $data['use_same_specific_excerpt_instructions'] = isset($_POST['use_same_specific_excerpt_instructions']) ? intval($_POST['use_same_specific_excerpt_instructions']) : 0; 531 515 532 516 533 … … 553 570 $data['video_position_bulk'] = isset($_POST['easy_gpt_video_position_bulk']) ? sanitize_text_field(wp_unslash($_POST['easy_gpt_video_position_bulk'])) : 'end'; 554 571 $data['video_paragraph_bulk'] = isset($_POST['easy_gpt_video_paragraph_bulk']) ? intval($_POST['easy_gpt_video_paragraph_bulk']) : 3; 572 573 $data['include_citations_bulk'] = isset($_POST['easy_gpt_include_citations_bulk']) ? intval($_POST['easy_gpt_include_citations_bulk']) : 0; 574 $data['final_review_bulk'] = isset($_POST['easy_gpt_final_review_bulk']) ? intval($_POST['easy_gpt_final_review_bulk']) : 0; 575 $data['minutes_between_articles'] = isset($_POST['minutes_between_articles']) ? intval($_POST['minutes_between_articles']) : 0; 576 577 578 579 580 error_log('Valores recibidos para insert (easy_gpt_handle_save_bulk_generation):'); 581 foreach ($data as $key => $value) { 582 error_log("$key => " . var_export($value, true)); 583 } 555 584 556 585 // Inserción en la base de datos … … 607 636 '%s', // video_position_bulk 608 637 '%d', // video_paragraph_bulk 638 '%d', // include_citations_bulk 639 '%d', 640 '%d', 609 641 ); 610 642 -
easy-gpt-for-wp/trunk/includes/easy-gpt-bulk-article-generator.php
r3232882 r3260025 82 82 83 83 // Calcular las fechas programadas 84 $scheduled_dates = easy_gpt_calculate_scheduled_dates($start_date, $start_time, $frequency, $num_articles, $articles_per_interval); 84 $minutes_between_articles = isset($other_params['minutes_between_articles']) ? intval($other_params['minutes_between_articles']) : 0; 85 86 $scheduled_dates = easy_gpt_calculate_scheduled_dates($start_date, $start_time, $frequency, $num_articles, $articles_per_interval, $minutes_between_articles); 85 87 } 86 88 … … 163 165 'include_videos_bulk' => !empty($other_params['include_videos_bulk']), 164 166 'video_position_bulk' => sanitize_text_field($other_params['video_position_bulk']), 165 'video_paragraph_bulk' => intval($other_params['video_paragraph_bulk']) 167 'video_paragraph_bulk' => intval($other_params['video_paragraph_bulk']), 168 'include_citations_bulk' => !empty($other_params['include_citations_bulk']), 169 'final_review_bulk' => !empty($other_params['final_review_bulk']) 166 170 ]; 167 171 … … 171 175 } 172 176 173 function easy_gpt_calculate_scheduled_dates($start_date, $start_time, $frequency, $num_articles, $articles_per_interval ) {177 function easy_gpt_calculate_scheduled_dates($start_date, $start_time, $frequency, $num_articles, $articles_per_interval, $minutes_between) { 174 178 $dates = []; 175 179 $interval_spec = ''; … … 177 181 switch ($frequency) { 178 182 case 'daily': 179 $interval_spec = 'P1D'; // Periodo de 1 día183 $interval_spec = 'P1D'; 180 184 break; 181 185 case 'weekly': 182 $interval_spec = 'P1W'; // Periodo de 1 semana186 $interval_spec = 'P1W'; 183 187 break; 184 188 case 'monthly': 185 $interval_spec = 'P1M'; // Periodo de 1 mes189 $interval_spec = 'P1M'; 186 190 break; 187 191 default: 188 $interval_spec = 'P1D'; // Valor por defecto192 $interval_spec = 'P1D'; 189 193 break; 190 194 } 191 195 192 196 try { 193 $ current_date = new DateTime($start_date . ' ' . $start_time);197 $base_datetime = new DateTime($start_date . ' ' . $start_time); 194 198 } catch (Exception $e) { 195 $ current_date = new DateTime();199 $base_datetime = new DateTime(); 196 200 } 197 201 … … 199 203 200 204 while ($articles_scheduled < $num_articles) { 205 // Clonar el objeto para evitar modificar la base directamente 206 $current_datetime = clone $base_datetime; 207 201 208 for ($i = 0; $i < $articles_per_interval && $articles_scheduled < $num_articles; $i++) { 202 $dates[] = $current_date->format('Y-m-d H:i:s'); 209 // Agregar minutos solo si es el segundo o posterior artículo del mismo intervalo 210 if ($i > 0 && $minutes_between > 0) { 211 $current_datetime->modify("+{$minutes_between} minutes"); 212 } 213 214 $dates[] = $current_datetime->format('Y-m-d H:i:s'); 203 215 $articles_scheduled++; 204 216 } 205 $current_date->add(new DateInterval($interval_spec)); 217 218 // Pasar al siguiente intervalo (día/semana/mes) 219 $base_datetime->add(new DateInterval($interval_spec)); 206 220 } 207 221 208 222 return $dates; 209 223 } 224 210 225 211 226 function easy_gpt_enqueue_article_generation_tasks($generation_id, $article_params) { -
easy-gpt-for-wp/trunk/includes/metaboxes.php
r3254795 r3260025 270 270 if ($include_links === '') { 271 271 $include_links = isset($options['easy_gpt_include_links']) ? $options['easy_gpt_include_links'] : '0'; 272 } 273 274 $include_citations = get_post_meta($post->ID, '_easy_gpt_include_citations', true); 275 if ($include_citations === '') { 276 $include_citations = isset($options['easy_gpt_include_citations']) ? $options['easy_gpt_include_citations'] : '0'; 277 } 278 279 $final_review = get_post_meta($post->ID, '_easy_gpt_final_review', true); 280 if ($final_review === '') { 281 $final_review = isset($options['easy_gpt_final_review']) ? $options['easy_gpt_final_review'] : '0'; 272 282 } 273 283 … … 483 493 <small><?php esc_html_e( 'Format article with bold and italic text (e.g., bold, italic)', 'easy-gpt-for-wp' ); ?></small> 484 494 </p> 495 <p class="easy-gpt-field easy-gpt-inline-bold"> 496 <label for="easy_gpt_include_citations" class="black-label"><?php esc_html_e( 'Include Citations in Text:', 'easy-gpt-for-wp' ); ?></label> 497 <input type="checkbox" id="easy_gpt_include_citations" name="easy_gpt_include_citations" <?php checked( $include_citations ); ?> class="adjusted-checkbox"> 498 <small><?php esc_html_e( 'Insert citations within the body of the article.', 'easy-gpt-for-wp' ); ?></small> 499 </p> 485 500 <p class="easy-gpt-field easy-gpt-inline-bold"> 486 501 <label for="easy_gpt_include_links" class="black-label"><?php esc_html_e( 'Automatically Insert Links:', 'easy-gpt-for-wp' ); ?></label> … … 530 545 <input type="checkbox" id="easy_gpt_include_excerpt" name="easy_gpt_include_excerpt" <?php checked( $include_excerpt ); ?> class="adjusted-checkbox"> 531 546 </p> 547 <p class="easy-gpt-field easy-gpt-inline-bold"> 548 <label for="easy_gpt_final_review" class="black-label"><?php esc_html_e( 'Final AI-Based Review:', 'easy-gpt-for-wp' ); ?></label> 549 <input type="checkbox" id="easy_gpt_final_review" name="easy_gpt_final_review" <?php checked( $final_review ); ?> class="adjusted-checkbox"> 550 <small><?php esc_html_e( 'Request a final AI-based review for the article (it may correct minor errors in the text but slightly increases the API cost).', 'easy-gpt-for-wp' ); ?></small> 551 </p> 552 532 553 <h3><?php esc_html_e( 'Video Settings', 'easy-gpt-for-wp' ); ?></h3> 533 554 … … 676 697 $new_video_position_per_post = isset($_POST['easy_gpt_video_position_per_post']) ? sanitize_text_field(wp_unslash($_POST['easy_gpt_video_position_per_post'])) : 'end'; 677 698 $new_video_paragraph_per_post = isset($_POST['easy_gpt_video_paragraph_per_post']) ? intval($_POST['easy_gpt_video_paragraph_per_post']) : 3; 678 699 $new_include_citations = isset($_POST['easy_gpt_include_citations']) ? '1' : '0'; 700 $new_final_review = isset($_POST['easy_gpt_final_review']) ? '1' : '0'; 679 701 680 702 // Actualizar los campos meta en la base de datos. … … 708 730 update_post_meta($post_id, '_easy_gpt_video_position_per_post', $new_video_position_per_post); 709 731 update_post_meta($post_id, '_easy_gpt_video_paragraph_per_post', $new_video_paragraph_per_post); 732 update_post_meta($post_id, '_easy_gpt_include_citations', $new_include_citations); 733 update_post_meta($post_id, '_easy_gpt_final_review', $new_final_review); 734 710 735 } 711 736 … … 855 880 $after_paragraph = isset($_POST['easy_gpt_video_paragraph_per_post']) ? max(1, intval($_POST['easy_gpt_video_paragraph_per_post'])) : 3; 856 881 882 $include_citations = isset($_POST['easy_gpt_include_citations']) ? '1' : '0'; 883 $final_review = isset($_POST['easy_gpt_final_review']) ? '1' : '0'; 884 857 885 858 886 // Construir instrucciones adicionales 859 887 $links_instructions = $includeLinks 860 ? " If necessary, you can insert links using <a> </a> tags to justify data or claims, recommendations in the middle of the text. For example, 'according to a study made by <a>...'</a>. If possible, use the name for the link, but do not say 'for more information'."888 ? " You can insert links using <a> </a> tags to justify data or claims, recommendations in the middle of the text. For example, 'according to a study made by <a>...'</a>. If possible, use the name for the link, but do not say 'for more information'." 861 889 : ""; 862 890 … … 881 909 $entity_type = $is_product ? "product" : "article"; 882 910 883 $intro_prompt = "Generate an introduction for a {$entity_type} titled '{$title}' with the following details, formatted with <p> tags for each paragraph{$format_instructions} (only return the introduction):\n" .911 $intro_prompt = "Generate an introduction for a {$entity_type} titled '{$title}' with the following details, formatted with <p> tags for each paragraph{$format_instructions}, do not include the title in the introducction, do not use # or * and <html> tag, (only return the introduction):\n" . 884 912 "Prompt: {$prompt}\n" . 885 913 "Keywords: {$keywords}\n" . … … 938 966 $max_words_per_section = $num_sections > 0 ? $max_words / $num_sections : $max_words; 939 967 968 969 970 $citation_instructions = $include_citations 971 ? " and blockquotes (`<i>`) (blockquotes only if necesary) with the autor name (like real) where relevant." 972 : "."; 973 974 $citation_instructions2 = $include_citations 975 ? ", blockquotes (with the person of the quote), " 976 : " "; 977 978 979 940 980 foreach ($h2_sections as $index => $h2_section) { 941 981 error_log("Generando..."); … … 948 988 } 949 989 950 $section_prompt = "Generate a detailed section for the {$entity_type} titled '{$title}'. Include the following details:\n" . 951 "Section Title: {$h2_title}\n" . 952 "Subheadings:\n{$h3_h4}\n" . 953 "Format the {$entity_type} using tags, like <h2> for section title, <p> for paragraphs, <h3>, <h4> for subheadings, <ul><li> for lists... {$format_instructions}, do not write <html>.\n" . 954 "Prompt: {$prompt}\n" . 955 "Keywords: {$keywords}\n" . 956 "Specific Instructions: {$specific_instructions_content}\n" . 957 "Language: {$language}\n" . 958 "Style: {$writing_style}\n" . 959 "Tone: {$writing_tone}\n" . 960 "Note: This is a section of a larger {$entity_type}. Begin with an introduction (an introduction for the section, not a subheading), follow with detailed content under each subheading, and do not include conclusions or summaries.\n" . 961 "Word Limit: This section should contain at least {$min_words_per_section} words and no more than {$max_words_per_section} words. Do not use this symbol #.\n" . 962 $links_instructions; 990 //error_log("Contenido previo - ". $index . ": ". $previous_content); 991 $previous_content = implode("\n", $responses); // Unir todo lo generado hasta el momento 992 993 994 $section_prompt = "Continue writing the article about {$entity_type} titled '{$title}', ensuring a smooth transition from the previous sections. Avoid repeating general information already covered. 995 996 Previously written sections:\n{$previous_content}\n 997 998 Generate a detailed section with the following details: 999 1000 - Section Title: {$h2_title} 1001 - Subheadings: {$h3_h4} 1002 - Format: Use proper HTML tags, like <h2> for section titles, <h3>, <h4> for subheadings, <p> for paragraphs, and <ul><li> for lists, and <blockquote> for quotes. {$format_instructions}. 1003 - Do not use # and <html> tag. 1004 - Important: In the section Apply bold <b> for key concepts, important phrases, and crucial data. 1005 - Apply italics <i> to scientific terms, foreign words... 1006 - Incorporate lists (`<ul><li>`){$citation_instructions} 1007 - Ensure these formatting elements appear naturally throughout the entire section, not just in the introduction or conclusion. 1008 - Before introducing any `<h3>` or `<h4>`, ensure there is a short introductory paragraph (2-3 sentences) explaining what will be covered in the subsection. 1009 1010 --- 1011 1012 Refining Introductions and Transitions: 1013 * Vary how the section starts: Instead of beginning with a direct statement about the topic, consider alternative openings: 1014 - Ask a rhetorical question to engage the reader. 1015 - Use an intriguing fact or statistic to draw attention. 1016 - Introduce a brief anecdote or historical reference (if relevant). 1017 - Make a comparison or contrast with another related concept. 1018 *Avoid starting multiple sections or paragraphs with the same noun or phrase. Instead, use synonyms, rephrase, or introduce the idea in a different way. 1019 *Make transitions natural and fluid, do not use always the same, variety 1020 *Ensure logical connections between subtopics, so the article flows smoothly rather than feeling fragmented. 1021 1022 --- 1023 1024 The section must begin with a short, engaging introduction that: 1025 - Do not start by repeating the article’s main topic. 1026 - Introduce the section in a natural and engaging way to maintain reader interest. 1027 - Avoid generic phrasing—connect the section to the broader article context. 1028 - You can use a rhetorical question. 1029 1030 Detailed Section Development 1031 - Expand each subheading into 2-4 paragraphs. 1032 - Use lists{$citation_instructions2}or tables when appropriate to improve readability. 1033 - Introduce new insights rather than restating previous content. 1034 - Add real-world examples, statistics, or historical context where relevant. 1035 - {$links_instructions} 1036 1037 --- 1038 1039 ### Enhancing Readability and Style 1040 - Avoid repetitive sentence structures (e.g., multiple paragraphs starting with the same noun or phrase). 1041 - If a keyword (singular or plural) appeared in the first 20 words of the last 3 paragraphs, avoid it in the new paragraph. 1042 - Diversify sentence structures: Mix short and long sentences, use subordinate clauses, and include comparisons or rhetorical questions. 1043 - Ensure a smooth, engaging flow that keeps the reader interested. 1044 - Use proper linking phrases for smooth transitions between subtopics. 1045 1046 --- 1047 1048 Formatting Consistency 1049 Ensure proper distribution of formatting elements: 1050 - Bold (`<b>`) should emphasize key facts, not entire sentences. 1051 - Italics (`<i>`) should highlight technical terms and foreign words. 1052 - Lists and blockquotes should naturally complement the content, rather than being forced in. 1053 - Dont use ** or *, use <b> or <i> insteed 1054 1055 --- 1056 1057 - Prompt: {$prompt} 1058 - Keywords: {$keywords} 1059 - Specific Instructions: {$specific_instructions_content} 1060 - Language: {$language} 1061 - Style: {$writing_style} 1062 - Tone: {$writing_tone} 1063 1064 - Do not forget Apply bold <b> for key concepts, important phrases, and crucial data. 1065 - Word Limit: Between {$min_words_per_section} and {$max_words_per_section} words. 1066 1067 {$links_instructions}"; 1068 1069 1070 1071 //error_log($section_prompt); 963 1072 964 1073 $response = easy_gpt_call_openai_api($section_prompt, $model, $temperature, $api_key, $post_id); … … 983 1092 } 984 1093 985 $conclusion_prompt = "Generate a conclusion for a {$entity_type} titled '{$title}' with the following details, formatted with <p> tags for each paragraph{$format_instructions}, give it a <h2> heading:\n" . 986 "Prompt: {$prompt}\n" . 987 "Keywords: {$keywords}\n" . 988 "Language: {$language}\n" . 989 "Writing Style: {$writing_style}\n" . 990 "Tone: {$writing_tone}\n" . 991 "Maximum Words for the conclusion: 200 words.\n" . 992 $bibliography_instructions; 1094 $previous_content = implode("\n", $responses); // Unir todo el contenido generado antes de la conclusión 1095 1096 $conclusion_prompt = "Generate a strong conclusion for a {$entity_type} titled '{$title}'. The conclusion should summarize the main insights without repeating detailed information already covered. Ensure a natural and engaging closing statement. 1097 1098 Previously written content:\n{$previous_content}\n 1099 1100 Consider the key points from this outline: {$outline}. Format the conclusion with <p> tags for each paragraph{$format_instructions}. Provide a <h2> heading that naturally summarizes the key message of the conclusion, avoiding generic titles like 'Conclusion'.\n 1101 1102 Prompt: {$prompt}\n 1103 Keywords: {$keywords}\n 1104 Language: {$language}\n 1105 Writing Style: {$writing_style}\n 1106 Tone: {$writing_tone}\n 1107 Maximum Words for the conclusion: 200 words.\n 1108 {$bibliography_instructions}"; 993 1109 994 1110 … … 1003 1119 1004 1120 1005 // Manejar la opción 'after_paragraph' 1006 if (!empty($video_url) && $include_video && $video_position === 'after_paragraph') { 1007 $full_article = implode("", $responses); 1008 // Usar preg_split para mantener las etiquetas <p> 1009 $paragraphs = preg_split('/(<p\b[^>]*>.*?<\/p>)/i', $full_article, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 1010 1011 1012 error_log("Total paragraphs found: " . count($paragraphs)); 1013 error_log("After paragraph number: " . $after_paragraph); 1014 1015 // Validar el número de párrafos 1016 if ($after_paragraph > 0 && $after_paragraph <= count($paragraphs)) { 1017 // Insertar el video después del párrafo especificado 1018 // $after_paragraph es 1-based, ajustar a 0-based 1019 $insert_index = $after_paragraph; // Como cada párrafo está en un índice separado 1020 if (isset($paragraphs[$insert_index])) { 1021 array_splice($paragraphs, $insert_index, 0, "\n<p>{$video_url}</p>\n"); 1022 error_log("Inserted video after paragraph {$after_paragraph}."); 1023 } else { 1024 // Fallback en caso de que no exista el índice 1025 $paragraphs[] = "\n<p>{$video_url}</p>\n"; 1026 error_log("Paragraph index {$insert_index} not found. Inserted video at the end."); 1027 } 1028 } else { 1029 // Si el número de párrafos es mayor o igual, insertar al final antes de la conclusión 1030 $paragraphs[] = "\n<p>{$video_url}</p>\n"; 1031 error_log("After paragraph number {$after_paragraph} exceeds paragraph count. Inserted video at the end."); 1032 } 1033 1034 $full_article = implode("", $paragraphs); 1035 } else { 1036 $full_article = implode("", $responses); 1037 } 1121 $full_article = implode("\n", $responses); 1122 1123 if ($final_review) { 1124 // 📌 **Paso adicional: Revisar el artículo después de la conclusión pero antes del video** 1125 $review_prompt = "Here is a complete article about {$entity_type} titled '{$title}'. Review and refine it to improve coherence, eliminate redundancies, and ensure a more natural flow. 1126 1127 Previously written content:\n{$full_article}\n 1128 1129 Instructions for Refinement: 1130 - Each section (H2) must start with a short, engaging introduction (2-3 sentences) if missing. 1131 - Ensure a logical transition between sections and subheadings (H3, H4). 1132 - Avoid repetitive sentence structures: Do not start multiple paragraphs with the same noun or phrase. 1133 - Reword initial sentences to introduce variety while keeping the meaning intact. 1134 - Do not add new information—only refine and optimize existing content. 1135 - Summarize the conclusion concisely without repeating details already covered. 1136 - Use bold (`<b>`) for key concepts, important phrases, and crucial data. 1137 - Apply italics (`<i>`) to scientific terms, foreign words... 1138 - Use <a> for links 1139 - If there are ** or * change per <b> or <i> tags 1140 1141 Formatting Instructions: 1142 - Maintain proper structure using <h2> for section titles, <h3> and <h4> for subheadings, <p> for paragraphs, and <ul><li> for lists and <i> for quotes, {$format_instructions}, do not write <html> tag. 1143 - If a YouTube URL is present, leave it unchanged. 1144 1145 Only return the article 1146 1147 Article for Review: 1148 {$full_article}"; 1149 1150 1151 $review_response = easy_gpt_call_openai_api($review_prompt, $model, $temperature, $api_key, $post_id); 1152 1153 if (!$review_response) { 1154 wp_send_json_error(['message' => "Failed to review the article"]); 1155 wp_die(); 1156 } 1157 1158 // Reemplazar el contenido con la versión revisada 1159 $full_article = $review_response['text']; 1160 } 1161 1162 // 📌 **Solo ahora, insertar el video si corresponde** 1163 if (!empty($video_url) && $include_video && $video_position === 'after_paragraph') { 1164 $paragraphs = preg_split('/(<p\b[^>]*>.*?<\/p>)/i', $full_article, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 1165 1166 error_log("Total paragraphs found: " . count($paragraphs)); 1167 error_log("After paragraph number: " . $after_paragraph); 1168 1169 // Validar el número de párrafos 1170 if ($after_paragraph > 0 && $after_paragraph <= count($paragraphs)) { 1171 // Insertar el video después del párrafo especificado 1172 $insert_index = $after_paragraph; 1173 if (isset($paragraphs[$insert_index])) { 1174 array_splice($paragraphs, $insert_index, 0, "\n<p>{$video_url}</p>\n"); 1175 error_log("Inserted video after paragraph {$after_paragraph}."); 1176 } else { 1177 $paragraphs[] = "\n<p>{$video_url}</p>\n"; 1178 error_log("Paragraph index {$insert_index} not found. Inserted video at the end."); 1179 } 1180 } else { 1181 $paragraphs[] = "\n<p>{$video_url}</p>\n"; 1182 error_log("After paragraph number {$after_paragraph} exceeds paragraph count. Inserted video at the end."); 1183 } 1184 1185 $full_article = implode("", $paragraphs); 1186 } 1038 1187 1039 1188 wp_send_json_success([ … … 1080 1229 "Writing Style: {$writing_style}\n" . 1081 1230 "Tone: {$writing_tone}\n" . 1082 "Maximum Words for the excerpt: 60 words. ";1231 "Maximum Words for the excerpt: 60 words. Do not include the title in the excerpt."; 1083 1232 1084 1233 … … 1786 1935 1787 1936 // Construir la URL con parámetros mejorados 1788 $api_url = "https://www.googleapis.com/youtube/v3/search?part=snippet&q={$encoded_query}&type=video&maxResults=3&order=relevance&relevanceLanguage=" . strtolower($language) . "&key={$api_key}";1937 $api_url = "https://www.googleapis.com/youtube/v3/search?part=snippet&q={$encoded_query}&type=video&maxResults=3&order=relevance&videoDuration=long&relevanceLanguage=" . strtolower($language) . "&key={$api_key}"; 1789 1938 1790 1939 error_log("YouTube API Request: " . urldecode($api_url)); // Log para depuración -
easy-gpt-for-wp/trunk/includes/settings-functions.php
r3257086 r3260025 136 136 'easy_gpt_article_settings_section' 137 137 ); 138 139 add_settings_field( 140 'easy_gpt_include_citations', 141 'Include Citations in Text', 142 'easy_gpt_include_citations_render', 143 'easy-gpt-settings', 144 'easy_gpt_article_settings_section' 145 ); 138 146 139 147 add_settings_field( … … 255 263 'easy_gpt_article_settings_section' 256 264 ); 265 266 add_settings_field( 267 'easy_gpt_final_review', 268 'Final Review (Optional)', 269 'easy_gpt_final_review_render', 270 'easy-gpt-settings', 271 'easy_gpt_article_settings_section' 272 ); 257 273 258 274 add_settings_field( … … 705 721 'easy_gpt_include_excerpt', 706 722 'easy_gpt_set_featured_image', 723 'easy_gpt_include_citations', 724 'easy_gpt_final_review', 707 725 ]; 708 726 … … 1190 1208 echo "<p><small>Set the maximum age (in days) of a comment that will be processed for auto reply (default: 7 days).</small></p>"; 1191 1209 } 1210 1211 function easy_gpt_include_citations_render() { 1212 $options = get_option('easy_gpt_options'); 1213 $value = isset($options['easy_gpt_include_citations']) ? $options['easy_gpt_include_citations'] : '0'; 1214 echo "<input type='checkbox' name='easy_gpt_options[easy_gpt_include_citations]' value='1' " . checked($value, '1', false) . ">"; 1215 echo "<small>Check this box to include in-text citations throughout the article.</small>"; 1216 } 1217 1218 function easy_gpt_final_review_render() { 1219 $options = get_option('easy_gpt_options'); 1220 $value = isset($options['easy_gpt_final_review']) ? $options['easy_gpt_final_review'] : '0'; 1221 echo "<input type='checkbox' name='easy_gpt_options[easy_gpt_final_review]' value='1' " . checked($value, '1', false) . ">"; 1222 echo '<small>' . esc_html__('Request a final AI-based review for the article (it may correct minor errors in the text but slightly increases the API cost).', 'easy-gpt-for-wp') . '</small>'; 1223 1224 } -
easy-gpt-for-wp/trunk/js/bulk-generation.js
r3253315 r3260025 180 180 'easy_gpt_video_position_bulk': $('#easy_gpt_video_position_bulk').val(), 181 181 'easy_gpt_video_paragraph_bulk': $('#easy_gpt_video_paragraph_bulk').val(), 182 'easy_gpt_include_citations_bulk': $('#easy_gpt_include_citations_bulk').is(':checked') ? 1 : 0, 183 'easy_gpt_final_review_bulk': $('#easy_gpt_final_review_bulk').is(':checked') ? 1 : 0, 184 'minutes_between_articles': $('#minutes_between_articles').val(), 182 185 }; 183 186 … … 292 295 293 296 }); 297 298 jQuery(document).ready(function($) { 299 $('#articles_per_interval').on('input change', function() { 300 const value = parseInt($(this).val(), 10); 301 if (value > 1) { 302 $('#minutes_between_articles_container').slideDown(); 303 } else { 304 $('#minutes_between_articles_container').slideUp(); 305 } 306 }).trigger('change'); // Ejecutar una vez al cargar la página 307 }); -
easy-gpt-for-wp/trunk/js/easy-gpt-custom.js
r3254795 r3260025 491 491 easy_gpt_include_videos_per_post: include_videos_per_post, 492 492 easy_gpt_video_position_per_post: video_position_per_post, 493 easy_gpt_video_paragraph_per_post: video_paragraph_per_post 493 easy_gpt_video_paragraph_per_post: video_paragraph_per_post, 494 easy_gpt_include_citations: $('#easy_gpt_include_citations').is(':checked') ? '1' : '0', 495 easy_gpt_final_review: $('#easy_gpt_final_review').is(':checked') ? '1' : '0' 494 496 }; 495 497 -
easy-gpt-for-wp/trunk/readme.txt
r3257086 r3260025 5 5 Tested up to: 6.7.2 6 6 Requires PHP: 7.3 7 Stable tag: 1.1 27 Stable tag: 1.13 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 134 134 135 135 == Changelog == 136 = 1.13 = 137 * Improved the quality of generated articles. 138 * Added support for automatic citation inclusion within articles. 139 * Introduced an optional final review step before publishing generated content. 140 * Enhanced batch generation with control over the time interval between same-day articles. 141 * Improved YouTube video selection for better content relevance. 142 136 143 = 1.12 = 137 144 * Added AI-powered comment moderation.
Note: See TracChangeset
for help on using the changeset viewer.