summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/modules/sharedaddy/sharing-service.php')
-rw-r--r--plugins/jetpack/modules/sharedaddy/sharing-service.php363
1 files changed, 299 insertions, 64 deletions
diff --git a/plugins/jetpack/modules/sharedaddy/sharing-service.php b/plugins/jetpack/modules/sharedaddy/sharing-service.php
index f6d80dc3..a760ec5d 100644
--- a/plugins/jetpack/modules/sharedaddy/sharing-service.php
+++ b/plugins/jetpack/modules/sharedaddy/sharing-service.php
@@ -1,33 +1,64 @@
-<?php
+<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
+/**
+ * Utilities to register and interact with a sharing service.
+ *
+ * Sharing_Service gets info about a service.
+ * Sharing_Service_Total and Sharing_Post_Total get stats data.
+ *
+ * @package automattic/jetpack
+ *
+ * phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound
+ */
use Automattic\Jetpack\Assets;
use Automattic\Jetpack\Redirect;
use Automattic\Jetpack\Status;
use Automattic\Jetpack\Sync\Settings;
-include_once dirname( __FILE__ ) . '/sharing-sources.php';
+require_once __DIR__ . '/sharing-sources.php';
define( 'WP_SHARING_PLUGIN_VERSION', JETPACK__VERSION );
+/**
+ * Interact with a sharing service.
+ */
class Sharing_Service {
- private $global = false;
+ /**
+ * Should the service be available globally?
+ *
+ * @var bool
+ */
+ private $global = false;
+
+ /**
+ * Default sharing label.
+ *
+ * @var string
+ */
public $default_sharing_label = '';
/**
* Initialize the sharing service.
* Only run this method once upon module loading.
+ *
+ * @return void
*/
public static function init() {
add_filter( 'the_content', 'sharing_display', 19 );
add_filter( 'the_excerpt', 'sharing_display', 19 );
}
+ /**
+ * Constructor.
+ */
public function __construct() {
$this->default_sharing_label = __( 'Share this:', 'jetpack' );
}
/**
* Gets a generic list of all services, without any config
+ *
+ * @return array
*/
public function get_all_services_blog() {
$options = get_option( 'sharing-options' );
@@ -39,7 +70,7 @@ class Sharing_Service {
$config = array();
// Pre-load custom modules otherwise they won't know who they are
- if ( substr( $id, 0, 7 ) == 'custom-' && is_array( $options[ $id ] ) ) {
+ if ( substr( $id, 0, 7 ) === 'custom-' && is_array( $options[ $id ] ) ) {
$config = $options[ $id ];
}
@@ -52,6 +83,10 @@ class Sharing_Service {
/**
* Gets a list of all available service names and classes
+ *
+ * @param bool $include_custom Include custom sharing services.
+ *
+ * @return array
*/
public function get_all_services( $include_custom = true ) {
// Default services
@@ -59,6 +94,7 @@ class Sharing_Service {
// in bin/tests/api/suites/SharingTest.php
$services = array(
'print' => 'Share_Print',
+ 'email' => 'Share_Email',
'facebook' => 'Share_Facebook',
'linkedin' => 'Share_LinkedIn',
'reddit' => 'Share_Reddit',
@@ -71,20 +107,6 @@ class Sharing_Service {
'skype' => 'Share_Skype',
);
- /**
- * Filters if Email Sharing is enabled.
- *
- * E-Mail sharing is often problematic due to spam concerns, so this filter enables it to be quickly and simply toggled.
- * @module sharedaddy
- *
- * @since 5.1.0
- *
- * @param bool $email Is e-mail sharing enabled? Default false if Akismet is not active or true if Akismet is active.
- */
- if ( apply_filters( 'sharing_services_email', Jetpack::is_akismet_active() ) ) {
- $services['email'] = 'Share_Email';
- }
-
if ( is_multisite() && is_plugin_active( 'press-this/press-this-plugin.php' ) ) {
$services['press-this'] = 'Share_PressThis';
}
@@ -109,8 +131,17 @@ class Sharing_Service {
return apply_filters( 'sharing_services', $services );
}
+ /**
+ * Save a new custom sharing service.
+ *
+ * @param string $label Service name.
+ * @param string $url Service sharing URL.
+ * @param string $icon Service icon.
+ *
+ * @return bool|Share_Custom
+ */
public function new_service( $label, $url, $icon ) {
- // Validate
+ // Validate.
$label = trim( wp_html_excerpt( wp_kses( $label, array() ), 30 ) );
$url = trim( esc_url_raw( $url ) );
$icon = trim( esc_url_raw( $icon ) );
@@ -133,7 +164,8 @@ class Sharing_Service {
// Create a custom service and set the options for it
$service = new Share_Custom(
- $service_id, array(
+ $service_id,
+ array(
'name' => $label,
'url' => $url,
'icon' => $icon,
@@ -148,13 +180,20 @@ class Sharing_Service {
return false;
}
+ /**
+ * Delete a sharing service.
+ *
+ * @param string $service_id Service ID.
+ *
+ * @return bool
+ */
public function delete_service( $service_id ) {
$options = get_option( 'sharing-options' );
if ( isset( $options[ $service_id ] ) ) {
unset( $options[ $service_id ] );
}
- $key = array_search( $service_id, $options['global']['custom'] );
+ $key = array_search( $service_id, $options['global']['custom'], true );
if ( $key !== false ) {
unset( $options['global']['custom'][ $key ] );
}
@@ -163,6 +202,14 @@ class Sharing_Service {
return true;
}
+ /**
+ * Save enabled sharing services.
+ *
+ * @param array $visible Visible sharing services.
+ * @param array $hidden Hidden sharing services (available under a dropdown).
+ *
+ * @return bool
+ */
public function set_blog_services( array $visible, array $hidden ) {
$services = $this->get_all_services();
// Validate the services
@@ -193,7 +240,8 @@ class Sharing_Service {
* }
*/
do_action(
- 'sharing_get_services_state', array(
+ 'sharing_get_services_state',
+ array(
'services' => $services,
'available' => $available,
'hidden' => $hidden,
@@ -203,13 +251,19 @@ class Sharing_Service {
);
return update_option(
- 'sharing-services', array(
+ 'sharing-services',
+ array(
'visible' => $visible,
'hidden' => $hidden,
)
);
}
+ /**
+ * Get information about enabled sharing services on the site.
+ *
+ * @return array
+ */
public function get_blog_services() {
$options = get_option( 'sharing-options' );
$enabled = get_option( 'sharing-services' );
@@ -218,6 +272,7 @@ class Sharing_Service {
/**
* Check if options exist and are well formatted.
* This avoids issues on sites with corrupted options.
+ *
* @see https://github.com/Automattic/jetpack/issues/6121
*/
if ( ! is_array( $options ) || ! isset( $options['button_style'], $options['global'] ) ) {
@@ -302,6 +357,13 @@ class Sharing_Service {
return $blog;
}
+ /**
+ * Get information about a specific enabled sharing service.
+ *
+ * @param string $service_name Service name.
+ *
+ * @return bool|Sharing_Source
+ */
public function get_service( $service_name ) {
$services = $this->get_blog_services();
@@ -316,6 +378,11 @@ class Sharing_Service {
return false;
}
+ /**
+ * Update global sharing options.
+ *
+ * @param array $data Array of new sharing options to save.
+ */
public function set_global_options( $data ) {
$options = get_option( 'sharing-options' );
@@ -345,7 +412,10 @@ class Sharing_Service {
$options['global'] = apply_filters( 'sharing_default_global', $options['global'] );
// Validate options and set from our data
- if ( isset( $data['button_style'] ) && in_array( $data['button_style'], array( 'icon-text', 'icon', 'text', 'official' ) ) ) {
+ if (
+ isset( $data['button_style'] )
+ && in_array( $data['button_style'], array( 'icon-text', 'icon', 'text', 'official' ), true )
+ ) {
$options['global']['button_style'] = $data['button_style'];
}
@@ -357,7 +427,10 @@ class Sharing_Service {
}
}
- if ( isset( $data['open_links'] ) && in_array( $data['open_links'], array( 'new', 'same' ) ) ) {
+ if (
+ isset( $data['open_links'] )
+ && in_array( $data['open_links'], array( 'new', 'same' ), true )
+ ) {
$options['global']['open_links'] = $data['open_links'];
}
@@ -378,7 +451,8 @@ class Sharing_Service {
}
}
- if ( $data['show'] = array_intersect( $data['show'], $shows ) ) {
+ $data['show'] = array_intersect( $data['show'], $shows );
+ if ( $data['show'] ) {
$options['global']['show'] = $data['show'];
}
}
@@ -387,6 +461,11 @@ class Sharing_Service {
return $options['global'];
}
+ /**
+ * Get global sharing options for the site.
+ *
+ * @return array
+ */
public function get_global_options() {
if ( $this->global === false ) {
$options = get_option( 'sharing-options' );
@@ -421,6 +500,14 @@ class Sharing_Service {
return $this->global;
}
+ /**
+ * Save a sharing service for use.
+ *
+ * @param int $id Sharing unique ID.
+ * @param Sharing_Source $service Sharing service.
+ *
+ * @return void
+ */
public function set_service( $id, Sharing_Source $service ) {
// Update the options for this service
$options = get_option( 'sharing-options' );
@@ -446,7 +533,8 @@ class Sharing_Service {
* }
*/
do_action(
- 'sharing_get_button_state', array(
+ 'sharing_get_button_state',
+ array(
'id' => $id,
'options' => $options,
'service' => $service,
@@ -458,13 +546,22 @@ class Sharing_Service {
update_option( 'sharing-options', array_filter( $options ) );
}
- // Soon to come to a .org plugin near you!
+ /**
+ * Get stats for a site, a post, or a sharing service.
+ * Soon to come to a .org plugin near you!
+ *
+ * @param string|bool $service_name Service name.
+ * @param int|bool $post_id Post ID.
+ * @param int|bool $_blog_id Blog ID.
+ *
+ * @return int
+ */
public function get_total( $service_name = false, $post_id = false, $_blog_id = false ) {
global $wpdb, $blog_id;
if ( ! $_blog_id ) {
$_blog_id = $blog_id;
}
- if ( $service_name == false ) {
+ if ( $service_name === false ) {
if ( $post_id > 0 ) {
// total number of shares for this post
return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND post_id = %d', $_blog_id, $post_id ) );
@@ -481,6 +578,13 @@ class Sharing_Service {
}
}
+ /**
+ * Get total stats for a site, for all sharing services.
+ *
+ * @param int|bool $post_id Post ID.
+ *
+ * @return array
+ */
public function get_services_total( $post_id = false ) {
$totals = array();
$services = $this->get_blog_services();
@@ -495,6 +599,11 @@ class Sharing_Service {
return $totals;
}
+ /**
+ * Get sharing stats for all posts on the site.
+ *
+ * @return array
+ */
public function get_posts_total() {
$totals = array();
global $wpdb, $blog_id;
@@ -513,12 +622,44 @@ class Sharing_Service {
}
}
+/**
+ * Get stats for a specific sharing service.
+ */
class Sharing_Service_Total {
- public $id = '';
- public $name = '';
+ /**
+ * Sharing service ID.
+ *
+ * @var int
+ */
+ public $id = '';
+
+ /**
+ * Service name.
+ *
+ * @var string
+ */
+ public $name = '';
+
+ /**
+ * Sharing service name.
+ *
+ * @var string
+ */
public $service = '';
- public $total = 0;
+ /**
+ * Total number of shares for this service.
+ *
+ * @var string
+ */
+ public $total = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param int $id Service ID.
+ * @param int $total Total shares.
+ */
public function __construct( $id, $total ) {
$services = new Sharing_Service();
$this->id = esc_html( $id );
@@ -528,20 +669,60 @@ class Sharing_Service_Total {
$this->name = $this->service->get_name();
}
- static function cmp( $a, $b ) {
- if ( $a->total == $b->total ) {
+ /**
+ * Compare total shares between 2 posts.
+ *
+ * @param object $a Sharing_Service_Total object.
+ * @param object $b Sharing_Service_Total object.
+ *
+ * @return bool
+ */
+ public static function cmp( $a, $b ) {
+ if ( $a->total === $b->total ) {
return $a->name < $b->name;
}
return $a->total < $b->total;
}
}
+/**
+ * Get sharing stats for a specific post.
+ */
class Sharing_Post_Total {
- public $id = 0;
+ /**
+ * Sharing service ID.
+ *
+ * @var int
+ */
+ public $id = 0;
+
+ /**
+ * Total shares.
+ *
+ * @var int
+ */
public $total = 0;
+
+ /**
+ * Post title.
+ *
+ * @var string
+ */
public $title = '';
- public $url = '';
+ /**
+ * Post permalink.
+ *
+ * @var string
+ */
+ public $url = '';
+
+ /**
+ * Constructor.
+ *
+ * @param int $id Service ID.
+ * @param int $total Total shares.
+ */
public function __construct( $id, $total ) {
$this->id = (int) $id;
$this->total = (int) $total;
@@ -549,14 +730,29 @@ class Sharing_Post_Total {
$this->url = get_permalink( $this->id );
}
- static function cmp( $a, $b ) {
- if ( $a->total == $b->total ) {
+ /**
+ * Compare total shares between 2 posts.
+ *
+ * @param object $a Sharing_Post_Total object.
+ * @param object $b Sharing_Post_Total object.
+ *
+ * @return bool
+ */
+ public static function cmp( $a, $b ) {
+ if ( $a->total === $b->total ) {
return $a->id < $b->id;
}
return $a->total < $b->total;
}
}
+/**
+ * Populate sharing counts global with a post we want to count shares for.
+ *
+ * @param int $post_id Post ID.
+ *
+ * @return void
+ */
function sharing_register_post_for_share_counts( $post_id ) {
global $jetpack_sharing_counts;
@@ -567,14 +763,28 @@ function sharing_register_post_for_share_counts( $post_id ) {
$jetpack_sharing_counts[ (int) $post_id ] = get_permalink( $post_id );
}
+/**
+ * Determine whether we should load sharing scripts or not.
+ *
+ * @return bool
+ */
function sharing_maybe_enqueue_scripts() {
$sharer = new Sharing_Service();
$global_options = $sharer->get_global_options();
$enqueue = false;
- if ( is_singular() && in_array( get_post_type(), $global_options['show'] ) ) {
+ if ( is_singular() && in_array( get_post_type(), $global_options['show'], true ) ) {
$enqueue = true;
- } elseif ( in_array( 'index', $global_options['show'] ) && ( is_home() || is_front_page() || is_archive() || is_search() || in_array( get_post_type(), $global_options['show'] ) ) ) {
+ } elseif (
+ in_array( 'index', $global_options['show'], true )
+ && (
+ is_home()
+ || is_front_page()
+ || is_archive()
+ || is_search()
+ || in_array( get_post_type(), $global_options['show'], true )
+ )
+ ) {
$enqueue = true;
}
@@ -590,6 +800,11 @@ function sharing_maybe_enqueue_scripts() {
return (bool) apply_filters( 'sharing_enqueue_scripts', $enqueue );
}
+/**
+ * Add sharing JavaScript to the footer of a page.
+ *
+ * @return void
+ */
function sharing_add_footer() {
if (
class_exists( 'Jetpack_AMP_Support' )
@@ -600,33 +815,39 @@ function sharing_add_footer() {
global $jetpack_sharing_counts;
- /**
- * Filter all JavaScript output by the sharing module.
- *
- * @module sharedaddy
- *
- * @since 1.1.0
- *
- * @param bool true Control whether the sharing module should add any JavaScript to the site. Default to true.
- */
- if ( apply_filters( 'sharing_js', true ) && sharing_maybe_enqueue_scripts() ) {
-
+ if (
/**
- * Filter the display of sharing counts next to the sharing buttons.
+ * Filter all JavaScript output by the sharing module.
*
* @module sharedaddy
*
- * @since 3.2.0
+ * @since 1.1.0
*
- * @param bool true Control the display of counters next to the sharing buttons. Default to true.
+ * @param bool true Control whether the sharing module should add any JavaScript to the site. Default to true.
*/
- if ( apply_filters( 'jetpack_sharing_counts', true ) && is_array( $jetpack_sharing_counts ) && count( $jetpack_sharing_counts ) ) :
+ apply_filters( 'sharing_js', true )
+ && sharing_maybe_enqueue_scripts()
+ ) {
+ if (
+ /**
+ * Filter the display of sharing counts next to the sharing buttons.
+ *
+ * @module sharedaddy
+ *
+ * @since 3.2.0
+ *
+ * @param bool true Control the display of counters next to the sharing buttons. Default to true.
+ */
+ apply_filters( 'jetpack_sharing_counts', true )
+ && is_array( $jetpack_sharing_counts )
+ && count( $jetpack_sharing_counts )
+ ) :
$sharing_post_urls = array_filter( $jetpack_sharing_counts );
if ( $sharing_post_urls ) :
?>
<script type="text/javascript">
- window.WPCOM_sharing_counts = <?php echo json_encode( array_flip( $sharing_post_urls ) ); ?>;
+ window.WPCOM_sharing_counts = <?php echo wp_json_encode( array_flip( $sharing_post_urls ) ); ?>;
</script>
<?php
endif;
@@ -648,6 +869,11 @@ function sharing_add_footer() {
}
}
+/**
+ * Enqueue sharing CSS in head.
+ *
+ * @return void
+ */
function sharing_add_header() {
$sharer = new Sharing_Service();
$enabled = $sharer->get_blog_services();
@@ -664,6 +890,11 @@ function sharing_add_header() {
}
add_action( 'wp_head', 'sharing_add_header', 1 );
+/**
+ * Launch sharing requests on page load when a specific query string is used.
+ *
+ * @return void
+ */
function sharing_process_requests() {
global $post;
@@ -671,9 +902,9 @@ function sharing_process_requests() {
if ( ( is_page() || is_single() ) && isset( $_GET['share'] ) && is_string( $_GET['share'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$sharer = new Sharing_Service();
- $service = $sharer->get_service( $_GET['share'] );
+ $service = $sharer->get_service( sanitize_text_field( wp_unslash( $_GET['share'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( $service ) {
- $service->process_request( $post, $_POST );
+ $service->process_request( $post, $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
}
}
}
@@ -805,8 +1036,8 @@ function sharing_display( $text = '', $echo = false ) {
if (
defined( 'DOING_AJAX' )
&& DOING_AJAX
- && isset( $_REQUEST['action'] )
- && $ajax_action === $_REQUEST['action']
+ && isset( $_REQUEST['action'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce handling happens within each custom implementation.
+ && $ajax_action === $_REQUEST['action'] // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce handling happens within each custom implementation.
) {
$show = true;
}
@@ -852,7 +1083,7 @@ function sharing_display( $text = '', $echo = false ) {
// Visible items.
$visible = '';
- foreach ( $enabled['visible'] as $id => $service ) {
+ foreach ( $enabled['visible'] as $service ) {
$klasses = array( 'share-' . $service->get_class() );
if ( $service->is_deprecated() ) {
if ( ! current_user_can( 'manage_options' ) ) {
@@ -907,7 +1138,7 @@ function sharing_display( $text = '', $echo = false ) {
}
$count = 1;
- foreach ( $enabled['hidden'] as $id => $service ) {
+ foreach ( $enabled['hidden'] as $service ) {
// Individual HTML for sharing service.
$klasses = array( 'share-' . $service->get_class() );
if ( $service->is_deprecated() ) {
@@ -971,14 +1202,18 @@ function sharing_display( $text = '', $echo = false ) {
$sharing_markup = apply_filters( 'jetpack_sharing_display_markup', $sharing_content, $enabled );
if ( $echo ) {
- echo $text . $sharing_markup;
+ echo $text . $sharing_markup; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} else {
return $text . $sharing_markup;
}
}
+/**
+ * Get reCAPTCHA language code based off the language code of the site.
+ *
+ * @return string
+ */
function get_base_recaptcha_lang_code() {
-
$base_recaptcha_lang_code_mapping = array(
'en' => 'en',
'nl' => 'nl',