'; $custom_class = ''; if ( ! empty( $config['selected'] ) ) { $buttons = tve_social_networks_default_html( null, $config ); foreach ( $config['selected'] as $item ) { if ( $item === 'pin_share' && $config['btn_type'] === 'btn_count' ) { $custom_class = 'tve_s_pin_share_count'; } $html .= '
' . $buttons[ $item ] . '
'; } } $html .= '
'; return $html; } /** * * this applied only to default share buttons * * get the default html for each of the social buttons * usually, there would be a
element with some configuration for each social button * * @param string|null $network allows returning the html for just a single button * @param array $config button configuration * @param bool $editor_page whether or not we are on the editor page * * @return array|string */ function tve_social_networks_default_html( $network = null, $config = [], $editor_page = false ) { $defaults = [ 'btn_type' => 'btn', ]; $config = array_merge( $defaults, $config ); if ( ! empty( $network ) && function_exists( 'tve_social_network_default_' . $network ) ) { return call_user_func( 'tve_social_network_default_' . $network, $config, $editor_page ); } $networks = [ 'fb_share', 'fb_like', 'x_share', 'x_follow', 'in_share', 'pin_share', 'xing_share', 'bluesky_share', ]; $html = []; foreach ( $networks as $network ) { $html[ $network ] = call_user_func( 'tve_social_network_default_' . $network, $config, $editor_page ); } return $html; } /** * default fb share button * * @param array $config * * @return string */ function tve_social_network_default_fb_share( $config ) { //this function is also used when the control panel is loaded through AJAX request and we don't have access yet at get_the_ID() function $post_id = get_the_ID(); if ( ! $post_id && ! empty( $_POST['post_id'] ) ) { $post_id = (int) $_POST['post_id']; } return sprintf( '
', ! empty( $config['fb_share']['href'] ) ? $config['fb_share']['href'] : get_permalink( $post_id ), $config['btn_type'] == 'btn' ? 'button' : 'button_count' ); } /** * default fb like button * * @param array $config * * @return string */ function tve_social_network_default_fb_like( $config ) { return sprintf( '
', ! empty( $config['fb_like']['href'] ) ? $config['fb_like']['href'] : '{tcb_post_url}', $config['btn_type'] == 'btn' ? 'button' : 'button_count' ); } /** * default twitter tweet button * * @param array $config * * @return string */ function tve_social_network_default_x_share( $config ) { return sprintf( '', ! empty( $config['x_share']['href'] ) ? 'data-url="' . $config['x_share']['href'] . '"' : '', ! empty( $config['x_share']['tweet'] ) ? 'data-text="' . $config['x_share']['tweet'] . '"' : '', ! empty( $config['x_share']['via'] ) ? 'data-via="' . $config['x_share']['via'] . '"' : '', $config['btn_type'] == 'btn' ? ' data-count="none"' : '' ); } /** * default X (twitter follow button * * @param array $config * * @return string */ function tve_social_network_default_x_follow( $config ) { $username = ! empty( $config['x_follow']['username'] ) ? trim( $config['x_follow']['username'], "@" ) : ""; return sprintf( 'Follow', $username, $config['btn_type'] == 'btn' ? 'data-show-count="false"' : '', ! empty( $config['x_follow']['hide_username'] ) ? 'data-show-screen-name="false"' : '' ); } /** * default linkedin button * * @param array $config * * @return string */ function tve_social_network_default_in_share( $config ) { return sprintf( '', $config['btn_type'] == 'btn_count' ? 'data-counter="right"' : '', ! empty( $config['in_share']['href'] ) ? $config['in_share']['href'] : '{tcb_post_url}' ); } /** * default pinterest button * * @param array $config * @param bool $editor_page * * @return string */ function tve_social_network_default_pin_share( $config, $editor_page ) { $html = sprintf( '', ! empty( $config['pin_share']['href'] ) ? urlencode( $config['pin_share']['href'] ) : '{tcb_encoded_post_url}', ! empty( $config['pin_share']['media'] ) ? $config['pin_share']['media'] : '{tcb_post_image}', ! empty( $config['pin_share']['description'] ) ? $config['pin_share']['description'] : '{tcb_post_title}', $config['btn_type'] == 'btn_count' ? 'data-pin-config="beside" data-pin-zero="true"' : '' ); if ( ! $editor_page ) { $html .= <<< EOT EOT; } return $html; } /** * default xing button * * @param array $config * * @return string */ function tve_social_network_default_xing_share( $config ) { return sprintf( '
', $config['btn_type'] == 'btn_count' ? 'data-counter="true"' : '', ! empty( $config['xing_share']['href'] ) ? $config['xing_share']['href'] : '{tcb_post_url}' ); } /** * default bluesky button * * @param array $config * * @return string */ function tve_social_network_default_bluesky_share( $config ) { return sprintf( '
', $config['btn_type'] == 'btn_count' ? 'data-counter="true"' : '', ! empty( $config['bluesky_share']['href'] ) ? $config['bluesky_share']['href'] : '{tcb_post_url}' ); } /** * fetch and decode a JSON response from a URL * * @param string $url * @param string $fn * * @return array */ function _tve_social_helper_get_json( $url, $fn = 'wp_remote_get' ) { $response = $fn( $url, [ 'sslverify' => false ] ); if ( $response instanceof WP_Error ) { return []; } $body = wp_remote_retrieve_body( $response ); if ( empty( $body ) ) { return []; } $data = json_decode( $body, true ); return empty( $data ) ? [] : $data; } /** * format big numbers in the form of 2.4K * * @param int $count */ function tve_social_count_format( $count ) { $suffixes = [ '', 'K', 'M', 'G' ]; $suffixIndex = 0; while ( $count >= 1000 ) { $suffixIndex ++; $count /= 1000; } return $suffixIndex ? number_format( $count, 1, '.', '' ) . $suffixes[ $suffixIndex ] : $count; } /** * get the cached share count (or, if expired, fetch the count from the API for the network) * * @param mixed|null $post_id * @param string $post_permalink optional, if passed in will be used instead of get_permalink * @param array|string $networks the network to fetch the share count for (can also be an array) * @param bool $force_fetch if true, it will bypass the cache and make the API request * * Allowed values for the network / network keys: * 'fb_share', * 'x_share', * 'pin_share', * 'in_share', * 'xing_share' * * @return array * [fb_share] => $count * [_share] => $count * .. */ function tve_social_get_share_count( $post_id, $post_permalink = null, $networks = null, $force_fetch = false ) { $cache_lifetime = apply_filters( 'thrive_cache_shares_lifetime', 300 ); /* the share count is returned for a URL */ if ( null === $post_permalink ) { $post_permalink = get_permalink( $post_id ); } /** * all possible networks */ $all_networks = [ 'fb_share', 'x_share', 'pin_share', 'in_share', 'xing_share', ]; /* make sure the $networks will be an array */ if ( $networks !== null ) { $networks = is_array( $networks ) ? $networks : [ $networks ]; $networks = array_intersect( $networks, $all_networks ); } else { $networks = $all_networks; } $count = get_post_meta( $post_id, 'thrive_ss_count', true ); /* if no cache or if the URL has changed => re-fetch the whole thing */ if ( empty( $count ) || $count['url'] != $post_permalink ) { $count = []; $force_fetch = true; } /* cache expired => re-fetch */ if ( ! empty( $count['last_fetch'] ) && $count['last_fetch'] < time() - $cache_lifetime ) { $force_fetch = true; } /* check to see if we have all of the required networks added to cache */ if ( ! $force_fetch && ! empty( $count ) ) { foreach ( $networks as $network ) { if ( ! isset( $count[ $network ] ) ) { $force_fetch = true; break; } } } if ( $force_fetch ) { $count['url'] = $post_permalink; $count['last_fetch'] = time(); foreach ( $networks as $network ) { $shares = call_user_func( 'tve_social_fetch_count_' . $network, $post_permalink ); /* do not set the share count if it already exists and the value received from API is 0 */ if ( isset( $count[ $network ] ) && empty( $shares ) ) { continue; } $count[ $network ] = $shares; } update_post_meta( $post_id, 'thrive_ss_count', $count ); } return $count; } /** * get the social share count for a range of networks (array param), for all (empty) or for an individual network (string) * * this triggers API calls to the network * * @param string $url the URL to get the shares for * @param null|array|string $for * * @return array | int | false for error */ function tve_social_fetch_count( $url, $for = null ) { $all = tve_social_get_custom_networks(); $response = []; if ( $for === null ) { foreach ( $all as $network ) { $response[ $network ] = call_user_func( 'tve_social_fetch_count_' . $network, $url ); } return $response; } if ( is_array( $for ) ) { $for = array_intersect( $for, $all ); foreach ( $for as $network ) { $response[ $network ] = call_user_func( 'tve_social_fetch_count_' . $network, $url ); } return $response; } if ( is_string( $for ) && in_array( $for, $all ) ) { return call_user_func( 'tve_social_fetch_count_' . $for, $url ); } return false; } /** * fetch the FB total number of shares for an url * * @param string $url * * @return int */ function tve_social_fetch_count_fb_share( $url ) { /* not nice but the idea would be to use same function */ return tve_dash_fetch_share_count_facebook( $url ); } /** * fetch the total number of shares for an url from twitter * * @param string $url * * @return int */ function tve_social_fetch_count_x_share( $url ) { return 0; } /** * fetch the total number of shares for an url from Pinterest * * @param string $url * * @return int */ function tve_social_fetch_count_pin_share( $url ) { $response = wp_remote_get( 'https://api.pinterest.com/v1/urls/count.json?callback=_&url=' . rawurlencode( $url ), [ 'sslverify' => false, ] ); $body = wp_remote_retrieve_body( $response ); if ( empty( $body ) ) { return 0; } $body = preg_replace( '#_\((.+?)\)$#', '$1', $body ); $data = json_decode( $body, true ); return empty( $data['count'] ) ? 0 : (int) $data['count']; } /** * fetch the total number of shares for an url from LinkedIn * * @param string $url * * @return int */ function tve_social_fetch_count_in_share( $url ) { $data = _tve_social_helper_get_json( 'http://www.linkedin.com/countserv/count/share?format=json&url=' . rawurlencode( $url ) ); return empty( $data['count'] ) ? 0 : (int) $data['count']; } /** * fetch the total number of shares for an url from Xing * * @param string $url * * @return int */ function tve_social_fetch_count_xing_share( $url ) { $response = _tve_social_helper_get_json( 'https://www.xing-share.com/spi/shares/statistics?url=' . rawurlencode( $url ), 'wp_remote_post' ); return isset( $response['share_counter'] ) ? $response['share_counter'] : 0; } /** * entry point for the main ajax request - count social shares * * @param array $current no used * @param array $post_data post data received from the main ajax request * * @see tve_dash_frontend_ajax_load * */ function tve_social_dash_ajax_share_counts( $current, $post_data ) { return tve_social_ajax_count( true, $post_data ); } /** * get the social count an array of networks * * POST['for'] each element is an object : a key-value pair - key=network value=url to get the counts for * * @param bool $return whether to return the counts or send them as json * @param array $post_data allow overriding the default $_POST data */ function tve_social_ajax_count( $return = false, $post_data = null ) { $response = [ 'counts' => [], 'totals' => [], ]; $data = null !== $post_data ? $post_data : $_POST; if ( empty( $data['for'] ) || ! is_array( $data['for'] ) ) { if ( $return ) { return $response; } wp_send_json( $response ); } $url_cache = []; $count_cache = []; foreach ( $data['for'] as $index => $item ) { if ( ! is_array( $item ) ) { continue; } $default = tve_social_get_custom_networks(); $networks = array_intersect( $default, array_keys( $item ) ); $total = 0; $post_permalink = empty( $data['post_id'] ) ? '' : get_permalink( $data['post_id'] ); $response['counts'][ $index ] = []; foreach ( $networks as $network ) { $url = $item[ $network ]; if ( $url == '{tcb_post_url}' ) { $url = $post_permalink; $post_id = $data['post_id']; } else { if ( ! isset( $url_cache[ $url ] ) ) { $url_cache[ $url ] = url_to_postid( $url ); } $post_id = $url_cache[ $url ]; } if ( ! empty( $post_id ) ) { /* get the count value from cache */ if ( ! isset( $count_cache[ $post_id ] ) ) { $count_cache[ $post_id ] = tve_social_get_share_count( $post_id, $url, $networks ); } $count = $count_cache[ $post_id ][ $network ]; } else { $count = call_user_func( 'tve_social_fetch_count_' . $network, $url ); } $total += $count; $response['counts'][ $index ][ $network ] = array( 'value' => $count, 'formatted' => tve_social_count_format( $count ), ); } $response['totals'][ $index ] = array( 'value' => $total, 'formatted' => tve_social_count_format( $total ), ); } if ( $return ) { return $response; } wp_send_json( $response ); }