post_content; $source_url = get_permalink($post_id); $site_url = get_site_url(); $links = array(); // Match all anchor tags with href attributes preg_match_all('/]+href=["\']([^"\']+)["\'][^>]*>(.*?)<\/a>/is', $content, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $href = $match[1]; $anchor = strip_tags($match[2]); // Skip empty anchors if (empty(trim($anchor))) { continue; } // Only process internal links if (strpos($href, $site_url) === 0 || strpos($href, '/') === 0) { // Convert relative URLs to absolute if (strpos($href, '/') === 0 && strpos($href, '//') !== 0) { $href = $site_url . $href; } // Normalize URL (remove trailing slash, fragments, query params for matching) $target_url = rtrim($href, '/'); // Skip if source and target are the same if ($source_url === $target_url) { continue; } $links[] = array( 'source_url' => $source_url, 'target_url' => $target_url, 'anchor' => trim($anchor), 'post_id' => $post_id ); } } return $links; } /** * Extract link graph from all posts * * @param array $post_ids Optional array of post IDs to process. If empty, processes all enabled posts. * @return array Link graph array */ function igny8_extract_link_graph($post_ids = array()) { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { return array(); } if (function_exists('igny8_is_module_enabled') && !igny8_is_module_enabled('linker')) { return array(); } $enabled_post_types = igny8_get_enabled_post_types(); if (empty($post_ids)) { // Get all published posts of enabled types $query_args = array( 'post_type' => $enabled_post_types, 'post_status' => 'publish', 'posts_per_page' => -1, 'fields' => 'ids', 'suppress_filters' => true ); $post_ids = get_posts($query_args); } $link_graph = array(); $processed = 0; foreach ($post_ids as $post_id) { $links = igny8_extract_post_links($post_id); if (!empty($links)) { $link_graph = array_merge($link_graph, $links); } $processed++; // Limit processing to prevent timeout (can be increased or made configurable) if ($processed >= 1000) { break; } } return $link_graph; } /** * Send link graph to IGNY8 Linker module * * @param int $site_id IGNY8 site ID * @param array $link_graph Link graph array (optional, will extract if not provided) * @return array|false Response data or false on failure */ function igny8_send_link_graph_to_igny8($site_id, $link_graph = null) { // Skip if connection is disabled if (!igny8_is_connection_enabled()) { return false; } if (function_exists('igny8_is_module_enabled') && !igny8_is_module_enabled('linker')) { return false; } $api = new Igny8API(); if (!$api->is_authenticated()) { return false; } // Extract link graph if not provided if ($link_graph === null) { $link_graph = igny8_extract_link_graph(); } if (empty($link_graph)) { return array('success' => true, 'message' => 'No links found', 'links_count' => 0); } // Send in batches (max 500 links per batch) $batch_size = 500; $batches = array_chunk($link_graph, $batch_size); $total_sent = 0; $errors = array(); foreach ($batches as $batch) { $response = $api->post("/linker/link-map/", array( 'site_id' => $site_id, 'links' => $batch, 'total_links' => count($link_graph), 'batch_number' => count($batches) > 1 ? (count($batches) - count($batches) + array_search($batch, $batches) + 1) : 1, 'total_batches' => count($batches) )); if ($response['success']) { $total_sent += count($batch); } else { $errors[] = $response['error'] ?? 'Unknown error'; } } if ($total_sent > 0) { update_option('igny8_last_link_graph_sync', current_time('timestamp')); update_option('igny8_last_link_graph_count', $total_sent); return array( 'success' => true, 'links_sent' => $total_sent, 'total_links' => count($link_graph), 'batches' => count($batches), 'errors' => $errors ); } return false; }