settings = get_option('fulgid_aicogu_settings', array());
}
/**
* Generate the llms.txt file with the provided content.
*
* @param string $content The content to write to the file.
* @return bool True on success, false on failure.
*/
public function generate_file($content) {
// Store the content in the database regardless of file method
update_option('fulgid_aicogu_file_content', $content);
// Get file method from settings
$file_method = isset($this->settings['file_method']) ? $this->settings['file_method'] : 'rewrite';
if ('direct' === $file_method) {
return $this->write_file_directly($content);
}
// For rewrite method, just store content in database
// The rewrite rules will serve it dynamically
// Flush rewrite rules to ensure our rule is registered
flush_rewrite_rules();
return true;
}
/**
* Write the llms.txt file directly to the site root.
*
* @param string $content The content to write.
* @return bool True on success, false on failure.
*/
private function write_file_directly($content) {
// Check if we can get the ABSPATH directory
$root_path = ABSPATH;
$file_path = $root_path . 'llms.txt';
// Try to write the file
$result = @file_put_contents($file_path, $content);
if (false === $result) {
// Log error or set admin notice
add_action('admin_notices', array($this, 'file_write_error_notice'));
return false;
}
return true;
}
/**
* Show admin notice for file write errors.
*/
public function file_write_error_notice() {
?>
analyze_site_content();
// Store for future use
update_option('fulgid_aicogu_file_content', $content);
}
// Do not escape here - escaping should be done at the output point
return $content;
}
/**
* Check if the llms.txt file exists and is accessible via URL.
*
* @return array Status information.
*/
public function check_file_status() {
$result = array(
'exists' => false,
'accessible' => false,
'method' => isset($this->settings['file_method']) ? $this->settings['file_method'] : 'rewrite',
'url' => site_url('/llms.txt'),
);
// For direct method, check if file exists in the file system
if ('direct' === $result['method']) {
$root_path = ABSPATH;
$file_path = $root_path . 'llms.txt';
$result['exists'] = file_exists($file_path);
} else {
// For rewrite method, check if content exists in the database
$content = get_option('fulgid_aicogu_file_content', '');
$result['exists'] = !empty($content);
}
// Check if file is accessible via URL
$response = wp_remote_get($result['url']);
$result['accessible'] = !is_wp_error($response) && 200 === wp_remote_retrieve_response_code($response);
return $result;
}
/**
* Get last modification time of the file.
*
* @return int|bool Timestamp or false if file doesn't exist.
*/
public function get_last_modified() {
$file_method = isset($this->settings['file_method']) ? $this->settings['file_method'] : 'rewrite';
if ('direct' === $file_method) {
$root_path = ABSPATH;
$file_path = $root_path . 'llms.txt';
if (file_exists($file_path)) {
return filemtime($file_path);
}
}
// For rewrite method or if direct file doesn't exist, use option update time
return get_option('fulgid_aicogu_file_updated', time());
}
/**
* Add a reference to llms.txt in robots.txt.
*
* @param string $robots_content Current robots.txt content.
* @return string Modified robots.txt content.
*/
public function add_robots_txt_reference($robots_content) {
if (empty($this->settings['add_to_robots']) || 'yes' !== $this->settings['add_to_robots']) {
return $robots_content;
}
$llms_line = "\n# For LLM training, we have implemented an llms.txt file following https://llmstxt.org/ guidelines.";
$llms_line .= "\n# This file helps AI systems better understand our website content.";
$llms_line .= "\nSitemap: " . site_url('/llms.txt');
// Check if reference already exists
if (strpos($robots_content, 'llms.txt') !== false) {
return $robots_content;
}
return $robots_content . $llms_line;
}
/**
* Generate an enhanced llms-full.txt file with comprehensive content.
*
* @param string $basic_content The basic llms.txt content.
* @return string The expanded content for llms-full.txt.
*/
public function generate_full_file($basic_content) {
// Check if full file generation is enabled
if (empty($this->settings['generate_full_file']) || 'yes' !== $this->settings['generate_full_file']) {
return $basic_content;
}
// Start with enhanced header for full file
$full_content = "# " . get_bloginfo('name') . " - Complete Content Archive\n\n";
$full_content .= "> **Full llms.txt file with comprehensive content and metadata**\n\n";
$full_content .= "đ **Website:** [" . home_url() . "](" . home_url() . ")\n";
$full_content .= "đ
**Generated:** " . date('Y-m-d H:i:s T') . "\n";
$full_content .= "đ **File Type:** llms-full.txt (Extended Version)\n\n";
$full_content .= "---\n\n";
// Add basic content first
$full_content .= $basic_content . "\n\n";
// Add comprehensive content sections
$full_content .= "## đ Complete Content Archive\n\n";
$full_content .= "_This section contains full content for better AI understanding._\n\n";
// Add more detailed content for each post type
$post_types = isset($this->settings['post_types']) ? $this->settings['post_types'] : array('post', 'page');
foreach ($post_types as $post_type) {
$post_type_obj = get_post_type_object($post_type);
if (!$post_type_obj) {
continue;
}
$full_content .= "### đ " . $post_type_obj->labels->name . " - Full Content\n\n";
// Get a limited number of posts
$args = array(
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => 15, // More content for full version
'orderby' => 'date',
'order' => 'DESC',
);
$posts = get_posts($args);
if (empty($posts)) {
$full_content .= "_No content available for this post type._\n\n";
continue;
}
foreach ($posts as $post) {
$title = $post->post_title;
$url = get_permalink($post->ID);
$post_content = wp_strip_all_tags($post->post_content);
$excerpt = $post->post_excerpt;
$date = get_the_date('Y-m-d', $post->ID);
$author = get_the_author_meta('display_name', $post->post_author);
// Get categories and tags
$categories = get_the_category($post->ID);
$tags = get_the_tags($post->ID);
// Limit content length but allow more than basic version
$max_length = 2000; // Double the basic limit for full version
if (strlen($post_content) > $max_length) {
$post_content = substr($post_content, 0, $max_length) . '...';
}
$full_content .= "#### đ {$title}\n\n";
$full_content .= "**URL:** [{$url}]({$url})\n";
$full_content .= "**Published:** {$date} | **Author:** {$author}\n";
if (!empty($categories)) {
$cat_names = array_map(function($cat) { return $cat->name; }, $categories);
$full_content .= "**Categories:** " . implode(', ', $cat_names) . "\n";
}
if (!empty($tags)) {
$tag_names = array_map(function($tag) { return $tag->name; }, $tags);
$full_content .= "**Tags:** " . implode(', ', $tag_names) . "\n";
}
if (!empty($excerpt)) {
$full_content .= "\n**Excerpt:** _{$excerpt}_\n";
}
$full_content .= "\n**Content:**\n{$post_content}\n\n";
$full_content .= "---\n\n";
}
}
// Add site statistics section
$full_content .= $this->get_site_statistics();
// Add footer for full file
$full_content .= "## âšī¸ About This Full File\n\n";
$full_content .= "This llms-full.txt file provides comprehensive content for AI training and understanding.\n";
$full_content .= "It includes complete post content, metadata, and site statistics.\n\n";
$full_content .= "**Generated by:** LLMs Text Generator for WordPress\n";
$full_content .= "**Enhanced by:** [llmstxt.in](https://llmstxt.in/?utm_source=plugin&utm_medium=full-file)\n";
$full_content .= "**Made with â¤ī¸ by:** [Fulgid](https://fulgid.in)\n";
$full_content .= "**Last Updated:** " . date('Y-m-d H:i:s T') . "\n\n";
$full_content .= "_This file is automatically regenerated when content changes._\n";
// Store the full content
update_option('fulgid_aicogu_full_file_content', $full_content);
return $full_content;
}
/**
* Get detailed site statistics for full file.
*
* @return string
*/
private function get_site_statistics() {
$content = "## đ Detailed Site Statistics\n\n";
// Get all post types and their counts
$post_types = get_post_types(array('public' => true), 'objects');
$content .= "### Content Statistics\n\n";
foreach ($post_types as $post_type) {
$count = wp_count_posts($post_type->name)->publish;
$content .= "- **{$post_type->labels->name}:** {$count} published\n";
}
// Get taxonomy statistics
$taxonomies = get_taxonomies(array('public' => true), 'objects');
$content .= "\n### Taxonomy Statistics\n\n";
foreach ($taxonomies as $taxonomy) {
$terms = get_terms(array('taxonomy' => $taxonomy->name, 'hide_empty' => false));
if (!is_wp_error($terms)) {
$count = count($terms);
$content .= "- **{$taxonomy->labels->name}:** {$count} terms\n";
}
}
// Get user statistics
$user_count = count_users();
$content .= "\n### User Statistics\n\n";
$content .= "- **Total Users:** {$user_count['total_users']}\n";
foreach ($user_count['avail_roles'] as $role => $count) {
$role_obj = get_role($role);
$role_name = ucfirst($role);
$content .= "- **{$role_name}:** {$count}\n";
}
$content .= "\n";
return $content;
}
/**
* Get the full file content from the database.
*
* @return string The full file content.
*/
public function get_full_file_content() {
$content = get_option('fulgid_aicogu_full_file_content', '');
if (empty($content)) {
// If no content is stored, generate it now
$basic_content = $this->get_file_content();
$content = $this->generate_full_file($basic_content);
}
return $content;
}
}