PluginProbe
BotWriter – AI Writer & SEO Content Generator / 3.4.9
BotWriter – AI Writer & SEO Content Generator v3.4.9
3.4.10 3.4.9 3.4.8 3.4.7 3.4.6 3.4.4 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 3.3.0 3.2.8 trunk 1.3.0 1.3.1 1.3.2 1.3.3 All 51 releases
botwriter / includes / super.php

super.php in BotWriter – AI Writer & SEO Content Generator 3.4.9, at includes/super.php

1,045 lines 44.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 function botwriter_super_page_handler(){
7 // Verify user has permission
8 if (!current_user_can('manage_options')) {
9 wp_die(esc_html__('You do not have permission to access this page.', 'botwriter'));
10 }
11
12 global $wpdb;
13 $message = '';
14 $notice = '';
15
16
17 $is_editing = isset($_REQUEST['id']) && intval($_REQUEST['id']) > 0;
18 if ($is_editing) {
19 $id = intval($_REQUEST['id']);
20 $super1status=$id;
21 } else {
22 $super1status=botwriter_super1_check_task_finish();
23 }
24
25
26
27
28 $table_name = $wpdb->prefix . 'botwriter_tasks';
29 $dir_images = plugin_dir_url(dirname(__FILE__)) . '/assets/images/';
30
31
32 ?>
33 <?php $super_mode = isset($_GET['mode']) && $_GET['mode'] === 'manual' ? 'manual' : 'auto'; ?>
34 <input type="hidden" id="super1status" name="super1status" value="<?php echo esc_attr($super1status); ?>">
35 <input type="hidden" id="super_mode" name="super_mode" value="<?php echo esc_attr($super_mode); ?>">
36 <div class="wrap">
37
38
39 <div class="icon32 icon32-posts-post" id="icon-edit"><br></div>
40
41 <?php // by default and process the form data
42 $default = array(
43 'id' => 0,
44 /* translators: %d: next super task number */
45 'task_name' => sprintf(__('Super Task %d', 'botwriter'), $wpdb->get_var("SELECT COUNT(*) FROM $table_name WHERE website_type LIKE 'super%'") + 1),
46 'writer' => 'ai_cerebro',
47 'narration' => 'Descriptive',
48 'custom_style' => '',
49 'post_language' => '',
50 'post_length' => '800',
51 'custom_post_length' => '',
52 'post_status' => 'publish',
53 'days' => '',
54 'times_per_day' => 1,
55 'execution_count' => 0, // Initialize execution count to zero
56 'last_execution_date' => gmdate('Y-m-d H:i:s', current_time('timestamp')), // Set last execution date to null initially
57 'website_type' => 'ai',
58
59 'website_name' => '',
60 'domain_name' => '',
61 'category_id' => '0',
62 'website_category_id' => '',
63 'website_category_name' => '',
64 'aigenerated_title' => '',
65 'aigenerated_content' => '',
66 'aigenerated_tags' => '',
67 'aigenerated_image' => '',
68 'post_count' => '',
69 'post_order' => '',
70 'title_prompt' => '',
71 'content_prompt' => '',
72 'tags_prompt' => '',
73 'image_prompt' => '',
74 'image_generating_status' => '',
75 'author_selection' => '',
76
77 'news_keyword' => '',
78 'news_country' => '',
79 'news_language' => '',
80 'news_time_published' => '',
81 'news_source' => '',
82 'rss_source' => '',
83 'ai_keywords' => '',
84 'disable_ai_images' => 0,
85 'template_id' => null,
86
87
88
89
90 );
91
92
93 if ( isset($_REQUEST['nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['nonce'])), basename(__FILE__))) {
94
95 /*
96 echo "<pre>";
97 print_r($_POST);
98 echo "</pre>";
99 */
100
101 $days = isset($_POST['days']) ? implode(",", array_map('sanitize_text_field', wp_unslash($_POST['days']))) : "";
102 $times_per_day = isset($_POST['times_per_day']) ? intval(wp_unslash($_POST['times_per_day'])) : 1;
103
104
105 // Process only the specific values needed
106 $item = array(
107 'id' => isset($_POST['id']) ? intval(wp_unslash($_POST['id'])) : 0,
108
109 'task_name' => isset($_POST['task_name']) ? sanitize_text_field(wp_unslash($_POST['task_name'])) : '',
110 'post_status' => isset($_POST['post_status']) ? sanitize_text_field(wp_unslash($_POST['post_status'])) : '',
111 'days' => $days,
112 'times_per_day' => $times_per_day,
113 'writer' => 'ai_cerebro',
114 'narration' => isset($_POST['narration']) ? sanitize_text_field(wp_unslash($_POST['narration'])) : '',
115 'post_length' => isset($_POST['post_length']) ? sanitize_text_field(wp_unslash($_POST['post_length'])) : '',
116 'custom_post_length'=> isset($_POST['custom_post_length']) ? sanitize_text_field(wp_unslash($_POST['custom_post_length'])) : '',
117 'custom_style' => isset($_POST['custom_style']) ? sanitize_text_field(wp_unslash($_POST['custom_style'])) : '',
118 'post_language' => isset($_POST['post_language']) ? sanitize_text_field(wp_unslash($_POST['post_language'])) : '',
119
120 'website_type' => 'super2',
121 'website_name' => '',
122 'domain_name' => isset($_POST['domain_name']) ? sanitize_url(wp_unslash($_POST['domain_name'])) : '',
123 'category_id' => isset($_POST['category_id']) ? sanitize_text_field(wp_unslash($_POST['category_id'])) : '0',
124 'website_category_id'=> '',
125 'website_category_name'=> '',
126 'aigenerated_title' => '',
127 'aigenerated_content'=> '',
128 'aigenerated_tags' => '',
129 'aigenerated_image' => '',
130 'post_count' => 5,
131 'post_order' => '',
132 'title_prompt' => '',
133
134 'content_prompt' => '',
135
136 'tags_prompt' => '',
137 'image_prompt' => '',
138 'image_generating_status' => '',
139
140 'author_selection' => isset($_POST['author_selection']) ? sanitize_text_field(wp_unslash($_POST['author_selection'])) : '',
141
142 'news_keyword' => isset($_POST['news_keyword']) ? sanitize_text_field(wp_unslash($_POST['news_keyword'])) : '',
143 'news_country' => isset($_POST['news_country']) ? sanitize_text_field(wp_unslash($_POST['news_country'])) : '',
144 'news_language' => isset($_POST['news_language']) ? sanitize_text_field(wp_unslash($_POST['news_language'])) : '',
145 'news_time_published' => isset($_POST['news_time_published']) ? sanitize_text_field(wp_unslash($_POST['news_time_published'])) : '',
146 'news_source' => isset($_POST['news_source']) ? sanitize_text_field(wp_unslash($_POST['news_source'])) : '',
147
148 'rss_source' => isset($_POST['rss_source']) ? sanitize_text_field(wp_unslash($_POST['rss_source'])) : '',
149 'ai_keywords' => isset($_POST['ai_keywords']) ? sanitize_text_field(wp_unslash($_POST['ai_keywords'])) : '',
150 'disable_ai_images' => isset($_POST['disable_ai_images']) ? intval(wp_unslash($_POST['disable_ai_images'])) : 0,
151 'template_id' => isset($_POST['template_id']) && !empty($_POST['template_id']) ? intval(wp_unslash($_POST['template_id'])) : null
152
153 );
154
155
156
157
158
159
160 //$item_valid = botwriter_validate_website($item);
161 $item_valid = true;
162 if ($item_valid === true) {
163
164
165 //$item = array_map('sanitize_text_field', $item); // Sanitize all inputs
166 if ($item['id'] == 0) {
167 // Do not insert primary key 'id' explicitly to allow AUTO_INCREMENT to work
168 $insert_data = $item;
169 unset($insert_data['id']);
170 $result = $wpdb->insert($table_name, $insert_data);
171
172 //echo "<h1>" . $wpdb->last_error . "</h1> ";
173
174 $item['id'] = $wpdb->insert_id;
175
176
177
178 if ($result) {
179 $message = __('New task was successfully saved!', 'botwriter');
180 // asignamos el id de la tarea
181 botwriter_super_assign_id_task($item['id']);
182 // y borramos el log, solo puede haber 1 tarea super1
183 $wpdb->delete($wpdb->prefix . 'botwriter_logs', array('website_type' => 'super1'));
184 ?>
185 <div id="redirecion" data-url="<?php echo esc_url( admin_url('admin.php?page=botwriter_automatic_posts') ); ?>"></div>
186 <?php
187
188
189 } else {
190 $notice = __('There was an error while saving item', 'botwriter');
191 }
192 } else {
193 $result = $wpdb->update($table_name, $item, array('id' => $item['id']));
194
195
196 if ($result !== false) {
197 if ($result === 0) {
198 $message = __('It was successfully updated', 'botwriter');
199 ?>
200 <div id="redirecion" data-url="<?php echo esc_url( admin_url('admin.php?page=botwriter_automatic_posts') ); ?>"></div>
201 <?php
202
203 } else {
204 $message = __('It was successfully updated!', 'botwriter');
205 ?>
206 <div id="redirecion" data-url="<?php echo esc_url( admin_url('admin.php?page=botwriter_automatic_posts') ); ?>"></div>
207 <?php
208 }
209 } else {
210 $notice = __('There was an error while updating item: ', 'botwriter') . $wpdb->last_error;
211 }
212 }
213 } else {
214
215 $notice = $item_valid;
216 }
217 }
218 else {
219
220 $item = $default;
221 if (isset($_REQUEST['id'])) {
222 $sanitized_id = absint($_REQUEST['id']); // Sanitize as an integer
223 $item = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $sanitized_id), ARRAY_A);
224 if (!$item) {
225 $item = $default;
226 $notice = __('Item not found', 'botwriter');
227 }
228 }
229
230 }
231 // end of process the form data
232 ?>
233
234
235
236 <?php
237 $title_text = $is_editing ? __('Edit Super Task', 'botwriter') : __('Add New Super Task', 'botwriter');
238 ?>
239 <h2><?php echo esc_html($title_text); ?> <a class="add-new-h2"
240 href="<?php echo esc_url(get_admin_url(get_current_blog_id(), 'admin.php?page=botwriter_automatic_posts')); ?>"><?php esc_html_e('Back to List', 'botwriter'); ?></a>
241 </h2>
242
243 <?php if (!empty($notice)): ?>
244 <div id="notice" class="error"><p><?php echo esc_attr($notice) ?></p></div>
245 <?php endif;?>
246 <?php if (!empty($message)): ?>
247 <div id="message" class="updated"><p><?php echo esc_attr($message) ?></p></div>
248 <?php endif;?>
249
250
251 <?php if (botwriter_super1_check_first_time()){ ?>
252
253 <div class="super-task-welcome-box">
254 <h3>First Time! Welcome to the Super Task AI!</h3>
255 <p>Super Task AI is a powerful tool that allows you to create a large number of articles in a few seconds. You can choose from predefined article packs or create a custom pack. The AI will generate titles and summaries for your articles based on your blog content. You can customize the prompts or use the default ones.</p>
256 <h4>The first time Botwriter proposes some articles to improve your blog, review them below and save the task.</h4>
257 </div>
258
259 <?php } ?>
260
261 <?php if (!$is_editing) { ?>
262
263 <div class="super-content">
264 <h2 class="super-title"><?php echo $super_mode === 'manual' ? 'Manual titles for articles' : 'Creation of titles and summaries for articles'; ?></h2>
265 <p class="super-text"><?php echo $super_mode === 'manual' ? 'Paste your list of titles and the AI will write the articles.' : 'Choose a predefined one or customize.'; ?></p>
266
267 <div id="new_supertask">
268 <div class="super-ia">
269
270
271 <div class="super-ia-image">
272 <img src="<?php echo esc_url($dir_images . 'ai_cerebro.png'); ?>" alt="<?php echo esc_attr__('AI', 'botwriter'); ?>"<?php echo $super_mode === 'manual' ? ' style="filter: hue-rotate(90deg);"' : ''; ?>>
273 </div>
274
275 <form id="form_super1" name="form_super1">
276 <div class="col-md-6">
277 <label for="super1">Select the type of article pack:</label>
278 <select id="super1_prompt" name="super1_prompt">
279 <option value="Pack of Blog Improvement Articles">Pack of Blog Improvement Articles</option>
280 <option value="Pack of Tutorial/Step-by-Step Articles">Pack of Tutorial/Step-by-Step Articles</option>
281 <option value="Pack of Tips, Tricks, and Recommendations Articles">Pack of Tips, Tricks, and Recommendations Articles</option>
282 <option value="Pack of Reviews, Buying Guides, etc.">Pack of Reviews, Buying Guides, etc.</option>
283 <option value="Custom">Custom Pack</option>
284 <option value="Manual"<?php echo $super_mode === 'manual' ? ' selected' : ''; ?>>Manual Titles</option>
285 </select>
286 <p class="form-text">Choose a pack and the AI will automatically propose articles based on your blog content. Choose Custom Pack for a custom prompt, or Manual Titles to paste your own list.</p>
287
288 </div>
289
290
291 <div class="col-md-6" id="customPromptInput" style="display: none;">
292 <label for="custom_prompt">Custom Prompt:</label>
293 <textarea id="super1_custom_prompt" name="super1_custom_prompt" rows="4" cols="50" placeholder="For example: Articles about pet care or Articles about the solar system, etc"></textarea>
294 <br><br>
295 </div>
296
297 <div class="col-md-6" id="manualTitlesInput" style="display: none;">
298 <label for="manual_titles">List of Titles (one per line):</label>
299 <textarea id="super1_manual_titles" name="super1_manual_titles" rows="10" cols="50" placeholder="How to train your dog&#10;Best recipes for beginners&#10;10 tips for better sleep&#10;..."></textarea>
300 <br><br>
301 <label for="manual_global_prompt">Global Instructions/Prompt (Optional):</label>
302 <textarea id="super1_manual_global_prompt" name="super1_manual_global_prompt" rows="4" cols="50" placeholder="Optional: Write in a friendly tone, include practical examples, etc."></textarea>
303 <br><br>
304 </div>
305
306
307 <div class="col-md-6" id="div_category_id" style="display: none;">
308 <label for="category_id" class="form-label">Category:</label>
309 <select id="category_id" name="category_id" required class="form-select">
310 <?php
311 $selected_category = 0;
312 $categories = get_categories(array(
313 'orderby' => 'name',
314 'order' => 'ASC',
315 'hide_empty' => false
316 ));
317
318 foreach ($categories as $category) {
319 if (isset($selected_categories) && in_array($category->term_id, $selected_categories)) {
320 echo '<option value="' . esc_attr($category->term_id) . '" selected>' . esc_html($category->name) . '</option>';
321 continue;
322 }
323 echo '<option value="' . esc_attr($category->term_id) . '">' . esc_html($category->name) . '</option>';
324 }
325 ?>
326 </select>
327 <p class="form-text">Select one category where the posts will be published.</p>
328
329 </div>
330
331
332 <div class="col-md-6" id="div_numarticles">
333 <label for="super1number">Number of Articles (1-50max):</label>
334 <input type="number" id="super1_numarticles" name="super1_numarticles" value="10" min="1" max="50"><br>
335
336 </div>
337 <br>
338 <button id="super1button_createtask" name="super1button_createtask">Create Titles</button>
339
340 <!-- Rate-limit advisory for Super Tasks -->
341 <div class="bw-supertask-tier-warning">
342 <span class="dashicons dashicons-info"></span>
343 <div>
344 <strong><?php esc_html_e('Super Tasks Advisory', 'botwriter'); ?></strong>
345 <p><?php esc_html_e('Super Tasks generate multiple articles in sequence, which sends many requests to your AI provider in a short time. Some providers enforce rate limits that may interrupt the batch.', 'botwriter'); ?></p>
346 <p><?php esc_html_e('For best results:', 'botwriter'); ?></p>
347 <ul>
348 <li><?php esc_html_e('Ensure your API key has sufficient rate allowance for your provider', 'botwriter'); ?></li>
349 <li><?php esc_html_e('Or use regular scheduled tasks to spread requests over time', 'botwriter'); ?></li>
350 </ul>
351 </div>
352 </div>
353
354 </form>
355 </div>
356
357 </div>
358 <div id="label countup"></div><div id='countup'></div>
359
360 </div>
361 <?php } ?>
362
363
364
365 <div id='resultados'>
366 <?php
367 // si es editing que sea vea el html
368 if ($is_editing) {
369 echo wp_kses_post(botwriter_super1_view_articles_html($id));
370 }
371 ?>
372 </div>
373
374
375
376 <?php
377
378
379 add_meta_box('botwriter_super_form_meta_box', __('Super Task Properties', 'botwriter'), 'botwriter_super_form_meta_box_handler', 'botwriter_super_post_new', 'normal', 'default');
380
381 if ($is_editing) {
382 $display_form_part2 = 'block';
383 } else {
384 $display_form_part2 = 'none';
385 }
386 ?>
387
388 <div id="form_part2" style="display: <?php echo esc_attr($display_form_part2); ?>;">
389 <form id="form" method="POST">
390 <input type="hidden" name="nonce" value="<?php echo esc_attr(wp_create_nonce(basename(__FILE__))); ?>"/>
391 <input type="hidden" name="id" value="<?php echo esc_attr($item['id']) ?>"/>
392 <div class="metabox-holder" id="poststuff">
393 <div id="post-body">
394 <div id="post-body-content">
395 <?php do_meta_boxes('botwriter_super_post_new', 'normal', $item); ?>
396 <input type="submit" value="<?php esc_attr_e('Save', 'botwriter')?>" id="submit" class="button-primary" name="submit">
397 </div>
398 </div>
399 </div>
400 </form>
401 </div>
402 </div>
403
404
405 <?php
406 }
407
408
409
410
411
412
413 function botwriter_super_form_meta_box_handler($item)
414 {
415 Global $botwriter_languages, $botwriter_countries;
416
417 $selected_days = isset($item["days"]) ? explode(",", $item["days"]) : array();
418 $times_per_day = isset($item["times_per_day"]) ? $item["times_per_day"] : 1;
419
420 $dir_images_writers = plugin_dir_url(dirname(__FILE__)) . '/assets/images/writers/';
421 $dir_images_icons = plugin_dir_url(dirname(__FILE__)) . '/assets/images/icons/';
422 ?>
423 <div id="loading">
424 <div class="loader">
425 <div class="inner one"></div>
426 <div class="inner two"></div>
427 <div class="inner three"></div>
428 </div>
429 </div>
430
431 <form>
432 <div class="form2bc">
433 <div class="container">
434 <?php
435 $botwriter_admin_email = botwriter_get_admin_email();
436 $botwriter_domain_name = esc_url(get_site_url());
437 ?>
438
439 <input type="hidden" id="botwriter_admin_email" value="<?php echo esc_attr($botwriter_admin_email); ?>">
440 <input type="hidden" id="botwriter_domain_name" value="<?php echo esc_attr($botwriter_domain_name); ?>">
441
442 <div class="col-md-6">
443 <label class="form-label">Task Name:</label>
444 <input id="task_name" name="task_name" type="text" class="form-control" value="<?php echo esc_attr($item['task_name']); ?>" required>
445 </div>
446 <br>
447
448 <div class="col-md-6">
449 <label class="form-label">Author Selection</label>
450 <select name="author_selection" class="form-select">
451 <?php
452 $authors = get_users();
453 foreach ($authors as $author) {
454 $author_id = $author->ID;
455 $author_name = $author->display_name;
456 $selected = ($item['author_selection'] == strval($author_id)) ? 'selected' : '';
457 echo "<option value='" . esc_attr($author_id) . "' " . esc_attr($selected) . ">" . esc_html($author_name) . "</option>";
458 }
459 ?>
460 </select>
461 <p class="form-text">Select an author from the list.</p>
462 </div>
463
464 <div class="col-md-6">
465 <label for="post_status" class="form-label">Post Status:</label>
466 <select id="post_status" name="post_status" class="form-select">
467 <option value="publish" <?php selected($item['post_status'], 'publish'); ?>>Publish</option>
468 <option value="draft" <?php selected($item['post_status'], 'draft'); ?>>Draft</option>
469 </select>
470 <p class="form-text">Select the status of the post. Choose 'Draft' if you want to revise it before publishing.</p>
471 </div>
472
473 <div class="col-md-6">
474 <label class="form-label">Days of the Week:</label><br>
475 <?php
476 $days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
477 foreach ($days_of_week as $day) {
478 $is_checked = in_array($day, $selected_days) ? 'checked' : '';
479 echo "<input type='checkbox' name='days[]' value='" . esc_attr($day) . "' " . esc_attr($is_checked) . "> " . esc_html($day) . "<br>";
480 }
481 ?>
482 <p class="form-text">Select the days on which you want to write and publish.</p>
483 </div>
484
485 <div class="col-md-6">
486 <label class="form-label">Post per Day:</label>
487 <input type="number" name="times_per_day" min="1" value="<?php echo esc_attr($times_per_day); ?>" required>
488 </div>
489
490 <div class="col-md-6">
491 <div class="bw-schedule-tip">
492 <span class="dashicons dashicons-calendar-alt"></span>
493 <span><?php esc_html_e('This schedule runs only until all articles in the task are published. For example, if you have 3 articles and set 1 post per day on weekdays, they will be published over 3 days and then the task will stop automatically.', 'botwriter'); ?></span>
494 </div>
495 </div>
496 <br>
497
498 <?php
499 $default_language_code = substr(get_locale(), 0, 2);
500 if (empty($item['post_language'])) {
501 $item['post_language'] = $default_language_code;
502 }
503 ?>
504
505 <div class="col-md-6">
506 <label for="post_language" class="form-label">Post Language:</label>
507 <select class="form-select" id="post_language" name="post_language">
508 <?php
509 foreach ($botwriter_languages as $code => $name) {
510 $selected = ($item['post_language'] == $code) ? 'selected' : '';
511 echo "<option value='" . esc_attr($code) . "' " . esc_attr($selected) . ">" . esc_html($name) . "</option>";
512 }
513 ?>
514 </select>
515 </div>
516
517 <br>
518
519 <!-- Post Length -->
520 <div class="col-md-6">
521 <label class="form-label">Post Length:</label>
522 <select id="post_length" name="post_length" class="form-select">
523 <option value="400" <?php selected($item['post_length'], 400); ?>>Short (400 words)</option>
524 <option value="800" <?php selected($item['post_length'], 800); ?>>Medium (800 words)</option>
525 <option value="1600" <?php selected($item['post_length'], 1600); ?>>Long (1600 words)</option>
526 <option value="custom" <?php echo (!in_array($item['post_length'], [400, 800, 1600])) ? 'selected' : ''; ?>>Custom</option>
527 </select>
528 <p class="form-text">Select the desired post length or choose custom to enter a specific number of words.</p>
529 </div>
530 <!-- End Post Length -->
531
532 <!-- Custom Length Input -->
533 <div class="col-md-6" id="customLengthInput" style="display: <?php echo (!in_array($item['post_length'], [400, 800, 1600])) ? 'block' : 'none'; ?>;">
534 <label class="form-label">Custom Length (max 4000):</label>
535 <input id="custom_post_length" name="custom_post_length" type="number" class="form-control" value="<?php echo esc_html($item['custom_post_length']); ?>">
536 <p class="form-text">Enter the number of words you want the post to have.</p>
537 </div>
538 <br>
539
540 <!-- Template Selection -->
541 <div class="col-md-6">
542 <label class="form-label"><?php esc_html_e('Prompt Template:', 'botwriter'); ?></label>
543 <select id="template_id" name="template_id" class="form-select">
544 <?php
545 $templates = botwriter_get_all_templates();
546 $selected_template_id = isset($item['template_id']) && !empty($item['template_id']) ? intval($item['template_id']) : null;
547
548 // If no template selected, find the default one
549 if ($selected_template_id === null) {
550 foreach ($templates as $tpl) {
551 if (!empty($tpl['is_default'])) {
552 $selected_template_id = intval($tpl['id']);
553 break;
554 }
555 }
556 }
557
558 foreach ($templates as $tpl) {
559 $label = (string) $tpl['name'];
560 if (!empty($tpl['is_default'])) {
561 $label .= ' �
562 ';
563 }
564 echo '<option value="' . esc_attr($tpl['id']) . '"';
565 selected($selected_template_id, $tpl['id']);
566 echo '>' . esc_html($label) . '</option>';
567 }
568 ?>
569 </select>
570 <p class="form-text"><?php esc_html_e('Select the prompt template to use for content generation. Templates marked with �
571 are the default.', 'botwriter'); ?></p>
572 </div>
573 <br>
574
575 <!-- Disable AI Images -->
576 <div class="col-md-6">
577 <?php
578 $image_provider = get_option('botwriter_image_provider', 'stockphoto');
579 $force_disable_images = ($image_provider === 'none');
580 ?>
581 <label class="form-label"><?php esc_html_e('AI Image Generation:', 'botwriter'); ?></label>
582 <input type="hidden" name="disable_ai_images" value="<?php echo $force_disable_images ? '1' : '0'; ?>">
583 <input type="checkbox" name="disable_ai_images" value="1" id="disable_ai_images_checkbox"
584 <?php checked($force_disable_images || $item['disable_ai_images'], 1); ?>
585 <?php echo $force_disable_images ? 'disabled' : ''; ?>>
586 <span><?php esc_html_e('Disable AI image generation for this task', 'botwriter'); ?></span>
587 <?php if ($force_disable_images): ?>
588 <p class="form-text bw-text-error bw-disabled-images-warning"><span class="dashicons dashicons-info bw-icon-small"></span> <?php esc_html_e('Image generation is globally disabled. Change the Image Provider in Settings to enable it.', 'botwriter'); ?></p>
589 <?php else: ?>
590 <p class="form-text" id="disable_ai_images_description"><?php esc_html_e('Check this option to generate only text articles without AI-generated images for this specific task.', 'botwriter'); ?></p>
591 <?php endif; ?>
592 <?php
593 $is_checked = $force_disable_images || $item['disable_ai_images'];
594 $tip_style = $is_checked ? '' : 'display:none;';
595 ?>
596 <p class="form-text bw-asi-inline-tip" id="bw_asi_tip" style="<?php echo esc_attr($tip_style); ?>"><span class="dashicons dashicons-images-alt2"></span> <?php printf(
597 /* translators: %s: link to All Sources Images plugin */
598 esc_html__('Tip: Use %s to add free images from Pexels, Unsplash & Pixabay automatically.', 'botwriter'),
599 '<a href="' . esc_url(admin_url('plugin-install.php?s=all+sources+images&tab=search&type=term')) . '" target="_blank">All Sources Images</a>'
600 ); ?></p>
601 </div>
602 <br>
603
604 </div> <!-- Fin div class="container" -->
605 </div> <!-- Fin div class="form2bc" -->
606 </form>
607 <?php
608 } // End of the function
609
610
611 function botwriter_get_info_blog() {
612 // Obtener título y descripción del blog
613 $blog_title = get_bloginfo('name');
614 $blog_description = get_bloginfo('description');
615
616 // Obtener solo las categorías de WordPress (excluyendo las de WooCommerce)
617 $categories = get_categories(array(
618 'hide_empty' => false, // Obtener también las categorías sin posts
619 'taxonomy' => 'category' // Asegura que solo obtenemos categorías de posts, no de productos
620 ));
621
622 $cats = array();
623
624 if (!empty($categories)) {
625 foreach ($categories as $cat) {
626 // Configurar argumentos para obtener los últimos 5 posts de la categoría actual
627 $args = array(
628 'post_type' => 'post', // Solo posts, no productos ni otros CPTs
629 'post_status' => 'publish',
630 'cat' => $cat->term_id, // Filtrar por el ID de la categoría
631 'posts_per_page' => 5,
632 'orderby' => 'date',
633 'order' => 'DESC'
634 );
635 $query = new WP_Query($args);
636 $posts = array();
637
638 if ($query->have_posts()) {
639 while ($query->have_posts()) {
640 $query->the_post();
641 $posts[] = array(
642 'title' => get_the_title(),
643 'description' => get_the_excerpt(), // Para contenido completo usar get_the_content()
644 'date' => get_the_date() // Fecha del post
645 );
646 }
647 wp_reset_postdata(); // Importante para restaurar el loop principal
648 }
649
650 // Agregar la categoría incluso si no tiene posts
651 $cats[] = array(
652 'id' => $cat->term_id,
653 'name' => $cat->name,
654 'description' => $cat->description,
655 'posts' => $posts // Se agrega vacío si no tiene posts
656 );
657 }
658 }
659
660 // Obtener páginas publicadas
661 $pages_args = array(
662 'post_type' => 'page',
663 'post_status' => 'publish',
664 'posts_per_page' => 10,
665 'orderby' => 'date',
666 'order' => 'DESC'
667 );
668 $pages_query = new WP_Query($pages_args);
669 $pages = array();
670
671 if ($pages_query->have_posts()) {
672 while ($pages_query->have_posts()) {
673 $pages_query->the_post();
674 // Obtener el excerpt, y si no existe, tomar los primeros 200 caracteres del contenido
675 $excerpt = get_the_excerpt();
676 if (empty($excerpt)) {
677 $content = wp_strip_all_tags(get_the_content()); // Quitar etiquetas HTML del contenido
678 $excerpt = substr($content, 0, 250); // Tomar los primeros 200 caracteres
679 if (strlen($content) > 250) {
680 $excerpt .= '...'; // Agregar puntos suspensivos si el contenido es más largo
681 }
682 }
683
684 $pages[] = array(
685 'id' => get_the_ID(),
686 'title' => get_the_title(),
687 'description' => $excerpt, // Usar el excerpt o los primeros 200 caracteres
688 //'date' => get_the_date(), // Fecha de creación
689 //'modified' => get_the_modified_date(), // Fecha de última modificación
690 //'slug' => get_post_field('post_name') // Slug de la página
691 );
692 }
693 wp_reset_postdata(); // Restaurar el loop principal
694 }
695
696 // Armar el array con la información completa del blog
697 $info_blog = array(
698 'title' => $blog_title,
699 'description' => $blog_description,
700 'categories' => $cats,
701 'pages' => $pages // Nueva sección para las páginas
702 );
703
704 return $info_blog;
705 }
706
707 function botwriter_super1_create_first_task() {
708 $info_blog = botwriter_get_info_blog();
709 $json_info_blog = json_encode($info_blog, JSON_PRETTY_PRINT);
710 $content_prompt = $json_info_blog;
711 botwriter_super1_create_task('FIRSTSUPER1',"", $content_prompt);
712 }
713
714 // create a log not task, only 1 for titles
715 function botwriter_super1_create_task($task_name, $title_prompt, $content_prompt,$post_count=10,$category_id=0) {
716 global $wpdb;
717 $table_name = $wpdb->prefix . 'botwriter_logs';
718 $current_time = gmdate('Y-m-d H:i:s', current_time('timestamp'));
719
720 botwriter_log('Initializing super1 task log', [
721 'task_name' => $task_name,
722 'post_count' => $post_count,
723 'category_id' => $category_id,
724 ]);
725
726 // default values
727 $data = array(
728 'id' => 1,
729 'id_task' => 0,
730 'created_at' => '',
731 'last_execution_time' => $current_time = gmdate('Y-m-d H:i:s', current_time('timestamp')),
732 'intentosfase1' => 0,
733 'intentosfase2' => 0,
734 'task_status' => '',
735 'error' => '',
736 'link_post_original' => '',
737 'id_post_published' => 0,
738 'post_status' => 'draft',
739 'task_name' => $task_name,
740 'writer' => 'ai_cerebro',
741 'narration' => 'Descriptive',
742 'custom_style' => '',
743 'post_language' => substr(get_locale(), 0, 2),
744 'post_length' => 2000,
745 'custom_post_length' => '',
746 'website_name' => '',
747 'website_type' => 'super1',
748 'domain_name' => '',
749 'category_id' => $category_id,
750 'website_category_id' => '',
751 'aigenerated_title' => '',
752 'aigenerated_content' => '',
753 'aigenerated_tags' => '',
754 'aigenerated_image' => '',
755 'post_count' => $post_count,
756 'post_order' => '',
757 'title_prompt' => $title_prompt,
758 'content_prompt' => $content_prompt,
759 'tags_prompt' => '',
760 'image_prompt' => '',
761 'image_generating_status' => '',
762 'author_selection' => 1,
763 'news_time_published' => '',
764 'news_language' => '',
765 'news_country' => '',
766 'news_keyword' => '',
767 'news_source' => '',
768 'rss_source' => '',
769 'ai_keywords' => '',
770 'version' => '',
771 'user_domainname' => '',
772 'ai_image_size' => '',
773 'titles' => '',
774 'links' => '',
775 );
776
777 $event=$data;
778 $event["task_status"] = "pending";
779 $event["id_task"] = $data["id"];
780 $event["intentosfase1"] = 0;
781 $id_log=botwriter_logs_register($event); // create log in db
782 $event["id"]=$id_log;
783 botwriter_log('Super1 log registered', [
784 'log_id' => $id_log,
785 'task_name' => $task_name,
786 ]);
787
788 botwriter_send1_data_to_server( (array) $event);
789 return $id_log;
790 }
791
792
793 function botwriter_super1_log_to_bd($result,$id_log) {
794 global $wpdb;
795 $table_name = $wpdb->prefix . 'botwriter_super';
796 $aigenerated_content = $result["aigenerated_content"];
797 $title_prompt = $result["title_prompt"];
798
799 try {
800 $data_array=json_decode($aigenerated_content, true);
801 } catch (Exception $e) {
802 echo "Error: " . esc_html($e->getMessage());
803 }
804
805 if (!is_array($data_array)) {
806 botwriter_log('Super1 JSON decode failed', [
807 'log_id' => $id_log,
808 ]);
809 return false; // Or throw an exception as needed
810 }
811
812 /*
813 echo "<h1>Finish Task titulos etc</h1>";
814 echo "<pre>";
815 print_r($data_array);
816 echo "</pre>";
817 */
818
819 botwriter_log('Persisting super1 outlines', [
820 'log_id' => $id_log,
821 'articles' => count($data_array),
822 ]);
823
824 foreach ($data_array as $post) {
825 // Verifica si el artículo ya existe para evitar duplicados (por título)
826 $existing_post = $wpdb->get_row($wpdb->prepare(
827 "SELECT * FROM $table_name WHERE title = %s",
828 $post['title']
829 ));
830
831
832
833 if (!$existing_post) {
834 if ($title_prompt!="Custom") {
835 $data = array(
836 'title' => $post['title'],
837 'content' => $post['resumen'],
838 'category_name' => $post['categoria'],
839 'category_id' => $post['categoria_id'],
840 'id_log' => $id_log
841 );
842 } else {
843 $data = array(
844 'title' => $post['title'],
845 'content' => $post['resumen'],
846 'category_name' => get_cat_name($result['category_id']),
847 'category_id' => $result['category_id'],
848 'id_log' => $id_log
849 );
850 }
851
852 $wpdb->insert($table_name, $data);
853 botwriter_log('Super1 outline stored', [
854 'log_id' => $id_log,
855 'title' => $post['title'],
856 ]);
857 } else {
858 botwriter_log('Super1 outline skipped (duplicate)', [
859 'log_id' => $id_log,
860 'title' => $post['title'],
861 ]);
862 }
863 }
864
865
866
867
868 }
869
870 function botwriter_super1_view_articles_html($id_task=0) {
871
872
873
874 global $wpdb;
875 $table_name = $wpdb->prefix . 'botwriter_super';
876 $posts = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE id_task = %d ORDER BY category_id", $id_task), ARRAY_A);
877 //
878
879 $html = '<button type="button" class="button-primary botwriter-reset-super1">Reset Task and Try Again</button>';
880 $contador = 0;
881 $auxcategoria = "";
882
883 foreach ($posts as $post) {
884 $task_status = $post['task_status'];
885 if ($auxcategoria != $post['category_name']) {
886 $html .= '<h2>' . esc_html($post['category_name']) . '</h2>';
887 }
888
889 $html .= '<div class="super-article" data-id="' . esc_attr($post['id']) . '">';
890 $html .= '<div class="super-number">' . ++$contador . '</div>';
891 $html .= '<div class="super-content">';
892 $html .= '<h2 class="super-title">' . esc_html($post['title']) . '</h2>';
893 $html .= '<p class="super-text">' . esc_html($post['content']) . '</p>';
894 $html .= '</div>';
895 if ($task_status == 'completed') {
896 $html .= '<div class="super-status">Completed �
897 </div>';
898 }
899 // si esta en cola
900 if ($task_status == 'inqueue') {
901 $html .= '<div class="super-status">In Queue 🔄</div>';
902 }
903 // si hay un error
904 if ($task_status == 'error') {
905 $html .= '<div class="super-status">Error </div>';
906 }
907
908 // si es blanco o null
909 if ($task_status == '') {
910 $html .= '<div class="super-actions">';
911 $html .= '<button class="super-edit" data-id="' . esc_attr($post['id']) . '">✏️</button>';
912 $html .= '<button class="super-delete" data-id="' . esc_attr($post['id']) . '"></button>';
913 $html .= '</div>';
914 }
915
916
917 $html .= '</div>';
918
919 $auxcategoria = $post['category_name'];
920 }
921
922 return $html;
923 }
924
925
926 function botwriter_super1_check_task_exist() {
927 global $wpdb;
928 $table_name = $wpdb->prefix . 'botwriter_logs';
929 $task = $wpdb->get_row($wpdb->prepare(
930 "SELECT * FROM $table_name WHERE website_type = %d",
931 'super1'
932 ));
933 if ($task) {
934 return true;
935 } else {
936 return false;
937 }
938 }
939
940
941 // crea una funcion que mire en la tabla task si la tarea super esta completeda (la ultima que se ha creado)
942 function botwriter_super1_check_task_finish() {
943 global $wpdb;
944 $table_name = $wpdb->prefix . 'botwriter_logs';
945 $task = $wpdb->get_row("SELECT * FROM $table_name WHERE website_type = 'super1' order by id desc limit 1");
946
947 if ($task) {
948 if ($task->task_status == 'completed') {
949 botwriter_log('Super1 task status completed', [
950 'log_id' => $task->id,
951 ]);
952 return 'completed';
953 }
954
955 if ($task->task_status == 'error') {
956 botwriter_log('Super1 task status error', [
957 'log_id' => $task->id,
958 ]);
959 return 'error';
960 }
961
962 if ($task->task_status == 'pending' || $task->task_status == 'inqueue') {
963 botwriter_log('Super1 task still pending', [
964 'log_id' => $task->id,
965 'status' => $task->task_status,
966 ]);
967 botwriter_execute_events_pass2();
968 return 'inqueue';
969 }
970 }
971
972
973 botwriter_log('Super1 task status unknown');
974 return "";
975 }
976
977
978
979 function botwriter_super_prepare_event($event) {
980
981 global $wpdb;
982 $table_name = $wpdb->prefix . 'botwriter_super';
983 $articulo = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id_task = %d AND (task_status IS NULL OR task_status = '') ORDER BY category_id", $event["id_task"]), ARRAY_A);
984
985 /*
986 echo "<h1>Prepare Event</h1>";
987 echo "<pre>";
988 print_r($articulo);
989 echo "</pre>";
990 */
991
992
993
994 if (!empty($articulo['title'])) {
995 botwriter_log('Super2 outline selected', [
996 'task_id' => $event['id_task'],
997 'log_id' => $event['id'],
998 'article_id' => $articulo['id'],
999 ]);
1000 // For rewriter/siterewriter tasks, preserve the original content_prompt
1001 // (rewrite instructions) before overwriting with the article content.
1002 $task_type = $event['task_type'] ?? '';
1003 if (in_array($task_type, ['rewriter', 'siterewriter'], true) && !empty($event['content_prompt'])) {
1004 $event['rewrite_prompt'] = $event['content_prompt'];
1005 }
1006 $event['content_prompt'] = $articulo['content'];
1007 $event['title_prompt'] = $articulo['title'];
1008 $event['category_id'] = $articulo['category_id'];
1009 $id = $articulo['id'];
1010 $id_log=$event["id"];
1011 // actualizamos el status y el id_log con el nuevo id_log
1012 $wpdb->update($table_name, array('id_log' => $id_log, 'task_status' => 'inqueue'), array('id' => $id));
1013
1014
1015 } else {
1016 botwriter_log('Super2 outline not found', [
1017 'task_id' => $event['id_task'],
1018 'log_id' => $event['id'],
1019 ]);
1020 return false;
1021 }
1022
1023
1024 return $event;
1025 }
1026
1027 function botwriter_super_assign_id_task($id_task) {
1028 global $wpdb;
1029 $table_name = $wpdb->prefix . 'botwriter_super';
1030 // update the super table with the id_task for those with id_task 0
1031 $wpdb->update($table_name, array('id_task' => $id_task), array('id_task' => 0));
1032
1033 return $id_task;
1034 }
1035
1036 function botwriter_super1_check_first_time() {
1037 global $wpdb;
1038 $table_name = $wpdb->prefix . 'botwriter_logs';
1039 $task = $wpdb->get_row("SELECT * FROM $table_name WHERE website_type = 'super1' AND task_name = 'FIRSTSUPER1'");
1040 if ($task) {
1041 return true;
1042 } else {
1043 return false;
1044 }
1045 }