Completed
Push — fix/videopress-missing-from-se... ( 60564b )
by
unknown
22:41 queued 12:31
created

WPCOM_JSON_API_GET_Site_Endpoint::callback()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 5
nop 2
dl 0
loc 26
rs 8.439
c 0
b 0
f 0
1
<?php
2
class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
3
4
	public static $site_format = array(
5
		'ID'                => '(int) Site ID',
6
		'name'              => '(string) Title of site',
7
		'description'       => '(string) Tagline or description of site',
8
		'URL'               => '(string) Full URL to the site',
9
		'user_can_manage'   => '(bool) The current user can manage this site', // deprecated
10
		'capabilities'      => '(array) Array of capabilities for the current user on this site.',
11
		'jetpack'           => '(bool)  Whether the site is a Jetpack site or not',
12
		'is_multisite'      => '(bool) Whether the site is a Multisite site or not. Always true for WP.com sites.',
13
		'post_count'        => '(int) The number of posts the site has',
14
		'subscribers_count' => '(int) The number of subscribers the site has',
15
		'lang'              => '(string) Primary language code of the site',
16
		'icon'              => '(array) An array of icon formats for the site',
17
		'logo'              => '(array) The site logo, set in the Customizer',
18
		'visible'           => '(bool) If this site is visible in the user\'s site list',
19
		'is_private'        => '(bool) If the site is a private site or not',
20
		'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.',
21
		'is_vip'            => '(bool) If the site is a VIP site or not.',
22
		'is_following'      => '(bool) If the current user is subscribed to this site in the reader',
23
		'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/',
24
		'plan'              => '(array) Details of the current plan for this site.',
25
		'updates'           => '(array) An array of available updates for plugins, themes, wordpress, and languages.',
26
		'jetpack_modules'   => '(array) A list of active Jetpack modules.',
27
		'meta'              => '(object) Meta data',
28
	);
29
30
	protected static $no_member_fields = array(
31
		'ID',
32
		'name',
33
		'description',
34
		'URL',
35
		'jetpack',
36
		'post_count',
37
		'subscribers_count',
38
		'lang',
39
		'locale',
40
		'icon',
41
		'logo',
42
		'visible',
43
		'is_private',
44
		'is_following',
45
		'meta',
46
	);
47
48
	protected static $site_options_format = array(
49
		'timezone',
50
		'gmt_offset',
51
		'videopress_enabled',
52
		'upgraded_filetypes_enabled',
53
		'login_url',
54
		'admin_url',
55
		'is_mapped_domain',
56
		'is_redirect',
57
		'unmapped_url',
58
		'featured_images_enabled',
59
		'theme_slug',
60
		'header_image',
61
		'background_color',
62
		'image_default_link_type',
63
		'image_thumbnail_width',
64
		'image_thumbnail_height',
65
		'image_thumbnail_crop',
66
		'image_medium_width',
67
		'image_medium_height',
68
		'image_large_width',
69
		'image_large_height',
70
		'permalink_structure',
71
		'post_formats',
72
		'default_post_format',
73
		'default_category',
74
		'allowed_file_types',
75
		'show_on_front',
76
		/** This filter is documented in modules/likes.php */
77
		'default_likes_enabled',
78
		'default_sharing_status',
79
		'default_comment_status',
80
		'default_ping_status',
81
		'software_version',
82
		'created_at',
83
		'wordads',
84
		'publicize_permanently_disabled',
85
		'frame_nonce',
86
		'page_on_front',
87
		'page_for_posts',
88
		'headstart',
89
		'ak_vp_bundle_enabled',
90
		'verification_services_codes',
91
		Jetpack_SEO_Utils::FRONT_PAGE_META_OPTION,
92
		Jetpack_SEO_Titles::TITLE_FORMATS_OPTION,
93
	);
94
95
	protected static $jetpack_response_field_additions = array(
96
		'subscribers_count',
97
	);
98
99
	protected static $jetpack_response_field_member_additions = array(
100
		'capabilities',
101
		'plan',
102
	);
103
104
	protected static $jetpack_response_option_additions = array(
105
		'publicize_permanently_disabled',
106
		'ak_vp_bundle_enabled'
107
	);
108
109
	private $site;
110
111
	// protected $compact = null;
112
	protected $fields_to_include = '_all';
113
	protected $options_to_include = '_all';
