PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 10.8.2
Jetpack – WP Security, Backup, Speed, & Growth v10.8.2
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / modules / sharedaddy / sharing-sources.php

sharing-sources.php in Jetpack – WP Security, Backup, Speed, & Growth 10.8.2, at modules/sharedaddy/sharing-sources.php

2,084 lines 61.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use Automattic\Jetpack\Device_Detection\User_Agent_Info;
4
5 abstract class Sharing_Source {
6 public $button_style;
7 public $smart;
8 protected $open_link_in_new;
9 protected $id;
10
11 public function __construct( $id, array $settings ) {
12 $this->id = $id;
13 /**
14 * Filter the way sharing links open.
15 *
16 * By default, sharing links open in a new window.
17 *
18 * @module sharedaddy
19 *
20 * @since 3.4.0
21 *
22 * @param bool true Should Sharing links open in a new window. Default to true.
23 */
24 $this->open_link_in_new = apply_filters( 'jetpack_open_sharing_in_new_window', true );
25
26 if ( isset( $settings['button_style'] ) ) {
27 $this->button_style = $settings['button_style'];
28 }
29
30 if ( isset( $settings['smart'] ) ) {
31 $this->smart = $settings['smart'];
32 }
33 }
34
35 public function is_deprecated() {
36 return false;
37 }
38
39 public function http() {
40 return is_ssl() ? 'https' : 'http';
41 }
42
43 public function get_id() {
44 return $this->id;
45 }
46
47 public function get_class() {
48 return $this->id;
49 }
50
51 public function get_share_url( $post_id ) {
52 /**
53 * Filter the sharing permalink.
54 *
55 * @module sharedaddy
56 *
57 * @since 1.2.0
58 *
59 * @param string get_permalink( $post_id ) Post Permalink.
60 * @param int $post_id Post ID.
61 * @param int $this->id Sharing ID.
62 */
63 return apply_filters( 'sharing_permalink', get_permalink( $post_id ), $post_id, $this->id );
64 }
65
66 public function get_share_title( $post_id ) {
67 $post = get_post( $post_id );
68 /**
69 * Filter the sharing title.
70 *
71 * @module sharedaddy
72 *
73 * @since 2.8.0
74 *
75 * @param string $post->post_title Post Title.
76 * @param int $post_id Post ID.
77 * @param int $this->id Sharing ID.
78 */
79 $title = apply_filters( 'sharing_title', $post->post_title, $post_id, $this->id );
80
81 return html_entity_decode( wp_kses( $title, null ) );
82 }
83
84 public function has_custom_button_style() {
85 return false;
86 }
87
88 public function get_link( $url, $text, $title, $query = '', $id = false ) {
89 $args = func_get_args();
90 $klasses = array( 'share-' . $this->get_class(), 'sd-button' );
91
92 if ( 'icon' == $this->button_style || 'icon-text' == $this->button_style ) {
93 $klasses[] = 'share-icon';
94 }
95
96 if ( 'icon' == $this->button_style ) {
97 $text = $title;
98 $klasses[] = 'no-text';
99
100 if ( true == $this->open_link_in_new ) {
101 $text .= __( ' (Opens in new window)', 'jetpack' );
102 }
103 }
104
105 /**
106 * Filter the sharing display ID.
107 *
108 * @module sharedaddy
109 *
110 * @since 3.4.0
111 *
112 * @param int|false $id Sharing ID.
113 * @param object $this Sharing service properties.
114 * @param array $args Array of sharing service options.
115 */
116 $id = apply_filters( 'jetpack_sharing_display_id', $id, $this, $args );
117 /**
118 * Filter the sharing display link.
119 *
120 * @module sharedaddy
121 *
122 * @since 2.8.0
123 *
124 * @param string $url Post URL.
125 * @param object $this Sharing service properties.
126 * @param int|false $id Sharing ID.
127 * @param array $args Array of sharing service options.
128 */
129 $url = apply_filters( 'sharing_display_link', $url, $this, $id, $args ); // backwards compatibility
130 /**
131 * Filter the sharing display link.
132 *
133 * @module sharedaddy
134 *
135 * @since 2.8.0
136 *
137 * @param string $url Post URL.
138 * @param object $this Sharing service properties.
139 * @param int|false $id Sharing ID.
140 * @param array $args Array of sharing service options.
141 */
142 $url = apply_filters( 'jetpack_sharing_display_link', $url, $this, $id, $args );
143 /**
144 * Filter the sharing display query.
145 *
146 * @module sharedaddy
147 *
148 * @since 2.8.0
149 *
150 * @param string $query Sharing service URL parameter.
151 * @param object $this Sharing service properties.
152 * @param int|false $id Sharing ID.
153 * @param array $args Array of sharing service options.
154 */
155 $query = apply_filters( 'jetpack_sharing_display_query', $query, $this, $id, $args );
156
157 if ( ! empty( $query ) ) {
158 if ( false === stripos( $url, '?' ) ) {
159 $url .= '?' . $query;
160 } else {
161 $url .= '&amp;' . $query;
162 }
163 }
164
165 if ( 'text' == $this->button_style ) {
166 $klasses[] = 'no-icon';
167 }
168
169 /**
170 * Filter the sharing display classes.
171 *
172 * @module sharedaddy
173 *
174 * @since 3.4.0
175 *
176 * @param array $klasses Sharing service classes.
177 * @param object $this Sharing service properties.
178 * @param int|false $id Sharing ID.
179 * @param array $args Array of sharing service options.
180 */
181 $klasses = apply_filters( 'jetpack_sharing_display_classes', $klasses, $this, $id, $args );
182 /**
183 * Filter the sharing display title.
184 *
185 * @module sharedaddy
186 *
187 * @since 3.4.0
188 *
189 * @param string $title Sharing service title.
190 * @param object $this Sharing service properties.
191 * @param int|false $id Sharing ID.
192 * @param array $args Array of sharing service options.
193 */
194 $title = apply_filters( 'jetpack_sharing_display_title', $title, $this, $id, $args );
195 /**
196 * Filter the sharing display text.
197 *
198 * @module sharedaddy
199 *
200 * @since 3.4.0
201 *
202 * @param string $text Sharing service text.
203 * @param object $this Sharing service properties.
204 * @param int|false $id Sharing ID.
205 * @param array $args Array of sharing service options.
206 */
207 $text = apply_filters( 'jetpack_sharing_display_text', $text, $this, $id, $args );
208
209 return sprintf(
210 '<a rel="nofollow%s" data-shared="%s" class="%s" href="%s"%s title="%s"><span%s>%s</span></a>',
211 ( true == $this->open_link_in_new ) ? ' noopener noreferrer' : '',
212 ( $id ? esc_attr( $id ) : '' ),
213 implode( ' ', $klasses ),
214 $url,
215 ( true == $this->open_link_in_new ) ? ' target="_blank"' : '',
216 $title,
217 ( 'icon' == $this->button_style ) ? '></span><span class="sharing-screen-reader-text"' : '',
218 $text
219 );
220 }
221
222 /**
223 * Get an unfiltered post permalink to use when generating a sharing URL with get_link.
224 * Use instead of get_share_url for non-official styles as get_permalink ensures that process_request
225 * will be executed more reliably, in the case that the filtered URL uses a service that strips query parameters.
226 *
227 * @since 3.7.0
228 * @param int $post_id Post ID.
229 * @uses get_permalink
230 * @return string get_permalink( $post_id ) Post permalink.
231 */
232 public function get_process_request_url( $post_id ) {
233 return get_permalink( $post_id );
234 }
235
236 abstract public function get_name();
237 abstract public function get_display( $post );
238
239 public function display_header() {
240 }
241
242 public function display_footer() {
243 }
244
245 public function has_advanced_options() {
246 return false;
247 }
248
249 /**
250 * Get the AMP specific markup for a sharing button.
251 *
252 * @param \WP_Post $post The current post being viewed.
253 */
254 public function get_amp_display( $post ) {
255 // Only display markup if we're on a post.
256 if ( empty( $post ) ) {
257 return false;
258 }
259
260 return $this->build_amp_markup();
261 }
262
263 /**
264 * Generates and returns the markup for an AMP sharing button.
265 *
266 * @param array $attrs Custom attributes for rendering the social icon.
267 */
268 protected function build_amp_markup( $attrs = array() ) {
269
270 $title = sprintf(
271 /* translators: placeholder is a service name, such as "Twitter" or "Facebook". */
272 __( 'Click to share on %s', 'jetpack' ),
273 $this->get_name()
274 );
275
276 $attrs = array_merge(
277 array(
278 'type' => $this->get_id(),
279 'height' => '32px',
280 'width' => '32px',
281 'aria-label' => $title,
282 'title' => $title,
283 ),
284 $attrs
285 );
286 $sharing_link = '<amp-social-share';
287 foreach ( $attrs as $key => $value ) {
288 $sharing_link .= sprintf( ' %s="%s"', sanitize_key( $key ), esc_attr( $value ) );
289 }
290 $sharing_link .= '></amp-social-share>';
291 return $sharing_link;
292 }
293
294 public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
295 $text = '&nbsp;';
296 $button_style = ( ! empty( $button_style ) ) ? $button_style : $this->button_style;
297 if ( ! $this->smart && ! $force_smart ) {
298 if ( $button_style != 'icon' ) {
299 $text = $this->get_name();
300 }
301 }
302
303 $klasses = array( 'share-' . $this->get_class(), 'sd-button' );
304
305 if ( $button_style == 'icon' || $button_style == 'icon-text' ) {
306 $klasses[] = 'share-icon';
307 }
308
309 if ( $button_style == 'icon' ) {
310 $klasses[] = 'no-text';
311 }
312
313 if ( $button_style == 'text' ) {
314 $klasses[] = 'no-icon';
315 }
316
317 $is_deprecated = $this->is_deprecated();
318
319 $link = sprintf(
320 '<a rel="nofollow" class="%s" href="javascript:void(0)" title="%s"><span>%s</span></a>',
321 implode( ' ', $klasses ),
322 esc_attr(
323 $is_deprecated
324 /* translators: %1$s is the name of a deprecated Sharing Service like "Google+" */
325 ? sprintf( __( 'The %1$s service has shut down. This sharing button is not displayed to your visitors and should be removed.', 'jetpack' ), $this->get_name() )
326 : $this->get_name()
327 ),
328 esc_html(
329 $is_deprecated
330 /* translators: %1$s is the name of a deprecated Sharing Service like "Google+" */
331 ? sprintf( __( '%1$s has shut down', 'jetpack' ), $this->get_name() )
332 : $text
333 )
334 );
335
336 $smart = ( $this->smart || $force_smart ) ? 'on' : 'off';
337 $return = "<div class='option option-smart-$smart'>$link</div>";
338 if ( $echo ) {
339 echo $return;
340 }
341
342 return $return;
343 }
344
345 public function get_total( $post = false ) {
346 global $wpdb, $blog_id;
347
348 $name = strtolower( $this->get_id() );
349
350 if ( $post == false ) {
351 // get total number of shares for service
352 return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND share_service = %s', $blog_id, $name ) );
353 }
354
355 // get total shares for a post
356 return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT count FROM sharing_stats WHERE blog_id = %d AND post_id = %d AND share_service = %s', $blog_id, $post->ID, $name ) );
357 }
358
359 public function get_posts_total() {
360 global $wpdb, $blog_id;
361
362 $totals = array();
363 $name = strtolower( $this->get_id() );
364
365 $my_data = $wpdb->get_results( $wpdb->prepare( 'SELECT post_id as id, SUM( count ) as total FROM sharing_stats WHERE blog_id = %d AND share_service = %s GROUP BY post_id ORDER BY count DESC ', $blog_id, $name ) );
366
367 if ( ! empty( $my_data ) ) {
368 foreach ( $my_data as $row ) {
369 $totals[] = new Sharing_Post_Total( $row->id, $row->total );
370 }
371 }
372
373 usort( $totals, array( 'Sharing_Post_Total', 'cmp' ) );
374
375 return $totals;
376 }
377
378 public function process_request( $post, array $post_data ) {
379 /**
380 * Fires when a post is shared via one of the sharing buttons.
381 *
382 * @module sharedaddy
383 *
384 * @since 1.1.0
385 *
386 * @param array $args Aray of information about the sharing service.
387 */
388 do_action( 'sharing_bump_stats', array( 'service' => $this, 'post' => $post ) );
389 }
390
391 /**
392 * Redirect to an external social network site to finish sharing.
393 *
394 * @param string $url Sharing URL for a given service.
395 */
396 public function redirect_request( $url ) {
397 wp_redirect( $url ); // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect -- We allow external redirects here; we define them ourselves.
398
399 // We set up this custom header to indicate to search engines not to index this page.
400 header( 'X-Robots-Tag: noindex, nofollow' );
401 die();
402 }
403
404 public function js_dialog( $name, $params = array() ) {
405 if ( true !== $this->open_link_in_new ) {
406 return;
407 }
408
409 $defaults = array(
410 'menubar' => 1,
411 'resizable' => 1,
412 'width' => 600,
413 'height' => 400,
414 );
415 $params = array_merge( $defaults, $params );
416 $opts = array();
417 foreach ( $params as $key => $val ) {
418 $opts[] = "$key=$val";
419 }
420 $opts = implode( ',', $opts );
421
422 // Add JS after sharing-js has been enqueued.
423 wp_add_inline_script( 'sharing-js',
424 "var windowOpen;
425 ( function () {
426 function matches( el, sel ) {
427 return !! (
428 el.matches && el.matches( sel ) ||
429 el.msMatchesSelector && el.msMatchesSelector( sel )
430 );
431 }
432
433 document.body.addEventListener( 'click', function ( event ) {
434 if ( ! event.target ) {
435 return;
436 }
437
438 var el;
439 if ( matches( event.target, 'a.share-$name' ) ) {
440 el = event.target;
441 } else if ( event.target.parentNode && matches( event.target.parentNode, 'a.share-$name' ) ) {
442 el = event.target.parentNode;
443 }
444
445 if ( el ) {
446 event.preventDefault();
447
448 // If there's another sharing window open, close it.
449 if ( typeof windowOpen !== 'undefined' ) {
450 windowOpen.close();
451 }
452 windowOpen = window.open( el.getAttribute( 'href' ), 'wpcom$name', '$opts' );
453 return false;
454 }
455 } );
456 } )();"
457 );
458 }
459 }
460
461 abstract class Deprecated_Sharing_Source extends Sharing_Source {
462 public $button_style = 'text';
463 public $smart = false;
464 protected $open_link_in_new = false;
465 protected $id;
466 protected $deprecated = true;
467
468 final public function __construct( $id, array $settings ) {
469 $this->id = $id;
470
471 if ( isset( $settings['button_style'] ) ) {
472 $this->button_style = $settings['button_style'];
473 }
474 }
475
476 final public function is_deprecated() {
477 return true;
478 }
479
480 final public function get_share_url( $post_id ) {
481 return get_permalink( $post_id );
482 }
483
484 /**
485 * No AMP display for deprecated sources.
486 *
487 * @param \WP_Post $post The current post being viewed.
488 */
489 final public function get_amp_display( $post ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
490 return false;
491 }
492
493 final public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
494 return parent::display_preview( $echo, false, $button_style );
495 }
496
497 final public function get_total( $post = false ) {
498 return 0;
499 }
500
501 final public function get_posts_total() {
502 return 0;
503 }
504
505 final public function process_request( $post, array $post_data ) {
506 parent::process_request( $post, $post_data );
507 }
508
509 final public function get_display( $post ) {
510 if ( current_user_can( 'manage_options' ) ) {
511 return $this->display_deprecated( $post );
512 }
513
514 return '';
515 }
516
517 public function display_deprecated( $post ) {
518 return $this->get_link(
519 $this->get_share_url( $post->ID ),
520 /* translators: %1$s is the name of a deprecated Sharing Service like "Google+" */
521 sprintf( __( '%1$s has shut down', 'jetpack' ), $this->get_name() ),
522 /* translators: %1$s is the name of a deprecated Sharing Service like "Google+" */
523 sprintf( __( 'The %1$s service has shut down. This sharing button is not displayed to your visitors and should be removed.', 'jetpack' ), $this->get_name() )
524 );
525 }
526 }
527
528 abstract class Sharing_Advanced_Source extends Sharing_Source {
529 public function has_advanced_options() {
530 return true;
531 }
532
533 abstract public function display_options();
534 abstract public function update_options( array $data );
535 abstract public function get_options();
536 }
537
538 class Share_Email extends Sharing_Source {
539 public $shortname = 'email';
540 public $icon = '\f410';
541 public function __construct( $id, array $settings ) {
542 parent::__construct( $id, $settings );
543
544 if ( 'official' == $this->button_style ) {
545 $this->smart = true;
546 } else {
547 $this->smart = false;
548 }
549 }
550
551 public function get_name() {
552 return _x( 'Email', 'as sharing source', 'jetpack' );
553 }
554
555 // Default does nothing
556 public function process_request( $post, array $post_data ) {
557 $ajax = false;
558 if ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) == 'xmlhttprequest' ) {
559 $ajax = true;
560 }
561
562 $source_email = $target_email = $source_name = false;
563
564 if ( isset( $post_data['source_email'] ) && is_email( $post_data['source_email'] ) ) {
565 $source_email = $post_data['source_email'];
566 }
567
568 if ( isset( $post_data['target_email'] ) && is_email( $post_data['target_email'] ) ) {
569 $target_email = $post_data['target_email'];
570 }
571
572 if ( isset( $post_data['source_name'] ) && strlen( $post_data['source_name'] ) < 200 ) {
573 $source_name = $post_data['source_name'];
574 } elseif ( isset( $post_data['source_name'] ) ) {
575 $source_name = substr( $post_data['source_name'], 0, 200 );
576 } else {
577 $source_name = '';
578 }
579
580 // Test email
581 $error = 1; // Failure in data
582 if ( empty( $post_data['source_f_name'] ) && $source_email && $target_email && $source_name ) {
583 /**
584 * Allow plugins to stop the email sharing button from running the shared message through Akismet.
585 *
586 * @module sharedaddy
587 *
588 * @since 1.1.0
589 *
590 * @param bool true Should we check if the message isn't spam?
591 * @param object $post Post information.
592 * @param array $post_data Information about the shared message.
593 */
594 if ( apply_filters( 'sharing_email_check', true, $post, $post_data ) ) {
595 $data = array(
596 'post' => $post,
597 'source' => $source_email,
598 'target' => $target_email,
599 'name' => $source_name,
600 'sharing_source' => $this,
601 );
602 // todo: implement an error message when email doesn't get sent.
603 /**
604 * Filter whether an email can be sent from the Email sharing button.
605 *
606 * @module sharedaddy
607 *
608 * @since 1.1.0
609 *
610 * @param array $data Array of information about the shared message.
611 */
612 if ( ( $data = apply_filters( 'sharing_email_can_send', $data ) ) !== false ) {
613 // Record stats
614 parent::process_request( $data['post'], $post_data );
615
616 /**
617 * Fires when an email is sent via the Email sharing button.
618 *
619 * @module sharedaddy
620 *
621 * @since 1.1.0
622 *
623 * @param array $data Array of information about the shared message.
624 */
625 do_action( 'sharing_email_send_post', $data );
626 }
627
628 // Return a positive regardless of whether the user is subscribed or not
629 if ( $ajax ) {
630 ?>
631 <div class="response">
632 <div class="response-title"><?php _e( 'This post has been shared!', 'jetpack' ); ?></div>
633 <div class="response-sub"><?php printf( __( 'You have shared this post with %s', 'jetpack' ), esc_html( $target_email ) ); ?></div>
634 <div class="response-close"><a href="#" class="sharing_cancel"><?php _e( 'Close', 'jetpack' ); ?></a></div>
635 </div>
636 <?php
637 } else {
638 wp_safe_redirect( get_permalink( $post->ID ) . '?shared=email' );
639 }
640
641 die();
642 } else {
643 $error = 2; // Email check failed
644 }
645 }
646
647 if ( $ajax ) {
648 echo $error;
649 } else {
650 wp_safe_redirect( get_permalink( $post->ID ) . '?shared=email&msg=fail' );
651 }
652
653 die();
654 }
655
656 public function get_display( $post ) {
657 return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Email', 'share to', 'jetpack' ), __( 'Click to email this to a friend', 'jetpack' ), 'share=email' );
658 }
659
660 /**
661 * AMP display for email.
662 *
663 * @param \WP_Post $post The current post being viewed.
664 */
665 public function get_amp_display( $post ) { // phpcs:ignore
666 $attrs = array(
667 // Prevents an empty window from opening on desktop: https://github.com/ampproject/amphtml/issues/9157.
668 'data-target' => '_self',
669 );
670
671 return $this->build_amp_markup( $attrs );
672 }
673
674 /**
675 * Outputs the hidden email dialog
676 */
677 public function display_footer() {
678 global $current_user;
679
680 $visible = $status = false;
681 ?>
682 <div id="sharing_email" style="display: none;">
683 <form action="<?php echo esc_url( $_SERVER['REQUEST_URI'] ); ?>" method="post">
684 <label for="target_email"><?php _e( 'Send to Email Address', 'jetpack' ) ?></label>
685 <input type="email" name="target_email" id="target_email" value="" />
686
687 <?php if ( is_user_logged_in() ) : ?>
688 <input type="hidden" name="source_name" value="<?php echo esc_attr( $current_user->display_name ); ?>" />
689 <input type="hidden" name="source_email" value="<?php echo esc_attr( $current_user->user_email ); ?>" />
690 <?php else : ?>
691
692 <label for="source_name"><?php _e( 'Your Name', 'jetpack' ) ?></label>
693 <input type="text" name="source_name" id="source_name" value="" />
694
695 <label for="source_email"><?php _e( 'Your Email Address', 'jetpack' ) ?></label>
696 <input type="email" name="source_email" id="source_email" value="" />
697
698 <?php endif; ?>
699 <input type="text" id="jetpack-source_f_name" name="source_f_name" class="input" value="" size="25" autocomplete="off" title="<?php esc_attr_e( 'This field is for validation and should not be changed', 'jetpack' ); ?>" />
700 <?php
701 /**
702 * Fires when the Email sharing dialog is loaded.
703 *
704 * @module sharedaddy
705 *
706 * @since 1.1.0
707 *
708 * @param string jetpack Eail sharing source.
709 */
710 do_action( 'sharing_email_dialog', 'jetpack' );
711 ?>
712
713 <img style="float: right; display: none" class="loading" src="<?php
714 /** This filter is documented in modules/stats.php */
715 echo apply_filters( 'jetpack_static_url', plugin_dir_url( __FILE__ ) . 'images/loading.gif' ); ?>" alt="loading" width="16" height="16" />
716 <input type="submit" value="<?php esc_attr_e( 'Send Email', 'jetpack' ); ?>" class="sharing_send" />
717 <a rel="nofollow" href="#cancel" class="sharing_cancel" role="button"><?php _e( 'Cancel', 'jetpack' ); ?></a>
718
719 <div class="errors errors-1" style="display: none;">
720 <?php _e( 'Post was not sent - check your email addresses!', 'jetpack' ); ?>
721 </div>
722
723 <div class="errors errors-2" style="display: none;">
724 <?php _e( 'Email check failed, please try again', 'jetpack' ); ?>
725 </div>
726
727 <div class="errors errors-3" style="display: none;">
728 <?php _e( 'Sorry, your blog cannot share posts by email.', 'jetpack' ); ?>
729 </div>
730 </form>
731 </div>
732 <?php
733 }
734 }
735
736 class Share_Twitter extends Sharing_Source {
737 public $shortname = 'twitter';
738 public $icon = '\f202';
739 // 'https://dev.twitter.com/rest/reference/get/help/configuration' ( 2015/02/06 ) short_url_length is 22, short_url_length_https is 23
740 public $short_url_length = 24;
741
742 public function __construct( $id, array $settings ) {
743 parent::__construct( $id, $settings );
744
745 if ( 'official' == $this->button_style ) {
746 $this->smart = true;
747 } else {
748 $this->smart = false;
749 }
750 }
751
752 public function get_name() {
753 return __( 'Twitter', 'jetpack' );
754 }
755
756 /**
757 * Determine the Twitter 'via' value for a post.
758 *
759 * @param WP_Post|int $post Post object or post ID.
760 * @return string Twitter handle without the preceding @.
761 **/
762 public static function sharing_twitter_via( $post ) {
763 $post = get_post( $post );
764 /**
765 * Allow third-party plugins to customize the Twitter username used as "twitter:site" Twitter Card Meta Tag.
766 *
767 * @module sharedaddy
768 *
769 * @since 3.0.0
770 *
771 * @param string $string Twitter Username.
772 * @param array $args Array of Open Graph Meta Tags and Twitter Cards tags.
773 */
774 $twitter_site_tag_value = apply_filters(
775 'jetpack_twitter_cards_site_tag',
776 '',
777 /** This action is documented in modules/sharedaddy/sharing-sources.php */
778 array( 'twitter:creator' => apply_filters( 'jetpack_sharing_twitter_via', '', $post->ID ) )
779 );
780
781 /*
782 * Hack to remove the unwanted behavior of adding 'via @jetpack' which
783 * was introduced with the adding of the Twitter cards.
784 * This should be a temporary solution until a better method is setup.
785 */
786 if ( 'jetpack' == $twitter_site_tag_value ) {
787 $twitter_site_tag_value = '';
788 }
789
790 /**
791 * Filters the Twitter username used as "via" in the Twitter sharing button.
792 *
793 * @module sharedaddy
794 *
795 * @since 1.7.0
796 *
797 * @param string $twitter_site_tag_value Twitter Username.
798 * @param int $post->ID Post ID.
799 */
800 $twitter_site_tag_value = apply_filters( 'jetpack_sharing_twitter_via', $twitter_site_tag_value, $post->ID );
801
802 // Strip out anything other than a letter, number, or underscore.
803 // This will prevent the inadvertent inclusion of an extra @, as well as normalizing the handle.
804 return preg_replace( '/[^\da-z_]+/i', '', $twitter_site_tag_value );
805 }
806
807 /**
808 * Determine the 'related' Twitter accounts for a post.
809 *
810 * @param WP_Post|int $post Post object or post ID.
811 * @return string Comma-separated list of Twitter handles.
812 **/
813 public static function get_related_accounts( $post ) {
814 $post = get_post( $post );
815 /**
816 * Filter the list of related Twitter accounts added to the Twitter sharing button.
817 *
818 * @module sharedaddy
819 *
820 * @since 1.7.0
821 *
822 * @param array $args Array of Twitter usernames. Format is 'username' => 'Optional description'
823 * @param int $post->ID Post ID.
824 */
825 $related_accounts = apply_filters( 'jetpack_sharing_twitter_related', array(), $post->ID );
826
827 // Example related string: account1,account2:Account 2 description,account3
828 $related = array();
829
830 foreach ( $related_accounts as $related_account_username => $related_account_description ) {
831 // Join the description onto the end of the username
832 if ( $related_account_description ) {
833 $related_account_username .= ':' . $related_account_description;
834 }
835
836 $related[] = $related_account_username;
837 }
838
839 return implode( ',', $related );
840 }
841
842 public function get_display( $post ) {
843 $via = $this->sharing_twitter_via( $post );
844
845 if ( $via ) {
846 $via = 'data-via="' . esc_attr( $via ) . '"';
847 } else {
848 $via = '';
849 }
850
851 $related = $this->get_related_accounts( $post );
852 if ( ! empty( $related ) && $related !== $via ) {
853 $related = 'data-related="' . esc_attr( $related ) . '"';
854 } else {
855 $related = '';
856 }
857
858 if ( $this->smart ) {
859 $share_url = $this->get_share_url( $post->ID );
860 $post_title = $this->get_share_title( $post->ID );
861 return sprintf(
862 '<a href="https://twitter.com/share" class="twitter-share-button" data-url="%1$s" data-text="%2$s" %3$s %4$s>Tweet</a>',
863 esc_url( $share_url ),
864 esc_attr( $post_title ),
865 $via,
866 $related
867 );
868 } else {
869 if (
870 /**
871 * Allow plugins to disable sharing counts for specific sharing services.
872 *
873 * @module sharedaddy
874 *
875 * @since 3.0.0
876 *
877 * @param bool true Should sharing counts be enabled for this specific service. Default to true.
878 * @param int $post->ID Post ID.
879 * @param string $str Sharing service name.
880 */
881 apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'twitter' )
882 ) {
883 sharing_register_post_for_share_counts( $post->ID );
884 }
885 return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Twitter', 'share to', 'jetpack' ), __( 'Click to share on Twitter', 'jetpack' ), 'share=twitter', 'sharing-twitter-' . $post->ID );
886 }
887 }
888
889 public function process_request( $post, array $post_data ) {
890 $post_title = $this->get_share_title( $post->ID );
891 $post_link = $this->get_share_url( $post->ID );
892
893 if ( function_exists( 'mb_stripos' ) ) {
894 $strlen = 'mb_strlen';
895 $substr = 'mb_substr';
896 } else {
897 $strlen = 'strlen';
898 $substr = 'substr';
899 }
900
901 $via = $this->sharing_twitter_via( $post );
902 $related = $this->get_related_accounts( $post );
903 if ( $via ) {
904 $sig = " via @$via";
905 if ( $related === $via ) {
906 $related = false;
907 }
908 } else {
909 $via = false;
910 $sig = '';
911 }
912
913 $suffix_length = $this->short_url_length + $strlen( $sig );
914 // $sig is handled by twitter in their 'via' argument.
915 // $post_link is handled by twitter in their 'url' argument.
916 if ( 280 < $strlen( $post_title ) + $suffix_length ) {
917 // The -1 is for "\xE2\x80\xA6", a UTF-8 ellipsis.
918 $text = $substr( $post_title, 0, 280 - $suffix_length - 1 ) . "\xE2\x80\xA6";
919 } else {
920 $text = $post_title;
921 }
922
923 // Record stats
924 parent::process_request( $post, $post_data );
925
926 $url = $post_link;
927 $twitter_url = add_query_arg(
928 rawurlencode_deep( array_filter( compact( 'via', 'related', 'text', 'url' ) ) ),
929 'https://twitter.com/intent/tweet'
930 );
931
932 parent::redirect_request( $twitter_url );
933 }
934
935 public function has_custom_button_style() {
936 return $this->smart;
937 }
938
939 public function display_footer() {
940 if ( $this->smart ) {
941 ?>
942 <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
943 <?php
944 } else {
945 $this->js_dialog( $this->shortname, array( 'height' => 350 ) );
946 }
947 }
948 }
949
950
951 class Share_Reddit extends Sharing_Source {
952 public $shortname = 'reddit';
953 public $icon = '\f222';
954 public function __construct( $id, array $settings ) {
955 parent::__construct( $id, $settings );
956
957 if ( 'official' == $this->button_style ) {
958 $this->smart = true;
959 } else {
960 $this->smart = false;
961 }
962 }
963
964 public function get_name() {
965 return __( 'Reddit', 'jetpack' );
966 }
967
968 public function get_display( $post ) {
969 if ( $this->smart ) {
970 return '<div class="reddit_button"><iframe src="' . $this->http() . '://www.reddit.com/static/button/button1.html?newwindow=true&width=120&amp;url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&amp;title=' . rawurlencode( $this->get_share_title( $post->ID ) ) . '" height="22" width="120" scrolling="no" frameborder="0"></iframe></div>';
971 } else {
972 return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Reddit', 'share to', 'jetpack' ), __( 'Click to share on Reddit', 'jetpack' ), 'share=reddit' );
973 }
974 }
975
976 /**
977 * AMP display for Reddit.
978 *
979 * @param \WP_Post $post The current post being viewed.
980 */
981 public function get_amp_display( $post ) {
982 $attrs = array(
983 'data-share-endpoint' => esc_url_raw( 'https://reddit.com/submit?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) ) ),
984 );
985
986 return $this->build_amp_markup( $attrs );
987 }
988
989 public function process_request( $post, array $post_data ) {
990 $reddit_url = $this->http() . '://reddit.com/submit?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) );
991
992 // Record stats
993 parent::process_request( $post, $post_data );
994
995 parent::redirect_request( $reddit_url );
996 }
997 }
998
999 class Share_LinkedIn extends Sharing_Source {
1000 public $shortname = 'linkedin';
1001 public $icon = '\f207';
1002 public function __construct( $id, array $settings ) {
1003 parent::__construct( $id, $settings );
1004
1005 if ( 'official' == $this->button_style ) {
1006 $this->smart = true;
1007 } else {
1008 $this->smart = false;
1009 }
1010 }
1011
1012 public function get_name() {
1013 return __( 'LinkedIn', 'jetpack' );
1014 }
1015
1016 public function has_custom_button_style() {
1017 return $this->smart;
1018 }
1019
1020 public function get_display( $post ) {
1021 $display = '';
1022
1023 if ( $this->smart ) {
1024 $share_url = $this->get_share_url( $post->ID );
1025 $display .= sprintf( '<div class="linkedin_button"><script type="in/share" data-url="%s" data-counter="right"></script></div>', esc_url( $share_url ) );
1026 } else {
1027 $display = $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'LinkedIn', 'share to', 'jetpack' ), __( 'Click to share on LinkedIn', 'jetpack' ), 'share=linkedin', 'sharing-linkedin-' . $post->ID );
1028 }
1029
1030 /** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1031 if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
1032 sharing_register_post_for_share_counts( $post->ID );
1033 }
1034
1035 return $display;
1036 }
1037
1038 public function process_request( $post, array $post_data ) {
1039
1040 $post_link = $this->get_share_url( $post->ID );
1041
1042 // Using the same URL as the official button, which is *not* LinkedIn's documented sharing link
1043 // https://www.linkedin.com/cws/share?url={url}&token=&isFramed=false
1044 $linkedin_url = add_query_arg( array(
1045 'url' => rawurlencode( $post_link ),
1046 ), 'https://www.linkedin.com/cws/share?token=&isFramed=false' );
1047
1048 // Record stats
1049 parent::process_request( $post, $post_data );
1050
1051 parent::redirect_request( $linkedin_url );
1052 }
1053
1054 public function display_footer() {
1055 if ( ! $this->smart ) {
1056 $this->js_dialog( $this->shortname, array( 'width' => 580, 'height' => 450 ) );
1057 } else {
1058 ?>
1059 <script type="text/javascript">
1060 ( function () {
1061 var currentScript = document.currentScript;
1062
1063 // Helper function to load an external script.
1064 function loadScript( url, cb ) {
1065 var script = document.createElement( 'script' );
1066 var prev = currentScript || document.getElementsByTagName( 'script' )[ 0 ];
1067 script.setAttribute( 'async', true );
1068 script.setAttribute( 'src', url );
1069 prev.parentNode.insertBefore( script, prev );
1070 script.addEventListener( 'load', cb );
1071 }
1072
1073 function init() {
1074 loadScript( 'https://platform.linkedin.com/in.js?async=true', function () {
1075 if ( typeof IN !== 'undefined' ) {
1076 IN.init();
1077 }
1078 } );
1079 }
1080
1081 if ( document.readyState === 'loading' ) {
1082 document.addEventListener( 'DOMContentLoaded', init );
1083 } else {
1084 init();
1085 }
1086
1087 document.body.addEventListener( 'is.post-load', function() {
1088 if ( typeof IN !== 'undefined' ) {
1089 IN.parse();
1090 }
1091 } );
1092 } )();
1093 </script>
1094 <?php
1095 }
1096 }
1097 }
1098
1099 class Share_Facebook extends Sharing_Source {
1100 public $shortname = 'facebook';
1101 public $icon = '\f204';
1102 private $share_type = 'default';
1103
1104 public function __construct( $id, array $settings ) {
1105 parent::__construct( $id, $settings );
1106
1107 if ( isset( $settings['share_type'] ) ) {
1108 $this->share_type = $settings['share_type'];
1109 }
1110
1111 if ( 'official' == $this->button_style ) {
1112 $this->smart = true;
1113 } else {
1114 $this->smart = false;
1115 }
1116 }
1117
1118 public function get_name() {
1119 return __( 'Facebook', 'jetpack' );
1120 }
1121
1122 public function display_header() {
1123 }
1124
1125 function guess_locale_from_lang( $lang ) {
1126 if ( 'en' == $lang || 'en_US' == $lang || ! $lang ) {
1127 return 'en_US';
1128 }
1129
1130 if ( ! class_exists( 'GP_Locales' ) ) {
1131 if ( ! defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) || ! file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
1132 return false;
1133 }
1134
1135 require JETPACK__GLOTPRESS_LOCALES_PATH;
1136 }
1137
1138 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
1139 // WP.com: get_locale() returns 'it'
1140 $locale = GP_Locales::by_slug( $lang );
1141 } else {
1142 // Jetpack: get_locale() returns 'it_IT';
1143 $locale = GP_Locales::by_field( 'wp_locale', $lang );
1144 }
1145
1146 if ( ! $locale ) {
1147 return false;
1148 }
1149
1150 if ( empty( $locale->facebook_locale ) ) {
1151 if ( empty( $locale->wp_locale ) ) {
1152 return false;
1153 } else {
1154 // Facebook SDK is smart enough to fall back to en_US if a
1155 // locale isn't supported. Since supported Facebook locales
1156 // can fall out of sync, we'll attempt to use the known
1157 // wp_locale value and rely on said fallback.
1158 return $locale->wp_locale;
1159 }
1160 }
1161
1162 return $locale->facebook_locale;
1163 }
1164
1165 public function get_display( $post ) {
1166 if ( $this->smart ) {
1167 $share_url = $this->get_share_url( $post->ID );
1168 $fb_share_html = '<div class="fb-share-button" data-href="' . esc_attr( $share_url ) . '" data-layout="button_count"></div>';
1169 /**
1170 * Filter the output of the Facebook Sharing button.
1171 *
1172 * @module sharedaddy
1173 *
1174 * @since 3.6.0
1175 *
1176 * @param string $fb_share_html Facebook Sharing button HTML.
1177 * @param string $share_url URL of the post to share.
1178 */
1179 return apply_filters( 'jetpack_sharing_facebook_official_button_output', $fb_share_html, $share_url );
1180 }
1181
1182 /** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1183 if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'facebook' ) ) {
1184 sharing_register_post_for_share_counts( $post->ID );
1185 }
1186 return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Facebook', 'share to', 'jetpack' ), __( 'Click to share on Facebook', 'jetpack' ), 'share=facebook', 'sharing-facebook-' . $post->ID );
1187 }
1188
1189 /**
1190 * AMP display for Facebook.
1191 *
1192 * @param \WP_Post $post The current post being viewed.
1193 */
1194 public function get_amp_display( $post ) {
1195 $attrs = array(
1196 /** This filter is documented in modules/sharedaddy/sharing-sources.php */
1197 'data-param-app_id' => apply_filters( 'jetpack_sharing_facebook_app_id', '249643311490' ),
1198 );
1199
1200 return $this->build_amp_markup( $attrs );
1201 }
1202
1203 public function process_request( $post, array $post_data ) {
1204 $fb_url = $this->http() . '://www.facebook.com/sharer.php?u=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&t=' . rawurlencode( $this->get_share_title( $post->ID ) );
1205
1206 // Record stats
1207 parent::process_request( $post, $post_data );
1208
1209 parent::redirect_request( $fb_url );
1210 }
1211
1212 public function display_footer() {
1213 $this->js_dialog( $this->shortname );
1214 if ( $this->smart ) {
1215 $locale = $this->guess_locale_from_lang( get_locale() );
1216 if ( ! $locale ) {
1217 $locale = 'en_US';
1218 }
1219 /**
1220 * Filter the App ID used in the official Facebook Share button.
1221 *
1222 * @since 3.8.0
1223 *
1224 * @param int $fb_app_id Facebook App ID. Default to 249643311490 (WordPress.com's App ID).
1225 */
1226 $fb_app_id = apply_filters( 'jetpack_sharing_facebook_app_id', '249643311490' );
1227 if ( is_numeric( $fb_app_id ) ) {
1228 $fb_app_id = '&appId=' . $fb_app_id;
1229 } else {
1230 $fb_app_id = '';
1231 }
1232 ?><div id="fb-root"></div>
1233 <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = 'https://connect.facebook.net/<?php echo $locale; ?>/sdk.js#xfbml=1<?php echo $fb_app_id; ?>&version=v2.3'; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script>
1234 <script>
1235 document.body.addEventListener( 'is.post-load', function() {
1236 if ( 'undefined' !== typeof FB ) {
1237 FB.XFBML.parse();
1238 }
1239 } );
1240 </script>
1241 <?php
1242 }
1243 }
1244 }
1245
1246 class Share_Print extends Sharing_Source {
1247 public $shortname = 'print';
1248 public $icon = '\f469';
1249 public function __construct( $id, array $settings ) {
1250 parent::__construct( $id, $settings );
1251
1252 if ( 'official' == $this->button_style ) {
1253 $this->smart = true;
1254 } else {
1255 $this->smart = false;
1256 }
1257 }
1258
1259 public function get_name() {
1260 return __( 'Print', 'jetpack' );
1261 }
1262
1263 public function get_display( $post ) {
1264 return $this->get_link( $this->get_process_request_url( $post->ID ) . ( ( is_single() || is_page() ) ? '#print': '' ), _x( 'Print', 'share to', 'jetpack' ), __( 'Click to print', 'jetpack' ) );
1265 }
1266
1267 /**
1268 * AMP display for Print.
1269 *
1270 * @param \WP_Post $post The current post being viewed.
1271 */
1272 public function get_amp_display( $post ) {
1273 if ( empty( $post ) ) {
1274 return false;
1275 }
1276
1277 return '<button class="amp-social-share print" on="tap:AMP.print">Print</button>';
1278 }
1279 }
1280
1281 class Share_PressThis extends Sharing_Source {
1282 public $shortname = 'pressthis';
1283 public $icon = '\f205';
1284 public function __construct( $id, array $settings ) {
1285 parent::__construct( $id, $settings );
1286
1287 if ( 'official' == $this->button_style ) {
1288 $this->smart = true;
1289 } else {
1290 $this->smart = false;
1291 }
1292 }
1293
1294 public function get_name() {
1295 return __( 'Press This', 'jetpack' );
1296 }
1297
1298 public function process_request( $post, array $post_data ) {
1299 global $current_user;
1300
1301 $primary_blog = (int) get_user_meta( $current_user->ID, 'primary_blog', true );
1302 if ( $primary_blog ) {
1303 $primary_blog_details = get_blog_details( $primary_blog );
1304 } else {
1305 $primary_blog_details = false;
1306 }
1307
1308 if ( $primary_blog_details ) {
1309 $blogs = array( $primary_blog_details );
1310 } elseif ( function_exists( 'get_active_blogs_for_user' ) ) {
1311 $blogs = get_active_blogs_for_user();
1312 if ( empty( $blogs ) ) {
1313 $blogs = get_blogs_of_user( $current_user->ID );
1314 }
1315 } else {
1316 $blogs = get_blogs_of_user( $current_user->ID );
1317 }
1318
1319 if ( empty( $blogs ) ) {
1320 wp_safe_redirect( get_permalink( $post->ID ) );
1321 die();
1322 }
1323
1324 $blog = current( $blogs );
1325
1326 $args = array(
1327 'u' => rawurlencode( $this->get_share_url( $post->ID ) ),
1328 );
1329
1330 $args[ 'url-scan-submit' ] = 'Scan';
1331 $args[ '_wpnonce' ] = wp_create_nonce( 'scan-site' );
1332
1333 $url = $blog->siteurl . '/wp-admin/press-this.php';
1334 $url = add_query_arg( $args, $url );
1335
1336 // Record stats
1337 parent::process_request( $post, $post_data );
1338
1339 parent::redirect_request( $url );
1340 }
1341
1342 public function get_display( $post ) {
1343 return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Press This', 'share to', 'jetpack' ), __( 'Click to Press This!', 'jetpack' ), 'share=press-this' );
1344 }
1345
1346 /**
1347 * No AMP display for PressThis.
1348 *
1349 * @param \WP_Post $post The current post being viewed.
1350 */
1351 public function get_amp_display( $post ) { // phpcs:ignore
1352 return false;
1353 }
1354 }
1355
1356 class Share_Custom extends Sharing_Advanced_Source {
1357 private $name;
1358 private $icon;
1359 private $url;
1360 public $smart = true;
1361 public $shortname;
1362
1363 public function get_class() {
1364 return 'custom share-custom-' . sanitize_html_class( strtolower( $this->name ) );
1365 }
1366
1367 public function __construct( $id, array $settings ) {
1368 parent::__construct( $id, $settings );
1369
1370 $opts = $this->get_options();
1371
1372 if ( isset( $settings['name'] ) ) {
1373 $this->name = $settings['name'];
1374 $this->shortname = preg_replace( '/[^a-z0-9]*/', '', $settings['name'] );
1375 }
1376
1377 if ( isset( $settings['icon'] ) ) {
1378 $this->icon = $settings['icon'];
1379
1380 $new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1381 $i = 0;
1382 while ( $new_icon != $this->icon ) {
1383 if ( $i > 5 ) {
1384 $this->icon = false;
1385 break;
1386 } else {
1387 $this->icon = $new_icon;
1388 $new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1389 }
1390 $i++;
1391 }
1392 }
1393
1394 if ( isset( $settings['url'] ) ) {
1395 $this->url = $settings['url'];
1396 }
1397 }
1398
1399 public function get_name() {
1400 return $this->name;
1401 }
1402
1403 public function get_display( $post ) {
1404 $str = $this->get_link( $this->get_process_request_url( $post->ID ), esc_html( $this->name ), sprintf( __( 'Click to share on %s', 'jetpack' ), esc_attr( $this->name ) ), 'share=' . $this->id );
1405 return str_replace( '<span>', '<span style="' . esc_attr( 'background-image:url("' . addcslashes( esc_url_raw( $this->icon ), '"' ) . '");' ) . '">', $str );
1406 }
1407
1408 /**
1409 * No AMP display for custom elements.
1410 *
1411 * @param \WP_Post $post The current post being viewed.
1412 */
1413 public function get_amp_display( $post ) { // phpcs:ignore
1414 return false;
1415 }
1416
1417 public function process_request( $post, array $post_data ) {
1418 $url = str_replace( '&amp;', '&', $this->url );
1419 $url = str_replace( '%post_id%', rawurlencode( $post->ID ), $url );
1420 $url = str_replace( '%post_url%', rawurlencode( $this->get_share_url( $post->ID ) ), $url );
1421 $url = str_replace( '%post_full_url%', rawurlencode( get_permalink( $post->ID ) ), $url );
1422 $url = str_replace( '%post_title%', rawurlencode( $this->get_share_title( $post->ID ) ), $url );
1423 $url = str_replace( '%home_url%', rawurlencode( home_url() ), $url );
1424 $url = str_replace( '%post_slug%', rawurlencode( $post->post_name ), $url );
1425
1426 if ( strpos( $url, '%post_tags%' ) !== false ) {
1427 $tags = get_the_tags( $post->ID );
1428 $tagged = '';
1429
1430 if ( $tags ) {
1431 $tagged_raw = array();
1432 foreach ( $tags as $tag ) {
1433 $tagged_raw[] = rawurlencode( $tag->name );
1434 }
1435
1436 $tagged = implode( ',', $tagged_raw );
1437 }
1438
1439 $url = str_replace( '%post_tags%', $tagged, $url );
1440 }
1441
1442 if ( strpos( $url, '%post_excerpt%' ) !== false ) {
1443 $url_excerpt = $post->post_excerpt;
1444 if ( empty( $url_excerpt ) ) {
1445 $url_excerpt = $post->post_content;
1446 }
1447
1448 $url_excerpt = strip_tags( strip_shortcodes( $url_excerpt ) );
1449 $url_excerpt = wp_html_excerpt( $url_excerpt, 100 );
1450 $url_excerpt = rtrim( preg_replace( '/[^ .]*$/', '', $url_excerpt ) );
1451 $url = str_replace( '%post_excerpt%', rawurlencode( $url_excerpt ), $url );
1452 }
1453
1454 // Record stats
1455 parent::process_request( $post, $post_data );
1456
1457 parent::redirect_request( $url );
1458 }
1459
1460 public function display_options() {
1461 ?>
1462 <div class="input">
1463 <table class="form-table">
1464 <tbody>
1465 <tr>
1466 <th scope="row"><?php _e( 'Label', 'jetpack' ); ?></th>
1467 <td><input type="text" name="name" value="<?php echo esc_attr( $this->name ); ?>" /></td>
1468 </tr>
1469
1470 <tr>
1471 <th scope="row"><?php _e( 'URL', 'jetpack' ); ?></th>
1472 <td><input type="text" name="url" value="<?php echo esc_attr( $this->url ); ?>" /></td>
1473 </tr>
1474
1475 <tr>
1476 <th scope="row"><?php _e( 'Icon', 'jetpack' ); ?></th>
1477 <td><input type="text" name="icon" value="<?php echo esc_attr( $this->icon ); ?>" /></td>
1478 </tr>
1479
1480 <tr>
1481 <th scope="row"></th>
1482 <td>
1483 <input class="button-secondary" type="submit" value="<?php esc_attr_e( 'Save', 'jetpack' ); ?>" />
1484 <a href="#" class="remove"><small><?php _e( 'Remove Service', 'jetpack' ); ?></small></a>
1485 </td>
1486 </tr>
1487 </tbody>
1488 </table>
1489 </div>
1490 <?php
1491 }
1492
1493 public function update_options( array $data ) {
1494 $name = trim( wp_html_excerpt( wp_kses( stripslashes( $data['name'] ), array() ), 30 ) );
1495 $url = trim( esc_url_raw( $data['url'] ) );
1496 $icon = trim( esc_url_raw( $data['icon'] ) );
1497
1498 if ( $name ) {
1499 $this->name = $name;
1500 }
1501
1502 if ( $url ) {
1503 $this->url = $url;
1504 }
1505
1506 if ( $icon ) {
1507 $this->icon = $icon;
1508 }
1509 }
1510
1511 public function get_options() {
1512 return array(
1513 'name' => $this->name,
1514 'icon' => $this->icon,
1515 'url' => $this->url,
1516 );
1517 }
1518
1519 public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
1520 $opts = $this->get_options();
1521
1522 $text = '&nbsp;';
1523 if ( ! $this->smart ) {
1524 if ( $this->button_style != 'icon' ) {
1525 $text = $this->get_name();
1526 }
1527 }
1528
1529 $klasses = array( 'share-' . $this->shortname );
1530
1531 if ( $this->button_style == 'icon' || $this->button_style == 'icon-text' ) {
1532 $klasses[] = 'share-icon';
1533 }
1534
1535 if ( $this->button_style == 'icon' ) {
1536 $text = '';
1537 $klasses[] = 'no-text';
1538 }
1539
1540 if ( $this->button_style == 'text' ) {
1541 $klasses[] = 'no-icon';
1542 }
1543
1544 $link = sprintf(
1545 '<a rel="nofollow" class="%s" href="javascript:void(0)" title="%s"><span style="background-image:url(&quot;%s&quot;) !important;background-position:left center;background-repeat:no-repeat;">%s</span></a>',
1546 implode( ' ', $klasses ),
1547 $this->get_name(),
1548 addcslashes( esc_url_raw( $opts['icon'] ), '"' ),
1549 $text
1550 );
1551 ?>
1552 <div class="option option-smart-off">
1553 <?php echo $link ; ?>
1554 </div><?php
1555 }
1556 }
1557
1558 class Share_Tumblr extends Sharing_Source {
1559 public $shortname = 'tumblr';
1560 public $icon = '\f214';
1561 public function __construct( $id, array $settings ) {
1562 parent::__construct( $id, $settings );
1563 if ( 'official' == $this->button_style ) {
1564 $this->smart = true;
1565 } else {
1566 $this->smart = false;
1567 }
1568 }
1569
1570 public function get_name() {
1571 return __( 'Tumblr', 'jetpack' );
1572 }
1573
1574 public function get_display( $post ) {
1575 if ( $this->smart ) {
1576 $target = '';
1577 if ( true == $this->open_link_in_new ) {
1578 $target = '_blank';
1579 }
1580
1581 /**
1582 * If we are looking at a single post, let Tumblr figure out the post type (text, photo, link, quote, chat, or video)
1583 * based on the content available on the page.
1584 * If we are not looking at a single post, content from other posts can appear on the page and Tumblr will pick that up.
1585 * In this case, we want Tumblr to focus on our current post, so we will limit the post type to link, where we can give Tumblr a link to our post.
1586 */
1587 if ( ! is_single() ) {
1588 $posttype = 'data-posttype="link"';
1589 } else {
1590 $posttype = '';
1591 }
1592
1593 // Documentation: https://www.tumblr.com/docs/en/share_button
1594 return sprintf(
1595 '<a class="tumblr-share-button" target="%1$s" href="%2$s" data-title="%3$s" data-content="%4$s" title="%5$s"%6$s>%5$s</a>',
1596 $target,
1597 'https://www.tumblr.com/share',
1598 $this->get_share_title( $post->ID ),
1599 $this->get_share_url( $post->ID ),
1600 __( 'Share on Tumblr', 'jetpack' ),
1601 $posttype
1602 );
1603 } else {
1604 return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Tumblr', 'share to', 'jetpack' ), __( 'Click to share on Tumblr', 'jetpack' ), 'share=tumblr' );
1605 }
1606 }
1607
1608 public function process_request( $post, array $post_data ) {
1609 // Record stats
1610 parent::process_request( $post, $post_data );
1611
1612 // Redirect to Tumblr's sharing endpoint (a la their bookmarklet)
1613 $url = 'https://www.tumblr.com/share?v=3&u=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&t=' . rawurlencode( $this->get_share_title( $post->ID ) ) . '&s=';
1614
1615 parent::redirect_request( $url );
1616 }
1617
1618 public function display_footer() {
1619 if ( $this->smart ) {
1620 ?><script id="tumblr-js" type="text/javascript" src="https://assets.tumblr.com/share-button.js"></script><?php
1621 } else {
1622 $this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1623 }
1624 }
1625 }
1626
1627 class Share_Pinterest extends Sharing_Source {
1628 public $shortname = 'pinterest';
1629 public $icon = '\f209';
1630
1631 public function __construct( $id, array $settings ) {
1632 parent::__construct( $id, $settings );
1633 if ( 'official' == $this->button_style ) {
1634 $this->smart = true;
1635 } else {
1636 $this->smart = false;
1637 }
1638 }
1639
1640 public function get_name() {
1641 return __( 'Pinterest', 'jetpack' );
1642 }
1643
1644 public function get_image( $post ) {
1645 if ( class_exists( 'Jetpack_PostImages' ) ) {
1646 $image = Jetpack_PostImages::get_image( $post->ID, array( 'fallback_to_avatars' => true ) );
1647 if ( ! empty( $image ) ) {
1648 return $image['src'];
1649 }
1650 }
1651
1652 /**
1653 * Filters the default image used by the Pinterest Pin It share button.
1654 *
1655 * @module sharedaddy
1656 *
1657 * @since 3.6.0
1658 *
1659 * @param string $url Default image URL.
1660 */
1661 return apply_filters( 'jetpack_sharing_pinterest_default_image', 'https://s0.wp.com/i/blank.jpg' );
1662 }
1663
1664 public function get_external_url( $post ) {
1665 $url = 'https://www.pinterest.com/pin/create/button/?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&media=' . rawurlencode( $this->get_image( $post ) ) . '&description=' . rawurlencode( $post->post_title );
1666
1667 /**
1668 * Filters the Pinterest share URL used in sharing button output.
1669 *
1670 * @module sharedaddy
1671 *
1672 * @since 3.6.0
1673 *
1674 * @param string $url Pinterest share URL.
1675 */
1676 return apply_filters( 'jetpack_sharing_pinterest_share_url', $url );
1677 }
1678
1679 public function get_widget_type() {
1680 /**
1681 * Filters the Pinterest widget type.
1682 *
1683 * @see https://business.pinterest.com/en/widget-builder
1684 *
1685 * @module sharedaddy
1686 *
1687 * @since 3.6.0
1688 *
1689 * @param string $type Pinterest widget type. Default of 'buttonPin' for single-image selection. 'buttonBookmark' for multi-image modal.
1690 */
1691 return apply_filters( 'jetpack_sharing_pinterest_widget_type', 'buttonPin' );
1692 }
1693
1694 public function get_display( $post ) {
1695 $display = '';
1696
1697 if ( $this->smart ) {
1698 $display = sprintf(
1699 '<div class="pinterest_button"><a href="%s" data-pin-do="%s" data-pin-config="beside"><img src="//assets.pinterest.com/images/pidgets/pinit_fg_en_rect_gray_20.png" /></a></div>',
1700 esc_url( $this->get_external_url( $post ) ),
1701 esc_attr( $this->get_widget_type() )
1702 );
1703 } else {
1704 $display = $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Pinterest', 'share to', 'jetpack' ), __( 'Click to share on Pinterest', 'jetpack' ), 'share=pinterest', 'sharing-pinterest-' . $post->ID );
1705 }
1706
1707 /** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1708 if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
1709 sharing_register_post_for_share_counts( $post->ID );
1710 }
1711
1712 return $display;
1713 }
1714
1715 public function process_request( $post, array $post_data ) {
1716 // Record stats
1717 parent::process_request( $post, $post_data );
1718 // If we're triggering the multi-select panel, then we don't need to redirect to Pinterest
1719 if ( ! isset( $_GET['js_only'] ) ) {
1720 $pinterest_url = esc_url_raw( $this->get_external_url( $post ) );
1721 parent::redirect_request( $pinterest_url );
1722 } else {
1723 echo '// share count bumped';
1724 die();
1725 }
1726 }
1727
1728 public function display_footer() {
1729 /**
1730 * Filter the Pin it button appearing when hovering over images when using the official button style.
1731 *
1732 * @module sharedaddy
1733 *
1734 * @since 3.6.0
1735 *
1736 * @param bool $jetpack_pinit_over True by default, displays the Pin it button when hovering over images.
1737 */
1738 $jetpack_pinit_over = apply_filters( 'jetpack_pinit_over_button', true );
1739 ?>
1740 <?php if ( $this->smart ) : ?>
1741 <script type="text/javascript">
1742 ( function () {
1743 // Pinterest shared resources
1744 var s = document.createElement( 'script' );
1745 s.type = 'text/javascript';
1746 s.async = true;
1747 <?php
1748 if ( $jetpack_pinit_over ) {
1749 echo "s.setAttribute( 'data-pin-hover', true );";
1750 }
1751 ?>
1752 s.src = window.location.protocol + '//assets.pinterest.com/js/pinit.js';
1753 var x = document.getElementsByTagName( 'script' )[ 0 ];
1754 x.parentNode.insertBefore(s, x);
1755 // if 'Pin it' button has 'counts' make container wider
1756 function init() {
1757 var shares = document.querySelectorAll( 'li.share-pinterest' );
1758 for ( var i = 0; i < shares.length; i++ ) {
1759 var share = shares[ i ];
1760 if ( share.querySelector( 'a span:visible' ) ) {
1761 share.style.width = '80px';
1762 }
1763 }
1764 }
1765
1766 if ( document.readyState !== 'complete' ) {
1767 document.addEventListener( 'load', init );
1768 } else {
1769 init();
1770 }
1771 } )();
1772 </script>
1773 <?php elseif ( 'buttonPin' != $this->get_widget_type() ) : ?>
1774 <script type="text/javascript">
1775 ( function () {
1776 function init() {
1777 document.body.addEventListener( 'click', function ( e ) {
1778 if ( e.target && (
1779 e.target.matches && e.target.matches( 'a.share-pinterest' ) ||
1780 e.target.msMatchesSelector && e.target.msMatchesSelector( 'a.share-pinterest' )
1781 ) ) {
1782 e.preventDefault();
1783 // Load Pinterest Bookmarklet code
1784 var s = document.createElement( 'script' );
1785 s.type = 'text/javascript';
1786 s.src = window.location.protocol + '//assets.pinterest.com/js/pinmarklet.js?r=' + ( Math.random() * 99999999 );
1787 var x = document.getElementsByTagName( 'script' )[ 0 ];
1788 x.parentNode.insertBefore( s, x );
1789 // Trigger Stats
1790 var s = document.createElement( 'script' );
1791 s.type = 'text/javascript';
1792 s.src = e.target.href + ( e.target.href.indexOf( '?' ) ? '&' : '?' ) + 'js_only=1';
1793 var x = document.getElementsByTagName( 'script' )[ '0' ];
1794 x.parentNode.insertBefore( s, x );
1795 }
1796 } );
1797 }
1798
1799 if ( document.readyState === 'loading' ) {
1800 document.addEventListener( 'DOMContentLoaded', init );
1801 } else {
1802 init();
1803 }
1804 } )();
1805 </script>
1806 <?php endif;
1807 }
1808 }
1809
1810 class Share_Pocket extends Sharing_Source {
1811 public $shortname = 'pocket';
1812 public $icon = '\f224';
1813
1814 public function __construct( $id, array $settings ) {
1815 parent::__construct( $id, $settings );
1816
1817 if ( 'official' == $this->button_style ) {
1818 $this->smart = true;
1819 } else {
1820 $this->smart = false;
1821 }
1822 }
1823
1824 public function get_name() {
1825 return __( 'Pocket', 'jetpack' );
1826 }
1827
1828 public function process_request( $post, array $post_data ) {
1829 // Record stats
1830 parent::process_request( $post, $post_data );
1831
1832 $pocket_url = esc_url_raw( 'https://getpocket.com/save/?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) ) );
1833
1834 parent::redirect_request( $pocket_url );
1835 }
1836
1837 public function get_display( $post ) {
1838 if ( $this->smart ) {
1839 $post_count = 'horizontal';
1840
1841 $button = '';
1842 $button .= '<div class="pocket_button">';
1843 $button .= sprintf( '<a href="https://getpocket.com/save" class="pocket-btn" data-lang="%s" data-save-url="%s" data-pocket-count="%s" >%s</a>', 'en', esc_attr( $this->get_share_url( $post->ID ) ), $post_count, esc_attr__( 'Pocket', 'jetpack' ) );
1844 $button .= '</div>';
1845
1846 return $button;
1847 } else {
1848 return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Pocket', 'share to', 'jetpack' ), __( 'Click to share on Pocket', 'jetpack' ), 'share=pocket' );
1849 }
1850
1851 }
1852
1853 /**
1854 * AMP display for Pocket.
1855 *
1856 * @param \WP_Post $post The current post being viewed.
1857 */
1858 public function get_amp_display( $post ) {
1859 $attrs = array(
1860 'data-share-endpoint' => esc_url_raw( 'https://getpocket.com/save/?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) ) ),
1861 );
1862
1863 return $this->build_amp_markup( $attrs );
1864 }
1865
1866 function display_footer() {
1867 if ( $this->smart ) :
1868 ?>
1869 <script>
1870 ( function () {
1871 var currentScript = document.currentScript;
1872
1873 // Don't use Pocket's default JS as it we need to force init new Pocket share buttons loaded via JS.
1874 function jetpack_sharing_pocket_init() {
1875 var script = document.createElement( 'script' );
1876 var prev = currentScript || document.getElementsByTagName( 'script' )[ 0 ];
1877 script.setAttribute( 'async', true );
1878 script.setAttribute( 'src', 'https://widgets.getpocket.com/v1/j/btn.js?v=1' );
1879 prev.parentNode.insertBefore( script, prev );
1880 }
1881
1882 if ( document.readyState === 'loading' ) {
1883 document.addEventListener( 'DOMContentLoaded', jetpack_sharing_pocket_init );
1884 } else {
1885 jetpack_sharing_pocket_init();
1886 }
1887 document.body.addEventListener( 'is.post-load', jetpack_sharing_pocket_init );
1888 } )();
1889 </script>
1890 <?php
1891 else :
1892 $this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1893 endif;
1894
1895 }
1896
1897 }
1898
1899 class Share_Telegram extends Sharing_Source {
1900 public $shortname = 'telegram';
1901
1902 public function __construct( $id, array $settings ) {
1903 parent::__construct( $id, $settings );
1904 }
1905
1906 public function get_name() {
1907 return __( 'Telegram', 'jetpack' );
1908 }
1909 public function process_request( $post, array $post_data ) {
1910 // Record stats
1911 parent::process_request( $post, $post_data );
1912
1913 $telegram_url = esc_url_raw( 'https://telegram.me/share/url?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&text=' . rawurlencode( $this->get_share_title( $post->ID ) ) );
1914
1915 parent::redirect_request( $telegram_url );
1916 }
1917
1918 public function get_display( $post ) {
1919 return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Telegram', 'share to', 'jetpack' ), __( 'Click to share on Telegram', 'jetpack' ), 'share=telegram' );
1920 }
1921
1922 /**
1923 * AMP display for Telegram.
1924 *
1925 * @param \WP_Post $post The current post being viewed.
1926 */
1927 public function get_amp_display( $post ) {
1928 $attrs = array(
1929 'data-share-endpoint' => esc_url_raw( 'https://telegram.me/share/url?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&text=' . rawurlencode( $this->get_share_title( $post->ID ) ) ),
1930 );
1931
1932 return $this->build_amp_markup( $attrs );
1933 }
1934
1935 function display_footer() {
1936 $this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1937 }
1938 }
1939
1940 class Jetpack_Share_WhatsApp extends Sharing_Source {
1941 public $shortname = 'jetpack-whatsapp';
1942
1943 public function __construct( $id, array $settings ) {
1944 parent::__construct( $id, $settings );
1945 }
1946
1947 public function get_name() {
1948 return __( 'WhatsApp', 'jetpack' );
1949 }
1950
1951 public function get_display( $post ) {
1952 return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'WhatsApp', 'share to', 'jetpack' ), __( 'Click to share on WhatsApp', 'jetpack' ), 'share=jetpack-whatsapp' );
1953 }
1954
1955 /**
1956 * AMP display for Whatsapp.
1957 *
1958 * @param \WP_Post $post The current post being viewed.
1959 */
1960 public function get_amp_display( $post ) {
1961 $attrs = array(
1962 'type' => 'whatsapp',
1963 );
1964
1965 return $this->build_amp_markup( $attrs );
1966 }
1967
1968 public function process_request( $post, array $post_data ) {
1969 // Record stats
1970 parent::process_request( $post, $post_data );
1971
1972 // Firefox for desktop doesn't handle the "api.whatsapp.com" URL properly, so use "web.whatsapp.com"
1973 if ( User_Agent_Info::is_firefox_desktop() ) {
1974 $url = 'https://web.whatsapp.com/send?text=';
1975 } else {
1976 $url = 'https://api.whatsapp.com/send?text=';
1977 }
1978
1979 $url .= rawurlencode( $this->get_share_title( $post->ID ) . ' ' . $this->get_share_url( $post->ID ) );
1980
1981 parent::redirect_request( $url );
1982 }
1983 }
1984
1985 class Share_Skype extends Sharing_Source {
1986 public $shortname = 'skype';
1987 public $icon = '\f220';
1988 private $share_type = 'default';
1989
1990 public function __construct( $id, array $settings ) {
1991 parent::__construct( $id, $settings );
1992
1993 if ( isset( $settings['share_type'] ) ) {
1994 $this->share_type = $settings['share_type'];
1995 }
1996
1997 if ( 'official' == $this->button_style ) {
1998 $this->smart = true;
1999 } else {
2000 $this->smart = false;
2001 }
2002
2003 }
2004
2005 public function get_name() {
2006 return __( 'Skype', 'jetpack' );
2007 }
2008
2009 public function get_display( $post ) {
2010 if ( $this->smart ) {
2011 $skype_share_html = sprintf(
2012 '<div class="skype-share" data-href="%1$s" data-lang="%2$s" data-style="small" data-source="jetpack" ></div>',
2013 esc_attr( $this->get_share_url( $post->ID ) ),
2014 'en-US'
2015 );
2016 return $skype_share_html;
2017 }
2018
2019 /** This filter is already documented in modules/sharedaddy/sharing-sources.php */
2020 if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'skype' ) ) {
2021 sharing_register_post_for_share_counts( $post->ID );
2022 }
2023 return $this->get_link(
2024 $this->get_process_request_url( $post->ID ), _x( 'Skype', 'share to', 'jetpack' ), __( 'Click to share on Skype', 'jetpack' ), 'share=skype', 'sharing-skype-' . $post->ID );
2025 }
2026
2027 /**
2028 * AMP display for Skype.
2029 *
2030 * @param \WP_Post $post The current post being viewed.
2031 */
2032 public function get_amp_display( $post ) {
2033 $attrs = array(
2034 'data-share-endpoint' => sprintf(
2035 'https://web.skype.com/share?url=%1$s&lang=%2$s=&source=jetpack',
2036 rawurlencode( $this->get_share_url( $post->ID ) ),
2037 'en-US'
2038 ),
2039 );
2040
2041 return $this->build_amp_markup( $attrs );
2042 }
2043
2044 public function process_request( $post, array $post_data ) {
2045 $skype_url = sprintf(
2046 'https://web.skype.com/share?url=%1$s&lang=%2$s=&source=jetpack',
2047 rawurlencode( $this->get_share_url( $post->ID ) ),
2048 'en-US'
2049 );
2050
2051 // Record stats
2052 parent::process_request( $post, $post_data );
2053
2054 parent::redirect_request( $skype_url );
2055 }
2056
2057 public function display_footer() {
2058 if ( $this->smart ) :
2059 ?>
2060 <script>
2061 (function(r, d, s) {
2062 r.loadSkypeWebSdkAsync = r.loadSkypeWebSdkAsync || function(p) {
2063 var js, sjs = d.getElementsByTagName(s)[0];
2064 if (d.getElementById(p.id)) { return; }
2065 js = d.createElement(s);
2066 js.id = p.id;
2067 js.src = p.scriptToLoad;
2068 js.onload = p.callback
2069 sjs.parentNode.insertBefore(js, sjs);
2070 };
2071 var p = {
2072 scriptToLoad: 'https://swx.cdn.skype.com/shared/v/latest/skypewebsdk.js',
2073 id: 'skype_web_sdk'
2074 };
2075 r.loadSkypeWebSdkAsync(p);
2076 })(window, document, 'script');
2077 </script>
2078 <?php
2079 else :
2080 $this->js_dialog( $this->shortname, array( 'width' => 305, 'height' => 665 ) );
2081 endif;
2082 }
2083 }
2084