PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-beta.3
Jetpack – WP Security, Backup, Speed, & Growth v16.1-beta.3
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / _inc / lib / core-api / wpcom-endpoints / class-wpcom-rest-api-v2-endpoint-agent-guidelines-ai.php
jetpack / _inc / lib / core-api / wpcom-endpoints Last commit date
business-hours.php 9 months ago class-wpcom-rest-api-v2-endpoint-admin-bar.php 3 months ago class-wpcom-rest-api-v2-endpoint-admin-color.php 9 months ago class-wpcom-rest-api-v2-endpoint-admin-menu.php 1 month ago class-wpcom-rest-api-v2-endpoint-agent-guidelines-ai.php 2 weeks ago class-wpcom-rest-api-v2-endpoint-ai.php 1 month ago class-wpcom-rest-api-v2-endpoint-app-media.php 9 months ago class-wpcom-rest-api-v2-endpoint-application-password-extras.php 5 months ago class-wpcom-rest-api-v2-endpoint-block-editor-assets.php 1 month ago class-wpcom-rest-api-v2-endpoint-blog-stats.php 9 months ago class-wpcom-rest-api-v2-endpoint-email-preview.php 3 months ago class-wpcom-rest-api-v2-endpoint-external-media.php 9 months ago class-wpcom-rest-api-v2-endpoint-following.php 9 months ago class-wpcom-rest-api-v2-endpoint-goodreads.php 9 months ago class-wpcom-rest-api-v2-endpoint-google-docs.php 9 months ago class-wpcom-rest-api-v2-endpoint-guidelines-banner-dismissed.php 1 month ago class-wpcom-rest-api-v2-endpoint-instagram-gallery.php 3 months ago class-wpcom-rest-api-v2-endpoint-mailchimp.php 9 months ago class-wpcom-rest-api-v2-endpoint-mcp-settings.php 1 month ago class-wpcom-rest-api-v2-endpoint-newsletter-categories-list.php 9 months ago class-wpcom-rest-api-v2-endpoint-newsletter-categories-subscriptions-count.php 9 months ago class-wpcom-rest-api-v2-endpoint-newsletter-categories-subscriptions.php 2 weeks ago class-wpcom-rest-api-v2-endpoint-newsletter-email-sent-status.php 4 months ago class-wpcom-rest-api-v2-endpoint-podcast-player.php 3 months ago class-wpcom-rest-api-v2-endpoint-profile.php 9 months ago class-wpcom-rest-api-v2-endpoint-related-posts.php 9 months ago class-wpcom-rest-api-v2-endpoint-resolve-redirect.php 9 months ago class-wpcom-rest-api-v2-endpoint-search.php 1 month ago class-wpcom-rest-api-v2-endpoint-send-email-preview.php 2 weeks ago class-wpcom-rest-api-v2-endpoint-subscribers-list.php 1 month ago class-wpcom-rest-api-v2-endpoint-template-loader.php 9 months ago class-wpcom-rest-api-v2-endpoint-top-posts.php 3 months ago class-wpcom-rest-api-v2-endpoint-transient.php 9 months ago class-wpcom-rest-api-v3-endpoint-blogging-prompts.php 9 months ago class-wpcom-rest-api-v3-endpoint-jitm.php 9 months ago gutenberg-available-extensions.php 9 months ago hello.php 9 months ago memberships.php 1 month ago publicize-connection-test-results.php 9 months ago service-api-keys.php 2 months ago sites-posts-featured-media-url.php 9 months ago subscribers.php 9 months ago
class-wpcom-rest-api-v2-endpoint-agent-guidelines-ai.php
191 lines
1 <?php
2 /**
3 * REST API proxy endpoint for AI-powered content guidelines suggestions.
4 *
5 * Proxies requests to the wpcom endpoint that generates guidelines
6 * using site content analysis.
7 *
8 * @package automattic/jetpack
9 */
10
11 use Automattic\Jetpack\Connection\Client;
12 use Automattic\Jetpack\Connection\Manager;
13 use Automattic\Jetpack\Status\Host;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit( 0 );
17 }
18
19 /**
20 * Class WPCOM_REST_API_V2_Endpoint_Agent_Guidelines_AI
21 */
22 class WPCOM_REST_API_V2_Endpoint_Agent_Guidelines_AI extends WP_REST_Controller {
23 /**
24 * Namespace prefix.
25 *
26 * @var string
27 */
28 public $namespace = 'wpcom/v2';
29
30 /**
31 * Endpoint base route.
32 *
33 * @var string
34 */
35 public $rest_base = 'jetpack-ai/suggest-guidelines';
36
37 /**
38 * Constructor.
39 */
40 public function __construct() {
41 $this->is_wpcom = true;
42 $this->wpcom_is_wpcom_only_endpoint = true;
43
44 add_action( 'rest_api_init', array( $this, 'maybe_register_routes' ) );
45 }
46
47 /**
48 * Register routes on `rest_api_init`, gating on the AI feature state.
49 *
50 * The Jetpack_AI_Helper check (which loads the helper and instantiates
51 * Status/Host classes) runs here rather than in the constructor so that code
52 * is only loaded when the REST API is actually in use, not on every
53 * front-end, cron, or login request.
54 */
55 public function maybe_register_routes() {
56 if ( ! class_exists( 'Jetpack_AI_Helper' ) ) {
57 require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-ai-helper.php';
58 }
59
60 // Intentionally gated to Simple and Atomic sites only.
61 // Self-hosted Jetpack support is deferred — we want to roll out
62 // on WordPress.com platforms first before opening to all connected sites.
63 if ( ! \Jetpack_AI_Helper::is_enabled() ) {
64 return;
65 }
66
67 $this->register_routes();
68 }
69
70 /**
71 * Register routes.
72 */
73 public function register_routes() {
74 register_rest_route(
75 $this->namespace,
76 '/' . $this->rest_base,
77 array(
78 'methods' => WP_REST_Server::CREATABLE,
79 'callback' => array( $this, 'suggest_guidelines' ),
80 'permission_callback' => array( $this, 'permission_callback' ),
81 'args' => array(
82 'categories' => array(
83 'description' => __( 'Categories to generate guidelines for.', 'jetpack' ),
84 'type' => 'object',
85 'required' => true,
86 ),
87 ),
88 )
89 );
90 }
91
92 /**
93 * Permission check — require manage_options, plus a connected user account
94 * on sites that proxy the request to WordPress.com over the connection.
95 *
96 * @return bool|WP_Error
97 */
98 public function permission_callback() {
99 if ( ! current_user_can( 'manage_options' ) ) {
100 return false;
101 }
102
103 // suggest_guidelines() signs with the user token off Simple, so without a
104 // user connection there is no identity to present and WordPress.com rejects
105 // the request on private sites.
106 if ( ! ( new Host() )->is_wpcom_simple() && ! ( new Manager() )->is_user_connected() ) {
107 return new WP_Error(
108 'rest_cannot_suggest_guidelines',
109 __( 'Please connect your user account to WordPress.com', 'jetpack' ),
110 array( 'status' => rest_authorization_required_code() )
111 );
112 }
113
114 return true;
115 }
116
117 /**
118 * Proxy the suggest-guidelines request to wpcom.
119 *
120 * @param WP_REST_Request $request The request object.
121 * @return mixed|WP_Error
122 */
123 public function suggest_guidelines( $request ) {
124 $blog_id = \Jetpack_Options::get_option( 'id' );
125
126 $body = array(
127 'categories' => $request->get_param( 'categories' ),
128 );
129
130 $path = sprintf( '/sites/%d/jetpack-ai/suggest-guidelines', $blog_id ) . '?force=wpcom';
131 $args = array(
132 'method' => 'POST',
133 'headers' => array( 'content-type' => 'application/json' ),
134 'timeout' => 90,
135 );
136
137 // On a private site WordPress.com resolves access from the requesting user,
138 // and a blog token carries no user_id — so the request is rejected before
139 // the endpoint runs, and again on the internal AI proxy dispatch. Signing
140 // as the user clears both, because the identity holds for the whole request.
141 // permission_callback() has already established that a user token exists.
142 //
143 // Simple sites keep the blog-token call: it short-circuits to an in-process
144 // WPCOM_API_Direct dispatch that never leaves the request, so the logged-in
145 // user is already present and there is no connection to authenticate against.
146 if ( ( new Host() )->is_wpcom_simple() ) {
147 $response = Client::wpcom_json_api_request_as_blog(
148 $path,
149 '2',
150 $args,
151 wp_json_encode( $body, JSON_UNESCAPED_SLASHES ),
152 'wpcom'
153 );
154 } else {
155 $response = Client::wpcom_json_api_request_as_user(
156 $path,
157 '2',
158 $args,
159 wp_json_encode( $body, JSON_UNESCAPED_SLASHES ),
160 'wpcom'
161 );
162 }
163
164 if ( is_wp_error( $response ) ) {
165 return $response;
166 }
167
168 $status_code = wp_remote_retrieve_response_code( $response );
169 $body_str = wp_remote_retrieve_body( $response );
170 $data = json_decode( $body_str, true );
171
172 if ( $status_code !== 200 ) {
173 $message = is_array( $data ) && isset( $data['message'] ) ? $data['message'] : __( 'Failed to generate guidelines.', 'jetpack' );
174 $code = is_array( $data ) && isset( $data['code'] ) ? $data['code'] : 'upstream_error';
175 return new WP_Error( $code, $message, array( 'status' => $status_code ) );
176 }
177
178 if ( JSON_ERROR_NONE !== json_last_error() ) {
179 return new WP_Error(
180 'invalid_response',
181 __( 'The guidelines service returned a malformed response.', 'jetpack' ),
182 array( 'status' => 502 )
183 );
184 }
185
186 return $data;
187 }
188 }
189
190 wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Agent_Guidelines_AI' );
191