PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
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 / jetpack_vendor / automattic / jetpack-connection / src / abilities / class-connection-abilities.php
jetpack / jetpack_vendor / automattic / jetpack-connection / src / abilities Last commit date
class-connection-abilities.php 4 days ago
class-connection-abilities.php
222 lines
1 <?php
2 /**
3 * Jetpack Connection Abilities Registration.
4 *
5 * Registers Jetpack Connection abilities with the WordPress Abilities API so
6 * AI agents can inspect the site's connection state through the standard
7 * `wp-abilities/v1` REST surface.
8 *
9 * @package automattic/jetpack-connection
10 */
11
12 namespace Automattic\Jetpack\Connection\Abilities;
13
14 use Automattic\Jetpack\Connection\Manager as Connection_Manager;
15 use Automattic\Jetpack\Connection\Package_Version;
16 use Automattic\Jetpack\WP_Abilities\Registrar;
17 use Jetpack_Options;
18
19 /**
20 * Registers Jetpack Connection abilities with the WordPress Abilities API.
21 *
22 * Exposes a single read-only ability for site-level connection state so AI
23 * agents can answer "is this site registered?" without having to
24 * reverse-engineer Jetpack_Options keys.
25 *
26 * Writes (registering a new site, disconnecting a user, transferring
27 * ownership) are deliberately deferred to a follow-up PR.
28 */
29 class Connection_Abilities extends Registrar {
30
31 const CATEGORY_SLUG = 'jetpack';
32
33 /**
34 * {@inheritDoc}
35 */
36 public static function get_category_slug(): string {
37 return self::CATEGORY_SLUG;
38 }
39
40 /**
41 * {@inheritDoc}
42 *
43 * The `jetpack` ability-category is shared with other Jetpack registrars
44 * (e.g. the Modules_Abilities class in the Jetpack plugin). Only the first
45 * registration wins, so the English source string is kept byte-identical
46 * across registrars to keep the visible category text consistent
47 * regardless of load order.
48 */
49 public static function get_category_definition(): array {
50 return array(
51 // "Jetpack" is a product name and should not be translated.
52 'label' => 'Jetpack',
53 'description' => __( 'Abilities provided by Jetpack.', 'jetpack-connection' ),
54 );
55 }
56
57 /**
58 * {@inheritDoc}
59 */
60 public static function get_abilities(): array {
61 return array(
62 'jetpack/get-connection-status' => self::spec_get_connection_status(),
63 );
64 }
65
66 /*
67 ---------------------------------------------------------------------
68 * Ability specs
69 * ---------------------------------------------------------------------
70 */
71
72 /**
73 * Spec: jetpack/get-connection-status.
74 */
75 private static function spec_get_connection_status(): array {
76 return array(
77 'label' => __( 'Get Jetpack connection status', 'jetpack-connection' ),
78 'description' => __(
79 'Return the site-level Jetpack connection state in one zero-argument call. Shape: { site_registered, user_connected, master_user, blog_id, registration_url, connection_version }. `site_registered` is true when the site has a blog id and a blog token. `user_connected` is true when at least one user has linked their WordPress.com account. `master_user` is the local user id of the connection owner (the user who registered the site), or null if there is no owner. `blog_id` is the WordPress.com site id, or null when the site has not been registered. `registration_url` is the wp-admin URL the site owner should visit to register the site when `site_registered` is false; null once the site is registered. `connection_version` is the running Jetpack Connection package version. Read-only and idempotent — safe to poll.',
80 'jetpack-connection'
81 ),
82 'input_schema' => array(
83 'type' => 'object',
84 'properties' => new \stdClass(),
85 'additionalProperties' => false,
86 ),
87 'output_schema' => array(
88 'type' => 'object',
89 'properties' => array(
90 'site_registered' => array( 'type' => 'boolean' ),
91 'user_connected' => array( 'type' => 'boolean' ),
92 'master_user' => array( 'type' => array( 'integer', 'null' ) ),
93 'blog_id' => array( 'type' => array( 'integer', 'null' ) ),
94 'registration_url' => array( 'type' => array( 'string', 'null' ) ),
95 'connection_version' => array( 'type' => 'string' ),
96 ),
97 ),
98 'execute_callback' => array( __CLASS__, 'get_connection_status' ),
99 'permission_callback' => array( __CLASS__, 'can_view_connection' ),
100 'meta' => array(
101 'annotations' => array(
102 'readonly' => true,
103 'destructive' => false,
104 'idempotent' => true,
105 ),
106 'show_in_rest' => true,
107 'mcp' => array(
108 'public' => true,
109 'type' => 'tool', // default is already "tool", but can be explicit.
110 ),
111 ),
112 );
113 }
114
115 /*
116 ---------------------------------------------------------------------
117 * Permission callbacks
118 * ---------------------------------------------------------------------
119 */
120
121 /**
122 * Permission check: mirrors the capability used by the Jetpack admin page.
123 *
124 * Connection state is not sensitive in itself (the same data is exposed
125 * on the Jetpack admin page and through several existing REST endpoints),
126 * but subscribers and contributors have no legitimate need to inspect it.
127 * Gating on `jetpack_admin_page` aligns with how {@see Modules_Abilities}
128 * scopes its read.
129 *
130 * @return bool
131 */
132 public static function can_view_connection(): bool {
133 return current_user_can( 'jetpack_admin_page' );
134 }
135
136 /*
137 ---------------------------------------------------------------------
138 * Execute callbacks
139 * ---------------------------------------------------------------------
140 */
141
142 /**
143 * Execute: get-connection-status.
144 *
145 * @param array|null $input Ignored — zero-arg ability.
146 * @return array
147 */
148 public static function get_connection_status( $input = null ) {
149 unset( $input );
150
151 $manager = self::get_manager();
152 $site_registered = (bool) $manager->is_connected();
153 $user_connected = (bool) $manager->has_connected_user();
154
155 $master_user_raw = Jetpack_Options::get_option( 'master_user' );
156 $master_user = is_numeric( $master_user_raw ) && (int) $master_user_raw > 0 ? (int) $master_user_raw : null;
157
158 $blog_id_raw = Jetpack_Options::get_option( 'id' );
159 $blog_id = is_numeric( $blog_id_raw ) && (int) $blog_id_raw > 0 ? (int) $blog_id_raw : null;
160
161 return array(
162 'site_registered' => $site_registered,
163 'user_connected' => $user_connected,
164 'master_user' => $master_user,
165 'blog_id' => $blog_id,
166 'registration_url' => $site_registered ? null : self::registration_url(),
167 'connection_version' => Package_Version::PACKAGE_VERSION,
168 );
169 }
170
171 /*
172 ---------------------------------------------------------------------
173 * Helpers
174 * ---------------------------------------------------------------------
175 */
176
177 /**
178 * Return a Connection_Manager instance. Filterable for tests so they can
179 * inject a partial mock without having to seed Jetpack_Options + tokens.
180 *
181 * @return Connection_Manager
182 */
183 protected static function get_manager(): Connection_Manager {
184 /**
185 * Filters the Connection_Manager instance used by the Connection abilities.
186 *
187 * Tests inject a partial mock here; production callers should leave
188 * the default. The filter callback receives the package-default
189 * instance and must return a Connection_Manager — non-Manager
190 * returns are discarded.
191 *
192 * @since 8.4.0
193 *
194 * @param Connection_Manager $manager The default instance.
195 */
196 $instance = apply_filters( 'jetpack_connection_abilities_manager', new Connection_Manager() );
197 return $instance instanceof Connection_Manager ? $instance : new Connection_Manager();
198 }
199
200 /**
201 * Build the wp-admin URL the site owner should visit to register the
202 * site to WordPress.com. We deliberately return a stable admin URL (no
203 * secret generation, no XML-RPC roundtrip) so this read stays side-effect
204 * free and cheap to poll. The destination page handles the actual
205 * registration handshake from there.
206 *
207 * WP 7.0+ ships a core "Connectors" screen at `wp-admin/options-connectors.php`
208 * with a Jetpack card registered by {@see Jetpack_Connector}. We probe
209 * for the file directly (rather than a `class_exists()` on the registry)
210 * because the file is what actually serves the URL — if it isn't on
211 * disk, the redirect 404s regardless of which classes have loaded.
212 *
213 * @return string
214 */
215 private static function registration_url(): string {
216 if ( defined( 'ABSPATH' ) && file_exists( ABSPATH . 'wp-admin/options-connectors.php' ) ) {
217 return admin_url( 'options-connectors.php' );
218 }
219 return admin_url( 'admin.php?page=jetpack' );
220 }
221 }
222