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