114
115
	// /sites/mine
116
	// /sites/%s -> $blog_id
117
	function callback( $path = '', $blog_id = 0 ) {
118
		if ( 'mine' === $blog_id ) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of 'mine' (string) and $blog_id (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
119
			$api = WPCOM_JSON_API::init();
120
			if ( ! $api->token_details || empty( $api->token_details['blog_id'] ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $api->token_details of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
121
				return new WP_Error( 'authorization_required', 'An active access token must be used to query information about the current blog.', 403 );
122
			}
123
			$blog_id = $api->token_details['blog_id'];
124
		}
125
126
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
127
		if ( is_wp_error( $blog_id ) ) {
128
			return $blog_id;
129
		}
130
131
		// TODO: enable this when we can do so without being interfered with by
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
132
		// other endpoints that might be wrapping this one.
133
		// Uncomment and see failing test: test_jetpack_site_should_have_true_jetpack_property_via_site_meta
134
		// $this->filter_fields_and_options();
135
136
		$response = $this->build_current_site_response();
137
138
		/** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
139
		do_action( 'wpcom_json_api_objects', 'sites' );
140
141
		return $response;
142
	}
143
144
	public function filter_fields_and_options() {
145
		$query_args = $this->query_args();
146
147
		$this->fields_to_include  = empty( $query_args['fields'] ) ? '_all' : array_map( 'trim', explode( ',', $query_args['fields'] ) );
0 ignored issues
show
Documentation Bug introduced by
It seems like empty($query_args['field...$query_args['fields'])) can also be of type array. However, the property $fields_to_include is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
148
		$this->options_to_include = empty( $query_args['options'] ) ? '_all' : array_map( 'trim', explode( ',', $query_args['options'] ) );
0 ignored issues
show
Documentation Bug introduced by
It seems like empty($query_args['optio...query_args['options'])) can also be of type array. However, the property $options_to_include is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
149
	}
150
151
	/**
152
	 * Collects the necessary information to return for a site's response.
153
	 *
154
	 * @return (array)
155
	 */
156
	public function build_current_site_response() {
157
158
		$blog_id = (int) $this->api->get_blog_id_for_output();
159
160
		$this->site = $this->get_platform()->get_site( $blog_id );
161
162
		/**
163
 		 * Filter the structure of information about the site to return.
164
 		 *
165
 		 * @module json-api
166
 		 *
167
 		 * @since 3.9.3
168
 		 *
169
 		 * @param array $site_format Data structure.
170
 		 */
171
		$default_fields = array_keys( apply_filters( 'sites_site_format', self::$site_format ) );
172
173
		$response_keys = is_array( $this->fields_to_include ) ?
174
			array_intersect( $default_fields, $this->fields_to_include ) :
175
			$default_fields;
176
177
		if ( ! is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
178
			$response_keys = array_intersect( $response_keys, self::$no_member_fields );
179
		}
180
181
		return $this->render_response_keys( $response_keys );
182
	}
183
184
	private function render_response_keys( &$response_keys ) {
185
		$response = array();
186
187
		$is_user_logged_in = is_user_logged_in();
188
189
		$this->site->before_render();
190
191
		foreach ( $response_keys as $key ) {
192
			$this->render_response_key( $key, $response, $is_user_logged_in );
193
		}
194
195
		$this->site->after_render( $response );
196
197
		return $response;
198
	}
199
200
	protected function render_response_key( $key, &$response, $is_user_logged_in ) {
201
		do_action( 'pre_render_site_response_key', $key );
202
203
		switch ( $key ) {
204
			case 'ID' :
205
				$response[ $key ] = $this->site->blog_id;
206
				break;
207
			case 'name' :
208
				$response[ $key ] = $this->site->get_name();
209
				break;
210
			case 'description' :
211
				$response[ $key ] = $this->site->get_description();
212
				break;
213
			case 'URL' :
214
				$response[ $key ] = $this->site->get_url();
215
				break;
216
			case 'user_can_manage' :
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
217
				$response[ $key ] = $this->site->user_can_manage();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $response[$key] is correct as $this->site->user_can_manage() (which targets SAL_Site::user_can_manage()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
218
			case 'is_private' :
219
				$response[ $key ] = $this->site->is_private();
220
				break;
221
			case 'visible' :
222
				$response[ $key ] = $this->site->is_visible();
223
				break;
224
			case 'subscribers_count' :
225
				$response[ $key ] = $this->site->get_subscribers_count();
226
				break;
227
			case 'post_count' :
228
				if ( $is_user_logged_in ) {
229
					$response[ $key ] = $this->site->get_post_count();
230
				}
231
				break;
232
			case 'icon' :
233
				$icon = $this->site->get_icon();
234
235
				if ( ! is_null( $icon ) ) {
236
					$response[ $key ] = $icon;
237
				}
238
				break;
239
			case 'logo' :
240
				$response[ $key ] = $this->site->get_logo();
241
				break;
242
			case 'is_following':
243
				$response[ $key ] = $this->site->is_following();
244
				break;
245
			case 'options':
246
				// small optimisation - don't recalculate
247
				$all_options = apply_filters( 'sites_site_options_format', self::$site_options_format );
248
249
				$options_response_keys = is_array( $this->options_to_include ) ?
250
					array_intersect( $all_options, $this->options_to_include ) :
251
					$all_options;
252
253
				$options = $this->render_option_keys( $options_response_keys );
254
255
				$this->site->after_render_options( $options );
256
257
				$response[ $key ] = (object) $options;
258
				break;
259
			case 'meta':
260
				$this->build_meta_response( $response );
261
				break;
262
			case 'lang' :
263
				$response[ $key ] = $is_user_logged_in ? $this->site->get_locale() : false;
264
				break;
265
			case 'locale' :
266
				$response[ $key ] = $is_user_logged_in ? $this->site->get_locale() : false;
267
				break;
268
			case 'jetpack' :
269
				$response[ $key ] = $this->site->is_jetpack();
270
				break;
271
			case 'single_user_site' :
272
				$response[ $key ] = $this->site->is_single_user_site();
273
				break;
274
			case 'is_vip' :
275
				$response[ $key ] = $this->site->is_vip();
276
				break;
277
			case 'is_multisite' :
278
				$response[ $key ] = $this->site->is_multisite();
279
				break;
280
			case 'capabilities' :
281
				$response[ $key ] = $this->site->get_capabilities();
282
				break;
283
			case 'jetpack_modules':
284
				$jetpack_modules = $this->site->get_jetpack_modules();
285
				if ( ! is_null( $jetpack_modules ) ) {
286
					$response[ $key ] = $jetpack_modules;
287
				}
288
				break;
289
			case 'plan' :
290
				$response[ $key ] = $this->site->get_plan();
291
				break;
292
		}
293
294
		do_action( 'post_render_site_response_key', $key );
295
	}
296
297
	protected function render_option_keys( &$options_response_keys ) {
298
		if ( ! current_user_can( 'edit_posts' ) ) {
299
			return array();
300
		}
301
302
		$options = array();
303
		$site = $this->site;
304
305
		$custom_front_page = $site->is_custom_front_page();
306
307
308
		foreach ( $options_response_keys as $key ) {
309
			switch ( $key ) {
310
				case 'timezone' :
311
					$options[ $key ] = $site->get_timezone();
312
					break;
313
				case 'gmt_offset' :
314
					$options[ $key ] = $site->get_gmt_offset();
315
					break;
316
				case 'videopress_enabled' :
317
					$options[ $key ] = $site->has_videopress();
318
					break;
319
				case 'upgraded_filetypes_enabled' :
320
					$options[ $key ] = $site->upgraded_filetypes_enabled();
321
					break;
322
				case 'login_url' :
323
					$options[ $key ] = $site->get_login_url();
324
					break;
325
				case 'admin_url' :
326
					$options[ $key ] = $site->get_admin_url();
327
					break;
328
				case 'is_mapped_domain' :
329
					$options[ $key ] = $site->is_mapped_domain();
330
					break;
331
				case 'is_redirect' :
332
					$options[ $key ] = $site->is_redirect();
333
					break;
334
				case 'unmapped_url' :
335
					$options[ $key ] = $site->get_unmapped_url();
336
					break;
337
				case 'featured_images_enabled' :
338
					$options[ $key ] = $site->featured_images_enabled();
339
					break;
340
				case 'theme_slug' :
341
					$options[ $key ] = $site->get_theme_slug();
342
					break;
343
				case 'header_image' :
344
					$options[ $key ] = $site->get_header_image();
345
					break;
346
				case 'background_color' :
347
					$options[ $key ] = $site->get_background_color();
348
					break;
349
				case 'image_default_link_type' :
350
					$options[ $key ] = $site->get_image_default_link_type();
351
					break;
352
				case 'image_thumbnail_width' :
353
					$options[ $key ] = $site->get_image_thumbnail_width();
354
					break;
355
				case 'image_thumbnail_height' :
356
					$options[ $key ] = $site->get_image_thumbnail_height();
357
					break;
358
				case 'image_thumbnail_crop' :
359
					$options[ $key ] = $site->get_image_thumbnail_crop();
360
					break;
361
				case 'image_medium_width' :
362
					$options[ $key ] = $site->get_image_medium_width();
363
					break;
364
				case 'image_medium_height' :
365
					$options[ $key ] = $site->get_image_medium_height();
366
					break;
367
				case 'image_large_width' :
368
					$options[ $key ] = $site->get_image_large_width();
369
					break;
370
				case 'image_large_height' :
371
					$options[ $key ] = $site->get_image_large_height();
372
					break;
373
				case 'permalink_structure' :
374
					$options[ $key ] = $site->get_permalink_structure();
375
					break;
376
				case 'post_formats' :
377
					$options[ $key ] = $site->get_post_formats();
378
					break;
379
				case 'default_post_format' :
380
					$options[ $key ] = $site->get_default_post_format();
381
					break;
382
				case 'default_category' :
383
					$options[ $key ] = $site->get_default_category();
384
					break;
385
				case 'allowed_file_types' :
386
					$options[ $key ] = $site->allowed_file_types();
387
					break;
388
				case 'show_on_front' :
389
					$options[ $key ] = $site->get_show_on_front();
390
					break;
391
				/** This filter is documented in modules/likes.php */
392
				case 'default_likes_enabled' :
393
					$options[ $key ] = $site->get_default_likes_enabled();
394
					break;
395
				case 'default_sharing_status' :
396
					$options[ $key ] = $site->get_default_sharing_status();
397
					break;
398
				case 'default_comment_status' :
399
					$options[ $key ] = $site->get_default_comment_status();
400
					break;
401
				case 'default_ping_status' :
402
					$options[ $key ] = $site->default_ping_status();
403
					break;
404
				case 'software_version' :
405
					$options[ $key ] = $site->get_wordpress_version();
406
					break;
407
				case 'created_at' :
408
					$options[ $key ] = $site->get_registered_date();
409
					break;
410
				case 'wordads' :
411
					$options[ $key ] = $site->has_wordads();
412
					break;
413
				case 'publicize_permanently_disabled' :
414
					$options[ $key ] = $site->is_publicize_permanently_disabled();
415
					break;
416
				case 'frame_nonce' :
417
					$options[ $key ] = $site->get_frame_nonce();
418
					break;
419
				case 'page_on_front' :
420
					if ( $custom_front_page ) {
421
						$options[ $key ] = $site->get_page_on_front();
422
					}
423
					break;
424
				case 'page_for_posts' :
425
					if ( $custom_front_page ) {
426
						$options[ $key ] = $site->get_page_for_posts();
427
					}
428
					break;
429
				case 'headstart' :
430
					$options[ $key ] = $site->is_headstart();
431
					break;
432
				case 'ak_vp_bundle_enabled' :
433
					$options[ $key ] = $site->get_ak_vp_bundle_enabled();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $options[$key] is correct as $site->get_ak_vp_bundle_enabled() (which targets Jetpack_Site::get_ak_vp_bundle_enabled()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
434
					break;
435
				case Jetpack_SEO_Utils::FRONT_PAGE_META_OPTION :
436
					$options[ $key ] = $site->get_jetpack_seo_front_page_description();
437
					break;
438
				case Jetpack_SEO_Titles::TITLE_FORMATS_OPTION :
439
					$options[ $key ] = $site->get_jetpack_seo_title_formats();
440
					break;
441
				case 'verification_services_codes' :
442
					$options[ $key ] = $site->get_verification_services_codes();
443
					break;
444
			}
445
		}
446
447
		return $options;
448
	}
449
450
	protected function build_meta_response( &$response ) {
451
		$links = array(
452
			'self'     => (string) $this->links->get_site_link( $this->site->blog_id ),
453
			'help'     => (string) $this->links->get_site_link( $this->site->blog_id, 'help'      ),
454
			'posts'    => (string) $this->links->get_site_link( $this->site->blog_id, 'posts/'    ),
455
			'comments' => (string) $this->links->get_site_link( $this->site->blog_id, 'comments/' ),
456
			'xmlrpc'   => (string) $this->site->get_xmlrpc_url(),
457
		);
458
459
		$icon = $this->site->get_icon();
460
		if ( ! empty( $icon ) && ! empty( $icon['media_id'] ) ) {
461
			$links['site_icon'] = (string) $this->links->get_site_link( $this->site->blog_id, 'media/' . $icon['media_id'] );
462
		}
463
464
		$response['meta'] = (object) array(
465
			'links' => (object) $links
466
		);
467
	}
468
469
	// apply any WPCOM-only response components to a Jetpack site response
470
	public function decorate_jetpack_response( &$response ) {
471
		$this->site = $this->get_platform()->get_site( $response->ID );
472
473
		// ensure the response is marked as being from Jetpack
474
		$response->jetpack = true;
475
476
		$wpcom_response = $this->render_response_keys( self::$jetpack_response_field_additions );
477
478
		foreach( $wpcom_response as $key => $value ) {
479
			$response->{ $key } = $value;
480
		}
481
482
		$token_details = (object) $this->api->token_details;
483
		if ( is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) || 'blog' === $token_details->access ) {
484
			$wpcom_member_response = $this->render_response_keys( self::$jetpack_response_field_member_additions );
485
486
			foreach( $wpcom_member_response as $key => $value ) {
487
				$response->{ $key } = $value;
488
			}
489
		} else {
490
			// ensure private data is not rendered for non members of the site
491
			unset( $response->options );
492
			unset( $response->is_vip );
493
			unset( $response->single_user_site );
494
			unset( $response->is_private );
495
			unset( $response->capabilities );
496
			unset( $response->lang );
497
			unset( $response->user_can_manage );
498
			unset( $response->is_multisite );
499
			unset( $response->plan );
500
		}
501
502
		// render additional options
503
		if ( $response->options ) {
504
			$wpcom_options_response = $this->render_option_keys( self::$jetpack_response_option_additions );
505
506
			foreach ( $wpcom_options_response as $key => $value ) {
507
				$response->options[ $key ] = $value;
508
			}
509
		}
510
511
		return $response; // possibly no need since it's modified in place
512
	}
513
}
514
515
class WPCOM_JSON_API_List_Post_Formats_Endpoint extends WPCOM_JSON_API_Endpoint {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
516
	// /sites/%s/post-formats -> $blog_id
517
	function callback( $path = '', $blog_id = 0 ) {
518
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
519
		if ( is_wp_error( $blog_id ) ) {
520
			return $blog_id;
521
		}
522
523
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
524
			$this->load_theme_functions();
525
		}
526
527
		// Get a list of supported post formats.
528
		$all_formats = get_post_format_strings();
529
		$supported   = get_theme_support( 'post-formats' );
530
531
		$supported_formats = $response['formats'] = array();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
532
533 View Code Duplication
		if ( isset( $supported[0] ) ) {
534
			foreach ( $supported[0] as $format ) {
535
				$supported_formats[ $format ] = $all_formats[ $format ];
536
			}
537
		}
538
539
		$response['formats'] = (object) $supported_formats;
540
541
		return $response;
542
	}
543
}
544
545
class WPCOM_JSON_API_List_Page_Templates_Endpoint extends WPCOM_JSON_API_Endpoint {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
546
	// /sites/%s/page-templates -> $blog_id
547
	function callback( $path = '', $blog_id = 0 ) {
548
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
549
		if ( is_wp_error( $blog_id ) ) {
550
			return $blog_id;
551
		}
552
553
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
554
			$this->load_theme_functions();
555
		}
556
557
		$response = array();
558
		$page_templates = array();
559
560
		$templates = get_page_templates();
561
		ksort( $templates );
562
563
		foreach ( array_keys( $templates ) as $label ) {
564
			$page_templates[] = array(
565
				'label' => $label,
566
				'file'  => $templates[ $label ]
567
			);
568
		}
569
570
		$response['templates'] = $page_templates;
571
572
		return $response;
573
	}
574
}
575