PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.7
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.7
16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 All 506 releases
← All changes | sal/class.json-api-site-base.php +276 -27 13.7.2 → 16.3-a.7 View file →
@@ -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.
@@ -423,8 +438,20 @@
423 438 */
424 439 abstract public function is_a4a_client();
425 440
426 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 + /**
427 454 * Return the user interactions with a site. Not used in Jetpack.
428 455 *
429 456 * @param string $role The capability to check.
430 457 * @return bool
@@ -745,26 +772,29 @@
745 772 private function user_can_view_post( $post ) {
746 773 if ( ! $post || is_wp_error( $post ) ) {
747 774 return false;
748 775 }
749 -
750 - 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 ) {
751 778 $parent_post = get_post( $post->post_parent );
752 - $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;
753 780 } else {
754 781 $post_status_obj = get_post_status_object( $post->post_status );
755 782 }
756 783
757 - $authorized = (
758 - $post_status_obj->public ||
759 - ( is_user_logged_in() &&
760 - (
761 - ( $post_status_obj->protected && current_user_can( 'edit_post', $post->ID ) ) ||
762 - ( $post_status_obj->private && current_user_can( 'read_post', $post->ID ) ) ||
763 - ( 'trash' === $post->post_status && current_user_can( 'edit_post', $post->ID ) ) ||
764 - 'auto-draft' === $post->post_status
765 - )
766 - )
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
767 797 );
768 798
769 799 if ( ! $authorized ) {
770 800 return new WP_Error( 'unauthorized', 'User cannot view post', 403 );
@@ -946,18 +976,8 @@
946 976 'upload_files' => $this->current_user_can( 'upload_files' ),
947 977 'delete_users' => $this->current_user_can( 'delete_users' ),
948 978 'remove_users' => $this->current_user_can( 'remove_users' ),
949 979 'own_site' => $is_wpcom_blog_owner,
950 - /**
951 - * Filter whether the Hosting section in Calypso should be available for site.
952 - *
953 - * @module json-api
954 - *
955 - * @since 8.2.0
956 - *
957 - * @param bool $view_hosting Can site access Hosting section. Default to false.
958 - */
959 - 'view_hosting' => apply_filters( 'jetpack_json_api_site_can_view_hosting', false ),
960 980 'view_stats' => stats_is_blog_user( $this->blog_id ),
961 981 'activate_plugins' => $this->current_user_can( 'activate_plugins' ),
962 982 'update_plugins' => $this->current_user_can( 'update_plugins' ),
963 983 'export' => $this->current_user_can( 'export' ),
@@ -994,9 +1014,9 @@
994 1014 **/
995 1015 public function get_logo() {
996 1016 // Set an empty response array.
997 1017 $logo_setting = array(
998 - 'id' => (int) 0,
1018 + 'id' => 0,
999 1019 'sizes' => array(),
1000 1020 'url' => '',
1001 1021 );
1002 1022
@@ -1235,9 +1255,9 @@
1235 1255 $ss = new Sharing_Service();
1236 1256 $blog_services = $ss->get_blog_services();
1237 1257 $default_sharing_status = ! empty( $blog_services['visible'] );
1238 1258 }
1239 - return (bool) $default_sharing_status;
1259 + return $default_sharing_status;
1240 1260 }
1241 1261
1242 1262 /**
1243 1263 * Displays the current comment status
@@ -1499,8 +1519,81 @@
1499 1519 return false;
1500 1520 }
1501 1521
1502 1522 /**
1523 + * Get the DIFM Lite site options exposed to the frontend while a build is in progress.
1524 + *
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
1529 + */
1530 + public function get_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 + );
1565 + }
1566 +
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 + /**
1583 + * Whether the site is still on the pre-2026 feature gating.
1584 + *
1585 + * @return bool
1586 + */
1587 + public function is_legacy_gating_site() {
1588 + if ( ! method_exists( 'WPCOM_Features', 'is_legacy_gating_site' ) ) {
1589 + return false;
1590 + }
1591 +
1592 + return (bool) WPCOM_Features::is_legacy_gating_site( $this->blog_id );
1593 + }
1594 +
1595 + /**
1503 1596 * Get the option of site intent which value is coming from the Hero Flow
1504 1597 *
1505 1598 * @return string
1506 1599 */
@@ -1508,8 +1601,17 @@
1508 1601 return get_option( 'site_intent', '' );
1509 1602 }
1510 1603
1511 1604 /**
1605 + * Get the option of site partner bundle which value is coming from the Partner Flow
1606 + *
1607 + * @return string
1608 + */
1609 + public function get_site_partner_bundle() {
1610 + return get_option( 'site_partner_bundle', '' );
1611 + }
1612 +
1613 + /**
1512 1614 * Get site option to determine if and how to display launchpad onboarding
1513 1615 *
1514 1616 * @return string
1515 1617 */
@@ -1541,8 +1643,56 @@
1541 1643 return array();
1542 1644 }
1543 1645
1544 1646 /**
1647 + * Whether the AI Launchpad is enabled for this site, for the requesting user.
1648 + *
1649 + * The launchpad-personalization assignment is user-scoped: every site of an
1650 + * ai_launchpad user gets the AI Launchpad, however the site was created. Mirrors
1651 + * AI_Launchpad::is_enabled_for_site() in jetpack-mu-wpcom, so wp-admin and the
1652 + * Calypso-facing payload agree. Like the capabilities in this payload, the value
1653 + * is relative to the current user.
1654 + *
1655 + * @return bool
1656 + */
1657 + public function is_ai_launchpad_enabled() {
1658 + if ( (bool) get_option( 'wpcom_ai_launchpad_enabled' ) ) {
1659 + return true;
1660 + }
1661 +
1662 + return class_exists( '\Automattic\Jetpack\Jetpack_Mu_Wpcom\Launchpad_Personalization_Experiment' )
1663 + // @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.
1664 + && 'ai_launchpad' === \Automattic\Jetpack\Jetpack_Mu_Wpcom\Launchpad_Personalization_Experiment::get_variation();
1665 + }
1666 +
1667 + /**
1668 + * Whether the AI Launchpad was dismissed, reverting the site to the regular launchpad.
1669 + *
1670 + * @return bool
1671 + */
1672 + public function is_ai_launchpad_dismissed() {
1673 + return (bool) get_option( 'wpcom_ai_launchpad_dismissed' );
1674 + }
1675 +
1676 + /**
1677 + * Whether every AI Launchpad task has been completed.
1678 + *
1679 + * @return bool
1680 + */
1681 + public function is_ai_launchpad_completed() {
1682 + return (bool) get_option( 'wpcom_ai_launchpad_completed' );
1683 + }
1684 +
1685 + /**
1686 + * Get site option for migration source site domain
1687 + *
1688 + * @return string
1689 + */
1690 + public function get_migration_source_site_domain() {
1691 + return get_option( 'migration_source_site_domain', '' );
1692 + }
1693 +
1694 + /**
1545 1695 * Detect whether a site is WordPress.com Staging Site.
1546 1696 *
1547 1697 * @see class.json-api-site-jetpack.php for implementation.
1548 1698 */
@@ -1642,8 +1792,20 @@
1642 1792 return ! empty( get_option( 'wpcom_classic_early_release' ) );
1643 1793 }
1644 1794
1645 1795 /**
1796 + * Returns whether APM (Application Performance Monitoring) is enabled for the site.
1797 + *
1798 + * APM is an Atomic-only hosting feature. Non-Atomic site types (Simple wpcom, real
1799 + * Jetpack) return false; Jetpack_Shadow_Site overrides with the actual read.
1800 + *
1801 + * @return bool
1802 + **/
1803 + public function get_apm_enabled() {
1804 + return false;
1805 + }
1806 +
1807 + /**
1646 1808 * Get Zendesk site meta.
1647 1809 *
1648 1810 * @return array|null
1649 1811 */
@@ -1654,5 +1816,92 @@
1654 1816 *
1655 1817 * @return bool
1656 1818 */
1657 1819 abstract public function is_pending_plan();
1820 +
1821 + /**
1822 + * Detect whether the site is a Garden site.
1823 + *
1824 + * @return bool
1825 + */
1826 + public function is_garden() {
1827 + return false;
1828 + }
1829 +
1830 + /**
1831 + * Get the Garden name.
1832 + *
1833 + * @return string
1834 + */
1835 + public function garden_name() {
1836 + return null;
1837 + }
1838 +
1839 + /**
1840 + * Get the Garden partner.
1841 + *
1842 + * @return string
1843 + */
1844 + public function garden_partner() {
1845 + return null;
1846 + }
1847 +
1848 + /**
1849 + * Detect whether the Garden site is provisioned.
1850 + *
1851 + * @return bool|null
1852 + */
1853 + public function garden_is_provisioned() {
1854 + return null;
1855 + }
1856 +
1857 + /**
1858 + * Detect whether the site is a Flex site.
1859 + *
1860 + * @return bool
1861 + */
1862 + public function is_wpcom_flex() {
1863 + if ( function_exists( 'has_blog_sticker' ) ) {
1864 + return has_blog_sticker( 'flex-cache-site' );
1865 + }
1866 + return false;
1867 + }
1868 +
1869 + /**
1870 + * Detect whether Big Sky AI assistant is enabled for this site.
1871 + *
1872 + * @return bool
1873 + */
1874 + public function is_big_sky_enabled() {
1875 + return false;
1876 + }
1877 +
1878 + /**
1879 + * Get the state of any block on the site's outgoing email.
1880 + *
1881 + * @return array|null `status` (`blocked` or `at_risk`), `reason` and `expires_on`,
1882 + * or null if the site has never been blocked.
1883 + */
1884 + public function get_atomic_email_block() {
1885 + return null;
1886 + }
1887 +
1888 + /**
1889 + * Get Jetpack recovery mode status.
1890 + *
1891 + * @return array|null
1892 + */
1893 + public function get_jetpack_recovery_mode_status() {
1894 + $status = get_option( 'jetpack_recovery_mode_status' );
1895 + return is_array( $status ) ? $status : null;
1896 + }
1897 +
1898 + /**
1899 + * Whether WordPress.com accounts must have two-step authentication to log in through SSO.
1900 + *
1901 + * @return bool
1902 + */
1903 + public function get_jetpack_sso_require_two_step() {
1904 + /** This filter is documented in projects/packages/connection/src/sso/class-helpers.php */
1905 + return (bool) apply_filters( 'jetpack_sso_require_two_step', get_option( 'jetpack_sso_require_two_step', false ) );
1906 + }
1658 1907 }