PluginProbe ʕ •ᴥ•ʔ
Hostinger Tools / 3.0.71
Hostinger Tools v3.0.71
3.0.71 3.0.70 3.0.69 3.0.68 3.0.67 3.0.66 1.8.1 1.8.2 1.8.3 1.9.1 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.4 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.2 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 3.0.0 3.0.10 3.0.11 3.0.12 3.0.13 3.0.14 3.0.15 3.0.16 3.0.17 3.0.18 3.0.19 3.0.2 3.0.20 3.0.21 3.0.22 3.0.23 3.0.24 3.0.25 3.0.26 3.0.27 3.0.28 3.0.29 3.0.3 3.0.30 3.0.31 3.0.32 3.0.33 3.0.34 3.0.35 3.0.36 3.0.37 3.0.38 3.0.39 3.0.4 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.0.46 3.0.47 3.0.48 3.0.49 3.0.5 3.0.50 3.0.51 3.0.52 3.0.53 3.0.54 3.0.55 3.0.56 3.0.57 3.0.58 3.0.59 3.0.6 3.0.60 3.0.61 3.0.62 3.0.65 3.0.7 3.0.8 3.0.9 trunk 1.8.0
hostinger / includes / LlmsTxtGenerator / LlmsTxtGenerator.php
hostinger / includes / LlmsTxtGenerator Last commit date
LlmsTxtFileHelper.php 10 months ago LlmsTxtGenerator.php 2 weeks ago LlmsTxtParser.php 10 months ago
LlmsTxtGenerator.php
178 lines
1 <?php
2
3 namespace Hostinger\LlmsTxtGenerator;
4
5 use Hostinger\Admin\Jobs\LlmsTxtInjectContentJob;
6 use Hostinger\Admin\PluginSettings;
7 use Hostinger\Helper;
8
9 defined( 'ABSPATH' ) || exit;
10
11 class LlmsTxtGenerator {
12
13 public const HOSTINGER_LLMSTXT_SIGNATURE = '[comment]: # (Generated by Hostinger Tools Plugin)';
14 protected const UTF8_BOM = "\xEF\xBB\xBF";
15 public const HOSTINGER_LLMSTXT_SUPPORTED_POST_TYPES = array(
16 'post' => 'Posts',
17 'page' => 'Pages',
18 'product' => 'Products',
19 );
20
21 /**
22 * Activation and deactivation hooks appears too early,
23 * so the plugin status is not available yet.
24 *
25 * That's why we use a flag this->woocommerce_status to know the plugin status.
26 *
27 * @var string|null
28 */
29 protected ?string $woocommerce_status = null;
30 protected PluginSettings $plugin_settings;
31 protected LlmsTxtFileHelper $file_helper;
32 protected LlmsTxtParser $parser;
33
34 public function __construct( PluginSettings $plugin_settings, LlmsTxtFileHelper $llmstxt_file_helper, LlmsTxtParser $llms_txt_parser ) {
35 $this->plugin_settings = $plugin_settings;
36 $this->file_helper = $llmstxt_file_helper;
37 $this->parser = $llms_txt_parser;
38 add_action( 'init', array( $this, 'init' ) );
39 }
40
41 public function on_woocommerce_activation(): void {
42 $this->woocommerce_status = 'active';
43 $this->generate();
44 }
45
46 public function on_woocommerce_deactivation(): void {
47 $this->woocommerce_status = 'inactive';
48 $this->generate();
49 }
50
51 public function init(): void {
52 $this->init_hooks();
53
54 if ( wp_doing_ajax() || wp_doing_cron() || ! current_user_can( 'manage_options' ) ) {
55 return;
56 }
57
58 $settings = $this->plugin_settings->get_plugin_settings();
59
60 if ( $settings->get_enable_llms_txt() && ! $this->file_helper->llmstxt_file_exists() ) {
61 $this->generate();
62 }
63 }
64
65 public function on_settings_update( bool $is_enabled ): void {
66 if ( $is_enabled ) {
67 $this->generate();
68 } else {
69 $this->delete();
70 }
71 }
72
73 public function on_post_status_change( string $new_status, string $old_status, \WP_Post $post ): void {
74 if ( ! $this->is_post_type_supported( $post->post_type ) ) {
75 return;
76 }
77
78 if ( $new_status === 'publish' || $old_status === 'publish' ) {
79 $this->generate();
80 }
81 }
82
83 public function on_blog_change( mixed $old_value, mixed $new_value ): void {
84 if ( $old_value !== $new_value ) {
85 $this->generate();
86 }
87 }
88
89 public function get_content(): string {
90 $content = self::UTF8_BOM;
91 $content .= $this->parser->inject_title();
92 $content .= $this->parser->inject_site_description();
93 $content .= $this->parser->inject_items( $this->parser->get_by_post_type( 'post' ), 'Posts' );
94 $content .= $this->parser->inject_items( $this->parser->get_by_post_type( 'page' ), 'Pages' );
95 $content .= $this->maybe_inject_woocommerce_products();
96 $content .= $this->maybe_inject_optional_entries();
97 $content .= $this->parser->inject_signature();
98
99 return $content;
100 }
101
102 public function init_hooks(): void {
103 add_action( 'transition_post_status', array( $this, 'on_post_status_change' ), 10, 3 );
104 add_action( 'hostinger_tools_settings_saved', array( $this, 'on_settings_saved' ) );
105 add_action( 'update_option_blogname', array( $this, 'on_blog_change' ), 10, 2 );
106 add_action( 'update_option_blogdescription', array( $this, 'on_blog_change' ), 10, 2 );
107 add_action( 'activate_woocommerce/woocommerce.php', array( $this, 'on_woocommerce_activation' ) );
108 add_action( 'deactivate_woocommerce/woocommerce.php', array( $this, 'on_woocommerce_deactivation' ) );
109 }
110
111 public function on_settings_saved( array $settings ): void {
112 if ( $settings['enable_llms_txt'] ) {
113 $this->generate();
114 } else {
115 $this->delete();
116 }
117 }
118
119 public function generate(): void {
120 $settings = $this->plugin_settings->get_plugin_settings();
121 if ( ! $settings->get_enable_llms_txt() ) {
122 return;
123 }
124
125 if ( $this->file_helper->is_user_generated_file() ) {
126 return;
127 }
128
129 $this->file_helper->create( $this->get_content() );
130 do_action( LlmsTxtInjectContentJob::JOB_NAME, array( 'post_type' => 'post' ) );
131 do_action( LlmsTxtInjectContentJob::JOB_NAME, array( 'post_type' => 'page' ) );
132
133 if ( $this->is_woocommerce_active() ) {
134 do_action( LlmsTxtInjectContentJob::JOB_NAME, array( 'post_type' => 'product' ) );
135 }
136 }
137
138 protected function delete(): void {
139 $this->file_helper->delete();
140 }
141
142 protected function is_post_type_supported( string $post_type ): bool {
143 return array_key_exists( $post_type, self::HOSTINGER_LLMSTXT_SUPPORTED_POST_TYPES );
144 }
145
146 protected function is_woocommerce_active(): bool {
147 return ( is_null( $this->woocommerce_status ) && Helper::is_plugin_active( 'woocommerce/woocommerce' ) ) || $this->woocommerce_status === 'active';
148 }
149
150 protected function maybe_inject_woocommerce_products(): string {
151 if ( ! $this->is_woocommerce_active() ) {
152 return '';
153 }
154
155 return $this->parser->inject_items( $this->parser->get_by_post_type( 'product' ), 'Products' );
156 }
157
158 protected function maybe_inject_optional_entries(): string {
159 $entries = array();
160 $mcp_entry = $this->maybe_inject_mcp_agent_entry();
161
162 if ( $mcp_entry ) {
163 $entries[] = $mcp_entry;
164 }
165
166 return $this->parser->inject_optional_entries( $entries );
167 }
168
169 protected function maybe_inject_mcp_agent_entry(): string {
170 $settings = $this->plugin_settings->get_plugin_settings();
171 if ( ! $settings->get_optin_mcp() ) {
172 return '';
173 }
174
175 return $this->parser->inject_mcp_agent_entry();
176 }
177 }
178