PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 13.3.2
Jetpack – WP Security, Backup, Speed, & Growth v13.3.2
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 / gravatar-hovercards.php
jetpack / modules Last commit date
calypsoify 2 years ago carousel 2 years ago cloudflare-analytics 4 years ago comment-likes 5 years ago comments 2 years ago contact-form 2 years ago custom-css 2 years ago custom-post-types 2 years ago geo-location 4 years ago google-analytics 2 years ago google-fonts 2 years ago gravatar 5 years ago infinite-scroll 2 years ago likes 2 years ago markdown 2 years ago masterbar 2 years ago memberships 2 years ago photon-cdn 2 years ago plugin-search 4 years ago post-by-email 3 years ago related-posts 2 years ago scan 2 years ago seo-tools 2 years ago sharedaddy 2 years ago shortcodes 2 years ago simple-payments 2 years ago site-icon 4 years ago sitemaps 2 years ago sso 2 years ago stats 2 years ago subscriptions 2 years ago theme-tools 2 years ago tiled-gallery 2 years ago verification-tools 4 years ago videopress 2 years ago widget-visibility 2 years ago widgets 2 years ago woocommerce-analytics 2 years ago wordads 2 years ago wpcom-block-editor 2 years ago wpcom-tos 5 years ago blaze.php 2 years ago carousel.php 2 years ago comment-likes.php 2 years ago comments.php 2 years ago contact-form.php 2 years ago copy-post.php 2 years ago custom-content-types.php 4 years ago custom-css.php 3 years ago enhanced-distribution.php 2 years ago geo-location.php 4 years ago google-analytics.php 4 years ago google-fonts.php 2 years ago gravatar-hovercards.php 2 years ago infinite-scroll.php 2 years ago json-api.php 5 years ago latex.php 4 years ago likes.php 2 years ago markdown.php 4 years ago masterbar.php 2 years ago module-extras.php 3 years ago module-headings.php 2 years ago module-info.php 2 years ago monitor.php 2 years ago notes.php 2 years ago photon-cdn.php 2 years ago photon.php 3 years ago plugin-search.php 2 years ago post-by-email.php 5 years ago post-list.php 3 years ago protect.php 3 years ago publicize.php 2 years ago related-posts.php 2 years ago search.php 4 years ago seo-tools.php 2 years ago sharedaddy.php 2 years ago shortcodes.php 2 years ago shortlinks.php 2 years ago sitemaps.php 4 years ago sso.php 2 years ago stats.php 2 years ago subscriptions.php 2 years ago theme-tools.php 3 years ago tiled-gallery.php 4 years ago vaultpress.php 2 years ago verification-tools.php 5 years ago videopress.php 3 years ago waf.php 3 years ago widget-visibility.php 4 years ago widgets.php 3 years ago woocommerce-analytics.php 2 years ago wordads.php 2 years ago wpgroho.js 5 years ago
gravatar-hovercards.php
402 lines
1 <?php
2 /**
3 * Module Name: Gravatar Hovercards
4 * Module Description: Enable pop-up business cards over commenters’ Gravatars.
5 * Sort Order: 11
6 * Recommendation Order: 13
7 * First Introduced: 1.1
8 * Requires Connection: No
9 * Auto Activate: No
10 * Module Tags: Social, Appearance
11 * Feature: Appearance
12 * Additional Search Queries: gravatar, hovercards
13 *
14 * @package automattic/jetpack
15 */
16
17 define( 'GROFILES__CACHE_BUSTER', gmdate( 'YW' ) );
18
19 /**
20 * Actions that are run on init.
21 */
22 function grofiles_hovercards_init() {
23 add_filter( 'get_avatar', 'grofiles_get_avatar', 10, 2 );
24 add_action( 'wp_enqueue_scripts', 'grofiles_attach_cards' );
25 add_action( 'wp_footer', 'grofiles_extra_data' );
26 add_action( 'admin_init', 'grofiles_add_settings' );
27
28 add_action( 'load-index.php', 'grofiles_admin_cards' );
29 add_action( 'load-users.php', 'grofiles_admin_cards' );
30 add_action( 'load-edit-comments.php', 'grofiles_admin_cards' );
31 add_action( 'load-options-discussion.php', 'grofiles_admin_cards_forced' );
32
33 add_filter( 'jetpack_module_configuration_url_gravatar-hovercards', 'gravatar_hovercards_configuration_url' );
34
35 add_filter( 'get_comment_author_url', 'grofiles_amp_comment_author_url', 10, 2 );
36 }
37
38 /**
39 * Set configuration page URL.
40 */
41 function gravatar_hovercards_configuration_url() {
42 return admin_url( 'options-discussion.php#show_avatars' );
43 }
44
45 add_action( 'jetpack_modules_loaded', 'grofiles_hovercards_init' );
46
47 /* Hovercard Settings */
48
49 /**
50 * Adds Gravatar Hovercard setting
51 *
52 * @todo - always print HTML, hide via CSS/JS if !show_avatars
53 */
54 function grofiles_add_settings() {
55 if ( ! get_option( 'show_avatars' ) ) {
56 return;
57 }
58
59 add_settings_field( 'gravatar_disable_hovercards', __( 'Gravatar Hovercards', 'jetpack' ), 'grofiles_setting_callback', 'discussion', 'avatars' );
60 register_setting( 'discussion', 'gravatar_disable_hovercards', 'grofiles_hovercard_option_sanitize' );
61 }
62
63 /**
64 * HTML for Gravatar Hovercard setting
65 */
66 function grofiles_setting_callback() {
67 global $current_user;
68
69 $option = get_option( 'gravatar_disable_hovercards' );
70 printf(
71 "<label id='gravatar-hovercard-options'><input %s name='gravatar_disable_hovercards' id='gravatar_disable_hovercards' type='checkbox' value='enabled' class='code'/>%s</label>",
72 checked( $option, 'enabled', false ),
73 esc_html__( 'View people\'s profiles when you mouse over their Gravatars', 'jetpack' )
74 );
75
76 ?>
77 <style type="text/css">
78 #grav-profile-example img {
79 float: left;
80 }
81 #grav-profile-example span {
82 padding: 0 1em;
83 }
84 </style>
85 <script type="text/javascript">
86 // <![CDATA[
87 jQuery( function($) {
88 var tr = $( '#gravatar_disable_hovercards' ).change( function() {
89 if ( $( this ).is( ':checked' ) ) {
90 $( '#grav-profile-example' ).slideDown( 'fast' );
91 } else {
92 $( '#grav-profile-example' ).slideUp( 'fast' );
93 }
94 } ).parents( 'tr' );
95 var ftr = tr.parents( 'table' ).find( 'tr:first' );
96 if ( ftr.length && !ftr.find( '#gravatar_disable_hovercards' ).length ) {
97 ftr.after( tr );
98 }
99 } );
100 // ]]>
101 </script>
102 <p id="grav-profile-example" class="hide-if-no-js"
103 <?php
104 if ( 'disabled' === $option ) {
105 echo ' style="display:none"';}
106 ?>
107 >
108 <?php echo get_avatar( $current_user->ID, 64 ); ?> <span><?php esc_html_e( 'Put your mouse over your Gravatar to check out your profile.', 'jetpack' ); ?> <br class="clear" /></span></p>
109 <?php
110 }
111
112 /**
113 * Sanitation filter for Gravatar Hovercard setting
114 *
115 * @param string $val Disabled or enabled.
116 */
117 function grofiles_hovercard_option_sanitize( $val ) {
118 if ( 'disabled' === $val ) {
119 return $val;
120 }
121
122 return $val ? 'enabled' : 'disabled';
123 }
124
125 /* Hovercard Display */
126
127 /**
128 * Stores the gravatars' users that need extra profile data attached.
129 *
130 * Getter/Setter
131 *
132 * @param int|string|null $author Setter: User ID or email address. Getter: null.
133 *
134 * @return mixed Setter: void. Getter: array of user IDs and email addresses.
135 */
136 function grofiles_gravatars_to_append( $author = null ) {
137 static $authors = array();
138
139 // Get.
140 if ( $author === null ) {
141 return array_keys( $authors );
142 }
143
144 // Set.
145
146 if ( is_numeric( $author ) ) {
147 $author = (int) $author;
148 }
149
150 $authors[ $author ] = true;
151 }
152
153 /**
154 * In AMP, override the comment URL to allow for interactivity without
155 * navigating to a new page
156 *
157 * @param string $url The comment author's URL.
158 * @param int $id The comment ID.
159 *
160 * @return string The adjusted URL
161 */
162 function grofiles_amp_comment_author_url( $url, $id ) {
163 if ( 'comment' === get_comment_type( $id ) && class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
164 // @todo Disabling the comment author link in this way is not ideal since clicking the link does not cause the lightbox to open in the same way as clicking the gravatar. Likely get_comment_author_url_link should be used instead so that the href attribute can be replaced with an `on` attribute that activates the gallery.
165 return '#!';
166 }
167
168 return $url;
169 }
170
171 /**
172 * Stores the user ID or email address for each gravatar generated.
173 *
174 * Attached to the 'get_avatar' filter.
175 *
176 * @param string $avatar The <img/> element of the avatar.
177 * @param mixed $author User ID, email address, user login, comment object, user object, post object.
178 *
179 * @return string The <img/> element of the avatar.
180 */
181 function grofiles_get_avatar( $avatar, $author ) {
182 $is_amp = class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request();
183
184 if ( is_numeric( $author ) ) {
185 grofiles_gravatars_to_append( $author );
186 } elseif ( is_string( $author ) ) {
187 if ( str_contains( $author, '@' ) ) {
188 grofiles_gravatars_to_append( $author );
189 } else {
190 $user = get_user_by( 'slug', $author );
191 if ( $user ) {
192 grofiles_gravatars_to_append( $user->ID );
193 }
194 }
195 } elseif ( isset( $author->comment_type ) ) {
196 if ( $is_amp ) {
197 if ( 1 === preg_match( '/avatar\/([a-zA-Z0-9]+)\?/', $avatar, $email_hash ) ) {
198 $email_hash = $email_hash[1];
199 $cache_group = 'gravatar_profiles_';
200 $cache_key = 'gravatar_profile_' . $email_hash;
201
202 $response_body = wp_cache_get( $cache_key, $cache_group );
203 if ( false === $response_body ) {
204 $response = wp_remote_get( esc_url_raw( 'https://gravatar.com/' . $email_hash . '.json' ) );
205 if ( is_array( $response ) && ! is_wp_error( $response ) ) {
206 $response_body = json_decode( $response['body'] );
207 wp_cache_set( $cache_key, $response_body, $cache_group, 60 * MINUTE_IN_SECONDS );
208 }
209 }
210
211 $profile = isset( $response_body->entry[0] ) ? $response_body->entry[0] : null;
212 $display_name = isset( $profile->displayName ) ? $profile->displayName : ''; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
213 $location = isset( $profile->currentLocation ) ? $profile->currentLocation : ''; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
214 $description = isset( $profile->aboutMe ) ? $profile->aboutMe : ''; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
215
216 $avatar = '
217 <figure data-amp-lightbox="true">
218 ' . $avatar . '
219 <figcaption>
220 ' . esc_html( $display_name ) . ( ! empty( $location ) ? '' . esc_html( $location ) : '' ) . ( ! empty( $description ) ? '' . esc_html( $description ) : '' ) . '
221 </figcaption>
222 </figure>
223 ';
224 }
225
226 return $avatar;
227 }
228
229 if ( '' !== $author->comment_type && 'comment' !== $author->comment_type ) {
230 return $avatar;
231 }
232 if ( $author->user_id ) {
233 grofiles_gravatars_to_append( $author->user_id );
234 } else {
235 grofiles_gravatars_to_append( $author->comment_author_email );
236 }
237 } elseif ( isset( $author->user_login ) ) {
238 grofiles_gravatars_to_append( $author->ID );
239 } elseif ( isset( $author->post_author ) ) {
240 grofiles_gravatars_to_append( $author->post_author );
241 }
242
243 return $avatar;
244 }
245
246 /**
247 * Loads Gravatar Hovercard script.
248 *
249 * @todo is_singular() only?
250 */
251 function grofiles_attach_cards() {
252
253 // Is the display of Avatars disabled?
254 if ( ! get_option( 'show_avatars' ) ) {
255 return;
256 }
257
258 // Is the display of Gravatar Hovercards disabled?
259 if ( 'disabled' === Jetpack_Options::get_option_and_ensure_autoload( 'gravatar_disable_hovercards', '0' ) ) {
260 return;
261 }
262
263 if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
264 wp_enqueue_style( 'gravatar-hovercard-style', plugins_url( '/gravatar/gravatar-hovercards-amp.css', __FILE__ ), array(), JETPACK__VERSION );
265 } else {
266 wp_enqueue_script( 'grofiles-cards', 'https://secure.gravatar.com/js/gprofiles.js', array(), GROFILES__CACHE_BUSTER, true );
267 wp_enqueue_script( 'wpgroho', plugins_url( 'wpgroho.js', __FILE__ ), array( 'grofiles-cards' ), JETPACK__VERSION, true );
268 if ( is_user_logged_in() ) {
269 $cu = wp_get_current_user();
270 $my_hash = md5( $cu->user_email );
271 } elseif ( ! empty( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ) ) {
272 $my_hash = md5( filter_var( wp_unslash( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ) ) );
273 } else {
274 $my_hash = '';
275 }
276 wp_localize_script( 'wpgroho', 'WPGroHo', compact( 'my_hash' ) );
277 }
278 }
279 /**
280 * Add hovercards on Discussion settings panel.
281 */
282 function grofiles_attach_cards_forced() {
283 add_filter( 'pre_option_gravatar_disable_hovercards', 'grofiles_force_gravatar_enable_hovercards' );
284 grofiles_attach_cards();
285 }
286 /**
287 * Set hovercards as enabled on Discussion settings panel.
288 */
289 function grofiles_force_gravatar_enable_hovercards() {
290 return 'enabled';
291 }
292 /**
293 * Add script to admin footer on Discussion settings panel.
294 */
295 function grofiles_admin_cards_forced() {
296 add_action( 'admin_footer', 'grofiles_attach_cards_forced' );
297 }
298 /**
299 * Add script to admin footer.
300 */
301 function grofiles_admin_cards() {
302 add_action( 'admin_footer', 'grofiles_attach_cards' );
303 }
304 /**
305 * Dequeue the FE assets when there are no gravatars on the page to be displayed.
306 */
307 function grofiles_extra_data() {
308 $authors = grofiles_gravatars_to_append();
309
310 if ( ! $authors ) {
311 wp_dequeue_script( 'grofiles-cards' );
312 wp_dequeue_script( 'wpgroho' );
313 } else {
314 ?>
315 <div style="display:none">
316 <?php
317 foreach ( $authors as $author ) {
318 grofiles_hovercards_data_html( $author );
319 }
320 ?>
321 </div>
322 <?php
323 }
324 }
325
326 /**
327 * Echoes the data from grofiles_hovercards_data() as HTML elements.
328 *
329 * @since 5.5.0 Add support for a passed WP_User object
330 *
331 * @param int|string|WP_User $author User ID, email address, or a WP_User object.
332 */
333 function grofiles_hovercards_data_html( $author ) {
334 $data = grofiles_hovercards_data( $author );
335 $hash = '';
336 if ( is_numeric( $author ) ) {
337 $user = get_userdata( $author );
338 if ( $user ) {
339 $hash = md5( $user->user_email );
340 }
341 } elseif ( is_email( $author ) ) {
342 $hash = md5( $author );
343 } elseif ( is_a( $author, 'WP_User' ) ) {
344 $hash = md5( $author->user_email );
345 }
346
347 if ( ! $hash ) {
348 return;
349 }
350 ?>
351 <div class="grofile-hash-map-<?php echo esc_attr( $hash ); ?>">
352 <?php foreach ( $data as $key => $value ) : ?>
353 <span class="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $value ); ?></span>
354 <?php endforeach; ?>
355 </div>
356 <?php
357 }
358
359 /* API */
360
361 /**
362 * Returns the PHP callbacks for data sources.
363 *
364 * 'grofiles_hovercards_data_callbacks' filter
365 *
366 * @return array( data_key => data_callback, ... )
367 */
368 function grofiles_hovercards_data_callbacks() {
369 /**
370 * Filter the Gravatar Hovercard PHP callbacks.
371 *
372 * @module gravatar-hovercards
373 *
374 * @since 1.1.0
375 *
376 * @param array $args Array of data callbacks.
377 */
378 return apply_filters( 'grofiles_hovercards_data_callbacks', array() );
379 }
380
381 /**
382 * Keyed JSON object containing all profile data provided by registered callbacks
383 *
384 * @param int|strung $author User ID or email address.
385 *
386 * @return array( data_key => data, ... )
387 */
388 function grofiles_hovercards_data( $author ) {
389 $r = array();
390 foreach ( grofiles_hovercards_data_callbacks() as $key => $callback ) {
391 if ( ! is_callable( $callback ) ) {
392 continue;
393 }
394 $data = call_user_func( $callback, $author, $key );
395 if ( $data !== null ) {
396 $r[ $key ] = $data;
397 }
398 }
399
400 return $r;
401 }
402