Completed
Push — update/comments-ignore-author-... ( 4f8a13...0fe3a8 )
by
unknown
11:38
created

Jetpack_Comments::setup_globals()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 12
rs 9.4285
cc 1
eloc 8
nc 1
nop 0
1
<?php
2
3
require dirname( __FILE__ ) . '/base.php';
4
5
/**
6
 * Main Comments class
7
 *
8
 * @package JetpackComments
9
 * @version 1.4
10
 * @since 1.4
11
 */
12
class Jetpack_Comments extends Highlander_Comments_Base {
13
14
	/** Variables *************************************************************/
15
16
	/**
17
	 * Possible comment form sources
18
	 * @var array
19
	 */
20
	public $id_sources = array();
21
22
	/**
23
	 * URL
24
	 * @var string
25
	 */
26
	public $signed_url = '';
27
28
	/**
29
	 * The default comment form color scheme
30
	 * @var string
31
	 * @see ::set_default_color_theme_based_on_theme_settings()
32
	 */
33
	public $default_color_scheme =  'light';
34
35
	/** Methods ***************************************************************/
36
37
	public static function init() {
38
		static $instance = false;
39
40
		if ( !$instance ) {
41
			$instance = new Jetpack_Comments;
42
		}
43
44
		return $instance;
45
	}
46
47
	/**
48
	 * Main constructor for Comments
49
	 *
50
	 * @since JetpackComments (1.4)
51
	 */
52
	public function __construct() {
53
		parent::__construct();
54
55
		// Comments is loaded
56
57
		/**
58
		 * Fires after the Jetpack_Comments object has been instantiated
59
		 *
60
		 * @module comments
61
		 *
62
		 * @since 1.4.0
63
		 *
64
		 * @param array $jetpack_comments_loaded First element in array of type Jetpack_Comments
65
		 **/
66
		do_action_ref_array( 'jetpack_comments_loaded', array( $this ) );
67
		add_action( 'after_setup_theme', array( $this, 'set_default_color_theme_based_on_theme_settings' ), 100 );
68
	}
69
70
	public function set_default_color_theme_based_on_theme_settings() {
71
		if ( function_exists( 'twentyeleven_get_theme_options' ) ) {
72
			$theme_options = twentyeleven_get_theme_options();
73
			$theme_color_scheme = isset( $theme_options['color_scheme'] ) ? $theme_options['color_scheme'] : 'transparent';
74
		} else {
75
			$theme_color_scheme = get_theme_mod( 'color_scheme', 'transparent' );
76
		}
77
		// Default for $theme_color_scheme is 'transparent' just so it doesn't match 'light' or 'dark'
78
		// The default for Jetpack's color scheme is still defined above as 'light'
79
80
		if ( false !== stripos( $theme_color_scheme, 'light' ) ) {
81
			$this->default_color_scheme = 'light';
82
		} elseif ( false !== stripos( $theme_color_scheme, 'dark' ) ) {
83
			$this->default_color_scheme = 'dark';
84
		}
85
	}
86
87
	/** Private Methods *******************************************************/
88
89
	/**
90
	 * Set any global variables or class variables
91
	 * @since JetpackComments (1.4)
92
	 */
93
	protected function setup_globals() {
94
		parent::setup_globals();
95
96
		// Sources
97
		$this->id_sources = array(
98
			'guest',
99
			'jetpack',
100
			'wordpress',
101
			'twitter',
102
			'facebook'
103
		);
104
	}
105
106
	/**
107
	 * Setup actions for methods in this class
108
	 * @since JetpackComments (1.4)
109
	 */
110
	protected function setup_actions() {
111
		parent::setup_actions();
112
113
		// Selfishly remove everything from the existing comment form
114
		remove_all_actions( 'comment_form_before' );
115
		remove_all_actions( 'comment_form_after'  );
116
117
		// Selfishly add only our actions back to the comment form
118
		add_action( 'comment_form_before', array( $this, 'comment_form_before' ) );
119
		add_action( 'comment_form_after',  array( $this, 'comment_form_after'  ) );
120
121
		// Before a comment is posted
122
		add_action( 'pre_comment_on_post', array( $this, 'pre_comment_on_post' ), 1 );
123
124
		// After a comment is posted
125
		add_action( 'comment_post', array( $this, 'add_comment_meta' ) );
126
	}
127
128
	/**
129
	 * Setup filters for methods in this class
130
	 * @since 1.6.2
131
	 */
132
	protected function setup_filters() {
133
		parent::setup_filters();
134
135
		add_filter( 'comment_post_redirect', array( $this, 'capture_comment_post_redirect_to_reload_parent_frame' ), 100 );
136
		add_filter( 'get_avatar',            array( $this, 'get_avatar' ), 10, 4 );
137
	}
138
139
	/**
140
	 * Get the comment avatar from Gravatar, Twitter, or Facebook
141
	 *
142
	 * @since JetpackComments (1.4)
143
	 * @param string $avatar Current avatar URL
144
	 * @param string $comment Comment for the avatar
145
	 * @param int $size Size of the avatar
146
	 * @param string $default Not used
147
	 * @return string New avatar
148
	 */
149
	public function get_avatar( $avatar, $comment, $size, $default ) {
0 ignored issues
show
Unused Code introduced by
The parameter $default is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
150
		if ( ! isset( $comment->comment_post_ID ) || ! isset( $comment->comment_ID ) ) {
151
			// it's not a comment - bail
152
			return $avatar;
153
		}
154
155
		// Detect whether it's a Facebook or Twitter avatar
156
		$foreign_avatar = get_comment_meta( $comment->comment_ID, 'hc_avatar', true );
157
		$foreign_avatar_hostname = parse_url( $foreign_avatar, PHP_URL_HOST );
158
		if ( ! $foreign_avatar_hostname ||
0 ignored issues
show
Bug Best Practice introduced by
The expression $foreign_avatar_hostname of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
159
				! preg_match( '/\.?(graph\.facebook\.com|twimg\.com)$/', $foreign_avatar_hostname ) ) {
160
			return $avatar;
161
		}
162
163
		// Return the FB or Twitter avatar
164
		return preg_replace( '#src=([\'"])[^\'"]+\\1#', 'src=\\1' . esc_url( $this->photon_avatar( $foreign_avatar, $size ) ) . '\\1', $avatar );
165
	}
166
167
	/** Output Methods ********************************************************/
168
169
	/**
170
	 * Start capturing the core comment_form() output
171
	 * @since JetpackComments (1.4)
172
	 */
173
	public function comment_form_before() {
174
		/**
175
		 * Filters the setting that determines if Jetpagk comments should be enabled for
176
		 * the current post type.
177
		 *
178
		 * @module comments
179
		 *
180
		 * @since 3.8.1
181
		 *
182
		 * @param boolean $return Should comments be enabled?
183
		 */
184
		if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type(), true ) ) {
185
			return;
186
		}
