| 1 |
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName |
| 2 |
/** |
| 3 |
* This file defines the base class for the Site Abstraction Layer (SAL). |
| 4 |
* Note that this is the site "as seen by user $user_id with token $token", which |
| 5 |
* is why we pass the token to the platform; these site instances are value objects |
| 6 |
* to be used in the context of a single request for a single user. |
| 7 |
* Also note that at present this class _assumes_ you've "switched to" |
| 8 |
* the site in question, and functions like `get_bloginfo( 'name' )` will |
| 9 |
* therefore return the correct value. |
| 10 |
* |
| 11 |
* @package automattic/jetpack |
| 12 |
**/ |
| 13 |
|
| 14 |
use Automattic\Jetpack\Blaze; |
| 15 |
use Automattic\Jetpack\Status; |
| 16 |
use Automattic\Jetpack\Status\Host; |
| 17 |
|
| 18 |
require_once __DIR__ . '/class.json-api-date.php'; |
| 19 |
require_once __DIR__ . '/class.json-api-post-base.php'; |
| 20 |
|
| 21 |
/** |
| 22 |
* Base class for SAL_Site. |
| 23 |
* The abstract functions here are extended by Abstract_Jetpack_Site in class.json-api-site-jetpack-base.php. |
| 24 |
*/ |
| 25 |
abstract class SAL_Site { |
| 26 |
|
| 27 |
/** |
| 28 |
* The Jetpack blog ID for the site. |
| 29 |
* |
| 30 |
* @var int |
| 31 |
*/ |
| 32 |
public $blog_id; |
| 33 |
|
| 34 |
/** |
| 35 |
* A new WPORG_Platform instance. |
| 36 |
* |
| 37 |
* @see class.json-api-platform-jetpack.php. |
| 38 |
* |
| 39 |
* @var WPORG_Platform |
| 40 |
*/ |
| 41 |
public $platform; |
| 42 |
|
| 43 |
/** |
| 44 |
* Contructs the SAL_Site instance. |
| 45 |
* |
| 46 |
* @param int $blog_id The Jetpack blog ID for the site. |
| 47 |
* @param WPORG_Platform $platform A new WPORG_Platform instance. |
| 48 |
*/ |
| 49 |
public function __construct( $blog_id, $platform ) { |
| 50 |
$this->blog_id = $blog_id; |
| 51 |
$this->platform = $platform; |
| 52 |
} |
| 53 |
|
| 54 |
/** |
| 55 |
* Get the blog_id property. |
| 56 |
* |
| 57 |
* @return int |
| 58 |
*/ |
| 59 |
public function get_id() { |
| 60 |
return $this->blog_id; |
| 61 |
} |
| 62 |
|
| 63 |
/** |
| 64 |
* Returns the site name. |
| 65 |
* |
| 66 |
* @return string |
| 67 |
*/ |
| 68 |
public function get_name() { |
| 69 |
return (string) htmlspecialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ); |
| 70 |
} |
| 71 |
|
| 72 |
/** |
| 73 |
* Returns the site description. |
| 74 |
* |
| 75 |
* @return string |
| 76 |
*/ |
| 77 |
public function get_description() { |
| 78 |
return (string) htmlspecialchars_decode( get_bloginfo( 'description' ), ENT_QUOTES ); |
| 79 |
} |
| 80 |
|
| 81 |
/** |
| 82 |
* Returns the URL for the current site. |
| 83 |
* |
| 84 |
* @return string |
| 85 |
*/ |
| 86 |
public function get_url() { |
| 87 |
return (string) home_url(); |
| 88 |
} |
| 89 |
|
| 90 |
/** |
| 91 |
* Returns the number of published posts with the 'post' post-type. |
| 92 |
* |
| 93 |
* @return int |
| 94 |
*/ |
| 95 |
public function get_post_count() { |
| 96 |
return (int) wp_count_posts( 'post' )->publish; |
| 97 |
} |
| 98 |
|
| 99 |
/** |
| 100 |
* A prototype function for get_quota - currently returns null. |
| 101 |
* |
| 102 |
* @return null |
| 103 |
*/ |
| 104 |
public function get_quota() { |
| 105 |
return null; |
| 106 |
} |
| 107 |
|
| 108 |
/** |
| 109 |
* Returns an array of blogging prompt settings. Only applicable on WordPress.com. |
| 110 |
* |
| 111 |
* Data comes from .com since the fearture requires a .com connection to work. |
| 112 |
* |
| 113 |
* @param int $user_id the current user_id. |
| 114 |
* @param int $blog_id the blog id in this context. |
| 115 |
*/ |
| 116 |
public function get_blogging_prompts_settings( $user_id, $blog_id ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable |
| 117 |
return false; |
| 118 |
} |
| 119 |
|
| 120 |
/** |
| 121 |
* Returns true if a site has the 'videopress' option enabled, false otherwise. |
| 122 |
* |
| 123 |
* @see class.json-api-site-jetpack.php for implementation. |
| 124 |
*/ |
| 125 |
abstract public function has_videopress(); |
| 126 |
|
| 127 |
/** |
| 128 |
* Returns VideoPress storage used, in MB. |
| 129 |
* |
| 130 |
* @see class.json-api-site-jetpack-shadow.php on WordPress.com for implementation. Only applicable on WordPress.com. |
| 131 |
*/ |
| 132 |
abstract public function get_videopress_storage_used(); |
| 133 |
|
| 134 |
/** |
| 135 |
* Sets the upgraded_filetypes_enabled Jetpack option to true as a default. Only relevant for WordPress.com sites. |
| 136 |
* |
| 137 |
* @see class.json-api-site-jetpack.php for implementation. |
| 138 |
*/ |
| 139 |
abstract public function upgraded_filetypes_enabled(); |
| 140 |
|
| 141 |
/** |
| 142 |
* Sets the is_mapped_domain Jetpack option to true as a default. |
| 143 |
* |
| 144 |
* Primarily used in WordPress.com to confirm the current blog's domain does or doesn't match the primary redirect. |
| 145 |
* |
| 146 |
* @see class.json-api-site-jetpack.php for implementation. |
| 147 |
*/ |
| 148 |
abstract public function is_mapped_domain(); |
| 149 |
|
| 150 |
/** |
| 151 |
* Fallback to the home URL since all Jetpack sites don't have an unmapped *.wordpress.com domain. |
| 152 |
* |
| 153 |
* @see class.json-api-site-jetpack.php for implementation. |
| 154 |
*/ |
| 155 |
abstract public function get_unmapped_url(); |
| 156 |
|
| 157 |
/** |
| 158 |
* Whether the domain is a site redirect or not. Defaults to false on a Jetpack site. |
| 159 |
* |
| 160 |
* Primarily used in WordPress.com where it is determined if a HTTP status check is a redirect or not and whether an exception should be thrown. |
| 161 |
* |
| 162 |
* @see class.json-api-site-jetpack.php for implementation. |
| 163 |
*/ |
| 164 |
abstract public function is_redirect(); |
| 165 |
|
| 166 |
/** |
| 167 |
* Defaults to false on Jetpack sites, however is used on WordPress.com sites, where it returns true if the headstart-fresh blog sticker is present. |
| 168 |
* |
| 169 |
* @see class.json-api-site-jetpack.php for implementation. |
| 170 |
*/ |
| 171 |
abstract public function is_headstart_fresh(); |
| 172 |
|
| 173 |
/** |
| 174 |
* If the site's current theme supports post thumbnails, return true (otherwise return false). |
| 175 |
* |
| 176 |
* @see class.json-api-site-jetpack-base.php for implementation. |
| 177 |
*/ |
| 178 |
abstract public function featured_images_enabled(); |
| 179 |
|
| 180 |
/** |
| 181 |
* Whether or not the Jetpack 'wordads' module is active on the site. |
| 182 |
* |
| 183 |
* @see class.json-api-site-jetpack.php for implementation. |
| 184 |
*/ |
| 185 |
abstract public function has_wordads(); |
| 186 |
|
| 187 |
/** |
| 188 |
* Defaults to false on Jetpack sites, however is used on WordPress.com sites. This nonce is used for previews on Jetpack sites. |
| 189 |
* |
| 190 |
* @see class.json-api-site-jetpack.php for implementation. |
| 191 |
*/ |
| 192 |
abstract public function get_frame_nonce(); |
| 193 |
|
| 194 |
/** |
| 195 |
* Defaults to false on Jetpack sites, however is used on WordPress.com sites where |
| 196 |
* it creates a nonce to be used with iframed block editor requests to a Jetpack site. |
| 197 |
* |
| 198 |
* @see class.json-api-site-jetpack.php for implementation. |
| 199 |
*/ |
| 200 |
abstract public function get_jetpack_frame_nonce(); |
| 201 |
|
| 202 |
/** |
| 203 |
* Returns the allowed mime types and file extensions for a site. |
| 204 |
* |
| 205 |
* @see class.json-api-site-jetpack.php for implementation. |
| 206 |
*/ |
| 207 |
abstract public function allowed_file_types(); |
| 208 |
|
| 209 |
/** |
| 210 |
* Returns an array of supported post formats. |
| 211 |
* |
| 212 |
* @see class.json-api-site-jetpack-base.php for implementation. |
| 213 |
*/ |
| 214 |
abstract public function get_post_formats(); |
| 215 |
|
| 216 |
/** |
| 217 |
* Return site's privacy status. |
| 218 |
* |
| 219 |
* @see class.json-api-site-jetpack.php for implementation. |
| 220 |
*/ |
| 221 |
abstract public function is_private(); |
| 222 |
|
| 223 |
/** |
| 224 |
* Return site's coming soon status. |
| 225 |
* |
| 226 |
* @see class.json-api-site-jetpack.php for implementation. |
| 227 |
*/ |
| 228 |
abstract public function is_coming_soon(); |
| 229 |
|
| 230 |
/** |
| 231 |
* Whether or not the current user is following this blog. Defaults to false. |
| 232 |
* |
| 233 |
* @see class.json-api-site-jetpack.php for implementation. |
| 234 |
*/ |
| 235 |
abstract public function is_following(); |
| 236 |
|
| 237 |
/** |
| 238 |
* Defaults to 0 for the number of WordPress.com subscribers - this is filled in on the WordPress.com side. |
| 239 |
* |
| 240 |
* @see class.json-api-site-jetpack.php for implementation. |
| 241 |
*/ |
| 242 |
abstract public function get_subscribers_count(); |
| 243 |
|
| 244 |
/** |
| 245 |
* Returns the language code for the current site. |
| 246 |
* |
| 247 |
* @see class.json-api-site-jetpack.php for implementation. |
| 248 |
*/ |
| 249 |
abstract public function get_locale(); |
| 250 |
|
| 251 |
/** |
| 252 |
* The flag indicates that the site has Jetpack installed. |
| 253 |
* |
| 254 |
* @see class.json-api-site-jetpack.php for implementation. |
| 255 |
*/ |
| 256 |
abstract public function is_jetpack(); |
| 257 |
|
| 258 |
/** |
| 259 |
* The flag indicates that the site is connected to WP.com via Jetpack Connection. |
| 260 |
* |
| 261 |
* @see class.json-api-site-jetpack.php for implementation. |
| 262 |
*/ |
| 263 |
abstract public function is_jetpack_connection(); |
| 264 |
|
| 265 |
/** |
| 266 |
* This function returns the values of any active Jetpack modules. |
| 267 |
* |
| 268 |
* @see class.json-api-site-jetpack-base.php for implementation. |
| 269 |
*/ |
| 270 |
abstract public function get_jetpack_modules(); |
| 271 |
|
| 272 |
/** |
| 273 |
* This function returns true if a specified Jetpack module is active, false otherwise. |
| 274 |
* |
| 275 |
* @see class.json-api-site-jetpack-base.php for implementation. |
| 276 |
* |
| 277 |
* @param string $module The Jetpack module name to check. |
| 278 |
*/ |
| 279 |
abstract public function is_module_active( $module ); |
| 280 |
|
| 281 |
/** |
| 282 |
* This function returns false for a check as to whether a site is a VIP site or not. |
| 283 |
* |
| 284 |
* @see class.json-api-site-jetpack-base.php for implementation. |
| 285 |
*/ |
| 286 |
abstract public function is_vip(); |
| 287 |
|
| 288 |
/** |
| 289 |
* Returns true if Multisite is enabled, false otherwise. |
| 290 |
* |
| 291 |
* @see class.json-api-site-jetpack.php for implementation. |
| 292 |
*/ |
| 293 |
abstract public function is_multisite(); |
| 294 |
|
| 295 |
/** |
| 296 |
* Points to the user ID of the site owner |
| 297 |
* |
| 298 |
* @see class.json-api-site-jetpack.php for implementation. |
| 299 |
*/ |
| 300 |
abstract public function get_site_owner(); |
| 301 |
|
| 302 |
/** |
| 303 |
* Returns true if the current site is a single user site, false otherwise. |
| 304 |
* |
| 305 |
* @see class.json-api-site-jetpack.php for implementation. |
| 306 |
*/ |
| 307 |
abstract public function is_single_user_site(); |
| 308 |
|
| 309 |
/** |
| 310 |
* Defaults to false instead of returning the current site plan. |
| 311 |
* |
| 312 |
* @see class.json-api-site-jetpack.php for implementation. |
| 313 |
*/ |
| 314 |
abstract public function get_plan(); |
| 315 |
|
| 316 |
/** |
| 317 |
* Empty function declaration - this function is filled out on the WordPress.com side, returning true if the site has an AK / VP bundle. |
| 318 |
* |
| 319 |
* @see class.json-api-site-jetpack.php and /wpcom/public.api/rest/sal/class.json-api-site-jetpack-shadow.php. |
| 320 |
*/ |
| 321 |
abstract public function get_ak_vp_bundle_enabled(); |
| 322 |
|
| 323 |
/** |
| 324 |
* Returns null for Jetpack sites. For WordPress.com sites this returns the value of the 'podcasting_archive' option. |
| 325 |
* |
| 326 |
* @see class.json-api-site-jetpack.php for implementation. |
| 327 |
*/ |
| 328 |
abstract public function get_podcasting_archive(); |
| 329 |
|
| 330 |
/** |
| 331 |
* Return the last engine used for an import on the site. Not used in Jetpack. |
| 332 |
* |
| 333 |
* @see class.json-api-site-jetpack.php for implementation. |
| 334 |
*/ |
| 335 |
abstract public function get_import_engine(); |
| 336 |
|
| 337 |
/** |
| 338 |
* Returns the front page meta description for current site. |
| 339 |
* |
| 340 |
* @see class.json-api-site-jetpack.php for implementation. |
| 341 |
*/ |
| 342 |
abstract public function get_jetpack_seo_front_page_description(); |
| 343 |
|
| 344 |
/** |
| 345 |
* Returns custom title formats from site option. |
| 346 |
* |
| 347 |
* @see class.json-api-site-jetpack.php for implementation. |
| 348 |
*/ |
| 349 |
abstract public function get_jetpack_seo_title_formats(); |
| 350 |
|
| 351 |
/** |
| 352 |
* Returns website verification codes. Allowed keys include: google, pinterest, bing, yandex, facebook. |
| 353 |
* |
| 354 |
* @see class.json-api-site-jetpack.php for implementation. |
| 355 |
*/ |
| 356 |
abstract public function get_verification_services_codes(); |
| 357 |
|
| 358 |
/** |
| 359 |
* This function is implemented on WPCom sites, where a filter is removed which forces the URL to http. |
| 360 |
* |
| 361 |
* @see class.json-api-site-jetpack-base.php and /wpcom/public.api/rest/sal/class.json-api-site-jetpack-shadow.php. |
| 362 |
*/ |
| 363 |
abstract public function before_render(); |
| 364 |
|
| 365 |
/** |
| 366 |
* If a user has manage options permissions and the site is the main site of the network, make updates visible. |
| 367 |
* |
| 368 |
* Called after response_keys have been rendered, which itself is used to return all the necessary information for a site’s response. |
| 369 |
* |
| 370 |
* @see class.json-api-site-jetpack-base.php for implementation. |
| 371 |
* |
| 372 |
* @param array $response an array of the response keys. |
| 373 |
*/ |
| 374 |
abstract public function after_render( &$response ); |
| 375 |
|
| 376 |
/** |
| 377 |
* Extends the Jetpack options array with details including site constraints, WordPress and Jetpack versions, and plugins using the Jetpack connection. |
| 378 |
* |
| 379 |
* @see class.json-api-site-jetpack-base.php for implementation. |
| 380 |
* @todo factor this out? Seems an odd thing to have on a site |
| 381 |
* |
| 382 |
* @param array $options an array of the Jetpack options. |
| 383 |
*/ |
| 384 |
abstract public function after_render_options( &$options ); |
| 385 |
|
| 386 |
/** |
| 387 |
* Wrap a WP_Post object with SAL methods, returning a Jetpack_Post object. |
| 388 |
* |
| 389 |
* @see class.json-api-site-jetpack.php for implementation. |
| 390 |
* |
| 391 |
* @param WP_Post $post A WP_Post object. |
| 392 |
* @param string $context The post request context (for example 'edit' or 'display'). |
| 393 |
*/ |
| 394 |
abstract public function wrap_post( $post, $context ); |
| 395 |
|
| 396 |
/** |
| 397 |
* For Jetpack sites this will always return false. |
| 398 |
* |
| 399 |
* @see class.json-api-site-jetpack-base.php for implementation. |
| 400 |
* |
| 401 |
* @param int $post_id The post id. |
| 402 |
*/ |
| 403 |
abstract protected function is_a8c_publication( $post_id ); |
| 404 |
|
| 405 |
/** |
| 406 |
* Return the user interactions with a site. Not used in Jetpack. |
| 407 |
* |
| 408 |
* @see class.json-api-site-jetpack.php for implementation. |
| 409 |
*/ |
| 410 |
abstract public function get_user_interactions(); |
| 411 |
|
| 412 |
/** |
| 413 |
* Flag a site as deleted. Not used in Jetpack. |
| 414 |
* |
| 415 |
* @see class.json-api-site-jetpack.php for implementation. |
| 416 |
*/ |
| 417 |
abstract public function is_deleted(); |
| 418 |
|
| 419 |
/** |
| 420 |
* Indicates that a site is an A4A client. Not used in Jetpack. |
| 421 |
* |
| 422 |
* @see class.json-api-site-jetpack.php for implementation. |
| 423 |
*/ |
| 424 |
abstract public function is_a4a_client(); |
| 425 |
|
| 426 |
/** |
| 427 |
* Indicates that a site is an A4A dev site. |
| 428 |
* |
| 429 |
* @return bool |
| 430 |
*/ |
| 431 |
public function is_a4a_dev_site() { |
| 432 |
if ( function_exists( 'has_blog_sticker' ) ) { |
| 433 |
return has_blog_sticker( 'a4a-is-dev-site' ); |
| 434 |
} |
| 435 |
return false; |
| 436 |
} |
| 437 |
|
| 438 |
/** |
| 439 |
* Return the user interactions with a site. Not used in Jetpack. |
| 440 |
* |
| 441 |
* @param string $role The capability to check. |
| 442 |
* @return bool |
| 443 |
* @see class.json-api-site-jetpack.php for implementation. |
| 444 |
* @see class.json-api-site-wpcom.php (on WPCOM) for Simple-site implementation. |
| 445 |
* @see class.json-api-site-jetpack-shadow.php (on WPCOM) for Atomic-site implementation. |
| 446 |
*/ |
| 447 |
abstract public function current_user_can( $role ); |
| 448 |
|
| 449 |
/** |
| 450 |
* Defines a filter to set whether a site is an automated_transfer site or not. |
| 451 |
* |
| 452 |
* Default is false. |
| 453 |
* |
| 454 |
* @return bool |
| 455 |
*/ |
| 456 |
public function is_automated_transfer() { |
| 457 |
/** |
| 458 |
* Filter if a site is an automated-transfer site. |
| 459 |
* |
| 460 |
* @module json-api |
| 461 |
* |
| 462 |
* @since 6.4.0 |
| 463 |
* |
| 464 |
* @param bool is_automated_transfer( $this->blog_id ) |
| 465 |
* @param int $blog_id Blog identifier. |
| 466 |
*/ |
| 467 |
return apply_filters( |
| 468 |
'jetpack_site_automated_transfer', |
| 469 |
false, |
| 470 |
$this->blog_id |
| 471 |
); |
| 472 |
} |
| 473 |
|
| 474 |
/** |
| 475 |
* Defaulting to false and not relevant for Jetpack sites, this is expanded on the WordPress.com side for a specific wp.com/start 'WP for teams' flow. |
| 476 |
* |
| 477 |
* @see class.json-api-site-jetpack.php for implementation. |
| 478 |
*/ |
| 479 |
abstract public function is_wpforteams_site(); |
| 480 |
|
| 481 |
/** |
| 482 |
* Get hub blog id for P2 sites. |
| 483 |
* |
| 484 |
* @return null |
| 485 |
*/ |
| 486 |
public function get_p2_hub_blog_id() { |
| 487 |
return null; |
| 488 |
} |
| 489 |
|
| 490 |
/** |
| 491 |
* Getter for the p2 organization ID. |
| 492 |
* |
| 493 |
* @return int |
| 494 |
*/ |
| 495 |
public function get_p2_organization_id() { |
| 496 |
return 0; // WPForTeams\Constants\NO_ORG_ID not loaded. |
| 497 |
} |
| 498 |
|
| 499 |
/** |
| 500 |
* Get details used to render a thumbnail of the site. P2020 themed sites only. |
| 501 |
* |
| 502 |
* @return ?array |
| 503 |
*/ |
| 504 |
public function get_p2_thumbnail_elements() { |
| 505 |
return null; |
| 506 |
} |
| 507 |
|
| 508 |
/** |
| 509 |
* Detect whether a site is a WordPress.com on Atomic site. |
| 510 |
* |
| 511 |
* @return bool |
| 512 |
*/ |
| 513 |
public function is_wpcom_atomic() { |
| 514 |
return ( new Host() )->is_woa_site(); |
| 515 |
} |
| 516 |
|
| 517 |
/** |
| 518 |
* Detect whether a site is an automated transfer site and WooCommerce is active. |
| 519 |
* |
| 520 |
* @see /wpcom/public.api/rest/sal/class.json-api-site-jetpack-shadow.php. |
| 521 |
* |
| 522 |
* @return bool - False for Jetpack-connected sites. |
| 523 |
*/ |
| 524 |
public function is_wpcom_store() { |
| 525 |
return false; |
| 526 |
} |
| 527 |
|
| 528 |
/** |
| 529 |
* Indicate whether this site was ever a specific trial. |
| 530 |
* |
| 531 |
* @param string $trial The trial type to check for. |
| 532 |
* |
| 533 |
* @return bool |
| 534 |
*/ |
| 535 |
public function was_trial( $trial ) { |
| 536 |
if ( function_exists( 'has_blog_sticker' ) ) { |
| 537 |
return has_blog_sticker( "had-{$trial}-trial" ); |
| 538 |
} |
| 539 |
return false; |
| 540 |
} |
| 541 |
|
| 542 |
/** |
| 543 |
* Indicate whether this site was upgraded from a trial plan at some point. |
| 544 |
* |
| 545 |
* @return bool |
| 546 |
*/ |
| 547 |
public function was_upgraded_from_trial() { |
| 548 |
if ( function_exists( 'has_blog_sticker' ) ) { |
| 549 |
return has_blog_sticker( 'has-upgraded-from-ecommerce-trial' ); |
| 550 |
} |
| 551 |
return false; |
| 552 |
} |
| 553 |
|
| 554 |
/** |
| 555 |
* Detect whether a site has the WooCommerce plugin active. |
| 556 |
* |
| 557 |
* @see /wpcom/public.api/rest/sal/class.json-api-site-jetpack-shadow.php. |
| 558 |
* |
| 559 |
* @return bool - Default false for Jetpack-connected sites. |
| 560 |
*/ |
| 561 |
public function woocommerce_is_active() { |
| 562 |
return false; |
| 563 |
} |
| 564 |
|
| 565 |
/** |
| 566 |
* Whether the Editing Toolkit plugin is active (relevant only on WordPress.com). |
| 567 |
* |
| 568 |
* @return true |
| 569 |
*/ |
| 570 |
public function editing_toolkit_is_active() { |
| 571 |
return true; |
| 572 |
} |
| 573 |
|
| 574 |
/** |
| 575 |
* Detect whether a site has access to the Jetpack cloud. |
| 576 |
* |
| 577 |
* @see /wpcom/public.api/rest/sal/class.json-api-site-jetpack-shadow.php. |
| 578 |
* |
| 579 |
* @return bool - Default false for Jetpack-connected sites. |
| 580 |
*/ |
| 581 |
public function is_cloud_eligible() { |
| 582 |
return false; |
| 583 |
} |
| 584 |
|
| 585 |
/** |
| 586 |
* Returns an array of WPCOM_Store products. |
| 587 |
* |
| 588 |
* @see /wpcom/public.api/rest/sal/class.json-api-site-jetpack-shadow.php. |
| 589 |
* |
| 590 |
* @return bool - Default empty array for Jetpack-connected sites. |
| 591 |
*/ |
| 592 |
public function get_products() { |
| 593 |
return array(); |
| 594 |
} |
| 595 |
|
| 596 |
/** |
| 597 |
* Get post by ID |
| 598 |
* |
| 599 |
* @param int $post_id The ID of the post. |
| 600 |
* @param string $context The context by which the post data is required (display or edit). |
| 601 |
* |
| 602 |
* @return Jetpack_Post Post object on success, WP_Error object on failure |
| 603 |
**/ |
| 604 |
public function get_post_by_id( $post_id, $context ) { |
| 605 |
$post = get_post( $post_id, OBJECT, $context ); |
| 606 |
|
| 607 |
if ( ! $post ) { |
| 608 |
return new WP_Error( 'unknown_post', 'Unknown post', 404 ); |
| 609 |
} |
| 610 |
|
| 611 |
$wrapped_post = $this->wrap_post( $post, $context ); |
| 612 |
// validate access |
| 613 |
return $this->validate_access( $wrapped_post ); |
| 614 |
} |
| 615 |
|
| 616 |
/** |
| 617 |
* Validate current user can access the post |
| 618 |
* |
| 619 |
* @param Jetpack_Post $post Post object. |
| 620 |
* |
| 621 |
* @return WP_Error|Jetpack_Post |
| 622 |
*/ |
| 623 |
private function validate_access( $post ) { |
| 624 |
$context = $post->context; |
| 625 |
|
| 626 |
if ( |
| 627 |
! $this->is_post_type_allowed( $post->post_type ) |
| 628 |
&& ! $this->is_a8c_publication( $post->ID ) |
| 629 |
) { |
| 630 |
return new WP_Error( 'unknown_post', 'Unknown post', 404 ); |
| 631 |
} |
| 632 |
|
| 633 |
switch ( $context ) { |
| 634 |
case 'edit': |
| 635 |
if ( ! current_user_can( 'edit_post', $post->ID ) ) { |
| 636 |
return new WP_Error( 'unauthorized', 'User cannot edit post', 403 ); |
| 637 |
} |
| 638 |
break; |
| 639 |
case 'display': |
| 640 |
$can_view = $this->user_can_view_post( $post ); |
| 641 |
if ( is_wp_error( $can_view ) ) { |
| 642 |
return $can_view; |
| 643 |
} |
| 644 |
break; |
| 645 |
default: |
| 646 |
return new WP_Error( 'invalid_context', 'Invalid API CONTEXT', 400 ); |
| 647 |
} |
| 648 |
|
| 649 |
return $post; |
| 650 |
} |
| 651 |
|
| 652 |
/** |
| 653 |
* Validate whether the current user can access the specified post type. |
| 654 |
* |
| 655 |
* @param string $post_type The post type to check. |
| 656 |
* @param string $context The context by which the post data is required (display or edit). |
| 657 |
* |
| 658 |
* @return bool |
| 659 |
*/ |
| 660 |
public function current_user_can_access_post_type( $post_type, $context ) { |
| 661 |
$post_type_object = $this->get_post_type_object( $post_type ); |
| 662 |
if ( ! $post_type_object ) { |
| 663 |
return false; |
| 664 |
} |
| 665 |
|
| 666 |
switch ( $context ) { |
| 667 |
case 'edit': |
| 668 |
return current_user_can( $post_type_object->cap->edit_posts ); |
| 669 |
case 'display': |
| 670 |
return $post_type_object->public || current_user_can( $post_type_object->cap->read_private_posts ); |
| 671 |
default: |
| 672 |
return false; |
| 673 |
} |
| 674 |
} |
| 675 |
|
| 676 |
/** |
| 677 |
* Retrieves a post type object by name. |
| 678 |
* |
| 679 |
* @param string $post_type The post type to check. |
| 680 |
* |
| 681 |
* @return WP_Post_Type|null |
| 682 |
*/ |
| 683 |
protected function get_post_type_object( $post_type ) { |
| 684 |
return get_post_type_object( $post_type ); |
| 685 |
} |
| 686 |
|
| 687 |
/** |
| 688 |
* Is the post type allowed? |
| 689 |
* |
| 690 |
* Function copied from class.json-api-endpoints.php. |
| 691 |
* |
| 692 |
* @param string $post_type Post type. |
| 693 |
* |
| 694 |
* @return bool |
| 695 |
*/ |
| 696 |
public function is_post_type_allowed( $post_type ) { |
| 697 |
// if the post type is empty, that's fine, WordPress will default to post |
| 698 |
if ( empty( $post_type ) ) { |
| 699 |
return true; |
| 700 |
} |
| 701 |
|
| 702 |
// allow special 'any' type |
| 703 |
if ( 'any' === $post_type ) { |
| 704 |
return true; |
| 705 |
} |
| 706 |
|
| 707 |
// check for allowed types |
| 708 |
if ( in_array( $post_type, $this->get_whitelisted_post_types(), true ) ) { |
| 709 |
return true; |
| 710 |
} |
| 711 |
|
| 712 |
$post_type_object = get_post_type_object( $post_type ); |
| 713 |
if ( $post_type_object ) { |
| 714 |
if ( ! empty( $post_type_object->show_in_rest ) ) { |
| 715 |
return $post_type_object->show_in_rest; |
| 716 |
} |
| 717 |
if ( ! empty( $post_type_object->publicly_queryable ) ) { |
| 718 |
return $post_type_object->publicly_queryable; |
| 719 |
} |
| 720 |
} |
| 721 |
|
| 722 |
return ! empty( $post_type_object->public ); |
| 723 |
} |
| 724 |
|
| 725 |
/** |
| 726 |
* Gets the whitelisted post types that JP should allow access to. |
| 727 |
* |
| 728 |
* Function copied from class.json-api-endpoints.php. |
| 729 |
* |
| 730 |
* @return array Whitelisted post types. |
| 731 |
*/ |
| 732 |
public function get_whitelisted_post_types() { |
| 733 |
$allowed_types = array( 'post', 'page', 'revision' ); |
| 734 |
|
| 735 |
/** |
| 736 |
* Filter the post types Jetpack has access to, and can synchronize with WordPress.com. |
| 737 |
* |
| 738 |
* @module json-api |
| 739 |
* |
| 740 |
* @since 2.2.3 |
| 741 |
* |
| 742 |
* @param array $allowed_types Array of whitelisted post types. Default to `array( 'post', 'page', 'revision' )`. |
| 743 |
*/ |
| 744 |
$allowed_types = apply_filters( 'rest_api_allowed_post_types', $allowed_types ); |
| 745 |
|
| 746 |
return array_unique( $allowed_types ); |
| 747 |
} |
| 748 |
|
| 749 |
/** |
| 750 |
* Can the user view the post? |
| 751 |
* |
| 752 |
* Function copied from class.json-api-endpoints.php and modified. |
| 753 |
* |
| 754 |
* @param Jetpack_Post $post Post object. |
| 755 |
* @return bool|WP_Error |
| 756 |
*/ |
| 757 |
private function user_can_view_post( $post ) { |
| 758 |
if ( ! $post || is_wp_error( $post ) ) { |
| 759 |
return false; |
| 760 |
} |
| 761 |
// If the post is of status inherit, check if the parent exists ( different to 0 ) to check for the parent status object. |
| 762 |
if ( 'inherit' === $post->post_status && 0 !== (int) $post->post_parent ) { |
| 763 |
$parent_post = get_post( $post->post_parent ); |
| 764 |
$post_status_obj = get_post_status_object( $parent_post->post_status ); |
| 765 |
} else { |
| 766 |
$post_status_obj = get_post_status_object( $post->post_status ); |
| 767 |
} |
| 768 |
|
| 769 |
$authorized = ( |
| 770 |
$post_status_obj->public || |
| 771 |
( is_user_logged_in() && |
| 772 |
( |
| 773 |
( $post_status_obj->protected && current_user_can( 'edit_post', $post->ID ) ) || |
| 774 |
( $post_status_obj->private && current_user_can( 'read_post', $post->ID ) ) || |
| 775 |
( 'trash' === $post->post_status && current_user_can( 'edit_post', $post->ID ) ) || |
| 776 |
'auto-draft' === $post->post_status |
| 777 |
) |
| 778 |
) |
| 779 |
); |
| 780 |
|
| 781 |
if ( ! $authorized ) { |
| 782 |
return new WP_Error( 'unauthorized', 'User cannot view post', 403 ); |
| 783 |
} |
| 784 |
|
| 785 |
if ( |
| 786 |
( new Status() )->is_private_site() && |
| 787 |
/** |
| 788 |
* Filter access to a specific post. |
| 789 |
* |
| 790 |
* @module json-api |
| 791 |
* |
| 792 |
* @since 3.4.0 |
| 793 |
* |
| 794 |
* @param bool current_user_can( 'read_post', $post->ID ) Can the current user access the post. |
| 795 |
* @param WP_Post $post Post data. |
| 796 |
*/ |
| 797 |
! apply_filters( |
| 798 |
'wpcom_json_api_user_can_view_post', |
| 799 |
current_user_can( 'read_post', $post->ID ), |
| 800 |
$post |
| 801 |
) |
| 802 |
) { |
| 803 |
return new WP_Error( |
| 804 |
'unauthorized', |
| 805 |
'User cannot view post', |
| 806 |
array( |
| 807 |
'status_code' => 403, |
| 808 |
'error' => 'private_blog', |
| 809 |
) |
| 810 |
); |
| 811 |
} |
| 812 |
|
| 813 |
if ( strlen( $post->post_password ) && ! current_user_can( 'edit_post', $post->ID ) ) { |
| 814 |
return new WP_Error( |
| 815 |
'unauthorized', |
| 816 |
'User cannot view password protected post', |
| 817 |
array( |
| 818 |
'status_code' => 403, |
| 819 |
'error' => 'password_protected', |
| 820 |
) |
| 821 |
); |
| 822 |
} |
| 823 |
|
| 824 |
return true; |
| 825 |
} |
| 826 |
|
| 827 |
/** |
| 828 |
* Get post ID by name |
| 829 |
* |
| 830 |
* Attempts to match name on post title and page path |
| 831 |
* |
| 832 |
* @param string $name The post name. |
| 833 |
* |
| 834 |
* @return int|WP_Error Post ID on success, WP_Error object on failure |
| 835 |
*/ |
| 836 |
public function get_post_id_by_name( $name ) { |
| 837 |
$name = sanitize_title( $name ); |
| 838 |
|
| 839 |
if ( ! $name ) { |
| 840 |
return new WP_Error( 'invalid_post', 'Invalid post', 400 ); |
| 841 |
} |
| 842 |
|
| 843 |
$posts = get_posts( |
| 844 |
array( |
| 845 |
'name' => $name, |
| 846 |
'numberposts' => 1, |
| 847 |
'post_type' => $this->get_whitelisted_post_types(), |
| 848 |
) |
| 849 |
); |
| 850 |
|
| 851 |
if ( ! $posts || ! isset( $posts[0]->ID ) || ! $posts[0]->ID ) { |
| 852 |
$page = get_page_by_path( $name ); |
| 853 |
|
| 854 |
if ( ! $page ) { |
| 855 |
return new WP_Error( 'unknown_post', 'Unknown post', 404 ); |
| 856 |
} |
| 857 |
|
| 858 |
return $page->ID; |
| 859 |
} |
| 860 |
|
| 861 |
return (int) $posts[0]->ID; |
| 862 |
} |
| 863 |
|
| 864 |
/** |
| 865 |
* Get post by name |
| 866 |
* |
| 867 |
* Attempts to match name on post title and page path |
| 868 |
* |
| 869 |
* @param string $name The post name. |
| 870 |
* @param string $context (display or edit). |
| 871 |
* |
| 872 |
* @return Jetpack_Post|WP_Error Post object on success, WP_Error object on failure |
| 873 |
**/ |
| 874 |
public function get_post_by_name( $name, $context ) { |
| 875 |
$post_id = $this->get_post_id_by_name( $name ); |
| 876 |
if ( is_wp_error( $post_id ) ) { |
| 877 |
return $post_id; |
| 878 |
} |
| 879 |
|
| 880 |
return $this->get_post_by_id( $post_id, $context ); |
| 881 |
} |
| 882 |
|
| 883 |
/** |
| 884 |
* Whether or not the current user is an admin (has option management capabilities). |
| 885 |
* |
| 886 |
* @return bool |
| 887 |
**/ |
| 888 |
public function user_can_manage() { |
| 889 |
return current_user_can( 'manage_options' ); |
| 890 |
} |
| 891 |
|
| 892 |
/** |
| 893 |
* Returns the XMLRPC URL - the site URL including the URL scheme that is used when querying your site's REST API endpoint. |
| 894 |
* |
| 895 |
* @return string |
| 896 |
**/ |
| 897 |
public function get_xmlrpc_url() { |
| 898 |
$xmlrpc_scheme = apply_filters( 'wpcom_json_api_xmlrpc_scheme', wp_parse_url( get_option( 'home' ), PHP_URL_SCHEME ) ); |
| 899 |
return site_url( 'xmlrpc.php', $xmlrpc_scheme ); |
| 900 |
} |
| 901 |
|
| 902 |
/** |
| 903 |
* Returns a date/time string with the date the site was registered, or a default date/time string otherwise. |
| 904 |
* |
| 905 |
* @return string |
| 906 |
**/ |
| 907 |
public function get_registered_date() { |
| 908 |
if ( function_exists( 'get_blog_details' ) ) { |
| 909 |
$blog_details = get_blog_details(); |
| 910 |
if ( ! empty( $blog_details->registered ) ) { |
| 911 |
return WPCOM_JSON_API_Date::format_date( $blog_details->registered ); |
| 912 |
} |
| 913 |
} |
| 914 |
|
| 915 |
return '0000-00-00T00:00:00+00:00'; |
| 916 |
} |
| 917 |
|
| 918 |
/** |
| 919 |
* Returns a date/time string with the date the site was last updated, or a default date/time string otherwise. |
| 920 |
* |
| 921 |
* @return string |
| 922 |
**/ |
| 923 |
public function get_last_update_date() { |
| 924 |
if ( function_exists( 'get_blog_details' ) ) { |
| 925 |
$blog_details = get_blog_details(); |
| 926 |
if ( ! empty( $blog_details->last_updated ) ) { |
| 927 |
return WPCOM_JSON_API_Date::format_date( $blog_details->last_updated ); |
| 928 |
} |
| 929 |
} |
| 930 |
|
| 931 |
return '0000-00-00T00:00:00+00:00'; |
| 932 |
} |
| 933 |
|
| 934 |
/** |
| 935 |
* Returns an array including the current users relevant capabilities. |
| 936 |
* |
| 937 |
* @return array |
| 938 |
**/ |
| 939 |
public function get_capabilities() { |
| 940 |
$is_wpcom_blog_owner = wpcom_get_blog_owner() === (int) get_current_user_id(); |
| 941 |
|
| 942 |
return array( |
| 943 |
'edit_pages' => $this->current_user_can( 'edit_pages' ), |
| 944 |
'edit_posts' => $this->current_user_can( 'edit_posts' ), |
| 945 |
'edit_others_posts' => $this->current_user_can( 'edit_others_posts' ), |
| 946 |
'edit_others_pages' => $this->current_user_can( 'edit_others_pages' ), |
| 947 |
'delete_posts' => $this->current_user_can( 'delete_posts' ), |
| 948 |
'delete_others_posts' => $this->current_user_can( 'delete_others_posts' ), |
| 949 |
'edit_theme_options' => $this->current_user_can( 'edit_theme_options' ), |
| 950 |
'edit_users' => $this->current_user_can( 'edit_users' ), |
| 951 |
'list_users' => $this->current_user_can( 'list_users' ), |
| 952 |
'manage_categories' => $this->current_user_can( 'manage_categories' ), |
| 953 |
'manage_options' => $this->current_user_can( 'manage_options' ), |
| 954 |
'moderate_comments' => $this->current_user_can( 'moderate_comments' ), |
| 955 |
'activate_wordads' => $is_wpcom_blog_owner, |
| 956 |
'promote_users' => $this->current_user_can( 'promote_users' ), |
| 957 |
'publish_posts' => $this->current_user_can( 'publish_posts' ), |
| 958 |
'upload_files' => $this->current_user_can( 'upload_files' ), |
| 959 |
'delete_users' => $this->current_user_can( 'delete_users' ), |
| 960 |
'remove_users' => $this->current_user_can( 'remove_users' ), |
| 961 |
'own_site' => $is_wpcom_blog_owner, |
| 962 |
/** |
| 963 |
* Filter whether the Hosting section in Calypso should be available for site. |
| 964 |
* |
| 965 |
* @module json-api |
| 966 |
* |
| 967 |
* @since 8.2.0 |
| 968 |
* |
| 969 |
* @param bool $view_hosting Can site access Hosting section. Default to false. |
| 970 |
*/ |
| 971 |
'view_hosting' => apply_filters( 'jetpack_json_api_site_can_view_hosting', false ), |
| 972 |
'view_stats' => stats_is_blog_user( $this->blog_id ), |
| 973 |
'activate_plugins' => $this->current_user_can( 'activate_plugins' ), |
| 974 |
'update_plugins' => $this->current_user_can( 'update_plugins' ), |
| 975 |
'export' => $this->current_user_can( 'export' ), |
| 976 |
'import' => $this->current_user_can( 'import' ), |
| 977 |
); |
| 978 |
} |
| 979 |
|
| 980 |
/** |
| 981 |
* Whether or not a site is public. |
| 982 |
* |
| 983 |
* @return bool |
| 984 |
**/ |
| 985 |
public function is_visible() { |
| 986 |
if ( is_user_logged_in() ) { |
| 987 |
$current_user = wp_get_current_user(); |
| 988 |
$visible = (array) get_user_meta( $current_user->ID, 'blog_visibility', true ); |
| 989 |
|
| 990 |
$is_visible = true; |
| 991 |
if ( isset( $visible[ $this->blog_id ] ) ) { |
| 992 |
$is_visible = (bool) $visible[ $this->blog_id ]; |
| 993 |
} |
| 994 |
|
| 995 |
// null and true are visible |
| 996 |
return $is_visible; |
| 997 |
} |
| 998 |
|
| 999 |
return null; |
| 1000 |
} |
| 1001 |
|
| 1002 |
/** |
| 1003 |
* Creates and returns an array with logo settings. |
| 1004 |
* |
| 1005 |
* @return array |
| 1006 |
**/ |
| 1007 |
public function get_logo() { |
| 1008 |
// Set an empty response array. |
| 1009 |
$logo_setting = array( |
| 1010 |
'id' => (int) 0, |
| 1011 |
'sizes' => array(), |
| 1012 |
'url' => '', |
| 1013 |
); |
| 1014 |
|
| 1015 |
// Get current site logo values. |
| 1016 |
$logo_id = get_option( 'site_logo' ); |
| 1017 |
|
| 1018 |
// Update the response array if there's a site logo currenty active. |
| 1019 |
if ( $logo_id ) { |
| 1020 |
$logo_setting['id'] = $logo_id; |
| 1021 |
$logo_setting['url'] = wp_get_attachment_url( $logo_id ); |
| 1022 |
} |
| 1023 |
|
| 1024 |
return $logo_setting; |
| 1025 |
} |
| 1026 |
|
| 1027 |
/** |
| 1028 |
* Returns the timezone string from the site's settings (eg. 'Europe/London'). |
| 1029 |
* |
| 1030 |
* @return string |
| 1031 |
**/ |
| 1032 |
public function get_timezone() { |
| 1033 |
return (string) get_option( 'timezone_string' ); |
| 1034 |
} |
| 1035 |
|
| 1036 |
/** |
| 1037 |
* Returns the GMT offset from the site's settings (eg. 5.5). |
| 1038 |
* |
| 1039 |
* @return float |
| 1040 |
**/ |
| 1041 |
public function get_gmt_offset() { |
| 1042 |
return (float) get_option( 'gmt_offset' ); |
| 1043 |
} |
| 1044 |
|
| 1045 |
/** |
| 1046 |
* Returns the site's login URL. |
| 1047 |
* |
| 1048 |
* @return string |
| 1049 |
**/ |
| 1050 |
public function get_login_url() { |
| 1051 |
return wp_login_url(); |
| 1052 |
} |
| 1053 |
|
| 1054 |
/** |
| 1055 |
* Returns the URL for a site's admin area. |
| 1056 |
* |
| 1057 |
* @return string |
| 1058 |
**/ |
| 1059 |
public function get_admin_url() { |
| 1060 |
return get_admin_url(); |
| 1061 |
} |
| 1062 |
|
| 1063 |
/** |
| 1064 |
* Returns the theme's slug (eg. 'twentytwentytwo') |
| 1065 |
* |
| 1066 |
* @return string |
| 1067 |
**/ |
| 1068 |
public function get_theme_slug() { |
| 1069 |
return get_option( 'stylesheet' ); |
| 1070 |
} |
| 1071 |
|
| 1072 |
/** |
| 1073 |
* Returns a list of errors for broken themes on the site. |
| 1074 |
* |
| 1075 |
* @return array |
| 1076 |
*/ |
| 1077 |
public function get_theme_errors() { |
| 1078 |
$themes_with_errors = wp_get_themes( array( 'errors' => true ) ); |
| 1079 |
$theme_errors = array(); |
| 1080 |
|
| 1081 |
foreach ( $themes_with_errors as $theme ) { |
| 1082 |
$errors = $theme->errors(); |
| 1083 |
|
| 1084 |
if ( is_wp_error( $errors ) && ! empty( $errors->get_error_messages() ) ) { |
| 1085 |
$theme_errors[] = array( |
| 1086 |
'name' => sanitize_title( $theme->get( 'Name' ) ), |
| 1087 |
'errors' => (array) $errors->get_error_messages(), |
| 1088 |
); |
| 1089 |
} |
| 1090 |
} |
| 1091 |
|
| 1092 |
return $theme_errors; |
| 1093 |
} |
| 1094 |
|
| 1095 |
/** |
| 1096 |
* Gets the header image data. |
| 1097 |
* |
| 1098 |
* @return bool|object |
| 1099 |
**/ |
| 1100 |
public function get_header_image() { |
| 1101 |
return get_theme_mod( 'header_image_data' ); |
| 1102 |
} |
| 1103 |
|
| 1104 |
/** |
| 1105 |
* Gets the theme background color. |
| 1106 |
* |
| 1107 |
* @return bool|string |
| 1108 |
**/ |
| 1109 |
public function get_background_color() { |
| 1110 |
return get_theme_mod( 'background_color' ); |
| 1111 |
} |
| 1112 |
|
| 1113 |
/** |
| 1114 |
* Get the image default link type. |
| 1115 |
* |
| 1116 |
* @return string |
| 1117 |
**/ |
| 1118 |
public function get_image_default_link_type() { |
| 1119 |
return get_option( 'image_default_link_type' ); |
| 1120 |
} |
| 1121 |
|
| 1122 |
/** |
| 1123 |
* Gets the image thumbnails width. |
| 1124 |
* |
| 1125 |
* @return int |
| 1126 |
**/ |
| 1127 |
public function get_image_thumbnail_width() { |
| 1128 |
return (int) get_option( 'thumbnail_size_w' ); |
| 1129 |
} |
| 1130 |
|
| 1131 |
/** |
| 1132 |
* Gets the image thumbnails height. |
| 1133 |
* |
| 1134 |
* @return int |
| 1135 |
**/ |
| 1136 |
public function get_image_thumbnail_height() { |
| 1137 |
return (int) get_option( 'thumbnail_size_h' ); |
| 1138 |
} |
| 1139 |
|
| 1140 |
/** |
| 1141 |
* Whether cropping is enabled for thumbnails. |
| 1142 |
* |
| 1143 |
* @return string |
| 1144 |
**/ |
| 1145 |
public function get_image_thumbnail_crop() { |
| 1146 |
return get_option( 'thumbnail_crop' ); |
| 1147 |
} |
| 1148 |
|
| 1149 |
/** |
| 1150 |
* Gets the medium sized image setting's width. |
| 1151 |
* |
| 1152 |
* @return int |
| 1153 |
**/ |
| 1154 |
public function get_image_medium_width() { |
| 1155 |
return (int) get_option( 'medium_size_w' ); |
| 1156 |
} |
| 1157 |
|
| 1158 |
/** |
| 1159 |
* Gets the medium sized image setting's height. |
| 1160 |
* |
| 1161 |
* @return int |
| 1162 |
**/ |
| 1163 |
public function get_image_medium_height() { |
| 1164 |
return (int) get_option( 'medium_size_h' ); |
| 1165 |
} |
| 1166 |
|
| 1167 |
/** |
| 1168 |
* Gets the large sized image setting's width. |
| 1169 |
* |
| 1170 |
* @return int |
| 1171 |
**/ |
| 1172 |
public function get_image_large_width() { |
| 1173 |
return (int) get_option( 'large_size_w' ); |
| 1174 |
} |
| 1175 |
|
| 1176 |
/** |
| 1177 |
* Gets the large sized image setting's height. |
| 1178 |
* |
| 1179 |
* @return int |
| 1180 |
**/ |
| 1181 |
public function get_image_large_height() { |
| 1182 |
return (int) get_option( 'large_size_h' ); |
| 1183 |
} |
| 1184 |
|
| 1185 |
/** |
| 1186 |
* Gets the permalink structure as defined in the site's settings. |
| 1187 |
* |
| 1188 |
* @return string |
| 1189 |
**/ |
| 1190 |
public function get_permalink_structure() { |
| 1191 |
return get_option( 'permalink_structure' ); |
| 1192 |
} |
| 1193 |
|
| 1194 |
/** |
| 1195 |
* Gets the default post format |
| 1196 |
* |
| 1197 |
* @return string |
| 1198 |
**/ |
| 1199 |
public function get_default_post_format() { |
| 1200 |
return get_option( 'default_post_format' ); |
| 1201 |
} |
| 1202 |
|
| 1203 |
/** |
| 1204 |
* Gets the default post category |
| 1205 |
* |
| 1206 |
* @return int |
| 1207 |
**/ |
| 1208 |
public function get_default_category() { |
| 1209 |
return (int) get_option( 'default_category' ); |
| 1210 |
} |
| 1211 |
|
| 1212 |
/** |
| 1213 |
* Returns what should be shown on the front page (eg. page or posts) |
| 1214 |
* |
| 1215 |
* @return string |
| 1216 |
**/ |
| 1217 |
public function get_show_on_front() { |
| 1218 |
return get_option( 'show_on_front' ); |
| 1219 |
} |
| 1220 |
|
| 1221 |
/** |
| 1222 |
* Whether or not the front page is set as 'page' to allow a custom front page |
| 1223 |
* |
| 1224 |
* @return bool |
| 1225 |
**/ |
| 1226 |
public function is_custom_front_page() { |
| 1227 |
return ( 'page' === $this->get_show_on_front() ); |
| 1228 |
} |
| 1229 |
|
| 1230 |
/** |
| 1231 |
* Whether or not likes have been enabled on all site posts |
| 1232 |
* |
| 1233 |
* @return bool |
| 1234 |
**/ |
| 1235 |
public function get_default_likes_enabled() { |
| 1236 |
return (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) ); |
| 1237 |
} |
| 1238 |
|
| 1239 |
/** |
| 1240 |
* If sharing has been enabled and there are visible blog services (eg. 'facebook', 'twitter'), returns true. |
| 1241 |
* |
| 1242 |
* @return bool |
| 1243 |
**/ |
| 1244 |
public function get_default_sharing_status() { |
| 1245 |
$default_sharing_status = false; |
| 1246 |
if ( class_exists( 'Sharing_Service' ) ) { |
| 1247 |
$ss = new Sharing_Service(); |
| 1248 |
$blog_services = $ss->get_blog_services(); |
| 1249 |
$default_sharing_status = ! empty( $blog_services['visible'] ); |
| 1250 |
} |
| 1251 |
return (bool) $default_sharing_status; |
| 1252 |
} |
| 1253 |
|
| 1254 |
/** |
| 1255 |
* Displays the current comment status |
| 1256 |
* |
| 1257 |
* @return bool False if closed, true for all other comment statuses. |
| 1258 |
**/ |
| 1259 |
public function get_default_comment_status() { |
| 1260 |
return 'closed' !== get_option( 'default_comment_status' ); |
| 1261 |
} |
| 1262 |
|
| 1263 |
/** |
| 1264 |
* Displays the current site-wide post ping status (for pingbacks and trackbacks) |
| 1265 |
* |
| 1266 |
* @return bool False if closed, true for all other ping statuses. |
| 1267 |
**/ |
| 1268 |
public function default_ping_status() { |
| 1269 |
return 'closed' !== get_option( 'default_ping_status' ); |
| 1270 |
} |
| 1271 |
|
| 1272 |
/** |
| 1273 |
* Whether or not Publicize has been permanently disabled on the site |
| 1274 |
* |
| 1275 |
* @see wpcom/wp-content/admin-plugins/publicize/publicize-wpcom.php |
| 1276 |
* |
| 1277 |
* @return bool Default false. |
| 1278 |
**/ |
| 1279 |
public function is_publicize_permanently_disabled() { |
| 1280 |
$publicize_permanently_disabled = false; |
| 1281 |
if ( function_exists( 'is_publicize_permanently_disabled' ) ) { |
| 1282 |
$publicize_permanently_disabled = is_publicize_permanently_disabled( $this->blog_id ); |
| 1283 |
} |
| 1284 |
return $publicize_permanently_disabled; |
| 1285 |
} |
| 1286 |
|
| 1287 |
/** |
| 1288 |
* Returns the post ID of the static front page. |
| 1289 |
* |
| 1290 |
* @return int |
| 1291 |
**/ |
| 1292 |
public function get_page_on_front() { |
| 1293 |
return (int) get_option( 'page_on_front' ); |
| 1294 |
} |
| 1295 |
|
| 1296 |
/** |
| 1297 |
* Returns the post ID of the page designated as the posts page. |
| 1298 |
* |
| 1299 |
* @return int |
| 1300 |
**/ |
| 1301 |
public function get_page_for_posts() { |
| 1302 |
return (int) get_option( 'page_for_posts' ); |
| 1303 |
} |
| 1304 |
|
| 1305 |
/** |
| 1306 |
* Whether or not headstart is enabled for the site |
| 1307 |
* |
| 1308 |
* @return bool |
| 1309 |
**/ |
| 1310 |
public function is_headstart() { |
| 1311 |
return get_option( 'headstart' ); |
| 1312 |
} |
| 1313 |
|
| 1314 |
/** |
| 1315 |
* The WordPress version on the site. |
| 1316 |
* |
| 1317 |
* @return string |
| 1318 |
**/ |
| 1319 |
public function get_wordpress_version() { |
| 1320 |
global $wp_version; |
| 1321 |
return $wp_version; |
| 1322 |
} |
| 1323 |
|
| 1324 |
/** |
| 1325 |
* Whether or not this is a domain-only site (only relevant on WordPress.com simple sites - false otherwise) |
| 1326 |
* |
| 1327 |
* @return bool |
| 1328 |
**/ |
| 1329 |
public function is_domain_only() { |
| 1330 |
$options = get_option( 'options' ); |
| 1331 |
return ! empty( $options['is_domain_only'] ) ? (bool) $options['is_domain_only'] : false; |
| 1332 |
} |
| 1333 |
|
| 1334 |
/** |
| 1335 |
* Whether or not the blog is set to public (not hidden from search engines) |
| 1336 |
* |
| 1337 |
* @return int 1 for true, 0 for false. |
| 1338 |
**/ |
| 1339 |
public function get_blog_public() { |
| 1340 |
return (int) get_option( 'blog_public' ); |
| 1341 |
} |
| 1342 |
|
| 1343 |
/** |
| 1344 |
* Whether or not the site is in a 'pending automated transfer' state. |
| 1345 |
* |
| 1346 |
* @return bool |
| 1347 |
**/ |
| 1348 |
public function has_pending_automated_transfer() { |
| 1349 |
/** |
| 1350 |
* Filter if a site is in pending automated transfer state. |
| 1351 |
* |
| 1352 |
* @module json-api |
| 1353 |
* |
| 1354 |
* @since 6.4.0 |
| 1355 |
* |
| 1356 |
* @param bool has_site_pending_automated_transfer( $this->blog_id ) |
| 1357 |
* @param int $blog_id Blog identifier. |
| 1358 |
*/ |
| 1359 |
return apply_filters( |
| 1360 |
'jetpack_site_pending_automated_transfer', |
| 1361 |
false, |
| 1362 |
$this->blog_id |
| 1363 |
); |
| 1364 |
} |
| 1365 |
|
| 1366 |
/** |
| 1367 |
* Whether or not the site has a 'designType' option set as 'store' |
| 1368 |
* |
| 1369 |
* @return bool |
| 1370 |
**/ |
| 1371 |
public function signup_is_store() { |
| 1372 |
return $this->get_design_type() === 'store'; |
| 1373 |
} |
| 1374 |
|
| 1375 |
/** |
| 1376 |
* Return a new WP_Roles instance, which implements a user roles API |
| 1377 |
* |
| 1378 |
* @return WP_Roles |
| 1379 |
**/ |
| 1380 |
public function get_roles() { |
| 1381 |
return new WP_Roles(); |
| 1382 |
} |
| 1383 |
|
| 1384 |
/** |
| 1385 |
* Returns the 'designType' option if set (the site design type), null otherwise. |
| 1386 |
* |
| 1387 |
* @return string|null |
| 1388 |
**/ |
| 1389 |
public function get_design_type() { |
| 1390 |
$options = get_option( 'options' ); |
| 1391 |
return empty( $options['designType'] ) ? null : $options['designType']; |
| 1392 |
} |
| 1393 |
|
| 1394 |
/** |
| 1395 |
* Returns the 'site_goals' option if set (eg. share, promote, educate, sell, showcase). |
| 1396 |
* |
| 1397 |
* @return array |
| 1398 |
**/ |
| 1399 |
public function get_site_goals() { |
| 1400 |
$site_goals_option = get_option( 'site_goals' ); |
| 1401 |
|
| 1402 |
if ( is_array( $site_goals_option ) ) { |
| 1403 |
return $site_goals_option; |
| 1404 |
} |
| 1405 |
|
| 1406 |
return array(); |
| 1407 |
} |
| 1408 |
/** |
| 1409 |
* Return site's launch status. Expanded in class.json-api-site-jetpack.php. |
| 1410 |
* |
| 1411 |
* @return bool False in this case. |
| 1412 |
*/ |
| 1413 |
public function get_launch_status() { |
| 1414 |
return false; |
| 1415 |
} |
| 1416 |
|
| 1417 |
/** |
| 1418 |
* Whether a site has any migration meta details - only applicable on WordPress.com |
| 1419 |
* |
| 1420 |
* @see /wpcom/public.api/rest/sal/class.json-api-site-jetpack-shadow.php |
| 1421 |
* |
| 1422 |
* @return null |
| 1423 |
*/ |
| 1424 |
public function get_migration_meta() { |
| 1425 |
return null; |
| 1426 |
} |
| 1427 |
|
| 1428 |
/** |
| 1429 |
* Whether a site has a site segment - only applicable on WordPress.com |
| 1430 |
* |
| 1431 |
* @see /wpcom/public.api/rest/sal/class.json-api-site-wpcom.php |
| 1432 |
* |
| 1433 |
* @return false |
| 1434 |
*/ |
| 1435 |
public function get_site_segment() { |
| 1436 |
return false; |
| 1437 |
} |
| 1438 |
|
| 1439 |
/** |
| 1440 |
* Whether a site has Vertical ID (used for Starter Templates) - default to only applicable on WordPress.com |
| 1441 |
* |
| 1442 |
* @see /wpcom/public.api/rest/sal/class.json-api-site-wpcom.php |
| 1443 |
* |
| 1444 |
* @return false |
| 1445 |
*/ |
| 1446 |
public function get_site_vertical_id() { |
| 1447 |
return false; |
| 1448 |
} |
| 1449 |
|
| 1450 |
/** |
| 1451 |
* Whether a site has a 'site_creation_flow' option set (eg gutenboarding, mobile) - only applicable on WordPress.com |
| 1452 |
* |
| 1453 |
* @see /wpcom-json-endpoints/class.wpcom-json-api-new-site-endpoint.php for more on the option. |
| 1454 |
* |
| 1455 |
* @return bool |
| 1456 |
*/ |
| 1457 |
public function get_site_creation_flow() { |
| 1458 |
return get_option( 'site_creation_flow' ); |
| 1459 |
} |
| 1460 |
|
| 1461 |
/** |
| 1462 |
* Whether a site has a 'site_source_slug' option set - only applicable on WordPress.com |
| 1463 |
* |
| 1464 |
* @see /wpcom-json-endpoints/class.wpcom-json-api-new-site-endpoint.php for more on the option. |
| 1465 |
* |
| 1466 |
* @return bool |
| 1467 |
*/ |
| 1468 |
public function get_site_source_slug() { |
| 1469 |
return get_option( 'site_source_slug' ); |
| 1470 |
} |
| 1471 |
|
| 1472 |
/** |
| 1473 |
* Return any selected features (used to help recommend plans) |
| 1474 |
* |
| 1475 |
* @return string |
| 1476 |
*/ |
| 1477 |
public function get_selected_features() { |
| 1478 |
return get_option( 'selected_features' ); |
| 1479 |
} |
| 1480 |
|
| 1481 |
/** |
| 1482 |
* Return true if the site design was created with a Blank Canvas (empty homepage template), false otherwise. |
| 1483 |
* |
| 1484 |
* @return bool |
| 1485 |
*/ |
| 1486 |
public function was_created_with_blank_canvas_design() { |
| 1487 |
return (bool) get_option( 'was_created_with_blank_canvas_design' ); |
| 1488 |
} |
| 1489 |
|
| 1490 |
/** |
| 1491 |
* Get the option storing the Anchor podcast ID that identifies a site as a podcasting site. |
| 1492 |
* |
| 1493 |
* @return string |
| 1494 |
*/ |
| 1495 |
public function get_anchor_podcast() { |
| 1496 |
return get_option( 'anchor_podcast' ); |
| 1497 |
} |
| 1498 |
|
| 1499 |
/** |
| 1500 |
* Check if the site is currently being built by the DIFM Lite team. |
| 1501 |
* |
| 1502 |
* @return bool |
| 1503 |
*/ |
| 1504 |
public function is_difm_lite_in_progress() { |
| 1505 |
if ( function_exists( 'has_blog_sticker' ) ) { |
| 1506 |
return has_blog_sticker( 'difm-lite-in-progress' ); |
| 1507 |
} elseif ( function_exists( 'wpcomsh_is_site_sticker_active' ) ) { |
| 1508 |
// For atomic sites |
| 1509 |
return wpcomsh_is_site_sticker_active( 'difm-lite-in-progress' ); |
| 1510 |
} |
| 1511 |
return false; |
| 1512 |
} |
| 1513 |
|
| 1514 |
/** |
| 1515 |
* Get the option of site intent which value is coming from the Hero Flow |
| 1516 |
* |
| 1517 |
* @return string |
| 1518 |
*/ |
| 1519 |
public function get_site_intent() { |
| 1520 |
return get_option( 'site_intent', '' ); |
| 1521 |
} |
| 1522 |
|
| 1523 |
/** |
| 1524 |
* Get the option of site partner bundle which value is coming from the Partner Flow |
| 1525 |
* |
| 1526 |
* @return string |
| 1527 |
*/ |
| 1528 |
public function get_site_partner_bundle() { |
| 1529 |
return get_option( 'site_partner_bundle', '' ); |
| 1530 |
} |
| 1531 |
|
| 1532 |
/** |
| 1533 |
* Get site option to determine if and how to display launchpad onboarding |
| 1534 |
* |
| 1535 |
* @return string |
| 1536 |
*/ |
| 1537 |
public function get_launchpad_screen() { |
| 1538 |
return get_option( 'launchpad_screen' ); |
| 1539 |
} |
| 1540 |
|
| 1541 |
/** |
| 1542 |
* Get the option onboarding_segment coming from the Guided Flow |
| 1543 |
* |
| 1544 |
* @return string |
| 1545 |
*/ |
| 1546 |
public function get_onboarding_segment() { |
| 1547 |
return get_option( 'onboarding_segment', '' ); |
| 1548 |
} |
| 1549 |
|
| 1550 |
/** |
| 1551 |
* Get site option for completed launchpad checklist tasks |
| 1552 |
* |
| 1553 |
* @return string |
| 1554 |
*/ |
| 1555 |
public function get_launchpad_checklist_tasks_statuses() { |
| 1556 |
$launchpad_checklist_tasks_statuses_option = get_option( 'launchpad_checklist_tasks_statuses' ); |
| 1557 |
|
| 1558 |
if ( is_array( $launchpad_checklist_tasks_statuses_option ) ) { |
| 1559 |
return $launchpad_checklist_tasks_statuses_option; |
| 1560 |
} |
| 1561 |
|
| 1562 |
return array(); |
| 1563 |
} |
| 1564 |
|
| 1565 |
/** |
| 1566 |
* Get site option for migration source site domain |
| 1567 |
* |
| 1568 |
* @return string |
| 1569 |
*/ |
| 1570 |
public function get_migration_source_site_domain() { |
| 1571 |
return get_option( 'migration_source_site_domain', '' ); |
| 1572 |
} |
| 1573 |
|
| 1574 |
/** |
| 1575 |
* Detect whether a site is WordPress.com Staging Site. |
| 1576 |
* |
| 1577 |
* @see class.json-api-site-jetpack.php for implementation. |
| 1578 |
*/ |
| 1579 |
abstract public function is_wpcom_staging_site(); |
| 1580 |
|
| 1581 |
/** |
| 1582 |
* Get site option for the production blog id (if is a WP.com Staging Site). |
| 1583 |
* |
| 1584 |
* @see class.json-api-site-jetpack.php for implementation. |
| 1585 |
*/ |
| 1586 |
abstract public function get_wpcom_production_blog_id(); |
| 1587 |
|
| 1588 |
/** |
| 1589 |
* Get site option for the staging blog ids (if it has them) |
| 1590 |
* |
| 1591 |
* @see class.json-api-site-jetpack.php for implementation. |
| 1592 |
*/ |
| 1593 |
abstract public function get_wpcom_staging_blog_ids(); |
| 1594 |
|
| 1595 |
/** |
| 1596 |
* Get the site's Blaze eligibility status. |
| 1597 |
* |
| 1598 |
* @return bool |
| 1599 |
*/ |
| 1600 |
public function can_blaze() { |
| 1601 |
return (bool) Blaze::site_supports_blaze( $this->blog_id ); |
| 1602 |
} |
| 1603 |
|
| 1604 |
/** |
| 1605 |
* Return site's setup identifier. |
| 1606 |
* |
| 1607 |
* @return string |
| 1608 |
*/ |
| 1609 |
public function get_wpcom_site_setup() { |
| 1610 |
return get_option( 'wpcom_site_setup' ); |
| 1611 |
} |
| 1612 |
|
| 1613 |
/** |
| 1614 |
* Returns whether the site is commercial. |
| 1615 |
* |
| 1616 |
* @return mixed |
| 1617 |
* |
| 1618 |
* - `true`: the site is commercial |
| 1619 |
* - `false`: the site is not commercial |
| 1620 |
* - `null`: the commercial status is not yet determined |
| 1621 |
*/ |
| 1622 |
public function is_commercial() { |
| 1623 |
// Override if blog has the commercial stickers. |
| 1624 |
if ( function_exists( 'has_blog_sticker' ) ) { |
| 1625 |
$has_not_commercial_sticker = has_blog_sticker( 'jetpack-site-is-not-commercial-override', $this->blog_id ); |
| 1626 |
if ( $has_not_commercial_sticker ) { |
| 1627 |
return false; |
| 1628 |
} |
| 1629 |
$has_commercial_sticker = has_blog_sticker( 'jetpack-site-is-commercial-override', $this->blog_id ); |
| 1630 |
if ( $has_commercial_sticker ) { |
| 1631 |
return true; |
| 1632 |
} |
| 1633 |
} |
| 1634 |
|
| 1635 |
$is_commercial = get_option( '_jetpack_site_is_commercial', null ); |
| 1636 |
return $is_commercial === null ? null : (bool) $is_commercial; |
| 1637 |
} |
| 1638 |
|
| 1639 |
/** |
| 1640 |
* Returns an array of reasons why the site is considered commercial. |
| 1641 |
* |
| 1642 |
* @return array|null |
| 1643 |
*/ |
| 1644 |
public function get_is_commercial_reasons() { |
| 1645 |
$reasons = get_option( '_jetpack_site_is_commercial_reason', array() ); |
| 1646 |
|
| 1647 |
// Add override as reason if blog has the commercial stickers. |
| 1648 |
if ( empty( $reasons ) && $this->is_commercial() ) { |
| 1649 |
return array( 'manual-override' ); |
| 1650 |
} elseif ( ! is_array( $reasons ) ) { |
| 1651 |
return array(); |
| 1652 |
} |
| 1653 |
|
| 1654 |
return $reasons; |
| 1655 |
} |
| 1656 |
|
| 1657 |
/** |
| 1658 |
* Returns the site's interface selection e.g. calypso vs. wp-admin |
| 1659 |
* |
| 1660 |
* @return string |
| 1661 |
**/ |
| 1662 |
public function get_wpcom_admin_interface() { |
| 1663 |
return (string) get_option( 'wpcom_admin_interface' ); |
| 1664 |
} |
| 1665 |
|
| 1666 |
/** |
| 1667 |
* Returns whether the site is part of the classic view early release. |
| 1668 |
* |
| 1669 |
* @return bool |
| 1670 |
**/ |
| 1671 |
public function get_wpcom_classic_early_release() { |
| 1672 |
return ! empty( get_option( 'wpcom_classic_early_release' ) ); |
| 1673 |
} |
| 1674 |
|
| 1675 |
/** |
| 1676 |
* Get Zendesk site meta. |
| 1677 |
* |
| 1678 |
* @return array|null |
| 1679 |
*/ |
| 1680 |
abstract public function get_zendesk_site_meta(); |
| 1681 |
|
| 1682 |
/** |
| 1683 |
* Detect whether there's a pending plan for this site. |
| 1684 |
* |
| 1685 |
* @return bool |
| 1686 |
*/ |
| 1687 |
abstract public function is_pending_plan(); |
| 1688 |
} |
| 1689 |
|