| 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' ); ?> |
| 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> </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 |
|