127 lines
3.8 KiB
PHP
127 lines
3.8 KiB
PHP
<?php
|
|
namespace HermesAiBridge;
|
|
|
|
defined('ABSPATH') or die();
|
|
|
|
class Scheduler {
|
|
/**
|
|
* Process all due scheduled AI tasks.
|
|
* Called by WP-Cron every hour.
|
|
*/
|
|
public function process_due_tasks() {
|
|
$tasks = get_posts([
|
|
'post_type' => 'hermes_schedule',
|
|
'posts_per_page' => 10,
|
|
'post_status' => 'publish',
|
|
'meta_query' => [
|
|
[
|
|
'key' => '_hermes_scheduled_date',
|
|
'value' => current_time('mysql'),
|
|
'compare' => '<=',
|
|
'type' => 'DATETIME',
|
|
],
|
|
[
|
|
'key' => '_hermes_processed',
|
|
'compare' => 'NOT EXISTS',
|
|
],
|
|
],
|
|
]);
|
|
|
|
foreach ($tasks as $task) {
|
|
$this->execute_task($task);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute a single scheduled task.
|
|
*/
|
|
protected function execute_task($task) {
|
|
$task_type = get_post_meta($task->ID, '_hermes_task_type', true);
|
|
|
|
switch ($task_type) {
|
|
case 'content_generation':
|
|
$this->execute_content_task($task);
|
|
break;
|
|
case 'publish_scheduled':
|
|
$this->publish_scheduled_posts();
|
|
break;
|
|
default:
|
|
RestController::log('warning', 'Unknown task type', ['task_id' => $task->ID, 'type' => $task_type]);
|
|
}
|
|
|
|
update_post_meta($task->ID, '_hermes_processed', time());
|
|
update_post_meta($task->ID, '_hermes_processed_date', current_time('mysql'));
|
|
}
|
|
|
|
/**
|
|
* Execute a content generation task.
|
|
*/
|
|
protected function execute_content_task($task) {
|
|
$prompt = get_post_meta($task->ID, '_hermes_prompt', true);
|
|
$scheduled_date = get_post_meta($task->ID, '_hermes_scheduled_date', true);
|
|
|
|
if (!$prompt) {
|
|
RestController::log('error', 'Task has no prompt', ['task_id' => $task->ID]);
|
|
return;
|
|
}
|
|
|
|
$ai = new AiProvider();
|
|
$content = $ai->generate($prompt, 'post');
|
|
|
|
if (is_wp_error($content)) {
|
|
RestController::log('error', 'Task generation failed', [
|
|
'task_id' => $task->ID,
|
|
'error' => $content->get_error_message(),
|
|
]);
|
|
return;
|
|
}
|
|
|
|
$post_id = wp_insert_post([
|
|
'post_title' => $task->post_title,
|
|
'post_content' => $content,
|
|
'post_status' => 'future',
|
|
'post_date' => $scheduled_date,
|
|
'post_type' => 'post',
|
|
]);
|
|
|
|
if ($post_id) {
|
|
RestController::log('info', 'Task executed: post scheduled', [
|
|
'task_id' => $task->ID,
|
|
'post_id' => $post_id,
|
|
'scheduled' => $scheduled_date,
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Publish posts that are scheduled but stuck in 'future' status.
|
|
*/
|
|
protected function publish_scheduled_posts() {
|
|
$scheduled = get_posts([
|
|
'post_status' => 'future',
|
|
'posts_per_page' => 10,
|
|
'post_type' => 'any',
|
|
]);
|
|
|
|
foreach ($scheduled as $post) {
|
|
if (strtotime($post->post_date) <= time()) {
|
|
wp_publish_post($post->ID);
|
|
RestController::log('info', 'Post published', ['post_id' => $post->ID, 'title' => $post->post_title]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register the hermes_schedule custom post type.
|
|
*/
|
|
public static function register_post_type() {
|
|
register_post_type('hermes_schedule', [
|
|
'labels' => ['name' => 'AI Tasks', 'singular_name' => 'AI Task'],
|
|
'public' => false,
|
|
'show_ui' => true,
|
|
'show_in_menu' => false,
|
|
'supports' => ['title', 'editor', 'custom-fields'],
|
|
]);
|
|
}
|
|
}
|