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.8.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 All 49 releases
← All changes | includes/abilities/content/class-update-post-seo.php +33 -1 2.2.02.7.0 View file →
@@ -10,8 +10,9 @@
10 10 namespace ThinkRank\Abilities\Content;
11 11
12 12 use ThinkRank\Abilities\Ability_Base;
13 13 use ThinkRank\Admin\Metabox_Manager;
14 +use ThinkRank\SEO\Object_Redirect;
14 15
15 16 if ( ! defined( 'ABSPATH' ) ) {
16 17 exit; // Exit if accessed directly.
17 18 }
@@ -50,8 +51,17 @@
50 51 'properties' => [
51 52 'title' => [ 'type' => 'string' ],
52 53 'description' => [ 'type' => 'string' ],
53 54 'canonical_url' => [ 'type' => 'string' ],
55 + 'redirect_url' => [
56 + 'type' => 'string',
57 + 'description' => __( 'Send visitors from this post to this URL. Empty string removes the redirect. Requires ThinkRank Pro.', 'thinkrank' ),
58 + ],
59 + 'redirect_type' => [
60 + 'type' => 'integer',
61 + 'enum' => Object_Redirect::TYPES,
62 + 'description' => __( 'Redirect status code. Defaults to 301.', 'thinkrank' ),
63 + ],
54 64 'focus_keyword' => [ 'type' => 'string' ],
55 65 'focus_keywords' => [
56 66 'type' => 'array',
57 67 'items' => [ 'type' => 'string' ],
@@ -131,10 +141,24 @@
131 141 [ 'status' => 400 ]
132 142 );
133 143 }
134 144
135 - ( new Metabox_Manager() )->save_seo_fields( $post_id, $fields );
145 + $manager = new Metabox_Manager();
146 + $manager->save_seo_fields( $post_id, $fields );
136 147
148 + // Everything else is stored unconditionally; the redirect can be
149 + // refused (no Pro, plain permalinks, a destination that is this post's
150 + // own URL). Reporting success for a redirect that was not written would
151 + // leave the caller believing the site now redirects when it does not.
152 + $redirect_error = $manager->get_last_redirect_error();
153 + if ( null !== $redirect_error ) {
154 + return new \WP_Error(
155 + $redirect_error->get_error_code(),
156 + $redirect_error->get_error_message(),
157 + [ 'status' => 400 ]
158 + );
159 + }
160 +
137 161 return [
138 162 'success' => true,
139 163 'message' => __( 'Post SEO metadata updated.', 'thinkrank' ),
140 164 'post_id' => $post_id,
@@ -154,8 +178,9 @@
154 178 $simple = [
155 179 'title' => 'thinkrank_seo_title',
156 180 'description' => 'thinkrank_meta_description',
157 181 'canonical_url' => 'thinkrank_canonical_url',
182 + 'redirect_url' => 'thinkrank_redirect_url',
158 183 'focus_keyword' => 'thinkrank_focus_keyword',
159 184 'og_title' => 'thinkrank_og_title',
160 185 'og_description' => 'thinkrank_og_description',
161 186 'og_image' => 'thinkrank_og_image',
@@ -167,8 +192,15 @@
167 192 foreach ( $simple as $key => $field ) {
168 193 if ( array_key_exists( $key, $settings ) ) {
169 194 $fields[ $field ] = (string) $settings[ $key ];
170 195 }
196 + }
197 +
198 + // Only meaningful alongside a destination: sending a code on its own
199 + // would be read by save_object_redirect() as "no redirect submitted"
200 + // and dropped, so requiring the pair keeps the payload honest.
201 + if ( array_key_exists( 'redirect_type', $settings ) && array_key_exists( 'redirect_url', $settings ) ) {
202 + $fields['thinkrank_redirect_type'] = Object_Redirect::normalize_type( $settings['redirect_type'] );
171 203 }
172 204
173 205 if ( array_key_exists( 'focus_keywords', $settings ) && is_array( $settings['focus_keywords'] ) ) {
174 206 $fields['thinkrank_focus_keywords'] = (string) wp_json_encode( array_values( $settings['focus_keywords'] ) );