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