This commit is contained in:
emmymayo
2025-02-05 23:15:46 +01:00
commit 7269c99357
16995 changed files with 3389680 additions and 0 deletions
@@ -0,0 +1,244 @@
<?php
/**
* Place to properly deprecate Jetpack features.
*
* @package automattic/jetpack
*/
namespace Automattic\Jetpack\Plugin;
use Automattic\Jetpack\Assets;
use Automattic\Jetpack\Redirect;
use Automattic\Jetpack\Status\Host;
/**
* Place to properly deprecate Jetpack features.
*/
class Deprecate {
/**
* The singleton instance.
*
* @var Deprecate
*/
private static $instance;
/**
* An array of notices to display.
*
* @var array
*/
private $notices = array();
/**
* Initialize the class.
*/
private function __construct() {
// Modify the notices array to include the notices you want to display.
// For more information, see /docs/deprecating-features.md.
$this->notices = array(
'my-admin' => array(
'title' => __( "Retired feature: Jetpack's XYZ Feature", 'jetpack' ),
'message' => __( 'This feature is being retired and will be removed effective November, 2024. Please use the Classic Theme Helper plugin instead.', 'jetpack' ),
'link' => array(
'label' => __( 'Learn more', 'jetpack' ),
'url' => 'jetpack-support-xyz',
),
'show' => false, // 'show' is not required, but setting it to false will ensure that the notice will not be displayed.
'hide_in_woa' => true, // 'hide_in_woa' is not required, but setting it to true will ensure that the notice will not be displayed in the WoA admin (none will display in Simple regardless).
),
);
$this->set_notices();
if ( $this->has_notices() ) {
// We only want the notice to appear on the main WP Admin dashboard, which hooking into load-index.php will allow.
add_action(
'load-index.php',
function () {
add_action( 'admin_notices', array( $this, 'render_admin_notices' ) );
}
);
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
add_filter( 'my_jetpack_red_bubble_notification_slugs', array( $this, 'add_my_jetpack_red_bubbles' ) );
}
}
/**
* Create/get the singleton instance.
*
* @return static
*/
public static function instance() {
if ( null === static::$instance ) {
static::$instance = new static();
}
return static::$instance;
}
/**
* Enqueue the scripts.
*
* @return void
*/
public function enqueue_admin_scripts() {
if ( ! $this->has_notices() ) {
return;
}
if ( ! wp_script_is( 'jetpack-deprecate', 'registered' ) ) {
wp_register_script(
'jetpack-deprecate',
Assets::get_file_url_for_environment( '_inc/build/deprecate.min.js', '_inc/deprecate.js' ),
array(),
JETPACK__VERSION,
true
);
}
wp_enqueue_script( 'jetpack-deprecate' );
wp_add_inline_script(
'jetpack-deprecate',
'window.noticeInfo = ' . wp_json_encode( $this->notices ) . ';',
'before'
);
}
/**
* Ensure the notices variable is properly formatted and includes the required suffix and show value.
*
* @return void
*/
private function set_notices() {
$notices = array();
$required_id_suffix = '-deprecate-feature';
$host = new Host();
foreach ( $this->notices as $id => $notice ) {
if ( $host->is_woa_site() && isset( $notice['hide_in_woa'] ) && true === $notice['hide_in_woa'] ) {
continue;
}
if ( isset( $notice['show'] ) && false === $notice['show'] ) {
continue;
}
if ( empty( $notice['title'] ) || empty( $notice['message'] ) || empty( $notice['link']['url'] ) ) {
continue;
}
if ( empty( $notice['link']['label'] ) ) {
$notice['link']['label'] = __( 'Learn more', 'jetpack' );
}
if ( strpos( $id, $required_id_suffix ) === false ) {
$id .= $required_id_suffix;
}
$notices[ $id ] = $notice;
}
$this->notices = $notices;
}
/**
* Render deprecation notices for relevant features.
*
* @return void
*/
public function render_admin_notices() {
foreach ( $this->notices as $id => $notice ) {
if ( $this->show_feature_notice( $id ) ) {
$support_url = Redirect::get_url( $notice['link']['url'] );
$this->render_notice(
$id,
'<div class="jetpack-deprecation-notice-container">' .
'<div class="jetpack-deprecation-notice-svg">' .
'<svg class="jetpack-deprecation-notice-icon gridicon gridicons-info-outline needs-offset" height="20" width="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" color="#000000">' .
'<g><path d="M13 9h-2V7h2v2zm0 2h-2v6h2v-6zm-1-7c-4.41 0-8 3.59-8 8s3.59 8 8 8 8-3.59 8-8-3.59-8-8-8m0-2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2z"></path></g>' .
'</svg>' .
'</div>' .
'<div class="jetpack-deprecation-notice-text">' .
'<p class="jetpack-deprection-notice-title">' . esc_html( $notice['title'] ) . '</p>' .
'<p>' . esc_html( $notice['message'] ) . '</p>' .
'<a href="' . $support_url . '" target="_blank" class="jetpack-deprecation-notice-link"> ' . esc_html( $notice['link']['label'] ) . '</a>' .
'<svg class="gridicons-external" height="14" width="14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 20">' .
'<g><path d="M19 13v6c0 1.105-.895 2-2 2H5c-1.105 0-2-.895-2-2V7c0-1.105.895-2 2-2h6v2H5v12h12v-6h2zM13 3v2h4.586l-7.793 7.793 1.414 1.414L19 6.414V11h2V3h-8z"></path></g>' .
'</svg>' .
'</div>' .
'</div>'
);
}
}
}
/**
* Add the deprecation notices to My Jetpack.
*
* @param array $slugs Already added bubbles.
*
* @return array
*/
public function add_my_jetpack_red_bubbles( $slugs ) {
foreach ( $this->notices as $id => $notice ) {
if ( $this->show_feature_notice( $id ) ) {
$slugs[ $id ] = array(
'data' => array(
'text' => $notice['message'],
'title' => $notice['title'],
'link' => array(
'label' => esc_html( $notice['link']['label'] ),
'url' => Redirect::get_url( $notice['link']['url'] ),
),
'id' => $id,
),
);
}
}
return $slugs;
}
/**
* Render the notice.
*
* @param string $id The notice ID.
* @param string $text The notice text.
*
* @return void
*/
private function render_notice( $id, $text ) {
printf(
'<div id="%1$s" class="notice notice-warning is-dismissible jetpack-deprecate-dismissible" style="border-left-color: #000000;">%2$s</div>',
esc_html( $id ),
$text // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output already escaped in render_admin_notices
);
}
/**
* Check if there are any notices to be displayed, so we wouldn't load unnecessary JS and run excessive hooks.
*
* @return bool
*/
private function has_notices() {
foreach ( $this->notices as $id => $notice ) {
if ( $this->show_feature_notice( $id ) ) {
return true;
}
}
return false;
}
/**
* Check if the feature notice should be shown, based on the existence of the cookie.
*
* @param string $id The notice ID.
*
* @return bool
*/
private function show_feature_notice( $id ) {
return empty( $_COOKIE['jetpack_deprecate_dismissed'][ $id ] );
}
}
@@ -0,0 +1,79 @@
<?php
/**
* Compatibility functions for the Jetpack CRM plugin.
*
* @since 9.0.0
*
* @package automattic/jetpack
*/
namespace Automattic\Jetpack;
use WP_Error;
/**
* Provides Jetpack CRM plugin data.
*/
class Jetpack_CRM_Data {
const JETPACK_CRM_PLUGIN_SLUG = 'zero-bs-crm/ZeroBSCRM.php';
/**
* Provides Jetpack CRM plugin data for use in the Contact Form block sidebar menu.
*
* @return array An array containing the Jetpack CRM plugin data.
*/
public function get_crm_data() {
$plugins = Plugins_Installer::get_plugins();
// Set default values.
$response = array(
'crm_installed' => false,
'crm_active' => false,
'crm_version' => null,
'jp_form_ext_enabled' => null,
'can_install_crm' => false,
'can_activate_crm' => false,
'can_activate_extension' => false,
);
if ( isset( $plugins[ self::JETPACK_CRM_PLUGIN_SLUG ] ) ) {
$response['crm_installed'] = true;
$crm_data = $plugins[ self::JETPACK_CRM_PLUGIN_SLUG ];
$response['crm_active'] = $crm_data['active'];
$response['crm_version'] = $crm_data['Version'];
if ( $response['crm_active'] ) {
if ( function_exists( 'zeroBSCRM_isExtensionInstalled' ) ) {
$response['jp_form_ext_enabled'] = zeroBSCRM_isExtensionInstalled( 'jetpackforms' );
}
}
}
$response['can_install_crm'] = $response['crm_installed'] ? false : current_user_can( 'install_plugins' );
$response['can_activate_crm'] = $response['crm_active'] ? false : current_user_can( 'activate_plugins' );
if ( $response['crm_active'] && function_exists( 'zeroBSCRM_extension_install_jetpackforms' ) ) {
// phpcs:ignore WordPress.WP.Capabilities.Unknown
$response['can_activate_extension'] = current_user_can( 'admin_zerobs_manage_options' );
}
return $response;
}
/**
* Activates Jetpack CRM's Jetpack Forms extension. This is used by a button in the Jetpack Contact Form
* sidebar menu.
*
* @return true|WP_Error Returns true if activation is success, else returns a WP_Error object.
*/
public function activate_crm_jetpackforms_extension() {
if ( function_exists( 'zeroBSCRM_extension_install_jetpackforms' ) ) {
return zeroBSCRM_extension_install_jetpackforms();
}
return new WP_Error( 'jp_forms_extension_activation_failed', esc_html__( 'The Jetpack Forms extension could not be activated.', 'jetpack' ) );
}
}
@@ -0,0 +1,146 @@
<?php
/**
* Special cases for overriding modules.
*
* @package automattic/jetpack
*/
/**
* Provides methods for dealing with module overrides.
*
* @since 5.9.0
*/
class Jetpack_Modules_Overrides {
/**
* Used to cache module overrides so that we minimize how many times we apply the
* option_jetpack_active_modules filter.
*
* @var null|array
*/
private $overrides = null;
/**
* Clears the $overrides member used for caching.
*
* Since get_overrides() can be passed a falsey value to skip caching, this is probably
* most useful for clearing cache between tests.
*
* @return void
*/
public function clear_cache() {
$this->overrides = null;
}
/**
* Returns true if there is a filter on the jetpack_active_modules option.
*
* @return bool Whether there is a filter on the jetpack_active_modules option.
*/
public function do_overrides_exist() {
return (bool) ( has_filter( 'option_jetpack_active_modules' ) || has_filter( 'jetpack_active_modules' ) );
}
/**
* Gets the override for a given module.
*
* @param string $module_slug The module's slug.
* @param boolean $use_cache Whether or not cached overrides should be used.
*
* @return bool|string False if no override for module. 'active' or 'inactive' if there is an override.
*/
public function get_module_override( $module_slug, $use_cache = true ) {
$overrides = $this->get_overrides( $use_cache );
if ( ! isset( $overrides[ $module_slug ] ) ) {
return false;
}
return $overrides[ $module_slug ];
}
/**
* Returns an array of module overrides where the key is the module slug and the value
* is true if the module is forced on and false if the module is forced off.
*
* @param bool $use_cache Whether or not cached overrides should be used.
*
* @return array The array of module overrides.
*/
public function get_overrides( $use_cache = true ) {
if ( $use_cache && $this->overrides !== null ) {
return $this->overrides;
}
if ( ! $this->do_overrides_exist() ) {
return array();
}
$available_modules = Jetpack::get_available_modules();
/**
* First, let's get all modules that have been forced on.
*/
/** This filter is documented in wp-includes/option.php */
$filtered = apply_filters( 'option_jetpack_active_modules', array() );
/** This filter is documented in class.jetpack.php */
$filtered = apply_filters( 'jetpack_active_modules', $filtered );
$forced_on = array_diff( $filtered, array() );
/**
* Second, let's get all modules forced off.
*/
/** This filter is documented in wp-includes/option.php */
$filtered = apply_filters( 'option_jetpack_active_modules', $available_modules );
/** This filter is documented in class.jetpack.php */
$filtered = apply_filters( 'jetpack_active_modules', $filtered );
$forced_off = array_diff( $available_modules, $filtered );
/**
* Last, build the return value.
*/
$return_value = array();
foreach ( $forced_on as $on ) {
$return_value[ $on ] = 'active';
}
foreach ( $forced_off as $off ) {
$return_value[ $off ] = 'inactive';
}
$this->overrides = $return_value;
return $return_value;
}
/**
* A reference to an instance of this class.
*
* @var Jetpack_Modules_Overrides
*/
private static $instance = null;
/**
* Returns the singleton instance of Jetpack_Modules_Overrides
*
* @return Jetpack_Modules_Overrides
*/
public static function instance() {
if ( self::$instance === null ) {
self::$instance = new Jetpack_Modules_Overrides();
}
return self::$instance;
}
/**
* Private construct to enforce singleton.
*/
private function __construct() {
}
}
@@ -0,0 +1,236 @@
<?php
/**
* Tracks class.
*
* @package automattic/jetpack
*/
namespace Automattic\Jetpack\Plugin;
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
use Automattic\Jetpack\Tracking as Tracks;
use IXR_Error;
use WP_Error;
use WP_User;
/**
* Tracks class.
*/
class Tracking {
/**
* Tracking object.
*
* @var Tracks
*
* @access private
*/
private $tracking;
/**
* Prevents the Tracking from being initialized more than once.
*
* @var bool
*/
private static $initialized = false;
/**
* Initialization function.
*/
public function init() {
if ( static::$initialized ) {
return;
}
static::$initialized = true;
$this->tracking = new Tracks( 'jetpack' );
// For tracking stuff via js/ajax.
add_action( 'admin_enqueue_scripts', array( $this->tracking, 'enqueue_tracks_scripts' ) );
add_action( 'jetpack_activate_module', array( $this, 'jetpack_activate_module' ), 1, 1 );
add_action( 'jetpack_deactivate_module', array( $this, 'jetpack_deactivate_module' ), 1, 1 );
add_action( 'jetpack_user_authorized', array( $this, 'jetpack_user_authorized' ) );
// Tracking XMLRPC server events.
add_action( 'jetpack_xmlrpc_server_event', array( $this, 'jetpack_xmlrpc_server_event' ), 10, 4 );
// Track that we've begun verifying the previously generated secret.
add_action( 'jetpack_verify_secrets_begin', array( $this, 'jetpack_verify_secrets_begin' ), 10, 2 );
add_action( 'jetpack_verify_secrets_success', array( $this, 'jetpack_verify_secrets_success' ), 10, 2 );
add_action( 'jetpack_verify_secrets_fail', array( $this, 'jetpack_verify_secrets_fail' ), 10, 3 );
add_action( 'jetpack_verify_api_authorization_request_error_double_encode', array( $this, 'jetpack_verify_api_authorization_request_error_double_encode' ) );
add_action( 'jetpack_connection_register_fail', array( $this, 'jetpack_connection_register_fail' ), 10, 2 );
add_action( 'jetpack_connection_register_success', array( $this, 'jetpack_connection_register_success' ) );
}
/**
* Track that a specific module has been activated.
*
* @access public
*
* @param string $module Module slug.
*/
public function jetpack_activate_module( $module ) {
$this->tracking->record_user_event( 'module_activated', array( 'module' => $module ) );
}
/**
* Track that a specific module has been deactivated.
*
* @access public
*
* @param string $module Module slug.
*/
public function jetpack_deactivate_module( $module ) {
$this->tracking->record_user_event( 'module_deactivated', array( 'module' => $module ) );
}
/**
* Track that the user has successfully received an auth token.
*
* @access public
*/
public function jetpack_user_authorized() {
$user_id = get_current_user_id();
$anon_id = get_user_meta( $user_id, 'jetpack_tracks_anon_id', true );
if ( $anon_id ) {
$this->tracking->record_user_event( '_aliasUser', array( 'anonId' => $anon_id ) );
delete_user_meta( $user_id, 'jetpack_tracks_anon_id' );
if ( ! headers_sent() ) {
setcookie( 'tk_ai', 'expired', time() - 1000, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), false ); // phpcs:ignore Jetpack.Functions.SetCookie -- Want this accessible.
}
}
$connection_manager = new Connection_Manager();
$wpcom_user_data = $connection_manager->get_connected_user_data( $user_id );
if ( isset( $wpcom_user_data['ID'] ) ) {
update_user_meta( $user_id, 'jetpack_tracks_wpcom_id', $wpcom_user_data['ID'] );
}
$this->tracking->record_user_event( 'wpa_user_linked', array() );
}
/**
* Track that we've begun verifying the secrets.
*
* @access public
*
* @param string $action Type of secret (one of 'register', 'authorize', 'publicize').
* @param WP_User $user The user object.
*/
public function jetpack_verify_secrets_begin( $action, $user ) {
$this->tracking->record_user_event( "jpc_verify_{$action}_begin", array(), $user );
}
/**
* Track that we've succeeded in verifying the secrets.
*
* @access public
*
* @param string $action Type of secret (one of 'register', 'authorize', 'publicize').
* @param WP_User $user The user object.
*/
public function jetpack_verify_secrets_success( $action, $user ) {
$this->tracking->record_user_event( "jpc_verify_{$action}_success", array(), $user );
}
/**
* Track that we've failed verifying the secrets.
*
* @access public
*
* @param string $action Type of secret (one of 'register', 'authorize', 'publicize').
* @param WP_User $user The user object.
* @param WP_Error $error Error object.
*/
public function jetpack_verify_secrets_fail( $action, $user, $error ) {
$this->tracking->record_user_event(
"jpc_verify_{$action}_fail",
array(
'error_code' => $error->get_error_code(),
'error_message' => $error->get_error_message(),
),
$user
);
}
/**
* Track a failed login attempt.
*
* @deprecated 13.9 Method is not longer in use.
*/
public function wp_login_failed() {
_deprecated_function( __METHOD__, '13.9' );
}
/**
* Track a connection failure at the registration step.
*
* @access public
*
* @param string|int $error The error code.
* @param WP_Error $registered The error object.
*/
public function jetpack_connection_register_fail( $error, $registered ) {
$this->tracking->record_user_event(
'jpc_register_fail',
array(
'error_code' => $error,
'error_message' => $registered->get_error_message(),
)
);
}
/**
* Track that the registration step of the connection has been successful.
*
* @access public
*
* @param string $from The 'from' GET parameter.
*/
public function jetpack_connection_register_success( $from ) {
$this->tracking->record_user_event(
'jpc_register_success',
array(
'from' => $from,
)
);
}
/**
* Handles the jetpack_xmlrpc_server_event action that combines several types of events that
* happen during request serving.
*
* @param String $action the action name, i.e., 'remote_authorize'.
* @param String $stage the execution stage, can be 'begin', 'success', 'error', etc.
* @param array|WP_Error|IXR_Error $parameters (optional) extra parameters to be passed to the tracked action.
* @param WP_User $user (optional) the acting user.
*/
public function jetpack_xmlrpc_server_event( $action, $stage, $parameters = array(), $user = null ) {
if ( is_wp_error( $parameters ) ) {
$parameters = array(
'error_code' => $parameters->get_error_code(),
'error_message' => $parameters->get_error_message(),
);
} elseif ( is_a( $parameters, IXR_Error::class ) ) {
$parameters = array(
'error_code' => $parameters->code,
'error_message' => $parameters->message,
);
}
$this->tracking->record_user_event( 'jpc_' . $action . '_' . $stage, $parameters, $user );
}
/**
* Track that the site is incorrectly double-encoding redirects from http to https.
*
* @access public
*/
public function jetpack_verify_api_authorization_request_error_double_encode() {
$this->tracking->record_user_event( 'error_double_encode' );
}
}