init
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility files for third-party plugins.
|
||||
* This is used to improve compatibility of specific Jetpack features with third-party plugins.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack;
|
||||
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
|
||||
add_action( 'plugins_loaded', __NAMESPACE__ . '\load_3rd_party_compat_filters', 11 );
|
||||
/**
|
||||
* Loads the individual 3rd-party compat functions.
|
||||
*
|
||||
* This is a refactor of load_3rd_party() to load the individual compat files only when needed instead of universally.
|
||||
*/
|
||||
function load_3rd_party_compat_filters() {
|
||||
|
||||
// bbPress
|
||||
if ( function_exists( 'bbpress' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/bbpress.php';
|
||||
}
|
||||
|
||||
// Beaver Builder
|
||||
if ( class_exists( 'FLBuilder' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/beaverbuilder.php';
|
||||
}
|
||||
|
||||
// Bitly
|
||||
if ( class_exists( 'Bitly' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/bitly.php';
|
||||
}
|
||||
|
||||
// BuddyPress
|
||||
if ( class_exists( 'BuddyPress' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/buddypress.php';
|
||||
}
|
||||
|
||||
// AMP. AMP__DIR__ is defined in the AMP plugin since the very first version.
|
||||
if ( Constants::is_defined( 'AMP__DIR__' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/amp.php';
|
||||
}
|
||||
|
||||
// Domain Mapping. All assume multisite, so it's an easy check.
|
||||
if ( Constants::is_defined( 'SUNRISE' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/class-domain-mapping.php';
|
||||
}
|
||||
|
||||
// Debug Bar
|
||||
if ( class_exists( 'Debug_Bar' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/debug-bar.php';
|
||||
}
|
||||
|
||||
// Letting these always load since it handles somethings upon plugin activation.
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/creative-mail.php';
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/jetpack-backup.php';
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/jetpack-boost.php';
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/woocommerce-services.php';
|
||||
|
||||
// qTranslate. Plugin closed in 2021, but leaving support for now to allow sites to drop it.
|
||||
if ( Constants::is_defined( 'QTX_VERSION' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/qtranslate-x.php';
|
||||
}
|
||||
|
||||
// VaultPress.
|
||||
if ( Constants::is_defined( 'VAULTPRESS__VERSION' ) || class_exists( 'VaultPress' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/vaultpress.php';
|
||||
}
|
||||
|
||||
// Web Stories
|
||||
if ( Constants::is_defined( 'WEBSTORIES_VERSION' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/web-stories.php';
|
||||
}
|
||||
|
||||
// WooCommerce
|
||||
if ( class_exists( 'WooCommerce' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/woocommerce.php';
|
||||
}
|
||||
|
||||
// Atomic Weekly
|
||||
if ( ( new Host() )->is_atomic_platform() ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/atomic.php';
|
||||
}
|
||||
|
||||
// WordPress.com Reader
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/wpcom-reader.php';
|
||||
|
||||
// WPML
|
||||
if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/wpml.php';
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* This file contains compatibility features for AMP to improve Jetpack feature support.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack;
|
||||
|
||||
/**
|
||||
* Load Jetpack_AMP_Support.
|
||||
*/
|
||||
function load_3rd_party_amp_support() {
|
||||
// Only load the support class when AMP actually initializes.
|
||||
// This avoids calls to some slow functions if the plugin is loaded but
|
||||
// 'amp_is_enabled' is used to prevent it from initializing.
|
||||
require_once JETPACK__PLUGIN_DIR . '/3rd-party/class.jetpack-amp-support.php';
|
||||
|
||||
add_action( 'init', array( 'Jetpack_AMP_Support', 'init' ), 1 );
|
||||
add_action( 'admin_init', array( 'Jetpack_AMP_Support', 'admin_init' ), 1 );
|
||||
}
|
||||
|
||||
add_action( 'amp_init', __NAMESPACE__ . '\load_3rd_party_amp_support' );
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper functions for the Atomic platform.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Third_Party;
|
||||
|
||||
use Automattic\Jetpack\Constants;
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
|
||||
/**
|
||||
* Handles suppressing development version notices on Atomic-hosted sites.
|
||||
*
|
||||
* @param bool $development_version Filterable value if this is a development version of Jetpack.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function atomic_weekly_override( $development_version ) {
|
||||
if ( ( new Host() )->is_atomic_platform() ) {
|
||||
$haystack = Constants::get_constant( 'JETPACK__PLUGIN_DIR' );
|
||||
$needle = '/jetpack-dev/';
|
||||
if ( str_ends_with( $haystack, $needle ) ) {
|
||||
return $development_version; // Returns the default response if the active Jetpack version is from the beta plugin.
|
||||
}
|
||||
|
||||
$development_version = false; // Returns false for regular installs on Atomic.
|
||||
}
|
||||
return $development_version; // Return default if not on Atomic.
|
||||
}
|
||||
|
||||
add_filter( 'jetpack_development_version', __NAMESPACE__ . '\atomic_weekly_override' );
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility functions for bbpress.
|
||||
*
|
||||
* Only added if bbpress is active via function_exists( 'bbpress' ) in 3rd-party.php.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Image_CDN\Image_CDN;
|
||||
|
||||
// Priority 11 needed to ensure sharing_display is loaded.
|
||||
add_action( 'init', 'jetpack_bbpress_compat', 11 );
|
||||
|
||||
/**
|
||||
* Adds Jetpack + bbPress Compatibility filters.
|
||||
*
|
||||
* @author Brandon Kraft
|
||||
* @since 3.7.1
|
||||
*/
|
||||
function jetpack_bbpress_compat() {
|
||||
/**
|
||||
* Add compatibility layer for REST API.
|
||||
*
|
||||
* @since 8.5.0 Moved from root-level file and check_rest_api_compat()
|
||||
*/
|
||||
require_once __DIR__ . '/class-jetpack-bbpress-rest-api.php';
|
||||
Jetpack_BbPress_REST_API::instance();
|
||||
|
||||
// Adds sharing buttons to bbPress items.
|
||||
if ( function_exists( 'sharing_display' ) ) {
|
||||
add_filter( 'bbp_get_topic_content', 'sharing_display', 19 );
|
||||
add_action( 'bbp_template_after_single_forum', 'jetpack_sharing_bbpress' );
|
||||
add_action( 'bbp_template_after_single_topic', 'jetpack_sharing_bbpress' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable Markdown support for bbpress post types.
|
||||
*
|
||||
* @author Brandon Kraft
|
||||
* @since 6.0.0
|
||||
*/
|
||||
if ( function_exists( 'bbp_get_topic_post_type' ) ) {
|
||||
add_post_type_support( bbp_get_topic_post_type(), 'wpcom-markdown' );
|
||||
add_post_type_support( bbp_get_reply_post_type(), 'wpcom-markdown' );
|
||||
add_post_type_support( bbp_get_forum_post_type(), 'wpcom-markdown' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Use Photon for all images in Topics and replies.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*/
|
||||
if ( class_exists( Image_CDN::class ) && Image_CDN::is_enabled() ) {
|
||||
add_filter( 'bbp_get_topic_content', array( Image_CDN::class, 'filter_the_content' ), 999999 );
|
||||
add_filter( 'bbp_get_reply_content', array( Image_CDN::class, 'filter_the_content' ), 999999 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Jetpack "Sharing" buttons on bbPress 2.x forums/ topics/ lead topics/ replies.
|
||||
*
|
||||
* Determination if the sharing buttons should display on the post type is handled within sharing_display().
|
||||
*
|
||||
* @author David Decker
|
||||
* @since 3.7.0
|
||||
*/
|
||||
function jetpack_sharing_bbpress() {
|
||||
sharing_display( null, true );
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Beaverbuilder Compatibility.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Third_Party;
|
||||
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
|
||||
add_action( 'init', __NAMESPACE__ . '\beaverbuilder_refresh' );
|
||||
|
||||
/**
|
||||
* If masterbar module is active force BeaverBuilder to refresh when publishing a layout.
|
||||
*/
|
||||
function beaverbuilder_refresh() {
|
||||
if ( ( new Host() )->is_woa_site() ) {
|
||||
add_filter( 'fl_builder_should_refresh_on_publish', '__return_true' );
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Fixes issues with the Official Bitly for WordPress
|
||||
* https://wordpress.org/plugins/bitly/
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
if ( isset( $GLOBALS['bitly'] ) ) {
|
||||
if ( method_exists( $GLOBALS['bitly'], 'og_tags' ) ) {
|
||||
remove_action( 'wp_head', array( $GLOBALS['bitly'], 'og_tags' ) );
|
||||
}
|
||||
add_action( 'wp_head', 'jetpack_bitly_og_tag', 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds bitly OG tags.
|
||||
*/
|
||||
function jetpack_bitly_og_tag() {
|
||||
if ( has_filter( 'wp_head', 'jetpack_og_tags' ) === false ) {
|
||||
// Add the bitly part again back if we don't have any jetpack_og_tags added.
|
||||
if ( method_exists( $GLOBALS['bitly'], 'og_tags' ) ) {
|
||||
$GLOBALS['bitly']->og_tags();
|
||||
}
|
||||
} elseif (
|
||||
isset( $GLOBALS['posts'] )
|
||||
&& $GLOBALS['posts'][0]->ID > 0
|
||||
&& method_exists( $GLOBALS['bitly'], 'get_bitly_link_for_post_id' )
|
||||
) {
|
||||
printf(
|
||||
"<meta property=\"bitly:url\" content=\"%s\" /> \n",
|
||||
esc_attr( $GLOBALS['bitly']->get_bitly_link_for_post_id( $GLOBALS['posts'][0]->ID ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* 3rd Party Integration for BuddyPress.
|
||||
*
|
||||
* @package automattic/jetpack.
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Third_Party;
|
||||
|
||||
add_filter( 'bp_core_pre_avatar_handle_upload', __NAMESPACE__ . '\blobphoto' );
|
||||
|
||||
/**
|
||||
* Adds filters for skipping photon during pre_avatar_handle_upload.
|
||||
*
|
||||
* @param bool $bool Passthrough of filter's original content. No changes made.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function blobphoto( $bool ) {
|
||||
add_filter( 'jetpack_photon_skip_image', '__return_true' );
|
||||
|
||||
return $bool;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* Domain Mapping 3rd Party
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Third_Party;
|
||||
|
||||
use Automattic\Jetpack\Constants;
|
||||
|
||||
/**
|
||||
* Class Automattic\Jetpack\Third_Party\Domain_Mapping.
|
||||
*
|
||||
* This class contains methods that are used to provide compatibility between Jetpack sync and domain mapping plugins.
|
||||
*/
|
||||
class Domain_Mapping {
|
||||
|
||||
/**
|
||||
* Singleton holder.
|
||||
*
|
||||
* @var Domain_Mapping
|
||||
**/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* An array of methods that are used to hook the Jetpack sync filters for home_url and site_url to a mapping plugin.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $test_methods = array(
|
||||
'hook_wordpress_mu_domain_mapping',
|
||||
'hook_wpmu_dev_domain_mapping',
|
||||
);
|
||||
|
||||
/**
|
||||
* Singleton constructor.
|
||||
*
|
||||
* @return Domain_Mapping|null
|
||||
*/
|
||||
public static function init() {
|
||||
if ( self::$instance === null ) {
|
||||
self::$instance = new Domain_Mapping();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Automattic\Jetpack\Third_Party\Domain_Mapping constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
add_action( 'plugins_loaded', array( $this, 'attempt_to_hook_domain_mapping_plugins' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called on the plugins_loaded action and will loop through the $test_methods
|
||||
* to try and hook a domain mapping plugin to the Jetpack sync filters for the home_url and site_url callables.
|
||||
*/
|
||||
public function attempt_to_hook_domain_mapping_plugins() {
|
||||
if ( ! Constants::is_defined( 'SUNRISE' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hooked = false;
|
||||
$count = count( self::$test_methods );
|
||||
for ( $i = 0; $i < $count && ! $hooked; $i++ ) {
|
||||
$hooked = call_user_func( array( $this, self::$test_methods[ $i ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will test for a constant and function that are known to be used with Donncha's WordPress MU
|
||||
* Domain Mapping plugin. If conditions are met, we hook the domain_mapping_siteurl() function to Jetpack sync
|
||||
* filters for home_url and site_url callables.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hook_wordpress_mu_domain_mapping() {
|
||||
if ( ! Constants::is_defined( 'SUNRISE_LOADED' ) || ! $this->function_exists( 'domain_mapping_siteurl' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
add_filter( 'jetpack_sync_home_url', 'domain_mapping_siteurl' );
|
||||
add_filter( 'jetpack_sync_site_url', 'domain_mapping_siteurl' );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will test for a class and method known to be used in WPMU Dev's domain mapping plugin. If the
|
||||
* method exists, then we'll hook the swap_to_mapped_url() to our Jetpack sync filters for home_url and site_url.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hook_wpmu_dev_domain_mapping() {
|
||||
if ( ! $this->class_exists( 'domain_map' ) || ! $this->method_exists( 'domain_map', 'utils' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$utils = $this->get_domain_mapping_utils_instance();
|
||||
add_filter( 'jetpack_sync_home_url', array( $utils, 'swap_to_mapped_url' ) );
|
||||
add_filter( 'jetpack_sync_site_url', array( $utils, 'swap_to_mapped_url' ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility Methods
|
||||
*
|
||||
* These methods are very minimal, and in most cases, simply pass on arguments. Why create them you ask?
|
||||
* So that we can test.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if a method exists.
|
||||
*
|
||||
* @param string $class Class name.
|
||||
* @param string $method Method name.
|
||||
*
|
||||
* @return bool Returns function_exists() without modification.
|
||||
*/
|
||||
public function method_exists( $class, $method ) {
|
||||
return method_exists( $class, $method );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a class exists.
|
||||
*
|
||||
* @param string $class Class name.
|
||||
*
|
||||
* @return bool Returns class_exists() without modification.
|
||||
*/
|
||||
public function class_exists( $class ) {
|
||||
return class_exists( $class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a function exists.
|
||||
*
|
||||
* @param string $function Function name.
|
||||
*
|
||||
* @return bool Returns function_exists() without modification.
|
||||
*/
|
||||
public function function_exists( $function ) {
|
||||
return function_exists( $function );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Domain_Map::utils() instance.
|
||||
*
|
||||
* @see https://github.com/wpmudev/domain-mapping/blob/master/classes/Domainmap/Utils.php
|
||||
* @return \Domainmap_Utils
|
||||
*/
|
||||
public function get_domain_mapping_utils_instance() {
|
||||
return \domain_map::utils();
|
||||
}
|
||||
}
|
||||
|
||||
Domain_Mapping::init();
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* REST API Compatibility: bbPress & Jetpack
|
||||
* Enables bbPress to work with the Jetpack REST API
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* REST API Compatibility: bbPress.
|
||||
*/
|
||||
class Jetpack_BbPress_REST_API {
|
||||
|
||||
/**
|
||||
* Singleton
|
||||
*
|
||||
* @var Jetpack_BbPress_REST_API
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* Returns or creates the singleton.
|
||||
*
|
||||
* @return Jetpack_BbPress_REST_API
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( isset( self::$instance ) ) {
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Jetpack_BbPress_REST_API constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
add_filter( 'rest_api_allowed_post_types', array( $this, 'allow_bbpress_post_types' ) );
|
||||
add_filter( 'bbp_map_meta_caps', array( $this, 'adjust_meta_caps' ), 10, 4 );
|
||||
add_filter( 'rest_api_allowed_public_metadata', array( $this, 'allow_bbpress_public_metadata' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the bbPress post types to the rest_api_allowed_post_types filter.
|
||||
*
|
||||
* @param array $allowed_post_types Allowed post types.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function allow_bbpress_post_types( $allowed_post_types ) {
|
||||
$allowed_post_types[] = 'forum';
|
||||
$allowed_post_types[] = 'topic';
|
||||
$allowed_post_types[] = 'reply';
|
||||
return $allowed_post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the bbpress meta keys to the rest_api_allowed_public_metadata filter.
|
||||
*
|
||||
* @param array $allowed_meta_keys Allowed meta keys.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function allow_bbpress_public_metadata( $allowed_meta_keys ) {
|
||||
$allowed_meta_keys[] = '_bbp_forum_id';
|
||||
$allowed_meta_keys[] = '_bbp_topic_id';
|
||||
$allowed_meta_keys[] = '_bbp_status';
|
||||
$allowed_meta_keys[] = '_bbp_forum_type';
|
||||
$allowed_meta_keys[] = '_bbp_forum_subforum_count';
|
||||
$allowed_meta_keys[] = '_bbp_reply_count';
|
||||
$allowed_meta_keys[] = '_bbp_total_reply_count';
|
||||
$allowed_meta_keys[] = '_bbp_topic_count';
|
||||
$allowed_meta_keys[] = '_bbp_total_topic_count';
|
||||
$allowed_meta_keys[] = '_bbp_topic_count_hidden';
|
||||
$allowed_meta_keys[] = '_bbp_last_topic_id';
|
||||
$allowed_meta_keys[] = '_bbp_last_reply_id';
|
||||
$allowed_meta_keys[] = '_bbp_last_active_time';
|
||||
$allowed_meta_keys[] = '_bbp_last_active_id';
|
||||
$allowed_meta_keys[] = '_bbp_sticky_topics';
|
||||
$allowed_meta_keys[] = '_bbp_voice_count';
|
||||
$allowed_meta_keys[] = '_bbp_reply_count_hidden';
|
||||
$allowed_meta_keys[] = '_bbp_anonymous_reply_count';
|
||||
|
||||
return $allowed_meta_keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the needed caps to the bbp_map_meta_caps filter.
|
||||
*
|
||||
* @param array $caps Capabilities for meta capability.
|
||||
* @param string $cap Capability name.
|
||||
* @param int $user_id User id.
|
||||
* @param array $args Arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function adjust_meta_caps( $caps, $cap, $user_id, $args ) {
|
||||
|
||||
// Return early if not a REST request or if not meta bbPress caps.
|
||||
if ( $this->should_adjust_meta_caps_return_early( $caps, $cap, $user_id, $args ) ) {
|
||||
return $caps;
|
||||
}
|
||||
|
||||
// $args[0] could be a post ID or a post_type string.
|
||||
if ( is_int( $args[0] ) ) {
|
||||
$_post = get_post( $args[0] );
|
||||
if ( ! empty( $_post ) ) {
|
||||
$post_type = get_post_type_object( $_post->post_type );
|
||||
}
|
||||
} elseif ( is_string( $args[0] ) ) {
|
||||
$post_type = get_post_type_object( $args[0] );
|
||||
}
|
||||
|
||||
// no post type found, bail.
|
||||
if ( empty( $post_type ) ) {
|
||||
return $caps;
|
||||
}
|
||||
|
||||
// reset the needed caps.
|
||||
$caps = array();
|
||||
|
||||
// Add 'do_not_allow' cap if user is spam or deleted.
|
||||
if ( bbp_is_user_inactive( $user_id ) ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
|
||||
// Moderators can always edit meta.
|
||||
} elseif ( user_can( $user_id, 'moderate' ) ) { // phpcs:ignore WordPress.WP.Capabilities.Unknown
|
||||
$caps[] = 'moderate';
|
||||
|
||||
// Unknown so map to edit_posts.
|
||||
} else {
|
||||
$caps[] = $post_type->cap->edit_posts;
|
||||
}
|
||||
|
||||
return $caps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should adjust_meta_caps return early?
|
||||
*
|
||||
* @param array $caps Capabilities for meta capability.
|
||||
* @param string $cap Capability name.
|
||||
* @param int $user_id User id.
|
||||
* @param array $args Arguments.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function should_adjust_meta_caps_return_early( $caps, $cap, $user_id, $args ) {
|
||||
// only run for REST API requests.
|
||||
if ( ! defined( 'REST_API_REQUEST' ) || ! REST_API_REQUEST ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// only modify caps for meta caps and for bbPress meta keys.
|
||||
if ( ! in_array( $cap, array( 'edit_post_meta', 'delete_post_meta', 'add_post_meta' ), true ) || empty( $args[1] ) || ! str_contains( $args[1], '_bbp_' ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
<?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
|
||||
|
||||
use Automattic\Jetpack\Assets;
|
||||
use Automattic\Jetpack\Stats\Tracking_Pixel as Stats_Tracking_Pixel;
|
||||
use Automattic\Jetpack\Sync\Functions;
|
||||
|
||||
/**
|
||||
* Manages compatibility with the amp-wp plugin
|
||||
*
|
||||
* @see https://github.com/Automattic/amp-wp
|
||||
*/
|
||||
class Jetpack_AMP_Support {
|
||||
|
||||
/**
|
||||
* Apply custom AMP changes on the front-end.
|
||||
*/
|
||||
public static function init() {
|
||||
|
||||
// Add Stats tracking pixel on Jetpack sites when the Stats module is active.
|
||||
if (
|
||||
Jetpack::is_module_active( 'stats' )
|
||||
&& ! ( defined( 'IS_WPCOM' ) && IS_WPCOM )
|
||||
) {
|
||||
add_action( 'amp_post_template_footer', array( 'Jetpack_AMP_Support', 'add_stats_pixel' ) );
|
||||
}
|
||||
|
||||
// Sharing.
|
||||
add_filter( 'jetpack_sharing_display_markup', array( 'Jetpack_AMP_Support', 'render_sharing_html' ), 10, 2 );
|
||||
add_filter( 'sharing_enqueue_scripts', array( 'Jetpack_AMP_Support', 'amp_disable_sharedaddy_css' ) );
|
||||
add_action( 'wp_enqueue_scripts', array( 'Jetpack_AMP_Support', 'amp_enqueue_sharing_css' ) );
|
||||
|
||||
// Sharing for Reader mode.
|
||||
if ( function_exists( 'jetpack_social_menu_include_svg_icons' ) ) {
|
||||
add_action( 'amp_post_template_footer', 'jetpack_social_menu_include_svg_icons' );
|
||||
}
|
||||
add_action( 'amp_post_template_css', array( 'Jetpack_AMP_Support', 'amp_reader_sharing_css' ), 10, 0 );
|
||||
|
||||
// enforce freedom mode for videopress.
|
||||
add_filter( 'videopress_shortcode_options', array( 'Jetpack_AMP_Support', 'videopress_enable_freedom_mode' ) );
|
||||
|
||||
// include Jetpack og tags when rendering native AMP head.
|
||||
add_action( 'amp_post_template_head', array( 'Jetpack_AMP_Support', 'amp_post_jetpack_og_tags' ) );
|
||||
|
||||
// Post rendering changes for legacy AMP.
|
||||
add_action( 'pre_amp_render_post', array( 'Jetpack_AMP_Support', 'amp_disable_the_content_filters' ) );
|
||||
|
||||
// Disable Comment Likes.
|
||||
add_filter( 'jetpack_comment_likes_enabled', array( 'Jetpack_AMP_Support', 'comment_likes_enabled' ) );
|
||||
|
||||
// Transitional mode AMP should not have comment likes.
|
||||
add_filter( 'the_content', array( 'Jetpack_AMP_Support', 'disable_comment_likes_before_the_content' ) );
|
||||
|
||||
// Add post template metadata for legacy AMP.
|
||||
add_filter( 'amp_post_template_metadata', array( 'Jetpack_AMP_Support', 'amp_post_template_metadata' ), 10, 2 );
|
||||
|
||||
// Filter photon image args for AMP Stories.
|
||||
add_filter( 'jetpack_photon_post_image_args', array( 'Jetpack_AMP_Support', 'filter_photon_post_image_args_for_stories' ), 10, 2 );
|
||||
|
||||
// Sync the amp-options.
|
||||
add_filter( 'jetpack_options_whitelist', array( 'Jetpack_AMP_Support', 'filter_jetpack_options_safelist' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the Comment Likes feature on AMP views.
|
||||
*
|
||||
* @param bool $enabled Should comment likes be enabled.
|
||||
*/
|
||||
public static function comment_likes_enabled( $enabled ) {
|
||||
return $enabled && ! self::is_amp_request();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply custom AMP changes in wp-admin.
|
||||
*/
|
||||
public static function admin_init() {
|
||||
// disable Likes metabox for post editor if AMP canonical disabled.
|
||||
add_filter( 'post_flair_disable', array( 'Jetpack_AMP_Support', 'is_amp_canonical' ), 99 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the page in AMP 'canonical mode'.
|
||||
* Used when themes register support for AMP with `add_theme_support( 'amp' )`.
|
||||
*
|
||||
* @return bool is_amp_canonical
|
||||
*/
|
||||
public static function is_amp_canonical() {
|
||||
return function_exists( 'amp_is_canonical' ) && amp_is_canonical();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is AMP available for this request
|
||||
* This returns false for admin, CLI requests etc.
|
||||
*
|
||||
* @return bool is_amp_available
|
||||
*/
|
||||
public static function is_amp_available() {
|
||||
return ( function_exists( 'amp_is_available' ) && amp_is_available() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the page return AMP content.
|
||||
*
|
||||
* @return bool $is_amp_request Are we on am AMP view.
|
||||
*/
|
||||
public static function is_amp_request() {
|
||||
$is_amp_request = ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() );
|
||||
|
||||
/**
|
||||
* Returns true if the current request should return valid AMP content.
|
||||
*
|
||||
* @since 6.2.0
|
||||
*
|
||||
* @param boolean $is_amp_request Is this request supposed to return valid AMP content?
|
||||
*/
|
||||
return apply_filters( 'jetpack_is_amp_request', $is_amp_request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the legacy AMP post templates are being used.
|
||||
*
|
||||
* @since 10.6.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_amp_legacy() {
|
||||
return ( function_exists( 'amp_is_legacy' ) && amp_is_legacy() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove content filters added by Jetpack.
|
||||
*/
|
||||
public static function amp_disable_the_content_filters() {
|
||||
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
||||
add_filter( 'protected_embeds_use_form_post', '__return_false' );
|
||||
remove_filter( 'the_title', 'widont' );
|
||||
}
|
||||
|
||||
remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'filter' ), 11 );
|
||||
remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'maybe_create_links' ), 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not add comment likes on AMP requests.
|
||||
*
|
||||
* @param string $content Post content.
|
||||
*/
|
||||
public static function disable_comment_likes_before_the_content( $content ) {
|
||||
if ( self::is_amp_request() ) {
|
||||
remove_filter( 'comment_text', 'comment_like_button', 12 );
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Jetpack stats pixel.
|
||||
*
|
||||
* @since 6.2.1
|
||||
*/
|
||||
public static function add_stats_pixel() {
|
||||
if ( ! has_action( 'wp_footer', array( Stats_Tracking_Pixel::class, 'add_amp_pixel' ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$stats_data = Stats_Tracking_Pixel::build_view_data();
|
||||
Stats_Tracking_Pixel::render_amp_footer( $stats_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add publisher and image metadata to legacy AMP post.
|
||||
*
|
||||
* @since 6.2.0
|
||||
*
|
||||
* @param array $metadata Metadata array.
|
||||
* @param WP_Post $post Post.
|
||||
* @return array Modified metadata array.
|
||||
*/
|
||||
public static function amp_post_template_metadata( $metadata, $post ) {
|
||||
if ( isset( $metadata['publisher'] ) && ! isset( $metadata['publisher']['logo'] ) ) {
|
||||
$metadata = self::add_site_icon_to_metadata( $metadata );
|
||||
}
|
||||
|
||||
if ( ! isset( $metadata['image'] ) && ! empty( $post ) ) {
|
||||
$metadata = self::add_image_to_metadata( $metadata, $post );
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add blavatar to legacy AMP post metadata.
|
||||
*
|
||||
* @since 6.2.0
|
||||
*
|
||||
* @param array $metadata Metadata.
|
||||
*
|
||||
* @return array Metadata.
|
||||
*/
|
||||
private static function add_site_icon_to_metadata( $metadata ) {
|
||||
$size = 60;
|
||||
$site_icon_url = class_exists( 'Automattic\\Jetpack\\Sync\\Functions' ) ? Functions::site_icon_url( $size ) : '';
|
||||
|
||||
if ( function_exists( 'blavatar_domain' ) ) {
|
||||
$metadata['publisher']['logo'] = array(
|
||||
'@type' => 'ImageObject',
|
||||
'url' => blavatar_url( blavatar_domain( site_url() ), 'img', $size, self::staticize_subdomain( 'https://wordpress.com/i/favicons/apple-touch-icon-60x60.png' ) ),
|
||||
'width' => $size,
|
||||
'height' => $size,
|
||||
);
|
||||
} elseif ( $site_icon_url ) {
|
||||
$metadata['publisher']['logo'] = array(
|
||||
'@type' => 'ImageObject',
|
||||
'url' => $site_icon_url,
|
||||
'width' => $size,
|
||||
'height' => $size,
|
||||
);
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add image to legacy AMP post metadata.
|
||||
*
|
||||
* @since 6.2.0
|
||||
*
|
||||
* @param array $metadata Metadata.
|
||||
* @param WP_Post $post Post.
|
||||
* @return array Metadata.
|
||||
*/
|
||||
private static function add_image_to_metadata( $metadata, $post ) {
|
||||
$image = Jetpack_PostImages::get_image(
|
||||
$post->ID,
|
||||
array(
|
||||
'fallback_to_avatars' => true,
|
||||
'avatar_size' => 200,
|
||||
// AMP already attempts these.
|
||||
'from_thumbnail' => false,
|
||||
'from_attachment' => false,
|
||||
)
|
||||
);
|
||||
|
||||
if ( empty( $image ) ) {
|
||||
return self::add_fallback_image_to_metadata( $metadata );
|
||||
}
|
||||
|
||||
if ( ! isset( $image['src_width'] ) ) {
|
||||
$dimensions = self::extract_image_dimensions_from_getimagesize(
|
||||
array(
|
||||
$image['src'] => false,
|
||||
)
|
||||
);
|
||||
|
||||
if ( false !== $dimensions[ $image['src'] ] ) {
|
||||
$image['src_width'] = $dimensions['width'];
|
||||
$image['src_height'] = $dimensions['height'];
|
||||
}
|
||||
}
|
||||
|
||||
$metadata['image'] = array(
|
||||
'@type' => 'ImageObject',
|
||||
'url' => $image['src'],
|
||||
);
|
||||
if ( isset( $image['src_width'] ) ) {
|
||||
$metadata['image']['width'] = $image['src_width'];
|
||||
}
|
||||
if ( isset( $image['src_width'] ) ) {
|
||||
$metadata['image']['height'] = $image['src_height'];
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add fallback image to legacy AMP post metadata.
|
||||
*
|
||||
* @since 6.2.0
|
||||
*
|
||||
* @param array $metadata Metadata.
|
||||
* @return array Metadata.
|
||||
*/
|
||||
private static function add_fallback_image_to_metadata( $metadata ) {
|
||||
/** This filter is documented in functions.opengraph.php */
|
||||
$default_image = apply_filters( 'jetpack_open_graph_image_default', 'https://wordpress.com/i/blank.jpg' );
|
||||
|
||||
$metadata['image'] = array(
|
||||
'@type' => 'ImageObject',
|
||||
'url' => self::staticize_subdomain( $default_image ),
|
||||
'width' => 200,
|
||||
'height' => 200,
|
||||
);
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return static WordPress.com domain to use to load resources from WordPress.com.
|
||||
*
|
||||
* @param string $domain Asset URL.
|
||||
*/
|
||||
private static function staticize_subdomain( $domain ) {
|
||||
// deal with WPCOM vs Jetpack.
|
||||
if ( function_exists( 'staticize_subdomain' ) ) {
|
||||
return staticize_subdomain( $domain );
|
||||
} else {
|
||||
return Assets::staticize_subdomain( $domain );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract image dimensions via wpcom/imagesize, only on WPCOM
|
||||
*
|
||||
* @since 6.2.0
|
||||
*
|
||||
* @param array $dimensions Dimensions.
|
||||
* @return array Dimensions.
|
||||
*/
|
||||
private static function extract_image_dimensions_from_getimagesize( $dimensions ) {
|
||||
if ( ! ( defined( 'IS_WPCOM' ) && IS_WPCOM && function_exists( 'require_lib' ) ) ) {
|
||||
return $dimensions;
|
||||
}
|
||||
require_lib( 'wpcom/imagesize' );
|
||||
|
||||
foreach ( $dimensions as $url => $value ) {
|
||||
if ( is_array( $value ) ) {
|
||||
continue;
|
||||
}
|
||||
$result = wpcom_getimagesize( $url );
|
||||
if ( is_array( $result ) ) {
|
||||
$dimensions[ $url ] = array(
|
||||
'width' => $result[0],
|
||||
'height' => $result[1],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Open Graph Meta tags in AMP views.
|
||||
*/
|
||||
public static function amp_post_jetpack_og_tags() {
|
||||
if ( ! ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
|
||||
Jetpack::init()->check_open_graph();
|
||||
}
|
||||
|
||||
if ( function_exists( 'jetpack_og_tags' ) ) {
|
||||
jetpack_og_tags();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force Freedom mode in VideoPress.
|
||||
*
|
||||
* @param array $options Array of VideoPress shortcode options.
|
||||
*/
|
||||
public static function videopress_enable_freedom_mode( $options ) {
|
||||
if ( self::is_amp_request() ) {
|
||||
$options['freedom'] = true;
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display custom markup for the sharing buttons when in an AMP view.
|
||||
*
|
||||
* @param string $markup Content markup of the Jetpack sharing links.
|
||||
* @param array $sharing_enabled Array of Sharing Services currently enabled.
|
||||
*/
|
||||
public static function render_sharing_html( $markup, $sharing_enabled ) {
|
||||
global $post;
|
||||
|
||||
if ( empty( $post ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( ! self::is_amp_request() ) {
|
||||
return $markup;
|
||||
}
|
||||
|
||||
remove_action( 'wp_footer', 'sharing_add_footer' );
|
||||
if ( empty( $sharing_enabled ) ) {
|
||||
return $markup;
|
||||
}
|
||||
|
||||
$sharing_links = array();
|
||||
foreach ( $sharing_enabled['visible'] as $service ) {
|
||||
$sharing_link = $service->get_amp_display( $post );
|
||||
if ( ! empty( $sharing_link ) ) {
|
||||
$sharing_links[] = $sharing_link;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the existing unordered list with AMP sharing buttons.
|
||||
$markup = preg_replace( '#<ul>(.+)</ul>#', implode( '', $sharing_links ), $markup );
|
||||
|
||||
// Remove any lingering share-end list items.
|
||||
$markup = str_replace( '<li class="share-end"></li>', '', $markup );
|
||||
|
||||
return $markup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells Jetpack not to enqueue CSS for share buttons.
|
||||
*
|
||||
* @param bool $enqueue Whether or not to enqueue.
|
||||
* @return bool Whether or not to enqueue.
|
||||
*/
|
||||
public static function amp_disable_sharedaddy_css( $enqueue ) {
|
||||
if ( self::is_amp_request() ) {
|
||||
$enqueue = false;
|
||||
}
|
||||
|
||||
return $enqueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the AMP specific sharing styles for the sharing icons.
|
||||
*/
|
||||
public static function amp_enqueue_sharing_css() {
|
||||
if (
|
||||
Jetpack::is_module_active( 'sharedaddy' )
|
||||
&& self::is_amp_request()
|
||||
&& ! self::is_amp_legacy()
|
||||
) {
|
||||
wp_enqueue_style( 'sharedaddy-amp', plugin_dir_url( __DIR__ ) . 'modules/sharedaddy/amp-sharing.css', array( 'social-logos' ), JETPACK__VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For the AMP Reader mode template, include styles that we need.
|
||||
*/
|
||||
public static function amp_reader_sharing_css() {
|
||||
// If sharing is not enabled, we should not proceed to render the CSS.
|
||||
if ( ! defined( 'JETPACK_SOCIAL_LOGOS_DIR' ) || ! defined( 'JETPACK_SOCIAL_LOGOS_URL' ) || ! defined( 'WP_SHARING_PLUGIN_DIR' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We'll need to output the full contents of the 2 files
|
||||
* in the head on AMP views. We can't rely on regular enqueues here.
|
||||
* @todo As of AMP plugin v1.5, you can actually rely on regular enqueues thanks to https://github.com/ampproject/amp-wp/pull/4299. Once WPCOM upgrades AMP, then this method can be eliminated.
|
||||
*
|
||||
* phpcs:disable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
||||
* phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
*/
|
||||
$css = file_get_contents( JETPACK_SOCIAL_LOGOS_DIR . 'social-logos.css' );
|
||||
$css = preg_replace( '#(?<=url\(")(?=social-logos\.)#', JETPACK_SOCIAL_LOGOS_URL, $css ); // Make sure font files get their absolute paths.
|
||||
echo $css;
|
||||
echo file_get_contents( WP_SHARING_PLUGIN_DIR . 'amp-sharing.css' );
|
||||
|
||||
/*
|
||||
* phpcs:enable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
||||
* phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure proper Photon image dimensions for AMP Stories.
|
||||
*
|
||||
* @param array $args Array of Photon Arguments.
|
||||
* @param array $details {
|
||||
* Array of image details.
|
||||
*
|
||||
* @type string $tag Image tag (Image HTML output).
|
||||
* @type string $src Image URL.
|
||||
* @type string $src_orig Original Image URL.
|
||||
* @type int|false $width Image width.
|
||||
* @type int|false $height Image height.
|
||||
* @type int|false $width_orig Original image width before constrained by content_width.
|
||||
* @type int|false $height_orig Original Image height before constrained by content_width.
|
||||
* @type string $transform_orig Original transform before constrained by content_width.
|
||||
* }
|
||||
* @return array Args.
|
||||
*/
|
||||
public static function filter_photon_post_image_args_for_stories( $args, $details ) {
|
||||
if ( ! is_singular( 'amp_story' ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
// Percentage-based dimensions are not allowed in AMP, so this shouldn't happen, but short-circuit just in case.
|
||||
if ( str_contains( $details['width_orig'], '%' ) || str_contains( $details['height_orig'], '%' ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$max_height = 1280; // See image size with the slug \AMP_Story_Post_Type::MAX_IMAGE_SIZE_SLUG.
|
||||
$transform = $details['transform_orig'];
|
||||
$width = $details['width_orig'];
|
||||
$height = $details['height_orig'];
|
||||
|
||||
// If height is available, constrain to $max_height.
|
||||
if ( false !== $height ) {
|
||||
if ( $height > $max_height && false !== $height ) {
|
||||
$width = ( $max_height * $width ) / $height;
|
||||
$height = $max_height;
|
||||
} elseif ( $height > $max_height ) {
|
||||
$height = $max_height;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a height if none is found.
|
||||
* If height is set in this manner and height is available, use `fit` instead of `resize` to prevent skewing.
|
||||
*/
|
||||
if ( false === $height ) {
|
||||
$height = $max_height;
|
||||
if ( false !== $width ) {
|
||||
$transform = 'fit';
|
||||
}
|
||||
}
|
||||
|
||||
// Build array of Photon args and expose to filter before passing to Photon URL function.
|
||||
$args = array();
|
||||
|
||||
if ( false !== $width && false !== $height ) {
|
||||
$args[ $transform ] = $width . ',' . $height;
|
||||
} elseif ( false !== $width ) {
|
||||
$args['w'] = $width;
|
||||
} elseif ( false !== $height ) {
|
||||
$args['h'] = $height;
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds amp-options to the list of options to sync, if AMP is available
|
||||
*
|
||||
* @param array $options_safelist Safelist of options to sync.
|
||||
*
|
||||
* @return array Updated options safelist
|
||||
*/
|
||||
public static function filter_jetpack_options_safelist( $options_safelist ) {
|
||||
if ( function_exists( 'is_amp_endpoint' ) ) {
|
||||
$options_safelist[] = 'amp-options';
|
||||
}
|
||||
return $options_safelist;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility functions for the Creative Mail plugin.
|
||||
* https://wordpress.org/plugins/creative-mail-by-constant-contact/
|
||||
*
|
||||
* @since 8.9.0
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Creative_Mail;
|
||||
|
||||
use Automattic\Jetpack\Plugins_Installer;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
const PLUGIN_SLUG = 'creative-mail-by-constant-contact';
|
||||
const PLUGIN_FILE = 'creative-mail-by-constant-contact/creative-mail-plugin.php';
|
||||
|
||||
add_action( 'jetpack_activated_plugin', __NAMESPACE__ . '\configure_plugin', 10, 2 );
|
||||
|
||||
// Check for the JITM action.
|
||||
if ( isset( $_GET['creative-mail-action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
add_action( 'admin_init', __NAMESPACE__ . '\try_install' );
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['creative-mail-install-error'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
add_action( 'admin_notices', __NAMESPACE__ . '\error_notice' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the intent to install Creative Mail, and kick off installation.
|
||||
*
|
||||
* This works in tandem with a JITM set up in the JITM package.
|
||||
*
|
||||
* @return never
|
||||
*/
|
||||
function try_install() {
|
||||
check_admin_referer( 'creative-mail-install' );
|
||||
|
||||
$result = false;
|
||||
$redirect = admin_url( 'edit.php?post_type=feedback' );
|
||||
|
||||
// Attempt to install and activate the plugin.
|
||||
if ( current_user_can( 'activate_plugins' ) ) {
|
||||
switch ( $_GET['creative-mail-action'] ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- Function only hooked if set.
|
||||
case 'install':
|
||||
$result = install_and_activate();
|
||||
break;
|
||||
case 'activate':
|
||||
$result = activate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $result ) {
|
||||
/** This action is already documented in _inc/lib/class.core-rest-api-endpoints.php */
|
||||
do_action( 'jetpack_activated_plugin', PLUGIN_FILE, 'jitm' );
|
||||
$redirect = admin_url( 'admin.php?page=creativemail' );
|
||||
} else {
|
||||
$redirect = add_query_arg( 'creative-mail-install-error', true, $redirect );
|
||||
}
|
||||
|
||||
wp_safe_redirect( $redirect );
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Install and activate the Creative Mail plugin.
|
||||
*
|
||||
* @return bool result of installation
|
||||
*/
|
||||
function install_and_activate() {
|
||||
$result = Plugins_Installer::install_and_activate_plugin( PLUGIN_SLUG );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the Creative Mail plugin.
|
||||
*
|
||||
* @return bool result of activation
|
||||
*/
|
||||
function activate() {
|
||||
$result = activate_plugin( PLUGIN_FILE );
|
||||
|
||||
// Activate_plugin() returns null on success.
|
||||
return $result === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the user that the installation of Creative Mail failed.
|
||||
*/
|
||||
function error_notice() {
|
||||
wp_admin_notice(
|
||||
esc_html__( 'There was an error installing Creative Mail.', 'jetpack' ),
|
||||
array(
|
||||
'type' => 'error',
|
||||
'dismissible' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some options when first activating the plugin via Jetpack.
|
||||
*
|
||||
* @since 8.9.0
|
||||
*
|
||||
* @param string $plugin_file Plugin file.
|
||||
* @param string $source Where did the plugin installation originate.
|
||||
*/
|
||||
function configure_plugin( $plugin_file, $source ) {
|
||||
if ( PLUGIN_FILE !== $plugin_file ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$plugin_info = array(
|
||||
'plugin' => 'jetpack',
|
||||
'version' => JETPACK__VERSION,
|
||||
'time' => time(),
|
||||
'source' => esc_attr( $source ),
|
||||
);
|
||||
|
||||
update_option( 'ce4wp_referred_by', $plugin_info );
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* 3rd Party integration for Debug Bar.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if the search module is active, and if so, will initialize the singleton instance
|
||||
* of Jetpack_Search_Debug_Bar and add it to the array of debug bar panels.
|
||||
*
|
||||
* @param array $panels The array of debug bar panels.
|
||||
* @return array $panel The array of debug bar panels with our added panel.
|
||||
*/
|
||||
function init_jetpack_search_debug_bar( $panels ) {
|
||||
if ( ! Jetpack::is_module_active( 'search' ) ) {
|
||||
return $panels;
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/debug-bar/class-jetpack-search-debug-bar.php';
|
||||
$panels[] = Jetpack_Search_Debug_Bar::instance();
|
||||
return $panels;
|
||||
}
|
||||
add_filter( 'debug_bar_panels', 'init_jetpack_search_debug_bar' );
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a Jetpack Search debug panel to Debug Bar.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Search as Jetpack_Search;
|
||||
|
||||
/**
|
||||
* Singleton class instantiated by Jetpack_Searc_Debug_Bar::instance() that handles
|
||||
* rendering the Jetpack Search debug bar menu item and panel.
|
||||
*/
|
||||
class Jetpack_Search_Debug_Bar extends Debug_Bar_Panel {
|
||||
/**
|
||||
* Holds singleton instance
|
||||
*
|
||||
* @var Jetpack_Search_Debug_Bar
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* The title to use in the debug bar navigation
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->title( esc_html__( 'Jetpack Search', 'jetpack' ) );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'login_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'enqueue_embed_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of Jetpack_Search_Debug_Bar
|
||||
*
|
||||
* @return Jetpack_Search_Debug_Bar
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( self::$instance === null ) {
|
||||
self::$instance = new Jetpack_Search_Debug_Bar();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues styles for our panel in the debug bar
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
// Do not enqueue scripts if we haven't already enqueued Debug Bar or Query Monitor styles.
|
||||
if ( ! wp_style_is( 'debug-bar' ) && ! wp_style_is( 'query-monitor' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_style(
|
||||
'jetpack-search-debug-bar',
|
||||
plugins_url( '3rd-party/debug-bar/debug-bar.css', JETPACK__PLUGIN_FILE ),
|
||||
array(),
|
||||
JETPACK__VERSION
|
||||
);
|
||||
wp_enqueue_script(
|
||||
'jetpack-search-debug-bar',
|
||||
plugins_url( '3rd-party/debug-bar/debug-bar.js', JETPACK__PLUGIN_FILE ),
|
||||
array( 'jquery' ),
|
||||
JETPACK__VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the Jetpack Search Debug Bar show?
|
||||
*
|
||||
* Since we've previously done a check for the search module being activated, let's just return true.
|
||||
* Later on, we can update this to only show when `is_search()` is true.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_visible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the panel content
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render() {
|
||||
$jetpack_search = (
|
||||
Jetpack_Search\Options::is_instant_enabled() ?
|
||||
Jetpack_Search\Instant_Search::instance() :
|
||||
Jetpack_Search\Classic_Search::instance()
|
||||
);
|
||||
|
||||
// Search hasn't been initialized. Exit early and do not display the debug bar.
|
||||
if ( ! method_exists( $jetpack_search, 'get_last_query_info' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$last_query_info = $jetpack_search->get_last_query_info();
|
||||
|
||||
// If not empty, let's reshuffle the order of some things.
|
||||
if ( ! empty( $last_query_info ) ) {
|
||||
$args = $last_query_info['args'];
|
||||
$response = $last_query_info['response'];
|
||||
$response_code = $last_query_info['response_code'];
|
||||
|
||||
unset( $last_query_info['args'] );
|
||||
unset( $last_query_info['response'] );
|
||||
unset( $last_query_info['response_code'] );
|
||||
|
||||
if ( $last_query_info['es_time'] === null ) {
|
||||
$last_query_info['es_time'] = esc_html_x(
|
||||
'cache hit',
|
||||
'displayed in search results when results are cached',
|
||||
'jetpack'
|
||||
);
|
||||
}
|
||||
|
||||
$temp = array_merge(
|
||||
array( 'response_code' => $response_code ),
|
||||
array( 'args' => $args ),
|
||||
$last_query_info,
|
||||
array( 'response' => $response )
|
||||
);
|
||||
|
||||
$last_query_info = $temp;
|
||||
}
|
||||
?>
|
||||
<div class="jetpack-search-debug-bar">
|
||||
<h2><?php esc_html_e( 'Last query information:', 'jetpack' ); ?></h2>
|
||||
<?php if ( empty( $last_query_info ) ) : ?>
|
||||
<?php echo esc_html_x( 'None', 'Text displayed when there is no information', 'jetpack' ); ?>
|
||||
<?php
|
||||
else :
|
||||
foreach ( $last_query_info as $key => $info ) :
|
||||
?>
|
||||
<h3><?php echo esc_html( $key ); ?></h3>
|
||||
<?php
|
||||
if ( 'response' !== $key && 'args' !== $key ) :
|
||||
?>
|
||||
<pre><?php print_r( esc_html( $info ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions ?></pre>
|
||||
<?php
|
||||
else :
|
||||
$this->render_json_toggle( $info );
|
||||
endif;
|
||||
?>
|
||||
<?php
|
||||
endforeach;
|
||||
endif;
|
||||
?>
|
||||
</div><!-- Closes .jetpack-search-debug-bar -->
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for rendering the HTML necessary for the JSON toggle
|
||||
*
|
||||
* @param array $value The resonse from the API as an array.
|
||||
* @return void
|
||||
*/
|
||||
public function render_json_toggle( $value ) {
|
||||
?>
|
||||
<div class="json-toggle-wrap">
|
||||
<pre class="json">
|
||||
<?php
|
||||
// esc_html() will not double-encode entities (& -> &amp;).
|
||||
// If any entities are part of the JSON blob, we want to re-encoode them
|
||||
// (double-encode them) so that they are displayed correctly in the debug
|
||||
// bar.
|
||||
// Use _wp_specialchars() "manually" to ensure entities are encoded correctly.
|
||||
echo _wp_specialchars( // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
wp_json_encode( $value ),
|
||||
ENT_NOQUOTES, // Don't need to encode quotes (output is for a text node).
|
||||
'UTF-8', // wp_json_encode() outputs UTF-8 (really just ASCII), not the blog's charset.
|
||||
true // Do "double-encode" existing HTML entities.
|
||||
);
|
||||
?>
|
||||
</pre>
|
||||
<span class="pretty toggle"><?php echo esc_html_x( 'Pretty', 'label for formatting JSON', 'jetpack' ); ?></span>
|
||||
<span class="ugly toggle"><?php echo esc_html_x( 'Minify', 'label for formatting JSON', 'jetpack' ); ?></span>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
.jetpack-search-debug-bar h2,
|
||||
.qm-debug-bar-output .jetpack-search-debug-bar h2 {
|
||||
float: none !important;
|
||||
padding: 0 !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.qm-debug-bar-output .jetpack-search-debug-bar h2 {
|
||||
margin-top: 1em !important;
|
||||
}
|
||||
|
||||
.qm-debug-bar-output .jetpack-search-debug-bar h2:first-child {
|
||||
margin-top: .5em !important;
|
||||
}
|
||||
|
||||
.debug-menu-target h3 {
|
||||
padding-top: 0
|
||||
}
|
||||
|
||||
.jetpack-search-debug-output-toggle .print-r {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.json-toggle-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.json-toggle-wrap .toggle {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
background: #fff;
|
||||
border: 1px solid #000;
|
||||
cursor: pointer;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
.json-toggle-wrap .ugly {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.json-toggle-wrap.pretty .pretty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.json-toggle-wrap.pretty .ugly {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.jetpack-search-debug-bar pre {
|
||||
white-space: pre-wrap;
|
||||
white-space: -moz-pre-wrap;
|
||||
white-space: -pre-wrap;
|
||||
white-space: -o-pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/* global jQuery */
|
||||
/* eslint no-var: "off" */
|
||||
|
||||
( function ( $ ) {
|
||||
$( document ).ready( function () {
|
||||
$( '.jetpack-search-debug-bar .json-toggle-wrap .toggle' ).click( function () {
|
||||
var t = $( this ),
|
||||
wrap = t.closest( '.json-toggle-wrap' ),
|
||||
pre = wrap.find( 'pre' ),
|
||||
content = pre.text(),
|
||||
isPretty = wrap.hasClass( 'pretty' );
|
||||
|
||||
if ( ! isPretty ) {
|
||||
pre.text( JSON.stringify( JSON.parse( content ), null, 2 ) );
|
||||
} else {
|
||||
content.replace( '\t', '' ).replace( '\n', '' ).replace( ' ', '' );
|
||||
pre.text( JSON.stringify( JSON.parse( content ) ) );
|
||||
}
|
||||
|
||||
wrap.toggleClass( 'pretty' );
|
||||
} );
|
||||
} );
|
||||
} )( jQuery );
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility functions for the Jetpack Backup plugin.
|
||||
* https://wordpress.org/plugins/jetpack-backup/
|
||||
*
|
||||
* @since 10.4
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Jetpack_Backup;
|
||||
|
||||
use Automattic\Jetpack\Plugins_Installer;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
const PLUGIN_SLUG = 'jetpack-backup';
|
||||
const PLUGIN_FILE = 'jetpack-backup/jetpack-backup.php';
|
||||
|
||||
if ( isset( $_GET['jetpack-backup-install-error'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
add_action( 'admin_notices', __NAMESPACE__ . '\error_notice' );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['jetpack-backup-action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
add_action( 'admin_init', __NAMESPACE__ . '\try_install' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the intent to install Jetpack Backup, and kick off installation.
|
||||
*
|
||||
* This works in tandem with a JITM set up in the JITM package.
|
||||
*
|
||||
* @return never
|
||||
*/
|
||||
function try_install() {
|
||||
check_admin_referer( 'jetpack-backup-install' );
|
||||
|
||||
$result = false;
|
||||
// If the plugin install fails, redirect to plugin install page pre-populated with jetpack-backup search term.
|
||||
$redirect_on_error = admin_url( 'plugin-install.php?s=jetpack-backup&tab=search&type=term' );
|
||||
|
||||
// Attempt to install and activate the plugin.
|
||||
if ( current_user_can( 'activate_plugins' ) ) {
|
||||
switch ( $_GET['jetpack-backup-action'] ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- Function only hooked if set.
|
||||
case 'install':
|
||||
$result = install_and_activate();
|
||||
break;
|
||||
case 'activate':
|
||||
$result = activate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $result ) {
|
||||
/** This action is already documented in _inc/lib/class.core-rest-api-endpoints.php */
|
||||
do_action( 'jetpack_activated_plugin', PLUGIN_FILE, 'jitm' );
|
||||
$redirect = admin_url( 'admin.php?page=jetpack-backup' );
|
||||
} else {
|
||||
$redirect = add_query_arg( 'jetpack-backup-install-error', true, $redirect_on_error );
|
||||
}
|
||||
|
||||
wp_safe_redirect( $redirect );
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Install and activate the Jetpack Backup plugin.
|
||||
*
|
||||
* @return bool result of installation
|
||||
*/
|
||||
function install_and_activate() {
|
||||
$result = Plugins_Installer::install_and_activate_plugin( PLUGIN_SLUG );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the Jetpack Backup plugin.
|
||||
*
|
||||
* @return bool result of activation
|
||||
*/
|
||||
function activate() {
|
||||
$result = activate_plugin( PLUGIN_FILE );
|
||||
|
||||
// Activate_plugin() returns null on success.
|
||||
return $result === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the user that the installation of Jetpack Backup failed.
|
||||
*/
|
||||
function error_notice() {
|
||||
wp_admin_notice(
|
||||
esc_html__( 'There was an error installing Jetpack Backup. Please try again.', 'jetpack' ),
|
||||
array(
|
||||
'type' => 'error',
|
||||
'dismissible' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility functions for the Jetpack Boost plugin.
|
||||
* https://wordpress.org/plugins/jetpack-boost/
|
||||
*
|
||||
* @since 10.4
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Jetpack_Boost;
|
||||
|
||||
use Automattic\Jetpack\Plugins_Installer;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
const PLUGIN_SLUG = 'jetpack-boost';
|
||||
const PLUGIN_FILE = 'jetpack-boost/jetpack-boost.php';
|
||||
|
||||
if ( isset( $_GET['jetpack-boost-install-error'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
add_action( 'admin_notices', __NAMESPACE__ . '\error_notice' );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['jetpack-boost-action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
add_action( 'admin_init', __NAMESPACE__ . '\try_install' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the intent to install Jetpack Boost, and kick off installation.
|
||||
*
|
||||
* This works in tandem with a JITM set up in the JITM package.
|
||||
*/
|
||||
function try_install() {
|
||||
if ( ! isset( $_GET['jetpack-boost-action'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
check_admin_referer( 'jetpack-boost-install' );
|
||||
|
||||
$result = false;
|
||||
// If the plugin install fails, redirect to plugin install page pre-populated with jetpack-boost search term.
|
||||
$redirect_on_error = admin_url( 'plugin-install.php?s=jetpack-boost&tab=search&type=term' );
|
||||
|
||||
// Attempt to install and activate the plugin.
|
||||
if ( current_user_can( 'activate_plugins' ) ) {
|
||||
switch ( $_GET['jetpack-boost-action'] ) {
|
||||
case 'install':
|
||||
$result = install_and_activate();
|
||||
break;
|
||||
case 'activate':
|
||||
$result = activate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $result ) {
|
||||
/** This action is already documented in _inc/lib/class.core-rest-api-endpoints.php */
|
||||
do_action( 'jetpack_activated_plugin', PLUGIN_FILE, 'jitm' );
|
||||
$redirect = admin_url( 'admin.php?page=jetpack-boost' );
|
||||
} else {
|
||||
$redirect = add_query_arg( 'jetpack-boost-install-error', true, $redirect_on_error );
|
||||
}
|
||||
|
||||
wp_safe_redirect( $redirect );
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Install and activate the Jetpack Boost plugin.
|
||||
*
|
||||
* @return bool result of installation
|
||||
*/
|
||||
function install_and_activate() {
|
||||
$result = Plugins_Installer::install_and_activate_plugin( PLUGIN_SLUG );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the Jetpack Boost plugin.
|
||||
*
|
||||
* @return bool result of activation
|
||||
*/
|
||||
function activate() {
|
||||
$result = activate_plugin( PLUGIN_FILE );
|
||||
|
||||
// Activate_plugin() returns null on success.
|
||||
return $result === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the user that the installation of Jetpack Boost failed.
|
||||
*/
|
||||
function error_notice() {
|
||||
if ( empty( $_GET['jetpack-boost-install-error'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
return;
|
||||
}
|
||||
wp_admin_notice(
|
||||
esc_html__( 'There was an error installing Jetpack Boost. Please try again.', 'jetpack' ),
|
||||
array(
|
||||
'type' => 'error',
|
||||
'dismissible' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* 3rd party integration for qTranslate.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prevent qTranslate X from redirecting REST calls.
|
||||
*
|
||||
* @since 5.3
|
||||
*
|
||||
* @param string $url_lang Language URL to redirect to.
|
||||
* @param string $url_orig Original URL.
|
||||
* @param array $url_info Pieces of original URL.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function jetpack_no_qtranslate_rest_url_redirect( $url_lang, $url_orig, $url_info ) {
|
||||
if ( str_contains( $url_info['wp-path'], 'wp-json/jetpack' ) ) {
|
||||
return false;
|
||||
}
|
||||
return $url_lang;
|
||||
}
|
||||
add_filter( 'qtranslate_language_detect_redirect', 'jetpack_no_qtranslate_rest_url_redirect', 10, 3 );
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles VaultPress->Rewind transition by deactivating VaultPress when needed.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Redirect;
|
||||
|
||||
/**
|
||||
* Notify user that VaultPress has been disabled. Hide VaultPress notice that requested attention.
|
||||
*
|
||||
* @since 5.8
|
||||
*/
|
||||
function jetpack_vaultpress_rewind_enabled_notice() {
|
||||
// The deactivation is performed here because there may be pages that admin_init runs on,
|
||||
// such as admin_ajax, that could deactivate the plugin without showing this notification.
|
||||
deactivate_plugins( 'vaultpress/vaultpress.php' );
|
||||
|
||||
// Remove WP core notice that says that the plugin was activated.
|
||||
unset( $_GET['activate'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$message = sprintf(
|
||||
wp_kses(
|
||||
/* Translators: first variable is the full URL to the new dashboard */
|
||||
__( '<p style="margin-bottom: 0.25em;"><strong>Jetpack is now handling your backups.</strong></p><p>VaultPress is no longer needed and has been deactivated. You can access your backups at <a href="%3$s" target="_blank" rel="noopener noreferrer">this dashboard</a>.</p>', 'jetpack' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
'rel' => array(),
|
||||
),
|
||||
'p' => array(
|
||||
'style' => array(),
|
||||
),
|
||||
'strong' => array(),
|
||||
)
|
||||
),
|
||||
esc_url( Redirect::get_url( 'calypso-backups' ) )
|
||||
);
|
||||
wp_admin_notice(
|
||||
$message,
|
||||
array(
|
||||
'type' => 'success',
|
||||
'dismissible' => true,
|
||||
'additional_classes' => array( 'vp-deactivated' ),
|
||||
'paragraph_wrap' => false,
|
||||
)
|
||||
);
|
||||
?>
|
||||
<style>#vp-notice{display:none;}</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* If Backup & Scan is enabled, remove its entry in sidebar, deactivate VaultPress, and show a notification.
|
||||
*
|
||||
* @since 5.8
|
||||
*/
|
||||
function jetpack_vaultpress_rewind_check() {
|
||||
if (
|
||||
Jetpack::is_connection_ready() &&
|
||||
Jetpack::is_plugin_active( 'vaultpress/vaultpress.php' ) &&
|
||||
Jetpack::is_rewind_enabled()
|
||||
) {
|
||||
remove_submenu_page( 'jetpack', 'vaultpress' );
|
||||
|
||||
add_action( 'admin_notices', 'jetpack_vaultpress_rewind_enabled_notice' );
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'admin_init', 'jetpack_vaultpress_rewind_check', 11 );
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility functions for the Web Stories plugin.
|
||||
* https://wordpress.org/plugins/web-stories/
|
||||
*
|
||||
* @since 9.2.0
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Web_Stories;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to enable web stories built in open graph data from being output.
|
||||
* If Jetpack is already handling Open Graph Meta Tags, the Web Stories plugin will not output any.
|
||||
*
|
||||
* @param bool $enabled If web stories open graph data is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function maybe_disable_open_graph( $enabled ) {
|
||||
/** This filter is documented in class.jetpack.php */
|
||||
$jetpack_enabled = apply_filters( 'jetpack_enable_open_graph', false );
|
||||
|
||||
if ( $jetpack_enabled ) {
|
||||
$enabled = false;
|
||||
}
|
||||
|
||||
return $enabled;
|
||||
}
|
||||
add_filter( 'web_stories_enable_open_graph_metadata', __NAMESPACE__ . '\maybe_disable_open_graph' );
|
||||
add_filter( 'web_stories_enable_twitter_metadata', __NAMESPACE__ . '\maybe_disable_open_graph' );
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
|
||||
|
||||
use Automattic\Jetpack\Plugins_Installer;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs and activates the WooCommerce Services plugin.
|
||||
*/
|
||||
class WC_Services_Installer {
|
||||
|
||||
/**
|
||||
* The instance of the Jetpack class.
|
||||
*
|
||||
* @var Jetpack
|
||||
*/
|
||||
private $jetpack;
|
||||
|
||||
/**
|
||||
* The singleton instance of this class.
|
||||
*
|
||||
* @var WC_Services_Installer
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of this class.
|
||||
*
|
||||
* @return object The WC_Services_Installer object.
|
||||
*/
|
||||
public static function init() {
|
||||
if ( self::$instance === null ) {
|
||||
self::$instance = new WC_Services_Installer();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'jetpack_loaded', array( $this, 'on_jetpack_loaded' ) );
|
||||
if ( ! empty( $_GET['wc-services-install-error'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
add_action( 'admin_notices', array( $this, 'error_notice' ) );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['wc-services-action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
add_action( 'admin_init', array( $this, 'try_install' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs on Jetpack being ready to load its packages.
|
||||
*
|
||||
* @param Jetpack $jetpack object.
|
||||
*/
|
||||
public function on_jetpack_loaded( $jetpack ) {
|
||||
$this->jetpack = $jetpack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the intent to install WooCommerce Services, and kick off installation.
|
||||
*/
|
||||
public function try_install() {
|
||||
if ( ! isset( $_GET['wc-services-action'] ) ) {
|
||||
return;
|
||||
}
|
||||
check_admin_referer( 'wc-services-install' );
|
||||
|
||||
$result = false;
|
||||
|
||||
switch ( $_GET['wc-services-action'] ) {
|
||||
case 'install':
|
||||
if ( current_user_can( 'install_plugins' ) ) {
|
||||
$this->jetpack->stat( 'jitm', 'wooservices-install-' . JETPACK__VERSION );
|
||||
$result = $this->install();
|
||||
if ( $result ) {
|
||||
$result = $this->activate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'activate':
|
||||
if ( current_user_can( 'activate_plugins' ) ) {
|
||||
$this->jetpack->stat( 'jitm', 'wooservices-activate-' . JETPACK__VERSION );
|
||||
$result = $this->activate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isset( $_GET['redirect'] ) ) {
|
||||
$redirect = home_url( esc_url_raw( wp_unslash( $_GET['redirect'] ) ) );
|
||||
} else {
|
||||
$redirect = admin_url();
|
||||
}
|
||||
|
||||
if ( $result ) {
|
||||
$this->jetpack->stat( 'jitm', 'wooservices-activated-' . JETPACK__VERSION );
|
||||
} else {
|
||||
$redirect = add_query_arg( 'wc-services-install-error', true, $redirect );
|
||||
}
|
||||
|
||||
wp_safe_redirect( $redirect );
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the user that the installation of WooCommerce Services failed.
|
||||
*/
|
||||
public function error_notice() {
|
||||
wp_admin_notice(
|
||||
esc_html__( 'There was an error installing WooCommerce Services.', 'jetpack' ),
|
||||
array(
|
||||
'type' => 'error',
|
||||
'dismissible' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download and install the WooCommerce Services plugin.
|
||||
*
|
||||
* @return bool result of installation
|
||||
*/
|
||||
private function install() {
|
||||
$result = Plugins_Installer::install_plugin( 'woocommerce-services' );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the WooCommerce Services plugin.
|
||||
*
|
||||
* @return bool result of activation
|
||||
*/
|
||||
private function activate() {
|
||||
$result = activate_plugin( 'woocommerce-services/woocommerce-services.php' );
|
||||
|
||||
// Activate_plugin() returns null on success.
|
||||
return $result === null;
|
||||
}
|
||||
}
|
||||
|
||||
WC_Services_Installer::init();
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* This file contains compatibility functions for WooCommerce to improve Jetpack feature support.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
add_action( 'woocommerce_init', 'jetpack_woocommerce_integration' );
|
||||
|
||||
/**
|
||||
* Loads JP+WC integration.
|
||||
*
|
||||
* Fires on `woocommerce_init` hook
|
||||
*/
|
||||
function jetpack_woocommerce_integration() {
|
||||
/**
|
||||
* Double check WooCommerce exists - unlikely to fail due to the hook being used but better safe than sorry.
|
||||
*/
|
||||
if ( ! class_exists( 'WooCommerce' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'woocommerce_share', 'jetpack_woocommerce_social_share_icons', 10 );
|
||||
|
||||
/**
|
||||
* Add product post type to Jetpack sitemap while skipping hidden products.
|
||||
*/
|
||||
add_filter( 'jetpack_sitemap_post_types', 'jetpack_woocommerce_add_to_sitemap' );
|
||||
add_filter( 'jetpack_sitemap_skip_post', 'jetpack_woocommerce_skip_hidden_products_in_sitemap', 10, 2 );
|
||||
|
||||
/**
|
||||
* Wrap in function exists check since this requires WooCommerce 3.3+.
|
||||
*/
|
||||
if ( function_exists( 'wc_get_default_products_per_row' ) ) {
|
||||
add_filter( 'infinite_scroll_render_callbacks', 'jetpack_woocommerce_infinite_scroll_render_callback', 10 );
|
||||
add_action( 'wp_enqueue_scripts', 'jetpack_woocommerce_infinite_scroll_style', 10 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add product post type to sitemap if Woocommerce is present.
|
||||
*
|
||||
* @param array $post_types Array of post types included in sitemap.
|
||||
*/
|
||||
function jetpack_woocommerce_add_to_sitemap( $post_types ) {
|
||||
$post_types[] = 'product';
|
||||
|
||||
return $post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip hidden products when generating the sitemap.
|
||||
*
|
||||
* @param bool $skip Whether to skip the post.
|
||||
* @param WP_Post $post The post object.
|
||||
*/
|
||||
function jetpack_woocommerce_skip_hidden_products_in_sitemap( $skip, $post ) {
|
||||
if ( $post !== null && $post->post_type === 'product' ) {
|
||||
$product = wc_get_product( $post->ID );
|
||||
if ( $product ) {
|
||||
$skip = ! $product->is_visible();
|
||||
}
|
||||
}
|
||||
return $skip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the social sharing icons show up under the product's short description
|
||||
*/
|
||||
function jetpack_woocommerce_social_share_icons() {
|
||||
if ( function_exists( 'sharing_display' ) ) {
|
||||
remove_filter( 'the_content', 'sharing_display', 19 );
|
||||
remove_filter( 'the_excerpt', 'sharing_display', 19 );
|
||||
sharing_display( '', true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove sharing display from account, cart, and checkout pages in WooCommerce.
|
||||
*/
|
||||
function jetpack_woocommerce_remove_share() {
|
||||
/**
|
||||
* Double check WooCommerce exists - unlikely to fail due to the hook being used but better safe than sorry.
|
||||
*/
|
||||
if ( ! class_exists( 'WooCommerce' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( is_cart() || is_checkout() || is_account_page() ) {
|
||||
remove_filter( 'the_content', 'sharing_display', 19 );
|
||||
if ( class_exists( 'Jetpack_Likes' ) ) {
|
||||
remove_filter( 'the_content', array( Jetpack_Likes::init(), 'post_likes' ), 30 );
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'loop_start', 'jetpack_woocommerce_remove_share' );
|
||||
|
||||
/**
|
||||
* Add a callback for WooCommerce product rendering in infinite scroll.
|
||||
*
|
||||
* @param array $callbacks Array of render callpacks for IS.
|
||||
* @return array
|
||||
*/
|
||||
function jetpack_woocommerce_infinite_scroll_render_callback( $callbacks ) {
|
||||
$callbacks[] = 'jetpack_woocommerce_infinite_scroll_render';
|
||||
return $callbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a default renderer for WooCommerce products within infinite scroll.
|
||||
*/
|
||||
function jetpack_woocommerce_infinite_scroll_render() {
|
||||
if ( ! is_shop() && ! is_product_taxonomy() && ! is_product_category() && ! is_product_tag() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
woocommerce_product_loop_start();
|
||||
|
||||
while ( have_posts() ) {
|
||||
the_post();
|
||||
wc_get_template_part( 'content', 'product' );
|
||||
}
|
||||
|
||||
woocommerce_product_loop_end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic styling when infinite scroll is active only.
|
||||
*/
|
||||
function jetpack_woocommerce_infinite_scroll_style() {
|
||||
$custom_css = '
|
||||
.infinite-scroll .woocommerce-pagination {
|
||||
display: none;
|
||||
}';
|
||||
wp_add_inline_style( 'woocommerce-layout', $custom_css );
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* This provides minor tweaks to improve the experience for Jetpack feed in the WordPress.com Reader.
|
||||
*
|
||||
* This does not make sites available in the Reader—that depends on the public access to /feed/ as a method on the WP.com side
|
||||
* to check if a site is public. It also does not add any content to the feed. Any content that should not be displayed in the Reader
|
||||
* or other RSS readers should be filtered out elsewhere.
|
||||
*
|
||||
* These hooks were originally part of the now-deprecated Enhanced Distribution.
|
||||
*
|
||||
* @since 13.3
|
||||
* @package Automattic/jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
|
||||
use Automattic\Jetpack\Status;
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
|
||||
foreach ( array( 'rss_head', 'rss1_head', 'rss2_head' ) as $rss_head_action ) {
|
||||
add_action( $rss_head_action, 'jetpack_wpcomreader_feed_id' );
|
||||
}
|
||||
foreach ( array( 'rss_item', 'rss1_item', 'rss2_item' ) as $rss_item_action ) {
|
||||
add_action( $rss_item_action, 'jetpack_wpcomreader_post_id' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Output feed identifier based on blog ID.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function jetpack_wpcomreader_feed_id() {
|
||||
if (
|
||||
( new Host() )->is_wpcom_simple()
|
||||
|| (
|
||||
( new Connection_Manager() )->is_connected()
|
||||
&& ! ( new Status() )->is_offline_mode()
|
||||
)
|
||||
) {
|
||||
$blog_id = Connection_Manager::get_site_id( true ); // Silence since we're not wanting to handle the error state.
|
||||
if ( ! $blog_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(
|
||||
'<site xmlns="com-wordpress:feed-additions:1">%d</site>',
|
||||
(int) $blog_id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output feed item identifier based on current post ID.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function jetpack_wpcomreader_post_id() {
|
||||
$id = get_the_ID();
|
||||
if ( ! $id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(
|
||||
'<post-id xmlns="com-wordpress:feed-additions:1">%d</post-id>',
|
||||
(int) $id
|
||||
);
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Only load these if WPML plugin is installed and active.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* Load routines only if WPML is loaded.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
function wpml_jetpack_init() {
|
||||
add_action( 'jetpack_widget_get_top_posts', 'wpml_jetpack_widget_get_top_posts', 10, 3 );
|
||||
add_filter( 'grunion_contact_form_field_html', 'grunion_contact_form_field_html_filter', 10, 3 );
|
||||
}
|
||||
add_action( 'wpml_loaded', 'wpml_jetpack_init' );
|
||||
|
||||
/**
|
||||
* Filter the Top Posts and Pages by language.
|
||||
*
|
||||
* @param array $posts Array of the most popular posts.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function wpml_jetpack_widget_get_top_posts( $posts ) {
|
||||
global $sitepress;
|
||||
|
||||
foreach ( $posts as $k => $post ) {
|
||||
$lang_information = wpml_get_language_information( $post['post_id'] );
|
||||
if ( ! is_wp_error( $lang_information ) ) {
|
||||
$post_language = substr( $lang_information['locale'], 0, 2 );
|
||||
if ( $post_language !== $sitepress->get_current_language() ) {
|
||||
unset( $posts[ $k ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the HTML of the Contact Form and output the one requested by language.
|
||||
*
|
||||
* @param string $r Contact Form HTML output.
|
||||
* @param string $field_label Field label.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function grunion_contact_form_field_html_filter( $r, $field_label ) {
|
||||
global $sitepress;
|
||||
|
||||
if ( function_exists( 'icl_translate' ) ) {
|
||||
if ( $sitepress->get_current_language() !== $sitepress->get_default_language() ) {
|
||||
$label_translation = icl_translate( 'jetpack ', $field_label . '_label', $field_label );
|
||||
$r = str_replace( $field_label, $label_translation, $r );
|
||||
}
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
Reference in New Issue
Block a user