Completed
Push — gutenpack-subscriptions ( 005b18...2275cc )
by
unknown
22:49 queued 16:14
created

SAL_Site::get_launch_status()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
require_once dirname( __FILE__ ) . '/class.json-api-date.php';
4
require_once dirname( __FILE__ ) . '/class.json-api-post-base.php';
5
6
/**
7
 * Base class for the Site Abstraction Layer (SAL)
8
 * Note that this is the site "as seen by user $user_id with token $token", which
9
 * is why we pass the token to the platform; these site instances are value objects
10
 * to be used in the context of a single request for a single user.
11
 * Also note that at present this class _assumes_ you've "switched to"
12
 * the site in question, and functions like `get_bloginfo( 'name' )` will
13
 * therefore return the correct value
14
 **/
15
abstract class SAL_Site {
16
	public $blog_id;
17
	public $platform;
18
19
	public function __construct( $blog_id, $platform ) {
20
		$this->blog_id = $blog_id;
21
		$this->platform = $platform;
22
	}
23
24
	public function get_id() {
25
		return $this->blog_id;
26
	}
27
28
	public function get_name() {
29
		return (string) htmlspecialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
30
	}
31
32
	public function get_description() {
33
		return (string) htmlspecialchars_decode( get_bloginfo( 'description' ), ENT_QUOTES );
34
	}
35
36
	public function get_url() {
37
		return (string) home_url();
38
	}
39
40
	public function get_post_count() {
41
		return (int) wp_count_posts( 'post' )->publish;
42
	}
43
44
	public function get_quota() {
45
		return null;
46
	}
47
48
	abstract public function has_videopress();
49
50
	abstract public function upgraded_filetypes_enabled();
51
52
	abstract public function is_mapped_domain();
53
54
	abstract public function is_redirect();
55
56
	abstract public function is_headstart_fresh();
57
58
	abstract public function featured_images_enabled();
59
60
	abstract public function has_wordads();
61
62
	abstract public function get_frame_nonce();
63
64
	abstract public function allowed_file_types();
65
66
	abstract public function get_post_formats();
67
68
	abstract public function is_private();
69
70
	abstract public function is_following();
71
72
	abstract public function get_subscribers_count();
73
74
	abstract public function get_locale();
75
76
	abstract public function is_jetpack();
77
78
	abstract public function get_jetpack_modules();
79
80
	abstract public function is_vip();
81
82
	abstract public function is_multisite();
83
84
	abstract public function is_single_user_site();
85
86
	abstract public function get_plan();
87
88
	abstract public function get_ak_vp_bundle_enabled();
89
90
	abstract public function get_podcasting_archive();
91
92
	abstract public function get_jetpack_seo_front_page_description();
93
94
	abstract public function get_jetpack_seo_title_formats();
95
96
	abstract public function get_verification_services_codes();
97
98
	abstract public function before_render();
99
100
	abstract public function after_render( &$response );
101
102
	// TODO - factor this out? Seems an odd thing to have on a site
103
	abstract public function after_render_options( &$options );
104
105
	// wrap a WP_Post object with SAL methods
106
	abstract public function wrap_post( $post, $context );
107
108
	abstract protected function is_a8c_publication( $post_id );
109
110
	public function is_automated_transfer() {
111
		/**
112
		 * Filter if a site is an automated-transfer site.
113
		 *
114
		 * @module json-api
115
		 *
116
		 * @since 6.4.0
117
		 *
118
		 * @param bool is_automated_transfer( $this->blog_id )
119
		 * @param int  $blog_id Blog identifier.
120
		 */
121
		return apply_filters(
122
			'jetpack_site_automated_transfer',
123
			false,
124
			$this->blog_id
125
		);
126
	}
127
128
	public function is_wpcom_store() {
129
		return false;
130
	}
131
132
	public function woocommerce_is_active() {
133
		return false;
134
	}
135
136
	public function get_post_by_id( $post_id, $context ) {
137
		// Remove the skyword tracking shortcode for posts returned via the API.
138
		remove_shortcode( 'skyword-tracking' );
139
		add_shortcode( 'skyword-tracking', '__return_empty_string' );
140
141
		$post = get_post( $post_id, OBJECT, $context );
142
143
		if ( ! $post ) {
144
			return new WP_Error( 'unknown_post', 'Unknown post', 404 );
145
		}
146
147
		$wrapped_post = $this->wrap_post( $post, $context );
148
149
		// validate access
150
		return $this->validate_access( $wrapped_post );
151
	}
152
153
	/**
154
	 * Validate current user can access the post
155
	 *
156
	 * @return WP_Error or post
157
	 */
158
	private function validate_access( $post ) {
159
		$context = $post->context;
160
161
		if (
162
			! $this->is_post_type_allowed( $post->post_type )
163
			&& ! $this->is_a8c_publication( $post->ID )
164
		) {
165
			return new WP_Error( 'unknown_post', 'Unknown post', 404 );
166
		}
167
168
		switch ( $context ) {
169
		case 'edit' :
170
			if ( ! current_user_can( 'edit_post', $post ) ) {
171
				return new WP_Error( 'unauthorized', 'User cannot edit post', 403 );
172
			}
173
			break;
174
		case 'display' :
175
			$can_view = $this->user_can_view_post( $post );
176
			if ( is_wp_error( $can_view ) ) {
177
				return $can_view;
178
			}
179
			break;
180
		default :
181
			return new WP_Error( 'invalid_context', 'Invalid API CONTEXT', 400 );
182
		}
183
184
		return $post;
185
	}
186
187 View Code Duplication
	public function current_user_can_access_post_type( $post_type, $context ) {
188
		$post_type_object = $this->get_post_type_object( $post_type );
189
		if ( ! $post_type_object ) {
190
			return false;
191
		}
192
193
		switch( $context ) {
194
			case 'edit':
195
				return current_user_can( $post_type_object->cap->edit_posts );
196
			case 'display':
197
				return $post_type_object->public || current_user_can( $post_type_object->cap->read_private_posts );
198
			default:
199
				return false;
200
		}
201
	}
202
203
	protected function get_post_type_object( $post_type ) {
204
		return get_post_type_object( $post_type );
205
	}
206
207
	// copied from class.json-api-endpoints.php
208 View Code Duplication
	public function is_post_type_allowed( $post_type ) {
209
		// if the post type is empty, that's fine, WordPress will default to post
210
		if ( empty( $post_type ) ) {
211
			return true;
212
		}
213
214
		// allow special 'any' type
215
		if ( 'any' == $post_type ) {
216
			return true;
217
		}
218
219
		// check for allowed types
220
		if ( in_array( $post_type, $this->get_whitelisted_post_types() ) ) {
221
			return true;
222
		}
223
224
		if ( $post_type_object = get_post_type_object( $post_type ) ) {
225
			if ( ! empty( $post_type_object->show_in_rest ) ) {
226
				return $post_type_object->show_in_rest;
227
			}
228
			if ( ! empty( $post_type_object->publicly_queryable ) ) {
229
				return $post_type_object->publicly_queryable;
230
			}
231
		}
232
233
		return ! empty( $post_type_object->public );
234
	}
235
236
	// copied from class.json-api-endpoints.php
237
	/**
238
	 * Gets the whitelisted post types that JP should allow access to.
239
	 *
240
	 * @return array Whitelisted post types.
241
	 */
242 View Code Duplication
	public function get_whitelisted_post_types() {
243
		$allowed_types = array( 'post', 'page', 'revision' );
244
245
		/**
246
		 * Filter the post types Jetpack has access to, and can synchronize with WordPress.com.
247
		 *
248
		 * @module json-api
249
		 *
250
		 * @since 2.2.3
251
		 *
252
		 * @param array $allowed_types Array of whitelisted post types. Default to `array( 'post', 'page', 'revision' )`.
253
		 */
254
		$allowed_types = apply_filters( 'rest_api_allowed_post_types', $allowed_types );
255
256
		return array_unique( $allowed_types );
257
	}
258
259
	// copied and modified a little from class.json-api-endpoints.php
260
	private function user_can_view_post( $post ) {
261
		if ( !$post || is_wp_error( $post ) ) {
262
			return false;
263
		}
264
265 View Code Duplication
		if ( 'inherit' === $post->post_status ) {
266
			$parent_post = get_post( $post->post_parent );
267
			$post_status_obj = get_post_status_object( $parent_post->post_status );
268
		} else {
269
			$post_status_obj = get_post_status_object( $post->post_status );
270
		}
271
272
		$authorized = (
273
			$post_status_obj->public ||
274
			( is_user_logged_in() &&
275
				(
276
					( $post_status_obj->protected    && current_user_can( 'edit_post', $post->ID ) ) ||
277
					( $post_status_obj->private      && current_user_can( 'read_post', $post->ID ) ) ||
278
					( 'trash' === $post->post_status && current_user_can( 'edit_post', $post->ID ) ) ||
279
					'auto-draft' === $post->post_status
280
				)
281
			)
282
		);
283
284
		if ( ! $authorized ) {
285
			return new WP_Error( 'unauthorized', 'User cannot view post', 403 );
286
		}
287
288 View Code Duplication
		if (
289
			-1 == get_option( 'blog_public' ) &&
290
			/**
291
			 * Filter access to a specific post.
292
			 *
293
			 * @module json-api
294
			 *
295
			 * @since 3.4.0
296
			 *
297
			 * @param bool current_user_can( 'read_post', $post->ID ) Can the current user access the post.
298
			 * @param WP_Post $post Post data.
299
			 */
300
			! apply_filters(
301
				'wpcom_json_api_user_can_view_post',
302
				current_user_can( 'read_post', $post->ID ),
303
				$post
304
			)
305
		) {
306
			return new WP_Error( 'unauthorized', 'User cannot view post', array( 'status_code' => 403, 'error' => 'private_blog' ) );
307
		}
308
309 View Code Duplication
		if ( strlen( $post->post_password ) && !current_user_can( 'edit_post', $post->ID ) ) {
310
			return new WP_Error( 'unauthorized', 'User cannot view password protected post', array( 'status_code' => 403, 'error' => 'password_protected' ) );
311
		}
312
313
		return true;
314
	}
315
316
	/**
317
	 * Get post ID by name
318
	 *
319
	 * Attempts to match name on post title and page path
320
	 *
321
	 * @param string $name
322
	 *
323
	 * @return int|object Post ID on success, WP_Error object on failure
324
	 */
325
	public function get_post_id_by_name( $name ) {
326
		$name = sanitize_title( $name );
327
328
		if ( ! $name ) {
329
			return new WP_Error( 'invalid_post', 'Invalid post', 400 );
330
		}
331
332
		$posts = get_posts( array(
333
			'name' => $name,
334
			'numberposts' => 1,
335
			'post_type' => $this->get_whitelisted_post_types(),
336
		) );
337
338
		if ( ! $posts || ! isset( $posts[0]->ID ) || ! $posts[0]->ID ) {
339
			$page = get_page_by_path( $name );
340
341
			if ( ! $page ) {
342
				return new WP_Error( 'unknown_post', 'Unknown post', 404 );
343
			}
344
345
			return $page->ID;
346
		}
347
348
		return (int) $posts[0]->ID;
349
	}
350
351
	/**
352
	 * Get post by name
353
	 *
354
	 * Attempts to match name on post title and page path
355
	 *
356
	 * @param string $name
357
	 * @param string $context (display or edit)
358
	 *
359
	 * @return object Post object on success, WP_Error object on failure
360
	 **/
361
	public function get_post_by_name( $name, $context ) {
362
		$post_id = $this->get_post_id_by_name( $name );
363
		if ( is_wp_error( $post_id ) ) {
364
			return $post_id;
365
		}
366
367
		return $this->get_post_by_id( $post_id, $context );
368
	}
369
370
	function user_can_manage() {
371
		current_user_can( 'manage_options' );
372
	}
373
374
	function get_xmlrpc_url() {
375
		$xmlrpc_scheme = apply_filters( 'wpcom_json_api_xmlrpc_scheme', parse_url( get_option( 'home' ), PHP_URL_SCHEME ) );
376
		return site_url( 'xmlrpc.php', $xmlrpc_scheme );
377
	}
378
379
	function get_registered_date() {
380
		if ( function_exists( 'get_blog_details' ) ) {
381
			$blog_details = get_blog_details();
382
			if ( ! empty( $blog_details->registered ) ) {
383
				return WPCOM_JSON_API_Date::format_date( $blog_details->registered );
384
			}
385
		}
386
387
		return '0000-00-00T00:00:00+00:00';
388
	}
389
390
	function get_capabilities() {
391
		return array(
392
			'edit_pages'          => current_user_can( 'edit_pages' ),
393
			'edit_posts'          => current_user_can( 'edit_posts' ),
394
			'edit_others_posts'   => current_user_can( 'edit_others_posts' ),
395
			'edit_others_pages'   => current_user_can( 'edit_others_pages' ),
396
			'delete_posts'        => current_user_can( 'delete_posts' ),
397
			'delete_others_posts' => current_user_can( 'delete_others_posts' ),
398
			'edit_theme_options'  => current_user_can( 'edit_theme_options' ),
399
			'edit_users'          => current_user_can( 'edit_users' ),
400
			'list_users'          => current_user_can( 'list_users' ),
401
			'manage_categories'   => current_user_can( 'manage_categories' ),
402
			'manage_options'      => current_user_can( 'manage_options' ),
403
			'moderate_comments'   => current_user_can( 'moderate_comments' ),
404
			'activate_wordads'    => wpcom_get_blog_owner() === (int) get_current_user_id(),
405
			'promote_users'       => current_user_can( 'promote_users' ),
406
			'publish_posts'       => current_user_can( 'publish_posts' ),
407
			'upload_files'        => current_user_can( 'upload_files' ),
408
			'delete_users'        => current_user_can( 'delete_users' ),
409
			'remove_users'        => current_user_can( 'remove_users' ),
410
			'view_stats'          => stats_is_blog_user( $this->blog_id )
411
		);
412
	}
413
414
	function is_visible() {
415
		if ( is_user_logged_in() ) {
416
			$current_user = wp_get_current_user();
417
			$visible      = (array) get_user_meta( $current_user->ID, 'blog_visibility', true );
418
419
			$is_visible = true;
420
			if ( isset( $visible[ $this->blog_id ] ) ) {
421
				$is_visible = (bool) $visible[ $this->blog_id ];
422
			}
423
424
			// null and true are visible
425
			return $is_visible;
426
		}
427
428
		return null;
429
	}
430
431
	function get_logo() {
432
433
		// Set an empty response array.
434
		$logo_setting = array(
435
			'id'    => (int) 0,
436
			'sizes' => array(),
437
			'url'   => '',
438
		);
439
440
		// Get current site logo values.
441
		$logo = get_option( 'site_logo' );
442
443
		// Update the response array if there's a site logo currenty active.
444
		if ( $logo && 0 != $logo['id'] ) {
445
			$logo_setting['id']  = $logo['id'];
446
			$logo_setting['url'] = $logo['url'];
447
448
			foreach ( $logo['sizes'] as $size => $properties ) {
449
				$logo_setting['sizes'][ $size ] = $properties;
450
			}
451
		}
452
453
		return $logo_setting;
454
	}
455
456
	function get_timezone() {
457
		return (string) get_option( 'timezone_string' );
458
	}
459
460
	function get_gmt_offset() {
461
		return (float) get_option( 'gmt_offset' );
462
	}
463
464
	function get_login_url() {
465
		return wp_login_url();
466
	}
467
468
	function get_admin_url() {
469
		return get_admin_url();
470
	}
471
472
	function get_unmapped_url() {
473
		return get_site_url( get_current_blog_id() );
474
	}
475
476
	function get_theme_slug() {
477
		return get_option( 'stylesheet' );
478
	}
479
480
	function get_header_image() {
481
		return get_theme_mod( 'header_image_data' );
482
	}
483
484
	function get_background_color() {
485
		return get_theme_mod( 'background_color' );
486
	}
487
488
	function get_image_default_link_type() {
489
		return get_option( 'image_default_link_type' );
490
	}
491
492
	function get_image_thumbnail_width() {
493
		return (int) get_option( 'thumbnail_size_w' );
494
	}
495
496
	function get_image_thumbnail_height() {
497
		return (int) get_option( 'thumbnail_size_h' );
498
	}
499
500
	function get_image_thumbnail_crop() {
501
		return get_option( 'thumbnail_crop' );
502
	}
503
504
	function get_image_medium_width() {
505
		return (int) get_option( 'medium_size_w' );
506
	}
507
508
	function get_image_medium_height() {
509
		return (int) get_option( 'medium_size_h' );
510
	}
511
512
	function get_image_large_width() {
513
		return (int) get_option( 'large_size_w' );
514
	}
515
516
	function get_image_large_height() {
517
		return (int) get_option( 'large_size_h' );
518
	}
519
520
	function get_permalink_structure() {
521
		return get_option( 'permalink_structure' );
522
	}
523
524
	function get_default_post_format() {
525
		return get_option( 'default_post_format' );
526
	}
527
528
	function get_default_category() {
529
		return (int) get_option( 'default_category' );
530
	}
531
532
	function get_show_on_front() {
533
		return get_option( 'show_on_front' );
534
	}
535
536
	function is_custom_front_page() {
537
		return ( 'page' === $this->get_show_on_front() );
538
	}
539
540
	function get_default_likes_enabled() {
541
		return (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
542
	}
543
544
	function get_default_sharing_status() {
545
		$default_sharing_status = false;
546
		if ( class_exists( 'Sharing_Service' ) ) {
547
			$ss                     = new Sharing_Service();
548
			$blog_services          = $ss->get_blog_services();
549
			$default_sharing_status = ! empty( $blog_services['visible'] );
550
		}
551
		return (bool) $default_sharing_status;
552
	}
553
554
	function get_default_comment_status() {
555
		return 'closed' !== get_option( 'default_comment_status' );
556
	}
557
558
	function default_ping_status() {
559
		return 'closed' !== get_option( 'default_ping_status' );
560
	}
561
562
	function is_publicize_permanently_disabled() {
563
		$publicize_permanently_disabled = false;
564
		if ( function_exists( 'is_publicize_permanently_disabled' ) ) {
565
			$publicize_permanently_disabled = is_publicize_permanently_disabled( $this->blog_id );
566
		}
567
		return $publicize_permanently_disabled;
568
	}
569
570
	function get_page_on_front() {
571
		return (int) get_option( 'page_on_front' );
572
	}
573
574
	function get_page_for_posts() {
575
		return (int) get_option( 'page_for_posts' );
576
	}
577
578
	function is_headstart() {
579
		return get_option( 'headstart' );
580
	}
581
582
	function get_wordpress_version() {
583
		global $wp_version;
584
		return $wp_version;
585
	}
586
587
	function is_domain_only() {
588
		$options = get_option( 'options' );
589
		return ! empty ( $options['is_domain_only'] ) ? (bool) $options['is_domain_only'] : false;
590
	}
591
592
	function get_blog_public() {
593
		return (int) get_option( 'blog_public' );
594
	}
595
596
	function has_pending_automated_transfer() {
597
		/**
598
		 * Filter if a site is in pending automated transfer state.
599
		 *
600
		 * @module json-api
601
		 *
602
		 * @since 6.4.0
603
		 *
604
		 * @param bool has_site_pending_automated_transfer( $this->blog_id )
605
		 * @param int  $blog_id Blog identifier.
606
		 */
607
		return apply_filters(
608
			'jetpack_site_pending_automated_transfer',
609
			false,
610
			$this->blog_id
611
		);
612
	}
613
614
	function signup_is_store() {
615
		return $this->get_design_type() === 'store';
616
	}
617
618
	function get_roles() {
619
		return new WP_Roles();
620
	}
621
622
	function get_design_type() {
623
		$options = get_option( 'options' );
624
		return empty( $options[ 'designType'] ) ? null : $options[ 'designType' ];
625
	}
626
627
	function get_site_goals() {
628
		$options = get_option( 'options' );
629
		return empty( $options[ 'siteGoals'] ) ? null : $options[ 'siteGoals' ];
630
	}
631
632
	function get_launch_status() {
633
		return false;
634
	}
635
}
636