PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.0.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.0.0
2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 All 48 releases
thinkrank / includes / abilities / settings / class-update-llms-txt-settings.php

class-update-llms-txt-settings.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 2.0.0, at includes/abilities/settings/class-update-llms-txt-settings.php

192 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Update llms.txt settings ability.
4 *
5 * @package ThinkRank\Abilities\Settings
6 */
7
8 declare(strict_types=1);
9
10 namespace ThinkRank\Abilities\Settings;
11
12 use ThinkRank\Abilities\Ability_Base;
13 use ThinkRank\SEO\LLMs_Txt_Manager;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 /**
20 * Updates ThinkRank llms.txt settings.
21 *
22 * These settings feed the AI-oriented llms.txt file describing the site to
23 * language models, persisted through the LLMs_Txt_Manager SEO manager.
24 */
25 class Update_Llms_Txt_Settings extends Ability_Base {
26 /**
27 * Boolean-typed llms.txt keys.
28 */
29 private const BOOL_KEYS = [
30 'enabled',
31 'auto_generate',
32 ];
33
34 /**
35 * String-typed llms.txt keys (multi-line content preserved).
36 */
37 private const STRING_KEYS = [
38 'site_name',
39 'website_description',
40 'key_features',
41 'target_audience',
42 'business_type',
43 'technical_stack',
44 'development_approach',
45 'setup_instructions',
46 'ai_context_custom',
47 'documentation_links',
48 'technical_links',
49 'optional_links',
50 'custom_sections',
51 ];
52
53 /**
54 * Constructor.
55 */
56 public function __construct() {
57 $this->id = 'thinkrank/update-llms-txt-settings';
58 $this->label = __( 'Update ThinkRank llms.txt Settings', 'thinkrank' );
59 $this->description = __( 'Update ThinkRank llms.txt settings, which describe the site to AI language models via the llms.txt file.', 'thinkrank' );
60 }
61
62 /**
63 * {@inheritDoc}
64 *
65 * @return array<string, bool|float|string>
66 */
67 public function get_annotations() {
68 return [
69 'readonly' => false,
70 'destructive' => true,
71 'idempotent' => true,
72 'priority' => 2.0,
73 'openWorldHint' => false,
74 ];
75 }
76
77 /**
78 * Build the JSON schema properties for llms.txt settings.
79 *
80 * @return array<string, mixed>
81 */
82 private static function schema_properties() {
83 $props = [];
84
85 foreach ( self::BOOL_KEYS as $key ) {
86 $props[ $key ] = [ 'type' => 'boolean' ];
87 }
88 foreach ( self::STRING_KEYS as $key ) {
89 $props[ $key ] = [ 'type' => 'string' ];
90 }
91
92 return $props;
93 }
94
95 /**
96 * {@inheritDoc}
97 *
98 * @return array<string, mixed>
99 */
100 public function get_input_schema() {
101 return [
102 'type' => 'object',
103 'additionalProperties' => false,
104 'properties' => [
105 'settings' => [
106 'type' => 'object',
107 'description' => __( 'llms.txt settings to update.', 'thinkrank' ),
108 'properties' => self::schema_properties(),
109 ],
110 ],
111 'required' => [ 'settings' ],
112 ];
113 }
114
115 /**
116 * {@inheritDoc}
117 *
118 * @return array<string, mixed>
119 */
120 public function get_output_schema() {
121 return [
122 'type' => 'object',
123 'properties' => [
124 'success' => [ 'type' => 'boolean' ],
125 'message' => [ 'type' => 'string' ],
126 ],
127 ];
128 }
129
130 /**
131 * Execute ability.
132 *
133 * @param array<string, mixed> $input Ability input payload.
134 * @return array<string, mixed>|\WP_Error
135 */
136 public function execute( $input ) {
137 $settings = isset( $input['settings'] ) && is_array( $input['settings'] ) ? $input['settings'] : [];
138
139 if ( empty( $settings ) ) {
140 return new \WP_Error(
141 'thinkrank_missing_llms_txt_settings_payload',
142 __( 'A llms.txt settings payload is required.', 'thinkrank' ),
143 [ 'status' => 400 ]
144 );
145 }
146
147 $mgr = new LLMs_Txt_Manager();
148 $merged = $mgr->get_settings( 'site', null );
149 $found = false;
150
151 foreach ( self::BOOL_KEYS as $key ) {
152 if ( array_key_exists( $key, $settings ) ) {
153 $merged[ $key ] = (bool) $settings[ $key ];
154 $found = true;
155 }
156 }
157 foreach ( self::STRING_KEYS as $key ) {
158 if ( array_key_exists( $key, $settings ) ) {
159 $merged[ $key ] = sanitize_textarea_field( (string) $settings[ $key ] );
160 $found = true;
161 }
162 }
163
164 if ( ! $found ) {
165 return new \WP_Error(
166 'thinkrank_no_valid_llms_txt_setting_keys',
167 __( 'No valid llms.txt setting keys were provided.', 'thinkrank' ),
168 [ 'status' => 400 ]
169 );
170 }
171
172 $result = $mgr->save_settings( 'site', null, $merged );
173
174 // A disable-save may persist the settings yet fail to remove the published
175 // file, so surface that partial failure instead of reporting plain success.
176 if ( $result && $mgr->unpublish_failed() ) {
177 return [
178 'success' => true,
179 'file_unpublished' => false,
180 'message' => __( 'Settings were saved, but the published llms.txt file could not be removed and may still be served. Please remove it manually.', 'thinkrank' ),
181 ];
182 }
183
184 return [
185 'success' => (bool) $result,
186 'message' => (bool) $result
187 ? __( 'llms.txt settings updated.', 'thinkrank' )
188 : __( 'Failed to update llms.txt settings.', 'thinkrank' ),
189 ];
190 }
191 }
192