is_authenticated()) { return false; } $site_id = get_option('igny8_site_id'); if (!$site_id) { return false; } // Get taxonomy data $taxonomy_obj = get_taxonomy($taxonomy); if (!$taxonomy_obj) { return false; } // Get all terms $terms = get_terms(array( 'taxonomy' => $taxonomy, 'hide_empty' => false )); if (is_wp_error($terms)) { return false; } // Format taxonomy data $taxonomy_data = array( 'name' => $taxonomy, 'label' => $taxonomy_obj->label, 'hierarchical' => $taxonomy_obj->hierarchical, 'terms' => array() ); foreach ($terms as $term) { $taxonomy_data['terms'][] = array( 'id' => $term->term_id, 'name' => $term->name, 'slug' => $term->slug, 'description' => $term->description, 'parent' => $term->parent ); } // Send to IGNY8 $response = $api->post("/planner/sites/{$site_id}/taxonomies/", array( 'taxonomy' => $taxonomy_data )); return $response['success'] ? $response['data'] : false; } /** * Sync IGNY8 sectors to WordPress taxonomies * * @return array|false Sync result or false on failure */ function igny8_sync_igny8_sectors_to_wp() { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { return array('synced' => 0, 'total' => 0, 'skipped' => true, 'disabled' => true); } $api = new Igny8API(); if (!$api->is_authenticated()) { return false; } $site_id = get_option('igny8_site_id'); if (!$site_id) { return false; } // Respect module toggle $enabled_modules = function_exists('igny8_get_enabled_modules') ? igny8_get_enabled_modules() : array(); if (!in_array('planner', $enabled_modules, true)) { return array('synced' => 0, 'total' => 0, 'skipped' => true); } // Get sectors from IGNY8 $response = $api->get("/planner/sites/{$site_id}/sectors/"); if (!$response['success']) { return false; } $sectors = $response['data']['results'] ?? $response['data'] ?? $response['results'] ?? array(); $synced = 0; foreach ($sectors as $sector) { $term = term_exists($sector['name'], 'igny8_sectors'); if (!$term) { $term = wp_insert_term( $sector['name'], 'igny8_sectors', array( 'description' => $sector['description'] ?? '', 'slug' => $sector['slug'] ?? sanitize_title($sector['name']) ) ); } else { wp_update_term($term['term_id'], 'igny8_sectors', array( 'description' => $sector['description'] ?? '', 'slug' => $sector['slug'] ?? sanitize_title($sector['name']) )); } if (!is_wp_error($term)) { $term_id = is_array($term) ? $term['term_id'] : $term; update_term_meta($term_id, '_igny8_sector_id', $sector['id']); $synced++; } } return array('synced' => $synced, 'total' => count($sectors)); } /** * Sync IGNY8 clusters to WordPress taxonomies * * @param int $sector_id Optional sector ID to filter clusters * @return array|false Sync result or false on failure */ function igny8_sync_igny8_clusters_to_wp($sector_id = null) { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { return array('synced' => 0, 'total' => 0, 'skipped' => true, 'disabled' => true); } $api = new Igny8API(); if (!$api->is_authenticated()) { return false; } $site_id = get_option('igny8_site_id'); if (!$site_id) { return false; } $enabled_modules = function_exists('igny8_get_enabled_modules') ? igny8_get_enabled_modules() : array(); if (!in_array('planner', $enabled_modules, true)) { return array('synced' => 0, 'total' => 0, 'skipped' => true); } // Build endpoint $endpoint = "/planner/sites/{$site_id}/clusters/"; if ($sector_id) { $endpoint .= "?sector_id={$sector_id}"; } // Get clusters from IGNY8 $response = $api->get($endpoint); if (!$response['success']) { return false; } $clusters = $response['data']['results'] ?? $response['data'] ?? $response['results'] ?? array(); $synced = 0; foreach ($clusters as $cluster) { // Get parent sector term if sector_id exists $parent = 0; if (!empty($cluster['sector_id'])) { $sector_terms = get_terms(array( 'taxonomy' => 'igny8_sectors', 'meta_key' => '_igny8_sector_id', 'meta_value' => $cluster['sector_id'], 'hide_empty' => false )); if (!is_wp_error($sector_terms) && !empty($sector_terms)) { $parent = $sector_terms[0]->term_id; } } $term_id = 0; $existing = get_terms(array( 'taxonomy' => 'igny8_clusters', 'meta_key' => '_igny8_cluster_id', 'meta_value' => $cluster['id'], 'hide_empty' => false )); if (!is_wp_error($existing) && !empty($existing)) { $term_id = $existing[0]->term_id; } if (!$term_id) { $term = term_exists($cluster['name'], 'igny8_clusters'); } else { $term = array('term_id' => $term_id); } if (!$term) { $term = wp_insert_term( $cluster['name'], 'igny8_clusters', array( 'description' => $cluster['description'] ?? '', 'slug' => $cluster['slug'] ?? sanitize_title($cluster['name']), 'parent' => $parent ) ); } else { wp_update_term($term['term_id'], 'igny8_clusters', array( 'description' => $cluster['description'] ?? '', 'slug' => $cluster['slug'] ?? sanitize_title($cluster['name']), 'parent' => $parent )); } if (!is_wp_error($term)) { $term_id = is_array($term) ? $term['term_id'] : $term; update_term_meta($term_id, '_igny8_cluster_id', $cluster['id']); if (!empty($cluster['sector_id'])) { update_term_meta($term_id, '_igny8_sector_id', $cluster['sector_id']); } $synced++; } } return array('synced' => $synced, 'total' => count($clusters)); } /** * Cron handler: sync sectors/clusters automatically * * @return array */ function igny8_cron_sync_taxonomies() { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { error_log('IGNY8: Connection disabled, skipping taxonomy sync'); return array('sectors' => array('skipped' => true), 'clusters' => array('skipped' => true)); } $results = array( 'sectors' => igny8_sync_igny8_sectors_to_wp(), 'clusters' => igny8_sync_igny8_clusters_to_wp() ); update_option('igny8_last_taxonomy_sync', current_time('timestamp')); return $results; } /** * Sync planner keywords for all referenced clusters * * @return array|false */ function igny8_sync_keywords_from_planner() { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { return array('synced_clusters' => 0, 'synced_posts' => 0, 'skipped' => true, 'disabled' => true); } $api = new Igny8API(); if (!$api->is_authenticated()) { return false; } $site_id = get_option('igny8_site_id'); if (!$site_id) { return false; } $enabled_modules = function_exists('igny8_get_enabled_modules') ? igny8_get_enabled_modules() : array(); if (!in_array('planner', $enabled_modules, true)) { return array('synced_clusters' => 0, 'synced_posts' => 0, 'skipped' => true); } global $wpdb; $cluster_ids = $wpdb->get_col(" SELECT DISTINCT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_igny8_cluster_id' AND meta_value IS NOT NULL AND meta_value != '' "); if (empty($cluster_ids)) { return array('synced_clusters' => 0, 'synced_posts' => 0); } $enabled_post_types = function_exists('igny8_get_enabled_post_types') ? igny8_get_enabled_post_types() : array('post', 'page'); $synced_clusters = 0; $synced_posts = 0; foreach ($cluster_ids as $cluster_id) { $cluster_id = intval($cluster_id); if (!$cluster_id) { continue; } $response = $api->get("/planner/keywords/?cluster_id={$cluster_id}&page_size=500"); if (!$response['success']) { continue; } $keywords = $response['data']['results'] ?? $response['data'] ?? $response['results'] ?? array(); $keyword_ids = array_map('intval', wp_list_pluck($keywords, 'id')); // Update cluster term meta $cluster_terms = get_terms(array( 'taxonomy' => 'igny8_clusters', 'meta_key' => '_igny8_cluster_id', 'meta_value' => $cluster_id, 'hide_empty' => false )); if (!is_wp_error($cluster_terms) && !empty($cluster_terms)) { foreach ($cluster_terms as $term) { update_term_meta($term->term_id, '_igny8_keyword_ids', $keyword_ids); } } // Update posts tied to this cluster $posts = get_posts(array( 'post_type' => $enabled_post_types, 'meta_query' => array( array( 'key' => '_igny8_cluster_id', 'value' => $cluster_id, 'compare' => '=' ) ), 'post_status' => 'any', 'fields' => 'ids', 'nopaging' => true )); foreach ($posts as $post_id) { update_post_meta($post_id, '_igny8_keyword_ids', $keyword_ids); $synced_posts++; } $synced_clusters++; } return array( 'synced_clusters' => $synced_clusters, 'synced_posts' => $synced_posts ); } /** * Cron handler: sync planner keywords * * @return array|false */ function igny8_cron_sync_keywords() { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { error_log('IGNY8: Connection disabled, skipping keyword sync'); return array('synced_clusters' => 0, 'synced_posts' => 0, 'skipped' => true); } $result = igny8_sync_keywords_from_planner(); if ($result !== false) { update_option('igny8_last_keyword_sync', current_time('timestamp')); } return $result; } /** * Map WordPress taxonomy term to IGNY8 cluster * * @param int $term_id Term ID * @param string $taxonomy Taxonomy name * @param int $cluster_id IGNY8 cluster ID * @return bool True on success */ function igny8_map_term_to_cluster($term_id, $taxonomy, $cluster_id) { if ($taxonomy !== 'igny8_clusters') { return false; } update_term_meta($term_id, '_igny8_cluster_id', $cluster_id); return true; } /** * Map WordPress taxonomy to IGNY8 sector * * @param string $taxonomy Taxonomy name * @param int $sector_id IGNY8 sector ID * @return bool True on success */ function igny8_map_taxonomy_to_sector($taxonomy, $sector_id) { // Store mapping in options $mappings = get_option('igny8_taxonomy_sector_mappings', array()); $mappings[$taxonomy] = $sector_id; update_option('igny8_taxonomy_sector_mappings', $mappings); return true; }