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-image-seo-settings.php

class-update-image-seo-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-image-seo-settings.php

171 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 image SEO 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\Image_SEO_Manager;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 /**
20 * Updates ThinkRank image SEO settings.
21 *
22 * Controls automatic alt/title injection and the token-based formats used when
23 * generating those attributes, persisted through the Image_SEO_Manager.
24 */
25 class Update_Image_Seo_Settings extends Ability_Base {
26 /**
27 * Boolean-typed image SEO keys.
28 */
29 private const BOOL_KEYS = [
30 'add_missing_alt',
31 'add_missing_title',
32 'save_alt_to_media',
33 'auto_fill_on_upload',
34 'media_alt_overwrite',
35 ];
36
37 /**
38 * String-typed image SEO keys.
39 */
40 private const STRING_KEYS = [
41 'alt_format',
42 'title_format',
43 ];
44
45 /**
46 * Constructor.
47 */
48 public function __construct() {
49 $this->id = 'thinkrank/update-image-seo-settings';
50 $this->label = __( 'Update ThinkRank Image SEO Settings', 'thinkrank' );
51 $this->description = __( 'Update ThinkRank image SEO settings, which control automatic alt/title injection, the token-based formats used to generate them, and whether generated alt text is persisted to the Media Library. Read the current values with get-image-seo-settings first; only the keys you pass are changed.', 'thinkrank' );
52 }
53
54 /**
55 * {@inheritDoc}
56 *
57 * @return array<string, bool|float|string>
58 */
59 public function get_annotations() {
60 return [
61 'readonly' => false,
62 // Settings writes are recoverable: the matching get-* ability reads
63 // the previous value, so nothing is lost that cannot be put back.
64 // `destructive` is reserved for calls that lose data or reach
65 // outside the site, and marking routine configuration with it made
66 // MCP clients demand a human approval for every save — which users
67 // reported as a permission bug, because the client's refusal reads
68 // as "No approval received" (#675).
69 'destructive' => false,
70 'idempotent' => true,
71 'priority' => 2.0,
72 'openWorldHint' => false,
73 ];
74 }
75
76 /**
77 * {@inheritDoc}
78 *
79 * @return array<string, mixed>
80 */
81 public function get_input_schema() {
82 return [
83 'type' => 'object',
84 'additionalProperties' => false,
85 'properties' => [
86 'settings' => [
87 'type' => 'object',
88 'description' => __( 'Image SEO settings to update.', 'thinkrank' ),
89 'properties' => [
90 'add_missing_alt' => [ 'type' => 'boolean' ],
91 'alt_format' => [ 'type' => 'string' ],
92 'add_missing_title' => [ 'type' => 'boolean' ],
93 'title_format' => [ 'type' => 'string' ],
94 'save_alt_to_media' => [ 'type' => 'boolean' ],
95 'auto_fill_on_upload' => [ 'type' => 'boolean' ],
96 'media_alt_overwrite' => [ 'type' => 'boolean' ],
97 ],
98 ],
99 ],
100 'required' => [ 'settings' ],
101 ];
102 }
103
104 /**
105 * {@inheritDoc}
106 *
107 * @return array<string, mixed>
108 */
109 public function get_output_schema() {
110 return [
111 'type' => 'object',
112 'properties' => [
113 'success' => [ 'type' => 'boolean' ],
114 'message' => [ 'type' => 'string' ],
115 ],
116 ];
117 }
118
119 /**
120 * Execute ability.
121 *
122 * @param array<string, mixed> $input Ability input payload.
123 * @return array<string, mixed>|\WP_Error
124 */
125 public function execute( $input ) {
126 $settings = isset( $input['settings'] ) && is_array( $input['settings'] ) ? $input['settings'] : [];
127
128 if ( empty( $settings ) ) {
129 return new \WP_Error(
130 'thinkrank_missing_image_seo_settings_payload',
131 __( 'An image SEO settings payload is required.', 'thinkrank' ),
132 [ 'status' => 400 ]
133 );
134 }
135
136 $mgr = new Image_SEO_Manager();
137 $merged = $mgr->get_settings( 'site', null );
138 $found = false;
139
140 foreach ( self::BOOL_KEYS as $key ) {
141 if ( array_key_exists( $key, $settings ) ) {
142 $merged[ $key ] = (bool) $settings[ $key ];
143 $found = true;
144 }
145 }
146 foreach ( self::STRING_KEYS as $key ) {
147 if ( array_key_exists( $key, $settings ) ) {
148 $merged[ $key ] = sanitize_text_field( (string) $settings[ $key ] );
149 $found = true;
150 }
151 }
152
153 if ( ! $found ) {
154 return new \WP_Error(
155 'thinkrank_no_valid_image_seo_setting_keys',
156 __( 'No valid image SEO setting keys were provided.', 'thinkrank' ),
157 [ 'status' => 400 ]
158 );
159 }
160
161 $result = $mgr->save_settings( 'site', null, $merged );
162
163 return [
164 'success' => (bool) $result,
165 'message' => (bool) $result
166 ? __( 'Image SEO settings updated.', 'thinkrank' )
167 : __( 'Failed to update image SEO settings.', 'thinkrank' ),
168 ];
169 }
170 }
171