187
188
		// Add some JS to the footer
189
		add_action( 'wp_footer', array( $this, 'watch_comment_parent' ), 100 );
190
191
		ob_start();
192
	}
193
194
	/**
195
	 * Noop the default comment form output, get some options, and output our
196
	 * tricked out totally radical comment form.
197
	 *
198
	 * @since JetpackComments (1.4)
199
	 */
200
	public function comment_form_after() {
201
		/** This filter is documented in modules/comments/comments.php */
202
		if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type(), true ) ) {
203
			return;
204
		}
205
206
		// Throw it all out and drop in our replacement
207
		ob_end_clean();
208
209
		// If users are required to be logged in, and they're not, then we don't need to do anything else
210
		if ( get_option( 'comment_registration' ) && !is_user_logged_in() ) {
211
			/**
212
			 * Changes the log in to comment prompt.
213
			 *
214
			 * @module comments
215
			 *
216
			 * @since 1.4.0
217
			 *
218
			 * @param string $var Default is "You must log in to post a comment."
219
			 */
220
			echo '<p class="must-log-in">' . sprintf( apply_filters( 'jetpack_must_log_in_to_comment', __( 'You must <a href="%s">log in</a> to post a comment.', 'jetpack' ) ), wp_login_url( get_permalink() . '#respond' ) ) . '</p>';
221
			return;
222
		}
223
224
		if ( in_array( 'subscriptions', Jetpack::get_active_modules() ) ) {
225
			$stb_enabled = get_option( 'stb_enabled', 1 );
226
			$stb_enabled = empty( $stb_enabled ) ? 0 : 1;
227
228
			$stc_enabled = get_option( 'stc_enabled', 1 );
229
			$stc_enabled = empty( $stc_enabled ) ? 0 : 1;
230
		} else {
231
			$stb_enabled = 0;
232
			$stc_enabled = 0;
233
		}
