settings = get_option('fulgid_aicogu_settings', array()); $this->seo_integrator = new FULGID_AICOGU_SEO_Integrator(); } /** * Analyze site content and return structured data for llms.txt. * * @return string The formatted content for llms.txt. */ public function analyze_site_content() { // Initialize content with enhanced header $content = $this->get_enhanced_site_header(); // Add site metadata section $content .= $this->get_site_metadata(); // Add navigation structure $content .= $this->get_navigation_structure(); // Get main content sections with enhanced formatting $content .= $this->get_enhanced_main_content(); // Get taxonomies if enabled if (!empty($this->settings['include_taxonomies'])) { $content .= $this->get_enhanced_taxonomies(); } // Add popular content section $content .= $this->get_popular_content(); // Add recent content section $content .= $this->get_recent_content(); // Add contact and social information $content .= $this->get_contact_information(); // Get custom content if set if (!empty($this->settings['custom_content'])) { $content .= "\n\n## Custom Information\n\n" . $this->settings['custom_content']; } // Add footer information $content .= $this->get_site_footer(); return $content; } /** * Get enhanced site header with title, description, and metadata. * * @return string */ private function get_enhanced_site_header() { $site_name = get_bloginfo('name'); $site_description = get_bloginfo('description'); $site_url = home_url(); $content = "# {$site_name}\n\n"; $content .= "> **{$site_description}**\n\n"; $content .= "🌐 **Website:** [{$site_url}]({$site_url})\n\n"; // Add generation timestamp $content .= "📅 **Generated:** " . date('Y-m-d H:i:s T') . "\n\n"; // Add site introduction if set if (!empty($this->settings['site_introduction'])) { $content .= "## About This Site\n\n"; $content .= $this->settings['site_introduction'] . "\n\n"; } $content .= "---\n\n"; return $content; } /** * Get site metadata section. * * @return string */ private function get_site_metadata() { $content = "## 📊 Site Information\n\n"; // WordPress info $wp_version = get_bloginfo('version'); $admin_email = get_bloginfo('admin_email'); $language = get_bloginfo('language'); $charset = get_bloginfo('charset'); $content .= "- **Content Management System:** WordPress {$wp_version}\n"; $content .= "- **Language:** {$language}\n"; $content .= "- **Character Encoding:** {$charset}\n"; // Site statistics $post_count = wp_count_posts('post')->publish; $page_count = wp_count_posts('page')->publish; $user_count = count_users()['total_users']; $content .= "- **Published Posts:** {$post_count}\n"; $content .= "- **Published Pages:** {$page_count}\n"; $content .= "- **Total Users:** {$user_count}\n"; // Theme info $theme = wp_get_theme(); $content .= "- **Active Theme:** {$theme->get('Name')} v{$theme->get('Version')}\n"; $content .= "\n"; return $content; } /** * Get navigation structure. * * @return string */ private function get_navigation_structure() { $content = "## 🧭 Site Navigation\n\n"; // Get primary menu if exists $locations = get_nav_menu_locations(); if (!empty($locations['primary'])) { $menu = wp_get_nav_menu_object($locations['primary']); if ($menu) { $menu_items = wp_get_nav_menu_items($menu->term_id); if ($menu_items) { $content .= "### Primary Menu\n\n"; foreach ($menu_items as $item) { if ($item->menu_item_parent == 0) { // Top level items only $content .= "- [{$item->title}]({$item->url})\n"; } } $content .= "\n"; } } } return $content; } /** * Get enhanced main content for llms.txt file. * * @return string */ private function get_enhanced_main_content() { $content = "## 📚 Content Sections\n\n"; $post_types = $this->get_included_post_types(); foreach ($post_types as $post_type) { $post_type_obj = get_post_type_object($post_type); if (!$post_type_obj) { continue; } // Get post count for this type $post_count = wp_count_posts($post_type)->publish; // Add enhanced section heading for post type $content .= "### " . $post_type_obj->labels->name . " ({$post_count} items)\n\n"; // Get posts for this post type $posts = $this->get_posts_for_post_type($post_type); if (empty($posts)) { $content .= "_No content available in this section._\n\n"; continue; } foreach ($posts as $post) { // Skip if this post is excluded if ($this->is_post_excluded($post->ID)) { continue; } // Get post title, URL, and description $title = $post->post_title; $url = get_permalink($post->ID); $description = $this->get_post_description($post); $date = get_the_date('Y-m-d', $post->ID); $author = get_the_author_meta('display_name', $post->post_author); // Get post tags/categories for context $tags = get_the_tags($post->ID); $categories = get_the_category($post->ID); $meta_info = []; if (!empty($categories)) { $cat_names = array_map(function($cat) { return $cat->name; }, $categories); $meta_info[] = 'Categories: ' . implode(', ', $cat_names); } if (!empty($tags)) { $tag_names = array_map(function($tag) { return $tag->name; }, $tags); $meta_info[] = 'Tags: ' . implode(', ', $tag_names); } // Enhanced content format $content .= "**[{$title}]({$url})**\n"; $content .= "_{$description}_\n"; $content .= "📅 Published: {$date} | âœī¸ Author: {$author}\n"; if (!empty($meta_info)) { $content .= "đŸˇī¸ " . implode(' | ', $meta_info) . "\n"; } $content .= "\n"; } $content .= "---\n\n"; } return $content; } /** * Get enhanced taxonomies content. * * @return string */ private function get_enhanced_taxonomies() { $content = "## đŸˇī¸ Content Categories & Tags\n\n"; $taxonomies = !empty($this->settings['taxonomies']) ? $this->settings['taxonomies'] : array('category', 'post_tag'); foreach ($taxonomies as $taxonomy) { $tax_obj = get_taxonomy($taxonomy); if (!$tax_obj) { continue; } // Get terms for this taxonomy $terms = get_terms(array( 'taxonomy' => $taxonomy, 'hide_empty' => true, 'orderby' => 'count', 'order' => 'DESC', )); if (empty($terms) || is_wp_error($terms)) { continue; } // Add section heading for taxonomy $content .= "### " . $tax_obj->labels->name . " (" . count($terms) . " terms)\n\n"; foreach ($terms as $term) { $name = $term->name; $url = get_term_link($term); $description = !empty($term->description) ? wp_strip_all_tags($term->description) : "Content related to {$name}"; $post_count = $term->count; // Enhanced format with post count and better styling $content .= "**[{$name}]({$url})** ({$post_count} posts)\n"; $content .= "_{$description}_\n\n"; } $content .= "---\n\n"; } return $content; } /** * Get included post types from settings. * * @return array */ private function get_included_post_types() { $default_post_types = array('page', 'post'); return !empty($this->settings['post_types']) ? $this->settings['post_types'] : $default_post_types; } /** * Get posts for a specific post type. * * @param string $post_type The post type. * @return array */ private function get_posts_for_post_type($post_type) { $max_posts = !empty($this->settings['max_posts_per_type']) ? intval($this->settings['max_posts_per_type']) : 20; $args = array( 'post_type' => $post_type, 'post_status' => 'publish', 'posts_per_page' => $max_posts, 'orderby' => 'date', 'order' => 'DESC', ); // Apply SEO filtering if integrated $args = $this->seo_integrator->filter_query_args($args); return get_posts($args); } /** * Check if a post is excluded from llms.txt. * * @param int $post_id The post ID. * @return bool */ private function is_post_excluded($post_id) { // Check if post is in excluded list $excluded_posts = !empty($this->settings['excluded_posts']) ? $this->settings['excluded_posts'] : array(); if (in_array($post_id, $excluded_posts)) { return true; } // Check if post has noindex from SEO plugins if ($this->seo_integrator->is_post_noindex($post_id)) { return true; } return false; } /** * Get description for a post. * * @param WP_Post $post The post object. * @return string */ private function get_post_description($post) { // Check for SEO description first $seo_description = $this->seo_integrator->get_meta_description($post->ID); if (!empty($seo_description)) { // Use wp_strip_all_tags to remove any HTML $description = wp_strip_all_tags($seo_description); } // Fall back to excerpt if available else if (!empty($post->post_excerpt)) { $description = wp_strip_all_tags($post->post_excerpt); } // Generate description from content else { $content = wp_strip_all_tags($post->post_content); // Clean up any extra whitespace or line breaks $content = preg_replace('/\s+/', ' ', $content); $content = trim($content); $max_length = !empty($this->settings['description_length']) ? intval($this->settings['description_length']) : 150; if (strlen($content) > $max_length) { $description = substr($content, 0, $max_length) . '...'; } else { $description = $content; } } // Ensure the description is properly sanitized before returning return sanitize_text_field($description); } /** * Get popular content section. * * @return string */ private function get_popular_content() { $content = "## đŸ”Ĩ Popular Content\n\n"; // Get most commented posts $popular_posts = get_posts(array( 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => 5, 'orderby' => 'comment_count', 'order' => 'DESC', 'meta_query' => array( array( 'key' => '_wp_old_slug', 'compare' => 'NOT EXISTS' ) ) )); if (!empty($popular_posts)) { $content .= "### Most Discussed Posts\n\n"; foreach ($popular_posts as $post) { if ($this->is_post_excluded($post->ID)) { continue; } $title = $post->post_title; $url = get_permalink($post->ID); $comment_count = $post->comment_count; $content .= "- **[{$title}]({$url})** ({$comment_count} comments)\n"; } $content .= "\n"; } return $content; } /** * Get recent content section. * * @return string */ private function get_recent_content() { $content = "## 🆕 Recent Updates\n\n"; // Get recently updated posts $recent_posts = get_posts(array( 'post_type' => array('post', 'page'), 'post_status' => 'publish', 'posts_per_page' => 5, 'orderby' => 'modified', 'order' => 'DESC', )); if (!empty($recent_posts)) { foreach ($recent_posts as $post) { if ($this->is_post_excluded($post->ID)) { continue; } $title = $post->post_title; $url = get_permalink($post->ID); $modified_date = get_the_modified_date('Y-m-d', $post->ID); $post_type = get_post_type_object($post->post_type)->labels->singular_name; $content .= "- **[{$title}]({$url})** ({$post_type}) - Updated: {$modified_date}\n"; } $content .= "\n"; } return $content; } /** * Get contact and social information. * * @return string */ private function get_contact_information() { $content = "## 📞 Contact & Social\n\n"; // Get admin email $admin_email = get_bloginfo('admin_email'); if ($admin_email && !empty($admin_email)) { $content .= "**Contact Email:** {$admin_email}\n\n"; } // Check for common social media and contact options $social_options = array( 'facebook' => 'Facebook', 'twitter' => 'Twitter', 'instagram' => 'Instagram', 'linkedin' => 'LinkedIn', 'youtube' => 'YouTube' ); $found_social = false; foreach ($social_options as $platform => $label) { $option_value = get_option($platform . '_url', ''); if (!empty($option_value)) { if (!$found_social) { $content .= "**Social Media:**\n"; $found_social = true; } $content .= "- [{$label}]({$option_value})\n"; } } if ($found_social) { $content .= "\n"; } return $content; } /** * Get site footer information. * * @return string */ private function get_site_footer() { $content = "---\n\n"; $content .= "## â„šī¸ About This File\n\n"; $content .= "This llms.txt file was automatically generated by the LLMs Text Generator plugin.\n"; $content .= "It follows the [llms.txt specification](https://llmstxt.org/) to help AI systems better understand this website's content.\n\n"; $content .= "**Last Updated:** " . date('Y-m-d H:i:s T') . "\n"; $content .= "**Generator:** LLMs Text Generator for WordPress\n"; $content .= "**Enhanced by:** [llmstxt.in](https://llmstxt.in/?utm_source=plugin&utm_medium=footer)\n"; $content .= "**Made with â¤ī¸ by:** [Fulgid](https://fulgid.in)\n\n"; $content .= "_This file is automatically updated when content changes._\n"; return $content; } }