| 1 |
<?php |
| 2 |
/** |
| 3 |
* Module Name: Gravatar Hovercards |
| 4 |
* Module Description: Enable pop-up business cards over commenters’ Gravatars. |
| 5 |
* Jumpstart Description: Let commenters link their profiles to their Gravatar accounts, making it easy for your visitors to learn more about your community. |
| 6 |
* Sort Order: 11 |
| 7 |
* Recommendation Order: 13 |
| 8 |
* First Introduced: 1.1 |
| 9 |
* Requires Connection: No |
| 10 |
* Auto Activate: Yes |
| 11 |
* Module Tags: Social, Appearance |
| 12 |
* Feature: Appearance, Jumpstart |
| 13 |
* Additional Search Queries: gravatar, hovercards |
| 14 |
*/ |
| 15 |
|
| 16 |
define( 'GROFILES__CACHE_BUSTER', gmdate( 'YM' ) . 'aa' ); // Break CDN cache, increment when gravatar.com/js/gprofiles.js changes |
| 17 |
|
| 18 |
function grofiles_hovercards_init() { |
| 19 |
add_filter( 'get_avatar', 'grofiles_get_avatar', 10, 2 ); |
| 20 |
add_action( 'wp_enqueue_scripts', 'grofiles_attach_cards' ); |
| 21 |
add_action( 'wp_footer', 'grofiles_extra_data' ); |
| 22 |
add_action( 'admin_init', 'grofiles_add_settings' ); |
| 23 |
|
| 24 |
add_action( 'load-index.php', 'grofiles_admin_cards' ); |
| 25 |
add_action( 'load-users.php', 'grofiles_admin_cards' ); |
| 26 |
add_action( 'load-edit-comments.php', 'grofiles_admin_cards' ); |
| 27 |
add_action( 'load-options-discussion.php', 'grofiles_admin_cards_forced' ); |
| 28 |
|
| 29 |
Jetpack::enable_module_configurable( __FILE__ ); |
| 30 |
Jetpack::module_configuration_load( __FILE__, 'gravatar_hovercards_configuration_load' ); |
| 31 |
} |
| 32 |
|
| 33 |
function gravatar_hovercards_configuration_load() { |
| 34 |
wp_safe_redirect( admin_url( 'options-discussion.php#show_avatars' ) ); |
| 35 |
exit; |
| 36 |
} |
| 37 |
|
| 38 |
add_action( 'jetpack_modules_loaded', 'grofiles_hovercards_init' ); |
| 39 |
|
| 40 |
/* Hovercard Settings */ |
| 41 |
|
| 42 |
/** |
| 43 |
* Adds Gravatar Hovercard setting |
| 44 |
* |
| 45 |
* @todo - always print HTML, hide via CSS/JS if !show_avatars |
| 46 |
*/ |
| 47 |
function grofiles_add_settings() { |
| 48 |
if ( !get_option( 'show_avatars' ) ) |
| 49 |
return; |
| 50 |
|
| 51 |
add_settings_field( 'gravatar_disable_hovercards', __( 'Gravatar Hovercards', 'jetpack' ), 'grofiles_setting_callback', 'discussion', 'avatars' ); |
| 52 |
register_setting( 'discussion', 'gravatar_disable_hovercards', 'grofiles_hovercard_option_sanitize' ); |
| 53 |
} |
| 54 |
|
| 55 |
/** |
| 56 |
* HTML for Gravatar Hovercard setting |
| 57 |
*/ |
| 58 |
function grofiles_setting_callback() { |
| 59 |
global $current_user; |
| 60 |
|
| 61 |
$checked = 'disabled' == get_option( 'gravatar_disable_hovercards' ) ? '' : 'checked="checked" '; |
| 62 |
|
| 63 |
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>"; |
| 64 |
?> |
| 65 |
<style type="text/css"> |
| 66 |
#grav-profile-example img { |
| 67 |
float: left; |
| 68 |
} |
| 69 |
#grav-profile-example span { |
| 70 |
padding: 0 1em; |
| 71 |
} |
| 72 |
</style> |
| 73 |
<script type="text/javascript"> |
| 74 |
// <![CDATA[ |
| 75 |
jQuery( function($) { |
| 76 |
var tr = $( '#gravatar_disable_hovercards' ).change( function() { |
| 77 |
if ( $( this ).is( ':checked' ) ) { |
| 78 |
$( '#grav-profile-example' ).slideDown( 'fast' ); |
| 79 |
} else { |
| 80 |
$( '#grav-profile-example' ).slideUp( 'fast' ); |
| 81 |
} |
| 82 |
} ).parents( 'tr' ); |
| 83 |
var ftr = tr.parents( 'table' ).find( 'tr:first' ); |
| 84 |
if ( ftr.length && !ftr.find( '#gravatar_disable_hovercards' ).length ) { |
| 85 |
ftr.after( tr ); |
| 86 |
} |
| 87 |
} ); |
| 88 |
// ]]> |
| 89 |
</script> |
| 90 |
<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> |
| 91 |
<?php |
| 92 |
} |
| 93 |
|
| 94 |
/** |
| 95 |
* Sanitation filter for Gravatar Hovercard setting |
| 96 |
*/ |
| 97 |
function grofiles_hovercard_option_sanitize( $val ) { |
| 98 |
if ( 'disabled' == $val ) { |
| 99 |
return $val; |
| 100 |
} |
| 101 |
|
| 102 |
return $val ? 'enabled' : 'disabled'; |
| 103 |
} |
| 104 |
|
| 105 |
|
| 106 |
/* Hovercard Display */ |
| 107 |
|
| 108 |
/** |
| 109 |
* Stores the gravatars' users that need extra profile data attached. |
| 110 |
* |
| 111 |
* Getter/Setter |
| 112 |
* |
| 113 |
* @param int|string|null $author Setter: User ID or email address. Getter: null. |
| 114 |
* |
| 115 |
* @return mixed Setter: void. Getter: array of user IDs and email addresses. |
| 116 |
*/ |
| 117 |
function grofiles_gravatars_to_append( $author = null ) { |
| 118 |
static $authors = array(); |
| 119 |
|
| 120 |
// Get |
| 121 |
if ( is_null( $author ) ) { |
| 122 |
return array_keys( $authors ); |
| 123 |
} |
| 124 |
|
| 125 |
// Set |
| 126 |
|
| 127 |
if ( is_numeric( $author ) ) { |
| 128 |
$author = (int) $author; |
| 129 |
} |
| 130 |
|
| 131 |
$authors[$author] = true; |
| 132 |
} |
| 133 |
|
| 134 |
/** |
| 135 |
* Stores the user ID or email address for each gravatar generated. |
| 136 |
* |
| 137 |
* Attached to the 'get_avatar' filter. |
| 138 |
* |
| 139 |
* @param string $avatar The <img/> element of the avatar. |
| 140 |
* @param mixed $author User ID, email address, user login, comment object, user object, post object |
| 141 |
* |
| 142 |
* @return The <img/> element of the avatar. |
| 143 |
*/ |
| 144 |
function grofiles_get_avatar( $avatar, $author ) { |
| 145 |
if ( is_numeric( $author ) ) { |
| 146 |
grofiles_gravatars_to_append( $author ); |
| 147 |
} else if ( is_string( $author ) ) { |
| 148 |
if ( false !== strpos( $author, '@' ) ) { |
| 149 |
grofiles_gravatars_to_append( $author ); |
| 150 |
} else { |
| 151 |
if ( $user = get_user_by( 'slug', $author ) ) |
| 152 |
grofiles_gravatars_to_append( $user->ID ); |
| 153 |
} |
| 154 |
} else if ( isset( $author->comment_type ) ) { |
| 155 |
if ( '' != $author->comment_type && 'comment' != $author->comment_type ) |
| 156 |
return $avatar; |
| 157 |
if ( $author->user_id ) |
| 158 |
grofiles_gravatars_to_append( $author->user_id ); |
| 159 |
else |
| 160 |
grofiles_gravatars_to_append( $author->comment_author_email ); |
| 161 |
} else if ( isset( $author->user_login ) ) { |
| 162 |
grofiles_gravatars_to_append( $author->ID ); |
| 163 |
} else if ( isset( $author->post_author ) ) { |
| 164 |
grofiles_gravatars_to_append( $author->post_author ); |
| 165 |
} |
| 166 |
|
| 167 |
return $avatar; |
| 168 |
} |
| 169 |
|
| 170 |
/** |
| 171 |
* Loads Gravatar Hovercard script. |
| 172 |
* |
| 173 |
* @todo is_singular() only? |
| 174 |
*/ |
| 175 |
function grofiles_attach_cards() { |
| 176 |
global $blog_id; |
| 177 |
|
| 178 |
// Is the display of Avatars disabled? |
| 179 |
if ( ! get_option( 'show_avatars' ) ) { |
| 180 |
return; |
| 181 |
} |
| 182 |
|
| 183 |
// Is the display of Gravatar Hovercards disabled? |
| 184 |
if ( 'disabled' == Jetpack_Options::get_option_and_ensure_autoload( 'gravatar_disable_hovercards', '0' ) ) { |
| 185 |
return; |
| 186 |
} |
| 187 |
|
| 188 |
wp_enqueue_script( 'grofiles-cards', 'https://secure.gravatar.com/js/gprofiles.js', array( 'jquery' ), GROFILES__CACHE_BUSTER, true ); |
| 189 |
wp_enqueue_script( 'wpgroho', plugins_url( 'wpgroho.js', __FILE__ ), array( 'grofiles-cards' ), false, true ); |
| 190 |
if ( is_user_logged_in() ) { |
| 191 |
$cu = wp_get_current_user(); |
| 192 |
$my_hash = md5( $cu->user_email ); |
| 193 |
} else if ( !empty( $_COOKIE['comment_author_email_' . COOKIEHASH] ) ) { |
| 194 |
$my_hash = md5( $_COOKIE['comment_author_email_' . COOKIEHASH] ); |
| 195 |
} else { |
| 196 |
$my_hash = ''; |
| 197 |
} |
| 198 |
wp_localize_script( 'wpgroho', 'WPGroHo', compact( 'my_hash' ) ); |
| 199 |
} |
| 200 |
|
| 201 |
function grofiles_attach_cards_forced() { |
| 202 |
add_filter( 'pre_option_gravatar_disable_hovercards', 'grofiles_force_gravatar_enable_hovercards' ); |
| 203 |
grofiles_attach_cards(); |
| 204 |
} |
| 205 |
|
| 206 |
function grofiles_force_gravatar_enable_hovercards() { |
| 207 |
return 'enabled'; |
| 208 |
} |
| 209 |
|
| 210 |
function grofiles_admin_cards_forced() { |
| 211 |
add_action( 'admin_footer', 'grofiles_attach_cards_forced' ); |
| 212 |
} |
| 213 |
|
| 214 |
function grofiles_admin_cards() { |
| 215 |
add_action( 'admin_footer', 'grofiles_attach_cards' ); |
| 216 |
} |
| 217 |
|
| 218 |
function grofiles_extra_data() { |
| 219 |
?> |
| 220 |
<div style="display:none"> |
| 221 |
<?php |
| 222 |
foreach ( grofiles_gravatars_to_append() as $author ) |
| 223 |
grofiles_hovercards_data_html( $author ); |
| 224 |
?> |
| 225 |
</div> |
| 226 |
<?php |
| 227 |
} |
| 228 |
|
| 229 |
/** |
| 230 |
* Echoes the data from grofiles_hovercards_data() as HTML elements. |
| 231 |
* |
| 232 |
* @since 5.5.0 Add support for a passed WP_User object |
| 233 |
* |
| 234 |
* @param int|string|WP_User $author User ID, email address, or a WP_User object |
| 235 |
*/ |
| 236 |
function grofiles_hovercards_data_html( $author ) { |
| 237 |
$data = grofiles_hovercards_data( $author ); |
| 238 |
$hash = ''; |
| 239 |
if ( is_numeric( $author ) ) { |
| 240 |
$user = get_userdata( $author ); |
| 241 |
if ( $user ) { |
| 242 |
$hash = md5( $user->user_email ); |
| 243 |
} |
| 244 |
} elseif ( is_email( $author ) ) { |
| 245 |
$hash = md5( $author ); |
| 246 |
} elseif ( is_a( $author, 'WP_User' ) ) { |
| 247 |
$hash = md5( $author->user_email ); |
| 248 |
} |
| 249 |
|
| 250 |
if ( ! $hash ) { |
| 251 |
return; |
| 252 |
} |
| 253 |
?> |
| 254 |
<div class="grofile-hash-map-<?php echo $hash; ?>"> |
| 255 |
<?php foreach ( $data as $key => $value ) : ?> |
| 256 |
<span class="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $value ); ?></span> |
| 257 |
<?php endforeach; ?> |
| 258 |
</div> |
| 259 |
<?php |
| 260 |
} |
| 261 |
|
| 262 |
|
| 263 |
/* API */ |
| 264 |
|
| 265 |
/** |
| 266 |
* Returns the PHP callbacks for data sources. |
| 267 |
* |
| 268 |
* 'grofiles_hovercards_data_callbacks' filter |
| 269 |
* |
| 270 |
* @return array( data_key => data_callback, ... ) |
| 271 |
*/ |
| 272 |
function grofiles_hovercards_data_callbacks() { |
| 273 |
/** |
| 274 |
* Filter the Gravatar Hovercard PHP callbacks. |
| 275 |
* |
| 276 |
* @module gravatar-hovercards |
| 277 |
* |
| 278 |
* @since 1.1.0 |
| 279 |
* |
| 280 |
* @param array $args Array of data callbacks. |
| 281 |
*/ |
| 282 |
return apply_filters( 'grofiles_hovercards_data_callbacks', array() ); |
| 283 |
} |
| 284 |
|
| 285 |
/** |
| 286 |
* Keyed JSON object containing all profile data provided by registered callbacks |
| 287 |
* |
| 288 |
* @param int|strung $author User ID or email address |
| 289 |
* |
| 290 |
* @return array( data_key => data, ... ) |
| 291 |
*/ |
| 292 |
function grofiles_hovercards_data( $author ) { |
| 293 |
$r = array(); |
| 294 |
foreach ( grofiles_hovercards_data_callbacks() as $key => $callback ) { |
| 295 |
if ( !is_callable( $callback ) ) |
| 296 |
continue; |
| 297 |
$data = call_user_func( $callback, $author, $key ); |
| 298 |
if ( !is_null( $data ) ) |
| 299 |
$r[$key] = $data; |
| 300 |
} |
| 301 |
|
| 302 |
return $r; |
| 303 |
} |
| 304 |
|