234
235
		$params  = array(
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 2 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
236
			'blogid'               => Jetpack_Options::get_option( 'id' ),
237
			'postid'               => get_the_ID(),
238
			'comment_registration' => ( get_option( 'comment_registration' ) ? '1' : '0' ), // Need to explicitly send a '1' or a '0' for these
239
			'require_name_email'   => ( get_option( 'require_name_email' )   ? '1' : '0' ),
240
			'stc_enabled'          => $stc_enabled,
241
			'stb_enabled'          => $stb_enabled,
242
			'show_avatars'         => ( get_option( 'show_avatars' )         ? '1' : '0' ),
243
			'avatar_default'       => get_option( 'avatar_default' ),
244
			'greeting'             => get_option( 'highlander_comment_form_prompt', __( 'Leave a Reply', 'jetpack' ) ),
245
			/**
246
			 * Changes the comment form prompt.
247
			 *
248
			 * @module comments
249
			 *
250
			 * @since 2.3.0
251
			 *
252
			 * @param string $var Default is "Leave a Reply to %s."
253
			 */
254
			'greeting_reply'       => apply_filters( 'jetpack_comment_form_prompt_reply', __( 'Leave a Reply to %s' , 'jetpack' ) ),
255
			'color_scheme'         => get_option( 'jetpack_comment_form_color_scheme', $this->default_color_scheme ),
256
			'lang'                 => get_bloginfo( 'language' ),
257
			'jetpack_version'      => JETPACK__VERSION,
258
		);
259
260
		// Extra parameters for logged in user
261
		if ( is_user_logged_in() ) {
262
			$current_user           = wp_get_current_user();
263
			$params['hc_post_as']   = 'jetpack';
264
			$params['hc_userid']    = $current_user->ID;
265
			$params['hc_username']  = $current_user->display_name;
266
			$params['hc_userurl']   = $current_user->user_url;
267
			$params['hc_useremail'] = md5( strtolower( trim( $current_user->user_email ) ) );
268
			if ( current_user_can( 'unfiltered_html' ) )
269
				$params['_wp_unfiltered_html_comment'] = wp_create_nonce( 'unfiltered-html-comment_' . get_the_ID() );
270
		}
271
272
		$signature = Jetpack_Comments::sign_remote_comment_parameters( $params, Jetpack_Options::get_option( 'blog_token' ) );
273
		if ( is_wp_error( $signature ) ) {
274
			$signature = 'error';
275
		}
276
277
		$params['sig']    = $signature;
278
		$url_origin       = set_url_scheme( 'http://jetpack.wordpress.com' );
279
		$url              = "{$url_origin}/jetpack-comment/?" . http_build_query( $params );
280
		$url              = "{$url}#parent=" . urlencode( set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) );
281
		$this->signed_url = $url;
282
		$height           = $params['comment_registration'] || is_user_logged_in() ? '315' : '430'; // Iframe can be shorter if we're not allowing guest commenting
283
		$transparent      = ( $params['color_scheme'] == 'transparent' ) ? 'true' : 'false';
284
285
		if ( isset( $_GET['replytocom'] ) ) {
286
			$url .= '&replytocom=' . (int) $_GET['replytocom'];
287
		}
288
289
		// The actual iframe (loads comment form from Jetpack server)
290
		?>
291
292
		<div id="respond" class="comment-respond">
293
			<h3 id="reply-title" class="comment-reply-title"><?php comment_form_title( esc_html( $params['greeting'] ), esc_html( $params['greeting_reply'] ) ); ?> <small><?php cancel_comment_reply_link( esc_html__( 'Cancel reply' , 'jetpack') ); ?></small></h3>
294
			<div id="commentform" class="comment-form">
295
				<iframe src="<?php echo esc_url( $url ); ?>" allowtransparency="<?php echo $transparent; ?>" style="width:100%; height: <?php echo $height; ?>px;border:0px;" frameBorder="0" scrolling="no" name="jetpack_remote_comment" id="jetpack_remote_comment"></iframe>
296
			</div>
297
		</div>
298
299
		<?php // Below is required for comment reply JS to work ?>
300
301
		<input type="hidden" name="comment_parent" id="comment_parent" value="" />
302
303
		<?php
304
	}
305
306
	/**
307
	 * Add some JS to wp_footer to watch for hierarchical reply parent change
308
	 *
309
	 * @since JetpackComments (1.4)
310
	 */
