<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
* Define all sharing sources.
* phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound
use Automattic\Jetpack\Device_Detection\User_Agent_Info;
if ( ! defined( 'ABSPATH' ) ) {
* Base class for sharing sources.
* See individual sharing classes below for the implementation of this class.
abstract class Sharing_Source {
* Button style (icon, icon-text, text, or official).
* Does the service have an official version.
* Should the sharing link open in a new tab.
protected $open_link_in_new;
* @param int $id Sharing source ID.
* @param array $settings Sharing settings.
public function __construct( $id, array $settings ) {
* Filter the way sharing links open.
* By default, sharing links open in a new window.
* @param bool true Should Sharing links open in a new window. Default to true.
$this->open_link_in_new = apply_filters( 'jetpack_open_sharing_in_new_window', true );
if ( isset( $settings['button_style'] ) ) {
$this->button_style = $settings['button_style'];
if ( isset( $settings['smart'] ) ) {
$this->smart = $settings['smart'];
* Is a service deprecated.
public function is_deprecated() {
* Get the protocol to use for a sharing service, based on the site settings.
return is_ssl() ? 'https' : 'http';
public function get_id() {
* Get unique sharing ID. Similar to get_id().
public function get_class() {
* Get a post's permalink to use for sharing.
* @param int $post_id Post ID.
public function get_share_url( $post_id ) {
* Filter the sharing permalink.
* @param string get_permalink( $post_id ) Post Permalink.
* @param int $post_id Post ID.
* @param int $this->id Sharing ID.
return apply_filters( 'sharing_permalink', get_permalink( $post_id ), $post_id, $this->id );
* Get a post's title to use for sharing.
* @param int $post_id Post ID.
public function get_share_title( $post_id ) {
$post = get_post( $post_id );
* Filter the sharing title.
* @param string $post->post_title Post Title.
* @param int $post_id Post ID.
* @param int $this->id Sharing ID.
$title = apply_filters( 'sharing_title', $post->post_title, $post_id, $this->id );
return html_entity_decode( wp_kses( $title, '' ), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 );
* Get a comma-separated list of the post's tags to use for sharing.
* Prepends a '#' to each tag.
* @param int $post_id Post ID.
public function get_share_tags( $post_id ) {
$tags = get_the_tags( $post_id );
// Camel case the tag name and remove spaces as well as apostrophes.
$tag = preg_replace( '/\s+|\'/', '', ucwords( $tag->name ) );
// Return with a '#' prepended.
* Allow customizing how the list of tags is displayed.
* @param string $tags Comma-separated list of tags.
* @param int $post_id Post ID.
* @param int $this->id Sharing ID.
$tag_list = (string) apply_filters( 'jetpack_sharing_tag_list', implode( ', ', $tags ), $post_id, $this->id );
return html_entity_decode( wp_kses( $tag_list, '' ), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 );
* Does this sharing source have a custom style.
public function has_custom_button_style() {
* Get the HTML markup to display a sharing link.
* @param string $url Post URL to share.
* @param string $text Sharing display text.
* @param string $accessible_name Accessible name for the link.
* @param string $query Additional query arguments to add to the link. They should be in 'foo=bar&baz=1' format.
* @param bool|string $id Sharing ID to include in the data-shared attribute.
* @param array $data_attributes The keys are used as additional attribute names with 'data-' prefix.
* The values are used as the attribute values.
* @return string The HTML for the link.
public function get_link( $url, $text, $accessible_name = '', $query = '', $id = false, $data_attributes = array() ) {
$klasses = array( 'share-' . $this->get_class(), 'sd-button' );
if ( 'icon' === $this->button_style || 'icon-text' === $this->button_style ) {
$klasses[] = 'share-icon';
if ( 'icon' === $this->button_style ) {
if ( true === $this->open_link_in_new ) {
$accessible_name .= __( ' (Opens in new window)', 'jetpack' );
* Filter the sharing display ID.
* @param string|false $id Sharing ID.
* @param object $this Sharing service properties.
* @param array $args Array of sharing service options.
$id = apply_filters( 'jetpack_sharing_display_id', $id, $this, $args );
* Filter the sharing display link.
* @param string $url Post URL.
* @param object $this Sharing service properties.
* @param string|false $id Sharing ID.
* @param array $args Array of sharing service options.
$url = apply_filters( 'sharing_display_link', $url, $this, $id, $args ); // backwards compatibility
* Filter the sharing display link.
* @param string $url Post URL.
* @param object $this Sharing service properties.
* @param string|false $id Sharing ID.
* @param array $args Array of sharing service options.
$url = apply_filters( 'jetpack_sharing_display_link', $url, $this, $id, $args );
* Filter the sharing display query.
* @param string $query Sharing service URL parameter.
* @param object $this Sharing service properties.
* @param string|false $id Sharing ID.
* @param array $args Array of sharing service options.
$query = apply_filters( 'jetpack_sharing_display_query', $query, $this, $id, $args );
if ( ! empty( $query ) ) {
if ( false === stripos( $url, '?' ) ) {
$url .= '&' . $query;
// @phan-suppress-next-line PhanSuspiciousValueComparison
if ( 'text' === $this->button_style ) {
* Filter the sharing display classes.
* @param array $klasses Sharing service classes.
* @param object $this Sharing service properties.
* @param string|false $id Sharing ID.
* @param array $args Array of sharing service options.
$klasses = apply_filters( 'jetpack_sharing_display_classes', $klasses, $this, $id, $args );
* Filter the sharing display title.
* @deprecated 14.6 Use jetpack_sharing_accessible_name instead.
* @param string $title Sharing service title.
* @param object $this Sharing service properties.
* @param string|false $id Sharing ID.
* @param array $args Array of sharing service options.
$accessible_name = apply_filters_deprecated( 'jetpack_sharing_display_title', array( $accessible_name, $this, $id, $args ), '14.6', 'jetpack_sharing_accessible_name' );
* Filter the sharing accessible name.
* @param string $accessible_name Sharing service accessible name.
* @param object $this Sharing service properties.
* @param string|false $id Sharing ID.
* @param array $args Array of sharing service options.
$accessible_name = apply_filters( 'jetpack_sharing_accessible_name', $accessible_name, $this, $id, $args );
* Filter the sharing display text.
* @param string $text Sharing service text.
* @param object $this Sharing service properties.
* @param string|false $id Sharing ID.
* @param array $args Array of sharing service options.
$text = apply_filters( 'jetpack_sharing_display_text', $text, $this, $id, $args );
* Filter the sharing data attributes.
* @param array $data_attributes Attributes supplied from the sharing source.
* Note that 'data-' will be prepended to all keys.
* @param Sharing_Source $this Sharing source instance.
* @param string|false $id Sharing ID.
* @param array $args Array of sharing service options.
$data_attributes = apply_filters( 'jetpack_sharing_data_attributes', (array) $data_attributes, $this, $id, $args );
$id_attr = $id ? esc_attr( $id ) : '';
$encoded_data_attributes = '';
if ( ! empty( $data_attributes ) ) {
// Check for aria-labelledby first, and separate this out.
if ( isset( $data_attributes['aria-labelledby'] ) ) {
$id_attr = $data_attributes['aria-labelledby'];
unset( $data_attributes['aria-labelledby'] );
$encoded_data_attributes = implode(
/** Filter for formatting attributes */
function ( $data_key, $data_value ) {
esc_attr( str_replace( array( ' ', '"' ), '', $data_key ) ),
array_keys( $data_attributes ),
array_values( $data_attributes )
$rel_attr = ( true === $this->open_link_in_new ) ? 'noopener noreferrer' : '';
$target_attr = ( true === $this->open_link_in_new ) ? 'target="_blank"' : '';
$classes = implode( ' ', $klasses );
<span id="%s" hidden>%s</span>
$encoded_data_attributes,
esc_html( $accessible_name ),
* Get an unfiltered post permalink to use when generating a sharing URL with get_link.
* Use instead of get_share_url for non-official styles as get_permalink ensures that process_request
* will be executed more reliably, in the case that the filtered URL uses a service that strips query parameters.
* @param int $post_id Post ID.
* @return string get_permalink( $post_id ) Post permalink.
public function get_process_request_url( $post_id ) {
return get_permalink( $post_id );
abstract public function get_name();
* Get the markup of the sharing button.
* @param WP_Post $post Post object.
abstract public function get_display( $post );
* Add content specific to a service in the head.
public function display_header() {
* Add content specific to a service in the footer.
public function display_footer() {
* Does the service have advanced options.
public function has_advanced_options() {
* Get the AMP specific markup for a sharing button.
* @param \WP_Post $post The current post being viewed.
public function get_amp_display( $post ) {
// Only display markup if we're on a post.
return $this->build_amp_markup();