PluginProbe
wpForo Forum / 3.2.0
wpForo Forum v3.2.0
3.2.0 3.1.7 3.1.6 3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 All 140 releases
wpforo / admin / pages / tabs / ai-features-tab-ai-tasks.php

ai-features-tab-ai-tasks.php in wpForo Forum 3.2.0, at admin/pages/tabs/ai-features-tab-ai-tasks.php

1,915 lines 95.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * AI Features - AI Tasks Tab
4 *
5 * Provides scheduling system for automated AI content generation:
6 * - AI Topic Generator - Automatically creates new forum topics
7 * - AI Reply Generator - Automatically replies to topics
8 *
9 * @package wpForo
10 * @subpackage Admin
11 */
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Render AI Tasks tab content
19 *
20 * @param bool $is_connected Whether tenant is connected to AI service
21 * @param array $status Tenant status data from API
22 */
23 function wpforo_ai_render_ai_tasks_tab( $is_connected, $status ) {
24 if ( ! $is_connected ) {
25 ?>
26 <div class="wpforo-ai-box wpforo-ai-not-connected-notice">
27 <div class="wpforo-ai-box-body">
28 <div class="wpforo-ai-status-badge status-warning">
29 <span class="dashicons dashicons-warning"></span>
30 <?php _e( 'Not Connected', 'wpforo' ); ?>
31 </div>
32 <p><?php _e( 'Please connect to wpForo AI API first in the Overview tab to enable AI Tasks.', 'wpforo' ); ?></p>
33 <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpforo-ai&tab=overview' ) ); ?>" class="button button-primary">
34 <?php _e( 'Go to Overview', 'wpforo' ); ?>
35 </a>
36 </div>
37 </div>
38 <?php
39 return;
40 }
41
42 // Check if user's plan allows AI Tasks (requires Professional or higher)
43 $subscription = isset( $status['subscription'] ) && is_array( $status['subscription'] ) ? $status['subscription'] : [];
44 $current_plan = isset( $subscription['plan'] ) ? strtolower( $subscription['plan'] ) : 'free_trial';
45
46 // AI Tasks require Professional plan or higher
47 if ( ! wpforo_ai_is_feature_enabled_by_plan( $current_plan, 'professional' ) ) {
48 ?>
49 <div class="wpforo-ai-box wpforo-ai-upgrade-notice">
50 <div class="wpforo-ai-box-body">
51 <div class="wpforo-ai-status-badge status-info">
52 <span class="dashicons dashicons-lock"></span>
53 <?php _e( 'Upgrade to Professional Plan to Unlock', 'wpforo' ); ?>&nbsp;
54 </div>
55 <h3><?php _e( 'AI Tasks and Automations', 'wpforo' ); ?></h3>
56 <p><?php _e( 'AI Tasks (Topic Generation, Reply Generation, and Tag Moderation) are available on Professional, Business, and Enterprise plans.', 'wpforo' ); ?></p>
57 <ul class="wpforo-ai-feature-list">
58 <li><span class="dashicons dashicons-yes-alt"></span> <?php _e( 'Generate new topics automatically on schedule', 'wpforo' ); ?></li>
59 <li><span class="dashicons dashicons-yes-alt"></span> <?php _e( 'Reply to discussions to boost engagement', 'wpforo' ); ?></li>
60 <li><span class="dashicons dashicons-yes-alt"></span> <?php _e( 'Automatically manage topic tags', 'wpforo' ); ?></li>
61 <li><span class="dashicons dashicons-yes-alt"></span> <?php _e( 'Flexible scheduling (hourly, daily, weekly)', 'wpforo' ); ?></li>
62 </ul>
63 <p>
64 <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpforo-ai&tab=overview#wpforo-ai-plans' ) ); ?>" class="button button-primary">
65 <?php _e( 'Upgrade to Professional', 'wpforo' ); ?>
66 </a>
67 </p>
68 </div>
69 </div>
70 <?php
71 return;
72 }
73
74 // Get all boards and determine current board
75 $boards = WPF()->board->get_boards();
76 $current_boardid = isset( $_GET['boardid'] ) ? intval( $_GET['boardid'] ) : 0;
77
78 // Validate boardid exists (use strict comparison for type safety)
79 $valid_boardids = array_map( 'intval', array_column( $boards, 'boardid' ) );
80 if ( ! in_array( $current_boardid, $valid_boardids, true ) ) {
81 $current_boardid = 0; // Default to main board
82 }
83
84 // Switch to the selected board context
85 if ( $current_boardid > 0 ) {
86 WPF()->change_board( $current_boardid );
87 }
88
89 // Render board sub-tabs if multiple boards exist
90 if ( count( $boards ) > 1 ) :
91 // Find current board title (from settings, not label)
92 $current_board_title = __( 'Board', 'wpforo' );
93 foreach ( $boards as $board ) {
94 if ( isset( $board['boardid'] ) && (int) $board['boardid'] === $current_boardid ) {
95 $current_board_title = isset( $board['settings']['title'] ) ? esc_html( $board['settings']['title'] ) : ( isset( $board['title'] ) ? esc_html( $board['title'] ) : $current_board_title );
96 break;
97 }
98 }
99 ?>
100 <div class="wpforo-ai-board-tabs">
101 <div class="wpforo-ai-board-current">
102 <?php echo esc_html__( 'Board:', 'wpforo' ); ?> <strong><?php echo $current_board_title; ?></strong>
103 </div>
104 <div class="wpforo-ai-board-tabs-list">
105 <?php foreach ( $boards as $board ) :
106 $board_id = isset( $board['boardid'] ) ? (int) $board['boardid'] : 0;
107 $board_label = isset( $board['title'] ) ? esc_html( $board['title'] ) : __( 'Board', 'wpforo' ) . ' ' . $board_id;
108 $tab_url = add_query_arg( array(
109 'page' => 'wpforo-ai',
110 'tab' => 'ai_tasks',
111 'boardid' => $board_id,
112 ), admin_url( 'admin.php' ) );
113 $active_class = ( $current_boardid === $board_id ) ? 'active' : '';
114 ?>
115 <a href="<?php echo esc_url( $tab_url ); ?>" class="wpforo-ai-board-tab <?php echo esc_attr( $active_class ); ?>">
116 <span class="dashicons dashicons-category"></span>
117 <?php echo $board_label; ?>
118 </a>
119 <?php endforeach; ?>
120 </div>
121 </div>
122 <?php
123 endif;
124
125 // Get available credits from status (subscription already defined above)
126 $credits_remaining = isset( $subscription['credits_remaining'] ) ? (int) $subscription['credits_remaining'] : 0;
127
128 // Get tasks for the current board
129 $tasks = wpforo_ai_get_tasks( $current_boardid );
130 $task_count = count( $tasks );
131
132 ?>
133 <div class="wpforo-ai-tasks wpforo-ai-tasks-tab">
134
135 <!-- Description Panel -->
136 <div class="wpforo-ai-box wpforo-ai-tasks-description-box">
137 <div class="wpforo-ai-box-body">
138 <div class="wpforo-ai-tasks-header">
139 <div class="wpforo-ai-tasks-info">
140 <h2>
141 <span class="dashicons dashicons-clock"></span>
142 <?php _e( 'AI Tasks', 'wpforo' ); ?>
143 </h2>
144 <p class="wpforo-ai-description">
145 <?php _e( 'Automate your forum with scheduled AI tasks. Create topics, generate replies, and keep your community active 24/7.', 'wpforo' ); ?>
146 </p>
147 <ul class="wpforo-ai-tasks-features">
148 <li><span class="dashicons dashicons-yes-alt"></span> <?php _e( 'Generate new topics automatically on schedule', 'wpforo' ); ?></li>
149 <li><span class="dashicons dashicons-yes-alt"></span> <?php _e( 'Reply to discussions to boost engagement', 'wpforo' ); ?></li>
150 <li><span class="dashicons dashicons-yes-alt"></span> <?php _e( 'Flexible scheduling (hourly, daily, weekly)', 'wpforo' ); ?></li>
151 <li><span class="dashicons dashicons-yes-alt"></span> <?php _e( 'Credit usage controls and limits', 'wpforo' ); ?></li>
152 </ul>
153 <div class="wpforo-ai-credit-notice wpforo-ai-notice-warning">
154 <span class="dashicons dashicons-warning"></span>
155 <p><?php _e( 'Tasks consume AI credits. Monitor usage carefully to avoid unexpected costs.', 'wpforo' ); ?></p>
156 </div>
157 </div>
158 <div class="wpforo-ai-tasks-action">
159 <button type="button" class="button button-primary button-hero wpforo-ai-create-task-btn" id="wpforo-ai-create-task-btn">
160 <span class="dashicons dashicons-plus-alt2"></span>
161 <?php _e( 'Create AI Task', 'wpforo' ); ?>
162 </button>
163 <p class="wpforo-ai-credits-info">
164 <span class="dashicons dashicons-database"></span>
165 <?php printf(
166 __( '%s credits available', 'wpforo' ),
167 '<strong>' . number_format( $credits_remaining ) . '</strong>'
168 ); ?>
169 </p>
170 </div>
171 </div>
172 </div>
173 </div>
174
175 <!-- Create Task Form (Hidden by default, slides down on button click) -->
176 <div class="wpforo-ai-box wpforo-ai-task-form-box wpforo-ai-task-form-container" id="wpforo-ai-create-task-form-box">
177 <div class="wpforo-ai-box-header">
178 <h2>
179 <span class="dashicons dashicons-plus-alt2"></span>
180 <span id="wpforo-ai-task-form-title"><?php _e( 'Create New Task', 'wpforo' ); ?></span>
181 </h2>
182 <button type="button" class="button button-secondary wpforo-ai-cancel-task-btn">
183 <span class="dashicons dashicons-no-alt"></span>
184 <?php _e( 'Cancel', 'wpforo' ); ?>
185 </button>
186 </div>
187 <div class="wpforo-ai-box-body">
188 <form id="wpforo-ai-task-form" class="wpforo-ai-task-form">
189 <?php wp_nonce_field( 'wpforo_ai_task_nonce', 'wpforo_ai_task_nonce' ); ?>
190 <input type="hidden" id="wpforo-ai-task-nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpforo_ai_task_nonce' ) ); ?>">
191 <input type="hidden" name="task_id" id="wpforo-ai-task-id" value="">
192 <input type="hidden" name="board_id" id="wpforo-ai-task-board-id" value="<?php echo esc_attr( $current_boardid ); ?>">
193
194 <!-- Basic Information Section -->
195 <div class="wpforo-ai-form-section">
196 <h3 class="wpforo-ai-form-section-title"><?php _e( 'Basic Information', 'wpforo' ); ?></h3>
197
198 <div class="wpforo-ai-form-row">
199 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
200 <label for="wpforo-ai-task-type"><?php _e( 'Task Type', 'wpforo' ); ?> <span class="required">*</span></label>
201 <select id="wpforo-ai-task-type" name="task_type" required>
202 <option value=""><?php _e( 'Select task type...', 'wpforo' ); ?></option>
203 <option value="topic_generator"><?php _e( 'AI Topic Generator', 'wpforo' ); ?></option>
204 <option value="reply_generator"><?php _e( 'AI Reply Generator', 'wpforo' ); ?></option>
205 <option value="tag_maintenance"><?php _e( 'AI Topic Tag Generator and Cleaning', 'wpforo' ); ?></option>
206 </select>
207 <p class="description"><?php _e( 'Choose what this task will do', 'wpforo' ); ?></p>
208 </div>
209
210 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
211 <label for="wpforo-ai-task-name"><?php _e( 'Task Name', 'wpforo' ); ?> <span class="required">*</span></label>
212 <input type="text" id="wpforo-ai-task-name" name="task_name" maxlength="100" required placeholder="<?php esc_attr_e( 'e.g., Daily Tech Topics', 'wpforo' ); ?>">
213 <p class="description"><?php _e( 'A descriptive name for this task (3-100 characters)', 'wpforo' ); ?></p>
214 </div>
215 </div>
216
217 <div class="wpforo-ai-form-row">
218 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
219 <label><?php _e( 'Status', 'wpforo' ); ?></label>
220 <div class="wpforo-ai-radio-group">
221 <label class="wpforo-ai-radio-item">
222 <input type="radio" name="status" value="active">
223 <span class="wpforo-ai-radio-label">
224 <?php _e( 'Active', 'wpforo' ); ?>
225 </span>
226 </label>
227 <label class="wpforo-ai-radio-item">
228 <input type="radio" name="status" value="paused" checked>
229 <span class="wpforo-ai-radio-label">
230 <?php _e( 'Paused', 'wpforo' ); ?>
231 </span>
232 </label>
233 </div>
234 <p class="description"><?php _e( 'Set to Paused to configure before activating', 'wpforo' ); ?></p>
235 </div>
236
237 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
238 <label for="wpforo-ai-task-language"><?php _e( 'Generated Content Language', 'wpforo' ); ?></label>
239 <select id="wpforo-ai-task-language" name="response_language">
240 <?php foreach ( WPF()->settings->get_variants_ai_languages() as $lang ) : ?>
241 <option value="<?php echo esc_attr( $lang['value'] ); ?>"><?php echo esc_html( $lang['label'] ); ?></option>
242 <?php endforeach; ?>
243 </select>
244 <p class="description"><?php _e( 'Language for AI-generated content', 'wpforo' ); ?></p>
245 </div>
246 </div>
247 </div>
248
249 <!-- Dynamic Configuration Section (changes based on task type) -->
250 <div id="wpforo-ai-task-config-section" class="wpforo-ai-form-section" style="display: none;">
251 <!-- Content will be loaded dynamically based on task type -->
252 </div>
253
254 <!-- Form Actions -->
255 <div class="wpforo-ai-form-actions">
256 <button type="button" class="button button-secondary wpforo-ai-cancel-task-btn">
257 <?php _e( 'Cancel', 'wpforo' ); ?>
258 </button>
259 <button type="submit" class="button button-primary button-large" id="wpforo-ai-save-task-btn">
260 <span class="dashicons dashicons-saved"></span>
261 <?php _e( 'Save Task', 'wpforo' ); ?>
262 </button>
263 </div>
264 </form>
265 </div>
266 </div>
267
268 <!-- Task List Table -->
269 <div class="wpforo-ai-box wpforo-ai-tasks-list-box">
270 <div class="wpforo-ai-box-header">
271 <h2><?php _e( 'Your Tasks', 'wpforo' ); ?> <span class="wpforo-ai-task-count">(<?php echo $task_count; ?>)</span></h2>
272 <div class="wpforo-ai-tasks-filters" style="display: flex; justify-content: flex-end; align-content: center;">
273 <select id="wpforo-ai-tasks-filter-type" class="wpforo-ai-tasks-filter wpforo-ai-filter-type">
274 <option value=""><?php _e( 'All Types', 'wpforo' ); ?></option>
275 <option value="topic_generator"><?php _e( 'Topic Generator', 'wpforo' ); ?></option>
276 <option value="reply_generator"><?php _e( 'Reply Generator', 'wpforo' ); ?></option>
277 <option value="tag_maintenance"><?php _e( 'Tag Maintenance', 'wpforo' ); ?></option>
278 </select>
279 <select id="wpforo-ai-tasks-filter-status" class="wpforo-ai-tasks-filter wpforo-ai-filter-status">
280 <option value=""><?php _e( 'All Status', 'wpforo' ); ?></option>
281 <option value="active"><?php _e( 'Active', 'wpforo' ); ?></option>
282 <option value="paused"><?php _e( 'Paused', 'wpforo' ); ?></option>
283 <option value="error"><?php _e( 'Error', 'wpforo' ); ?></option>
284 </select>
285 <input type="text" id="wpforo-ai-tasks-search" class="wpforo-ai-tasks-search wpforo-ai-search-tasks" placeholder="<?php esc_attr_e( 'Search tasks...', 'wpforo' ); ?>">
286 </div>
287 </div>
288 <div class="wpforo-ai-box-body">
289 <?php if ( $task_count > 0 ) : ?>
290 <!-- Bulk Actions -->
291 <div class="wpforo-ai-tasks-bulk-actions">
292 <select id="wpforo-ai-tasks-bulk-action" class="wpforo-ai-bulk-action-select">
293 <option value=""><?php _e( 'Bulk Actions', 'wpforo' ); ?></option>
294 <option value="activate"><?php _e( 'Activate Selected', 'wpforo' ); ?></option>
295 <option value="pause"><?php _e( 'Pause Selected', 'wpforo' ); ?></option>
296 <option value="delete"><?php _e( 'Delete Selected', 'wpforo' ); ?></option>
297 </select>
298 <button type="button" class="button wpforo-ai-bulk-apply" id="wpforo-ai-tasks-bulk-apply">
299 <?php _e( 'Apply', 'wpforo' ); ?>
300 </button>
301 </div>
302
303 <!-- Tasks Table -->
304 <table class="wp-list-table widefat fixed striped wpforo-ai-tasks-table" id="wpforo-ai-tasks-table">
305 <thead>
306 <tr>
307 <th class="check-column">
308 <input type="checkbox" id="wpforo-ai-tasks-select-all" class="wpforo-ai-select-all-tasks">
309 </th>
310 <th class="column-name sortable" data-sort="name"><?php _e( 'Task Name', 'wpforo' ); ?></th>
311 <th class="column-type"><?php _e( 'Type', 'wpforo' ); ?></th>
312 <th class="column-status sortable" data-sort="status"><?php _e( 'Status', 'wpforo' ); ?></th>
313 <th class="column-schedule"><?php _e( 'Schedule', 'wpforo' ); ?></th>
314 <th class="column-run-times sortable" data-sort="last_run"><?php _e( 'Next / Last Run', 'wpforo' ); ?></th>
315 <th class="column-stats"><?php _e( 'Stats', 'wpforo' ); ?></th>
316 <th class="column-actions" style="width: 80px"><?php _e( 'Actions', 'wpforo' ); ?></th>
317 </tr>
318 </thead>
319 <tbody id="wpforo-ai-tasks-tbody">
320 <?php foreach ( $tasks as $task ) : ?>
321 <?php wpforo_ai_render_task_row( $task ); ?>
322 <?php endforeach; ?>
323 </tbody>
324 </table>
325
326 <!-- Pagination -->
327 <div class="wpforo-ai-tasks-pagination" id="wpforo-ai-tasks-pagination">
328 <!-- Pagination will be rendered by JavaScript -->
329 </div>
330
331 <?php else : ?>
332 <!-- Empty State -->
333 <div class="wpforo-ai-tasks-empty">
334 <span class="dashicons dashicons-schedule"></span>
335 <h3><?php _e( 'No AI Tasks Yet', 'wpforo' ); ?></h3>
336 <p><?php _e( 'Create your first AI task to automate forum content generation.', 'wpforo' ); ?></p>
337 </div>
338 <?php endif; ?>
339 </div>
340 </div>
341
342 </div>
343
344 <!-- Task Type Configuration Templates -->
345 <?php wpforo_ai_render_task_type_templates( $current_boardid ); ?>
346
347 <!-- AI Tasks Tab JavaScript -->
348 <script type="text/javascript">
349 jQuery(document).ready(function($) {
350 // Initialize AI Tasks functionality
351 if (typeof window.WpForoAI !== 'undefined' && typeof WpForoAI.initAITasks === 'function') {
352 WpForoAI.initAITasks();
353 }
354 });
355 </script>
356 <?php
357 }
358
359 /**
360 * Get tasks for a specific board
361 *
362 * @param int $board_id Board ID
363 * @return array Array of task objects
364 */
365 function wpforo_ai_get_tasks( $board_id = 0 ) {
366 global $wpdb;
367
368 $table = WPF()->tables->ai_tasks;
369
370 // Check if table exists
371 $table_exists = $wpdb->get_var( $wpdb->prepare(
372 "SHOW TABLES LIKE %s",
373 $table
374 ) );
375
376 if ( ! $table_exists ) {
377 return [];
378 }
379
380 $sql = $wpdb->prepare(
381 "SELECT * FROM `{$table}` WHERE board_id = %d ORDER BY created_at DESC",
382 $board_id
383 );
384
385 $tasks = $wpdb->get_results( $sql, ARRAY_A );
386
387 return $tasks ? $tasks : [];
388 }
389
390 /**
391 * Render a single task row for the table
392 *
393 * @param array $task Task data
394 */
395 function wpforo_ai_render_task_row( $task ) {
396 $task_id = (int) $task['task_id'];
397 $task_name = esc_html( $task['task_name'] );
398 $task_type = $task['task_type'];
399 $status = $task['status'];
400 // Decode config if it's a JSON string
401 $config = $task['config'] ?? [];
402 if ( is_string( $config ) ) {
403 $config = json_decode( $config, true ) ?: [];
404 }
405 $frequency = $config['frequency'] ?? 'daily';
406 $last_run = $task['last_run_time'];
407 $last_run_status = $task['last_run_status'];
408 $total_runs = (int) ( $task['total_runs'] ?? 0 );
409 $items_created = (int) ( $task['items_created'] ?? 0 );
410 $credits_used = (int) ( $task['credits_used'] ?? 0 );
411
412 // Task type display
413 $type_labels = [
414 'topic_generator' => __( 'Topic Generator', 'wpforo' ),
415 'reply_generator' => __( 'Reply Generator', 'wpforo' ),
416 'tag_maintenance' => __( 'Tag Maintenance', 'wpforo' ),
417 ];
418 $type_icons = [
419 'topic_generator' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><g><path d="M21,0H3A3,3,0,0,0,0,3V20H6.9l3.808,3.218a2,2,0,0,0,2.582,0L17.1,20H24V3A3,3,0,0,0,21,0Zm1,18H16.366L12,21.69,7.634,18H2V3A1,1,0,0,1,3,2H21a1,1,0,0,1,1,1Z"/><rect x="6" y="5" width="6" height="2"/><rect x="6" y="9" width="12" height="2"/><rect x="6" y="13" width="12" height="2"/></g></svg>',
420 'reply_generator' => '<svg style="transform: rotate(180deg);" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M23,24a1,1,0,0,1-1-1,6.006,6.006,0,0,0-6-6H10.17v1.586A2,2,0,0,1,6.756,20L.877,14.121a3,3,0,0,1,0-4.242L6.756,4A2,2,0,0,1,10.17,5.414V7H15a9.01,9.01,0,0,1,9,9v7A1,1,0,0,1,23,24ZM8.17,5.414,2.291,11.293a1,1,0,0,0,0,1.414L8.17,18.586V16a1,1,0,0,1,1-1H16a7.984,7.984,0,0,1,6,2.714V16a7.008,7.008,0,0,0-7-7H9.17a1,1,0,0,1-1-1Z"/></svg>',
421 'tag_maintenance' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M12,0a4,4,0,0,0-4,4V6.75L.854,13.9a2.978,2.978,0,0,0,0,4.2L5.9,23.146a2.978,2.978,0,0,0,4.2,0L17.25,16H20a4,4,0,0,0,4-4V4a4,4,0,0,0-4-4ZM22,12a2,2,0,0,1-2,2H16.664a1,1,0,0,0-.707.293L8.686,21.564a1,1,0,0,1-1.372,0l-5.05-5.05a1,1,0,0,1,0-1.372l7.271-7.271A1,1,0,0,0,10,7.164V4a2,2,0,0,1,2-2h8a2,2,0,0,1,2,2ZM17,5a2,2,0,1,0,2,2A2,2,0,0,0,17,5Z"/></svg>',
422 ];
423 $type_label = isset( $type_labels[ $task_type ] ) ? $type_labels[ $task_type ] : $task_type;
424 $type_icon = isset( $type_icons[ $task_type ] ) ? $type_icons[ $task_type ] : '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M12,8a4,4,0,1,0,4,4A4,4,0,0,0,12,8Zm0,6a2,2,0,1,1,2-2A2,2,0,0,1,12,14Z"/><path d="M21.294,13.9l-.444-.256a9.1,9.1,0,0,0,0-3.29l.444-.256a3,3,0,1,0-3-5.2l-.445.257A8.977,8.977,0,0,0,15,3.513V3A3,3,0,0,0,9,3v.513A8.977,8.977,0,0,0,6.152,5.159L5.705,4.9a3,3,0,0,0-3,5.2l.444.256a9.1,9.1,0,0,0,0,3.29l-.444.256a3,3,0,1,0,3,5.2l.445-.257A8.977,8.977,0,0,0,9,20.487V21a3,3,0,0,0,6,0v-.513a8.977,8.977,0,0,0,2.848-1.646l.447.258a3,3,0,0,0,3-5.2Zm-2.548-3.776a7.048,7.048,0,0,1,0,3.75,1,1,0,0,0,.464,1.133l1.084.626a1,1,0,0,1-1,1.733l-1.086-.628a1,1,0,0,0-1.215.165,6.984,6.984,0,0,1-3.243,1.875,1,1,0,0,0-.751.969V21a1,1,0,0,1-2,0V19.748a1,1,0,0,0-.751-.969A6.984,6.984,0,0,1,7.006,16.9a1,1,0,0,0-1.215-.165l-1.084.627a1,1,0,1,1-1-1.732l1.084-.626a1,1,0,0,0,.464-1.133,7.048,7.048,0,0,1,0-3.75A1,1,0,0,0,4.79,8.992L3.706,8.366a1,1,0,0,1,1-1.733l1.086.628A1,1,0,0,0,7.006,7.1a6.984,6.984,0,0,1,3.243-1.875A1,1,0,0,0,11,4.252V3a1,1,0,0,1,2,0V4.252a1,1,0,0,0,.751.969A6.984,6.984,0,0,1,16.994,7.1a1,1,0,0,0,1.215.165l1.084-.627a1,1,0,1,1,1,1.732l-1.084.626A1,1,0,0,0,18.746,10.125Z"/></svg>';
425
426 // Status display
427 $status_classes = [
428 'active' => 'status-active',
429 'paused' => 'status-paused',
430 'error' => 'status-error',
431 ];
432 $status_labels = [
433 'active' => '<span class="dashicons dashicons-yes-alt"></span> ' . __( 'Active', 'wpforo' ),
434 'paused' => '<span class="dashicons dashicons-clock"></span> ' . __( 'Paused', 'wpforo' ),
435 'error' => '<span class="dashicons dashicons-warning"></span> ' . __( 'Error', 'wpforo' ),
436 ];
437 $status_class = isset( $status_classes[ $status ] ) ? $status_classes[ $status ] : 'status-paused';
438 $status_label = isset( $status_labels[ $status ] ) ? $status_labels[ $status ] : $status;
439
440 // Frequency display
441 $frequency_labels = [
442 'hourly' => __( 'Every Hour', 'wpforo' ),
443 '3hours' => __( 'Every 3 Hours', 'wpforo' ),
444 '6hours' => __( 'Every 6 Hours', 'wpforo' ),
445 'daily' => __( 'Daily', 'wpforo' ),
446 '3days' => __( 'Every 3 Days', 'wpforo' ),
447 'weekly' => __( 'Weekly', 'wpforo' ),
448 'custom' => __( 'Custom', 'wpforo' ),
449 ];
450 $frequency_label = isset( $frequency_labels[ $frequency ] ) ? $frequency_labels[ $frequency ] : $frequency;
451
452 // Check if run_on_approval is enabled
453 $run_on_approval = ! empty( $config['run_on_approval'] );
454
455 // Next run display (time until next run in "in X hours" style)
456 $next_run = $task['next_run_time'] ?? null;
457 $next_run_display = '';
458 $next_run_class = '';
459 if ( $run_on_approval && $status === 'active' ) {
460 // run_on_approval tasks trigger on topic/post approval, not cron
461 $next_run_display = __( 'New Topic', 'wpforo' );
462 $next_run_class = 'next-run-on-approval';
463 } elseif ( $next_run && $status === 'active' ) {
464 $next_run_display = wpforo_ai_format_time_until( $next_run );
465 // Check if overdue
466 if ( $next_run_display === __( 'overdue', 'wpforo' ) ) {
467 $next_run_class = 'next-run-overdue';
468 }
469 } elseif ( $status === 'paused' ) {
470 $next_run_display = __( 'Paused', 'wpforo' );
471 } else {
472 $next_run_display = '—';
473 }
474
475 // Last run display
476 $last_run_display = $last_run ? wpforo_ai_format_date( $last_run ) : __( 'Never', 'wpforo' );
477 $last_run_status_class = '';
478 if ( $last_run_status === 'success' ) {
479 $last_run_status_class = 'last-run-success';
480 } elseif ( $last_run_status === 'failure' ) {
481 $last_run_status_class = 'last-run-failure';
482 }
483
484 ?>
485 <tr data-task-id="<?php echo $task_id; ?>" data-task-type="<?php echo esc_attr( $task_type ); ?>" data-status="<?php echo esc_attr( $status ); ?>">
486 <td class="check-column">
487 <input type="checkbox" name="task_ids[]" value="<?php echo $task_id; ?>" class="wpforo-ai-task-checkbox">
488 </td>
489 <td class="column-name">
490 <strong class="wpforo-ai-task-name"><?php echo $task_name; ?></strong>
491 <div class="row-actions" style="display: none;">
492 <span class="edit">
493 <a href="#" class="wpforo-ai-task-edit" data-task-id="<?php echo $task_id; ?>"><?php _e( 'Edit', 'wpforo' ); ?></a> |
494 </span>
495 <span class="run">
496 <a href="#" class="wpforo-ai-task-run" data-task-id="<?php echo $task_id; ?>"><?php _e( 'Run Now', 'wpforo' ); ?></a> |
497 </span>
498 <span class="logs">
499 <a href="#" class="wpforo-ai-task-logs" data-task-id="<?php echo $task_id; ?>"><?php _e( 'View Logs', 'wpforo' ); ?></a> |
500 </span>
501 <span class="delete">
502 <a href="#" class="wpforo-ai-task-delete" data-task-id="<?php echo $task_id; ?>"><?php _e( 'Delete', 'wpforo' ); ?></a>
503 </span>
504 </div>
505 </td>
506 <td class="column-type">
507 <span class="wpforo-ai-task-type-badge">
508 <?php echo $type_icon; ?>
509 <?php echo $type_label; ?>
510 </span>
511 </td>
512 <td class="column-status">
513 <span class="wpforo-ai-task-status <?php echo esc_attr( $status_class ); ?>">
514 <?php echo $status_label; ?>
515 </span>
516 </td>
517 <td class="column-schedule">
518 <?php echo $run_on_approval ? '—' : $frequency_label; ?>
519 </td>
520 <td class="column-run-times <?php echo esc_attr( $last_run_status_class ); ?> <?php echo esc_attr( $next_run_class ); ?>">
521 <div class="wpforo-ai-next-run"><?php echo esc_html( $next_run_display ); ?></div>
522 <div class="wpforo-ai-last-run"><?php echo $last_run_display; ?></div>
523 </td>
524 <td class="column-stats">
525 <span class="wpforo-ai-task-stat" title="<?php esc_attr_e( 'Total Runs', 'wpforo' ); ?>">
526 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M20.492,7.969,10.954.975A5,5,0,0,0,3,5.005V19a4.994,4.994,0,0,0,7.954,4.03l9.538-6.994a5,5,0,0,0,0-8.062Z"/></svg>
527 <?php echo number_format( $total_runs ); ?>
528 </span>
529 <span class="wpforo-ai-task-stat" title="<?php esc_attr_e( 'Number of Items', 'wpforo' ); ?>">
530 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M18.656.93,6.464,13.122A4.966,4.966,0,0,0,5,16.657V18a1,1,0,0,0,1,1H7.343a4.966,4.966,0,0,0,3.535-1.464L23.07,5.344a3.125,3.125,0,0,0,0-4.414A3.194,3.194,0,0,0,18.656.93Zm3,3L9.464,16.122A3.02,3.02,0,0,1,7.343,17H7v-.343a3.02,3.02,0,0,1,.878-2.121L20.07,2.344a1.148,1.148,0,0,1,1.586,0A1.123,1.123,0,0,1,21.656,3.93Z"/><path d="M23,8.979a1,1,0,0,0-1,1V15H18a3,3,0,0,0-3,3v4H5a3,3,0,0,1-3-3V5A3,3,0,0,1,5,2h9.042a1,1,0,0,0,0-2H5A5.006,5.006,0,0,0,0,5V19a5.006,5.006,0,0,0,5,5H16.343a4.968,4.968,0,0,0,3.536-1.464l2.656-2.658A4.968,4.968,0,0,0,24,16.343V9.979A1,1,0,0,0,23,8.979ZM18.465,21.122a2.975,2.975,0,0,1-1.465.8V18a1,1,0,0,1,1-1h3.925a3.016,3.016,0,0,1-.8,1.464Z"/></svg>
531 <?php echo number_format( $items_created ); ?>
532 </span>
533 <span class="wpforo-ai-task-stat" title="<?php esc_attr_e( 'Credits Used', 'wpforo' ); ?>">
534 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M12,0C5.383,0,0,3.134,0,7v4c0,3.866,5.383,7,12,7s12-3.134,12-7V7C24,3.134,18.617,0,12,0Zm10,11c0,2.414-4.037,5-10,5S2,13.414,2,11V9.455C4.144,11.03,7.789,12,12,12s7.856-.97,10-2.545V11ZM12,2c5.963,0,10,2.586,10,5s-4.037,5-10,5S2,9.414,2,7,6.037,2,12,2Z"/><path d="M12,16c-6.617,0-12-3.134-12-7v6c0,3.866,5.383,7,12,7s12-3.134,12-7v-6C24,12.866,18.617,16,12,16Zm0,5c-5.963,0-10-2.586-10-5v-2.545C4.144,15.03,7.789,16,12,16s7.856-.97,10-2.545V16C22,18.414,17.963,21,12,21Z"/></svg>
535 <?php echo number_format( $credits_used ); ?>
536 </span>
537 </td>
538 <td class="column-actions">
539 <div class="wpforo-ai-task-actions-dropdown">
540 <button type="button" class="wpforo-ai-task-actions-toggle">
541 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M12,8a4,4,0,1,0,4,4A4,4,0,0,0,12,8Zm0,6a2,2,0,1,1,2-2A2,2,0,0,1,12,14Z"/><path d="M21.294,13.9l-.444-.256a9.1,9.1,0,0,0,0-3.29l.444-.256a3,3,0,1,0-3-5.2l-.445.257A8.977,8.977,0,0,0,15,3.513V3A3,3,0,0,0,9,3v.513A8.977,8.977,0,0,0,6.152,5.159L5.705,4.9a3,3,0,0,0-3,5.2l.444.256a9.1,9.1,0,0,0,0,3.29l-.444.256a3,3,0,1,0,3,5.2l.445-.257A8.977,8.977,0,0,0,9,20.487V21a3,3,0,0,0,6,0v-.513a8.977,8.977,0,0,0,2.848-1.646l.447.258a3,3,0,0,0,3-5.2Zm-2.548-3.776a7.048,7.048,0,0,1,0,3.75,1,1,0,0,0,.464,1.133l1.084.626a1,1,0,0,1-1,1.733l-1.086-.628a1,1,0,0,0-1.215.165,6.984,6.984,0,0,1-3.243,1.875,1,1,0,0,0-.751.969V21a1,1,0,0,1-2,0V19.748a1,1,0,0,0-.751-.969A6.984,6.984,0,0,1,7.006,16.9a1,1,0,0,0-1.215-.165l-1.084.627a1,1,0,1,1-1-1.732l1.084-.626a1,1,0,0,0,.464-1.133,7.048,7.048,0,0,1,0-3.75A1,1,0,0,0,4.79,8.992L3.706,8.366a1,1,0,0,1,1-1.733l1.086.628A1,1,0,0,0,7.006,7.1a6.984,6.984,0,0,1,3.243-1.875A1,1,0,0,0,11,4.252V3a1,1,0,0,1,2,0V4.252a1,1,0,0,0,.751.969A6.984,6.984,0,0,1,16.994,7.1a1,1,0,0,0,1.215.165l1.084-.627a1,1,0,1,1,1,1.732l-1.084.626A1,1,0,0,0,18.746,10.125Z"/></svg>
542 </button>
543 <div class="wpforo-ai-task-actions-menu">
544 <a href="#" class="wpforo-ai-task-run" data-task-id="<?php echo $task_id; ?>">
545 <span class="dashicons dashicons-controls-play"></span>
546 <?php _e( 'Run Now', 'wpforo' ); ?>
547 </a>
548 <?php if ( $status === 'active' ) : ?>
549 <a href="#" class="wpforo-ai-task-pause" data-task-id="<?php echo $task_id; ?>">
550 <span class="dashicons dashicons-controls-pause"></span>
551 <?php _e( 'Pause', 'wpforo' ); ?>
552 </a>
553 <?php else : ?>
554 <a href="#" class="wpforo-ai-task-activate" data-task-id="<?php echo $task_id; ?>">
555 <span class="dashicons dashicons-controls-play"></span>
556 <?php _e( 'Activate', 'wpforo' ); ?>
557 </a>
558 <?php endif; ?>
559 <a href="#" class="wpforo-ai-task-edit" data-task-id="<?php echo $task_id; ?>">
560 <span class="dashicons dashicons-edit"></span>
561 <?php _e( 'Edit', 'wpforo' ); ?>
562 </a>
563 <a href="#" class="wpforo-ai-task-duplicate" data-task-id="<?php echo $task_id; ?>">
564 <span class="dashicons dashicons-admin-page"></span>
565 <?php _e( 'Duplicate', 'wpforo' ); ?>
566 </a>
567 <a href="#" class="wpforo-ai-task-stats" data-task-id="<?php echo $task_id; ?>">
568 <span class="dashicons dashicons-chart-bar"></span>
569 <?php _e( 'View Stats', 'wpforo' ); ?>
570 </a>
571 <a href="#" class="wpforo-ai-task-logs" data-task-id="<?php echo $task_id; ?>">
572 <span class="dashicons dashicons-list-view"></span>
573 <?php _e( 'View Logs', 'wpforo' ); ?>
574 </a>
575 <hr>
576 <a href="#" class="wpforo-ai-task-delete" data-task-id="<?php echo $task_id; ?>">
577 <span class="dashicons dashicons-trash"></span>
578 <?php _e( 'Delete', 'wpforo' ); ?>
579 </a>
580 </div>
581 </div>
582 </td>
583 </tr>
584 <?php
585 }
586
587 /**
588 * Render task type configuration templates (hidden, used by JavaScript)
589 *
590 * @param int $board_id Current board ID
591 */
592 function wpforo_ai_render_task_type_templates( $board_id = 0 ) {
593 // Get forums for the current board and sort hierarchically
594 $forums = WPF()->forum->get_forums();
595
596 // Sort forums hierarchically: parents first, then children under each parent
597 $forums_by_parent = [];
598 foreach ( $forums as $forum ) {
599 $parent = (int) ( $forum['parentid'] ?? 0 );
600 if ( ! isset( $forums_by_parent[ $parent ] ) ) {
601 $forums_by_parent[ $parent ] = [];
602 }
603 $forums_by_parent[ $parent ][] = $forum;
604 }
605 foreach ( $forums_by_parent as &$children ) {
606 usort( $children, function( $a, $b ) {
607 return (int) ( $a['order'] ?? 0 ) - (int) ( $b['order'] ?? 0 );
608 } );
609 }
610 unset( $children );
611 $sorted_forums = [];
612 $add_forums_recursive = function( $parentid ) use ( &$add_forums_recursive, &$sorted_forums, &$forums_by_parent ) {
613 if ( ! isset( $forums_by_parent[ $parentid ] ) ) {
614 return;
615 }
616 foreach ( $forums_by_parent[ $parentid ] as $forum ) {
617 $sorted_forums[] = $forum;
618 $add_forums_recursive( (int) $forum['forumid'] );
619 }
620 };
621 $add_forums_recursive( 0 );
622 $forums = $sorted_forums;
623 ?>
624
625 <!-- Topic Generator Configuration Template -->
626 <script type="text/template" id="wpforo-ai-task-config-topic_generator">
627 <?php wpforo_ai_render_topic_generator_config( $forums ); ?>
628 </script>
629
630 <!-- Reply Generator Configuration Template -->
631 <script type="text/template" id="wpforo-ai-task-config-reply_generator">
632 <?php wpforo_ai_render_reply_generator_config( $forums ); ?>
633 </script>
634
635 <!-- Tag Maintenance Configuration Template -->
636 <script type="text/template" id="wpforo-ai-task-config-tag_maintenance">
637 <?php wpforo_ai_render_tag_maintenance_config( $forums ); ?>
638 </script>
639 <?php
640 }
641
642 /**
643 * Render Topic Generator configuration form fields
644 *
645 * @param array $forums Array of forums
646 */
647 function wpforo_ai_render_topic_generator_config( $forums ) {
648 ?>
649 <!-- Content Settings Section -->
650 <div class="wpforo-ai-form-section">
651 <h3 class="wpforo-ai-form-section-title">
652 <span class="dashicons dashicons-edit-page"></span>
653 <?php _e( 'Content Settings', 'wpforo' ); ?>
654 </h3>
655
656 <div class="wpforo-ai-two-column-layout">
657 <!-- Left Column: Target Forums -->
658 <div class="wpforo-ai-column wpforo-ai-column-left">
659 <div class="wpforo-ai-form-field">
660 <label><?php _e( 'Target Forums', 'wpforo' ); ?> <span class="required">*</span></label>
661 <div class="wpforo-ai-forum-checklist">
662 <?php foreach ( $forums as $forum ) :
663 $forum_id = (int) $forum['forumid'];
664 $forum_title = esc_html( $forum['title'] );
665 $parent_id = (int) $forum['parentid'];
666 $is_cat = (int) $forum['is_cat'];
667 $item_class = $parent_id > 0 ? 'wpforo-ai-forum-child' : 'wpforo-ai-forum-parent';
668 if ( $is_cat ) {
669 $item_class .= ' wpforo-ai-forum-category';
670 }
671 ?>
672 <label class="wpforo-ai-forum-checkbox-item <?php echo esc_attr( $item_class ); ?>">
673 <?php if ( $is_cat ) : ?>
674 <input type="checkbox"
675 class="forum-checkbox forum-parent-toggle"
676 data-forum-id="<?php echo $forum_id; ?>"
677 data-parent-id="<?php echo $parent_id; ?>"
678 data-is-category="1">
679 <?php else : ?>
680 <input type="checkbox"
681 name="config[target_forum_ids][]"
682 value="<?php echo $forum_id; ?>"
683 class="forum-checkbox"
684 data-forum-id="<?php echo $forum_id; ?>"
685 data-parent-id="<?php echo $parent_id; ?>"
686 data-is-category="0">
687 <?php endif; ?>
688 <?php echo $forum_title; ?>
689 </label>
690 <?php endforeach; ?>
691 </div>
692 <div class="wpforo-ai-forum-actions">
693 <button type="button" class="button button-small wpforo-ai-select-all-forums">
694 <?php _e( 'Select All', 'wpforo' ); ?>
695 </button>
696 <button type="button" class="button button-small wpforo-ai-deselect-all-forums">
697 <?php _e( 'Deselect All', 'wpforo' ); ?>
698 </button>
699 </div>
700 <p class="description"><?php _e( 'Select forums where new topics will be created', 'wpforo' ); ?></p>
701 </div>
702 </div>
703
704 <!-- Right Column: Topic Settings -->
705 <div class="wpforo-ai-column wpforo-ai-column-right">
706 <div class="wpforo-ai-form-field">
707 <label for="wpforo-ai-config-topic_theme"><?php _e( 'Topic Theme/Focus', 'wpforo' ); ?></label>
708 <div class="wpforo-ai-textarea-with-counter">
709 <textarea id="wpforo-ai-config-topic_theme" name="config[topic_theme]" rows="3" maxlength="120" placeholder="<?php esc_attr_e( 'e.g., Web development tutorials, JavaScript tips...', 'wpforo' ); ?>" data-char-limit="120"></textarea>
710 <span class="wpforo-ai-char-counter"><span class="current">0</span>/120</span>
711 </div>
712 <p class="description"><?php _e( 'Brief theme to guide topic creation (max 120 characters)', 'wpforo' ); ?></p>
713 </div>
714
715 <div class="wpforo-ai-form-field">
716 <label for="wpforo-ai-config-topic_style"><?php _e( 'Topic Style', 'wpforo' ); ?></label>
717 <select id="wpforo-ai-config-topic_style" name="config[topic_style]" required>
718 <option value="neutral" selected="selected"><?php _e( 'Neutral - Let custom instructions decide', 'wpforo' ); ?></option>
719 <option value="tutorial"><?php _e( 'Tutorial - Step-by-step guide', 'wpforo' ); ?></option>
720 <option value="question"><?php _e( 'Question - Asking for help/opinions', 'wpforo' ); ?></option>
721 <option value="discussion"><?php _e( 'Discussion - Open conversation starter', 'wpforo' ); ?></option>
722 <option value="news"><?php _e( 'News - Updates and announcements', 'wpforo' ); ?></option>
723 <option value="tips"><?php _e( 'Tips & Tricks - Quick helpful hints', 'wpforo' ); ?></option>
724 <option value="how_to"><?php _e( 'How-To Guide - Practical instructions', 'wpforo' ); ?></option>
725 <option value="review"><?php _e( 'Review - Product/service evaluation', 'wpforo' ); ?></option>
726 <option value="comparison"><?php _e( 'Comparison - Comparing options', 'wpforo' ); ?></option>
727 <option value="case_study"><?php _e( 'Case Study - Real-world example', 'wpforo' ); ?></option>
728 <option value="opinion"><?php _e( 'Opinion Piece - Personal perspective', 'wpforo' ); ?></option>
729 <option value="problem_solution"><?php _e( 'Problem/Solution - Issues and fixes', 'wpforo' ); ?></option>
730 <option value="listicle"><?php _e( 'List/Roundup - Curated collection', 'wpforo' ); ?></option>
731 <option value="interview"><?php _e( 'Interview Style - Q&A format', 'wpforo' ); ?></option>
732 <option value="beginners_guide"><?php _e( 'Beginner\'s Guide - Introductory content', 'wpforo' ); ?></option>
733 <option value="deep_dive"><?php _e( 'Deep Dive - In-depth analysis', 'wpforo' ); ?></option>
734 <option value="best_practices"><?php _e( 'Best Practices - Recommended approaches', 'wpforo' ); ?></option>
735 <option value="troubleshooting"><?php _e( 'Troubleshooting - Fixing common issues', 'wpforo' ); ?></option>
736 <option value="resources"><?php _e( 'Resource Collection - Useful links/tools', 'wpforo' ); ?></option>
737 <option value="myth_busting"><?php _e( 'Myth Busting - Correcting misconceptions', 'wpforo' ); ?></option>
738 <option value="success_story"><?php _e( 'Success Story - Sharing achievements', 'wpforo' ); ?></option>
739 <option value="challenge"><?php _e( 'Challenge/Exercise - Interactive content', 'wpforo' ); ?></option>
740 <option value="faq"><?php _e( 'FAQ - Frequently asked questions', 'wpforo' ); ?></option>
741 </select>
742 </div>
743
744 <div class="wpforo-ai-form-field">
745 <label for="wpforo-ai-config-topic_tone"><?php _e( 'Topic Tone', 'wpforo' ); ?></label>
746 <select id="wpforo-ai-config-topic_tone" name="config[topic_tone]" required>
747 <option value="neutral" selected="selected"><?php _e( 'Neutral - Let custom instructions decide', 'wpforo' ); ?></option>
748 <option value="professional"><?php _e( 'Professional - Business-like and formal', 'wpforo' ); ?></option>
749 <option value="friendly"><?php _e( 'Friendly - Warm and approachable', 'wpforo' ); ?></option>
750 <option value="casual"><?php _e( 'Casual - Relaxed and informal', 'wpforo' ); ?></option>
751 <option value="technical"><?php _e( 'Technical - Detailed and precise', 'wpforo' ); ?></option>
752 <option value="enthusiastic"><?php _e( 'Enthusiastic - Excited and energetic', 'wpforo' ); ?></option>
753 <option value="helpful"><?php _e( 'Helpful - Supportive and guiding', 'wpforo' ); ?></option>
754 <option value="authoritative"><?php _e( 'Authoritative - Expert and confident', 'wpforo' ); ?></option>
755 <option value="conversational"><?php _e( 'Conversational - Like chatting with a friend', 'wpforo' ); ?></option>
756 <option value="educational"><?php _e( 'Educational - Teaching and informative', 'wpforo' ); ?></option>
757 <option value="inspirational"><?php _e( 'Inspirational - Motivating and uplifting', 'wpforo' ); ?></option>
758 <option value="humorous"><?php _e( 'Humorous - Light-hearted and witty', 'wpforo' ); ?></option>
759 <option value="serious"><?php _e( 'Serious - Focused and earnest', 'wpforo' ); ?></option>
760 <option value="encouraging"><?php _e( 'Encouraging - Positive and supportive', 'wpforo' ); ?></option>
761 <option value="warm"><?php _e( 'Warm - Caring and compassionate', 'wpforo' ); ?></option>
762 <option value="direct"><?php _e( 'Direct - Straightforward and to the point', 'wpforo' ); ?></option>
763 <option value="thoughtful"><?php _e( 'Thoughtful - Considerate and reflective', 'wpforo' ); ?></option>
764 <option value="empathetic"><?php _e( 'Empathetic - Understanding and relatable', 'wpforo' ); ?></option>
765 <option value="confident"><?php _e( 'Confident - Self-assured and decisive', 'wpforo' ); ?></option>
766 <option value="curious"><?php _e( 'Curious - Inquisitive and engaging', 'wpforo' ); ?></option>
767 <option value="playful"><?php _e( 'Playful - Fun and lighthearted', 'wpforo' ); ?></option>
768 <option value="sincere"><?php _e( 'Sincere - Genuine and honest', 'wpforo' ); ?></option>
769 </select>
770 </div>
771
772 <div class="wpforo-ai-form-field">
773 <label for="wpforo-ai-config-content_length"><?php _e( 'Content Length', 'wpforo' ); ?></label>
774 <select id="wpforo-ai-config-content_length" name="config[content_length]" required>
775 <option value="brief"><?php _e( 'Brief (100-200 words)', 'wpforo' ); ?></option>
776 <option value="medium" selected="selected"><?php _e( 'Medium (200-400 words)', 'wpforo' ); ?></option>
777 <option value="detailed"><?php _e( 'Detailed (400-800 words)', 'wpforo' ); ?></option>
778 <option value="comprehensive"><?php _e( 'Comprehensive (800-1200 words)', 'wpforo' ); ?></option>
779 </select>
780 </div>
781
782 <div class="wpforo-ai-form-field">
783 <label><?php _e( 'Include in Topics', 'wpforo' ); ?></label>
784 <div class="wpforo-ai-checkbox-group wpforo-ai-checkbox-group-inline">
785 <label class="wpforo-ai-checkbox-item">
786 <input type="checkbox" name="config[include_code]" value="1">
787 <span><?php _e( 'Code examples', 'wpforo' ); ?></span>
788 </label>
789 <label class="wpforo-ai-checkbox-item">
790 <input type="checkbox" name="config[include_links]" value="1">
791 <span><?php _e( 'External links', 'wpforo' ); ?></span>
792 </label>
793 <label class="wpforo-ai-checkbox-item">
794 <input type="checkbox" name="config[include_steps]" value="1">
795 <span><?php _e( 'Step-by-step instructions', 'wpforo' ); ?></span>
796 </label>
797 <label class="wpforo-ai-checkbox-item">
798 <input type="checkbox" name="config[include_youtube]" value="1">
799 <span><?php _e( 'YouTube video URLs', 'wpforo' ); ?></span>
800 </label>
801 </div>
802 </div>
803 </div>
804 </div>
805 </div>
806
807 <!-- Author Settings & Scheduling Section -->
808 <div class="wpforo-ai-form-section">
809 <div class="wpforo-ai-two-column-layout">
810 <!-- Left Column: Author Settings -->
811 <div class="wpforo-ai-column wpforo-ai-column-left">
812 <h3 class="wpforo-ai-form-section-title">
813 <span class="dashicons dashicons-admin-users"></span>
814 <?php _e( 'Author Settings', 'wpforo' ); ?>
815 </h3>
816
817 <div class="wpforo-ai-form-row">
818 <div class="wpforo-ai-form-field">
819 <label for="wpforo-ai-config-author_userid"><?php _e( 'Topic Author', 'wpforo' ); ?></label>
820 <div class="wpforo-ai-user-search-wrapper">
821 <input type="hidden" id="wpforo-ai-config-author_userid" name="config[author_userid]" class="wpforo-ai-user-id-input">
822 <input type="text" id="wpforo-ai-config-author_search" class="wpforo-ai-user-search" placeholder="<?php esc_attr_e( 'Type to search users...', 'wpforo' ); ?>" autocomplete="off">
823 <div class="wpforo-ai-user-search-results"></div>
824 </div>
825 <p class="description"><?php _e( 'Search by username, display name, or email. Only activated users are shown.', 'wpforo' ); ?></p>
826 </div>
827 </div>
828
829 <div class="wpforo-ai-author-or-separator">
830 <span><?php _e( '-- OR --', 'wpforo' ); ?></span>
831 </div>
832
833 <div class="wpforo-ai-form-row">
834 <div class="wpforo-ai-form-field">
835 <label for="wpforo-ai-config-author_groupid"><?php _e( 'Author Usergroup', 'wpforo' ); ?></label>
836 <select id="wpforo-ai-config-author_groupid" name="config[author_groupid]" class="wpforo-ai-author-groupid-select">
837 <option value=""><?php _e( '-- Select Usergroup --', 'wpforo' ); ?></option>
838 <?php
839 $usergroups = WPF()->usergroup->get_usergroups();
840 if ( ! empty( $usergroups ) ) :
841 foreach ( $usergroups as $group ) :
842 $gid = intval( $group['groupid'] );
843 if ( $gid === 4 ) continue; // Exclude Guest group
844 ?>
845 <option value="<?php echo esc_attr( $gid ); ?>"><?php echo esc_html( $group['name'] ); ?></option>
846 <?php endforeach;
847 endif;
848 ?>
849 </select>
850 <p class="description"><?php _e( 'Randomly selects a user from this group for each generated topic.', 'wpforo' ); ?></p>
851 </div>
852 </div>
853
854 <div class="wpforo-ai-form-row">
855 <div class="wpforo-ai-form-field">
856 <label class="wpforo-ai-checkbox-item">
857 <input type="checkbox" name="config[show_ai_badge]" value="1">
858 <span><?php _e( 'Add AI disclosure notice to generated content', 'wpforo' ); ?></span>
859 </label>
860 <p class="description"><?php _e( 'Adds a small disclaimer line at the end of AI-generated topics indicating the content was created by AI.', 'wpforo' ); ?></p>
861 </div>
862 </div>
863 </div>
864
865 <!-- Right Column: Scheduling -->
866 <div class="wpforo-ai-column wpforo-ai-column-right">
867 <h3 class="wpforo-ai-form-section-title">
868 <span class="dashicons dashicons-calendar-alt"></span>
869 <?php _e( 'Scheduling', 'wpforo' ); ?>
870 </h3>
871
872 <div class="wpforo-ai-form-row">
873 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
874 <label for="wpforo-ai-config-frequency"><?php _e( 'Frequency', 'wpforo' ); ?> <span class="required">*</span></label>
875 <select id="wpforo-ai-config-frequency" name="config[frequency]" required>
876 <option value="hourly"><?php _e( 'Every Hour', 'wpforo' ); ?></option>
877 <option value="3hours"><?php _e( 'Every 3 Hours', 'wpforo' ); ?></option>
878 <option value="6hours"><?php _e( 'Every 6 Hours', 'wpforo' ); ?></option>
879 <option value="daily" selected="selected"><?php _e( 'Daily', 'wpforo' ); ?></option>
880 <option value="3days"><?php _e( 'Every 3 Days', 'wpforo' ); ?></option>
881 <option value="weekly"><?php _e( 'Weekly', 'wpforo' ); ?></option>
882 </select>
883 </div>
884
885 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
886 <label for="wpforo-ai-config-topics_per_run"><?php _e( 'Topics Per Run', 'wpforo' ); ?></label>
887 <select id="wpforo-ai-config-topics_per_run" name="config[topics_per_run]">
888 <option value="1" selected="selected">1</option>
889 <option value="2">2</option>
890 <option value="3">3</option>
891 <option value="5">5</option>
892 <option value="10">10</option>
893 </select>
894 </div>
895 </div>
896
897 <div class="wpforo-ai-form-row">
898 <div class="wpforo-ai-form-field">
899 <label><?php _e( 'Active Days', 'wpforo' ); ?></label>
900 <div class="wpforo-ai-checkbox-group wpforo-ai-checkbox-group-inline">
901 <?php
902 $days = [
903 'mon' => __( 'Mon', 'wpforo' ),
904 'tue' => __( 'Tue', 'wpforo' ),
905 'wed' => __( 'Wed', 'wpforo' ),
906 'thu' => __( 'Thu', 'wpforo' ),
907 'fri' => __( 'Fri', 'wpforo' ),
908 'sat' => __( 'Sat', 'wpforo' ),
909 'sun' => __( 'Sun', 'wpforo' ),
910 ];
911 foreach ( $days as $day_key => $day_label ) :
912 ?>
913 <label class="wpforo-ai-checkbox-item">
914 <input type="checkbox" name="config[active_days][]" value="<?php echo $day_key; ?>" checked>
915 <span><?php echo $day_label; ?></span>
916 </label>
917 <?php endforeach; ?>
918 </div>
919 <p class="description"><?php _e( 'Task will only run on selected days', 'wpforo' ); ?></p>
920 </div>
921 </div>
922 </div>
923 </div>
924 </div>
925
926 <!-- AI Quality & Credits + Content Safety Section -->
927 <div class="wpforo-ai-form-section">
928 <div class="wpforo-ai-two-column-layout">
929 <!-- Left Column: AI Quality & Credits -->
930 <div class="wpforo-ai-column wpforo-ai-column-left">
931 <h3 class="wpforo-ai-form-section-title">
932 <span class="dashicons dashicons-admin-generic"></span>
933 <?php _e( 'AI Quality & Credits', 'wpforo' ); ?>
934 </h3>
935
936 <div class="wpforo-ai-form-row">
937 <div class="wpforo-ai-form-field">
938 <label for="wpforo-ai-config-quality_tier"><?php _e( 'AI Quality Level', 'wpforo' ); ?> <span class="required">*</span></label>
939 <select id="wpforo-ai-config-quality_tier" name="config[quality_tier]" required>
940 <option value="fast"><?php _e( 'Fast - 1 credit per topic', 'wpforo' ); ?></option>
941 <option value="balanced"><?php _e( 'Balanced - 2 credits per topic', 'wpforo' ); ?></option>
942 <option value="advanced"><?php _e( 'Advanced - 3 credits per topic', 'wpforo' ); ?></option>
943 <option value="premium" selected="selected"><?php _e( 'Premium - 4 credits per topic', 'wpforo' ); ?></option>
944 </select>
945 </div>
946 </div>
947
948 <div class="wpforo-ai-form-row">
949 <div class="wpforo-ai-form-field">
950 <label for="wpforo-ai-config-credit_stop_threshold"><?php _e( 'Credit Stop Threshold', 'wpforo' ); ?></label>
951 <input type="number" id="wpforo-ai-config-credit_stop_threshold" name="config[credit_stop_threshold]" min="0" value="500" placeholder="0">
952 <p class="description"><?php _e( 'Stop when credits fall below this', 'wpforo' ); ?></p>
953 </div>
954 </div>
955
956 <div class="wpforo-ai-form-row">
957 <div class="wpforo-ai-form-field">
958 <label class="wpforo-ai-checkbox-item">
959 <input type="checkbox" name="config[auto_pause_on_limit]" value="1" checked>
960 <span><?php _e( 'Auto-pause when limit reached', 'wpforo' ); ?></span>
961 </label>
962 </div>
963 </div>
964
965 <div class="wpforo-ai-estimated-credits-notice">
966 <span class="dashicons dashicons-info-outline"></span>
967 <span class="wpforo-ai-estimated-credits-text">
968 <?php _e( 'Estimated monthly usage:', 'wpforo' ); ?>
969 <strong class="wpforo-ai-estimated-credits-value">~60 credits</strong>
970 </span>
971 </div>
972
973 <div class="wpforo-ai-credit-saving-notice">
974 <span class="dashicons dashicons-saved"></span>
975 <span class="wpforo-ai-credit-saving-text">
976 <strong><?php _e( 'Credit Saving Tip:', 'wpforo' ); ?></strong>
977 <?php _e( 'Manual Run is available. Create this task as paused, then manually run it whenever you want.', 'wpforo' ); ?>
978 <span class="wpforo-ai-manual-run-cost"><?php _e( 'One manual run costs:', 'wpforo' ); ?> <strong class="wpforo-ai-manual-run-cost-value">4 credits</strong></span>
979 </span>
980 </div>
981 </div>
982
983 <!-- Right Column: Content Safety -->
984 <div class="wpforo-ai-column wpforo-ai-column-right">
985 <h3 class="wpforo-ai-form-section-title">
986 <span class="dashicons dashicons-shield"></span>
987 <?php _e( 'Content Safety', 'wpforo' ); ?>
988 </h3>
989
990 <div class="wpforo-ai-form-row">
991 <div class="wpforo-ai-form-field">
992 <label class="wpforo-ai-checkbox-item">
993 <input type="checkbox" name="config[duplicate_prevention]" value="1" checked>
994 <span><?php _e( 'Enable duplicate prevention', 'wpforo' ); ?></span>
995 </label>
996 </div>
997 </div>
998
999 <div class="wpforo-ai-form-row wpforo-ai-duplicate-settings">
1000 <div class="wpforo-ai-form-field">
1001 <label for="wpforo-ai-config-similarity_threshold"><?php _e( 'Similarity Threshold', 'wpforo' ); ?></label>
1002 <input type="range" id="wpforo-ai-config-similarity_threshold" name="config[similarity_threshold]" min="0" max="100" value="75" class="wpforo-ai-range-slider">
1003 <span class="wpforo-ai-range-value">75%</span>
1004 </div>
1005 </div>
1006
1007 <div class="wpforo-ai-form-row wpforo-ai-duplicate-settings">
1008 <div class="wpforo-ai-form-field">
1009 <label for="wpforo-ai-config-duplicate_check_days"><?php _e( 'Check Period', 'wpforo' ); ?></label>
1010 <input type="number" id="wpforo-ai-config-duplicate_check_days" name="config[duplicate_check_days]" min="0" max="365" value="90" style="width: 80px; display: inline-block;">
1011 <span class="wpforo-ai-input-suffix"><?php _e( 'days', 'wpforo' ); ?></span>
1012 <p class="description"><?php _e( '0 = check all topics, or limit to last N days', 'wpforo' ); ?></p>
1013 </div>
1014 </div>
1015
1016 <div class="wpforo-ai-form-row">
1017 <div class="wpforo-ai-form-field">
1018 <label><?php _e( 'Topic Status', 'wpforo' ); ?></label>
1019 <div class="wpforo-ai-radio-group">
1020 <label class="wpforo-ai-radio-item">
1021 <input type="radio" name="config[topic_status]" value="0" checked>
1022 <span class="wpforo-ai-radio-label"><?php _e( 'Published', 'wpforo' ); ?></span>
1023 </label>
1024 <label class="wpforo-ai-radio-item">
1025 <input type="radio" name="config[topic_status]" value="1">
1026 <span class="wpforo-ai-radio-label"><?php _e( 'Unapproved', 'wpforo' ); ?></span>
1027 </label>
1028 </div>
1029 </div>
1030 </div>
1031
1032 </div>
1033 </div>
1034 </div>
1035
1036 <!-- Advanced Options Section (Collapsible) -->
1037 <div class="wpforo-ai-form-section wpforo-ai-form-section-collapsible">
1038 <h3 class="wpforo-ai-form-section-title wpforo-ai-collapsible-toggle" aria-expanded="false">
1039 <span class="dashicons dashicons-admin-settings"></span>
1040 <?php _e( 'Advanced Options', 'wpforo' ); ?>
1041 <span class="dashicons dashicons-arrow-down-alt2 wpforo-ai-toggle-icon"></span>
1042 </h3>
1043
1044 <div class="wpforo-ai-collapsible-content" style="display: none;">
1045 <div class="wpforo-ai-form-row">
1046 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1047 <label for="wpforo-ai-config-topic_prefix"><?php _e( 'Topic Prefix', 'wpforo' ); ?></label>
1048 <?php if ( function_exists( 'WPF_TOPIC_PREFIX' ) ) : ?>
1049 <?php
1050 // wpForo Topic Prefix addon is active - show dropdown
1051 $prefix_dropdown = WPF_TOPIC_PREFIX()->prefix_list( 'dropdown', 0, '', -1, false );
1052 ?>
1053 <select id="wpforo-ai-config-topic_prefix_id" name="config[topic_prefix_id]">
1054 <?php echo $prefix_dropdown; ?>
1055 </select>
1056 <input type="hidden" name="config[topic_prefix]" value="">
1057 <p class="description"><?php _e( 'Select a topic prefix from wpForo Topic Prefix addon', 'wpforo' ); ?></p>
1058 <?php else : ?>
1059 <input type="text" id="wpforo-ai-config-topic_prefix" name="config[topic_prefix]" maxlength="50" placeholder="<?php esc_attr_e( 'e.g., [Tutorial]', 'wpforo' ); ?>">
1060 <input type="hidden" name="config[topic_prefix_id]" value="">
1061 <p class="description"><?php _e( 'Optional prefix added to topic titles', 'wpforo' ); ?></p>
1062 <?php endif; ?>
1063 </div>
1064
1065 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1066 <label for="wpforo-ai-config-auto_tags"><?php _e( 'Auto-Tags', 'wpforo' ); ?></label>
1067 <input type="text" id="wpforo-ai-config-auto_tags" name="config[auto_tags]" placeholder="<?php esc_attr_e( 'tag1, tag2, tag3', 'wpforo' ); ?>">
1068 <p class="description"><?php _e( 'Comma-separated tags to add to topics', 'wpforo' ); ?></p>
1069 </div>
1070 </div>
1071
1072 <div class="wpforo-ai-form-row">
1073 <div class="wpforo-ai-form-field">
1074 <label for="wpforo-ai-config-search_keywords"><?php _e( 'Search Keywords for Ideas', 'wpforo' ); ?></label>
1075 <input type="text" id="wpforo-ai-config-search_keywords" name="config[search_keywords]" placeholder="<?php esc_attr_e( 'e.g., javascript, react, nodejs', 'wpforo' ); ?>">
1076 <p class="description"><?php _e( 'Keywords to help AI find topic inspiration from your forum content', 'wpforo' ); ?></p>
1077 </div>
1078 </div>
1079 </div>
1080 </div>
1081 <?php
1082 }
1083
1084 /**
1085 * Render Reply Generator configuration form fields
1086 *
1087 * @param array $forums Array of forums
1088 */
1089 function wpforo_ai_render_reply_generator_config( $forums ) {
1090 ?>
1091 <!-- Target Settings Section -->
1092 <div class="wpforo-ai-form-section">
1093 <h3 class="wpforo-ai-form-section-title">
1094 <span class="dashicons dashicons-admin-comments"></span>
1095 <?php _e( 'Target Settings', 'wpforo' ); ?>
1096 </h3>
1097 <p class="wpforo-ai-section-description"><?php _e( 'Select forums to reply to random topics, or specify exact topic IDs. Both can be combined for random selection between them.', 'wpforo' ); ?></p>
1098
1099 <div class="wpforo-ai-two-column-layout">
1100 <!-- Left Column: Forum Selection -->
1101 <div class="wpforo-ai-column wpforo-ai-column-left">
1102 <div class="wpforo-ai-form-field">
1103 <label><?php _e( 'Target Forums', 'wpforo' ); ?></label>
1104 <div class="wpforo-ai-forum-checklist">
1105 <?php foreach ( $forums as $forum ) :
1106 $forum_id = (int) $forum['forumid'];
1107 $forum_title = esc_html( $forum['title'] );
1108 $parent_id = (int) $forum['parentid'];
1109 $is_cat = (int) $forum['is_cat'];
1110 $item_class = $parent_id > 0 ? 'wpforo-ai-forum-child' : 'wpforo-ai-forum-parent';
1111 if ( $is_cat ) {
1112 $item_class .= ' wpforo-ai-forum-category';
1113 }
1114 ?>
1115 <label class="wpforo-ai-forum-checkbox-item <?php echo esc_attr( $item_class ); ?>">
1116 <?php if ( $is_cat ) : ?>
1117 <input type="checkbox"
1118 class="forum-checkbox forum-parent-toggle"
1119 data-forum-id="<?php echo $forum_id; ?>"
1120 data-parent-id="<?php echo $parent_id; ?>"
1121 data-is-category="1">
1122 <?php else : ?>
1123 <input type="checkbox"
1124 name="config[reply_target_forum_ids][]"
1125 value="<?php echo $forum_id; ?>"
1126 class="forum-checkbox"
1127 data-forum-id="<?php echo $forum_id; ?>"
1128 data-parent-id="<?php echo $parent_id; ?>"
1129 data-is-category="0">
1130 <?php endif; ?>
1131 <?php echo $forum_title; ?>
1132 </label>
1133 <?php endforeach; ?>
1134 </div>
1135 <div class="wpforo-ai-forum-actions">
1136 <button type="button" class="button button-small wpforo-ai-select-all-forums">
1137 <?php _e( 'Select All', 'wpforo' ); ?>
1138 </button>
1139 <button type="button" class="button button-small wpforo-ai-deselect-all-forums">
1140 <?php _e( 'Deselect All', 'wpforo' ); ?>
1141 </button>
1142 </div>
1143 <p class="description"><?php _e( 'Random topic from selected forums (excludes private, closed, unapproved)', 'wpforo' ); ?></p>
1144 </div>
1145 </div>
1146
1147 <!-- Right Column: Topic IDs and Date Range -->
1148 <div class="wpforo-ai-column wpforo-ai-column-right">
1149 <div class="wpforo-ai-form-field">
1150 <label for="wpforo-ai-config-target_topic_ids"><?php _e( 'Target Topic IDs', 'wpforo' ); ?></label>
1151 <textarea id="wpforo-ai-config-target_topic_ids" name="config[target_topic_ids]" rows="3" placeholder="<?php esc_attr_e( 'e.g.: 123, 456, 789', 'wpforo' ); ?>"></textarea>
1152 <p class="description"><?php _e( 'Specific topic IDs (any status). Separate with commas or new lines.', 'wpforo' ); ?></p>
1153 </div>
1154
1155 <div class="wpforo-ai-form-field">
1156 <label><?php _e( 'Topic Date Range Filter', 'wpforo' ); ?></label>
1157 <div class="wpforo-ai-tasks-date-range">
1158 <div class="wpforo-ai-tasks-date-field">
1159 <label for="wpforo-ai-config-date_from"><?php _e( 'From', 'wpforo' ); ?></label>
1160 <input type="date" id="wpforo-ai-config-date_from" name="config[date_range_from]">
1161 </div>
1162 <div class="wpforo-ai-tasks-date-field">
1163 <label for="wpforo-ai-config-date_to"><?php _e( 'To', 'wpforo' ); ?></label>
1164 <input type="date" id="wpforo-ai-config-date_to" name="config[date_range_to]">
1165 </div>
1166 </div>
1167 <p class="description"><?php _e( 'Filter topics by creation date. Works alone (any forum) or with forum selection.', 'wpforo' ); ?></p>
1168 </div>
1169
1170 <div class="wpforo-ai-form-field">
1171 <label class="wpforo-ai-checkbox-label">
1172 <input type="checkbox" name="config[only_not_replied]" value="1">
1173 <?php _e( 'Only Not Replied Topics', 'wpforo' ); ?>
1174 </label>
1175 <p class="description"><?php _e( 'Only select topics that have no replies yet. Works with all filters.', 'wpforo' ); ?></p>
1176 </div>
1177
1178 <div class="wpforo-ai-info-box">
1179 <span class="dashicons dashicons-info"></span>
1180 <div>
1181 <strong><?php _e( 'How targeting works:', 'wpforo' ); ?></strong>
1182 <ul>
1183 <li><?php _e( 'Forums only = random topic from selected forums', 'wpforo' ); ?></li>
1184 <li><?php _e( 'Date range only = random topic from any forum in date range', 'wpforo' ); ?></li>
1185 <li><?php _e( 'Forums + Date range = topics matching both criteria', 'wpforo' ); ?></li>
1186 <li><?php _e( 'Topic IDs = always included (any status)', 'wpforo' ); ?></li>
1187 </ul>
1188 <p style="margin: 8px 0 0; font-size: 11px; color: #646970;"><?php _e( 'Random selection excludes private, closed, and unapproved topics.', 'wpforo' ); ?></p>
1189 </div>
1190 </div>
1191 </div>
1192 </div>
1193 </div>
1194
1195 <!-- Reply Content Settings Section -->
1196 <div class="wpforo-ai-form-section">
1197 <h3 class="wpforo-ai-form-section-title">
1198 <span class="dashicons dashicons-edit-page"></span>
1199 <?php _e( 'Reply Content Settings', 'wpforo' ); ?>
1200 </h3>
1201
1202 <div class="wpforo-ai-form-row">
1203 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1204 <label for="wpforo-ai-config-reply_style"><?php _e( 'Reply Style', 'wpforo' ); ?> <span class="required">*</span></label>
1205 <select id="wpforo-ai-config-reply_style" name="config[reply_style]" required>
1206 <option value="neutral" selected="selected"><?php _e( 'Neutral - Let custom instructions decide', 'wpforo' ); ?></option>
1207 <option value="helpful_answer"><?php _e( 'Helpful Answer - Direct solution', 'wpforo' ); ?></option>
1208 <option value="clarifying_questions"><?php _e( 'Clarifying Questions - Ask for details', 'wpforo' ); ?></option>
1209 <option value="provide_context"><?php _e( 'Provide Context - Background info', 'wpforo' ); ?></option>
1210 <option value="encourage_discussion"><?php _e( 'Encourage Discussion - Promote conversation', 'wpforo' ); ?></option>
1211 <option value="step_by_step"><?php _e( 'Step-by-Step Solution - Detailed guide', 'wpforo' ); ?></option>
1212 <option value="quick_answer"><?php _e( 'Quick Answer - Brief response', 'wpforo' ); ?></option>
1213 <option value="expert_opinion"><?php _e( 'Expert Opinion - Authoritative view', 'wpforo' ); ?></option>
1214 <option value="supportive"><?php _e( 'Supportive Response - Empathetic help', 'wpforo' ); ?></option>
1215 <option value="resource_sharing"><?php _e( 'Resource Sharing - Links/references', 'wpforo' ); ?></option>
1216 <option value="alternatives"><?php _e( 'Alternative Solutions - Multiple options', 'wpforo' ); ?></option>
1217 <option value="troubleshooting"><?php _e( 'Troubleshooting Guide - Diagnostic approach', 'wpforo' ); ?></option>
1218 <option value="best_practice"><?php _e( 'Best Practice Advice - Recommended way', 'wpforo' ); ?></option>
1219 <option value="experience_sharing"><?php _e( 'Experience Sharing - Personal story', 'wpforo' ); ?></option>
1220 <option value="detailed_explanation"><?php _e( 'Detailed Explanation - Comprehensive answer', 'wpforo' ); ?></option>
1221 <option value="summary"><?php _e( 'Summary Response - Condensed info', 'wpforo' ); ?></option>
1222 <option value="follow_up"><?php _e( 'Follow-up Questions - Dig deeper', 'wpforo' ); ?></option>
1223 <option value="confirmation"><?php _e( 'Confirmation - Validate understanding', 'wpforo' ); ?></option>
1224 <option value="constructive_feedback"><?php _e( 'Constructive Feedback - Helpful critique', 'wpforo' ); ?></option>
1225 <option value="collaborative"><?php _e( 'Collaborative - Work together approach', 'wpforo' ); ?></option>
1226 <option value="educational"><?php _e( 'Educational - Teaching moment', 'wpforo' ); ?></option>
1227 <option value="acknowledgment"><?php _e( 'Acknowledgment - Recognize the issue', 'wpforo' ); ?></option>
1228 <option value="recommendation"><?php _e( 'Recommendation - Suggest specific action', 'wpforo' ); ?></option>
1229 </select>
1230 </div>
1231
1232 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1233 <label for="wpforo-ai-config-reply_tone"><?php _e( 'Reply Tone', 'wpforo' ); ?> <span class="required">*</span></label>
1234 <select id="wpforo-ai-config-reply_tone" name="config[reply_tone]" required>
1235 <option value="neutral" selected="selected"><?php _e( 'Neutral - Let custom instructions decide', 'wpforo' ); ?></option>
1236 <option value="professional"><?php _e( 'Professional - Business-like and formal', 'wpforo' ); ?></option>
1237 <option value="friendly"><?php _e( 'Friendly - Warm and approachable', 'wpforo' ); ?></option>
1238 <option value="casual"><?php _e( 'Casual - Relaxed and informal', 'wpforo' ); ?></option>
1239 <option value="technical"><?php _e( 'Technical - Detailed and precise', 'wpforo' ); ?></option>
1240 <option value="enthusiastic"><?php _e( 'Enthusiastic - Excited and energetic', 'wpforo' ); ?></option>
1241 <option value="helpful"><?php _e( 'Helpful - Supportive and guiding', 'wpforo' ); ?></option>
1242 <option value="authoritative"><?php _e( 'Authoritative - Expert and confident', 'wpforo' ); ?></option>
1243 <option value="conversational"><?php _e( 'Conversational - Like chatting with a friend', 'wpforo' ); ?></option>
1244 <option value="educational"><?php _e( 'Educational - Teaching and informative', 'wpforo' ); ?></option>
1245 <option value="inspirational"><?php _e( 'Inspirational - Motivating and uplifting', 'wpforo' ); ?></option>
1246 <option value="humorous"><?php _e( 'Humorous - Light-hearted and witty', 'wpforo' ); ?></option>
1247 <option value="serious"><?php _e( 'Serious - Focused and earnest', 'wpforo' ); ?></option>
1248 <option value="encouraging"><?php _e( 'Encouraging - Positive and supportive', 'wpforo' ); ?></option>
1249 <option value="warm"><?php _e( 'Warm - Caring and compassionate', 'wpforo' ); ?></option>
1250 <option value="direct"><?php _e( 'Direct - Straightforward and to the point', 'wpforo' ); ?></option>
1251 <option value="thoughtful"><?php _e( 'Thoughtful - Considerate and reflective', 'wpforo' ); ?></option>
1252 <option value="empathetic"><?php _e( 'Empathetic - Understanding and relatable', 'wpforo' ); ?></option>
1253 <option value="confident"><?php _e( 'Confident - Self-assured and decisive', 'wpforo' ); ?></option>
1254 <option value="curious"><?php _e( 'Curious - Inquisitive and engaging', 'wpforo' ); ?></option>
1255 <option value="playful"><?php _e( 'Playful - Fun and lighthearted', 'wpforo' ); ?></option>
1256 <option value="sincere"><?php _e( 'Sincere - Genuine and honest', 'wpforo' ); ?></option>
1257 </select>
1258 </div>
1259 </div>
1260
1261 <div class="wpforo-ai-form-row">
1262 <div class="wpforo-ai-form-field">
1263 <label for="wpforo-ai-config-response_guidelines"><?php _e( 'Response Guidelines', 'wpforo' ); ?> <span class="required">*</span></label>
1264 <div class="wpforo-ai-textarea-with-counter">
1265 <textarea id="wpforo-ai-config-response_guidelines" name="config[response_guidelines]" rows="3" maxlength="120" required placeholder="<?php esc_attr_e( 'e.g., Be helpful, include links when useful, ask follow-up questions...', 'wpforo' ); ?>" data-char-limit="120"></textarea>
1266 <span class="wpforo-ai-char-counter"><span class="current">0</span>/120</span>
1267 </div>
1268 <p class="description"><?php _e( 'Brief guidelines for AI responses (max 120 characters)', 'wpforo' ); ?></p>
1269 </div>
1270 </div>
1271
1272 <div class="wpforo-ai-form-row">
1273 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1274 <label for="wpforo-ai-config-reply_length"><?php _e( 'Reply Length', 'wpforo' ); ?></label>
1275 <select id="wpforo-ai-config-reply_length" name="config[reply_length]">
1276 <option value="brief" selected="selected"><?php _e( 'Brief (100-200 words)', 'wpforo' ); ?></option>
1277 <option value="medium"><?php _e( 'Medium (200-400 words)', 'wpforo' ); ?></option>
1278 <option value="detailed"><?php _e( 'Detailed (400-800 words)', 'wpforo' ); ?></option>
1279 </select>
1280 <div>&nbsp;</div>
1281 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1282 <label for="wpforo-ai-config-max_replies_per_topic"><?php _e( 'Max Replies Per Topic', 'wpforo' ); ?></label>
1283 <input type="number" id="wpforo-ai-config-max_replies_per_topic" name="config[max_replies_per_topic]" min="1" max="10" value="1">
1284 <p class="description"><?php _e( 'Maximum AI replies allowed per topic', 'wpforo' ); ?></p>
1285 </div>
1286 </div>
1287
1288 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1289 <label><?php _e( 'Include in Replies', 'wpforo' ); ?></label>
1290 <div class="wpforo-ai-checkbox-group wpforo-ai-checkbox-group-vertical">
1291 <label class="wpforo-ai-checkbox-item">
1292 <input type="checkbox" name="config[reply_include_code]" value="1">
1293 <span><?php _e( 'Code examples', 'wpforo' ); ?></span>
1294 </label>
1295 <label class="wpforo-ai-checkbox-item">
1296 <input type="checkbox" name="config[reply_include_links]" value="1">
1297 <span><?php _e( 'Links to documentation', 'wpforo' ); ?></span>
1298 </label>
1299 <label class="wpforo-ai-checkbox-item">
1300 <input type="checkbox" name="config[reply_include_steps]" value="1">
1301 <span><?php _e( 'Step-by-step solutions', 'wpforo' ); ?></span>
1302 </label>
1303 <label class="wpforo-ai-checkbox-item">
1304 <input type="checkbox" name="config[reply_include_followup]" value="1" checked>
1305 <span><?php _e( 'Follow-up questions', 'wpforo' ); ?></span>
1306 </label>
1307 <label class="wpforo-ai-checkbox-item">
1308 <input type="checkbox" name="config[reply_include_youtube]" value="1">
1309 <span><?php _e( 'YouTube video URLs', 'wpforo' ); ?></span>
1310 </label>
1311 <label class="wpforo-ai-checkbox-item">
1312 <input type="checkbox" name="config[reply_include_greeting]" value="1" checked>
1313 <span><?php _e( 'Personalized greeting (e.g., "Hi John")', 'wpforo' ); ?></span>
1314 </label>
1315 </div>
1316 </div>
1317 </div>
1318 </div>
1319
1320 <!-- Knowledge Source Section -->
1321 <div class="wpforo-ai-form-section">
1322 <h3 class="wpforo-ai-form-section-title">
1323 <span class="dashicons dashicons-database"></span>
1324 <?php _e( 'Knowledge Source', 'wpforo' ); ?>
1325 </h3>
1326
1327 <div class="wpforo-ai-form-row">
1328 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1329 <label for="wpforo-ai-config-knowledge_source"><?php _e( 'Knowledge Source', 'wpforo' ); ?></label>
1330 <select id="wpforo-ai-config-knowledge_source" name="config[knowledge_source]">
1331 <option value="forum_only"><?php _e( 'Forum content only (RAG)', 'wpforo' ); ?></option>
1332 <option value="forum_and_ai" selected="selected"><?php _e( 'Forum + AI general knowledge', 'wpforo' ); ?></option>
1333 <option value="forum_and_web"><?php _e( 'Forum + Web Search', 'wpforo' ); ?></option>
1334 <option value="forum_and_web_and_ai"><?php _e( 'Forum + Web Search + AI knowledge', 'wpforo' ); ?></option>
1335 <option value="ai_only"><?php _e( 'AI general knowledge only', 'wpforo' ); ?></option>
1336 </select>
1337 </div>
1338
1339 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1340 <label for="wpforo-ai-config-no_content_action"><?php _e( 'If No Relevant Content in Forum Found', 'wpforo' ); ?></label>
1341 <select id="wpforo-ai-config-no_content_action" name="config[no_content_action]">
1342 <option value="use_other_sources" selected="selected"><?php _e( 'Use other knowledge sources', 'wpforo' ); ?></option>
1343 <option value="skip"><?php _e( 'Skip this topic', 'wpforo' ); ?></option>
1344 <option value="ask_details"><?php _e( 'Ask for more details', 'wpforo' ); ?></option>
1345 </select>
1346 </div>
1347 </div>
1348 </div>
1349
1350 <!-- Author Settings & Scheduling Section -->
1351 <div class="wpforo-ai-form-section">
1352 <div class="wpforo-ai-two-column-layout">
1353 <!-- Left Column: Author Settings -->
1354 <div class="wpforo-ai-column wpforo-ai-column-left">
1355 <h3 class="wpforo-ai-form-section-title">
1356 <span class="dashicons dashicons-admin-users"></span>
1357 <?php _e( 'Author Settings', 'wpforo' ); ?>
1358 </h3>
1359
1360 <div class="wpforo-ai-form-row">
1361 <div class="wpforo-ai-form-field">
1362 <label for="wpforo-ai-config-reply-author_userid"><?php _e( 'Reply Author', 'wpforo' ); ?></label>
1363 <div class="wpforo-ai-user-search-wrapper">
1364 <input type="hidden" id="wpforo-ai-config-reply-author_userid" name="config[author_userid]" class="wpforo-ai-user-id-input">
1365 <input type="text" id="wpforo-ai-config-reply-author_search" class="wpforo-ai-user-search" placeholder="<?php esc_attr_e( 'Type to search users...', 'wpforo' ); ?>" autocomplete="off">
1366 <div class="wpforo-ai-user-search-results"></div>
1367 </div>
1368 <p class="description"><?php _e( 'Search by username, display name, or email. Only activated users are shown.', 'wpforo' ); ?></p>
1369 </div>
1370 </div>
1371
1372 <div class="wpforo-ai-author-or-separator">
1373 <span><?php _e( '-- OR --', 'wpforo' ); ?></span>
1374 </div>
1375
1376 <div class="wpforo-ai-form-row">
1377 <div class="wpforo-ai-form-field">
1378 <label for="wpforo-ai-config-reply-author_groupid"><?php _e( 'Author Usergroup', 'wpforo' ); ?></label>
1379 <select id="wpforo-ai-config-reply-author_groupid" name="config[author_groupid]" class="wpforo-ai-author-groupid-select">
1380 <option value=""><?php _e( '-- Select Usergroup --', 'wpforo' ); ?></option>
1381 <?php
1382 $usergroups = WPF()->usergroup->get_usergroups();
1383 if ( ! empty( $usergroups ) ) :
1384 foreach ( $usergroups as $group ) :
1385 $gid = intval( $group['groupid'] );
1386 if ( $gid === 4 ) continue; // Exclude Guest group
1387 ?>
1388 <option value="<?php echo esc_attr( $gid ); ?>"><?php echo esc_html( $group['name'] ); ?></option>
1389 <?php endforeach;
1390 endif;
1391 ?>
1392 </select>
1393 <p class="description"><?php _e( 'Randomly selects a user from this group for each reply (avoids replying as the topic author).', 'wpforo' ); ?></p>
1394 </div>
1395 </div>
1396
1397 <div class="wpforo-ai-form-row">
1398 <div class="wpforo-ai-form-field">
1399 <label class="wpforo-ai-checkbox-item">
1400 <input type="checkbox" name="config[show_ai_badge]" value="1">
1401 <span><?php _e( 'Add AI disclosure notice to generated content', 'wpforo' ); ?></span>
1402 </label>
1403 <p class="description"><?php _e( 'Adds a small disclaimer line at the end of AI-generated replies indicating the content was created by AI.', 'wpforo' ); ?></p>
1404 </div>
1405 </div>
1406 </div>
1407
1408 <!-- Right Column: Scheduling -->
1409 <div class="wpforo-ai-column wpforo-ai-column-right">
1410 <h3 class="wpforo-ai-form-section-title">
1411 <span class="dashicons dashicons-calendar-alt"></span>
1412 <?php _e( 'Scheduling', 'wpforo' ); ?>
1413 </h3>
1414
1415 <div class="wpforo-ai-form-row">
1416 <div class="wpforo-ai-form-field">
1417 <label class="wpforo-ai-auto-index-toggle wpforo-ai-run-on-approval-toggle">
1418 <span class="wpforo-ai-auto-index-label"><?php _e( 'Run on each approved post', 'wpforo' ); ?></span>
1419 <div class="wpforo-ai-switch">
1420 <input type="checkbox" id="wpforo-ai-config-reply-run_on_approval" name="config[run_on_approval]" value="1" class="wpforo-ai-run-on-approval-checkbox" data-task-type="reply_generator">
1421 <span class="wpforo-ai-switch-slider"></span>
1422 </div>
1423 </label>
1424 <p class="description"><?php _e( 'When enabled, task runs automatically when a new post is approved (instead of scheduled cron)', 'wpforo' ); ?></p>
1425 </div>
1426 </div>
1427
1428 <div class="wpforo-ai-form-row wpforo-ai-scheduled-options">
1429 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1430 <label for="wpforo-ai-config-reply-frequency"><?php _e( 'Frequency', 'wpforo' ); ?> <span class="required">*</span></label>
1431 <select id="wpforo-ai-config-reply-frequency" name="config[frequency]" required>
1432 <option value="hourly"><?php _e( 'Every Hour', 'wpforo' ); ?></option>
1433 <option value="3hours"><?php _e( 'Every 3 Hours', 'wpforo' ); ?></option>
1434 <option value="6hours"><?php _e( 'Every 6 Hours', 'wpforo' ); ?></option>
1435 <option value="daily" selected="selected"><?php _e( 'Daily', 'wpforo' ); ?></option>
1436 </select>
1437 </div>
1438
1439 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1440 <label for="wpforo-ai-config-replies_per_run"><?php _e( 'Replies Per Run', 'wpforo' ); ?></label>
1441 <select id="wpforo-ai-config-replies_per_run" name="config[replies_per_run]">
1442 <option value="1" selected="selected">1</option>
1443 <option value="2">2</option>
1444 <option value="3">3</option>
1445 <option value="5">5</option>
1446 <option value="10">10</option>
1447 </select>
1448 </div>
1449 </div>
1450
1451 <div class="wpforo-ai-form-row wpforo-ai-scheduled-options">
1452 <div class="wpforo-ai-form-field">
1453 <label><?php _e( 'Active Days', 'wpforo' ); ?></label>
1454 <div class="wpforo-ai-checkbox-group wpforo-ai-checkbox-group-inline">
1455 <?php
1456 $days = [
1457 'mon' => __( 'Mon', 'wpforo' ),
1458 'tue' => __( 'Tue', 'wpforo' ),
1459 'wed' => __( 'Wed', 'wpforo' ),
1460 'thu' => __( 'Thu', 'wpforo' ),
1461 'fri' => __( 'Fri', 'wpforo' ),
1462 'sat' => __( 'Sat', 'wpforo' ),
1463 'sun' => __( 'Sun', 'wpforo' ),
1464 ];
1465 foreach ( $days as $day_key => $day_label ) :
1466 ?>
1467 <label class="wpforo-ai-checkbox-item">
1468 <input type="checkbox" name="config[active_days][]" value="<?php echo $day_key; ?>" checked>
1469 <span><?php echo $day_label; ?></span>
1470 </label>
1471 <?php endforeach; ?>
1472 </div>
1473 <p class="description"><?php _e( 'Task will only run on selected days', 'wpforo' ); ?></p>
1474 </div>
1475 </div>
1476 </div>
1477 </div>
1478 </div>
1479
1480 <!-- AI Quality & Credits + Quality Control Section -->
1481 <div class="wpforo-ai-form-section">
1482 <div class="wpforo-ai-two-column-layout">
1483 <!-- Left Column: AI Quality & Credits -->
1484 <div class="wpforo-ai-column wpforo-ai-column-left">
1485 <h3 class="wpforo-ai-form-section-title">
1486 <span class="dashicons dashicons-admin-generic"></span>
1487 <?php _e( 'AI Quality & Credits', 'wpforo' ); ?>
1488 </h3>
1489
1490 <div class="wpforo-ai-form-row">
1491 <div class="wpforo-ai-form-field">
1492 <label for="wpforo-ai-config-reply-quality_tier"><?php _e( 'AI Quality Level', 'wpforo' ); ?> <span class="required">*</span></label>
1493 <select id="wpforo-ai-config-reply-quality_tier" name="config[quality_tier]" required>
1494 <option value="fast"><?php _e( 'Fast - 1 credit per reply', 'wpforo' ); ?></option>
1495 <option value="balanced"><?php _e( 'Balanced - 2 credits per reply', 'wpforo' ); ?></option>
1496 <option value="advanced"><?php _e( 'Advanced - 3 credits per reply', 'wpforo' ); ?></option>
1497 <option value="premium" selected="selected"><?php _e( 'Premium - 4 credits per reply', 'wpforo' ); ?></option>
1498 </select>
1499 </div>
1500 </div>
1501
1502 <div class="wpforo-ai-form-row">
1503 <div class="wpforo-ai-form-field">
1504 <label for="wpforo-ai-config-reply-credit_stop_threshold"><?php _e( 'Credit Stop Threshold', 'wpforo' ); ?></label>
1505 <input type="number" id="wpforo-ai-config-reply-credit_stop_threshold" name="config[credit_stop_threshold]" min="0" value="500" placeholder="0">
1506 <p class="description"><?php _e( 'Stop when credits fall below this', 'wpforo' ); ?></p>
1507 </div>
1508 </div>
1509
1510 <div class="wpforo-ai-form-row">
1511 <div class="wpforo-ai-form-field">
1512 <label class="wpforo-ai-checkbox-item">
1513 <input type="checkbox" name="config[auto_pause_on_limit]" value="1" checked>
1514 <span><?php _e( 'Auto-pause when limit reached', 'wpforo' ); ?></span>
1515 </label>
1516 </div>
1517 </div>
1518
1519 <div class="wpforo-ai-estimated-credits-notice">
1520 <span class="dashicons dashicons-info-outline"></span>
1521 <span class="wpforo-ai-estimated-credits-text">
1522 <?php _e( 'Estimated monthly usage:', 'wpforo' ); ?>
1523 <strong class="wpforo-ai-estimated-credits-value">~180 credits</strong>
1524 </span>
1525 </div>
1526
1527 <div class="wpforo-ai-credit-saving-notice">
1528 <span class="dashicons dashicons-saved"></span>
1529 <span class="wpforo-ai-credit-saving-text">
1530 <strong><?php _e( 'Credit Saving Tip:', 'wpforo' ); ?></strong>
1531 <?php _e( 'Manual Run is available. Create this task as paused, then manually run it whenever you want.', 'wpforo' ); ?>
1532 <span class="wpforo-ai-manual-run-cost"><?php _e( 'One manual run costs:', 'wpforo' ); ?> <strong class="wpforo-ai-manual-run-cost-value">4 credits</strong></span>
1533 </span>
1534 </div>
1535 </div>
1536
1537 <!-- Right Column: Content Safety -->
1538 <div class="wpforo-ai-column wpforo-ai-column-right">
1539 <h3 class="wpforo-ai-form-section-title">
1540 <span class="dashicons dashicons-shield"></span>
1541 <?php _e( 'Content Safety', 'wpforo' ); ?>
1542 </h3>
1543
1544 <div class="wpforo-ai-form-row">
1545 <div class="wpforo-ai-form-field">
1546 <label class="wpforo-ai-checkbox-item">
1547 <input type="checkbox" name="config[duplicate_prevention]" value="1" checked>
1548 <span><?php _e( 'Enable duplicate prevention', 'wpforo' ); ?></span>
1549 </label>
1550 </div>
1551 </div>
1552
1553 <div class="wpforo-ai-form-row wpforo-ai-duplicate-settings">
1554 <div class="wpforo-ai-form-field">
1555 <label for="wpforo-ai-reply-config-similarity_threshold"><?php _e( 'Similarity Threshold', 'wpforo' ); ?></label>
1556 <input type="range" id="wpforo-ai-reply-config-similarity_threshold" name="config[similarity_threshold]" min="0" max="100" value="75" class="wpforo-ai-range-slider">
1557 <span class="wpforo-ai-range-value">75%</span>
1558 </div>
1559 </div>
1560
1561 <div class="wpforo-ai-form-row wpforo-ai-duplicate-settings">
1562 <div class="wpforo-ai-form-field">
1563 <label for="wpforo-ai-reply-config-duplicate_check_days"><?php _e( 'Check Period', 'wpforo' ); ?></label>
1564 <input type="number" id="wpforo-ai-reply-config-duplicate_check_days" name="config[duplicate_check_days]" min="0" max="365" value="90" style="width: 80px; display: inline-block;">
1565 <span class="wpforo-ai-input-suffix"><?php _e( 'days.', 'wpforo' ); ?> (<?php _e( 'Set 0 to check all replies, or limit to last N days.', 'wpforo' ); ?>)</span>
1566 </div>
1567 </div>
1568
1569 <div class="wpforo-ai-form-row">
1570 <div class="wpforo-ai-form-field">
1571 <label><?php _e( 'Reply Status', 'wpforo' ); ?></label>
1572 <div class="wpforo-ai-radio-group">
1573 <label class="wpforo-ai-radio-item">
1574 <input type="radio" name="config[reply_status]" value="0" checked>
1575 <span class="wpforo-ai-radio-label"><?php _e( 'Published', 'wpforo' ); ?></span>
1576 </label>
1577 <label class="wpforo-ai-radio-item">
1578 <input type="radio" name="config[reply_status]" value="1">
1579 <span class="wpforo-ai-radio-label"><?php _e( 'Unapproved', 'wpforo' ); ?></span>
1580 </label>
1581 </div>
1582 </div>
1583 </div>
1584
1585 <div class="wpforo-ai-form-row">
1586 <div class="wpforo-ai-form-field">
1587 <label for="reply_strategy"><?php _e( 'Reply Strategy', 'wpforo' ); ?></label>
1588 <select name="config[reply_strategy]" id="reply_strategy" class="wpforo-ai-select">
1589 <option value="first_post"><?php _e( 'Reply to first post', 'wpforo' ); ?></option>
1590 <option value="whole_topic"><?php _e( 'Reply to whole topic', 'wpforo' ); ?></option>
1591 <option value="last_post"><?php _e( 'Reply to last post', 'wpforo' ); ?></option>
1592 </select>
1593 <p class="description"><?php _e( 'Choose how AI generates replies:', 'wpforo' ); ?></p>
1594 <ul class="description" style="margin-top: 5px; margin-left: 20px; list-style-type: disc;">
1595 <li style="margin-bottom: 0px;"><?php _e( '<strong>Reply to first post</strong> - Generates a reply based only on the first post content', 'wpforo' ); ?></li>
1596 <li style="margin-bottom: 0px;"><?php _e( '<strong>Reply to whole topic</strong> - Considers the topic first post and all replies for context', 'wpforo' ); ?></li>
1597 <li style="margin-bottom: 0px;"><?php _e( '<strong>Reply to last post</strong> - Responds to the last post while understanding the sub-thread context', 'wpforo' ); ?></li>
1598 </ul>
1599 </div>
1600 </div>
1601 </div>
1602 </div>
1603 </div>
1604
1605 <!-- Advanced Options Section (Collapsible) - Hidden for future use -->
1606 <div class="wpforo-ai-form-section wpforo-ai-form-section-collapsible" style="display: none;">
1607 <h3 class="wpforo-ai-form-section-title wpforo-ai-collapsible-toggle" aria-expanded="false">
1608 <span class="dashicons dashicons-admin-settings"></span>
1609 <?php _e( 'Advanced Options', 'wpforo' ); ?>
1610 <span class="dashicons dashicons-arrow-down-alt2 wpforo-ai-toggle-icon"></span>
1611 </h3>
1612 <div class="wpforo-ai-collapsible-content" style="display: none;">
1613 </div>
1614 </div>
1615 <?php
1616 }
1617
1618 /**
1619 * Render Tag Maintenance configuration form fields
1620 *
1621 * @param array $forums Array of forums
1622 */
1623 function wpforo_ai_render_tag_maintenance_config( $forums ) {
1624 ?>
1625 <!-- Target Settings Section -->
1626 <div class="wpforo-ai-form-section">
1627 <h3 class="wpforo-ai-form-section-title">
1628 <span class="dashicons dashicons-tag"></span>
1629 <?php _e( 'Target Settings', 'wpforo' ); ?>
1630 </h3>
1631 <p class="wpforo-ai-section-description"><?php _e( 'Select forums to process topic tags, or specify exact topic IDs. Both can be combined.', 'wpforo' ); ?></p>
1632
1633 <div class="wpforo-ai-two-column-layout">
1634 <!-- Left Column: Forum Selection -->
1635 <div class="wpforo-ai-column wpforo-ai-column-left">
1636 <div class="wpforo-ai-form-field">
1637 <label><?php _e( 'Target Forums', 'wpforo' ); ?></label>
1638 <div class="wpforo-ai-forum-checklist">
1639 <?php foreach ( $forums as $forum ) :
1640 $forum_id = (int) $forum['forumid'];
1641 $forum_title = esc_html( $forum['title'] );
1642 $parent_id = (int) $forum['parentid'];
1643 $is_cat = (int) $forum['is_cat'];
1644 $item_class = $parent_id > 0 ? 'wpforo-ai-forum-child' : 'wpforo-ai-forum-parent';
1645 if ( $is_cat ) {
1646 $item_class .= ' wpforo-ai-forum-category';
1647 }
1648 ?>
1649 <label class="wpforo-ai-forum-checkbox-item <?php echo esc_attr( $item_class ); ?>">
1650 <?php if ( $is_cat ) : ?>
1651 <input type="checkbox"
1652 class="forum-checkbox forum-parent-toggle"
1653 data-forum-id="<?php echo $forum_id; ?>"
1654 data-parent-id="<?php echo $parent_id; ?>"
1655 data-is-category="1">
1656 <?php else : ?>
1657 <input type="checkbox"
1658 name="config[tag_target_forum_ids][]"
1659 value="<?php echo $forum_id; ?>"
1660 class="forum-checkbox"
1661 data-forum-id="<?php echo $forum_id; ?>"
1662 data-parent-id="<?php echo $parent_id; ?>"
1663 data-is-category="0">
1664 <?php endif; ?>
1665 <?php echo $forum_title; ?>
1666 </label>
1667 <?php endforeach; ?>
1668 </div>
1669 <div class="wpforo-ai-forum-actions">
1670 <button type="button" class="button button-small wpforo-ai-select-all-forums">
1671 <?php _e( 'Select All', 'wpforo' ); ?>
1672 </button>
1673 <button type="button" class="button button-small wpforo-ai-deselect-all-forums">
1674 <?php _e( 'Deselect All', 'wpforo' ); ?>
1675 </button>
1676 </div>
1677 <p class="description"><?php _e( 'Topics from selected forums (excludes private, closed, unapproved)', 'wpforo' ); ?></p>
1678 </div>
1679 </div>
1680
1681 <!-- Right Column: Topic IDs and Date Range -->
1682 <div class="wpforo-ai-column wpforo-ai-column-right">
1683 <div class="wpforo-ai-form-field">
1684 <label for="wpforo-ai-tag-config-target_topic_ids"><?php _e( 'Target Topic IDs', 'wpforo' ); ?></label>
1685 <textarea id="wpforo-ai-tag-config-target_topic_ids" name="config[target_topic_ids]" rows="3" placeholder="<?php esc_attr_e( 'e.g.: 123, 456, 789', 'wpforo' ); ?>"></textarea>
1686 <p class="description"><?php _e( 'Specific topic IDs (any status). Separate with commas or new lines.', 'wpforo' ); ?></p>
1687 </div>
1688
1689 <div class="wpforo-ai-form-field">
1690 <label><?php _e( 'Topic Date Range Filter', 'wpforo' ); ?></label>
1691 <div class="wpforo-ai-tasks-date-range">
1692 <div class="wpforo-ai-tasks-date-field">
1693 <label for="wpforo-ai-tag-config-date_from"><?php _e( 'From', 'wpforo' ); ?></label>
1694 <input type="date" id="wpforo-ai-tag-config-date_from" name="config[date_range_from]">
1695 </div>
1696 <div class="wpforo-ai-tasks-date-field">
1697 <label for="wpforo-ai-tag-config-date_to"><?php _e( 'To', 'wpforo' ); ?></label>
1698 <input type="date" id="wpforo-ai-tag-config-date_to" name="config[date_range_to]">
1699 </div>
1700 </div>
1701 <p class="description"><?php _e( 'Filter topics by creation date. Works alone (any forum) or with forum selection.', 'wpforo' ); ?></p>
1702 </div>
1703
1704 <div class="wpforo-ai-form-field">
1705 <label class="wpforo-ai-checkbox-label">
1706 <input type="checkbox" name="config[only_not_tagged]" value="1">
1707 <?php _e( 'Only Topics Without Tags', 'wpforo' ); ?>
1708 </label>
1709 <p class="description"><?php _e( 'Only select topics that have no tags yet. Works with all filters.', 'wpforo' ); ?></p>
1710 </div>
1711
1712 <div class="wpforo-ai-info-box">
1713 <span class="dashicons dashicons-info"></span>
1714 <div>
1715 <strong><?php _e( 'How targeting works:', 'wpforo' ); ?></strong>
1716 <ul>
1717 <li><?php _e( 'Forums only = topics from selected forums', 'wpforo' ); ?></li>
1718 <li><?php _e( 'Date range only = topics from any forum in date range', 'wpforo' ); ?></li>
1719 <li><?php _e( 'Forums + Date range = topics matching both criteria', 'wpforo' ); ?></li>
1720 <li><?php _e( 'Topic IDs = always included (any status)', 'wpforo' ); ?></li>
1721 </ul>
1722 </div>
1723 </div>
1724 </div>
1725 </div>
1726 </div>
1727
1728 <!-- Tag Options Section -->
1729 <div class="wpforo-ai-form-section">
1730 <h3 class="wpforo-ai-form-section-title">
1731 <span class="dashicons dashicons-admin-settings"></span>
1732 <?php _e( 'Tag Options', 'wpforo' ); ?>
1733 </h3>
1734
1735 <div class="wpforo-ai-two-column-layout">
1736 <!-- Left Column: Tag Generation Settings -->
1737 <div class="wpforo-ai-column wpforo-ai-column-left">
1738 <div class="wpforo-ai-form-field">
1739 <label for="wpforo-ai-tag-config-max_tags"><?php _e( 'Maximum Tags Per Topic', 'wpforo' ); ?></label>
1740 <select id="wpforo-ai-tag-config-max_tags" name="config[max_tags]">
1741 <option value="1">1</option>
1742 <option value="2">2</option>
1743 <option value="3">3</option>
1744 <option value="4">4</option>
1745 <option value="5" selected="selected">5</option>
1746 </select>
1747 <p class="description"><?php _e( 'Maximum number of tags to generate for each topic', 'wpforo' ); ?></p>
1748 </div>
1749
1750 <div class="wpforo-ai-form-field">
1751 <label class="wpforo-ai-checkbox-label">
1752 <input type="checkbox" name="config[preserve_existing]" value="1" checked>
1753 <?php _e( 'Preserve Existing Tags', 'wpforo' ); ?>
1754 </label>
1755 <p class="description"><?php _e( 'Keep existing tags and add new ones. If unchecked, existing tags will be replaced.', 'wpforo' ); ?></p>
1756 </div>
1757
1758 <div class="wpforo-ai-form-field">
1759 <label class="wpforo-ai-checkbox-label">
1760 <input type="checkbox" name="config[maintain_vocabulary]" value="1" checked>
1761 <?php _e( 'Maintain Tag Vocabulary', 'wpforo' ); ?>
1762 </label>
1763 <p class="description"><?php _e( 'Prefer existing forum tags to maintain consistent vocabulary', 'wpforo' ); ?></p>
1764 </div>
1765 </div>
1766
1767 <!-- Right Column: Tag Cleaning Settings -->
1768 <div class="wpforo-ai-column wpforo-ai-column-right">
1769 <div class="wpforo-ai-form-field">
1770 <label class="wpforo-ai-checkbox-label">
1771 <input type="checkbox" name="config[remove_duplicates]" value="1" checked>
1772 <?php _e( 'Remove Duplicate Tags', 'wpforo' ); ?>
1773 </label>
1774 <p class="description"><?php _e( 'Identify and remove duplicate or near-duplicate tags', 'wpforo' ); ?></p>
1775 </div>
1776
1777 <div class="wpforo-ai-form-field">
1778 <label class="wpforo-ai-checkbox-label">
1779 <input type="checkbox" name="config[remove_irrelevant]" value="1" checked>
1780 <?php _e( 'Remove Irrelevant Tags', 'wpforo' ); ?>
1781 </label>
1782 <p class="description"><?php _e( 'Remove tags that are not relevant to the topic content', 'wpforo' ); ?></p>
1783 </div>
1784
1785 <div class="wpforo-ai-form-field">
1786 <label class="wpforo-ai-checkbox-label">
1787 <input type="checkbox" name="config[lowercase]" value="1">
1788 <?php _e( 'Lowercase All Tags', 'wpforo' ); ?>
1789 </label>
1790 <p class="description"><?php _e( 'Convert all tags to lowercase for consistency', 'wpforo' ); ?></p>
1791 </div>
1792 </div>
1793 </div>
1794 </div>
1795
1796 <!-- Scheduling Section -->
1797 <div class="wpforo-ai-form-section">
1798 <h3 class="wpforo-ai-form-section-title">
1799 <span class="dashicons dashicons-calendar-alt"></span>
1800 <?php _e( 'Scheduling', 'wpforo' ); ?>
1801 </h3>
1802
1803 <div class="wpforo-ai-form-row">
1804 <div class="wpforo-ai-form-field">
1805 <label class="wpforo-ai-auto-index-toggle wpforo-ai-run-on-approval-toggle">
1806 <span class="wpforo-ai-auto-index-label"><?php _e( 'Run on each approved topic', 'wpforo' ); ?></span>
1807 <div class="wpforo-ai-switch">
1808 <input type="checkbox" id="wpforo-ai-config-tag-run_on_approval" name="config[run_on_approval]" value="1" class="wpforo-ai-run-on-approval-checkbox" data-task-type="tag_generator">
1809 <span class="wpforo-ai-switch-slider"></span>
1810 </div>
1811 </label>
1812 <p class="description"><?php _e( 'When enabled, task runs automatically when a new topic is approved (instead of scheduled cron)', 'wpforo' ); ?></p>
1813 </div>
1814 </div>
1815
1816 <div class="wpforo-ai-form-row wpforo-ai-scheduled-options">
1817 <div class="wpforo-ai-form-field wpforo-ai-form-field-third">
1818 <label for="wpforo-ai-tag-config-frequency"><?php _e( 'Frequency', 'wpforo' ); ?> <span class="required">*</span></label>
1819 <select id="wpforo-ai-tag-config-frequency" name="config[frequency]" required>
1820 <option value="hourly"><?php _e( 'Every Hour', 'wpforo' ); ?></option>
1821 <option value="3hours"><?php _e( 'Every 3 Hours', 'wpforo' ); ?></option>
1822 <option value="6hours"><?php _e( 'Every 6 Hours', 'wpforo' ); ?></option>
1823 <option value="daily" selected="selected"><?php _e( 'Daily', 'wpforo' ); ?></option>
1824 </select>
1825 </div>
1826
1827 <div class="wpforo-ai-form-field wpforo-ai-form-field-third">
1828 <label for="wpforo-ai-tag-config-topics_per_run"><?php _e( 'Topics Per Run', 'wpforo' ); ?></label>
1829 <input type="number" id="wpforo-ai-tag-config-topics_per_run" name="config[topics_per_run]" min="1" max="50" value="20">
1830 <p class="description"><?php _e( '1-50 topics processed per run', 'wpforo' ); ?></p>
1831 </div>
1832 </div>
1833
1834 <div class="wpforo-ai-form-row wpforo-ai-scheduled-options">
1835 <div class="wpforo-ai-form-field">
1836 <label><?php _e( 'Active Days', 'wpforo' ); ?></label>
1837 <div class="wpforo-ai-checkbox-group wpforo-ai-checkbox-group-inline">
1838 <?php
1839 $days = [
1840 'mon' => __( 'Mon', 'wpforo' ),
1841 'tue' => __( 'Tue', 'wpforo' ),
1842 'wed' => __( 'Wed', 'wpforo' ),
1843 'thu' => __( 'Thu', 'wpforo' ),
1844 'fri' => __( 'Fri', 'wpforo' ),
1845 'sat' => __( 'Sat', 'wpforo' ),
1846 'sun' => __( 'Sun', 'wpforo' ),
1847 ];
1848 foreach ( $days as $day_key => $day_label ) :
1849 ?>
1850 <label class="wpforo-ai-checkbox-item">
1851 <input type="checkbox" name="config[active_days][]" value="<?php echo $day_key; ?>" checked>
1852 <span><?php echo $day_label; ?></span>
1853 </label>
1854 <?php endforeach; ?>
1855 </div>
1856 <p class="description"><?php _e( 'Task will only run on selected days', 'wpforo' ); ?></p>
1857 </div>
1858 </div>
1859 </div>
1860
1861 <!-- AI Quality & Credits Section -->
1862 <div class="wpforo-ai-form-section">
1863 <h3 class="wpforo-ai-form-section-title">
1864 <span class="dashicons dashicons-admin-generic"></span>
1865 <?php _e( 'AI Quality & Credits', 'wpforo' ); ?>
1866 </h3>
1867
1868 <div class="wpforo-ai-form-row">
1869 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1870 <label for="wpforo-ai-tag-config-quality_tier"><?php _e( 'AI Quality Level', 'wpforo' ); ?> <span class="required">*</span></label>
1871 <select id="wpforo-ai-tag-config-quality_tier" name="config[quality_tier]" required>
1872 <option value="fast"><?php _e( 'Fast - 1 credit per run', 'wpforo' ); ?></option>
1873 <option value="balanced"><?php _e( 'Balanced - 2 credits per run', 'wpforo' ); ?></option>
1874 <option value="advanced" selected="selected"><?php _e( 'Advanced - 3 credits per run (recommended for 20+ topics)', 'wpforo' ); ?></option>
1875 <option value="premium"><?php _e( 'Premium - 4 credits per run (recommended for 20+ topics)', 'wpforo' ); ?></option>
1876 </select>
1877 <p class="description"><?php _e( 'All topics in one run are processed in a single AI call', 'wpforo' ); ?></p>
1878 </div>
1879
1880 <div class="wpforo-ai-form-field wpforo-ai-form-field-half">
1881 <label for="wpforo-ai-tag-config-credit_stop_threshold"><?php _e( 'Credit Stop Threshold', 'wpforo' ); ?></label>
1882 <input type="number" id="wpforo-ai-tag-config-credit_stop_threshold" name="config[credit_stop_threshold]" min="0" value="500" placeholder="0">
1883 <p class="description"><?php _e( 'Stop when credits fall below this', 'wpforo' ); ?></p>
1884 </div>
1885 </div>
1886
1887 <div class="wpforo-ai-form-row">
1888 <div class="wpforo-ai-form-field">
1889 <label class="wpforo-ai-checkbox-item">
1890 <input type="checkbox" name="config[auto_pause_on_limit]" value="1" checked>
1891 <span><?php _e( 'Auto-pause when limit reached', 'wpforo' ); ?></span>
1892 </label>
1893 </div>
1894 </div>
1895
1896 <div class="wpforo-ai-estimated-credits-notice">
1897 <span class="dashicons dashicons-info-outline"></span>
1898 <span class="wpforo-ai-estimated-credits-text">
1899 <?php _e( 'Estimated monthly usage:', 'wpforo' ); ?>
1900 <strong class="wpforo-ai-estimated-credits-value">~120 credits</strong>
1901 </span>
1902 </div>
1903
1904 <div class="wpforo-ai-credit-saving-notice">
1905 <span class="dashicons dashicons-saved"></span>
1906 <span class="wpforo-ai-credit-saving-text">
1907 <strong><?php _e( 'Credit Saving Tip:', 'wpforo' ); ?></strong>
1908 <?php _e( 'Manual Run is available. Create this task as paused, then manually run it whenever you want.', 'wpforo' ); ?>
1909 <span class="wpforo-ai-manual-run-cost"><?php _e( 'One manual run costs:', 'wpforo' ); ?> <strong class="wpforo-ai-manual-run-cost-value">4 credits</strong></span>
1910 </span>
1911 </div>
1912 </div>
1913 <?php
1914 }
1915