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