PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 13.2.2
Jetpack – WP Security, Backup, Speed, & Growth v13.2.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.php

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

864 lines 29.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Set up Sharing functionality and management in wp-admin.
4 *
5 * @package automattic/jetpack
6 */
7
8 // phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
9
10 use Automattic\Jetpack\Assets;
11 use Automattic\Jetpack\Redirect;
12 use Automattic\Jetpack\Status;
13
14 if ( ! defined( 'WP_SHARING_PLUGIN_URL' ) ) {
15 define( 'WP_SHARING_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
16 define( 'WP_SHARING_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
17 }
18
19 /**
20 * Utilities to manage sharing settings from wp-admin.
21 */
22 class Sharing_Admin {
23
24 /**
25 * Constructor.
26 * Hook into WordPress to add our functionality.
27 */
28 public function __construct() {
29 require_once WP_SHARING_PLUGIN_DIR . 'sharing-service.php';
30
31 add_action( 'admin_init', array( $this, 'admin_init' ) );
32 add_action( 'admin_menu', array( $this, 'subscription_menu' ) );
33
34 // Insert our CSS and JS
35 add_action( 'load-settings_page_sharing', array( $this, 'sharing_head' ) );
36
37 // Catch AJAX
38 add_action( 'wp_ajax_sharing_save_services', array( $this, 'ajax_save_services' ) );
39 add_action( 'wp_ajax_sharing_save_options', array( $this, 'ajax_save_options' ) );
40 add_action( 'wp_ajax_sharing_new_service', array( $this, 'ajax_new_service' ) );
41 add_action( 'wp_ajax_sharing_delete_service', array( $this, 'ajax_delete_service' ) );
42 }
43
44 /**
45 * Enqueue scripts and styles on the sharing settings page.
46 *
47 * @return void
48 */
49 public function sharing_head() {
50 wp_enqueue_script(
51 'sharing-js',
52 Assets::get_file_url_for_environment(
53 '_inc/build/sharedaddy/admin-sharing.min.js',
54 'modules/sharedaddy/admin-sharing.js'
55 ),
56 array( 'jquery', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-sortable', 'jquery-form' ),
57 JETPACK__VERSION,
58 false
59 );
60
61 /**
62 * Filters the switch that if set to true allows Jetpack to use minified assets. Defaults to true
63 * if the SCRIPT_DEBUG constant is not set or set to false. The filter overrides it.
64 *
65 * @since 6.2.0
66 *
67 * @param boolean $var should Jetpack use minified assets.
68 */
69 $postfix = apply_filters( 'jetpack_should_use_minified_assets', true ) ? '.min' : '';
70 if ( is_rtl() ) {
71 wp_enqueue_style( 'sharing-admin', WP_SHARING_PLUGIN_URL . 'admin-sharing-rtl' . $postfix . '.css', false, JETPACK__VERSION );
72 } else {
73 wp_enqueue_style( 'sharing-admin', WP_SHARING_PLUGIN_URL . 'admin-sharing' . $postfix . '.css', false, JETPACK__VERSION );
74 }
75 wp_enqueue_style( 'sharing', WP_SHARING_PLUGIN_URL . 'sharing.css', false, JETPACK__VERSION );
76
77 wp_enqueue_style( 'social-logos' );
78 wp_enqueue_script( 'sharing-js-fe', WP_SHARING_PLUGIN_URL . 'sharing.js', array(), 4, false );
79 add_thickbox();
80
81 // On Jetpack sites, make sure we include CSS to style the admin page.
82 if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
83 Jetpack_Admin_Page::load_wrapper_styles();
84 }
85 }
86
87 /**
88 * Load the process that handles saving changes on the sharing settings page.
89 *
90 * @return void
91 */
92 public function admin_init() {
93 if ( isset( $_GET['page'] ) && ( $_GET['page'] === 'sharing.php' || $_GET['page'] === 'sharing' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonces are handled in process_requests.
94 $this->process_requests();
95 }
96 }
97
98 /**
99 * Save changes to sharing settings.
100 *
101 * @return void
102 */
103 public function process_requests() {
104 if (
105 isset( $_POST['_wpnonce'] )
106 && wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'sharing-options' )
107 ) {
108 $sharer = new Sharing_Service();
109 $sharer->set_global_options( $_POST );
110 /**
111 * Fires when updating sharing settings.
112 *
113 * @module sharedaddy
114 *
115 * @since 1.1.0
116 */
117 do_action( 'sharing_admin_update' );
118
119 wp_safe_redirect( admin_url( 'options-general.php?page=sharing&update=saved' ) );
120 die();
121 }
122 }
123
124 /**
125 * Register Sharing settings menu page in offline mode.
126 */
127 public function subscription_menu() {
128 if ( ! ( new Status() )->is_offline_mode() ) {
129 return;
130 }
131
132 add_submenu_page(
133 'options-general.php',
134 __( 'Sharing Settings', 'jetpack' ),
135 __( 'Sharing', 'jetpack' ),
136 'manage_options',
137 'sharing',
138 array( $this, 'wrapper_admin_page' )
139 );
140 }
141
142 /**
143 * Save changes to sharing services via AJAX.
144 *
145 * @return void
146 */
147 public function ajax_save_services() {
148 if (
149 isset( $_POST['_wpnonce'] )
150 && wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'sharing-options' )
151 && isset( $_POST['hidden'] )
152 && isset( $_POST['visible'] )
153 ) {
154 $sharer = new Sharing_Service();
155
156 $sharer->set_blog_services(
157 explode( ',', sanitize_text_field( wp_unslash( $_POST['visible'] ) ) ),
158 explode( ',', sanitize_text_field( wp_unslash( $_POST['hidden'] ) ) )
159 );
160 die();
161 }
162 }
163
164 /**
165 * Create a new custom sharing service via AJAX.
166 *
167 * @return void
168 */
169 public function ajax_new_service() {
170 if (
171 isset( $_POST['_wpnonce'] )
172 && isset( $_POST['sharing_name'] )
173 && isset( $_POST['sharing_url'] )
174 && isset( $_POST['sharing_icon'] )
175 && wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'sharing-new_service' )
176 ) {
177 $sharer = new Sharing_Service();
178 $service = $sharer->new_service(
179 sanitize_text_field( wp_unslash( $_POST['sharing_name'] ) ),
180 esc_url_raw( wp_unslash( $_POST['sharing_url'] ) ),
181 esc_url_raw( wp_unslash( $_POST['sharing_icon'] ) )
182 );
183
184 if ( $service ) {
185 $this->output_service( $service->get_id(), $service );
186 echo '<!--->';
187 $service->button_style = 'icon-text';
188 $this->output_preview( $service );
189
190 die();
191 }
192 }
193
194 // Fail
195 die( '1' );
196 }
197
198 /**
199 * Delete a sharing service via AJAX.
200 *
201 * @return void
202 */
203 public function ajax_delete_service() {
204 if (
205 isset( $_POST['_wpnonce'] )
206 && isset( $_POST['service'] )
207 && wp_verify_nonce(
208 sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ),
209 'sharing-options_' . sanitize_text_field( wp_unslash( $_POST['service'] ) )
210 )
211 ) {
212 $sharer = new Sharing_Service();
213 $sharer->delete_service( sanitize_text_field( wp_unslash( $_POST['service'] ) ) );
214 }
215 }
216
217 /**
218 * Save changes to sharing settings via AJAX.
219 *
220 * @return void
221 */
222 public function ajax_save_options() {
223 if (
224 isset( $_POST['_wpnonce'] )
225 && isset( $_POST['service'] )
226 && wp_verify_nonce(
227 sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ),
228 'sharing-options_' . sanitize_text_field( wp_unslash( $_POST['service'] ) )
229 )
230 ) {
231 $sharer = new Sharing_Service();
232 $service = $sharer->get_service( sanitize_text_field( wp_unslash( $_POST['service'] ) ) );
233
234 if ( $service && $service instanceof Sharing_Advanced_Source ) {
235 $service->update_options( $_POST );
236
237 $sharer->set_service( sanitize_text_field( wp_unslash( $_POST['service'] ) ), $service );
238 }
239
240 $this->output_service( $service->get_id(), $service, true );
241 echo '<!--->';
242 $service->button_style = 'icon-text';
243 $this->output_preview( $service );
244 die();
245 }
246 }
247
248 /**
249 * Display a preview of a sharing service.
250 *
251 * @param object $service Sharing service object.
252 *
253 * @return void
254 */
255 public function output_preview( $service ) {
256 $klasses = array( 'advanced', 'preview-item' );
257
258 if ( $service->button_style !== 'text' || $service->has_custom_button_style() ) {
259 $klasses[] = 'preview-' . $service->get_class();
260 $klasses[] = 'share-' . $service->get_class();
261 if ( $service->is_deprecated() ) {
262 $klasses[] = 'share-deprecated';
263 }
264
265 if ( $service->get_class() !== $service->get_id() ) {
266 $klasses[] = 'preview-' . $service->get_id();
267 }
268 }
269
270 echo '<li class="' . esc_attr( implode( ' ', $klasses ) ) . '">';
271 $service->display_preview();
272 echo '</li>';
273 }
274
275 /**
276 * Display a specific sharing service.
277 *
278 * @param int $id Service unique ID.
279 * @param object $service Sharing service.
280 * @param bool $show_dropdown Display a dropdown. Not in use at the moment.
281 *
282 * @return void
283 */
284 public function output_service( $id, $service, $show_dropdown = false ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
285 $title = '';
286 $klasses = array( 'service', 'advanced', 'share-' . $service->get_class() );
287 $displayed_klasses = implode( ' ', $klasses );
288
289 if ( $service->is_deprecated() ) {
290 /* translators: %1$s is the name of a deprecated Sharing Service like "Google+" */
291 $title = sprintf( __( 'The %1$s sharing service has shut down or discontinued support for sharing buttons. This sharing button is not displayed to your visitors and should be removed.', 'jetpack' ), $service->get_name() );
292 $klasses[] = 'share-deprecated';
293 }
294
295 ?>
296 <li class="<?php echo esc_attr( $displayed_klasses ); ?>" id="<?php echo esc_attr( $service->get_id() ); ?>" tabindex="0" title="<?php echo esc_attr( $title ); ?>">
297 <span class="options-left"><?php echo esc_html( $service->get_name() ); ?></span>
298 <?php if ( str_starts_with( $service->get_id(), 'custom-' ) || $service->has_advanced_options() ) : ?>
299 <span class="close"><a href="#" class="remove">&times;</a></span>
300 <form method="post" action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>">
301 <input type="hidden" name="action" value="sharing_delete_service" />
302 <input type="hidden" name="service" value="<?php echo esc_attr( $id ); ?>" />
303 <input type="hidden" name="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( 'sharing-options_' . $id ) ); ?>" />
304 </form>
305 <?php endif; ?>
306 </li>
307 <?php
308 }
309
310 /**
311 * Display admin UI within a Jetpack header and footer.
312 *
313 * @return void
314 */
315 public function wrapper_admin_page() {
316 Jetpack_Admin_Page::wrap_ui( array( $this, 'management_page' ), array( 'is-wide' => true ) );
317 }
318
319 /**
320 * Sharing settings inner page structure.
321 *
322 * @return void
323 */
324 public function management_page() {
325
326 if ( ! function_exists( 'mb_stripos' ) ) {
327 echo '<div id="message" class="updated fade"><h3>' . esc_html__( 'Warning! Multibyte support missing!', 'jetpack' ) . '</h3>';
328 echo '<p>' . wp_kses(
329 sprintf(
330 /* Translators: placeholder is a link to a PHP support document. */
331 __( 'This plugin will work without it, but multibyte support is used <a href="%s" rel="noopener noreferrer" target="_blank">if available</a>. You may see minor problems with Tweets and other sharing services.', 'jetpack' ),
332 'https://www.php.net/manual/en/mbstring.installation.php'
333 ),
334 array(
335 'a' => array(
336 'href' => array(),
337 'rel' => array(),
338 'target' => array(),
339 ),
340 )
341 ) . '</p></div>';
342 }
343
344 if ( isset( $_GET['update'] ) && 'saved' === $_GET['update'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- only used to display a message.
345 echo '<div class="updated"><p>' . esc_html__( 'Settings have been saved', 'jetpack' ) . '</p></div>';
346 }
347 ?>
348
349 <div class="wrap">
350 <div class="icon32" id="icon-options-general"><br /></div>
351 <h1><?php esc_html_e( 'Sharing Settings', 'jetpack' ); ?></h1>
352
353 <?php
354 /**
355 * Fires at the top of the admin sharing settings screen.
356 *
357 * @module sharedaddy
358 *
359 * @since 1.6.0
360 */
361 do_action( 'pre_admin_screen_sharing' );
362 ?>
363
364 <?php
365 $block_availability = Jetpack_Gutenberg::get_cached_availability();
366 $is_block_available = (bool) isset( $block_availability['sharing-buttons'] ) && $block_availability['sharing-buttons']['available'];
367 $is_block_theme = wp_is_block_theme();
368 $show_block_message = $is_block_available && $is_block_theme;
369
370 // We either show old services config or the sharing block message.
371 if ( current_user_can( 'manage_options' ) ) :
372 $show_block_message ? $this->sharing_block_display() : $this->services_config_display();
373 endif;
374 ?>
375 </div>
376
377 <script type="text/javascript">
378 var sharing_loading_icon = '<?php echo esc_js( admin_url( '/images/loading.gif' ) ); ?>';
379 <?php
380 // phpcs:disable WordPress.Security.NonceVerification.Recommended -- we handle the nonce on the PHP side.
381 if (
382 isset( $_GET['create_new_service'] ) && isset( $_GET['name'] ) && isset( $_GET['url'] ) && isset( $_GET['icon'] )
383 && 'true' == $_GET['create_new_service'] // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
384 ) :
385 ?>
386 jQuery(document).ready(function() {
387 // Prefill new service box and then open it
388 jQuery( '#new_sharing_name' ).val( '<?php echo esc_js( sanitize_text_field( wp_unslash( $_GET['name'] ) ) ); ?>' );
389 jQuery( '#new_sharing_url' ).val( '<?php echo esc_js( sanitize_text_field( wp_unslash( $_GET['url'] ) ) ); ?>' );
390 jQuery( '#new_sharing_icon' ).val( '<?php echo esc_js( sanitize_text_field( wp_unslash( $_GET['icon'] ) ) ); ?>' );
391 jQuery( '#add-a-new-service' ).click();
392 });
393 <?php endif; ?>
394 </script>
395 <?php
396 // phpcs:enable WordPress.Security.NonceVerification.Recommended
397 }
398
399 /**
400 * Display services admin UI for settings.
401 *
402 * @return void
403 */
404 public function services_config_display() {
405 $sharer = new Sharing_Service();
406 $enabled = $sharer->get_blog_services();
407 $global = $sharer->get_global_options();
408
409 $shows = array_values( get_post_types( array( 'public' => true ) ) );
410 array_unshift( $shows, 'index' );
411 if ( ! isset( $global['sharing_label'] ) ) {
412 $global['sharing_label'] = __( 'Share this:', 'jetpack' );
413 }
414 ?>
415 <div class="share_manage_options">
416 <h2><?php esc_html_e( 'Sharing Buttons', 'jetpack' ); ?></h2>
417 <p><?php esc_html_e( 'Add sharing buttons to your blog and allow your visitors to share posts with their friends.', 'jetpack' ); ?></p>
418
419 <div id="services-config">
420 <table id="available-services">
421 <tr>
422 <td class="description">
423 <h3><?php esc_html_e( 'Available Services', 'jetpack' ); ?></h3>
424 <p><?php esc_html_e( "Drag and drop the services you'd like to enable into the box below.", 'jetpack' ); ?></p>
425 <p><a href="#TB_inline?height=395&amp;width=600&amp;inlineId=new-service" class="thickbox" id="add-a-new-service"><?php esc_html_e( 'Add a new service', 'jetpack' ); ?></a></p>
426 </td>
427 <td class="services">
428 <ul class="services-available" style="height: 100px;">
429 <?php foreach ( $sharer->get_all_services_blog() as $id => $service ) : ?>
430 <?php
431 if ( ! isset( $enabled['all'][ $id ] ) ) {
432 $this->output_service( $id, $service );
433 }
434 ?>
435 <?php endforeach; ?>
436 </ul>
437 <?php
438 if ( ( new Status() )->is_private_site() ) {
439 echo '<p><strong>' . esc_html__( 'Please note that your services have been restricted because your site is private.', 'jetpack' ) . '</strong></p>';
440 }
441 ?>
442 <br class="clearing" />
443 </td>
444 </tr>
445 </table>
446
447 <table id="enabled-services">
448 <tr>
449 <td class="description">
450 <h3>
451 <?php esc_html_e( 'Enabled Services', 'jetpack' ); ?>
452 <img src="<?php echo esc_url( admin_url( 'images/loading.gif' ) ); ?>" width="16" height="16" alt="loading" style="vertical-align: middle; display: none" />
453 </h3>
454 <p><?php esc_html_e( 'Services dragged here will appear individually.', 'jetpack' ); ?></p>
455 </td>
456 <td class="services" id="share-drop-target">
457 <h2 id="drag-instructions"
458 <?php
459 if ( is_countable( $enabled['visible'] ) && count( $enabled['visible'] ) > 0 ) {
460 echo ' style="display: none"';}
461 ?>
462 ><?php esc_html_e( 'Drag and drop available services here.', 'jetpack' ); ?></h2>
463
464 <ul class="services-enabled">
465 <?php foreach ( $enabled['visible'] as $id => $service ) : ?>
466 <?php $this->output_service( $id, $service, true ); ?>
467 <?php endforeach; ?>
468
469 <li class="end-fix"></li>
470 </ul>
471 </td>
472 <td id="hidden-drop-target" class="services">
473 <p><?php esc_html_e( 'Services dragged here will be hidden behind a share button.', 'jetpack' ); ?></p>
474
475 <ul class="services-hidden">
476 <?php foreach ( $enabled['hidden'] as $id => $service ) : ?>
477 <?php $this->output_service( $id, $service, true ); ?>
478 <?php endforeach; ?>
479 <li class="end-fix"></li>
480 </ul>
481 </td>
482 </tr>
483 </table>
484
485 <table id="live-preview">
486 <tr>
487 <td class="description">
488 <h3><?php esc_html_e( 'Live Preview', 'jetpack' ); ?></h3>
489 </td>
490 <td class="services">
491 <h2 <?php echo ( is_countable( $enabled['all'] ) && count( $enabled['all'] ) > 0 ) ? ' style="display: none"' : ''; ?>><?php esc_html_e( 'Sharing is off. Add services above to enable.', 'jetpack' ); ?></h2>
492 <div class="sharedaddy sd-sharing-enabled">
493 <?php if ( is_countable( $enabled['all'] ) && count( $enabled['all'] ) > 0 ) : ?>
494 <h3 class="sd-title"><?php echo esc_html( $global['sharing_label'] ); ?></h3>
495 <?php endif; ?>
496 <div class="sd-content">
497 <ul class="preview">
498 <?php foreach ( $enabled['visible'] as $id => $service ) : ?>
499 <?php $this->output_preview( $service ); ?>
500 <?php endforeach; ?>
501
502 <?php if ( is_countable( $enabled['hidden'] ) && count( $enabled['hidden'] ) > 0 ) : ?>
503 <li class="advanced"><a href="#" class="sharing-anchor sd-button share-more"><span><?php esc_html_e( 'More', 'jetpack' ); ?></span></a></li>
504 <?php endif; ?>
505 </ul>
506
507 <?php if ( is_countable( $enabled['hidden'] ) && count( $enabled['hidden'] ) > 0 ) : ?>
508 <div class="sharing-hidden">
509 <div class="inner" style="display: none; <?php echo count( $enabled['hidden'] ) === 1 ? 'width:150px;' : ''; ?>">
510 <?php if ( count( $enabled['hidden'] ) === 1 ) : ?>
511 <ul style="background-image:none;">
512 <?php else : ?>
513 <ul>
514 <?php endif; ?>
515
516 <?php
517 foreach ( $enabled['hidden'] as $id => $service ) {
518 $this->output_preview( $service );
519 }
520 ?>
521 </ul>
522 </div>
523 </div>
524 <?php endif; ?>
525
526 <ul class="archive" style="display:none;">
527 <?php
528 foreach ( $sharer->get_all_services_blog() as $id => $service ) :
529 if ( isset( $enabled['visible'][ $id ] ) ) {
530 $service = $enabled['visible'][ $id ];
531 } elseif ( isset( $enabled['hidden'][ $id ] ) ) {
532 $service = $enabled['hidden'][ $id ];
533 }
534
535 $service->button_style = 'icon-text'; // The archive needs the full text, which is removed in JS later.
536 $service->smart = false;
537 $this->output_preview( $service );
538 endforeach;
539 ?>
540 <li class="advanced"><a href="#" class="sharing-anchor sd-button share-more"><span><?php esc_html_e( 'More', 'jetpack' ); ?></span></a></li>
541 </ul>
542 </div>
543 </div>
544 <br class="clearing" />
545 </td>
546 </tr>
547 </table>
548
549 <form method="post" action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" id="save-enabled-shares">
550 <input type="hidden" name="action" value="sharing_save_services" />
551 <input type="hidden" name="visible" value="<?php echo esc_attr( implode( ',', array_keys( $enabled['visible'] ) ) ); ?>" />
552 <input type="hidden" name="hidden" value="<?php echo esc_attr( implode( ',', array_keys( $enabled['hidden'] ) ) ); ?>" />
553 <input type="hidden" name="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( 'sharing-options' ) ); ?>" />
554 </form>
555 </div>
556
557 <form method="post" action="">
558 <table class="form-table">
559 <tbody>
560 <tr valign="top">
561 <th scope="row"><label><?php esc_html_e( 'Button style', 'jetpack' ); ?></label></th>
562 <td>
563 <select name="button_style" id="button_style">
564 <option<?php echo ( $global['button_style'] === 'icon-text' ) ? ' selected="selected"' : ''; ?> value="icon-text"><?php esc_html_e( 'Icon + text', 'jetpack' ); ?></option>
565 <option<?php echo ( $global['button_style'] === 'icon' ) ? ' selected="selected"' : ''; ?> value="icon"><?php esc_html_e( 'Icon only', 'jetpack' ); ?></option>
566 <option<?php echo ( $global['button_style'] === 'text' ) ? ' selected="selected"' : ''; ?> value="text"><?php esc_html_e( 'Text only', 'jetpack' ); ?></option>
567 <option<?php echo ( $global['button_style'] === 'official' ) ? ' selected="selected"' : ''; ?> value="official"><?php esc_html_e( 'Official buttons', 'jetpack' ); ?></option>
568 </select>
569 </td>
570 </tr>
571 <tr valign="top">
572 <th scope="row"><label><?php esc_html_e( 'Sharing label', 'jetpack' ); ?></label></th>
573 <td>
574 <input type="text" name="sharing_label" value="<?php echo esc_attr( $global['sharing_label'] ); ?>" />
575 </td>
576 </tr>
577 <?php
578 /**
579 * Filters the HTML at the beginning of the "Show button on" row.
580 *
581 * @module sharedaddy
582 *
583 * @since 2.1.0
584 *
585 * @param string $var Opening HTML tag at the beginning of the "Show button on" row.
586 */
587 echo apply_filters( 'sharing_show_buttons_on_row_start', '<tr valign="top">' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
588 ?>
589 <th scope="row"><label><?php esc_html_e( 'Show buttons on', 'jetpack' ); ?></label></th>
590 <td>
591 <?php
592 $br = false;
593 foreach ( $shows as $show ) :
594 if ( 'index' === $show ) {
595 $label = __( 'Front Page, Archive Pages, and Search Results', 'jetpack' );
596 } else {
597 $post_type_object = get_post_type_object( $show );
598 $label = $post_type_object->labels->name;
599 }
600 ?>
601 <?php
602 if ( $br ) {
603 echo '<br />';
604 }
605 ?>
606 <label><input type="checkbox"<?php checked( in_array( $show, $global['show'], true ) ); ?> name="show[]" value="<?php echo esc_attr( $show ); ?>" /> <?php echo esc_html( $label ); ?></label>
607 <?php
608 $br = true;
609 endforeach;
610 ?>
611 </td>
612 <?php
613 /**
614 * Filters the HTML at the end of the "Show button on" row.
615 *
616 * @module sharedaddy
617 *
618 * @since 2.1.0
619 *
620 * @param string $var Closing HTML tag at the end of the "Show button on" row.
621 */
622 echo apply_filters( 'sharing_show_buttons_on_row_end', '</tr>' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
623 ?>
624
625 <?php
626 /**
627 * Fires at the end of the sharing global options settings table.
628 *
629 * @module sharedaddy
630 *
631 * @since 1.1.0
632 */
633 do_action( 'sharing_global_options' );
634 ?>
635 </tbody>
636 </table>
637
638 <p class="submit">
639 <input type="submit" name="submit" class="button-primary" value="<?php esc_attr_e( 'Save Changes', 'jetpack' ); ?>" />
640 </p>
641
642 <input type="hidden" name="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( 'sharing-options' ) ); ?>" />
643 </form>
644
645 <div id="new-service" style="display: none">
646 <form method="post" action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" id="new-service-form">
647 <table class="form-table">
648 <tbody>
649 <tr valign="top">
650 <th scope="row" width="100"><label><?php esc_html_e( 'Service name', 'jetpack' ); ?></label></th>
651 <td>
652 <input type="text" name="sharing_name" id="new_sharing_name" size="40" />
653 </td>
654 </tr>
655 <tr valign="top">
656 <th scope="row" width="100"><label><?php esc_html_e( 'Sharing URL', 'jetpack' ); ?></label></th>
657 <td>
658 <input type="text" name="sharing_url" id="new_sharing_url" size="40" />
659
660 <p><?php esc_html_e( 'You can add the following variables to your service sharing URL:', 'jetpack' ); ?><br/>
661 <code>%post_id%</code>, <code>%post_title%</code>, <code>%post_slug%</code>, <code>%post_url%</code>, <code>%post_full_url%</code>, <code>%post_excerpt%</code>, <code>%post_tags%</code>, <code>%home_url%</code></p>
662 </td>
663 </tr>
664 <tr valign="top">
665 <th scope="row" width="100"><label><?php esc_html_e( 'Icon URL', 'jetpack' ); ?></label></th>
666 <td>
667 <input type="text" name="sharing_icon" id="new_sharing_icon" size="40" />
668 <p><?php esc_html_e( 'Enter the URL of a 16x16px icon you want to use for this service.', 'jetpack' ); ?></p>
669 </td>
670 </tr>
671 <tr valign="top" width="100">
672 <th scope="row"></th>
673 <td>
674 <input type="submit" class="button-primary" value="<?php esc_attr_e( 'Create Share Button', 'jetpack' ); ?>" />
675 <img src="<?php echo esc_url( admin_url( 'images/loading.gif' ) ); ?>" width="16" height="16" alt="loading" style="vertical-align: middle; display: none" />
676 </td>
677 </tr>
678
679 <?php
680 /**
681 * Fires after the custom sharing service form
682 *
683 * @module sharedaddy
684 *
685 * @since 1.1.0
686 */
687 do_action( 'sharing_new_service_form' );
688 ?>
689 </tbody>
690 </table>
691
692 <?php
693 /**
694 * Fires at the bottom of the admin sharing settings screen.
695 *
696 * @module sharedaddy
697 *
698 * @since 1.6.0
699 */
700 do_action( 'post_admin_screen_sharing' );
701 ?>
702
703 <div class="inerror" style="display: none; margin-top: 15px">
704 <p><?php esc_html_e( 'An error occurred creating your new sharing service - please check you gave valid details.', 'jetpack' ); ?></p>
705 </div>
706
707 <input type="hidden" name="action" value="sharing_new_service" />
708 <input type="hidden" name="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( 'sharing-new_service' ) ); ?>" />
709 </form>
710 </div>
711 <?php
712 }
713
714 /**
715 * Display sharing block admin UI for settings.
716 *
717 * @return void
718 */
719 public function sharing_block_display() {
720 $showcase_services = array(
721 new Share_Tumblr( 'tumblr', array() ),
722 new Share_Facebook( 'facebook', array() ),
723 new Share_Email( 'email', array() ),
724 new Share_Reddit( 'reddit', array() ),
725 );
726 ?>
727
728 <div class="share_manage_options">
729 <br class="clearing" />
730 <h2><?php esc_html_e( 'Sharing Buttons', 'jetpack' ); ?></h2>
731 <div class="sharing-block-message__items-wrapper">
732 <div>
733 <p><?php esc_html_e( 'Add sharing buttons to your blog and allow your visitors to share posts with their friends.', 'jetpack' ); ?></p>
734 <div class="sharing-block-message__buttons-wrapper">
735 <a href="<?php echo esc_url( admin_url( 'site-editor.php?path=%2Fwp_template' ) ); ?>" class="button button-primary">
736 <?php esc_html_e( 'Go to the site editor', 'jetpack' ); ?>
737 </a>
738 <a href="<?php echo esc_url( Redirect::get_url( 'jetpack-support-sharing-block' ) ); ?>" class="button" target="_blank" rel="noopener noreferrer">
739 <?php esc_html_e( 'Learn how to add Sharing Buttons', 'jetpack' ); ?>
740 </a>
741 </div>
742 </div>
743 <div>
744 <p><?php esc_html_e( 'Sharing Buttons example:', 'jetpack' ); ?></p>
745 <div class="sharedaddy sd-sharing-enabled">
746 <div class="sd-content">
747 <ul class="preview">
748 <?php foreach ( $showcase_services as $service ) : ?>
749 <?php $this->output_preview( $service ); ?>
750 <?php endforeach; ?>
751 </ul>
752 </div>
753 </div>
754 </div>
755 <p class="settings-sharing__block-theme-description">
756 <?php
757 printf(
758 wp_kses(
759 /* translators: Link to Jetpack sharing settings. */
760 __( 'You are using a block-based theme. You can <a class="dops-card__link" href="%s">disable Jetpack’s legacy sharing buttons</a> and add a sharing block to your theme’s template instead.', 'jetpack' ),
761 array(
762 'a' => array( 'href' => array() ),
763 )
764 ),
765 esc_url( admin_url( 'admin.php?page=jetpack#/sharing' ) )
766 );
767 ?>
768 </p>
769 </div>
770 <br class="clearing" />
771 </div>
772 <?php
773 }
774 }
775
776 /**
777 * Callback to get the value for the jetpack_sharing_enabled field.
778 *
779 * When the sharing_disabled post_meta is unset, we follow the global setting in Sharing.
780 * When it is set to 1, we disable sharing on the post, regardless of the global setting.
781 * It is not possible to enable sharing on a post if it is disabled globally.
782 *
783 * @param array $post The post object.
784 *
785 * @return bool
786 */
787 function jetpack_post_sharing_get_value( array $post ) {
788 // if sharing IS disabled on this post, enabled=false, so negate the meta
789 return (bool) ! get_post_meta( $post['id'], 'sharing_disabled', true );
790 }
791
792 /**
793 * Callback to set sharing_disabled post_meta when the
794 * jetpack_sharing_enabled field is updated.
795 *
796 * When the sharing_disabled post_meta is unset, we follow the global setting in Sharing.
797 * When it is set to 1, we disable sharing on the post, regardless of the global setting.
798 * It is not possible to enable sharing on a post if it is disabled globally.
799 *
800 * @param bool $enable_sharing Should sharing be enabled on this post.
801 * @param WP_Post $post_object The post object.
802 *
803 * @return int|bool
804 */
805 function jetpack_post_sharing_update_value( $enable_sharing, $post_object ) {
806 if ( $enable_sharing ) {
807 // delete the override if we want to enable sharing
808 return delete_post_meta( $post_object->ID, 'sharing_disabled' );
809 } else {
810 return update_post_meta( $post_object->ID, 'sharing_disabled', true );
811 }
812 }
813
814 /**
815 * Add Sharing post_meta to the REST API Post response.
816 *
817 * @action rest_api_init
818 * @uses register_rest_field
819 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
820 */
821 function jetpack_post_sharing_register_rest_field() {
822 $post_types = get_post_types( array( 'public' => true ) );
823 foreach ( $post_types as $post_type ) {
824 register_rest_field(
825 $post_type,
826 'jetpack_sharing_enabled',
827 array(
828 'get_callback' => 'jetpack_post_sharing_get_value',
829 'update_callback' => 'jetpack_post_sharing_update_value',
830 'schema' => array(
831 'description' => __( 'Are sharing buttons enabled?', 'jetpack' ),
832 'type' => 'boolean',
833 ),
834 )
835 );
836
837 /**
838 * Ensures all public internal post-types support `sharing`
839 * This feature support flag is used by the REST API and Gutenberg.
840 */
841 add_post_type_support( $post_type, 'jetpack-sharing-buttons' );
842 }
843 }
844
845 // Add Sharing post_meta to the REST API Post response.
846 add_action( 'rest_api_init', 'jetpack_post_sharing_register_rest_field' );
847
848 // Some CPTs (e.g. Jetpack portfolios and testimonials) get registered with
849 // restapi_theme_init because they depend on theme support, so let's also hook to that
850 add_action( 'restapi_theme_init', 'jetpack_post_likes_register_rest_field', 20 );
851
852 /**
853 * Initialize sharing settings in WP Admin.
854 *
855 * @return void
856 */
857 function sharing_admin_init() {
858 global $sharing_admin;
859
860 $sharing_admin = new Sharing_Admin();
861 }
862
863 add_action( 'init', 'sharing_admin_init' );
864