PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 11.2
Jetpack – WP Security, Backup, Speed, & Growth v11.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 11.2, at modules/sharedaddy/sharing.php

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