post_status; // Map WordPress status to IGNY8 task status $task_status = igny8_map_wp_status_to_igny8($post_status); // Sync to IGNY8 API $api = new Igny8API(); // Get content_id if available $content_id = get_post_meta($post_id, '_igny8_content_id', true); $update_data = array( 'status' => $task_status, 'assigned_post_id' => $post_id, 'post_url' => get_permalink($post_id), 'wordpress_status' => $post_status, // Actual WordPress status 'synced_at' => current_time('mysql') ); // Include content_id if available if ($content_id) { $update_data['content_id'] = $content_id; } $response = $api->put("/writer/tasks/{$task_id}/", $update_data); if ($response['success']) { // Update WordPress status in meta for IGNY8 to read update_post_meta($post_id, '_igny8_wordpress_status', $post_status); update_post_meta($post_id, '_igny8_last_synced', current_time('mysql')); error_log("IGNY8: Synced post {$post_id} status ({$post_status}) to task {$task_id}"); } else { error_log("IGNY8: Failed to sync post status: " . ($response['error'] ?? 'Unknown error')); } } /** * Update keyword status when WordPress post is published * * @param int $post_id Post ID */ function igny8_update_keywords_on_post_publish($post_id) { // Get task ID from post meta $task_id = get_post_meta($post_id, '_igny8_task_id', true); if (!$task_id) { return; } $api = new Igny8API(); // Get task details to find associated cluster/keywords $task_response = $api->get("/writer/tasks/{$task_id}/"); if (!$task_response['success']) { return; } $task = $task_response['data']; $cluster_id = $task['cluster_id'] ?? null; if ($cluster_id) { // Get keywords in this cluster $keywords_response = $api->get("/planner/keywords/?cluster_id={$cluster_id}"); if ($keywords_response['success']) { $keywords = $keywords_response['results']; // Update each keyword status to 'mapped' foreach ($keywords as $keyword) { $api->put("/planner/keywords/{$keyword['id']}/", array( 'status' => 'mapped' )); } } } // Update task status to completed $api->put("/writer/tasks/{$task_id}/", array( 'status' => 'completed', 'assigned_post_id' => $post_id, 'post_url' => get_permalink($post_id) )); update_post_meta($post_id, '_igny8_last_synced', current_time('mysql')); } /** * Sync post status changes to IGNY8 * * @param string $new_status New post status * @param string $old_status Old post status * @param WP_Post $post Post object */ function igny8_sync_post_status_transition($new_status, $old_status, $post) { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { return; } // Skip if status hasn't changed if ($new_status === $old_status) { return; } // Only sync IGNY8-managed posts if (!igny8_is_igny8_managed_post($post->ID)) { return; } $task_id = get_post_meta($post->ID, '_igny8_task_id', true); if (!$task_id) { return; } $api = new Igny8API(); // Map WordPress status to IGNY8 task status $task_status = igny8_map_wp_status_to_igny8($new_status); // Sync to IGNY8 $response = $api->put("/writer/tasks/{$task_id}/", array( 'status' => $task_status, 'assigned_post_id' => $post->ID, 'post_url' => get_permalink($post->ID) )); if ($response['success']) { update_post_meta($post->ID, '_igny8_last_synced', current_time('mysql')); do_action('igny8_post_status_synced', $post->ID, $task_id, $new_status); } } /** * Batch sync all IGNY8-managed posts status to IGNY8 API * * @return array Sync results */ function igny8_batch_sync_post_statuses() { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { return array( 'synced' => 0, 'failed' => 0, 'total' => 0, 'disabled' => true ); } global $wpdb; // Get all posts with IGNY8 task ID $posts = $wpdb->get_results(" SELECT p.ID, p.post_status, p.post_title, pm.meta_value as task_id FROM {$wpdb->posts} p INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id WHERE pm.meta_key = '_igny8_task_id' AND p.post_type IN ('post', 'page', 'product') AND p.post_status != 'trash' "); $api = new Igny8API(); $synced = 0; $failed = 0; foreach ($posts as $post_data) { $post_id = $post_data->ID; $task_id = intval($post_data->task_id); $wp_status = $post_data->post_status; // Map status $task_status = igny8_map_wp_status_to_igny8($wp_status); // Sync to IGNY8 $response = $api->put("/writer/tasks/{$task_id}/", array( 'status' => $task_status, 'assigned_post_id' => $post_id, 'post_url' => get_permalink($post_id) )); if ($response['success']) { update_post_meta($post_id, '_igny8_last_synced', current_time('mysql')); $synced++; } else { $failed++; error_log("IGNY8: Failed to sync post {$post_id}: " . ($response['error'] ?? 'Unknown error')); } } return array( 'synced' => $synced, 'failed' => $failed, 'total' => count($posts) ); } /** * Scheduled sync of WordPress post statuses to IGNY8 */ function igny8_cron_sync_post_statuses() { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { error_log('IGNY8: Connection disabled, skipping post status sync'); return; } $result = igny8_batch_sync_post_statuses(); error_log(sprintf( 'IGNY8: Synced %d posts, %d failed', $result['synced'], $result['failed'] )); } /** * Scheduled sync of site data */ function igny8_cron_sync_site_data() { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { error_log('IGNY8: Connection disabled, skipping site data sync'); return; } $site_id = get_option('igny8_site_id'); if (!$site_id) { error_log('IGNY8: Site ID not set, skipping site data sync'); return; } if (function_exists('igny8_is_module_enabled') && !igny8_is_module_enabled('sites')) { error_log('IGNY8: Sites module disabled, skipping incremental site sync'); return; } $settings = igny8_get_site_scan_settings(array( 'mode' => 'incremental', 'since' => get_option('igny8_last_site_sync', 0) )); $result = igny8_sync_incremental_site_data($site_id, $settings); if ($result) { error_log(sprintf( 'IGNY8: Synced %d posts to site %d', $result['synced'], $site_id )); } else { error_log('IGNY8: Site data sync failed'); } } /** * Scheduled full site scan (runs at most once per week) */ function igny8_cron_full_site_scan() { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { return; } $site_id = get_option('igny8_site_id'); if (!$site_id) { return; } if (function_exists('igny8_is_module_enabled') && !igny8_is_module_enabled('sites')) { return; } $last_full = intval(get_option('igny8_last_full_site_scan', 0)); if ($last_full && (time() - $last_full) < WEEK_IN_SECONDS) { return; } $settings = igny8_get_site_scan_settings(array( 'mode' => 'full', 'since' => null )); $result = igny8_perform_full_site_scan($site_id, $settings); if ($result) { error_log('IGNY8: Full site scan completed'); } else { error_log('IGNY8: Full site scan failed'); } } /** * Two-way sync class */ class Igny8WordPressSync { /** * API instance * * @var Igny8API */ private $api; /** * Constructor */ public function __construct() { $this->api = new Igny8API(); // WordPress → IGNY8 hooks are registered in hooks.php // IGNY8 → WordPress hooks can be added here if needed } }