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

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

181 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Update author archives 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\Core\Settings;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 /**
20 * Updates ThinkRank author archives settings.
21 *
22 * Controls whether author archives are enabled and indexable, whether empty
23 * archives are shown, and the SEO title/meta description templates.
24 */
25 class Update_Author_Archives_Settings extends Ability_Base {
26 /**
27 * Boolean settings: API alias => storage_key.
28 */
29 private const BOOL_MAP = [
30 'enabled' => 'author_archives_enabled',
31 'show_in_search_results' => 'author_archives_index',
32 'show_empty_archives' => 'author_archives_show_empty',
33 ];
34
35 /**
36 * String settings: API alias => storage_key.
37 */
38 private const STRING_MAP = [
39 'title' => 'author_archives_title',
40 'meta_description' => 'author_archives_meta_desc',
41 ];
42
43 /**
44 * Constructor.
45 */
46 public function __construct() {
47 $this->id = 'thinkrank/update-author-archives-settings';
48 $this->label = __( 'Update ThinkRank Author Archives Settings', 'thinkrank' );
49 $this->description = __( 'Update ThinkRank author archives settings: enable/index toggles, empty-archive visibility, and the SEO title/meta description templates. Read the current values with get-author-archives-settings first; only the keys you pass are changed.', 'thinkrank' );
50 }
51
52 /**
53 * {@inheritDoc}
54 *
55 * @return array<string, bool|float|string>
56 */
57 public function get_annotations() {
58 return [
59 'readonly' => false,
60 // Settings writes are recoverable: the matching get-* ability reads
61 // the previous value, so nothing is lost that cannot be put back.
62 // `destructive` is reserved for calls that lose data or reach
63 // outside the site, and marking routine configuration with it made
64 // MCP clients demand a human approval for every save — which users
65 // reported as a permission bug, because the client's refusal reads
66 // as "No approval received" (#675).
67 'destructive' => false,
68 'idempotent' => true,
69 'priority' => 2.0,
70 'openWorldHint' => false,
71 ];
72 }
73
74 /**
75 * {@inheritDoc}
76 *
77 * @return array<string, mixed>
78 */
79 public function get_input_schema() {
80 return [
81 'type' => 'object',
82 'additionalProperties' => false,
83 'properties' => [
84 'settings' => [
85 'type' => 'object',
86 'description' => __( 'Author archives settings to update.', 'thinkrank' ),
87 'properties' => [
88 'enabled' => [ 'type' => 'boolean' ],
89 'show_in_search_results' => [ 'type' => 'boolean' ],
90 'show_empty_archives' => [ 'type' => 'boolean' ],
91 'title' => [ 'type' => 'string' ],
92 'meta_description' => [ 'type' => 'string' ],
93 ],
94 ],
95 ],
96 'required' => [ 'settings' ],
97 ];
98 }
99
100 /**
101 * {@inheritDoc}
102 *
103 * @return array<string, mixed>
104 */
105 public function get_output_schema() {
106 return [
107 'type' => 'object',
108 'properties' => [
109 'success' => [ 'type' => 'boolean' ],
110 'message' => [ 'type' => 'string' ],
111 ],
112 ];
113 }
114
115 /**
116 * Execute ability.
117 *
118 * @param array<string, mixed> $input Ability input payload.
119 * @return array<string, mixed>|\WP_Error
120 */
121 public function execute( $input ) {
122 $settings = isset( $input['settings'] ) && is_array( $input['settings'] ) ? $input['settings'] : [];
123
124 if ( empty( $settings ) ) {
125 return new \WP_Error(
126 'thinkrank_missing_author_archives_settings_payload',
127 __( 'An author archives settings payload is required.', 'thinkrank' ),
128 [ 'status' => 400 ]
129 );
130 }
131
132 $store = Settings::instance();
133 $found = false;
134 $failed = [];
135
136 foreach ( self::BOOL_MAP as $alias => $storage_key ) {
137 if ( array_key_exists( $alias, $settings ) ) {
138 $found = true;
139 if ( ! $store->set( $storage_key, (bool) $settings[ $alias ] ) ) {
140 $failed[] = $alias;
141 }
142 }
143 }
144 foreach ( self::STRING_MAP as $alias => $storage_key ) {
145 if ( array_key_exists( $alias, $settings ) ) {
146 $found = true;
147 if ( ! $store->set( $storage_key, sanitize_text_field( (string) $settings[ $alias ] ) ) ) {
148 $failed[] = $alias;
149 }
150 }
151 }
152
153 if ( ! $found ) {
154 return new \WP_Error(
155 'thinkrank_no_valid_author_archives_setting_keys',
156 __( 'No valid author archives setting keys were provided.', 'thinkrank' ),
157 [ 'status' => 400 ]
158 );
159 }
160
161 // A discarded set() return meant a failed write still answered
162 // "settings updated"; surface it instead.
163 if ( ! empty( $failed ) ) {
164 return new \WP_Error(
165 'thinkrank_author_archives_settings_not_saved',
166 sprintf(
167 /* translators: %s is a comma-separated list of setting names that could not be saved. */
168 __( 'Some author archives settings could not be saved: %s', 'thinkrank' ),
169 implode( ', ', $failed )
170 ),
171 [ 'status' => 500 ]
172 );
173 }
174
175 return [
176 'success' => true,
177 'message' => __( 'Author archives settings updated.', 'thinkrank' ),
178 ];
179 }
180 }
181