Completed
Push — gm-17/payment-widget ( cb2702...55e70e )
by
unknown
13:32 queued 03:19
created

gravatar-hovercards.php ➔ grofiles_hovercards_data_html()   C

Complexity

Conditions 7
Paths 15

Size

Total Lines 25
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 20
nc 15
nop 1
dl 0
loc 25
rs 6.7272
c 0
b 0
f 0
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;
0 ignored issues
show
Coding Style Compatibility introduced by
The function gravatar_hovercards_configuration_load() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
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
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
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?
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
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', ( is_ssl() ? 'https://secure' : 'http://s' ) . '.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 )
0 ignored issues
show
Bug introduced by
The expression grofiles_gravatars_to_append() of type array<integer,integer|string>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
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, ... )
0 ignored issues
show
Documentation introduced by
The doc-type array( could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
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, ... )
0 ignored issues
show
Documentation introduced by
The doc-type array( could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
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