| @@ -14,8 +14,12 @@ | ||
| 14 | 14 | use Automattic\Jetpack\Blaze; |
| 15 | 15 | use Automattic\Jetpack\Status; |
| 16 | 16 | use Automattic\Jetpack\Status\Host; |
| 17 | 17 | |
| 18 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 19 | + exit( 0 ); | |
| 20 | +} | |
| 21 | + | |
| 18 | 22 | require_once __DIR__ . '/class.json-api-date.php'; |
| 19 | 23 | require_once __DIR__ . '/class.json-api-post-base.php'; |
| 20 | 24 | |
| 21 | 25 | /** |
| @@ -60,14 +64,24 @@ | ||
| 60 | 64 | return $this->blog_id; |
| 61 | 65 | } |
| 62 | 66 | |
| 63 | 67 | /** |
| 68 | + * Returns the site slug. | |
| 69 | + * | |
| 70 | + * @return string | |
| 71 | + */ | |
| 72 | + public function get_slug() { | |
| 73 | + return ( new Status() )->get_site_suffix(); | |
| 74 | + } | |
| 75 | + | |
| 76 | + /** | |
| 64 | 77 | * Returns the site name. |
| 65 | 78 | * |
| 66 | 79 | * @return string |
| 67 | 80 | */ |
| 68 | 81 | public function get_name() { |
| 69 | - return (string) htmlspecialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ); | |
| 82 | + $name = get_bloginfo( 'name' ); | |
| 83 | + return is_string( $name ) ? htmlspecialchars_decode( $name, ENT_QUOTES ) : ''; | |
| 70 | 84 | } |
| 71 | 85 | |
| 72 | 86 | /** |
| 73 | 87 | * Returns the site description. |
| @@ -74,9 +88,10 @@ | ||
| 74 | 88 | * |
| 75 | 89 | * @return string |
| 76 | 90 | */ |
| 77 | 91 | public function get_description() { |
| 78 | - return (string) htmlspecialchars_decode( get_bloginfo( 'description' ), ENT_QUOTES ); | |
| 92 | + $description = get_bloginfo( 'description' ); | |
| 93 | + return is_string( $description ) ? htmlspecialchars_decode( $description, ENT_QUOTES ) : ''; | |
| 79 | 94 | } |
| 80 | 95 | |
| 81 | 96 | /** |
| 82 | 97 | * Returns the URL for the current site. |
| @@ -409,8 +424,45 @@ | ||
| 409 | 424 | */ |
| 410 | 425 | abstract public function get_user_interactions(); |
| 411 | 426 | |
| 412 | 427 | /** |
| 428 | + * Flag a site as deleted. Not used in Jetpack. | |
| 429 | + * | |
| 430 | + * @see class.json-api-site-jetpack.php for implementation. | |
| 431 | + */ | |
| 432 | + abstract public function is_deleted(); | |
| 433 | + | |
| 434 | + /** | |
| 435 | + * Indicates that a site is an A4A client. Not used in Jetpack. | |
| 436 | + * | |
| 437 | + * @see class.json-api-site-jetpack.php for implementation. | |
| 438 | + */ | |
| 439 | + abstract public function is_a4a_client(); | |
| 440 | + | |
| 441 | + /** | |
| 442 | + * Indicates that a site is an A4A dev site. | |
| 443 | + * | |
| 444 | + * @return bool | |
| 445 | + */ | |
| 446 | + public function is_a4a_dev_site() { | |
| 447 | + if ( function_exists( 'has_blog_sticker' ) ) { | |
| 448 | + return has_blog_sticker( 'a4a-is-dev-site' ); | |
| 449 | + } | |
| 450 | + return false; | |
| 451 | + } | |
| 452 | + | |
| 453 | + /** | |
| 454 | + * Return the user interactions with a site. Not used in Jetpack. | |
| 455 | + * | |
| 456 | + * @param string $role The capability to check. | |
| 457 | + * @return bool | |
| 458 | + * @see class.json-api-site-jetpack.php for implementation. | |
| 459 | + * @see class.json-api-site-wpcom.php (on WPCOM) for Simple-site implementation. | |
| 460 | + * @see class.json-api-site-jetpack-shadow.php (on WPCOM) for Atomic-site implementation. | |
| 461 | + */ | |
| 462 | + abstract public function current_user_can( $role ); | |
| 463 | + | |
| 464 | + /** | |
| 413 | 465 | * Defines a filter to set whether a site is an automated_transfer site or not. |
| 414 | 466 | * |
| 415 | 467 | * Default is false. |
| 416 | 468 | * |
| @@ -438,9 +490,9 @@ | ||
| 438 | 490 | * 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. |
| 439 | 491 | * |
| 440 | 492 | * @see class.json-api-site-jetpack.php for implementation. |
| 441 | 493 | */ |
| 442 | - abstract protected function is_wpforteams_site(); | |
| 494 | + abstract public function is_wpforteams_site(); | |
| 443 | 495 | |
| 444 | 496 | /** |
| 445 | 497 | * Get hub blog id for P2 sites. |
| 446 | 498 | * |
| @@ -502,8 +554,20 @@ | ||
| 502 | 554 | return false; |
| 503 | 555 | } |
| 504 | 556 | |
| 505 | 557 | /** |
| 558 | + * Indicate whether this site was upgraded from a trial plan at some point. | |
| 559 | + * | |
| 560 | + * @return bool | |
| 561 | + */ | |
| 562 | + public function was_upgraded_from_trial() { | |
| 563 | + if ( function_exists( 'has_blog_sticker' ) ) { | |
| 564 | + return has_blog_sticker( 'has-upgraded-from-ecommerce-trial' ); | |
| 565 | + } | |
| 566 | + return false; | |
| 567 | + } | |
| 568 | + | |
| 569 | + /** | |
| 506 | 570 | * Detect whether a site has the WooCommerce plugin active. |
| 507 | 571 | * |
| 508 | 572 | * @see /wpcom/public.api/rest/sal/class.json-api-site-jetpack-shadow.php. |
| 509 | 573 | * |
| @@ -708,26 +772,29 @@ | ||
| 708 | 772 | private function user_can_view_post( $post ) { |
| 709 | 773 | if ( ! $post || is_wp_error( $post ) ) { |
| 710 | 774 | return false; |
| 711 | 775 | } |
| 712 | - | |
| 713 | - if ( 'inherit' === $post->post_status ) { | |
| 776 | + // If the post is of status inherit, check if the parent exists ( different to 0 ) to check for the parent status object. | |
| 777 | + if ( 'inherit' === $post->post_status && 0 !== (int) $post->post_parent ) { | |
| 714 | 778 | $parent_post = get_post( $post->post_parent ); |
| 715 | - $post_status_obj = get_post_status_object( $parent_post->post_status ); | |
| 779 | + $post_status_obj = $parent_post ? get_post_status_object( $parent_post->post_status ) : null; | |
| 716 | 780 | } else { |
| 717 | 781 | $post_status_obj = get_post_status_object( $post->post_status ); |
| 718 | 782 | } |
| 719 | 783 | |
| 720 | - $authorized = ( | |
| 721 | - $post_status_obj->public || | |
| 722 | - ( is_user_logged_in() && | |
| 723 | - ( | |
| 724 | - ( $post_status_obj->protected && current_user_can( 'edit_post', $post->ID ) ) || | |
| 725 | - ( $post_status_obj->private && current_user_can( 'read_post', $post->ID ) ) || | |
| 726 | - ( 'trash' === $post->post_status && current_user_can( 'edit_post', $post->ID ) ) || | |
| 727 | - 'auto-draft' === $post->post_status | |
| 728 | - ) | |
| 729 | - ) | |
| 784 | + $authorized = false; | |
| 785 | + | |
| 786 | + if ( $post_status_obj ) { | |
| 787 | + $authorized = $post_status_obj->public | |
| 788 | + || ( is_user_logged_in() && ( | |
| 789 | + ( $post_status_obj->protected && current_user_can( 'edit_post', $post->ID ) ) | |
| 790 | + || ( $post_status_obj->private && current_user_can( 'read_post', $post->ID ) ) | |
| 791 | + ) ); | |
| 792 | + } | |
| 793 | + | |
| 794 | + $authorized = $authorized || ( | |
| 795 | + ( 'trash' === $post->post_status && current_user_can( 'edit_post', $post->ID ) ) | |
| 796 | + || 'auto-draft' === $post->post_status | |
| 730 | 797 | ); |
| 731 | 798 | |
| 732 | 799 | if ( ! $authorized ) { |
| 733 | 800 | return new WP_Error( 'unauthorized', 'User cannot view post', 403 ); |
| @@ -890,39 +957,32 @@ | ||
| 890 | 957 | public function get_capabilities() { |
| 891 | 958 | $is_wpcom_blog_owner = wpcom_get_blog_owner() === (int) get_current_user_id(); |
| 892 | 959 | |
| 893 | 960 | return array( |
| 894 | - 'edit_pages' => current_user_can( 'edit_pages' ), | |
| 895 | - 'edit_posts' => current_user_can( 'edit_posts' ), | |
| 896 | - 'edit_others_posts' => current_user_can( 'edit_others_posts' ), | |
| 897 | - 'edit_others_pages' => current_user_can( 'edit_others_pages' ), | |
| 898 | - 'delete_posts' => current_user_can( 'delete_posts' ), | |
| 899 | - 'delete_others_posts' => current_user_can( 'delete_others_posts' ), | |
| 900 | - 'edit_theme_options' => current_user_can( 'edit_theme_options' ), | |
| 901 | - 'edit_users' => current_user_can( 'edit_users' ), | |
| 902 | - 'list_users' => current_user_can( 'list_users' ), | |
| 903 | - 'manage_categories' => current_user_can( 'manage_categories' ), | |
| 904 | - 'manage_options' => current_user_can( 'manage_options' ), | |
| 905 | - 'moderate_comments' => current_user_can( 'moderate_comments' ), | |
| 961 | + 'edit_pages' => $this->current_user_can( 'edit_pages' ), | |
| 962 | + 'edit_posts' => $this->current_user_can( 'edit_posts' ), | |
| 963 | + 'edit_others_posts' => $this->current_user_can( 'edit_others_posts' ), | |
| 964 | + 'edit_others_pages' => $this->current_user_can( 'edit_others_pages' ), | |
| 965 | + 'delete_posts' => $this->current_user_can( 'delete_posts' ), | |
| 966 | + 'delete_others_posts' => $this->current_user_can( 'delete_others_posts' ), | |
| 967 | + 'edit_theme_options' => $this->current_user_can( 'edit_theme_options' ), | |
| 968 | + 'edit_users' => $this->current_user_can( 'edit_users' ), | |
| 969 | + 'list_users' => $this->current_user_can( 'list_users' ), | |
| 970 | + 'manage_categories' => $this->current_user_can( 'manage_categories' ), | |
| 971 | + 'manage_options' => $this->current_user_can( 'manage_options' ), | |
| 972 | + 'moderate_comments' => $this->current_user_can( 'moderate_comments' ), | |
| 906 | 973 | 'activate_wordads' => $is_wpcom_blog_owner, |
| 907 | - 'promote_users' => current_user_can( 'promote_users' ), | |
| 908 | - 'publish_posts' => current_user_can( 'publish_posts' ), | |
| 909 | - 'upload_files' => current_user_can( 'upload_files' ), | |
| 910 | - 'delete_users' => current_user_can( 'delete_users' ), | |
| 911 | - 'remove_users' => current_user_can( 'remove_users' ), | |
| 974 | + 'promote_users' => $this->current_user_can( 'promote_users' ), | |
| 975 | + 'publish_posts' => $this->current_user_can( 'publish_posts' ), | |
| 976 | + 'upload_files' => $this->current_user_can( 'upload_files' ), | |
| 977 | + 'delete_users' => $this->current_user_can( 'delete_users' ), | |
| 978 | + 'remove_users' => $this->current_user_can( 'remove_users' ), | |
| 912 | 979 | 'own_site' => $is_wpcom_blog_owner, |
| 913 | - /** | |
| 914 | - * Filter whether the Hosting section in Calypso should be available for site. | |
| 915 | - * | |
| 916 | - * @module json-api | |
| 917 | - * | |
| 918 | - * @since 8.2.0 | |
| 919 | - * | |
| 920 | - * @param bool $view_hosting Can site access Hosting section. Default to false. | |
| 921 | - */ | |
| 922 | - 'view_hosting' => apply_filters( 'jetpack_json_api_site_can_view_hosting', false ), | |
| 923 | 980 | 'view_stats' => stats_is_blog_user( $this->blog_id ), |
| 924 | - 'activate_plugins' => current_user_can( 'activate_plugins' ), | |
| 981 | + 'activate_plugins' => $this->current_user_can( 'activate_plugins' ), | |
| 982 | + 'update_plugins' => $this->current_user_can( 'update_plugins' ), | |
| 983 | + 'export' => $this->current_user_can( 'export' ), | |
| 984 | + 'import' => $this->current_user_can( 'import' ), | |
| 925 | 985 | ); |
| 926 | 986 | } |
| 927 | 987 | |
| 928 | 988 | /** |
| @@ -954,9 +1014,9 @@ | ||
| 954 | 1014 | **/ |
| 955 | 1015 | public function get_logo() { |
| 956 | 1016 | // Set an empty response array. |
| 957 | 1017 | $logo_setting = array( |
| 958 | - 'id' => (int) 0, | |
| 1018 | + 'id' => 0, | |
| 959 | 1019 | 'sizes' => array(), |
| 960 | 1020 | 'url' => '', |
| 961 | 1021 | ); |
| 962 | 1022 | |
| @@ -1017,8 +1077,31 @@ | ||
| 1017 | 1077 | return get_option( 'stylesheet' ); |
| 1018 | 1078 | } |
| 1019 | 1079 | |
| 1020 | 1080 | /** |
| 1081 | + * Returns a list of errors for broken themes on the site. | |
| 1082 | + * | |
| 1083 | + * @return array | |
| 1084 | + */ | |
| 1085 | + public function get_theme_errors() { | |
| 1086 | + $themes_with_errors = wp_get_themes( array( 'errors' => true ) ); | |
| 1087 | + $theme_errors = array(); | |
| 1088 | + | |
| 1089 | + foreach ( $themes_with_errors as $theme ) { | |
| 1090 | + $errors = $theme->errors(); | |
| 1091 | + | |
| 1092 | + if ( is_wp_error( $errors ) && ! empty( $errors->get_error_messages() ) ) { | |
| 1093 | + $theme_errors[] = array( | |
| 1094 | + 'name' => sanitize_title( $theme->get( 'Name' ) ), | |
| 1095 | + 'errors' => (array) $errors->get_error_messages(), | |
| 1096 | + ); | |
| 1097 | + } | |
| 1098 | + } | |
| 1099 | + | |
| 1100 | + return $theme_errors; | |
| 1101 | + } | |
| 1102 | + | |
| 1103 | + /** | |
| 1021 | 1104 | * Gets the header image data. |
| 1022 | 1105 | * |
| 1023 | 1106 | * @return bool|object |
| 1024 | 1107 | **/ |
| @@ -1172,9 +1255,9 @@ | ||
| 1172 | 1255 | $ss = new Sharing_Service(); |
| 1173 | 1256 | $blog_services = $ss->get_blog_services(); |
| 1174 | 1257 | $default_sharing_status = ! empty( $blog_services['visible'] ); |
| 1175 | 1258 | } |
| 1176 | - return (bool) $default_sharing_status; | |
| 1259 | + return $default_sharing_status; | |
| 1177 | 1260 | } |
| 1178 | 1261 | |
| 1179 | 1262 | /** |
| 1180 | 1263 | * Displays the current comment status |
| @@ -1316,17 +1399,21 @@ | ||
| 1316 | 1399 | return empty( $options['designType'] ) ? null : $options['designType']; |
| 1317 | 1400 | } |
| 1318 | 1401 | |
| 1319 | 1402 | /** |
| 1320 | - * Returns the 'siteGoals' option if set (eg. share, promote, educate, sell, showcase), null otherwise. | |
| 1403 | + * Returns the 'site_goals' option if set (eg. share, promote, educate, sell, showcase). | |
| 1321 | 1404 | * |
| 1322 | - * @return string|null | |
| 1405 | + * @return array | |
| 1323 | 1406 | **/ |
| 1324 | 1407 | public function get_site_goals() { |
| 1325 | - $options = get_option( 'options' ); | |
| 1326 | - return empty( $options['siteGoals'] ) ? null : $options['siteGoals']; | |
| 1408 | + $site_goals_option = get_option( 'site_goals' ); | |
| 1409 | + | |
| 1410 | + if ( is_array( $site_goals_option ) ) { | |
| 1411 | + return $site_goals_option; | |
| 1412 | + } | |
| 1413 | + | |
| 1414 | + return array(); | |
| 1327 | 1415 | } |
| 1328 | - | |
| 1329 | 1416 | /** |
| 1330 | 1417 | * Return site's launch status. Expanded in class.json-api-site-jetpack.php. |
| 1331 | 1418 | * |
| 1332 | 1419 | * @return bool False in this case. |
| @@ -1432,17 +1519,68 @@ | ||
| 1432 | 1519 | return false; |
| 1433 | 1520 | } |
| 1434 | 1521 | |
| 1435 | 1522 | /** |
| 1436 | - * The site options for DIFM lite in the design picker step | |
| 1523 | + * Get the DIFM Lite site options exposed to the frontend while a build is in progress. | |
| 1437 | 1524 | * |
| 1438 | - * @return string | |
| 1525 | + * Returns null unless the site has an active DIFM Lite build and the code is | |
| 1526 | + * running on WordPress.com, where the DIFM Lite library exists. | |
| 1527 | + * | |
| 1528 | + * @return array|null | |
| 1439 | 1529 | */ |
| 1440 | 1530 | public function get_difm_lite_site_options() { |
| 1441 | - return get_option( 'difm_lite_site_options' ); | |
| 1531 | + if ( ! $this->is_difm_lite_in_progress() ) { | |
| 1532 | + return null; | |
| 1533 | + } | |
| 1534 | + if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM || ! function_exists( 'require_lib' ) ) { | |
| 1535 | + return null; | |
| 1536 | + } | |
| 1537 | + require_lib( 'difm-lite' ); | |
| 1538 | + if ( ! class_exists( '\DIFM_Lite_Options' ) ) { | |
| 1539 | + // Fail closed if the library did not define the class; this method | |
| 1540 | + // documents null for every path where the options are unavailable. | |
| 1541 | + return null; | |
| 1542 | + } | |
| 1543 | + // The submission state is canonical on the purchase blog. This site may be | |
| 1544 | + // the stickered staging build target, whose own options blob is empty, so | |
| 1545 | + // resolve to the purchase blog before reading — otherwise a post-submit | |
| 1546 | + // staging target reports itself as pre-submit. | |
| 1547 | + // | |
| 1548 | + // resolve_purchase_site_id() ships in the wpcom DIFM Lite site-role | |
| 1549 | + // pointers change. This Jetpack code can deploy before that lands, so | |
| 1550 | + // fall back to the current blog when it is unavailable — no retargeted | |
| 1551 | + // builds can exist until that change is live, so the current blog is the | |
| 1552 | + // purchase blog in that window. | |
| 1553 | + $purchase_blog_id = $this->blog_id; | |
| 1554 | + // @phan-suppress-next-line PhanUndeclaredClassReference -- wpcom-only class, guarded above. | |
| 1555 | + if ( method_exists( '\DIFM_Lite_Options', 'resolve_purchase_site_id' ) ) { | |
| 1556 | + // @phan-suppress-next-line PhanUndeclaredClassMethod -- wpcom-only class, guarded above. | |
| 1557 | + $purchase_blog_id = \DIFM_Lite_Options::resolve_purchase_site_id( $this->blog_id ); | |
| 1558 | + } | |
| 1559 | + // @phan-suppress-next-line PhanUndeclaredClassMethod -- wpcom-only class, guarded above. | |
| 1560 | + $difm_lite_options = new \DIFM_Lite_Options( $purchase_blog_id ); | |
| 1561 | + return array( | |
| 1562 | + // @phan-suppress-next-line PhanUndeclaredClassProperty -- wpcom-only class, guarded above. | |
| 1563 | + 'is_website_content_submitted' => (bool) $difm_lite_options->is_website_content_submitted, | |
| 1564 | + ); | |
| 1442 | 1565 | } |
| 1443 | 1566 | |
| 1444 | 1567 | /** |
| 1568 | + * Check if the site has the gating-business-q1 blog sticker. | |
| 1569 | + * | |
| 1570 | + * @return bool | |
| 1571 | + */ | |
| 1572 | + public function is_gating_business_q1() { | |
| 1573 | + if ( function_exists( 'has_blog_sticker' ) ) { | |
| 1574 | + return has_blog_sticker( 'gating-business-q1' ); | |
| 1575 | + } elseif ( function_exists( 'wpcomsh_is_site_sticker_active' ) ) { | |
| 1576 | + // For atomic sites | |
| 1577 | + return wpcomsh_is_site_sticker_active( 'gating-business-q1' ); | |
| 1578 | + } | |
| 1579 | + return false; | |
| 1580 | + } | |
| 1581 | + | |
| 1582 | + /** | |
| 1445 | 1583 | * Get the option of site intent which value is coming from the Hero Flow |
| 1446 | 1584 | * |
| 1447 | 1585 | * @return string |
| 1448 | 1586 | */ |
| @@ -1450,8 +1588,17 @@ | ||
| 1450 | 1588 | return get_option( 'site_intent', '' ); |
| 1451 | 1589 | } |
| 1452 | 1590 | |
| 1453 | 1591 | /** |
| 1592 | + * Get the option of site partner bundle which value is coming from the Partner Flow | |
| 1593 | + * | |
| 1594 | + * @return string | |
| 1595 | + */ | |
| 1596 | + public function get_site_partner_bundle() { | |
| 1597 | + return get_option( 'site_partner_bundle', '' ); | |
| 1598 | + } | |
| 1599 | + | |
| 1600 | + /** | |
| 1454 | 1601 | * Get site option to determine if and how to display launchpad onboarding |
| 1455 | 1602 | * |
| 1456 | 1603 | * @return string |
| 1457 | 1604 | */ |
| @@ -1459,8 +1606,17 @@ | ||
| 1459 | 1606 | return get_option( 'launchpad_screen' ); |
| 1460 | 1607 | } |
| 1461 | 1608 | |
| 1462 | 1609 | /** |
| 1610 | + * Get the option onboarding_segment coming from the Guided Flow | |
| 1611 | + * | |
| 1612 | + * @return string | |
| 1613 | + */ | |
| 1614 | + public function get_onboarding_segment() { | |
| 1615 | + return get_option( 'onboarding_segment', '' ); | |
| 1616 | + } | |
| 1617 | + | |
| 1618 | + /** | |
| 1463 | 1619 | * Get site option for completed launchpad checklist tasks |
| 1464 | 1620 | * |
| 1465 | 1621 | * @return string |
| 1466 | 1622 | */ |
| @@ -1474,8 +1630,56 @@ | ||
| 1474 | 1630 | return array(); |
| 1475 | 1631 | } |
| 1476 | 1632 | |
| 1477 | 1633 | /** |
| 1634 | + * Whether the AI Launchpad is enabled for this site, for the requesting user. | |
| 1635 | + * | |
| 1636 | + * The launchpad-personalization assignment is user-scoped: every site of an | |
| 1637 | + * ai_launchpad user gets the AI Launchpad, however the site was created. Mirrors | |
| 1638 | + * AI_Launchpad::is_enabled_for_site() in jetpack-mu-wpcom, so wp-admin and the | |
| 1639 | + * Calypso-facing payload agree. Like the capabilities in this payload, the value | |
| 1640 | + * is relative to the current user. | |
| 1641 | + * | |
| 1642 | + * @return bool | |
| 1643 | + */ | |
| 1644 | + public function is_ai_launchpad_enabled() { | |
| 1645 | + if ( (bool) get_option( 'wpcom_ai_launchpad_enabled' ) ) { | |
| 1646 | + return true; | |
| 1647 | + } | |
| 1648 | + | |
| 1649 | + return class_exists( '\Automattic\Jetpack\Jetpack_Mu_Wpcom\Launchpad_Personalization_Experiment' ) | |
| 1650 | + // @phan-suppress-next-line PhanUndeclaredClassMethod -- Lives in jetpack-mu-wpcom, outside this plugin's dependency graph; the class_exists guard above covers contexts where it isn't loaded. | |
| 1651 | + && 'ai_launchpad' === \Automattic\Jetpack\Jetpack_Mu_Wpcom\Launchpad_Personalization_Experiment::get_variation(); | |
| 1652 | + } | |
| 1653 | + | |
| 1654 | + /** | |
| 1655 | + * Whether the AI Launchpad was dismissed, reverting the site to the regular launchpad. | |
| 1656 | + * | |
| 1657 | + * @return bool | |
| 1658 | + */ | |
| 1659 | + public function is_ai_launchpad_dismissed() { | |
| 1660 | + return (bool) get_option( 'wpcom_ai_launchpad_dismissed' ); | |
| 1661 | + } | |
| 1662 | + | |
| 1663 | + /** | |
| 1664 | + * Whether every AI Launchpad task has been completed. | |
| 1665 | + * | |
| 1666 | + * @return bool | |
| 1667 | + */ | |
| 1668 | + public function is_ai_launchpad_completed() { | |
| 1669 | + return (bool) get_option( 'wpcom_ai_launchpad_completed' ); | |
| 1670 | + } | |
| 1671 | + | |
| 1672 | + /** | |
| 1673 | + * Get site option for migration source site domain | |
| 1674 | + * | |
| 1675 | + * @return string | |
| 1676 | + */ | |
| 1677 | + public function get_migration_source_site_domain() { | |
| 1678 | + return get_option( 'migration_source_site_domain', '' ); | |
| 1679 | + } | |
| 1680 | + | |
| 1681 | + /** | |
| 1478 | 1682 | * Detect whether a site is WordPress.com Staging Site. |
| 1479 | 1683 | * |
| 1480 | 1684 | * @see class.json-api-site-jetpack.php for implementation. |
| 1481 | 1685 | */ |
| @@ -1536,6 +1740,145 @@ | ||
| 1536 | 1740 | } |
| 1537 | 1741 | |
| 1538 | 1742 | $is_commercial = get_option( '_jetpack_site_is_commercial', null ); |
| 1539 | 1743 | return $is_commercial === null ? null : (bool) $is_commercial; |
| 1744 | + } | |
| 1745 | + | |
| 1746 | + /** | |
| 1747 | + * Returns an array of reasons why the site is considered commercial. | |
| 1748 | + * | |
| 1749 | + * @return array|null | |
| 1750 | + */ | |
| 1751 | + public function get_is_commercial_reasons() { | |
| 1752 | + $reasons = get_option( '_jetpack_site_is_commercial_reason', array() ); | |
| 1753 | + | |
| 1754 | + // Add override as reason if blog has the commercial stickers. | |
| 1755 | + if ( empty( $reasons ) && $this->is_commercial() ) { | |
| 1756 | + return array( 'manual-override' ); | |
| 1757 | + } elseif ( ! is_array( $reasons ) ) { | |
| 1758 | + return array(); | |
| 1759 | + } | |
| 1760 | + | |
| 1761 | + return $reasons; | |
| 1762 | + } | |
| 1763 | + | |
| 1764 | + /** | |
| 1765 | + * Returns the site's interface selection e.g. calypso vs. wp-admin | |
| 1766 | + * | |
| 1767 | + * @return string | |
| 1768 | + **/ | |
| 1769 | + public function get_wpcom_admin_interface() { | |
| 1770 | + return (string) get_option( 'wpcom_admin_interface' ); | |
| 1771 | + } | |
| 1772 | + | |
| 1773 | + /** | |
| 1774 | + * Returns whether the site is part of the classic view early release. | |
| 1775 | + * | |
| 1776 | + * @return bool | |
| 1777 | + **/ | |
| 1778 | + public function get_wpcom_classic_early_release() { | |
| 1779 | + return ! empty( get_option( 'wpcom_classic_early_release' ) ); | |
| 1780 | + } | |
| 1781 | + | |
| 1782 | + /** | |
| 1783 | + * Returns whether APM (Application Performance Monitoring) is enabled for the site. | |
| 1784 | + * | |
| 1785 | + * APM is an Atomic-only hosting feature. Non-Atomic site types (Simple wpcom, real | |
| 1786 | + * Jetpack) return false; Jetpack_Shadow_Site overrides with the actual read. | |
| 1787 | + * | |
| 1788 | + * @return bool | |
| 1789 | + **/ | |
| 1790 | + public function get_apm_enabled() { | |
| 1791 | + return false; | |
| 1792 | + } | |
| 1793 | + | |
| 1794 | + /** | |
| 1795 | + * Get Zendesk site meta. | |
| 1796 | + * | |
| 1797 | + * @return array|null | |
| 1798 | + */ | |
| 1799 | + abstract public function get_zendesk_site_meta(); | |
| 1800 | + | |
| 1801 | + /** | |
| 1802 | + * Detect whether there's a pending plan for this site. | |
| 1803 | + * | |
| 1804 | + * @return bool | |
| 1805 | + */ | |
| 1806 | + abstract public function is_pending_plan(); | |
| 1807 | + | |
| 1808 | + /** | |
| 1809 | + * Detect whether the site is a Garden site. | |
| 1810 | + * | |
| 1811 | + * @return bool | |
| 1812 | + */ | |
| 1813 | + public function is_garden() { | |
| 1814 | + return false; | |
| 1815 | + } | |
| 1816 | + | |
| 1817 | + /** | |
| 1818 | + * Get the Garden name. | |
| 1819 | + * | |
| 1820 | + * @return string | |
| 1821 | + */ | |
| 1822 | + public function garden_name() { | |
| 1823 | + return null; | |
| 1824 | + } | |
| 1825 | + | |
| 1826 | + /** | |
| 1827 | + * Get the Garden partner. | |
| 1828 | + * | |
| 1829 | + * @return string | |
| 1830 | + */ | |
| 1831 | + public function garden_partner() { | |
| 1832 | + return null; | |
| 1833 | + } | |
| 1834 | + | |
| 1835 | + /** | |
| 1836 | + * Detect whether the Garden site is provisioned. | |
| 1837 | + * | |
| 1838 | + * @return bool|null | |
| 1839 | + */ | |
| 1840 | + public function garden_is_provisioned() { | |
| 1841 | + return null; | |
| 1842 | + } | |
| 1843 | + | |
| 1844 | + /** | |
| 1845 | + * Detect whether the site is a Flex site. | |
| 1846 | + * | |
| 1847 | + * @return bool | |
| 1848 | + */ | |
| 1849 | + public function is_wpcom_flex() { | |
| 1850 | + if ( function_exists( 'has_blog_sticker' ) ) { | |
| 1851 | + return has_blog_sticker( 'flex-cache-site' ); | |
| 1852 | + } | |
| 1853 | + return false; | |
| 1854 | + } | |
| 1855 | + | |
| 1856 | + /** | |
| 1857 | + * Detect whether Big Sky AI assistant is enabled for this site. | |
| 1858 | + * | |
| 1859 | + * @return bool | |
| 1860 | + */ | |
| 1861 | + public function is_big_sky_enabled() { | |
| 1862 | + return false; | |
| 1863 | + } | |
| 1864 | + | |
| 1865 | + /** | |
| 1866 | + * Get the state of any block on the site's outgoing email. | |
| 1867 | + * | |
| 1868 | + * @return array|null `status` (`blocked` or `at_risk`), `reason` and `expires_on`, | |
| 1869 | + * or null if the site has never been blocked. | |
| 1870 | + */ | |
| 1871 | + public function get_atomic_email_block() { | |
| 1872 | + return null; | |
| 1873 | + } | |
| 1874 | + | |
| 1875 | + /** | |
| 1876 | + * Get Jetpack recovery mode status. | |
| 1877 | + * | |
| 1878 | + * @return array|null | |
| 1879 | + */ | |
| 1880 | + public function get_jetpack_recovery_mode_status() { | |
| 1881 | + $status = get_option( 'jetpack_recovery_mode_status' ); | |
| 1882 | + return is_array( $status ) ? $status : null; | |
| 1540 | 1883 | } |
| 1541 | 1884 | } |