PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.0.2
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.0.2
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-schema-settings.php

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

259 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Update schema 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\Schema_Management_System;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 /**
20 * Updates ThinkRank structured-data (schema) settings.
21 *
22 * Schema settings are persisted through the Schema_Management_System SEO
23 * manager. When auto_deploy is enabled, saving these settings automatically
24 * regenerates and redeploys the site-wide schema markup.
25 */
26 class Update_Schema_Settings extends Ability_Base {
27 /**
28 * Boolean-typed schema keys.
29 */
30 private const BOOL_KEYS = [
31 'enabled',
32 'auto_generate_schema',
33 'rich_snippets_optimization',
34 'auto_deploy',
35 'organization_schema',
36 'knowledge_graph',
37 'website_enable_search',
38 'enable_breadcrumbs_schema',
39 'enable_local_business',
40 ];
41
42 /**
43 * Integer-typed schema keys.
44 */
45 private const INT_KEYS = [
46 'cache_duration',
47 ];
48
49 /**
50 * Array-typed schema keys.
51 */
52 private const ARRAY_KEYS = [
53 'enabled_schema_types',
54 'business_opening_hours',
55 'person_same_as',
56 ];
57
58 /**
59 * String-typed schema keys.
60 */
61 private const STRING_KEYS = [
62 'validation_level',
63 'organization_name',
64 'organization_type',
65 'organization_logo',
66 'organization_url',
67 'organization_description',
68 'organization_social_facebook',
69 'organization_social_twitter',
70 'organization_social_linkedin',
71 'organization_social_instagram',
72 'organization_social_youtube',
73 'organization_social_pinterest',
74 'organization_social_whatsapp',
75 'organization_social_telegram',
76 'organization_contact_type',
77 'organization_contact_phone',
78 'organization_contact_email',
79 'organization_contact_hours',
80 'website_name',
81 'website_url',
82 'website_description',
83 'website_author',
84 'website_search_url',
85 'business_price_range',
86 'business_geo_latitude',
87 'business_geo_longitude',
88 'person_name',
89 'person_job_title',
90 'person_description',
91 'person_image',
92 'person_url',
93 'person_email',
94 'person_telephone',
95 'person_address',
96 'person_birth_date',
97 'person_nationality',
98 'person_works_for',
99 ];
100
101 /**
102 * Constructor.
103 */
104 public function __construct() {
105 $this->id = 'thinkrank/update-schema-settings';
106 $this->label = __( 'Update ThinkRank Schema Settings', 'thinkrank' );
107 $this->description = __( 'Update ThinkRank structured-data (schema) settings. When auto_deploy is enabled, saving automatically regenerates and redeploys the site-wide schema markup.', 'thinkrank' );
108 }
109
110 /**
111 * {@inheritDoc}
112 *
113 * @return array<string, bool|float|string>
114 */
115 public function get_annotations() {
116 return [
117 'readonly' => false,
118 'destructive' => true,
119 'idempotent' => true,
120 'priority' => 2.0,
121 'openWorldHint' => false,
122 ];
123 }
124
125 /**
126 * Build the JSON schema properties for schema settings.
127 *
128 * @return array<string, mixed>
129 */
130 private static function schema_properties() {
131 $props = [];
132
133 foreach ( self::BOOL_KEYS as $key ) {
134 $props[ $key ] = [ 'type' => 'boolean' ];
135 }
136 foreach ( self::INT_KEYS as $key ) {
137 $props[ $key ] = [ 'type' => 'integer' ];
138 }
139 foreach ( self::ARRAY_KEYS as $key ) {
140 $props[ $key ] = [ 'type' => 'array' ];
141 }
142 foreach ( self::STRING_KEYS as $key ) {
143 $props[ $key ] = [ 'type' => 'string' ];
144 }
145
146 return $props;
147 }
148
149 /**
150 * {@inheritDoc}
151 *
152 * @return array<string, mixed>
153 */
154 public function get_input_schema() {
155 return [
156 'type' => 'object',
157 'additionalProperties' => false,
158 'properties' => [
159 'settings' => [
160 'type' => 'object',
161 'description' => __( 'Schema settings to update.', 'thinkrank' ),
162 'properties' => self::schema_properties(),
163 ],
164 ],
165 'required' => [ 'settings' ],
166 ];
167 }
168
169 /**
170 * {@inheritDoc}
171 *
172 * @return array<string, mixed>
173 */
174 public function get_output_schema() {
175 return [
176 'type' => 'object',
177 'properties' => [
178 'success' => [ 'type' => 'boolean' ],
179 'message' => [ 'type' => 'string' ],
180 ],
181 ];
182 }
183
184 /**
185 * Execute ability.
186 *
187 * @param array<string, mixed> $input Ability input payload.
188 * @return array<string, mixed>|\WP_Error
189 */
190 public function execute( $input ) {
191 $settings = isset( $input['settings'] ) && is_array( $input['settings'] ) ? $input['settings'] : [];
192
193 if ( empty( $settings ) ) {
194 return new \WP_Error(
195 'thinkrank_missing_schema_settings_payload',
196 __( 'A schema settings payload is required.', 'thinkrank' ),
197 [ 'status' => 400 ]
198 );
199 }
200
201 $mgr = new Schema_Management_System();
202 $merged = $mgr->get_settings( 'site', null );
203 $found = false;
204
205 foreach ( self::BOOL_KEYS as $key ) {
206 if ( array_key_exists( $key, $settings ) ) {
207 $merged[ $key ] = (bool) $settings[ $key ];
208 $found = true;
209 }
210 }
211 foreach ( self::INT_KEYS as $key ) {
212 if ( array_key_exists( $key, $settings ) ) {
213 $merged[ $key ] = (int) $settings[ $key ];
214 $found = true;
215 }
216 }
217 foreach ( self::ARRAY_KEYS as $key ) {
218 if ( array_key_exists( $key, $settings ) && is_array( $settings[ $key ] ) ) {
219 $merged[ $key ] = array_values( $settings[ $key ] );
220 $found = true;
221 }
222 }
223 foreach ( self::STRING_KEYS as $key ) {
224 if ( array_key_exists( $key, $settings ) ) {
225 $value = sanitize_text_field( (string) $settings[ $key ] );
226
227 // validation_level is an enum. An out-of-range value would make
228 // the downstream all-or-nothing validator reject the entire
229 // save, silently dropping the other valid fields — so skip an
230 // invalid value here and let the rest of the payload save.
231 if ( 'validation_level' === $key
232 && ! in_array( $value, [ 'strict', 'moderate', 'lenient' ], true ) ) {
233 continue;
234 }
235
236 $merged[ $key ] = $value;
237 $found = true;
238 }
239 }
240
241 if ( ! $found ) {
242 return new \WP_Error(
243 'thinkrank_no_valid_schema_setting_keys',
244 __( 'No valid schema setting keys were provided.', 'thinkrank' ),
245 [ 'status' => 400 ]
246 );
247 }
248
249 $result = $mgr->save_settings( 'site', null, $merged );
250
251 return [
252 'success' => (bool) $result,
253 'message' => (bool) $result
254 ? __( 'Schema settings updated.', 'thinkrank' )
255 : __( 'Failed to update schema settings.', 'thinkrank' ),
256 ];
257 }
258 }
259