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