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