· 6 years ago · Oct 01, 2019, 04:22 PM
1<?php
2/**
3 * Social Sharing. Class generates sharing buttons.
4 *
5 * @package Social Snap
6 * @author Social Snap
7 * @since 1.0.0
8 * @license GPL-3.0+
9 * @copyright Copyright (c) 2018, Social Snap LLC
10*/
11class SocialSnap_Social_Share {
12
13 /**
14 * Social Networks array.
15 *
16 * @since 1.0.0
17 * @var array
18 */
19 protected $networks;
20
21 /**
22 * Display Positions of share bar.
23 *
24 * @since 1.0.0
25 * @var array
26 */
27 protected $positions;
28
29 /**
30 * Indicator to check if share buttons are placed on the page.
31 *
32 * @since 1.0.0
33 * @var array
34 */
35 protected $is_displayed = false;
36
37 /**
38 * Indicator to check if share counts are displayed.
39 *
40 * @since 1.0.0
41 * @var array
42 */
43 protected $counts_displayed = false;
44
45 /**
46 * Indicator to check if share all is displayed.
47 *
48 * @since 1.0.0
49 * @var array
50 */
51 protected $share_all_popup_displayed = false;
52
53 /**
54 * Primary class constructor.
55 *
56 * @since 1.0.0
57 */
58 public function __construct() {
59
60 if ( is_admin() ) {
61 add_action( 'init', array( $this, 'init'), 20 );
62 add_action( 'init', array( $this, 'display_positions' ), 20 );
63 add_action( 'init', array( $this, 'redirect' ), 999 );
64 } else {
65 add_action( 'wp', array( $this, 'init'), 20 );
66 add_action( 'wp', array( $this, 'display_positions' ), 20 );
67 }
68
69 // Register a shortcode for Social Share.
70 add_shortcode( 'ss_social_share', array( $this, 'register_shortcodes' ) );
71
72 // Add support for Block Editor.
73 add_action( 'plugins_loaded', array( $this, 'block_editor_support' ) );
74
75 // Refresh share count cache.
76 add_action( 'wp_ajax_socialsnap_ss_cache_refresh', array( $this, 'socialsnap_refresh_share_count_cache' ) );
77
78 // Add settings.
79 add_filter( 'socialsnap_settings_config', array( $this, 'add_settings_config' ) );
80 }
81
82 /**
83 * Initialize class variables.
84 *
85 * @since 1.0.0
86 */
87 public function init() {
88
89 // Social networks.
90 $this->networks = apply_filters(
91 'socialsnap_filter_social_share_networks',
92 socialsnap_settings( 'ss_social_share_networks' )
93 );
94
95 // Share buttons positions.
96 $this->positions = socialsnap_get_social_share_positions();
97
98 // Crate marker that shares have expired and to fetch new.
99 if ( ! is_admin() ) {
100 add_action( 'wp_footer', array( $this, 'share_count_cache_expired' ), 99 );
101 }
102
103 // Facebook App authorized for share count.
104 if ( isset( $_GET['ss_network_authorized'], $_GET['access_token'], $_GET['expires_in'] ) && 'facebook_shares' === $_GET['ss_network_authorized'] ) {
105
106 if ( 'never' !== $_GET['expires_in'] ) {
107
108 set_transient(
109 'ss_facebook_token',
110 array(
111 'access_token' => sanitize_text_field( $_GET['access_token'] ),
112 'expires_in' => time() + intval( $_GET['expires_in'] )
113 ),
114 intval( $_GET['expires_in'] ) + MONTH_IN_SECONDS
115 );
116
117 } else {
118
119 set_transient(
120 'ss_facebook_token',
121 array(
122 'access_token' => sanitize_text_field( $_GET['access_token'] ),
123 'expires_in' => 'never'
124 )
125 );
126 }
127
128 }
129 }
130
131 /**
132 * Redirect after authorization.
133 *
134 * @since 1.0.0
135 */
136 public function redirect() {
137
138 // Redirect to the same page without the authorization parameters.
139 if ( isset( $_GET['ss_network_authorized'], $_GET['access_token'], $_GET['expires_in'] ) && 'facebook_shares' === $_GET['ss_network_authorized'] ) {
140
141 wp_redirect( add_query_arg( array( 'page' => 'socialsnap-settings#ss_social_share_networks_display-ss' ), admin_url( 'admin.php' ) ) );
142 exit;
143 }
144 }
145
146 /**
147 * Display Social Sharing buttons on enabled positions in the settings panel.
148 *
149 * @since 1.0.0
150 */
151 public function display_positions() {
152
153 // No positions are enabled.
154 if ( ! is_array( $this->positions ) || empty( $this->positions ) ) {
155 return;
156 }
157
158 // Check AMP pages.
159 if ( socialsnap_is_amp_page() ) {
160 return;
161 }
162
163 add_filter( 'socialsnap_ss_button_data', array( $this, 'add_share_button_api_data' ), 10, 6 );
164 add_filter( 'socialsnap_display_position_classes', array( $this, 'get_display_position_classes' ), 10, 3 );
165
166 // All networks popup.
167 add_action( 'wp_footer', array( $this, 'render_share_all_popup' ), 20 );
168 add_action( 'wp_footer', array( $this, 'render_copy_popup' ), 20 );
169
170 foreach ( $this->positions as $position ) {
171
172 // Check if render method exists.
173 if ( ! method_exists( $this, 'render_position_' . $position ) ) {
174 continue;
175 }
176
177 // Hook into Admin Live Preview.
178 add_action( 'preview_social_share_' . $position, array( $this, 'render_position_' . $position ) );
179
180 // Move on if this position is not enabled.
181 if ( ! socialsnap_settings( 'ss_ss_' . $position . '_enabled' ) ) {
182 continue;
183 }
184
185 switch ( $position ) {
186 case 'sidebar':
187 add_action( 'wp_footer', array( $this, 'render_position_sidebar' ) );
188 break;
189
190 case 'inline_content' :
191
192 if ( ! is_admin() ) {
193
194 if ( is_singular() || socialsnap_settings( 'ss_ss_inline_content_full_content' ) ) {
195 add_filter( 'the_content', array( $this, 'filter_content_inline_content_share' ), 1000 );
196 } else {
197 add_filter( 'the_excerpt', array( $this, 'filter_content_inline_content_share' ), 1000 );
198 }
199 }
200 break;
201
202 case 'on_media' :
203
204 if ( ! is_admin() ) {
205 add_filter( 'the_content', array( $this, 'filter_content_on_media_share' ), 30 );
206 add_filter( 'post_thumbnail_html', array( $this, 'filter_content_on_media_share' ), 30 );
207 add_filter( 'woocommerce_single_product_image_thumbnail_html', array( $this, 'filter_content_on_media_share' ), 30 );
208 }
209 break;
210
211 default:
212 # code...
213 break;
214 }
215 }
216 }
217
218 /**
219 * Determines whether the location should be displayed on this page or not
220 *
221 * @since 1.0.0
222 * @return bool
223 */
224 public function check_display_on( $settings ) {
225
226 if ( ! is_array( $settings ) || empty( $settings ) ) {
227 return false;
228 }
229
230 if ( get_post_meta( get_the_ID(), 'ss_social_share_disable', true ) ) {
231 return false;
232 }
233
234 foreach ( $settings as $key => $value ) {
235
236 if ( ! $value ) {
237 continue;
238 }
239
240 switch( $key ) {
241 case 'home':
242 if ( is_front_page() ) {
243 return true;
244 }
245 break;
246
247 case 'blog':
248 if ( is_home() ) {
249 return true;
250 }
251 break;
252
253 case 'shop' :
254 if ( function_exists( 'is_shop' ) && is_shop() ) {
255 return true;
256 }
257 break;
258
259 default:
260 if ( post_type_exists( $key ) && is_singular( $key ) && ! socialsnap_is_homepage() ) {
261 return true;
262 }
263 break;
264 }
265 }
266
267 return false;
268 }
269
270 /**
271 * Determines whether the share popup html should be printed.
272 * Returns true if at least one All Networks button is enabled.
273 *
274 * @since 1.0.0
275 * @return bool
276 */
277 public function check_display_share_popup() {
278
279 $return = false;
280
281 if ( is_array( $this->positions ) && ! empty( $this->positions ) ) {
282 foreach ( $this->positions as $position ) {
283
284 if ( in_array( $position, array( 'on_media' ) ) ) {
285 continue;
286 }
287
288 $position_enabled = socialsnap_settings( 'ss_ss_' . $position . '_enabled' );
289 $all_networks_enabled = socialsnap_settings( 'ss_ss_' . $position . '_all_networks' );
290 $display = $this->check_display_on( socialsnap_settings( 'ss_ss_' . $position . '_post_types' ) );
291
292 $return = $return || ( $position_enabled && $all_networks_enabled && $display );
293 }
294 }
295
296 return apply_filters( 'socialsnap_display_share_popup', $return );
297 }
298
299 /**
300 * Render popup that displays share buttons for all networks
301 *
302 * @since 1.0.0
303 */
304 public function render_share_all_popup() {
305
306 // No need for this since no share buttons are displayed.
307 if ( ! apply_filters( 'socialsnap_share_all_popup_displayed', $this->share_all_popup_displayed ) ) {
308 return;
309 }
310
311 $all_networks = socialsnap_get_social_share_networks();
312 $post_id = socialsnap_get_current_post_id();
313 $post_title = socialsnap_get_current_page_title();
314 $current_link = socialsnap_get_current_url();
315
316 if ( 0 === $post_id ) {
317 return;
318 }
319
320 ob_start();
321 ?>
322
323 <div id="ss-all-networks-popup" class="ss-popup-overlay" data-nonce="<?php echo wp_create_nonce('socialsnap-ss-counts-refresh'); ?>">
324 <div class="ss-popup">
325
326 <div class="ss-popup-heading">
327 <span><?php _e( 'Share via', 'socialsnap' ); ?></span>
328 <a href="#" id="ss-close-share-networks-modal" class="ss-close-modal" rel="nofollow"><i class="ss ss-close"></i></a>
329 </div><!-- END .ss-popup-heading -->
330
331 <div class="ss-popup-content">
332 <div class="ss-popup-networks ss-clearfix">
333 <?php foreach ( $all_networks as $id => $name ) {
334
335 $permalink = socialsnap_get_shared_permalink( array( 'permalink' => $current_link, 'network' => $id ) );
336 $permalink = apply_filters( 'socialsnap_complete_shared_permalink', $permalink, $id );
337 $share_url = socialsnap_get_share_url( $id, array( 'permalink' => $permalink, 'title' => $post_title, 'location' => 'share_all_popup' ) );
338
339 $additional_data = apply_filters( 'socialsnap_ss_button_data', '', $share_url, $permalink, $id, $post_id, 'popup' );
340 $icon_class = apply_filters( 'socialsnap_social_share_button_class', 'ss-' . $id . '-color', $id, $post_id );
341 ?>
342
343 <div class="ss-popup-network ss-popup-<?php echo esc_attr( $id ); ?>">
344 <a href="#" data-ss-ss-link="<?php echo esc_url( $share_url ); ?>" data-id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $icon_class ); ?>" <?php echo $additional_data; ?> rel="nofollow">
345 <i class="ss ss-<?php echo $id; ?>"></i>
346 <span><?php echo $name; ?></span>
347 <?php /*<span class="ss-popup-network-counter"><?php echo socialsnap_get_share_count( $id, array( 'url' => $permalink, 'post_id' => $post_id ) ); */ ?>
348 </a>
349 </div>
350
351 <?php } ?>
352 </div><!-- END .ss-popup-networks -->
353
354 <?php socialsnap_signature(); ?>
355
356 </div><!-- END .ss-popup-content -->
357 </div><!-- END .ss-popup -->
358 </div><!-- END #ss-all-networks-popup -->
359
360 <?php
361 $output = ob_get_clean();
362
363 echo apply_filters( 'socialsnap_share_all_popup', $output );
364 }
365
366 /**
367 * Render popup that displays the copy link.
368 *
369 * @since 1.1.6
370 */
371 public function render_copy_popup() {
372
373 $post_id = socialsnap_get_current_post_id();
374
375 if ( 0 === $post_id ) {
376 return;
377 }
378
379 $permalink = socialsnap_get_shared_permalink(
380 array(
381 'permalink' => socialsnap_get_current_url(),
382 'network' => 'copy'
383 )
384 );
385 $permalink = apply_filters( 'socialsnap_complete_shared_permalink', $permalink, 'copy' );
386
387 ob_start();
388 ?>
389
390 <div id="ss-copy-popup" class="ss-popup-overlay">
391 <div class="ss-popup">
392
393 <div class="ss-popup-heading">
394 <span><?php esc_html_e( 'Copy link', 'socialsnap' ); ?></span>
395 <a href="#" id="ss-close-share-networks-modal" class="ss-close-modal" rel="nofollow"><i class="ss ss-close"></i></a>
396 </div><!-- END .ss-popup-heading -->
397
398 <div class="ss-popup-content">
399
400 <div class="ss-copy-action">
401 <input type="text" readonly="readonly" value="<?php echo esc_url( $permalink ); ?>" class="ss-copy-action-field" />
402 <a href="#" class="ss-button" rel="nofollow"><?php _e( 'Copy', 'socialsnap' ); ?><span class="ss-share-network-tooltip"><?php _e( 'Copied', 'socialsnap' ); ?></span></a>
403 <i class="ss ss-copy"></i>
404 </div><!-- END .ss-copy-action -->
405
406 <?php socialsnap_signature(); ?>
407
408 </div><!-- END .ss-popup-content -->
409 </div><!-- END .ss-popup -->
410 </div><!-- END #ss-copy-popup -->
411
412 <?php
413 $output = ob_get_clean();
414
415 echo apply_filters( 'socialsnap_copy_popup', $output );
416 }
417
418 /**
419 * Display Social Sharing buttons on a floating sidebar.
420 *
421 * @since 1.0.0
422 */
423 public function render_position_sidebar() {
424
425 if ( ! socialsnap_settings( 'ss_ss_sidebar_enabled' ) && ! is_admin() ) {
426 return;
427 }
428
429 if ( ! is_admin() && ! $this->check_display_on( socialsnap_settings( 'ss_ss_sidebar_post_types' ) ) ) {
430 return;
431 }
432
433 // No networks selected in the settings panel.
434 if ( ! is_array( $this->networks ) || empty( $this->networks ) ) {
435 return;
436 }
437
438 $class = array();
439 $class = apply_filters( 'socialsnap_display_position_classes', $class, 'sidebar' );
440 $class = implode( ' ', $class );
441
442 $atts = apply_filters( 'socialsnap_floating_sidebar_atts', array() );
443 $attributes = '';
444
445 if ( ! empty( $atts ) ) {
446 foreach ( $atts as $key => $value ) {
447 $attributes .= ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
448 }
449 }
450
451 ob_start();
452 ?>
453 <div id="ss-floating-bar" class="<?php echo esc_attr( $class ); ?>"<?php echo $attributes; ?>>
454
455 <?php
456 $this->render_share_count( 'sidebar' );
457 $this->render_social_icons( 'sidebar' );
458 $this->render_view_count( 'sidebar' );
459 ?>
460
461 <span class="ss-hide-floating-bar">
462 <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 370.814 370.814"><path d="M292.92 24.848L268.781 0 77.895 185.401l190.886 185.413 24.139-24.853-165.282-160.56"/></svg>
463 </span>
464
465 </div><!-- END #ss-floating-bar -->
466 <?php
467 $output = ob_get_clean();
468 echo apply_filters( 'socialsnap_social_share_sidebar', $output );
469 }
470
471 /**
472 * Display Social Sharing buttons around content.
473 *
474 * @since 1.0.0
475 */
476 public function render_position_inline_content( $options = array() ) {
477
478 $defaults = array(
479 'share_label' => socialsnap_settings( 'ss_ss_inline_content_share_label' ),
480 'show_total_count' => socialsnap_settings( 'ss_ss_inline_content_total_count' )
481 );
482
483 $options = array_replace_recursive( $defaults, (array) $options );
484
485 $class = array( 'ss-inline-share-wrapper' );
486 $class = apply_filters( 'socialsnap_display_position_classes', $class, 'inline_content', $options );
487 $class = implode( ' ', $class );
488
489 ob_start();
490 ?>
491 <div class="<?php echo $class; ?>">
492
493 <?php // Echo share label
494 if ( $options['share_label'] ) { ?>
495 <p class="ss-social-share-label">
496 <span><?php echo $options['share_label']; ?></span>
497 </p>
498 <?php } ?>
499
500 <div class="ss-inline-share-content">
501
502 <?php $this->render_share_count( 'inline_content', array( 'post_id' => get_the_ID(), 'options' => $options ) ); ?>
503 <?php $this->render_social_icons( 'inline_content', array( 'post_id' => get_the_ID(), 'options' => $options ) ); ?>
504
505 </div><!-- END .ss-inline-share-content -->
506 </div><!-- END .ss-inline-share-wrapper -->
507 <?php
508 $output = ob_get_clean();
509 echo apply_filters( 'socialsnap_social_share_inline_content', $output );
510 }
511
512 /**
513 * Filter content and insert inline social sharing buttons
514 *
515 * @since 1.0.0
516 */
517 public function filter_content_inline_content_share( $content ) {
518
519 if ( ! socialsnap_settings( 'ss_ss_inline_content_enabled' ) && ! is_admin() ) {
520 return $content;
521 }
522
523 if ( ! is_admin() && ! $this->check_display_on( socialsnap_settings( 'ss_ss_inline_content_post_types' ) ) ) {
524 return $content;
525 }
526
527 ob_start();
528 $this->render_position_inline_content();
529 $output = ob_get_clean();
530
531 $inline_location = socialsnap_settings( 'ss_ss_inline_content_location' );
532
533 if ( in_array( $inline_location, array( 'above', 'both' ) ) ) {
534 $content = $output . $content;
535 }
536
537 if ( in_array( $inline_location, array( 'below', 'both' ) ) ) {
538 $content = $content . $output;
539 }
540
541 return $content;
542 }
543
544 /**
545 * Filter content and insert on media sharing buttons
546 *
547 * @since 1.0.0
548 */
549 public function filter_content_on_media_share( $content ) {
550
551 if ( ! socialsnap_settings( 'ss_ss_on_media_enabled' ) ) {
552 return $content;
553 }
554
555 if ( is_admin() ) {
556 return $content;
557 }
558
559 if ( ! is_admin() && ! $this->check_display_on( socialsnap_settings( 'ss_ss_on_media_post_types' ) ) ) {
560 return $content;
561 }
562
563 // Get all imgs from content
564 preg_match_all( '/<img [^>]*>/s', $content, $images_array );
565
566 if ( ! is_array( $images_array ) || empty( $images_array ) ) {
567 return $content;
568 }
569
570 $images_array = array_unique( $images_array[0] );
571
572 foreach ( $images_array as $image ) {
573
574 if ( false !== strpos( $image, 'class="ngg_' ) ) {
575 continue;
576 }
577
578 preg_match( '@src="([^"]+)"@' , $image , $image_src );
579
580 // Check for image src
581 if ( isset( $image_src[1] ) ) {
582 $image_src = $image_src[1];
583 } elseif( isset( $image_src[0] ) ) {
584 $image_src = $image_src[0];
585 } else {
586 return $content;
587 }
588
589 // Get classes from img
590 preg_match( '@class="([^"]+)"@' , $image , $image_classes );
591
592 $image_class = 'ss-on-media-container';
593 $image_wrap_class = 'ss-on-media-image-wrap';
594
595 if ( isset( $image_classes[1] ) ) {
596 $image_class .= ' ' . $image_classes[1];
597 $image_wrap_class .= ' ' . $image_classes[1];
598 }
599
600 ob_start();
601 $this->render_position_on_media( $image_src );
602 $icons = ob_get_clean();
603
604 if ( ! $icons ) {
605 return $content;
606 }
607
608 $replacement = '<div class="' . $image_class . '"><span class="' . $image_wrap_class . '">' . $image . $icons . '</span></div>';
609 $content = str_replace( $image, $replacement, $content );
610 }
611
612 return $content;
613 }
614
615 /**
616 * Display Social Sharing buttons on a media element.
617 *
618 * @since 1.0.0
619 */
620 public function render_position_on_media( $image_src ) {
621
622 $class = array( 'ss-on-media-wrapper' );
623 $class = apply_filters( 'socialsnap_display_position_classes', $class, 'on_media' );
624 $class = implode( ' ', $class );
625
626 $button_type = socialsnap_settings( 'ss_ss_on_media_type' );
627
628 ob_start();
629 ?>
630 <div class="<?php echo $class; ?>">
631
632 <?php
633 if ( 'pin_it' === $button_type || is_admin() ) {
634
635 $share_url = is_admin() ? '#' : socialsnap_get_share_url( 'pinterest', array( 'image' => $image_src, 'location' => 'on_media' ) );
636
637 if ( $share_url ) {
638 ?>
639 <ul class="ss-social-icons-container ss-on-media-pinit">
640 <li>
641 <div data-ss-ss-link="<?php echo $share_url; ?>" class="ss-pinterest-color ss-pinit-button ss-ss-on-media-button">
642 <span class="ss-on-media-content">
643 <i class="ss ss-pinterest"></i><?php apply_filters( 'socialsnap_pinit_text', _e( 'Save', 'socialsnap' ) ); ?>
644 </span>
645 </div>
646 </li>
647 </ul>
648 <?php
649 }
650 }
651
652 if ( 'share_buttons' === $button_type || is_admin() ) {
653 $this->render_social_icons( 'on_media', array( 'image' => $image_src ) );
654 }
655 ?>
656 </div>
657 <?php
658 $output = ob_get_clean();
659 echo apply_filters( 'socialsnap_social_share_on_media', $output );
660 }
661
662 /**
663 * Display Total share count
664 *
665 * @since 1.0.0
666 */
667 protected function render_share_count( $location = null, $settings = array() ) {
668
669 if ( is_null( $location ) ) {
670 return;
671 }
672
673 $defaults = array(
674 'post_id' => socialsnap_get_current_post_id(),
675 'permalink' => socialsnap_get_current_url(),
676 'options' => array(
677 'show_total_count' => socialsnap_settings( 'ss_ss_' . $location . '_total_count' ),
678 'inline_total_style' => socialsnap_settings( 'ss_ss_inline_content_total_share_style' )
679 ),
680 );
681
682 $settings = array_replace_recursive( $defaults, $settings );
683
684 $settings = apply_filters( 'socialsnap_social_share_display_args', $settings );
685
686 if ( ! $settings['post_id'] ) {
687 $settings['post_id'] = socialsnap_get_current_post_id();
688 }
689
690 if ( is_admin() ) {
691 $count = rand( 300, 700 );
692 } else {
693 $count = socialsnap_get_total_share_count( array( 'post_id' => $settings['post_id'] ) );
694 }
695
696 $this->counts_displayed = $this->counts_displayed || $settings['options']['show_total_count'];
697
698 $settings = apply_filters( 'socialsnap_total_share_count_settings', $settings, $location, $count );
699
700 if ( ! $settings['options']['show_total_count'] && ! is_admin() ) {
701 return;
702 }
703
704 $count = socialsnap_format_number( $count );
705
706 if ( 'inline_content' === $location ) { ?>
707
708 <!-- Total share counter -->
709 <div class="ss-inline-counter">
710
711 <?php do_action( 'socialsnap_before_total_share_counter', $location, $settings ); ?>
712
713 <?php } ?>
714
715 <span class="ss-total-counter ss-total-shares ss-share-<?php echo $location; ?>-total-shares" data-ss-ss-post-id="<?php echo $settings['post_id']; ?>">
716 <span><?php echo $count ?></span>
717 <span><?php echo _n( 'Share', 'Shares', $count, 'socialsnap' ); ?></span>
718 </span>
719
720 <?php if ( 'inline_content' === $location ) { ?>
721 </div>
722 <?php }
723
724 do_action( 'socialsnap_after_total_share_counter', $location, $settings );
725 }
726
727 /**
728 * Display View count
729 *
730 * @since 1.0.0
731 */
732 protected function render_view_count( $location = null ) {
733 echo apply_filters( 'socialsnap_view_count', '', $location );
734 }
735
736 /**
737 * Generate list of social sharing icons
738 *
739 * @since 1.0.0
740 */
741 protected function render_social_icons( $location, $data = array() ) {
742
743 // Location is required.
744 if ( ! isset ( $location ) ) {
745 return;
746 }
747
748 // Set the displayed indicator to true.
749 $this->is_displayed = true;
750
751 // Default settings
752 $defaults = array(
753 'post_id' => socialsnap_get_current_post_id(),
754 'permalink' => socialsnap_get_current_url(),
755 'image' => '',
756 'options' => array(
757 'networks' => array(),
758 'share_count' => socialsnap_settings( 'ss_ss_' . $location . '_share_count' ),
759 'tooltip' => socialsnap_settings( 'ss_ss_' . $location . '_label_tooltip' ),
760 'all_networks' => socialsnap_settings( 'ss_ss_' . $location . '_all_networks' ),
761 'inline_button_label' => socialsnap_settings( 'ss_ss_inline_content_button_label' ),
762 'hover_animation' => socialsnap_settings( 'ss_ss_inline_content_hover_animation' ),
763 )
764 );
765
766 // Filter data with the default alues
767 $data = array_replace_recursive( $defaults, $data );
768
769 // Allow modification of data
770 $data = apply_filters( 'socialsnap_social_share_display_args', $data );
771
772 // Set up the Post ID
773 if ( ! $data['post_id'] ) {
774 $data['post_id'] = socialsnap_get_current_post_id( $data['permalink'] );
775 }
776
777 $data['title'] = socialsnap_get_shared_title( array( 'post_id' => $data['post_id'], 'location' => $location ) );
778
779 // No networks specified, take from settings
780 if ( ! is_array( $data['options']['networks'] ) || empty( $data['options']['networks'] ) ) {
781 $data['options']['networks'] = $this->networks;
782 }
783
784 // No networks selected in the settings panel.
785 if ( ! is_array( $data['options']['networks'] ) || empty( $data['options']['networks'] ) ) {
786
787 if ( is_admin() ) {
788 echo '<ul class="ss-social-icons-container"></ul>';
789 }
790
791 return;
792 }
793
794 // Mobile only social networks
795 $mobile_only_networks = socialsnap_get_mobile_only_social_share_networks();
796 $container_class = is_admin() ? ' ' . $location : '';
797 ?>
798
799 <ul class="ss-social-icons-container<?php echo $container_class; ?>">
800
801 <?php
802 // Loop through the networks
803 foreach ( $data['options']['networks'] as $network => $network_settings ) {
804
805 if ( 'order' === $network ) {
806 continue;
807 }
808
809 if ( ! $data['permalink'] ) {
810 $permalink = socialsnap_get_shared_permalink( array( 'network' => $network ) );
811 } else {
812 $permalink = $data['permalink'];
813 }
814
815 $permalink = apply_filters( 'socialsnap_complete_shared_permalink', $permalink, $network );
816
817 $network_settings = wp_parse_args( $network_settings, array(
818 'desktop_visibility' => ! in_array( $network, array_keys( $mobile_only_networks ) ),
819 'text' => socialsnap_get_network_name( $network ),
820 ));
821
822 $hide_class = array();
823
824 if ( ! isset( $network_settings['desktop_visibility'] ) || ! $network_settings['desktop_visibility'] ) {
825 $hide_class[] = 'ss-hide-on-desktop';
826 }
827
828 if ( ( ! isset( $network_settings['mobile_visibility'] ) || ! $network_settings['mobile_visibility'] ) && ! in_array( $network, array_keys( $mobile_only_networks ) ) ) {
829 $hide_class[] = 'ss-hide-on-mobile';
830 }
831
832 $hide_class = implode( ' ', $hide_class );
833 $share_url = is_admin() ? '#' : socialsnap_get_share_url( $network, array( 'image' => $data['image'], 'post_id' => $data['post_id'], 'permalink' => $permalink, 'title' => $data['title'], 'location' => $location ) );
834 $additional_data = apply_filters( 'socialsnap_ss_button_data', '', $share_url, $permalink, $network, $data['post_id'], $location );
835
836 // Share URL not valid, go to next network.
837 if ( ! $share_url ) {
838 continue;
839 }
840 ?>
841 <li class="<?php echo $hide_class; ?>">
842
843 <?php if ( 'on_media' === $location ) { ?>
844
845 <?php $icon_class = apply_filters( 'socialsnap_social_share_button_class', 'ss-ss-on-media-button ss-' . $network . '-color ss-on-media', $network, $data['post_id'] ); ?>
846
847 <div data-ss-ss-link="<?php echo $share_url; ?>" class="<?php echo $icon_class; ?>" <?php echo $additional_data; ?>>
848 <?php } else { ?>
849
850 <?php $icon_class = apply_filters( 'socialsnap_social_share_button_class', 'ss-' . $network . '-color', $network, $data['post_id'] ); ?>
851
852 <a href="#" data-ss-ss-link="<?php echo esc_url( $share_url ); ?>" class="<?php echo esc_attr( $icon_class ); ?>" rel="nofollow" <?php echo $additional_data; ?>>
853 <?php } ?>
854
855 <span class="ss-share-network-content">
856 <i class="ss ss-<?php echo $network; ?>"></i>
857
858 <?php
859 $share_count = socialsnap_get_share_count( $network, array( 'url' => $permalink, 'post_id' => $data['post_id'] ) );
860 $share_count = apply_filters( 'socialsnap_filter_social_share_count', $share_count, $location );
861 $share_count = is_admin() ? rand( 1, 200 ) : $share_count;
862
863 if ( in_array( $location, array( 'inline_content' ) ) ) {
864
865 if ( socialsnap()->pro && ( is_admin() || 'ss-reveal-label' === $data['options']['hover_animation'] ) ) { ?>
866 <span class="ss-reveal-label-wrap">
867 <?php }
868
869 $data['options']['share_count'] = in_array( $data['options']['inline_button_label'], array( 'count', 'both' ) );
870
871 if ( in_array( $data['options']['inline_button_label'], array( 'label', 'both' ) ) || is_admin() ) { ?>
872 <span class="ss-network-label"><?php echo $network_settings['text']; ?></span>
873 <?php }
874 }
875
876 $this->counts_displayed = $this->counts_displayed || $data['options']['share_count'];
877
878 if ( is_admin() || is_numeric( $share_count ) && $data['options']['share_count'] ) { ?>
879 <span class="ss-network-count">
880 <?php echo socialsnap_format_number( (int) $share_count ); ?>
881 </span>
882 <?php }
883
884 if ( socialsnap()->pro && 'ss-reveal-label' === $data['options']['hover_animation'] ) { ?>
885 </span><!-- .ss-reveal-label-wrap -->
886 <?php } ?>
887
888 </span>
889
890 <?php if ( 'on_media' === $location ) { ?>
891 </div>
892 <?php } else { ?>
893 </a>
894 <?php } ?>
895
896 <?php if ( $data['options']['tooltip'] || is_admin() ) { ?>
897 <span class="ss-share-network-tooltip"><?php echo $network_settings['text']; ?></span>
898 <?php } ?>
899 </li>
900 <?php } ?>
901
902 <?php
903 if ( $data['options']['all_networks'] || is_admin() ) {
904
905 $this->share_all_popup_displayed = true;
906
907 $no_label_class = '';
908
909 if ( 'inline_content' == $location && ! socialsnap_settings( 'ss_ss_inline_content_all_networks_label' ) ) {
910 $no_label_class = 'ss-without-all-networks-label ';
911 }
912 ?>
913
914 <li>
915 <a href="#" class="<?php echo $no_label_class; ?>ss-share-all ss-shareall-color" rel="nofollow">
916 <span class="ss-share-network-content">
917 <i class="ss ss-plus"></i>
918
919 <?php
920 if ( 'inline_content' == $location ) { ?>
921 <span class="ss-reveal-label-wrap">
922 <?php
923 if ( $label = socialsnap_settings( 'ss_ss_inline_content_all_networks_label' ) || is_admin() ) { ?>
924 <span class="ss-network-label"><?php echo socialsnap_settings( 'ss_ss_inline_content_all_networks_label' ); ?></span>
925 <?php } ?>
926 </span>
927 <?php } ?>
928 </span>
929 </a>
930
931 <?php if ( $data['options']['tooltip'] || is_admin() ) { ?>
932 <span class="ss-share-network-tooltip"><?php _e( 'More Networks', 'socialsnap' ); ?></span>
933 <?php } ?>
934
935 </li>
936 <?php } ?>
937 </ul>
938 <?php
939 }
940
941 /**
942 * Create array of classes for specified button location
943 *
944 * @since 1.0.0
945 */
946 public function get_display_position_classes( $class = array(), $location = null, $settings = array() ) {
947
948 if ( is_null( $location ) ) {
949 return $class;
950 }
951
952 // Default Settings
953 $defaults = array(
954 'position' => socialsnap_settings( 'ss_ss_' . $location . '_position' ),
955 'button_size' => socialsnap_settings( 'ss_ss_' . $location . '_button_size' ),
956 'button_spacing' => socialsnap_settings( 'ss_ss_' . $location . '_button_spacing' ),
957 'button_shape' => socialsnap_settings( 'ss_ss_' . $location . '_button_shape' ),
958 'hide_on_mobile' => socialsnap_settings( 'ss_ss_' . $location . '_hide_on_mobile' ),
959 'on_media_visibility' => socialsnap_settings( 'ss_ss_on_media_hover' ),
960 'inline_button_label' => socialsnap_settings( 'ss_ss_inline_content_button_label' ),
961 );
962
963 $settings = array_replace_recursive( $defaults, $settings );
964
965 $location_class = str_replace( '_', '-', $location );
966
967 $class[] = 'ss-' . $settings['position'] . '-'. $location_class;
968 $class[] = 'ss-' . $settings['button_size'] . '-icons';
969
970 if ( $settings['hide_on_mobile'] ) {
971 $class[] = 'ss-hide-on-mobile';
972 }
973
974 if ( in_array( $location, array( 'sidebar', 'inline_content', 'on_media' ) ) && $settings['button_spacing'] ) {
975 $class[] = 'ss-with-spacing';
976 }
977
978 if ( in_array( $location, array( 'sidebar', 'inline_content', 'on_media', 'hub' ) ) ) {
979 $class[] = 'ss-' . $settings['button_shape'] . '-icons';
980 }
981
982 if ( 'on_media' === $location && $settings['on_media_visibility'] === 'always' ) {
983 $class[] = 'ss-on-media-always-visible';
984 }
985
986 if ( 'inline_content' === $location ) {
987 if ( 'none' === $settings['inline_button_label'] ) {
988 $class[] = 'ss-without-labels';
989 }
990
991 if ( 'both' === $settings['inline_button_label'] ) {
992 $class[] = 'ss-both-labels';
993 }
994 }
995
996 return apply_filters( 'socialsnap_social_share_class', $class );
997 }
998
999 /**
1000 * Mark button to use API for share count.
1001 *
1002 * @since 1.0.0
1003 */
1004 public function add_share_button_api_data( $data, $url, $permalink, $network, $post_id, $location ) {
1005
1006 $data .= ' data-ss-ss-network-id="' . $network . '"';
1007 $data .= ' data-ss-ss-post-id="' . $post_id . '"';
1008 $data .= ' data-ss-ss-location="' . $location . '"';
1009 $data .= ' data-ss-ss-permalink="' . $permalink . '"';
1010
1011 if ( $network == 'heart' ) {
1012 $data .= ' data-ss-ss-type="like"';
1013 } else {
1014 $data .= ' data-ss-ss-type="share"';
1015 }
1016
1017 $with_api = socialsnap_get_social_share_networks_with_api();
1018
1019 if ( in_array( $network, $with_api ) ) {
1020 $data .= ' data-has-api="true"';
1021 }
1022
1023 return $data;
1024 }
1025
1026 /**
1027 * Javascript Indicator that share count cache has expired.
1028 *
1029 * @since 1.0.0
1030 */
1031 public function share_count_cache_expired() {
1032
1033 // Check AMP pages.
1034 if ( socialsnap_is_amp_page() ) {
1035 return;
1036 }
1037
1038 // No share buttons here.
1039 if ( ! apply_filters( 'socialsnap_share_buttons_displayed', $this->is_displayed ) ) {
1040 return;
1041 }
1042
1043 // No share counts here.
1044 if ( ! apply_filters( 'socialsnap_share_counts_displayed', $this->counts_displayed ) ) {
1045 return;
1046 }
1047
1048 // Skip WooCommerce account page.
1049 if ( function_exists( 'is_account_page' ) && is_account_page() ) {
1050 return;
1051 }
1052
1053 $expired = socialsnap_share_count_expired( socialsnap_get_current_url(), socialsnap_get_current_post_id() );
1054 $post_id = socialsnap_get_current_post_id();
1055
1056 // Only do for published pages.
1057 if ( $post_id > 0 && 'publish' !== get_post_status( $post_id ) ) {
1058 return;
1059 }
1060
1061 ?>
1062 <!-- Social Snap Share count cache indicator -->
1063 <script type="text/javascript">
1064
1065 var SocialSnapURL = window.location.href;
1066 var SocialSnapShareCacheExpired = <?php echo intval( $expired ); ?>;
1067
1068 if ( -1 !== SocialSnapURL.indexOf('?ss_cache_refresh') ) {
1069
1070 SocialSnapShareCacheExpired = true;
1071
1072 } else {
1073
1074 var SocialSnapServerTimestamp = <?php echo time(); ?>;
1075 var SocialSnapBrowserTimestamp = Date.now();
1076
1077 if ( ! SocialSnapBrowserTimestamp ) {
1078 SocialSnapBrowserTimestamp = new Date().getTime();
1079 }
1080
1081 SocialSnapBrowserTimestamp = Math.floor( SocialSnapBrowserTimestamp / 1000 );
1082
1083 SocialSnapShareCacheExpired = SocialSnapShareCacheExpired && ( SocialSnapBrowserTimestamp - SocialSnapServerTimestamp < 60 );
1084 }
1085
1086 </script>
1087 <!-- Social Snap Share count cache indicator -->
1088 <?php
1089 }
1090
1091 /**
1092 * Register shortcode for click to tweet module
1093 *
1094 * @since 1.0.0
1095 */
1096 public function register_shortcodes( $atts ) {
1097
1098 $defaults = array(
1099 'networks' => '',
1100 'align' => socialsnap_settings( 'ss_ss_inline_content_position' ),
1101 'total' => socialsnap_settings( 'ss_ss_inline_content_total_count' ),
1102 'shape' => socialsnap_settings( 'ss_ss_inline_content_button_shape' ),
1103 'size' => socialsnap_settings( 'ss_ss_inline_content_button_size' ),
1104 'labels' => socialsnap_settings( 'ss_ss_inline_content_button_label' ),
1105 'spacing' => socialsnap_settings( 'ss_ss_inline_content_button_spacing' ),
1106 'hide_on_mobile' => socialsnap_settings( 'ss_ss_inline_content_hide_on_mobile' ),
1107 'all_networks' => socialsnap_settings( 'ss_ss_inline_content_all_networks' )
1108 );
1109
1110 $defaults = apply_filters( 'socialsnap_social_share_shortcode_atts', $defaults );
1111
1112 $atts = shortcode_atts(
1113 $defaults,
1114 $atts
1115 );
1116
1117 $networks_default = $this->networks;
1118 $networks_mobile = socialsnap_get_mobile_only_social_share_networks();
1119 $allowed_networks = array_keys( socialsnap_get_social_share_networks() );
1120
1121 if ( '' === $atts['networks'] ) {
1122 $atts['networks'] = $networks_default;
1123 } else {
1124
1125 $networks = explode( ';', strtolower( str_replace( ' ', '', $atts['networks'] ) ) );
1126 $atts['networks'] = array();
1127
1128 if ( is_array( $networks ) && ! empty( $networks ) ) {
1129 foreach ( $networks as $network ) {
1130
1131 if ( ! in_array( $network, $allowed_networks ) ) {
1132 continue;
1133 }
1134
1135 if ( isset ( $networks_default[ $network ] ) ) {
1136 $atts['networks'][ $network ] = $networks_default[ $network ];
1137 } else {
1138 $atts['networks'][ $network ] = array(
1139 'text' => socialsnap_get_network_name( $network ),
1140 'desktop_visibility' => isset( $networks_mobile[ $network ] ) ? false : true,
1141 'mobile_visibility' => true,
1142 );
1143 }
1144 }
1145 }
1146 }
1147
1148 $options = array(
1149 'networks' => $atts['networks'],
1150 'button_shape' => $atts['shape'],
1151 'button_size' => $atts['size'],
1152 'button_spacing' => $atts['spacing'],
1153 'position' => $atts['align'],
1154 'inline_button_label' => $atts['labels'],
1155 'hide_on_mobile' => $atts['hide_on_mobile'],
1156 'show_total_count' => $atts['total'],
1157 'all_networks' => $atts['all_networks'],
1158 'share_label' => false,
1159 );
1160
1161 $options = apply_filters( 'socialsnap_social_share_shotcode_options', $options, $atts );
1162
1163 ob_start();
1164
1165 $this->render_position_inline_content( $options );
1166
1167 return ob_get_clean();
1168 }
1169
1170 /**
1171 * Register Block for Social Share.
1172 *
1173 * @since 1.0.0
1174 */
1175 public function block_editor_support() {
1176
1177 if ( ! function_exists( 'register_block_type' ) ) {
1178 return;
1179 }
1180
1181 register_block_type( 'socialsnap/social-share', array(
1182 'render_callback' => array( $this, 'block_editor_social_share' ),
1183 ) );
1184 }
1185
1186 /**
1187 * Social Share block editor support.
1188 *
1189 * @since 1.0.0
1190 */
1191 public function block_editor_social_share( $attributes ) {
1192 ob_start();
1193
1194 $defaults = array(
1195 'networks' => 'twitter;facebook;linkedin',
1196 'align' => 'left',
1197 'total' => false,
1198 'shape' => 'rounded',
1199 'size' => 'small',
1200 'labels' => 'label',
1201 'spacing' => true,
1202 'hide_on_mobile' => false,
1203 'all_networks' => true,
1204 );
1205
1206 $defaults = apply_filters( 'socialsnap_social_share_block_editor_atts', $defaults );
1207
1208 $attributes['networks'] = isset( $attributes['networks'] ) ? $attributes['networks'] : '';
1209 $attributes['networks'] = preg_replace( '/ |\t/', '', $attributes['networks'] );
1210 $attributes['networks'] = preg_replace( '/\n/', ';', $attributes['networks'] );
1211 $attributes['networks'] = strtolower( $attributes['networks'] );
1212
1213 $attributes = wp_parse_args( $attributes, $defaults );
1214
1215 $shortcode = '[ss_social_share';
1216
1217 foreach ( $attributes as $key => $value ) {
1218 $shortcode .= ' ' . $key . '="' . $value . '"';
1219 }
1220 $shortcode .= ']';
1221
1222 echo do_shortcode( $shortcode );
1223
1224 return ob_get_clean();
1225 }
1226
1227 /**
1228 * Reset flags for share count cache.
1229 *
1230 * @since 1.0.0
1231 */
1232 public function socialsnap_refresh_share_count_cache() {
1233
1234 check_ajax_referer( 'socialsnap-admin' );
1235
1236 if ( ! current_user_can( apply_filters( 'socialsnap_manage_cap', 'manage_options' ) ) ) {
1237 wp_send_json_error( array(
1238 'message' => __( 'Error. Access denied.', 'socialsnap' )
1239 ) );
1240 }
1241
1242 // Reset homepage flag.
1243 update_option( 'socialsnap_homepage_share_count_timestamp', false );
1244
1245 // Reset individual post/page flag.
1246 global $wpdb;
1247
1248 set_time_limit( 300 );
1249
1250 $query = "
1251 SELECT postmeta.post_id, postmeta.meta_value
1252 FROM $wpdb->postmeta postmeta
1253 WHERE postmeta.meta_key = %s
1254 ";
1255
1256 $results = $wpdb->get_results( $wpdb->prepare( $query, 'socialsnap_share_count_timestamp' ) );
1257
1258 if ( ! empty( $results ) ) {
1259 foreach ( $results as $row ) {
1260 update_post_meta( $row->post_id, 'socialsnap_share_count_timestamp', false );
1261 }
1262 }
1263 }
1264
1265 /**
1266 * Modify settings.
1267 *
1268 * @since 1.0.0
1269 * @param array $settings Array of Social Snap settings.
1270 * @return array Modified array of Social Snap settings.
1271 */
1272 public function add_settings_config( $settings ) {
1273
1274 $facebook_token = get_transient( 'ss_facebook_token' );
1275
1276 if ( false !== $facebook_token ) {
1277
1278 $note = array(
1279 'ss_ss_facebook_authorize_note' => array(
1280 'id' => 'ss_ss_facebook_authorize_note',
1281 'name' => '<span class="error">' . esc_html__( 'Authorization expired. ', 'socialsnap' ) . '</span>',
1282 'desc' => __( 'Please authorize again.', 'socialsnap' ),
1283 'type' => 'note',
1284 'dependency' => array(
1285 'element' => 'ss_ss_facebook_count_provider',
1286 'value' => 'authorize',
1287 ),
1288 ),
1289 );
1290
1291 if ( 'never' !== $facebook_token['expires_in'] && time() < intval( $facebook_token['expires_in'] ) ) {
1292 $note['ss_ss_facebook_authorize_note']['name'] = '<span class="ss-bitly-authorized"><i class="dashicons dashicons-yes"></i>' . __( 'Authorized. ', 'socialsnap' ) . '</span>';
1293 $note['ss_ss_facebook_authorize_note']['desc'] = __( 'Expires on ', 'socialsnap' ) . date( 'F j, Y', $facebook_token['expires_in'] ) . '.';
1294
1295 unset( $settings['ss_social_sharing']['fields']['ss_social_share_networks_display']['fields']['ss_ss_facebook_authorize_app'] );
1296 } elseif ( 'never' === $facebook_token['expires_in'] ) {
1297 $note['ss_ss_facebook_authorize_note']['name'] = '<span class="ss-bitly-authorized"><i class="dashicons dashicons-yes"></i>' . __( 'Authorized. ', 'socialsnap' ) . '</span>';
1298 $note['ss_ss_facebook_authorize_note']['desc'] = __( 'Never expires.', 'socialsnap' );
1299
1300 unset( $settings['ss_social_sharing']['fields']['ss_social_share_networks_display']['fields']['ss_ss_facebook_authorize_app'] );
1301 }
1302
1303 // Insert into settings.
1304 $settings['ss_social_sharing']['fields']['ss_social_share_networks_display']['fields'] = socialsnap_array_insert(
1305 $settings['ss_social_sharing']['fields']['ss_social_share_networks_display']['fields'],
1306 $note,
1307 'ss_ss_facebook_count_provider',
1308 'after'
1309 );
1310 }
1311
1312 return $settings;
1313 }
1314}
1315new SocialSnap_Social_Share;