311
	public function watch_comment_parent() {
312
		$url_origin = set_url_scheme( 'http://jetpack.wordpress.com' );
313
	?>
314
315
		<!--[if IE]>
316
		<script type="text/javascript">
317
		if ( 0 === window.location.hash.indexOf( '#comment-' ) ) {
318
			// window.location.reload() doesn't respect the Hash in IE
319
			window.location.hash = window.location.hash;
320
		}
321
		</script>
322
		<![endif]-->
323
		<script type="text/javascript">
324
			var comm_par_el = document.getElementById( 'comment_parent' ),
325
			    comm_par = (comm_par_el && comm_par_el.value) ? comm_par_el.value : '',
326
			    frame = document.getElementById( 'jetpack_remote_comment' ),
327
			    tellFrameNewParent;
328
329
			tellFrameNewParent = function() {
330
				if ( comm_par ) {
331
					frame.src = "<?php echo esc_url_raw( $this->signed_url ); ?>" + '&replytocom=' + parseInt( comm_par, 10 ).toString();
332
				} else {
333
					frame.src = "<?php echo esc_url_raw( $this->signed_url ); ?>";
334
				}
335
			};
336
337
	<?php if ( get_option( 'thread_comments' ) && get_option( 'thread_comments_depth' ) ) : ?>
338
339
			if ( 'undefined' !== typeof addComment ) {
340
				addComment._Jetpack_moveForm = addComment.moveForm;
341
342
				addComment.moveForm = function( commId, parentId, respondId, postId ) {
343
					var returnValue = addComment._Jetpack_moveForm( commId, parentId, respondId, postId ), cancelClick, cancel;
344
345
					if ( false === returnValue ) {
346
						cancel = document.getElementById( 'cancel-comment-reply-link' );
347
						cancelClick = cancel.onclick;
348
						cancel.onclick = function() {
349
							var cancelReturn = cancelClick.call( this );
350
							if ( false !== cancelReturn ) {
351
								return cancelReturn;
352
							}
353
354
							if ( !comm_par ) {
355
								return cancelReturn;
356
							}
357
358
							comm_par = 0;
359
360
							tellFrameNewParent();
361
362
							return cancelReturn;
363
						};
364
					}
365
366
					if ( comm_par == parentId ) {
367
						return returnValue;
368
					}
369
370
					comm_par = parentId;
371
372
					tellFrameNewParent();
373
374
					return returnValue;
375
				};
376
			}
377
378
	<?php endif; ?>
379
380
			if ( window.postMessage ) {
381
				if ( document.addEventListener ) {
382
					window.addEventListener( 'message', function( event ) {
383
						if ( <?php echo json_encode( esc_url_raw( $url_origin ) ); ?> !== event.origin ) {
384
							return;
385
						}
386
387
						jQuery( frame ).height( event.data );
388
					} );
389
				} else if ( document.attachEvent ) {
390
					window.attachEvent( 'message', function( event ) {
391
						if ( <?php echo json_encode( esc_url_raw( $url_origin ) ); ?> !== event.origin ) {
392
							return;
393
						}
394
395
						jQuery( frame ).height( event.data );
396
					} );
397
				}
398
			}
399
		</script>
400
401
	<?php
402
	}
403
404
	/**
405
	 * Verify the hash included in remote comments.
406
	 *
407
	 * @since JetpackComments (1.4)
408
	 * @param type $comment Not used
409
	 */
410
	public function pre_comment_on_post( $comment ) {
0 ignored issues
show
Unused Code introduced by
The parameter $comment is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
411
		$post_array = stripslashes_deep( $_POST );
412
413
		// Bail if missing the Jetpack token
414
		if ( ! isset( $post_array['sig'] ) ) {
415
			unset( $_POST['hc_post_as'] );
416
			return;
417
		}
418
419
		if ( FALSE !== strpos( $post_array['hc_avatar'], '.gravatar.com' ) )
420
			$post_array['hc_avatar'] = htmlentities( $post_array['hc_avatar'] );
421
422
		$check = Jetpack_Comments::sign_remote_comment_parameters( $post_array, Jetpack_Options::get_option( 'blog_token' ) );
423
		if ( is_wp_error( $check ) ) {
424
			wp_die( $check );
425
		}
426
427
		// Bail if token is expired or not valid
428
		if ( $check !== $post_array['sig'] )
429
			wp_die( __( 'Invalid security token.', 'jetpack' ) );
430
431
		/** This filter is documented in modules/comments/comments.php */
432
		if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type( $post_array['comment_post_ID'] ), true ) ) {
433
			// In case the comment POST is legit, but the comments are
434
			// now disabled, we don't allow the comment
435
436
			wp_die( __( 'Comments are not allowed.', 'jetpack' ) );
437
		}
438
	}
439
440
	/** Capabilities **********************************************************/
