PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 15.9.1
Jetpack – WP Security, Backup, Speed, & Growth v15.9.1
16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / sharedaddy / sharing.php
jetpack / modules / sharedaddy Last commit date
images 2 months ago services 7 months ago admin-sharing-rtl.css 4 months ago admin-sharing-rtl.min.css 1 month ago admin-sharing.css 4 months ago admin-sharing.js 1 month ago admin-sharing.min.css 1 month ago amp-sharing.css 4 months ago recaptcha.php 1 month ago sharedaddy.php 7 months ago sharing-service.php 1 month ago sharing-sources.php 3 weeks ago sharing.css 4 months ago sharing.js 3 years ago sharing.php 1 month ago
sharing.php
927 lines
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( 'ABSPATH' ) ) {
15 exit( 0 );
16 }
17
18 if ( ! defined( 'WP_SHARING_PLUGIN_URL' ) ) {
19 define( 'WP_SHARING_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
20 define( 'WP_SHARING_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
21 }
22
23 /**
24 * Utilities to manage sharing settings from wp-admin.
25 */
26 class Sharing_Admin {
27
28 /**
29 * Constructor.
30 * Hook into WordPress to add our functionality.
31 */
32 public function __construct() {
33 require_once WP_SHARING_PLUGIN_DIR . 'sharing-service.php';
34
35 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonces are handled in process_requests.
36 if ( isset( $_GET['page'] ) && ( $_GET['page'] === 'sharing.php' || $_GET['page'] === 'sharing' ) ) {
37 add_action( 'admin_init', array( $this, 'admin_init' ) );
38 }
39
40 add_action( 'admin_menu', array( $this, 'subscription_menu' ) );
41
42 // Insert our CSS and JS
43 add_action( 'load-settings_page_sharing', array( $this, 'sharing_head' ) );
44
45 // Catch AJAX
46 add_action( 'wp_ajax_sharing_save_services', array( $this, 'ajax_save_services' ) );
47 add_action( 'wp_ajax_sharing_save_options', array( $this, 'ajax_save_options' ) );
48 add_action( 'wp_ajax_sharing_new_service', array( $this, 'ajax_new_service' ) );
49 add_action( 'wp_ajax_sharing_delete_service', array( $this, 'ajax_delete_service' ) );
50 }
51
52 /**
53 * Enqueue scripts and styles on the sharing settings page.
54 *
55 * @return void
56 */
57 public function sharing_head() {
58 wp_enqueue_script(
59 'sharing-js',
60 Assets::get_file_url_for_environment(
61 '_inc/build/sharedaddy/admin-sharing.min.js',
62 'modules/sharedaddy/admin-sharing.js'
63 ),
64 array( 'jquery', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-sortable', 'jquery-form' ),
65 JETPACK__VERSION,
66 false
67 );
68
69 /**
70 * Filters the switch that if set to true allows Jetpack to use minified assets. Defaults to true
71 * if the SCRIPT_DEBUG constant is not set or set to false. The filter overrides it.
72 *
73 * @since 6.2.0
74 *
75 * @param boolean $var should Jetpack use minified assets.
76 */
77 $postfix = apply_filters( 'jetpack_should_use_minified_assets', true ) ? '.min' : '';
78 if ( is_rtl() ) {
79 wp_enqueue_style( 'sharing-admin', WP_SHARING_PLUGIN_URL . 'admin-sharing-rtl' . $postfix . '.css', false, JETPACK__VERSION );
80 } else {
81 wp_enqueue_style( 'sharing-admin', WP_SHARING_PLUGIN_URL . 'admin-sharing' . $postfix . '.css', false, JETPACK__VERSION );
82 }
83 wp_enqueue_style( 'sharing', WP_SHARING_PLUGIN_URL . 'sharing.css', false, JETPACK__VERSION );
84
85 wp_enqueue_style( 'social-logos' );
86 wp_enqueue_script( 'sharing-js-fe', WP_SHARING_PLUGIN_URL . 'sharing.js', array(), 4, false );
87 add_thickbox();
88
89 // On Jetpack sites, make sure we include CSS to style the admin page.
90 if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
91 Jetpack_Admin_Page::load_wrapper_styles();
92 }
93 }
94
95 /**
96 * Load the process that handles saving changes on the sharing settings page.
97 *
98 * @return void
99 */
100 public function admin_init() {
101 $this->process_requests();
102 }
103
104 /**
105 * Save changes to sharing settings.
106 *
107 * @return void
108 */
109 public function process_requests() {
110 if (
111 isset( $_POST['_wpnonce'] )
112 && wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'sharing-options' )
113 ) {
114 $sharer = new Sharing_Service();
115 $sharer->set_global_options( $_POST );
116 /**
117 * Fires when updating sharing settings.
118 *
119 * @module sharedaddy
120 *
121 * @since 1.1.0
122 */
123 do_action( 'sharing_admin_update' );
124
125 wp_safe_redirect( admin_url( 'options-general.php?page=sharing&update=saved' ) );
126 die( 0 );
127 }
128 }
129
130 /**
131 * Register Sharing settings menu page in Settings > Sharing.
132 */
133 public function subscription_menu() {
134 add_submenu_page(
135 'options-general.php',
136 __( 'Sharing Settings', 'jetpack' ),
137 __( 'Sharing', 'jetpack' ),
138 'manage_options',
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( 0 );
163 }
164 }
165
166 /**
167 * Create a new custom sharing service via AJAX.
168 *
169 * @return never
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( 0 );
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( 0 );
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 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() );
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 ( str_starts_with( $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
328 if ( ! function_exists( 'mb_stripos' ) ) {
329 echo '<div id="message" class="updated fade"><h3>' . esc_html__( 'Warning! Multibyte support missing!', 'jetpack' ) . '</h3>';
330 echo '<p>' . wp_kses(
331 sprintf(
332 /* Translators: placeholder is a link to a PHP support document. */
333 __( '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' ),
334 'https://www.php.net/manual/en/mbstring.installation.php'
335 ),
336 array(
337 'a' => array(
338 'href' => array(),
339 'rel' => array(),
340 'target' => array(),
341 ),
342 )
343 ) . '</p></div>';
344 }
345
346 if ( isset( $_GET['update'] ) && 'saved' === $_GET['update'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- only used to display a message.
347 echo '<div class="updated"><p>' . esc_html__( 'Settings have been saved', 'jetpack' ) . '</p></div>';
348 }
349 ?>
350
351 <div class="wrap">
352 <div class="icon32" id="icon-options-general"><br /></div>
353 <h1><?php esc_html_e( 'Sharing Settings', 'jetpack' ); ?></h1>
354
355 <?php
356 /**
357 * Fires at the top of the admin sharing settings screen.
358 *
359 * @module sharedaddy
360 *
361 * @since 1.6.0
362 */
363 do_action( 'pre_admin_screen_sharing' );
364 ?>
365
366 <?php
367 $is_simple_site = defined( 'IS_WPCOM' ) && IS_WPCOM;
368 $show_block_message = $this->should_use_site_editor() && ! $is_simple_site;
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 wp_json_encode( admin_url( '/images/loading.gif' ), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?>;
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 wp_json_encode( sanitize_text_field( wp_unslash( $_GET['name'] ) ), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?> );
389 jQuery( '#new_sharing_url' ).val( <?php echo wp_json_encode( sanitize_text_field( wp_unslash( $_GET['url'] ) ), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?> );
390 jQuery( '#new_sharing_icon' ).val( <?php echo wp_json_encode( sanitize_text_field( wp_unslash( $_GET['icon'] ) ), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?> );
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 * Check if we should encourage to use the site editor instead of the legacy sharing settings.
401 *
402 * @return boolean
403 */
404 public function should_use_site_editor() {
405 $block_availability = Jetpack_Gutenberg::get_cached_availability();
406 $is_block_available = isset( $block_availability['sharing-buttons'] ) && $block_availability['sharing-buttons']['available'];
407 $is_block_theme = wp_is_block_theme();
408 return $is_block_available && $is_block_theme;
409 }
410
411 /**
412 * Display services admin UI for settings.
413 *
414 * @return void
415 */
416 public function services_config_display() {
417 $sharer = new Sharing_Service();
418 $enabled = $sharer->get_blog_services();
419 $global = $sharer->get_global_options();
420
421 $shows = array_values( get_post_types( array( 'public' => true ) ) );
422 array_unshift( $shows, 'index' );
423 if ( ! isset( $global['sharing_label'] ) ) {
424 $global['sharing_label'] = __( 'Share this:', 'jetpack' );
425 }
426 ?>
427 <div class="share_manage_options">
428 <h2><?php esc_html_e( 'Sharing Buttons', 'jetpack' ); ?></h2>
429 <p><?php esc_html_e( 'Add sharing buttons to your blog and allow your visitors to share posts with their friends.', 'jetpack' ); ?></p>
430
431 <?php
432 $is_simple_site = defined( 'IS_WPCOM' ) && IS_WPCOM;
433 if ( $this->should_use_site_editor() && $is_simple_site ) :
434 $this->site_editor_prompt_display();
435 ?>
436 <div class="notice notice-info inline">
437 <p>
438 <?php esc_html_e( 'You are using a block-based theme. We recommend that you disable the legacy sharing features below and add a sharing button block to your theme’s template instead.', 'jetpack' ); ?>
439 </p>
440 </div>
441 <?php
442 endif;
443 ?>
444
445 <div id="services-config">
446 <table id="available-services">
447 <tr>
448 <td class="description">
449 <h3><?php esc_html_e( 'Available Services', 'jetpack' ); ?></h3>
450 <p><?php esc_html_e( "Drag and drop the services you'd like to enable into the box below.", 'jetpack' ); ?></p>
451 <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>
452 </td>
453 <td class="services">
454 <ul class="services-available" style="height: 100px;">
455 <?php foreach ( $sharer->get_all_services_blog() as $id => $service ) : ?>
456 <?php
457 if ( ! isset( $enabled['all'][ $id ] ) ) {
458 $this->output_service( $id, $service );
459 }
460 ?>
461 <?php endforeach; ?>
462 </ul>
463 <?php
464 if ( ( new Status() )->is_private_site() ) {
465 echo '<p><strong>' . esc_html__( 'Please note that your services have been restricted because your site is private.', 'jetpack' ) . '</strong></p>';
466 }
467 ?>
468 <br class="clearing" />
469 </td>
470 </tr>
471 </table>
472
473 <table id="enabled-services">
474 <tr>
475 <td class="description">
476 <h3>
477 <?php esc_html_e( 'Enabled Services', 'jetpack' ); ?>
478 <span class="spinner" style="vertical-align: middle"></span>
479 </h3>
480 <p><?php esc_html_e( 'Services dragged here will appear individually.', 'jetpack' ); ?></p>
481 </td>
482 <td class="services" id="share-drop-target">
483 <h2 id="drag-instructions"
484 <?php
485 if ( is_countable( $enabled['visible'] ) && count( $enabled['visible'] ) > 0 ) {
486 echo ' style="display: none"';}
487 ?>
488 ><?php esc_html_e( 'Drag and drop available services here.', 'jetpack' ); ?></h2>
489
490 <ul class="services-enabled">
491 <?php foreach ( $enabled['visible'] as $id => $service ) : ?>
492 <?php $this->output_service( $id, $service, true ); ?>
493 <?php endforeach; ?>
494
495 <li class="end-fix"></li>
496 </ul>
497 </td>
498 <td id="hidden-drop-target" class="services">
499 <p><?php esc_html_e( 'Services dragged here will be hidden behind a share button.', 'jetpack' ); ?></p>
500
501 <ul class="services-hidden">
502 <?php foreach ( $enabled['hidden'] as $id => $service ) : ?>
503 <?php $this->output_service( $id, $service, true ); ?>
504 <?php endforeach; ?>
505 <li class="end-fix"></li>
506 </ul>
507 </td>
508 </tr>
509 </table>
510
511 <table id="live-preview">
512 <tr>
513 <td class="description">
514 <h3><?php esc_html_e( 'Live Preview', 'jetpack' ); ?></h3>
515 </td>
516 <td class="services">
517 <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>
518 <div class="sharedaddy sd-sharing-enabled">
519 <?php if ( is_countable( $enabled['all'] ) && count( $enabled['all'] ) > 0 ) : ?>
520 <h3 class="sd-title"><?php echo esc_html( $global['sharing_label'] ); ?></h3>
521 <?php endif; ?>
522 <div class="sd-content">
523 <ul class="preview">
524 <?php foreach ( $enabled['visible'] as $id => $service ) : ?>
525 <?php $this->output_preview( $service ); ?>
526 <?php endforeach; ?>
527
528 <?php if ( is_countable( $enabled['hidden'] ) && count( $enabled['hidden'] ) > 0 ) : ?>
529 <li class="advanced"><a href="#" class="sharing-anchor sd-button share-more"><span><?php esc_html_e( 'More', 'jetpack' ); ?></span></a></li>
530 <?php endif; ?>
531 </ul>
532
533 <?php if ( is_countable( $enabled['hidden'] ) && count( $enabled['hidden'] ) > 0 ) : ?>
534 <div class="sharing-hidden">
535 <div class="inner" style="display: none; <?php echo count( $enabled['hidden'] ) === 1 ? 'width:150px;' : ''; ?>">
536 <?php if ( count( $enabled['hidden'] ) === 1 ) : ?>
537 <ul style="background-image:none;">
538 <?php else : ?>
539 <ul>
540 <?php endif; ?>
541
542 <?php
543 foreach ( $enabled['hidden'] as $id => $service ) {
544 $this->output_preview( $service );
545 }
546 ?>
547 </ul>
548 </div>
549 </div>
550 <?php endif; ?>
551
552 <ul class="archive" style="display:none;">
553 <?php
554 foreach ( $sharer->get_all_services_blog() as $id => $service ) :
555 if ( isset( $enabled['visible'][ $id ] ) ) {
556 $service = $enabled['visible'][ $id ];
557 } elseif ( isset( $enabled['hidden'][ $id ] ) ) {
558 $service = $enabled['hidden'][ $id ];
559 }
560
561 $service->button_style = 'icon-text'; // The archive needs the full text, which is removed in JS later.
562 $service->smart = false;
563 $this->output_preview( $service );
564 endforeach;
565 ?>
566 <li class="advanced"><a href="#" class="sharing-anchor sd-button share-more"><span><?php esc_html_e( 'More', 'jetpack' ); ?></span></a></li>
567 </ul>
568 </div>
569 </div>
570 <br class="clearing" />
571 </td>
572 </tr>
573 </table>
574
575 <form method="post" action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" id="save-enabled-shares">
576 <input type="hidden" name="action" value="sharing_save_services" />
577 <input type="hidden" name="visible" value="<?php echo esc_attr( implode( ',', array_keys( $enabled['visible'] ) ) ); ?>" />
578 <input type="hidden" name="hidden" value="<?php echo esc_attr( implode( ',', array_keys( $enabled['hidden'] ) ) ); ?>" />
579 <input type="hidden" name="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( 'sharing-options' ) ); ?>" />
580 </form>
581 </div>
582
583 <form method="post" action="">
584 <table class="form-table">
585 <tbody>
586 <tr valign="top">
587 <th scope="row"><label><?php esc_html_e( 'Button style', 'jetpack' ); ?></label></th>
588 <td>
589 <select name="button_style" id="button_style">
590 <option<?php echo ( $global['button_style'] === 'icon-text' ) ? ' selected="selected"' : ''; ?> value="icon-text"><?php esc_html_e( 'Icon + text', 'jetpack' ); ?></option>
591 <option<?php echo ( $global['button_style'] === 'icon' ) ? ' selected="selected"' : ''; ?> value="icon"><?php esc_html_e( 'Icon only', 'jetpack' ); ?></option>
592 <option<?php echo ( $global['button_style'] === 'text' ) ? ' selected="selected"' : ''; ?> value="text"><?php esc_html_e( 'Text only', 'jetpack' ); ?></option>
593 <option<?php echo ( $global['button_style'] === 'official' ) ? ' selected="selected"' : ''; ?> value="official"><?php esc_html_e( 'Official buttons', 'jetpack' ); ?></option>
594 </select>
595 </td>
596 </tr>
597 <tr valign="top">
598 <th scope="row"><label><?php esc_html_e( 'Sharing label', 'jetpack' ); ?></label></th>
599 <td>
600 <input type="text" name="sharing_label" value="<?php echo esc_attr( $global['sharing_label'] ); ?>" />
601 </td>
602 </tr>
603 <?php
604 /**
605 * Filters the HTML at the beginning of the "Show button on" row.
606 *
607 * @module sharedaddy
608 *
609 * @since 2.1.0
610 *
611 * @param string $var Opening HTML tag at the beginning of the "Show button on" row.
612 */
613 echo apply_filters( 'sharing_show_buttons_on_row_start', '<tr valign="top">' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
614 ?>
615 <th scope="row"><label><?php esc_html_e( 'Show buttons on', 'jetpack' ); ?></label></th>
616 <td>
617 <?php
618 $br = false;
619 foreach ( $shows as $show ) :
620 if ( 'index' === $show ) {
621 $label = __( 'Front Page, Archive Pages, and Search Results', 'jetpack' );
622 } else {
623 $post_type_object = get_post_type_object( $show );
624 $label = $post_type_object->labels->name;
625 }
626 ?>
627 <?php
628 if ( $br ) {
629 echo '<br />';
630 }
631 ?>
632 <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>
633 <?php
634 $br = true;
635 endforeach;
636 ?>
637 </td>
638 <?php
639 /**
640 * Filters the HTML at the end of the "Show button on" row.
641 *
642 * @module sharedaddy
643 *
644 * @since 2.1.0
645 *
646 * @param string $var Closing HTML tag at the end of the "Show button on" row.
647 */
648 echo apply_filters( 'sharing_show_buttons_on_row_end', '</tr>' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
649 ?>
650
651 <?php
652 /**
653 * Fires at the end of the sharing global options settings table.
654 *
655 * @module sharedaddy
656 *
657 * @since 1.1.0
658 */
659 do_action( 'sharing_global_options' );
660 ?>
661 </tbody>
662 </table>
663
664 <p class="submit">
665 <input type="submit" name="submit" class="button-primary" value="<?php esc_attr_e( 'Save Changes', 'jetpack' ); ?>" />
666 </p>
667
668 <input type="hidden" name="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( 'sharing-options' ) ); ?>" />
669 </form>
670
671 <div id="new-service" style="display: none">
672 <form method="post" action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" id="new-service-form">
673 <table class="form-table">
674 <tbody>
675 <tr valign="top">
676 <th scope="row" width="100"><label><?php esc_html_e( 'Service name', 'jetpack' ); ?></label></th>
677 <td>
678 <input type="text" name="sharing_name" id="new_sharing_name" size="40" />
679 </td>
680 </tr>
681 <tr valign="top">
682 <th scope="row" width="100"><label><?php esc_html_e( 'Sharing URL', 'jetpack' ); ?></label></th>
683 <td>
684 <input type="text" name="sharing_url" id="new_sharing_url" size="40" />
685
686 <p><?php esc_html_e( 'You can add the following variables to your service sharing URL:', 'jetpack' ); ?><br/>
687 <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>
688 </td>
689 </tr>
690 <tr valign="top">
691 <th scope="row" width="100"><label><?php esc_html_e( 'Icon URL', 'jetpack' ); ?></label></th>
692 <td>
693 <input type="text" name="sharing_icon" id="new_sharing_icon" size="40" />
694 <p><?php esc_html_e( 'Enter the URL of a 16x16px icon you want to use for this service.', 'jetpack' ); ?></p>
695 </td>
696 </tr>
697 <tr valign="top" width="100">
698 <th scope="row"></th>
699 <td>
700 <input type="submit" class="button-primary" value="<?php esc_attr_e( 'Create Share Button', 'jetpack' ); ?>" />
701 <span class="spinner" style="vertical-align: middle"></span>
702 </td>
703 </tr>
704
705 <?php
706 /**
707 * Fires after the custom sharing service form
708 *
709 * @module sharedaddy
710 *
711 * @since 1.1.0
712 */
713 do_action( 'sharing_new_service_form' );
714 ?>
715 </tbody>
716 </table>
717
718 <?php
719 /**
720 * Fires at the bottom of the admin sharing settings screen.
721 *
722 * @module sharedaddy
723 *
724 * @since 1.6.0
725 */
726 do_action( 'post_admin_screen_sharing' );
727 ?>
728
729 <div class="inerror" style="display: none; margin-top: 15px">
730 <p><?php esc_html_e( 'An error occurred creating your new sharing service - please check you gave valid details.', 'jetpack' ); ?></p>
731 </div>
732
733 <input type="hidden" name="action" value="sharing_new_service" />
734 <input type="hidden" name="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( 'sharing-new_service' ) ); ?>" />
735 </form>
736 </div>
737 <?php
738 }
739
740 /**
741 * Display sharing block admin UI for settings.
742 *
743 * @return void
744 */
745 public function sharing_block_display() {
746 $showcase_services = array(
747 new Share_Tumblr( 'tumblr', array() ),
748 new Share_Facebook( 'facebook', array() ),
749 new Share_Email( 'email', array() ),
750 new Share_Reddit( 'reddit', array() ),
751 );
752
753 global $submenu;
754 // Hide the link to Jetpack Sharing settings if no Jetpack Settings found in submenu list
755 $show_jetpack_admin_settings_link = array_reduce(
756 $submenu['jetpack'],
757 function ( $carry, $item ) {
758 return $carry || ( isset( $item[2] ) && $item[2] === 'jetpack#/settings' );
759 },
760 false
761 );
762 ?>
763
764 <div class="share_manage_options">
765 <br class="clearing" />
766 <h2><?php esc_html_e( 'Sharing Buttons', 'jetpack' ); ?></h2>
767 <div class="sharing-block-message__items-wrapper">
768 <div>
769 <p><?php esc_html_e( 'Add sharing buttons to your blog and allow your visitors to share posts with their friends.', 'jetpack' ); ?></p>
770 <?php $this->site_editor_prompt_display(); ?>
771 </div>
772 <div>
773 <p><?php esc_html_e( 'Sharing Buttons example:', 'jetpack' ); ?></p>
774 <div class="sharedaddy sd-sharing-enabled">
775 <div class="sd-content">
776 <ul class="preview">
777 <?php foreach ( $showcase_services as $service ) : ?>
778 <?php $this->output_preview( $service ); ?>
779 <?php endforeach; ?>
780 </ul>
781 </div>
782 </div>
783 </div>
784 <?php if ( $show_jetpack_admin_settings_link ) : ?>
785 <p class="settings-sharing__block-theme-description">
786 <?php
787 printf(
788 wp_kses(
789 /* translators: Link to Jetpack sharing settings. */
790 __( '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' ),
791 array(
792 'a' => array( 'href' => array() ),
793 )
794 ),
795 esc_url( admin_url( 'admin.php?page=jetpack#/sharing' ) )
796 );
797 ?>
798 </p>
799 <?php endif; ?>
800 </div>
801 <br class="clearing" />
802 </div>
803 <?php
804 }
805
806 /**
807 * Display the "Go to the site editor" prompt.
808 *
809 * @return void
810 */
811 public function site_editor_prompt_display() {
812 $host = new Status\Host();
813
814 $wpcom_link = 'https://wordpress.com/support/wordpress-editor/blocks/sharing-buttons-block/';
815
816 if ( function_exists( 'localized_wpcom_url' ) ) {
817 $wpcom_link = localized_wpcom_url( $wpcom_link );
818 }
819
820 $link = $host->is_wpcom_platform() ? $wpcom_link : Redirect::get_url( 'jetpack-support-sharing-block' );
821
822 ?>
823 <div class="sharing-block-message__buttons-wrapper">
824 <a href="<?php echo esc_url( admin_url( 'site-editor.php?path=%2Fwp_template' ) ); ?>" class="button button-primary">
825 <?php esc_html_e( 'Go to the site editor', 'jetpack' ); ?>
826 </a>
827 <a data-target="wpcom-help-center" href="<?php echo esc_url( $link ); ?>" class="button" target="_blank" rel="noopener noreferrer">
828 <?php esc_html_e( 'Learn how to add Sharing Buttons', 'jetpack' ); ?>
829 </a>
830 </div>
831 <?php
832 }
833 }
834
835 /**
836 * Callback to get the value for the jetpack_sharing_enabled field.
837 *
838 * When the sharing_disabled post_meta is unset, we follow the global setting in Sharing.
839 * When it is set to 1, we disable sharing on the post, regardless of the global setting.
840 * It is not possible to enable sharing on a post if it is disabled globally.
841 *
842 * @param array $post The post object.
843 *
844 * @return bool
845 */
846 function jetpack_post_sharing_get_value( array $post ) {
847 if ( ! isset( $post['id'] ) ) {
848 return false;
849 }
850
851 // if sharing IS disabled on this post, enabled=false, so negate the meta
852 return ! get_post_meta( $post['id'], 'sharing_disabled', true );
853 }
854
855 /**
856 * Callback to set sharing_disabled post_meta when the
857 * jetpack_sharing_enabled field is updated.
858 *
859 * When the sharing_disabled post_meta is unset, we follow the global setting in Sharing.
860 * When it is set to 1, we disable sharing on the post, regardless of the global setting.
861 * It is not possible to enable sharing on a post if it is disabled globally.
862 *
863 * @param bool $enable_sharing Should sharing be enabled on this post.
864 * @param WP_Post $post_object The post object.
865 *
866 * @return int|bool
867 */
868 function jetpack_post_sharing_update_value( $enable_sharing, $post_object ) {
869 if ( $enable_sharing ) {
870 // delete the override if we want to enable sharing
871 return delete_post_meta( $post_object->ID, 'sharing_disabled' );
872 } else {
873 return update_post_meta( $post_object->ID, 'sharing_disabled', true );
874 }
875 }
876
877 /**
878 * Add Sharing post_meta to the REST API Post response.
879 *
880 * @action rest_api_init
881 * @uses register_rest_field
882 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
883 */
884 function jetpack_post_sharing_register_rest_field() {
885 $post_types = get_post_types( array( 'public' => true ) );
886 foreach ( $post_types as $post_type ) {
887 register_rest_field(
888 $post_type,
889 'jetpack_sharing_enabled',
890 array(
891 'get_callback' => 'jetpack_post_sharing_get_value',
892 'update_callback' => 'jetpack_post_sharing_update_value',
893 'schema' => array(
894 'description' => __( 'Are sharing buttons enabled?', 'jetpack' ),
895 'type' => 'boolean',
896 ),
897 )
898 );
899
900 /**
901 * Ensures all public internal post-types support `sharing`
902 * This feature support flag is used by the REST API and Gutenberg.
903 */
904 add_post_type_support( $post_type, 'jetpack-sharing-buttons' );
905 }
906 }
907
908 // Add Sharing post_meta to the REST API Post response.
909 add_action( 'rest_api_init', 'jetpack_post_sharing_register_rest_field' );
910
911 // Some CPTs (e.g. Jetpack portfolios and testimonials) get registered with
912 // restapi_theme_init because they depend on theme support, so let's also hook to that
913 add_action( 'restapi_theme_init', 'jetpack_post_likes_register_rest_field', 20 );
914
915 /**
916 * Initialize sharing settings in WP Admin.
917 *
918 * @return void
919 */
920 function sharing_admin_init() {
921 global $sharing_admin;
922
923 $sharing_admin = new Sharing_Admin();
924 }
925
926 add_action( 'init', 'sharing_admin_init' );
927