Settings.', 'ai-internal-links' ), admin_url( 'options-general.php?page=ai-internal-links' ) ) ); } // Get available links. $content_analyzer = new AIIL_Content_Analyzer(); $available_links = $content_analyzer->get_available_links( $post_id ); if ( empty( $available_links ) ) { return new WP_Error( 'no_links_available', __( 'No published posts or pages found to link to.', 'ai-internal-links' ) ); } // Get LLM provider. $provider = AIIL_LLM_Factory::get_provider( $provider_name ); if ( is_wp_error( $provider ) ) { return $provider; } // Prepare settings for provider. $provider_settings = array( 'api_key' => $api_key, 'model' => $model, 'max_links' => $max_links, ); /** * Filter provider settings before generation. * * @since 1.0.0 * @param array $provider_settings Provider settings. * @param string $provider_name Provider name. */ $provider_settings = apply_filters( 'aiil_provider_settings', $provider_settings, $provider_name ); // Generate suggestions. $suggestions = $provider->generate_suggestions( $content, $available_links, $provider_settings ); if ( is_wp_error( $suggestions ) ) { return $suggestions; } /** * Filter generated suggestions. * * @since 1.0.0 * @param array $suggestions Generated suggestions. * @param string $content Original content. * @param int $post_id Post ID. */ return apply_filters( 'aiil_generated_suggestions', $suggestions, $content, $post_id ); } /** * Generate and apply internal links to content. * * @param string $content Content to process. * @param int $post_id Current post ID. * @return string|WP_Error Modified content with links or error. */ public function generate_and_apply( $content, $post_id = 0 ) { // Get suggestions. $suggestions = $this->generate( $content, $post_id ); if ( is_wp_error( $suggestions ) ) { return $suggestions; } // If no suggestions, return original content. if ( empty( $suggestions ) ) { return $content; } // Apply each suggestion to content. foreach ( $suggestions as $suggestion ) { if ( ! isset( $suggestion['search'] ) || ! isset( $suggestion['replace'] ) ) { continue; } $search = $suggestion['search']; $replace = $suggestion['replace']; // Replace first occurrence only (exact match, case-sensitive). $content = preg_replace( '/' . preg_quote( $search, '/' ) . '/', $replace, $content, 1 ); } /** * Filter content after links have been applied. * * @since 1.0.0 * @param string $content Modified content. * @param array $suggestions Applied suggestions. * @param int $post_id Post ID. */ return apply_filters( 'aiil_content_with_links', $content, $suggestions, $post_id ); } }