PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 15.3.2
Jetpack – WP Security, Backup, Speed, & Growth v15.3.2
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.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 / json-endpoints / class.wpcom-json-api-get-site-endpoint.php
jetpack / json-endpoints Last commit date
jetpack 9 months ago class.wpcom-json-api-add-widget-endpoint.php 9 months ago class.wpcom-json-api-autosave-post-v1-1-endpoint.php 9 months ago class.wpcom-json-api-bulk-delete-post-endpoint.php 9 months ago class.wpcom-json-api-bulk-restore-post-endpoint.php 9 months ago class.wpcom-json-api-bulk-update-comments-endpoint.php 9 months ago class.wpcom-json-api-comment-endpoint.php 9 months ago class.wpcom-json-api-delete-media-endpoint.php 9 months ago class.wpcom-json-api-delete-media-v1-1-endpoint.php 9 months ago class.wpcom-json-api-edit-media-v1-2-endpoint.php 9 months ago class.wpcom-json-api-get-autosave-v1-1-endpoint.php 9 months ago class.wpcom-json-api-get-comment-counts-endpoint.php 9 months ago class.wpcom-json-api-get-comment-endpoint.php 9 months ago class.wpcom-json-api-get-comment-history-endpoint.php 9 months ago class.wpcom-json-api-get-comments-tree-endpoint.php 9 months ago class.wpcom-json-api-get-comments-tree-v1-1-endpoint.php 9 months ago class.wpcom-json-api-get-comments-tree-v1-2-endpoint.php 9 months ago class.wpcom-json-api-get-customcss.php 9 months ago class.wpcom-json-api-get-media-endpoint.php 9 months ago class.wpcom-json-api-get-media-v1-1-endpoint.php 9 months ago class.wpcom-json-api-get-media-v1-2-endpoint.php 9 months ago class.wpcom-json-api-get-post-counts-v1-1-endpoint.php 9 months ago class.wpcom-json-api-get-post-endpoint.php 9 months ago class.wpcom-json-api-get-post-v1-1-endpoint.php 9 months ago class.wpcom-json-api-get-site-endpoint.php 9 months ago class.wpcom-json-api-get-site-v1-2-endpoint.php 9 months ago class.wpcom-json-api-get-taxonomies-endpoint.php 9 months ago class.wpcom-json-api-get-taxonomy-endpoint.php 9 months ago class.wpcom-json-api-get-term-endpoint.php 9 months ago class.wpcom-json-api-list-comments-endpoint.php 9 months ago class.wpcom-json-api-list-dropdown-pages-endpoint.php 9 months ago class.wpcom-json-api-list-embeds-endpoint.php 9 months ago class.wpcom-json-api-list-media-endpoint.php 9 months ago class.wpcom-json-api-list-media-v1-1-endpoint.php 9 months ago class.wpcom-json-api-list-media-v1-2-endpoint.php 9 months ago class.wpcom-json-api-list-post-type-taxonomies-endpoint.php 9 months ago class.wpcom-json-api-list-post-types-endpoint.php 9 months ago class.wpcom-json-api-list-posts-endpoint.php 9 months ago class.wpcom-json-api-list-posts-v1-1-endpoint.php 9 months ago class.wpcom-json-api-list-posts-v1-2-endpoint.php 9 months ago class.wpcom-json-api-list-roles-endpoint.php 9 months ago class.wpcom-json-api-list-shortcodes-endpoint.php 9 months ago class.wpcom-json-api-list-terms-endpoint.php 9 months ago class.wpcom-json-api-list-users-endpoint.php 9 months ago class.wpcom-json-api-menus-v1-1-endpoint.php 9 months ago class.wpcom-json-api-post-endpoint.php 9 months ago class.wpcom-json-api-post-v1-1-endpoint.php 9 months ago class.wpcom-json-api-render-embed-endpoint.php 9 months ago class.wpcom-json-api-render-embed-reversal-endpoint.php 9 months ago class.wpcom-json-api-render-endpoint.php 9 months ago class.wpcom-json-api-render-shortcode-endpoint.php 9 months ago class.wpcom-json-api-sharing-buttons-endpoint.php 9 months ago class.wpcom-json-api-site-settings-endpoint.php 9 months ago class.wpcom-json-api-site-settings-v1-2-endpoint.php 9 months ago class.wpcom-json-api-site-settings-v1-3-endpoint.php 9 months ago class.wpcom-json-api-site-settings-v1-4-endpoint.php 9 months ago class.wpcom-json-api-site-user-endpoint.php 9 months ago class.wpcom-json-api-taxonomy-endpoint.php 9 months ago class.wpcom-json-api-update-comment-endpoint.php 9 months ago class.wpcom-json-api-update-customcss.php 9 months ago class.wpcom-json-api-update-media-endpoint.php 9 months ago class.wpcom-json-api-update-media-v1-1-endpoint.php 9 months ago class.wpcom-json-api-update-post-endpoint.php 9 months ago class.wpcom-json-api-update-post-v1-1-endpoint.php 9 months ago class.wpcom-json-api-update-post-v1-2-endpoint.php 9 months ago class.wpcom-json-api-update-site-homepage-endpoint.php 9 months ago class.wpcom-json-api-update-site-logo-endpoint.php 9 months ago class.wpcom-json-api-update-taxonomy-endpoint.php 9 months ago class.wpcom-json-api-update-term-endpoint.php 9 months ago class.wpcom-json-api-update-user-endpoint.php 9 months ago class.wpcom-json-api-upload-media-endpoint.php 9 months ago class.wpcom-json-api-upload-media-v1-1-endpoint.php 9 months ago
class.wpcom-json-api-get-site-endpoint.php
1206 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit( 0 );
5 }
6
7 new WPCOM_JSON_API_GET_Site_Endpoint(
8 array(
9 'description' => 'Get information about a site.',
10 'group' => 'sites',
11 'stat' => 'sites:X',
12 'allowed_if_flagged' => true,
13 'method' => 'GET',
14 'max_version' => '1.1',
15 'new_version' => '1.2',
16 'path' => '/sites/%s',
17 'path_labels' => array(
18 '$site' => '(int|string) Site ID or domain',
19 ),
20 'rest_route' => '/site',
21 'rest_min_jp_version' => '14.5-a.2',
22 'allow_jetpack_site_auth' => true,
23
24 'allow_fallback_to_jetpack_blog_token' => true,
25
26 'query_parameters' => array(
27 'context' => false,
28 'options' => '(string) Optional. Returns specified options only. Comma-separated list. Example: options=login_url,timezone',
29 ),
30
31 'response_format' => WPCOM_JSON_API_GET_Site_Endpoint::$site_format,
32
33 'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/en.blog.wordpress.com/',
34 )
35 );
36
37 /**
38 * GET Site endpoint class.
39 *
40 * @phan-constructor-used-for-side-effects
41 */
42 class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
43
44 /**
45 * Site meta data.
46 *
47 * @var array $site_format
48 */
49 public static $site_format = array(
50 'ID' => '(int) Site ID',
51 'slug' => '(string) Slug of site',
52 'name' => '(string) Title of site',
53 'description' => '(string) Tagline or description of site',
54 'URL' => '(string) Full URL to the site',
55 'user_can_manage' => '(bool) The current user can manage this site', // deprecated.
56 'capabilities' => '(array) Array of capabilities for the current user on this site.',
57 'jetpack' => '(bool) Whether the site is a Jetpack site or not',
58 'jetpack_connection' => '(bool) Whether the site is connected to WP.com via `jetpack-connection`',
59 'is_multisite' => '(bool) Whether the site is a Multisite site or not. Always true for WP.com sites.',
60 'site_owner' => '(int) User ID of the site owner',
61 'post_count' => '(int) The number of posts the site has',
62 'subscribers_count' => '(int) The number of subscribers the site has',
63 'lang' => '(string) Primary language code of the site',
64 'icon' => '(array) An array of icon formats for the site',
65 'logo' => '(array) The site logo, set in the Customizer',
66 'visible' => '(bool) If this site is visible in the user\'s site list',
67 'is_private' => '(bool) If the site is a private site or not',
68 'is_coming_soon' => '(bool) If the site is marked as "coming soon" or not',
69 'single_user_site' => '(bool) Whether the site is single user. Only returned for WP.com sites and for Jetpack sites with version 3.4 or higher.',
70 'is_vip' => '(bool) If the site is a VIP site or not.',
71 'is_following' => '(bool) If the current user is subscribed to this site in the reader',
72 'organization_id' => '(int) P2 Organization identifier.',
73 'options' => '(array) An array of options/settings for the blog. Only viewable by users with post editing rights to the site. Note: Post formats is deprecated, please see /sites/$id/post-formats/',
74 'p2_thumbnail_elements' => '(array) Details used to render a thumbnail of the site. P2020 themed sites only.',
75 'plan' => '(array) Details of the current plan for this site.',
76 'products' => '(array) Details of the current products for this site.',
77 'zendesk_site_meta' => '(array) Site meta data for Zendesk.',
78 'updates' => '(array) An array of available updates for plugins, themes, wordpress, and languages.',
79 'jetpack_modules' => '(array) A list of active Jetpack modules.',
80 'meta' => '(object) Meta data',
81 'quota' => '(array) An array describing how much space a user has left for uploads',
82 'launch_status' => '(string) A string describing the launch status of a site',
83 'site_migration' => '(array) Data about any migration into the site.',
84 'is_fse_active' => '(bool) If the site has Full Site Editing active or not.',
85 'is_fse_eligible' => '(bool) If the site is capable of Full Site Editing or not',
86 'is_core_site_editor_enabled' => '(bool) If the site has the core site editor enabled.',
87 'is_wpcom_atomic' => '(bool) If the site is a WP.com Atomic one.',
88 'is_wpcom_staging_site' => '(bool) If the site is a WP.com staging site.',
89 'user_interactions' => '(array) An array of user interactions with a site.',
90 'was_ecommerce_trial' => '(bool) If the site ever used an eCommerce trial.',
91 'was_upgraded_from_trial' => '(bool) If the site ever upgraded to a paid plan from a trial.',
92 'was_migration_trial' => '(bool) If the site ever used a migration trial.',
93 'was_hosting_trial' => '(bool) If the site ever used a hosting trial.',
94 'wpcom_site_setup' => '(string) The WP.com site setup identifier.',
95 'is_deleted' => '(bool) If the site flagged as deleted.',
96 'is_a4a_client' => '(bool) If the site is an A4A client site.',
97 'is_a4a_dev_site' => '(bool) If the site is an A4A dev site.',
98 'is_garden' => '(bool) If the site is a Garden site.',
99 'garden_name' => '(string) The name of the Garden site.',
100 'garden_partner' => '(string) The partner of the Garden site.',
101 'garden_is_provisioned' => '(bool) If the Garden site is provisioned.',
102 'is_wpcom_flex' => '(bool) If the site is a Flex site',
103 );
104
105 /**
106 * No member fields.
107 *
108 * @var array $no_member_fields
109 */
110 protected static $no_member_fields = array(
111 'ID',
112 'name',
113 'description',
114 'URL',
115 'jetpack',
116 'jetpack_connection',
117 'post_count',
118 'subscribers_count',
119 'lang',
120 'locale',
121 'icon',
122 'logo',
123 'visible',
124 'is_private',
125 'is_coming_soon',
126 'is_following',
127 'organization_id',
128 'meta',
129 'launch_status',
130 'site_migration',
131 'is_fse_active',
132 'is_fse_eligible',
133 'is_core_site_editor_enabled',
134 'is_wpcom_atomic',
135 'is_wpcom_staging_site',
136 'is_deleted',
137 'is_wpcom_flex',
138 'is_a4a_client',
139 'is_a4a_dev_site',
140 );
141
142 /**
143 * Site options.
144 *
145 * @var array $site_options_format
146 */
147 protected static $site_options_format = array(
148 'timezone',
149 'gmt_offset',
150 'blog_public',
151 'videopress_enabled',
152 'upgraded_filetypes_enabled',
153 'login_url',
154 'admin_url',
155 'is_mapped_domain',
156 'is_redirect',
157 'unmapped_url',
158 'featured_images_enabled',
159 'theme_slug',
160 'theme_errors',
161 'header_image',
162 'background_color',
163 'image_default_link_type',
164 'image_thumbnail_width',
165 'image_thumbnail_height',
166 'image_thumbnail_crop',
167 'image_medium_width',
168 'image_medium_height',
169 'image_large_width',
170 'image_large_height',
171 'permalink_structure',
172 'post_formats',
173 'default_post_format',
174 'default_category',
175 'allowed_file_types',
176 'show_on_front',
177 /** This filter is documented in modules/likes.php */
178 'default_likes_enabled',
179 'default_sharing_status',
180 'default_comment_status',
181 'default_ping_status',
182 'software_version',
183 'created_at',
184 'updated_at',
185 'wordads',
186 'publicize_permanently_disabled',
187 'frame_nonce',
188 'jetpack_frame_nonce',
189 'page_on_front',
190 'page_for_posts',
191 'headstart',
192 'headstart_is_fresh',
193 'ak_vp_bundle_enabled',
194 Jetpack_SEO_Utils::FRONT_PAGE_META_OPTION,
195 Jetpack_SEO_Titles::TITLE_FORMATS_OPTION,
196 'verification_services_codes',
197 'podcasting_archive',
198 'is_domain_only',
199 'is_automated_transfer',
200 'is_wpcom_atomic',
201 'is_wpcom_store',
202 'signup_is_store',
203 'has_pending_automated_transfer',
204 'woocommerce_is_active',
205 'editing_toolkit_is_active',
206 'design_type',
207 'site_goals',
208 'site_segment',
209 'site_source_slug',
210 'import_engine',
211 'is_pending_plan',
212 'is_wpforteams_site',
213 'p2_hub_blog_id',
214 'site_creation_flow',
215 'is_cloud_eligible',
216 'selected_features',
217 'anchor_podcast',
218 'was_created_with_blank_canvas_design',
219 'videopress_storage_used',
220 'is_difm_lite_in_progress',
221 'is_summer_special_2025',
222 'site_intent',
223 'site_partner_bundle',
224 'onboarding_segment',
225 'site_vertical_id',
226 'blogging_prompts_settings',
227 'launchpad_screen',
228 'launchpad_checklist_tasks_statuses',
229 'migration_source_site_domain',
230 'wpcom_production_blog_id',
231 'wpcom_staging_blog_ids',
232 'can_blaze',
233 'wpcom_site_setup',
234 'is_commercial',
235 'is_commercial_reasons',
236 'wpcom_admin_interface',
237 'wpcom_classic_early_release',
238 );
239
240 /**
241 * Jetpack response fields.
242 *
243 * @var array $jetpack_response_field_additions
244 */
245 protected static $jetpack_response_field_additions = array(
246 'slug',
247 'subscribers_count',
248 'site_migration',
249 'site_owner',
250 'is_wpcom_staging_site',
251 'was_ecommerce_trial',
252 'was_migration_trial',
253 'was_hosting_trial',
254 'was_upgraded_from_trial',
255 'is_a4a_dev_site',
256 'is_garden',
257 'garden_name',
258 'garden_partner',
259 'garden_is_provisioned',
260 'is_wpcom_flex',
261 );
262
263 /**
264 * Jetpack response field member additions.
265 *
266 * @var array $jetpack_response_field_member_additions
267 */
268 protected static $jetpack_response_field_member_additions = array(
269 'capabilities',
270 'plan',
271 'products',
272 'zendesk_site_meta',
273 );
274
275 /**
276 * Jetpack response option additions.
277 *
278 * @var array $jetpack_response_option_additions
279 */
280 protected static $jetpack_response_option_additions = array(
281 'publicize_permanently_disabled',
282 'ak_vp_bundle_enabled',
283 'is_automated_transfer',
284 'is_wpcom_atomic',
285 'is_wpcom_store',
286 'woocommerce_is_active',
287 'editing_toolkit_is_active',
288 'frame_nonce',
289 'jetpack_frame_nonce',
290 'design_type',
291 'wordads',
292 // Use the site registered date from wpcom, since it is only available in a multisite context
293 // and defaults to `0000-00-00T00:00:00+00:00` from the Jetpack site.
294 // See https://github.com/Automattic/jetpack/blob/58638f46094b36f5df9cbc4570006544f0ad300c/sal/class.json-api-site-base.php#L387.
295 'created_at',
296 'updated_at',
297 'is_pending_plan',
298 'is_cloud_eligible',
299 'videopress_storage_used',
300 'blogging_prompts_settings',
301 'wpcom_production_blog_id',
302 'wpcom_staging_blog_ids',
303 'is_commercial',
304 'is_commercial_reasons',
305 'wpcom_admin_interface',
306 'wpcom_classic_early_release',
307 );
308
309 /**
310 * Current enabled trials.
311 *
312 * @var array $jetpack_enabled_trials
313 */
314 public static $jetpack_enabled_trials = array(
315 'was_ecommerce_trial' => 'ecommerce',
316 'was_migration_trial' => 'migration',
317 'was_hosting_trial' => 'hosting',
318 );
319
320 /**
321 * Site.
322 *
323 * @var SAL_Site $site.
324 */
325 private $site;
326
327 /**
328 * Fields to include.
329 *
330 * @var $fields_to_include
331 */
332 protected $fields_to_include = '_all';
333
334 /**
335 * Options to include.
336 *
337 * @var $options_to_include
338 */
339 protected $options_to_include = '_all';
340
341 /**
342 *
343 * API callback.
344 *
345 * /sites/mine
346 * /sites/%s -> $blog_id\
347 *
348 * @param string $path - the path.
349 * @param int|string $blog_id - the blog ID or the string 'mine'.
350 *
351 * @return array|\WP_Error Site response array on success, or WP_Error on failure.
352 */
353 public function callback( $path = '', $blog_id = 0 ) {
354 if ( 'mine' === $blog_id ) {
355 $api = WPCOM_JSON_API::init();
356 if ( ! $api->token_details || empty( $api->token_details['blog_id'] ) ) {
357 return new WP_Error( 'authorization_required', 'An active access token must be used to query information about the current blog.', 403 );
358 }
359 $blog_id = $api->token_details['blog_id'];
360 }
361
362 add_filter( 'wpcom_allow_jetpack_blog_token', '__return_true' );
363 $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
364 if ( is_wp_error( $blog_id ) ) {
365 return $blog_id;
366 }
367
368 $this->filter_fields_and_options();
369
370 $response = $this->build_current_site_response();
371
372 /** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
373 do_action( 'wpcom_json_api_objects', 'sites' );
374
375 return $response;
376 }
377
378 /**
379 * Filter fields and options.
380 */
381 public function filter_fields_and_options() {
382 $query_args = $this->query_args();
383
384 $this->fields_to_include = empty( $query_args['fields'] ) ? '_all' : array_map( 'trim', explode( ',', $query_args['fields'] ) );
385 $this->options_to_include = empty( $query_args['options'] ) ? '_all' : array_map( 'trim', explode( ',', $query_args['options'] ) );
386 }
387
388 /**
389 * Collects the necessary information to return for a site's response.
390 *
391 * @return array
392 */
393 public function build_current_site_response() {
394
395 $blog_id = (int) $this->api->get_blog_id_for_output();
396
397 $this->site = $this->get_platform()->get_site( $blog_id );
398
399 /**
400 * Filter the structure of information about the site to return.
401 *
402 * @module json-api
403 *
404 * @since 3.9.3
405 *
406 * @param array $site_format Data structure.
407 */
408 $default_fields = array_keys( apply_filters( 'sites_site_format', self::$site_format ) );
409
410 $response_keys = is_array( $this->fields_to_include ) ?
411 array_intersect( $default_fields, $this->fields_to_include ) :
412 $default_fields;
413
414 $has_blog_access = $this->has_blog_access( $this->api->token_details );
415 $has_user_access = $this->has_user_access();
416
417 if ( ! $has_user_access && ! $has_blog_access ) {
418 // Public access without user or blog auth, only return `$no_member_fields`.
419 $response_keys = array_intersect( $response_keys, self::$no_member_fields );
420 } elseif ( $has_user_access && ! current_user_can( 'edit_posts' ) ) {
421 // Subscriber level user, don't return site options.
422 $response_keys = array_diff( $response_keys, array( 'options' ) );
423 }
424
425 return $this->render_response_keys( $response_keys );
426 }
427
428 /**
429 * Checks that the current user has access to the current blog.
430 *
431 * @return bool Whether or not the current user can access the current blog.
432 */
433 private function has_user_access() {
434 return is_user_member_of_blog( get_current_user_id(), get_current_blog_id() );
435 }
436
437 /**
438 * Checks if the request has a valid blog token for the current blog.
439 *
440 * @param array $token_details Access token for the api request.
441 * @return bool
442 */
443 private function has_blog_access( $token_details ) {
444 $token_details = (array) $token_details;
445 if ( ! isset( $token_details['access'] ) || ! isset( $token_details['auth'] ) || ! isset( $token_details['blog_id'] ) ) {
446 return false;
447 }
448
449 return 'jetpack' === $token_details['auth'] &&
450 'blog' === $token_details['access'] &&
451 get_current_blog_id() === $token_details['blog_id'];
452 }
453
454 /**
455 * Render response keys.
456 *
457 * @param array $response_keys - the response keys.
458 */
459 private function render_response_keys( &$response_keys ) {
460 $response = array();
461
462 $is_user_logged_in = is_user_logged_in();
463
464 $this->site->before_render();
465
466 foreach ( $response_keys as $key ) {
467 $this->render_response_key( $key, $response, $is_user_logged_in );
468 }
469
470 $this->site->after_render( $response );
471
472 return $response;
473 }
474
475 /**
476 * Render response key.
477 *
478 * @param string $key - the key.
479 * @param array $response - the response.
480 * @param boolean $is_user_logged_in - if the user is logged in.
481 */
482 protected function render_response_key( $key, &$response, $is_user_logged_in ) {
483 do_action( 'pre_render_site_response_key', $key );
484
485 switch ( $key ) {
486 case 'ID':
487 $response[ $key ] = $this->site->blog_id;
488 break;
489 case 'slug':
490 $response[ $key ] = $this->site->get_slug();
491 break;
492 case 'name':
493 $response[ $key ] = $this->site->get_name();
494 break;
495 case 'description':
496 $response[ $key ] = $this->site->get_description();
497 break;
498 case 'URL':
499 $response[ $key ] = $this->site->get_url();
500 break;
501 case 'user_can_manage':
502 $response[ $key ] = $this->site->user_can_manage();
503 // fall through is intentional.
504 case 'is_private':
505 $response[ $key ] = $this->site->is_private();
506 break;
507 case 'is_coming_soon':
508 // This option is stored on wp.com for both simple and atomic sites. @see mu-plugins/private-blog.php.
509 $response[ $key ] = $this->site->is_coming_soon();
510
511 break;
512 case 'launch_status':
513 $response[ $key ] = $this->site->get_launch_status();
514 break;
515 case 'visible':
516 $response[ $key ] = $this->site->is_visible();
517 break;
518 case 'subscribers_count':
519 $response[ $key ] = $this->site->get_subscribers_count();
520 break;
521 case 'post_count':
522 if ( $is_user_logged_in ) {
523 $response[ $key ] = $this->site->get_post_count();
524 }
525 break;
526 case 'icon':
527 $icon = $this->site->get_icon();
528
529 if ( $icon !== null ) {
530 $response[ $key ] = $icon;
531 }
532 break;
533 case 'logo':
534 $response[ $key ] = $this->site->get_logo();
535 break;
536 case 'is_following':
537 $response[ $key ] = $this->site->is_following();
538 break;
539 case 'options':
540 // small optimisation - don't recalculate.
541 $all_options = apply_filters( 'sites_site_options_format', self::$site_options_format );
542
543 $options_response_keys = is_array( $this->options_to_include ) ?
544 array_intersect( $all_options, $this->options_to_include ) :
545 $all_options;
546
547 $options = $this->render_option_keys( $options_response_keys );
548
549 $this->site->after_render_options( $options );
550
551 $response[ $key ] = (object) $options;
552 break;
553 case 'meta':
554 $this->build_meta_response( $response );
555 break;
556 case 'lang':
557 $response[ $key ] = $is_user_logged_in ? $this->site->get_locale() : false;
558 break;
559 case 'locale':
560 $response[ $key ] = $is_user_logged_in ? $this->site->get_locale() : false;
561 break;
562 case 'jetpack':
563 $response[ $key ] = $this->site->is_jetpack();
564 break;
565 case 'jetpack_connection':
566 $response[ $key ] = $this->site->is_jetpack_connection();
567 break;
568 case 'single_user_site':
569 $response[ $key ] = $this->site->is_single_user_site();
570 break;
571 case 'is_vip':
572 $response[ $key ] = $this->site->is_vip();
573 break;
574 case 'is_multisite':
575 $response[ $key ] = $this->site->is_multisite();
576 break;
577 case 'site_owner':
578 $response[ $key ] = $this->site->get_site_owner();
579 break;
580 case 'organization_id':
581 $response[ $key ] = $this->site->get_p2_organization_id();
582 break;
583
584 case 'capabilities':
585 $response[ $key ] = $this->site->get_capabilities();
586 break;
587 case 'jetpack_modules':
588 if ( is_user_member_of_blog() ) {
589 $response[ $key ] = $this->site->get_jetpack_modules();
590 }
591 break;
592 case 'plan':
593 $response[ $key ] = $this->site->get_plan();
594 break;
595 case 'products':
596 $response[ $key ] = $this->site->get_products();
597 break;
598 case 'zendesk_site_meta':
599 $response[ $key ] = $this->site->get_zendesk_site_meta();
600 break;
601 case 'quota':
602 $response[ $key ] = $this->site->get_quota();
603 break;
604 case 'site_migration':
605 $response[ $key ] = $this->site->get_migration_meta();
606 break;
607 case 'is_fse_active':
608 $response[ $key ] = $this->site->is_fse_active();
609 break;
610 case 'is_fse_eligible':
611 $response[ $key ] = $this->site->is_fse_eligible();
612 break;
613 case 'is_core_site_editor_enabled':
614 $response[ $key ] = $this->site->is_core_site_editor_enabled();
615 break;
616 case 'is_wpcom_atomic':
617 $response[ $key ] = $this->site->is_wpcom_atomic();
618 break;
619 case 'is_wpcom_staging_site':
620 $response[ $key ] = $this->site->is_wpcom_staging_site();
621 break;
622 case 'user_interactions':
623 $response[ $key ] = $this->site->get_user_interactions();
624 break;
625 case 'p2_thumbnail_elements':
626 $response[ $key ] = $this->site->get_p2_thumbnail_elements();
627 break;
628 case 'was_ecommerce_trial':
629 $response[ $key ] = $this->site->was_trial( self::$jetpack_enabled_trials['was_ecommerce_trial'] );
630 break;
631 case 'was_migration_trial':
632 $response[ $key ] = $this->site->was_trial( self::$jetpack_enabled_trials['was_migration_trial'] );
633 break;
634 case 'was_hosting_trial':
635 $response[ $key ] = $this->site->was_trial( self::$jetpack_enabled_trials['was_hosting_trial'] );
636 break;
637 case 'was_upgraded_from_trial':
638 $response[ $key ] = $this->site->was_upgraded_from_trial();
639 break;
640 case 'is_deleted':
641 $response[ $key ] = $this->site->is_deleted();
642 break;
643 case 'is_a4a_client':
644 $response[ $key ] = $this->site->is_a4a_client();
645 break;
646 case 'is_a4a_dev_site':
647 $response[ $key ] = $this->site->is_a4a_dev_site();
648 break;
649 case 'is_garden':
650 $response[ $key ] = $this->site->is_garden();
651 break;
652 case 'garden_name':
653 $response[ $key ] = $this->site->garden_name();
654 break;
655 case 'garden_partner':
656 $response[ $key ] = $this->site->garden_partner();
657 break;
658 case 'garden_is_provisioned':
659 $response[ $key ] = $this->site->garden_is_provisioned();
660 break;
661 case 'is_wpcom_flex':
662 $response[ $key ] = $this->site->is_wpcom_flex();
663 break;
664 }
665
666 do_action( 'post_render_site_response_key', $key );
667 }
668
669 /**
670 * Render option keys.
671 *
672 * @param array $options_response_keys - the response keys.
673 */
674 protected function render_option_keys( &$options_response_keys ) {
675 $options = array();
676 $site = $this->site;
677
678 $custom_front_page = $site->is_custom_front_page();
679
680 foreach ( $options_response_keys as $key ) {
681 switch ( $key ) {
682 case 'timezone':
683 $options[ $key ] = $site->get_timezone();
684 break;
685 case 'gmt_offset':
686 $options[ $key ] = $site->get_gmt_offset();
687 break;
688 case 'videopress_enabled':
689 $options[ $key ] = $site->has_videopress();
690 break;
691 case 'upgraded_filetypes_enabled':
692 $options[ $key ] = $site->upgraded_filetypes_enabled();
693 break;
694 case 'login_url':
695 $options[ $key ] = $site->get_login_url();
696 break;
697 case 'admin_url':
698 $options[ $key ] = $site->get_admin_url();
699 break;
700 case 'is_mapped_domain':
701 $options[ $key ] = $site->is_mapped_domain();
702 break;
703 case 'is_redirect':
704 $options[ $key ] = $site->is_redirect();
705 break;
706 case 'unmapped_url':
707 $options[ $key ] = $site->get_unmapped_url();
708 break;
709 case 'featured_images_enabled':
710 $options[ $key ] = $site->featured_images_enabled();
711 break;
712 case 'theme_slug':
713 $options[ $key ] = $site->get_theme_slug();
714 break;
715 case 'theme_errors':
716 $options[ $key ] = $site->get_theme_errors();
717 break;
718 case 'header_image':
719 $options[ $key ] = $site->get_header_image();
720 break;
721 case 'background_color':
722 $options[ $key ] = $site->get_background_color();
723 break;
724 case 'image_default_link_type':
725 $options[ $key ] = $site->get_image_default_link_type();
726 break;
727 case 'image_thumbnail_width':
728 $options[ $key ] = $site->get_image_thumbnail_width();
729 break;
730 case 'image_thumbnail_height':
731 $options[ $key ] = $site->get_image_thumbnail_height();
732 break;
733 case 'image_thumbnail_crop':
734 $options[ $key ] = $site->get_image_thumbnail_crop();
735 break;
736 case 'image_medium_width':
737 $options[ $key ] = $site->get_image_medium_width();
738 break;
739 case 'image_medium_height':
740 $options[ $key ] = $site->get_image_medium_height();
741 break;
742 case 'image_large_width':
743 $options[ $key ] = $site->get_image_large_width();
744 break;
745 case 'image_large_height':
746 $options[ $key ] = $site->get_image_large_height();
747 break;
748 case 'permalink_structure':
749 $options[ $key ] = $site->get_permalink_structure();
750 break;
751 case 'post_formats':
752 $options[ $key ] = $site->get_post_formats();
753 break;
754 case 'default_post_format':
755 $options[ $key ] = $site->get_default_post_format();
756 break;
757 case 'default_category':
758 $options[ $key ] = $site->get_default_category();
759 break;
760 case 'allowed_file_types':
761 $options[ $key ] = $site->allowed_file_types();
762 break;
763 case 'show_on_front':
764 $options[ $key ] = $site->get_show_on_front();
765 break;
766 /** This filter is documented in modules/likes.php */
767 case 'default_likes_enabled':
768 $options[ $key ] = $site->get_default_likes_enabled();
769 break;
770 case 'default_sharing_status':
771 $options[ $key ] = $site->get_default_sharing_status();
772 break;
773 case 'default_comment_status':
774 $options[ $key ] = $site->get_default_comment_status();
775 break;
776 case 'default_ping_status':
777 $options[ $key ] = $site->default_ping_status();
778 break;
779 case 'software_version':
780 $options[ $key ] = $site->get_wordpress_version();
781 break;
782 case 'created_at':
783 $options[ $key ] = $site->get_registered_date();
784 break;
785 case 'updated_at':
786 $options[ $key ] = $site->get_last_update_date();
787 break;
788 case 'wordads':
789 $options[ $key ] = $site->has_wordads();
790 break;
791 case 'publicize_permanently_disabled':
792 $options[ $key ] = $site->is_publicize_permanently_disabled();
793 break;
794 case 'frame_nonce':
795 $options[ $key ] = $site->get_frame_nonce();
796 break;
797 case 'jetpack_frame_nonce':
798 $options[ $key ] = $site->get_jetpack_frame_nonce();
799 break;
800 case 'page_on_front':
801 if ( $custom_front_page ) {
802 $options[ $key ] = $site->get_page_on_front();
803 }
804 break;
805 case 'page_for_posts':
806 if ( $custom_front_page ) {
807 $options[ $key ] = $site->get_page_for_posts();
808 }
809 break;
810 case 'headstart':
811 $options[ $key ] = $site->is_headstart();
812 break;
813 case 'headstart_is_fresh':
814 $options[ $key ] = $site->is_headstart_fresh();
815 break;
816 case 'ak_vp_bundle_enabled':
817 $options[ $key ] = $site->get_ak_vp_bundle_enabled();
818 break;
819 case Jetpack_SEO_Utils::FRONT_PAGE_META_OPTION:
820 $options[ $key ] = $site->get_jetpack_seo_front_page_description();
821 break;
822 case Jetpack_SEO_Titles::TITLE_FORMATS_OPTION:
823 $options[ $key ] = $site->get_jetpack_seo_title_formats();
824 break;
825 case 'verification_services_codes':
826 $options[ $key ] = $site->get_verification_services_codes();
827 break;
828 case 'podcasting_archive':
829 $options[ $key ] = $site->get_podcasting_archive();
830 break;
831 case 'is_domain_only':
832 $options[ $key ] = $site->is_domain_only();
833 break;
834 case 'is_automated_transfer':
835 $options[ $key ] = $site->is_automated_transfer();
836 break;
837 case 'blog_public':
838 $options[ $key ] = $site->get_blog_public();
839 break;
840 case 'is_wpcom_atomic':
841 $options[ $key ] = $site->is_wpcom_atomic();
842 break;
843 case 'is_wpcom_store':
844 $options[ $key ] = $site->is_wpcom_store();
845 break;
846 case 'signup_is_store':
847 $signup_is_store = $site->signup_is_store();
848
849 if ( $signup_is_store ) {
850 $options[ $key ] = $site->signup_is_store();
851 }
852
853 break;
854 case 'has_pending_automated_transfer':
855 $has_pending_automated_transfer = $site->has_pending_automated_transfer();
856
857 if ( $has_pending_automated_transfer ) {
858 $options[ $key ] = true;
859 }
860
861 break;
862 case 'woocommerce_is_active':
863 $options[ $key ] = $site->woocommerce_is_active();
864 break;
865 case 'editing_toolkit_is_active':
866 $options[ $key ] = $site->editing_toolkit_is_active();
867 break;
868 case 'design_type':
869 $options[ $key ] = $site->get_design_type();
870 break;
871 case 'site_segment':
872 $options[ $key ] = $site->get_site_segment();
873 break;
874 case 'import_engine':
875 $options[ $key ] = $site->get_import_engine();
876 break;
877 case 'is_pending_plan':
878 $options[ $key ] = $site->is_pending_plan();
879 break;
880
881 case 'is_wpforteams_site':
882 $options[ $key ] = $site->is_wpforteams_site();
883 break;
884 case 'p2_hub_blog_id':
885 $options[ $key ] = $site->get_p2_hub_blog_id();
886 break;
887
888 case 'site_creation_flow':
889 $site_creation_flow = $site->get_site_creation_flow();
890 if ( $site_creation_flow ) {
891 $options[ $key ] = $site_creation_flow;
892 }
893 break;
894 case 'site_source_slug':
895 $site_source_slug = $site->get_site_source_slug();
896 if ( $site_source_slug ) {
897 $options[ $key ] = $site_source_slug;
898 }
899 break;
900 case 'is_cloud_eligible':
901 $options[ $key ] = $site->is_cloud_eligible();
902 break;
903 case 'selected_features':
904 $selected_features = $site->get_selected_features();
905 if ( $selected_features ) {
906 $options[ $key ] = $selected_features;
907 }
908 break;
909 case 'anchor_podcast':
910 $options[ $key ] = $site->get_anchor_podcast();
911 break;
912 case 'was_created_with_blank_canvas_design':
913 $options[ $key ] = $site->was_created_with_blank_canvas_design();
914 break;
915 case 'videopress_storage_used':
916 $options[ $key ] = $this->site->get_videopress_storage_used();
917 break;
918 case 'is_difm_lite_in_progress':
919 $options[ $key ] = $site->is_difm_lite_in_progress();
920 break;
921 case 'is_summer_special_2025':
922 $options[ $key ] = $site->is_summer_special_2025();
923 break;
924 case 'site_intent':
925 $options[ $key ] = $site->get_site_intent();
926 break;
927 case 'site_partner_bundle':
928 $options[ $key ] = $site->get_site_partner_bundle();
929 break;
930 case 'site_goals':
931 $options[ $key ] = $site->get_site_goals();
932 break;
933 case 'onboarding_segment':
934 $options[ $key ] = $site->get_onboarding_segment();
935 break;
936 case 'site_vertical_id':
937 $options[ $key ] = $site->get_site_vertical_id();
938 break;
939 case 'blogging_prompts_settings':
940 if ( current_user_can( 'edit_posts' ) ) {
941 $options[ $key ] = $site->get_blogging_prompts_settings( get_current_user_id(), $site->blog_id );
942 }
943 break;
944 case 'launchpad_screen':
945 $options[ $key ] = $site->get_launchpad_screen();
946 break;
947 case 'launchpad_checklist_tasks_statuses':
948 $options[ $key ] = $site->get_launchpad_checklist_tasks_statuses();
949 break;
950 case 'migration_source_site_domain':
951 $options[ $key ] = $site->get_migration_source_site_domain();
952 break;
953 case 'wpcom_production_blog_id':
954 $options[ $key ] = $site->get_wpcom_production_blog_id();
955 break;
956 case 'wpcom_staging_blog_ids':
957 $options[ $key ] = $site->get_wpcom_staging_blog_ids();
958 break;
959 case 'can_blaze':
960 $options[ $key ] = $site->can_blaze();
961 break;
962 case 'wpcom_site_setup':
963 $options[ $key ] = $site->get_wpcom_site_setup();
964 break;
965 case 'is_commercial':
966 $options[ $key ] = $site->is_commercial();
967 break;
968 case 'is_commercial_reasons':
969 $options[ $key ] = $site->get_is_commercial_reasons();
970 break;
971 case 'wpcom_admin_interface':
972 $options[ $key ] = $site->get_wpcom_admin_interface();
973 break;
974 case 'wpcom_classic_early_release':
975 $options[ $key ] = $site->get_wpcom_classic_early_release();
976 break;
977 }
978 }
979
980 return $options;
981 }
982
983 /**
984 * Build meta response.
985 *
986 * @param array $response - the response.
987 */
988 protected function build_meta_response( &$response ) {
989 $links = array(
990 'self' => (string) $this->links->get_site_link( $this->site->blog_id ),
991 'help' => (string) $this->links->get_site_link( $this->site->blog_id, 'help' ),
992 'posts' => (string) $this->links->get_site_link( $this->site->blog_id, 'posts/' ),
993 'comments' => (string) $this->links->get_site_link( $this->site->blog_id, 'comments/' ),
994 'xmlrpc' => (string) $this->site->get_xmlrpc_url(),
995 );
996
997 $icon = $this->site->get_icon();
998 if ( ! empty( $icon ) && ! empty( $icon['media_id'] ) ) {
999 $links['site_icon'] = (string) $this->links->get_site_link( $this->site->blog_id, 'media/' . $icon['media_id'] );
1000 }
1001
1002 $response['meta'] = (object) array(
1003 'links' => (object) $links,
1004 );
1005 }
1006
1007 /**
1008 * Apply any WPCOM-only response components to a Jetpack site response.
1009 *
1010 * @param array $response - the response.
1011 */
1012 public function decorate_jetpack_response( &$response ) {
1013 $this->site = $this->get_platform()->get_site( $response->ID );
1014 switch_to_blog( $this->site->get_id() );
1015
1016 $wpcom_response = $this->render_response_keys( self::$jetpack_response_field_additions );
1017
1018 foreach ( $wpcom_response as $key => $value ) {
1019 $response->{ $key } = $value;
1020 }
1021
1022 if ( $this->has_user_access() || $this->has_blog_access( $this->api->token_details ) ) {
1023 $wpcom_member_response = $this->render_response_keys( self::$jetpack_response_field_member_additions );
1024
1025 foreach ( $wpcom_member_response as $key => $value ) {
1026 $response->{ $key } = $value;
1027 }
1028 } else {
1029 // ensure private data is not rendered for non members of the site.
1030 unset( $response->options );
1031 unset( $response->is_vip );
1032 unset( $response->single_user_site );
1033 unset( $response->is_private );
1034 unset( $response->is_coming_soon );
1035 unset( $response->capabilities );
1036 unset( $response->lang );
1037 unset( $response->user_can_manage );
1038 unset( $response->is_multisite );
1039 unset( $response->site_owner );
1040 unset( $response->plan );
1041 unset( $response->products );
1042 unset( $response->zendesk_site_meta );
1043 }
1044
1045 // render additional options.
1046 if ( isset( $response->options ) && $response->options ) {
1047 $wpcom_options_response = $this->render_option_keys( self::$jetpack_response_option_additions );
1048
1049 // Remove heic from jetpack (and atomic) sites so that the iOS app know to convert the file format into a JPEG.
1050 // heic fromat is currently not supported by for uploading.
1051 // See https://jetpackp2.wordpress.com/2020/08/19/image-uploads-in-the-wp-ios-app-broken
1052 if ( $this->site->is_jetpack() && isset( $response->options['allowed_file_types'] ) ) {
1053 $remove_file_types = array(
1054 'heic',
1055 );
1056 $response->options['allowed_file_types'] = array_values( array_diff( $response->options['allowed_file_types'], $remove_file_types ) );
1057 }
1058
1059 foreach ( $wpcom_options_response as $key => $value ) {
1060 $response->options[ $key ] = $value;
1061 }
1062 }
1063
1064 restore_current_blog();
1065 return $response; // possibly no need since it's modified in place.
1066 }
1067 }
1068
1069 new WPCOM_JSON_API_List_Post_Formats_Endpoint(
1070 array(
1071 'description' => 'Get a list of post formats supported by a site.',
1072 'group' => '__do_not_document',
1073 'stat' => 'sites:X:post-formats',
1074
1075 'method' => 'GET',
1076 'path' => '/sites/%s/post-formats',
1077 'path_labels' => array(
1078 '$site' => '(int|string) Site ID or domain',
1079 ),
1080
1081 'query_parameters' => array(
1082 'context' => false,
1083 ),
1084
1085 'allow_fallback_to_jetpack_blog_token' => true,
1086
1087 'response_format' => array(
1088 'formats' => '(object) An object of supported post formats, each key a supported format slug mapped to its display string.',
1089 ),
1090 )
1091 );
1092
1093 /**
1094 * List Post Formats endpoint class.
1095 *
1096 * @phan-constructor-used-for-side-effects
1097 */
1098 class WPCOM_JSON_API_List_Post_Formats_Endpoint extends WPCOM_JSON_API_Endpoint { // phpcs:ignore
1099 /**
1100 *
1101 * API callback.
1102 *
1103 * /sites/%s/post-formats -> $blog_id
1104 *
1105 * @param string $path - the path.
1106 * @param int $blog_id - the blog ID.
1107 *
1108 * @return array|\WP_Error Array with 'formats' on success, or WP_Error on failure.
1109 */
1110 public function callback( $path = '', $blog_id = 0 ) {
1111 $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
1112 if ( is_wp_error( $blog_id ) ) {
1113 return $blog_id;
1114 }
1115
1116 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
1117 $this->load_theme_functions();
1118 }
1119
1120 // Get a list of supported post formats.
1121 $all_formats = get_post_format_strings();
1122 $supported = get_theme_support( 'post-formats' );
1123
1124 $response = array(
1125 'formats' => array(),
1126 );
1127 $supported_formats = $response['formats'];
1128
1129 if ( isset( $supported[0] ) ) {
1130 foreach ( $supported[0] as $format ) {
1131 $supported_formats[ $format ] = $all_formats[ $format ];
1132 }
1133 }
1134
1135 $response['formats'] = (object) $supported_formats;
1136
1137 return $response;
1138 }
1139 }
1140
1141 new WPCOM_JSON_API_List_Page_Templates_Endpoint(
1142 array(
1143 'description' => 'Get a list of page templates supported by a site.',
1144 'group' => 'sites',
1145 'stat' => 'sites:X:post-templates',
1146
1147 'method' => 'GET',
1148 'path' => '/sites/%s/page-templates',
1149 'path_labels' => array(
1150 '$site' => '(int|string) Site ID or domain',
1151 ),
1152 'query_parameters' => array(
1153 'context' => false,
1154 ),
1155 'response_format' => array(
1156 'templates' => '(array) A list of supported page templates. Contains label and file.',
1157 ),
1158 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/33534099/page-templates',
1159 )
1160 );
1161
1162 /**
1163 * List page templates endpoint class.
1164 *
1165 * @phan-constructor-used-for-side-effects
1166 */
1167 class WPCOM_JSON_API_List_Page_Templates_Endpoint extends WPCOM_JSON_API_Endpoint { // phpcs:ignore
1168 /**
1169 *
1170 * API callback.
1171 * /sites/%s/page-templates -> $blog_id
1172 *
1173 * @param string $path - the path.
1174 * @param int $blog_id - the blog ID.
1175 *
1176 * @return array|\WP_Error Array with 'templates' on success, or WP_Error on failure.
1177 */
1178 public function callback( $path = '', $blog_id = 0 ) {
1179 $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
1180 if ( is_wp_error( $blog_id ) ) {
1181 return $blog_id;
1182 }
1183
1184 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
1185 $this->load_theme_functions();
1186 }
1187
1188 $response = array();
1189 $page_templates = array();
1190
1191 $templates = get_page_templates();
1192 ksort( $templates );
1193
1194 foreach ( array_keys( $templates ) as $label ) {
1195 $page_templates[] = array(
1196 'label' => $label,
1197 'file' => $templates[ $label ],
1198 );
1199 }
1200
1201 $response['templates'] = $page_templates;
1202
1203 return $response;
1204 }
1205 }
1206