PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 9.2.3
Jetpack – WP Security, Backup, Speed, & Growth v9.2.3
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 / gravatar-hovercards.php
gravatar-hovercards.php
367 lines 10.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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
15 define( 'GROFILES__CACHE_BUSTER', gmdate( 'YW' ) );
16
17 function grofiles_hovercards_init() {
18 add_filter( 'get_avatar', 'grofiles_get_avatar', 10, 2 );
19 add_action( 'wp_enqueue_scripts', 'grofiles_attach_cards' );
20 add_action( 'wp_footer', 'grofiles_extra_data' );
21 add_action( 'admin_init', 'grofiles_add_settings' );
22
23 add_action( 'load-index.php', 'grofiles_admin_cards' );
24 add_action( 'load-users.php', 'grofiles_admin_cards' );
25 add_action( 'load-edit-comments.php', 'grofiles_admin_cards' );
26 add_action( 'load-options-discussion.php', 'grofiles_admin_cards_forced' );
27
28 add_filter( 'jetpack_module_configuration_url_gravatar-hovercards', 'gravatar_hovercards_configuration_url' );
29
30 add_filter( 'get_comment_author_url', 'grofiles_amp_comment_author_url', 10, 1 );
31 }
32
33 function gravatar_hovercards_configuration_url() {
34 return admin_url( 'options-discussion.php#show_avatars' );
35 }
36
37 add_action( 'jetpack_modules_loaded', 'grofiles_hovercards_init' );
38
39 /* Hovercard Settings */
40
41 /**
42 * Adds Gravatar Hovercard setting
43 *
44 * @todo - always print HTML, hide via CSS/JS if !show_avatars
45 */
46 function grofiles_add_settings() {
47 if ( !get_option( 'show_avatars' ) )
48 return;
49
50 add_settings_field( 'gravatar_disable_hovercards', __( 'Gravatar Hovercards', 'jetpack' ), 'grofiles_setting_callback', 'discussion', 'avatars' );
51 register_setting( 'discussion', 'gravatar_disable_hovercards', 'grofiles_hovercard_option_sanitize' );
52 }
53
54 /**
55 * HTML for Gravatar Hovercard setting
56 */
57 function grofiles_setting_callback() {
58 global $current_user;
59
60 $checked = 'disabled' == get_option( 'gravatar_disable_hovercards' ) ? '' : 'checked="checked" ';
61
62 echo "<label id='gravatar-hovercard-options'><input {$checked}name='gravatar_disable_hovercards' id='gravatar_disable_hovercards' type='checkbox' value='enabled' class='code' /> " . __( "View people's profiles when you mouse over their Gravatars", 'jetpack' ) . "</label>";
63 ?>
64 <style type="text/css">
65 #grav-profile-example img {
66 float: left;
67 }
68 #grav-profile-example span {
69 padding: 0 1em;
70 }
71 </style>
72 <script type="text/javascript">
73 // <![CDATA[
74 jQuery( function($) {
75 var tr = $( '#gravatar_disable_hovercards' ).change( function() {
76 if ( $( this ).is( ':checked' ) ) {
77 $( '#grav-profile-example' ).slideDown( 'fast' );
78 } else {
79 $( '#grav-profile-example' ).slideUp( 'fast' );
80 }
81 } ).parents( 'tr' );
82 var ftr = tr.parents( 'table' ).find( 'tr:first' );
83 if ( ftr.length && !ftr.find( '#gravatar_disable_hovercards' ).length ) {
84 ftr.after( tr );
85 }
86 } );
87 // ]]>
88 </script>
89 <p id="grav-profile-example" class="hide-if-no-js"<?php if ( !$checked ) echo ' style="display:none"'; ?>><?php echo get_avatar( $current_user->ID, 64 ); ?> <span><?php _e( 'Put your mouse over your Gravatar to check out your profile.', 'jetpack' ); ?> <br class="clear" /></span></p>
90 <?php
91 }
92
93 /**
94 * Sanitation filter for Gravatar Hovercard setting
95 */
96 function grofiles_hovercard_option_sanitize( $val ) {
97 if ( 'disabled' == $val ) {
98 return $val;
99 }
100
101 return $val ? 'enabled' : 'disabled';
102 }
103
104
105 /* Hovercard Display */
106
107 /**
108 * Stores the gravatars' users that need extra profile data attached.
109 *
110 * Getter/Setter
111 *
112 * @param int|string|null $author Setter: User ID or email address. Getter: null.
113 *
114 * @return mixed Setter: void. Getter: array of user IDs and email addresses.
115 */
116 function grofiles_gravatars_to_append( $author = null ) {
117 static $authors = array();
118
119 // Get
120 if ( is_null( $author ) ) {
121 return array_keys( $authors );
122 }
123
124 // Set
125
126 if ( is_numeric( $author ) ) {
127 $author = (int) $author;
128 }
129
130 $authors[$author] = true;
131 }
132
133 /**
134 * In AMP, override the comment URL to allow for interactivity without
135 * navigating to a new page
136 *
137 * @param string $url The comment author's URL.
138 *
139 * @return string The adjusted URL
140 */
141 function grofiles_amp_comment_author_url( $url ) {
142 if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
143 return '#!';
144 }
145
146 return $url;
147 }
148
149 /**
150 * Stores the user ID or email address for each gravatar generated.
151 *
152 * Attached to the 'get_avatar' filter.
153 *
154 * @param string $avatar The <img/> element of the avatar.
155 * @param mixed $author User ID, email address, user login, comment object, user object, post object
156 *
157 * @return The <img/> element of the avatar.
158 */
159 function grofiles_get_avatar( $avatar, $author ) {
160 $is_amp = class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request();
161
162 if ( is_numeric( $author ) ) {
163 grofiles_gravatars_to_append( $author );
164 } else if ( is_string( $author ) ) {
165 if ( false !== strpos( $author, '@' ) ) {
166 grofiles_gravatars_to_append( $author );
167 } else {
168 if ( $user = get_user_by( 'slug', $author ) )
169 grofiles_gravatars_to_append( $user->ID );
170 }
171 } else if ( isset( $author->comment_type ) ) {
172 if ( $is_amp ) {
173 if ( 1 === preg_match( '/avatar\/([a-zA-Z0-9]+)\?/', $avatar, $email_hash ) ) {
174 $email_hash = $email_hash[1];
175 $cache_group = 'gravatar_profiles_';
176 $cache_key = 'gravatar_profile_' . $email_hash;
177
178 $response_body = wp_cache_get( $cache_key, $cache_group );
179 if ( false === $response_body ) {
180 $response = wp_remote_get( esc_url_raw( 'https://en.gravatar.com/' . $email_hash . '.json' ) );
181
182 if ( is_array( $response ) && ! is_wp_error( $response ) ) {
183 $response_body = json_decode( $response['body'] );
184 wp_cache_set( $cache_key, $response_body, $cache_group, 60 * MINUTE_IN_SECONDS );
185 }
186 }
187
188 $profile = $response_body->entry[0];
189 $display_name = $profile->displayName; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
190 $location = isset( $profile->currentLocation ) ? $profile->currentLocation : ''; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
191 $description = isset( $profile->aboutMe ) ? $profile->aboutMe : ''; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
192
193 $avatar = '
194 <figure data-amp-lightbox="true">
195 ' . $avatar . '
196 <figcaption>
197 ' . esc_html( $display_name ) . ( ! empty( $location ) ? '' . esc_html( $location ) : '' ) . ( ! empty( $description ) ? '' . esc_html( $description ) : '' ) . '
198 </figcaption>
199 </figure>
200 ';
201 }
202
203 return $avatar;
204 }
205
206 if ( '' != $author->comment_type && 'comment' != $author->comment_type )
207 return $avatar;
208 if ( $author->user_id )
209 grofiles_gravatars_to_append( $author->user_id );
210 else
211 grofiles_gravatars_to_append( $author->comment_author_email );
212 } else if ( isset( $author->user_login ) ) {
213 grofiles_gravatars_to_append( $author->ID );
214 } else if ( isset( $author->post_author ) ) {
215 grofiles_gravatars_to_append( $author->post_author );
216 }
217
218 return $avatar;
219 }
220
221 /**
222 * Loads Gravatar Hovercard script.
223 *
224 * @todo is_singular() only?
225 */
226 function grofiles_attach_cards() {
227 global $blog_id;
228
229 // Is the display of Avatars disabled?
230 if ( ! get_option( 'show_avatars' ) ) {
231 return;
232 }
233
234 // Is the display of Gravatar Hovercards disabled?
235 if ( 'disabled' == Jetpack_Options::get_option_and_ensure_autoload( 'gravatar_disable_hovercards', '0' ) ) {
236 return;
237 }
238
239 if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
240 wp_enqueue_style( 'gravatar-hovercard-style', plugins_url( '/gravatar/gravatar-hovercards-amp.css', __FILE__ ), array(), JETPACK__VERSION );
241 } else {
242 wp_enqueue_script( 'grofiles-cards', 'https://secure.gravatar.com/js/gprofiles.js', array(), GROFILES__CACHE_BUSTER, true );
243 wp_enqueue_script( 'wpgroho', plugins_url( 'wpgroho.js', __FILE__ ), array( 'grofiles-cards' ), JETPACK__VERSION, true );
244 if ( is_user_logged_in() ) {
245 $cu = wp_get_current_user();
246 $my_hash = md5( $cu->user_email );
247 } elseif ( ! empty( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ) ) {
248 $my_hash = md5( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] );
249 } else {
250 $my_hash = '';
251 }
252 wp_localize_script( 'wpgroho', 'WPGroHo', compact( 'my_hash' ) );
253 }
254 }
255
256 function grofiles_attach_cards_forced() {
257 add_filter( 'pre_option_gravatar_disable_hovercards', 'grofiles_force_gravatar_enable_hovercards' );
258 grofiles_attach_cards();
259 }
260
261 function grofiles_force_gravatar_enable_hovercards() {
262 return 'enabled';
263 }
264
265 function grofiles_admin_cards_forced() {
266 add_action( 'admin_footer', 'grofiles_attach_cards_forced' );
267 }
268
269 function grofiles_admin_cards() {
270 add_action( 'admin_footer', 'grofiles_attach_cards' );
271 }
272
273 function grofiles_extra_data() {
274 $authors = grofiles_gravatars_to_append();
275
276 if ( ! $authors ) {
277 wp_dequeue_script( 'grofiles-cards' );
278 wp_dequeue_script( 'wpgroho' );
279 } else {
280 ?>
281 <div style="display:none">
282 <?php
283 foreach ( $authors as $author ) {
284 grofiles_hovercards_data_html( $author );
285 }
286 ?>
287 </div>
288 <?php
289 }
290 }
291
292 /**
293 * Echoes the data from grofiles_hovercards_data() as HTML elements.
294 *
295 * @since 5.5.0 Add support for a passed WP_User object
296 *
297 * @param int|string|WP_User $author User ID, email address, or a WP_User object
298 */
299 function grofiles_hovercards_data_html( $author ) {
300 $data = grofiles_hovercards_data( $author );
301 $hash = '';
302 if ( is_numeric( $author ) ) {
303 $user = get_userdata( $author );
304 if ( $user ) {
305 $hash = md5( $user->user_email );
306 }
307 } elseif ( is_email( $author ) ) {
308 $hash = md5( $author );
309 } elseif ( is_a( $author, 'WP_User' ) ) {
310 $hash = md5( $author->user_email );
311 }
312
313 if ( ! $hash ) {
314 return;
315 }
316 ?>
317 <div class="grofile-hash-map-<?php echo $hash; ?>">
318 <?php foreach ( $data as $key => $value ) : ?>
319 <span class="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $value ); ?></span>
320 <?php endforeach; ?>
321 </div>
322 <?php
323 }
324
325
326 /* API */
327
328 /**
329 * Returns the PHP callbacks for data sources.
330 *
331 * 'grofiles_hovercards_data_callbacks' filter
332 *
333 * @return array( data_key => data_callback, ... )
334 */
335 function grofiles_hovercards_data_callbacks() {
336 /**
337 * Filter the Gravatar Hovercard PHP callbacks.
338 *
339 * @module gravatar-hovercards
340 *
341 * @since 1.1.0
342 *
343 * @param array $args Array of data callbacks.
344 */
345 return apply_filters( 'grofiles_hovercards_data_callbacks', array() );
346 }
347
348 /**
349 * Keyed JSON object containing all profile data provided by registered callbacks
350 *
351 * @param int|strung $author User ID or email address
352 *
353 * @return array( data_key => data, ... )
354 */
355 function grofiles_hovercards_data( $author ) {
356 $r = array();
357 foreach ( grofiles_hovercards_data_callbacks() as $key => $callback ) {
358 if ( !is_callable( $callback ) )
359 continue;
360 $data = call_user_func( $callback, $author, $key );
361 if ( !is_null( $data ) )
362 $r[$key] = $data;
363 }
364
365 return $r;
366 }
367