441
442
	/**
443
	 * Add some additional comment meta after comment is saved about what
444
	 * service the comment is from, the avatar, user_id, etc...
445
	 *
446
	 * @since JetpackComments (1.4)
447
	 * @param type $comment_id
448
	 */
449
	public function add_comment_meta( $comment_id ) {
450
		$comment_meta = array();
451
452
		switch( $this->is_highlander_comment_post() ) {
453 View Code Duplication
			case 'facebook' :
454
				$comment_meta['hc_post_as']         = 'facebook';
455
				$comment_meta['hc_avatar']          = stripslashes( $_POST['hc_avatar'] );
456
				$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
457
				break;
458
459 View Code Duplication
			case 'twitter' :
460
				$comment_meta['hc_post_as']         = 'twitter';
461
				$comment_meta['hc_avatar']          = stripslashes( $_POST['hc_avatar'] );
462
				$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
463
				break;
464
465
			case 'wordpress' :
466
				$comment_meta['hc_post_as']         = 'wordpress';
467
				$comment_meta['hc_avatar']          = stripslashes( $_POST['hc_avatar'] );
468
				$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
469
				$comment_meta['hc_wpcom_id_sig']    = stripslashes( $_POST['hc_wpcom_id_sig'] ); //since 1.9
470
				break;
471
472 View Code Duplication
			case 'jetpack' :
473
				$comment_meta['hc_post_as']         = 'jetpack';
474
				$comment_meta['hc_avatar']          = stripslashes( $_POST['hc_avatar'] );
475
				$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
476
				break;
477
478
		}
479
480
		// Bail if no extra comment meta
481
		if ( empty( $comment_meta ) )
482
			return;
483
484
		// Loop through extra meta and add values
485
		foreach ( $comment_meta as $key => $value )
486
			add_comment_meta( $comment_id, $key, $value, true );
487
	}
488
	function capture_comment_post_redirect_to_reload_parent_frame( $url ) {
489
		if ( !isset( $_GET['for'] ) || 'jetpack' != $_GET['for'] ) {
490
			return $url;
491
		}
492
?>
493
<!DOCTYPE html>
494
<html <?php language_attributes(); ?>>
495
<!--<![endif]-->
496
<head>
497
<meta charset="<?php bloginfo( 'charset' ); ?>" />
498
<title><?php printf( __( 'Submitting Comment%s', 'jetpack' ), '&hellip;' ); ?></title>
499
<style type="text/css">
500
body {
501
	display: table;
502
	width: 100%;
503
	height: 60%;
504
	position: absolute;
505
	top: 0;
506
	left: 0;
507
	overflow: hidden;
508
	color: #333;
509
}
510
511
h1 {
512
	text-align: center;
513
	margin: 0;
514
	padding: 0;
515
	display: table-cell;
516
	vertical-align: middle;
517
	font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", sans-serif;
518
	font-weight: normal;
519
}
520
521
.hidden {
522
	opacity: 0;
523
}
524
525
h1 span {
526
	-moz-transition-property: opacity;
527
	-moz-transition-duration: 1s;
528
	-moz-transition-timing-function: ease-in-out;
529
530
	-webkit-transition-property: opacity;
531
	-webkit-transition-duration: 1s;
532
	-webbit-transition-timing-function: ease-in-out;
533
534
	-o-transition-property: opacity;
535
	-o-transition-duration: 1s;
536
	-o-transition-timing-function: ease-in-out;
537
538
	-ms-transition-property: opacity;
539
	-ms-transition-duration: 1s;
540
	-ms-transition-timing-function: ease-in-out;
541
542
	transition-property: opacity;
543
	transition-duration: 1s;
544
	transition-timing-function: ease-in-out;
545
}
546
</style>
547
</head>
548
<body>
549
	<h1><?php printf( __( 'Submitting Comment%s', 'jetpack' ), '<span id="ellipsis" class="hidden">&hellip;</span>' ); ?></h1>
550
<script type="text/javascript">
551
try {
552
	window.parent.location = <?php echo json_encode( $url ); ?>;
553
	window.parent.location.reload( true );
554
} catch ( e ) {
555
	window.location = <?php echo json_encode( $url ); ?>;
556
	window.location.reload( true );
557
}
558
ellipsis = document.getElementById( 'ellipsis' );
559
function toggleEllipsis() {
560
	ellipsis.className = ellipsis.className ? '' : 'hidden';
561
}
562
setInterval( toggleEllipsis, 1200 );
563
</script>
564
</body>
565
</html>
566
<?php
567
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method capture_comment_post_red...o_reload_parent_frame() 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...
568
	}
569
}
570
571
Jetpack_Comments::init();
572