gravatar-hovercards.php 8.7 KB

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