PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 13.6.2
Jetpack – WP Security, Backup, Speed, & Growth v13.6.2
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 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 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 / sharedaddy.php
jetpack / modules / sharedaddy Last commit date
images 2 years ago services 2 years ago admin-sharing-rtl.css 2 years ago admin-sharing-rtl.min.css 2 years ago admin-sharing.css 2 years ago admin-sharing.js 2 years ago admin-sharing.min.css 2 years ago amp-sharing.css 2 years ago recaptcha.php 4 years ago sharedaddy.php 2 years ago sharing-service.php 2 years ago sharing-sources.php 2 years ago sharing.css 2 years ago sharing.js 3 years ago sharing.php 2 years ago
sharedaddy.php
463 lines
1 <?php
2 /**
3 * Jetpack's Sharing feature, nee Sharedaddy.
4 * The most super duper sharing tool on the interwebs.
5 *
6 * @package automattic/jetpack
7 */
8
9 // Set up Sharing in wp-admin.
10 require_once plugin_dir_path( __FILE__ ) . 'sharing.php';
11
12 /**
13 * Send an email via the Email sharing button.
14 *
15 * @param array $data Array of information about the shared message.
16 *
17 * @return void
18 *
19 * @deprecated 11.0
20 */
21 function sharing_email_send_post( $data ) {
22
23 $content = sharing_email_send_post_content( $data );
24 // Borrowed from wp_mail();
25
26 if ( empty( $_SERVER['SERVER_NAME'] ) ) {
27 return;
28 }
29
30 $sitename = strtolower( sanitize_text_field( wp_unslash( $_SERVER['SERVER_NAME'] ) ) );
31 if ( str_starts_with( $sitename, 'www.' ) ) {
32 $sitename = substr( $sitename, 4 );
33 }
34
35 /** This filter is documented in core/src/wp-includes/pluggable.php */
36 $from_email = apply_filters( 'wp_mail_from', 'wordpress@' . $sitename );
37
38 if ( ! empty( $data['name'] ) ) {
39 $s_name = (string) $data['name'];
40 $name_needs_encoding_regex =
41 '/[' .
42 // SpamAssasin's list of characters which "need MIME" encoding
43 '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff' .
44 // Our list of "unsafe" characters
45 '<\r\n' .
46 ']/';
47
48 $needs_encoding =
49 // If it contains any blocked chars.
50 preg_match( $name_needs_encoding_regex, $s_name ) ||
51 // Or if we can't use `mb_convert_encoding`
52 ! function_exists( 'mb_convert_encoding' ) ||
53 // Or if it's not already ASCII
54 mb_convert_encoding( $data['name'], 'ASCII' ) !== $s_name;
55
56 if ( $needs_encoding ) {
57 $data['name'] = sprintf( '=?UTF-8?B?%s?=', base64_encode( $data['name'] ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
58 }
59 }
60
61 $headers = array();
62 $headers[] = sprintf( 'From: %1$s <%2$s>', $data['name'], $from_email );
63 $headers[] = sprintf( 'Reply-To: %1$s <%2$s>', $data['name'], $data['source'] );
64
65 // Make sure to pass the title through the normal sharing filters.
66 $title = $data['sharing_source']->get_share_title( $data['post']->ID );
67
68 /**
69 * Filter the Sharing Email Send Post Subject.
70 *
71 * @module sharedaddy
72 *
73 * @since 5.8.0
74 *
75 * @param string $var Sharing Email Send Post Subject. Default is "Shared Post".
76 */
77 $subject = apply_filters( 'wp_sharing_email_send_post_subject', '[' . __( 'Shared Post', 'jetpack' ) . '] ' . $title );
78
79 wp_mail( $data['target'], $subject, $content, $headers );
80 }
81
82 /**
83 * Checks for spam using Akismet if available.
84 * Return $data as it if email about to be send out is not spam.
85 *
86 * @param array $data Array of information about the shared message.
87 *
88 * @return array $data
89 *
90 * @deprecated 11.0
91 */
92 function sharing_email_check_for_spam_via_akismet( $data ) {
93
94 if ( ! Jetpack::is_akismet_active() ) {
95 return $data;
96 }
97
98 // Prepare the body_request for akismet
99 $body_request = array(
100 'blog' => get_option( 'home' ),
101 'permalink' => $data['sharing_source']->get_share_url( $data['post']->ID ),
102 'comment_type' => 'share',
103 'comment_author' => $data['name'],
104 'comment_author_email' => $data['source'],
105 'comment_content' => sharing_email_send_post_content( $data ),
106 'user_agent' => ( isset( $_SERVER['HTTP_USER_AGENT'] )
107 ? filter_var( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) )
108 : null
109 ),
110 );
111
112 if ( method_exists( 'Akismet', 'http_post' ) ) {
113 $body_request['user_ip'] = Akismet::get_ip_address();
114 $response = Akismet::http_post( build_query( $body_request ), 'comment-check' );
115 } else {
116 global $akismet_api_host, $akismet_api_port;
117 $body_request['user_ip'] = ( isset( $_SERVER['REMOTE_ADDR'] )
118 ? filter_var( wp_unslash( $_SERVER['REMOTE_ADDR'] ) )
119 : null
120 );
121 $response = akismet_http_post( build_query( $body_request ), $akismet_api_host, '/1.1/comment-check', $akismet_api_port );
122 }
123
124 /*
125 * The Response is spam lets not send the email.
126 * 'true' is spam
127 */
128 if (
129 ! empty( $response )
130 && isset( $response[1] )
131 && 'true' == trim( $response[1] ) // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual -- response comes from the Akismet API.
132 ) {
133 return false; // don't send the email
134 }
135 return $data;
136 }
137
138 /**
139 * Content of the emails sent to the target email address.
140 *
141 * @param array $data Array of information about the shared message.
142 *
143 * @return string $content
144 *
145 * @deprecated 11.0
146 */
147 function sharing_email_send_post_content( $data ) {
148 $content = sprintf(
149 /* translators: included in email when post is shared via email. First item is sender's name. Second is sender's email address. */
150 __( '%1$s (%2$s) thinks you may be interested in the following post:', 'jetpack' ),
151 $data['name'],
152 $data['source']
153 );
154 $content .= "\n\n";
155 // Make sure to pass the title and URL through the normal sharing filters.
156 $content .= $data['sharing_source']->get_share_title( $data['post']->ID ) . "\n";
157 $content .= $data['sharing_source']->get_share_url( $data['post']->ID ) . "\n";
158 return $content;
159 }
160
161 /**
162 * Add a meta box to the post editing screen for sharing.
163 *
164 * @return void
165 */
166 function sharing_add_meta_box() {
167 global $post;
168 if ( empty( $post ) ) { // If a current post is not defined, such as when editing a comment.
169 return;
170 }
171
172 /**
173 * Filter whether to display the Sharing Meta Box or not.
174 *
175 * @module sharedaddy
176 *
177 * @since 3.8.0
178 *
179 * @param bool true Display Sharing Meta Box.
180 * @param $post Post.
181 */
182 if ( ! apply_filters( 'sharing_meta_box_show', true, $post ) ) {
183 return;
184 }
185
186 $post_types = get_post_types( array( 'public' => true ) );
187 /**
188 * Filter the Sharing Meta Box title.
189 *
190 * @module sharedaddy
191 *
192 * @since 2.2.0
193 *
194 * @param string $var Sharing Meta Box title. Default is "Sharing".
195 */
196 $title = apply_filters( 'sharing_meta_box_title', __( 'Sharing', 'jetpack' ) );
197 if ( $post->ID !== get_option( 'page_for_posts' ) ) {
198 foreach ( $post_types as $post_type ) {
199 add_meta_box( 'sharing_meta', $title, 'sharing_meta_box_content', $post_type, 'side', 'default', array( '__back_compat_meta_box' => true ) );
200 }
201 }
202 }
203
204 /**
205 * Content of the meta box.
206 *
207 * @param WP_Post $post The post to share.
208 *
209 * @return void
210 */
211 function sharing_meta_box_content( $post ) {
212 /**
213 * Fires before the sharing meta box content.
214 *
215 * @module sharedaddy
216 *
217 * @since 2.2.0
218 *
219 * @param WP_Post $post The post to share.
220 */
221 do_action( 'start_sharing_meta_box_content', $post );
222
223 $disabled = get_post_meta( $post->ID, 'sharing_disabled', true ); ?>
224
225 <p>
226 <label for="enable_post_sharing">
227 <input type="checkbox" name="enable_post_sharing" id="enable_post_sharing" value="1" <?php checked( ! $disabled ); ?>>
228 <?php esc_html_e( 'Show sharing buttons.', 'jetpack' ); ?>
229 </label>
230 <input type="hidden" name="sharing_status_hidden" value="1" />
231 </p>
232
233 <?php
234 /**
235 * Fires after the sharing meta box content.
236 *
237 * @module sharedaddy
238 *
239 * @since 2.2.0
240 *
241 * @param WP_Post $post The post to share.
242 */
243 do_action( 'end_sharing_meta_box_content', $post );
244 }
245
246 /**
247 * Save new sharing status in post meta in the meta box.
248 *
249 * @param int $post_id Post ID.
250 *
251 * @return int
252 */
253 function sharing_meta_box_save( $post_id ) {
254 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
255 return $post_id;
256 }
257
258 if ( ! isset( $_POST['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Core takes care of the validation.
259 return $post_id;
260 }
261
262 $post_type_object = get_post_type_object( sanitize_key( $_POST['post_type'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Core takes care of the validation.
263
264 // Record sharing disable.
265 if (
266 $post_type_object->public
267 && current_user_can( 'edit_post', $post_id )
268 && isset( $_POST['sharing_status_hidden'] ) // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Core takes care of the validation.
269 ) {
270 if ( ! isset( $_POST['enable_post_sharing'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Core takes care of the validation.
271 update_post_meta( $post_id, 'sharing_disabled', 1 );
272 } else {
273 delete_post_meta( $post_id, 'sharing_disabled' );
274 }
275 }
276
277 return $post_id;
278 }
279
280 /**
281 * If Sharing is disabled, disable the meta box.
282 *
283 * @param bool $protected Whether the key is considered protected.
284 * @param string $meta_key Metadata key.
285 *
286 * @return bool
287 */
288 function sharing_meta_box_protected( $protected, $meta_key ) {
289 if ( 'sharing_disabled' === $meta_key ) {
290 $protected = true;
291 }
292
293 return $protected;
294 }
295 add_filter( 'is_protected_meta', 'sharing_meta_box_protected', 10, 2 );
296
297 /**
298 * Add link to sharing settings in the Plugins screen.
299 *
300 * @param array $links An array of plugin action links.
301 *
302 * @return array
303 */
304 function sharing_plugin_settings( $links ) {
305 $settings_link = '<a href="options-general.php?page=sharing.php">' . __( 'Settings', 'jetpack' ) . '</a>';
306 array_unshift( $links, $settings_link );
307 return $links;
308 }
309
310 /**
311 * Add links to settings and support in the plugin row.
312 *
313 * @param array $links An array of the plugin's metadata, including the version, author, author URI, and plugin URI.
314 * @param string $file Path to the plugin file relative to the plugins directory.
315 *
316 * @return array
317 */
318 function sharing_add_plugin_settings( $links, $file ) {
319 if ( $file === basename( __DIR__ ) . '/' . basename( __FILE__ ) ) {
320 $links[] = '<a href="options-general.php?page=sharing.php">' . __( 'Settings', 'jetpack' ) . '</a>';
321 $links[] = '<a href="https://support.wordpress.com/sharing/" rel="noopener noreferrer" target="_blank">' . __( 'Support', 'jetpack' ) . '</a>';
322 }
323
324 return $links;
325 }
326
327 /**
328 * Disable sharing on the frontend if disabled in the admin.
329 *
330 * @return void
331 */
332 function sharing_init() {
333 if ( Jetpack_Options::get_option_and_ensure_autoload( 'sharedaddy_disable_resources', '0' ) ) {
334 add_filter( 'sharing_js', '__return_false' );
335 remove_action( 'wp_head', 'sharing_add_header', 1 );
336 }
337 }
338
339 /**
340 * Add settings to disable CSS and JS normally enqueued by our feature.
341 *
342 * @return void
343 */
344 function sharing_global_resources() {
345 $disable = get_option( 'sharedaddy_disable_resources' );
346 ?>
347 <tr valign="top">
348 <th scope="row"><label for="disable_css"><?php esc_html_e( 'Disable CSS and JS', 'jetpack' ); ?></label></th>
349 <td>
350 <?php
351 printf(
352 '<input id="disable_css" type="checkbox" name="disable_resources"%1$s /> <small><em>%2$s</em></small>',
353 ( 1 == $disable ) ? ' checked="checked"' : '', // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
354 esc_html__( 'Advanced. If this option is checked, you must include these files in your theme manually for the sharing links to work.', 'jetpack' )
355 );
356 ?>
357 </td>
358 </tr>
359 <?php
360 }
361
362 /**
363 * Save settings to disable CSS and JS normally enqueued by our feature.
364 *
365 * @return void
366 */
367 function sharing_global_resources_save() {
368 update_option( 'sharedaddy_disable_resources', isset( $_POST['disable_resources'] ) ? 1 : 0 ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce handling is handled for all elements at once.
369 }
370
371 /**
372 * Returns the Recaptcha site/public key.
373 *
374 * Supports legacy RECAPTCHA_PUBLIC_KEY or RECAPTCHA_SITE_KEY.
375 *
376 * @return string
377 *
378 * @deprecated 11.0
379 */
380 function sharing_recaptcha_site_key() {
381 if ( ! defined( 'RECAPTCHA_PUBLIC_KEY' ) && ! defined( 'RECAPTCHA_SITE_KEY' ) ) {
382 return '';
383 }
384
385 if ( defined( 'RECAPTCHA_PUBLIC_KEY' ) && ! defined( 'RECAPTCHA_SITE_KEY' ) ) {
386 define( 'RECAPTCHA_SITE_KEY', RECAPTCHA_PUBLIC_KEY );
387 }
388
389 return RECAPTCHA_SITE_KEY;
390 }
391
392 /**
393 * Returns the Recaptcha private/secret key.
394 *
395 * Supports legacy RECAPTCHA_PRIVATE_KEY or RECAPTCHA_SECRET_KEY.
396 *
397 * @return string
398 *
399 * @deprecated 11.0
400 */
401 function sharing_recaptcha_secret_key() {
402 if ( ! defined( 'RECAPTCHA_PRIVATE_KEY' ) && ! defined( 'RECAPTCHA_SECRET_KEY' ) ) {
403 return '';
404 }
405
406 if ( defined( 'RECAPTCHA_PRIVATE_KEY' ) && ! defined( 'RECAPTCHA_SECRET_KEY' ) ) {
407 define( 'RECAPTCHA_SECRET_KEY', RECAPTCHA_PRIVATE_KEY );
408 }
409
410 return RECAPTCHA_SECRET_KEY;
411 }
412
413 /**
414 * Contents of a reCAPTCHA box.
415 *
416 * @return void
417 *
418 * @deprecated 11.0
419 */
420 function sharing_email_dialog() {
421 require_once plugin_dir_path( __FILE__ ) . 'recaptcha.php';
422
423 $recaptcha = new Jetpack_ReCaptcha(
424 sharing_recaptcha_site_key(),
425 sharing_recaptcha_secret_key(),
426 array( 'script_lazy' => true )
427 );
428 echo $recaptcha->get_recaptcha_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped in method.
429 }
430
431 /**
432 * Short-circuit the email sharing button based on the results of reCAPTCHA.
433 *
434 * @param bool $true Should we check if the message isn't spam.
435 * @param object $post Post information.
436 * @param array $data Information about the shared message.
437 *
438 * @deprecated 11.0
439 */
440 function sharing_email_check( $true, $post, $data ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
441 require_once plugin_dir_path( __FILE__ ) . 'recaptcha.php';
442
443 $recaptcha = new Jetpack_ReCaptcha( sharing_recaptcha_site_key(), sharing_recaptcha_secret_key(), array( 'script_lazy' => true ) );
444 $response = ! empty( $_POST['g-recaptcha-response'] ) // phpcs:ignore WordPress.Security.NonceVerification.Missing -- we do not change anything on the site based on that.
445 ? filter_var( wp_unslash( $_POST['g-recaptcha-response'] ) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing -- we do not change anything on the site based on that.
446 : '';
447 $remote_addr = ! empty( $_SERVER['REMOTE_ADDR'] )
448 ? filter_var( wp_unslash( $_SERVER['REMOTE_ADDR'] ) )
449 : '';
450 $result = $recaptcha->verify( $response, $remote_addr );
451
452 return ( true === $result );
453 }
454
455 add_action( 'init', 'sharing_init' );
456 add_action( 'add_meta_boxes', 'sharing_add_meta_box' );
457 add_action( 'save_post', 'sharing_meta_box_save' );
458 add_action( 'edit_attachment', 'sharing_meta_box_save' );
459 add_action( 'sharing_global_options', 'sharing_global_resources', 30 );
460 add_action( 'sharing_admin_update', 'sharing_global_resources_save' );
461 add_action( 'plugin_action_links_' . basename( __DIR__ ) . '/' . basename( __FILE__ ), 'sharing_plugin_settings', 10, 4 );
462 add_filter( 'plugin_row_meta', 'sharing_add_plugin_settings', 10, 2 );
463