Completed
Push — merge/contact-form-wpcom ( e34716 )
by
unknown
08:47
created

admin.php ➔ grunion_menu_alter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
function grunion_menu_alter() {
4
	wp_enqueue_style( 'grunion-menu-alter', plugins_url( 'css/menu-alter.css', __FILE__ ) );
5
	wp_style_add_data( 'grunion-menu-alter', 'rtl', 'replace' );
6
}
7
8
add_action( 'admin_enqueue_scripts', 'grunion_menu_alter' );
9
10
/**
11
 * Add a contact form button to the post composition screen
12
 */
13
add_action( 'media_buttons', 'grunion_media_button', 999 );
14
function grunion_media_button( ) {
15
	global $post_ID, $temp_ID, $pagenow;
16
17
	if ( 'press-this.php' === $pagenow ) {
18
		return;
19
	}
20
21
	$iframe_post_id = (int) (0 == $post_ID ? $temp_ID : $post_ID);
22
	$title = __( 'Add Contact Form', 'jetpack' );
23
	$plugin_url = esc_url( GRUNION_PLUGIN_URL );
0 ignored issues
show
Unused Code introduced by
$plugin_url is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
24
	$site_url = esc_url( admin_url( "/admin-ajax.php?post_id={$iframe_post_id}&action=grunion_form_builder&TB_iframe=true&width=768" ) );
25
	?>
26
27
	<a id="insert-jetpack-contact-form" class="button thickbox" title="<?php echo esc_attr( $title ); ?>" data-editor="content" href="<?php echo $site_url ?>&id=add_form">
28
		<span class="jetpack-contact-form-icon"></span> <?php echo esc_html( $title ); ?>
29
	</a>
30
31
	<?php
32
}
33
34
add_action( 'wp_ajax_grunion_form_builder', 'grunion_display_form_view' );
35
36
function grunion_display_form_view() {
37
	if ( current_user_can( 'edit_posts' ) ) {
38
		require_once GRUNION_PLUGIN_DIR . 'grunion-form-view.php';
39
	}
40
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_display_form_view() 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...
41
}
42
43
// feedback specific css items
44
add_action( 'admin_print_styles', 'grunion_admin_css' );
45
function grunion_admin_css() {
46
	global $current_screen;
47
	if ( is_null( $current_screen ) ) {
48
		return;
49
	}
50
	if ( 'edit-feedback' !== $current_screen->id ) {
51
		return;
52
	}
53
54
	wp_enqueue_script( 'wp-lists' );
55
?>
56
57
<style type='text/css'>
58
.add-new-h2, .view-switch, body.no-js .tablenav select[name^=action], body.no-js #doaction, body.no-js #doaction2 {
59
	display: none
60
}
61
62
.column-feedback_from img {
63
	float:left;
64
	margin-right:10px;
65
	margin-top:3px;
66
}
67
68
.widefat .column-feedback_from {
69
	width: 17%;
70
}
71
.widefat .column-feedback_date {
72
	width: 17%;
73
}
74
75
.spam a {
76
	color: #BC0B0B;
77
}
78
79
.untrash a {
80
	color: #D98500;
81
}
82
83
.unspam a {
84
color: #D98500;
85
}
86
87
</style>
88
89
<?php
90
}
91
92
/**
93
 * Hack a 'Bulk Spam' option for bulk edit in other than spam view
94
 * Hack a 'Bulk Delete' option for bulk edit in spam view
95
 *
96
 * There isn't a better way to do this until
97
 * http://core.trac.wordpress.org/changeset/17297 is resolved
98
 */
99
add_action( 'admin_head', 'grunion_add_bulk_edit_option' );
100
function grunion_add_bulk_edit_option() {
101
102
	$screen = get_current_screen();
103
104
	if ( is_null( $screen ) ) {
105
		return;
106
	}
107
108
	if ( 'edit-feedback' != $screen->id ) {
109
		return;
110
	}
111
112
	// When viewing spam we want to be able to be able to bulk delete
113
	// When viewing anything we want to be able to bulk move to spam
114
	if ( isset( $_GET['post_status'] ) && 'spam' == $_GET['post_status'] ) {
115
		// Create Delete Permanently bulk item
116
		$option_val = 'delete';
117
		$option_txt = __( 'Delete Permanently', 'jetpack' );
118
		$pseudo_selector = 'last-child';
119
120
	} else {
121
		// Create Mark Spam bulk item
122
		$option_val = 'spam';
123
		$option_txt = __( 'Mark as Spam', 'jetpack' );
124
		$pseudo_selector = 'first-child';
125
	}
126
127
	?>
128
		<script type="text/javascript">
129
			jQuery(document).ready(function($) {
130
				$('#posts-filter .actions select').filter('[name=action], [name=action2]').find('option:<?php echo $pseudo_selector; ?>').after('<option value="<?php echo $option_val; ?>"><?php echo esc_attr( $option_txt ); ?></option>' );
131
			})
132
		</script>
133
	<?php
134
}
135
136
/**
137
 * Hack an 'Empty Spam' button to spam view
138
 *
139
 * Leverages core's delete_all functionality
140
 */
141
add_action( 'admin_head', 'grunion_add_empty_spam_button' );
142
function grunion_add_empty_spam_button() {
143
	$screen = get_current_screen();
144
145
	if ( is_null( $screen ) ) {
146
		return;
147
	}
148
149
	// Only add to feedback, only to spam view
150 View Code Duplication
	if ( 'edit-feedback' != $screen->id
151
	|| empty( $_GET['post_status'] )
152
	|| 'spam' !== $_GET['post_status'] ) {
153
		return;
154
	}
155
156
	// Get HTML for the button
157
	$button_html = wp_nonce_field( 'bulk-destroy', '_destroy_nonce', true, false );
158
	$button_html .= get_submit_button( __( 'Empty Spam', 'jetpack' ), 'apply', 'delete_all', false );
159
160
	// Add the button next to the filter button via js
161
	?>
162
		<script type="text/javascript">
163
			jQuery(document).ready(function($) {
164
				$('#posts-filter #post-query-submit').after('<?php echo $button_html; ?>' );
165
			})
166
		</script>
167
	<?php
168
}
169
170
/**
171
 * Handle a bulk spam report
172
 */
173
add_action( 'admin_init', 'grunion_handle_bulk_spam' );
174
function grunion_handle_bulk_spam() {
175
	global $pagenow;
176
177
	if ( 'edit.php' != $pagenow
178
	|| ( empty( $_REQUEST['post_type'] ) || 'feedback' != $_REQUEST['post_type'] ) )
179
		return;
180
181
	// Slip in a success message
182
	if ( ! empty( $_REQUEST['message'] ) && 'marked-spam' == $_REQUEST['message'] )
183
		add_action( 'admin_notices', 'grunion_message_bulk_spam' );
184
185
	if ( ( empty( $_REQUEST['action'] ) || 'spam' != $_REQUEST['action'] ) && ( empty( $_REQUEST['action2'] ) || 'spam' != $_REQUEST['action2'] ) ) {
186
		return;
187
	}
188
189
	check_admin_referer('bulk-posts');
190
191
	if ( empty( $_REQUEST['post'] ) ) {
192
		wp_safe_redirect( wp_get_referer() );
193
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_handle_bulk_spam() 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...
194
	}
195
196
	$post_ids = array_map( 'intval', $_REQUEST['post'] );
197
198
	foreach( $post_ids as $post_id ) {
199
		if ( ! current_user_can( "edit_page", $post_id ) ) {
200
			wp_die( __( 'You are not allowed to manage this item.', 'jetpack' ) );
201
		}
202
203
		$post = array(
204
				'ID'           => $post_id,
205
				'post_status'  => 'spam',
206
			);
207
		$akismet_values = get_post_meta( $post_id, '_feedback_akismet_values', true );
208
		wp_update_post( $post );
209
210
		/**
211
		 * Fires after a comment has been marked by Akismet.
212
		 *
213
		 * Typically this means the comment is spam.
214
		 *
215
		 * @module contact-form
216
		 *
217
		 * @since 2.2.0
218
		 *
219
		 * @param string $comment_status Usually is 'spam', otherwise 'ham'.
220
		 * @param array $akismet_values From '_feedback_akismet_values' in comment meta
221
		 */
222
		do_action( 'contact_form_akismet', 'spam', $akismet_values );
223
	}
224
225
	$redirect_url = add_query_arg( 'message', 'marked-spam', wp_get_referer() );
226
	wp_safe_redirect( $redirect_url );
227
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_handle_bulk_spam() 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...
228
}
229
230
function grunion_message_bulk_spam() {
231
	echo '<div class="updated"><p>' . __( 'Feedback(s) marked as spam', 'jetpack' ) . '</p></div>';
232
}
233
234
// remove admin UI parts that we don't support in feedback management
235
add_action( 'admin_menu', 'grunion_admin_menu' );
236
function grunion_admin_menu() {
237
	global $menu, $submenu;
238
	unset( $submenu['edit.php?post_type=feedback'] );
239
}
240
241
add_filter( 'bulk_actions-edit-feedback', 'grunion_admin_bulk_actions' );
242
function grunion_admin_bulk_actions( $actions ) {
243
	global $current_screen;
244
	if ( 'edit-feedback' != $current_screen->id )
245
		return $actions;
246
247
	unset( $actions['edit'] );
248
	return $actions;
249
}
250
251
add_filter( 'views_edit-feedback', 'grunion_admin_view_tabs' );
252
function grunion_admin_view_tabs( $views ) {
253
	global $current_screen;
254
	if ( 'edit-feedback' != $current_screen->id )
255
		return $actions;
0 ignored issues
show
Bug introduced by
The variable $actions does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
256
257
	unset( $views['publish'] );
258
259
	preg_match( '|post_type=feedback\'( class="current")?\>(.*)\<span class=|', $views['all'], $match );
260
	if ( !empty( $match[2] ) )
261
		$views['all'] = str_replace( $match[2], __( 'Messages', 'jetpack' ) . ' ', $views['all'] );
262
263
	return $views;
264
}
265
266
add_filter( 'manage_feedback_posts_columns', 'grunion_post_type_columns_filter' );
267
function grunion_post_type_columns_filter( $cols ) {
268
	$cols = array(
269
		'cb'	=> '<input type="checkbox" />',
270
		'feedback_from'		=> __( 'From', 'jetpack' ),
271
		'feedback_message'		=> __( 'Message', 'jetpack' ),
272
		'feedback_date'			=> __( 'Date', 'jetpack' )
273
	);
274
275
	return $cols;
276
}
277
278
add_action( 'manage_posts_custom_column', 'grunion_manage_post_columns', 10, 2 );
279
function grunion_manage_post_columns( $col, $post_id ) {
280
	global $post;
281
282
	/**
283
	 * Only call parse_fields_from_content if we're dealing with a Grunion custom column.
284
	 */
285
	if ( ! in_array( $col, array( 'feedback_date', 'feedback_from', 'feedback_message' ) ) ) {
286
		return;
287
	}
288
289
	$content_fields = Grunion_Contact_Form_Plugin::parse_fields_from_content( $post_id );
290
291
	switch ( $col ) {
292
		case 'feedback_from':
293
			$author_name  = isset( $content_fields['_feedback_author'] ) ? $content_fields['_feedback_author'] : '';
294
			$author_email = isset( $content_fields['_feedback_author_email'] ) ? $content_fields['_feedback_author_email'] : '';
295
			$author_url   = isset( $content_fields['_feedback_author_url'] ) ? $content_fields['_feedback_author_url'] : '';
296
			$author_ip    = isset( $content_fields['_feedback_ip'] ) ? $content_fields['_feedback_ip'] : '';
297
			$form_url     = isset( $post->post_parent ) ? get_permalink( $post->post_parent ) : null;
298
299
			$author_name_line = '';
300
			if ( !empty( $author_name ) ) {
301
				if ( !empty( $author_email ) )
302
					$author_name_line = get_avatar( $author_email, 32 );
303
304
				$author_name_line .= sprintf( "<strong>%s</strong><br />", esc_html( $author_name ) );
305
			}
306
307
			$author_email_line = '';
308
			if ( !empty( $author_email ) ) {
309
				$author_email_line = sprintf( "<a href='%1\$s' target='_blank'>%2\$s</a><br />", esc_url( "mailto:" . $author_email ) , esc_html( $author_email ) );
310
			}
311
312
			$author_url_line = '';
313
			if ( !empty( $author_url ) ) {
314
				$author_url_line = sprintf( "<a href='%1\$s'>%1\$s</a><br />", esc_url( $author_url ) );
315
			}
316
317
			echo $author_name_line;
318
			echo $author_email_line;
319
			echo $author_url_line;
320
			echo "<a href='edit.php?post_type=feedback&s=" . urlencode( $author_ip );
321
			echo "&mode=detail'>" . esc_html( $author_ip ) . "</a><br />";
322
			if ( $form_url ) {
323
				echo '<a href="' . esc_url( $form_url ) . '">' . esc_html( $form_url ) . '</a>';
324
			}
325
			break;
326
327
		case 'feedback_message':
328
			$post_type_object = get_post_type_object( $post->post_type );
329
			if ( isset( $content_fields['_feedback_subject'] ) ) {
330
				echo '<strong>';
331
				echo esc_html( $content_fields['_feedback_subject'] );
332
				echo '</strong>';
333
				echo '<br />';
334
			}
335
			echo sanitize_text_field( get_the_content( '' ) );
336
			echo '<br />';
337
338
			$extra_fields = get_post_meta( $post_id, '_feedback_extra_fields', TRUE );
339
			if ( !empty( $extra_fields ) ) {
340
				echo '<br /><hr />';
341
				echo '<table cellspacing="0" cellpadding="0" style="">' . "\n";
342
				foreach ( (array) $extra_fields as $k => $v ) {
343
					// Remove prefix from exta fields
344
					echo "<tr><td align='right'><b>". esc_html( preg_replace( '#^\d+_#', '', $k ) ) ."</b></td><td>". sanitize_text_field( $v ) ."</td></tr>\n";
345
				}
346
				echo '</table>';
347
			}
348
349
			echo '<div class="row-actions">';
350
			if ( $post->post_status == 'trash' ) {
351
				echo '<span class="untrash" id="feedback-restore-' . $post_id;
352
				echo '"><a title="';
353
				echo esc_attr__( 'Restore this item from the Trash', 'jetpack' );
354
				echo '" href="' . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-' . $post->post_type . '_' . $post->ID );
355
				echo '">' . __( 'Restore', 'jetpack' ) . '</a></span> | ';
356
357
				echo "<span class='delete'> <a class='submitdelete' title='";
358
				echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
359
				echo "' href='" . get_delete_post_link( $post->ID, '', true );
360
				echo "'>" . __( 'Delete Permanently', 'jetpack' ) . "</a></span>";
361
?>
362
363
<script>
364
jQuery(document).ready(function($) {
365
$('#feedback-restore-<?php echo $post_id; ?>').click(function(e) {
366
	e.preventDefault();
367
	$.post(ajaxurl, {
368
			action: 'grunion_ajax_spam',
369
			post_id: '<?php echo $post_id; ?>',
370
			make_it: 'publish',
371
			sub_menu: jQuery('.subsubsub .current').attr('href'),
372
			_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
373
		},
374
		function(r) {
375
			$('#post-<?php echo $post_id; ?>')
376
				.css({backgroundColor: '#59C859'})
377
				.fadeOut(350, function() {
378
					$(this).remove();
379
					$('.subsubsub').html(r);
380
				});
381
		}
382
	);
383
});
384
});
385
</script>
386
387
<?php
388
			} elseif ( $post->post_status == 'publish' ) {
389
				echo '<span class="spam" id="feedback-spam-' . $post_id;
390
				echo '"><a title="';
391
				echo __( 'Mark this message as spam', 'jetpack' );
392
				echo '" href="' . wp_nonce_url( admin_url( 'admin-ajax.php?post_id=' . $post_id . '&amp;action=spam' ), 'spam-feedback_' . $post_id );
393
				echo '">Spam</a></span>';
394
				echo ' | ';
395
396
				echo '<span class="delete" id="feedback-trash-' . $post_id;
397
				echo '">';
398
				echo '<a class="submitdelete" title="' . esc_attr__( 'Trash', 'jetpack' );
399
				echo '" href="' . get_delete_post_link( $post_id );
400
				echo '">' . __( 'Trash', 'jetpack' ) . '</a></span>';
401
402
?>
403
404
<script>
405
jQuery(document).ready( function($) {
406
	$('#feedback-spam-<?php echo $post_id; ?>').click( function(e) {
407
		e.preventDefault();
408
		$.post( ajaxurl, {
409
				action: 'grunion_ajax_spam',
410
				post_id: '<?php echo $post_id; ?>',
411
				make_it: 'spam',
412
				sub_menu: jQuery('.subsubsub .current').attr('href'),
413
				_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
414
			},
415
			function( r ) {
416
				$('#post-<?php echo $post_id; ?>')
417
					.css( {backgroundColor:'#FF7979'} )
418
					.fadeOut(350, function() {
419
						$(this).remove();
420
						$('.subsubsub').html(r);
421
				});
422
		});
423
	});
424
425
	$('#feedback-trash-<?php echo $post_id; ?>').click(function(e) {
426
		e.preventDefault();
427
		$.post(ajaxurl, {
428
				action: 'grunion_ajax_spam',
429
				post_id: '<?php echo $post_id; ?>',
430
				make_it: 'trash',
431
				sub_menu: jQuery('.subsubsub .current').attr('href'),
432
				_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
433
			},
434
			function(r) {
435
				$('#post-<?php echo $post_id; ?>')
436
					.css({backgroundColor: '#FF7979'})
437
					.fadeOut(350, function() {
438
						$(this).remove();
439
						$('.subsubsub').html(r);
440
					});
441
			}
442
		);
443
	});
444
});
445
</script>
446
447
<?php
448
			} elseif ( $post->post_status == 'spam' ) {
449
				echo '<span class="unspam unapprove" id="feedback-ham-' . $post_id;
450
				echo '"><a title="';
451
				echo __( 'Mark this message as NOT spam', 'jetpack' );
452
				echo '" href="">Not Spam</a></span>';
453
				echo ' | ';
454
455
				echo "<span class='delete' id='feedback-trash-" . $post_id;
456
				echo "'> <a class='submitdelete' title='";
457
				echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
458
				echo "' href='" . get_delete_post_link( $post->ID, '', true );
459
				echo "'>" . __( 'Delete Permanently', 'jetpack' ) . "</a></span>";
460
?>
461
462
<script>
463
jQuery(document).ready( function($) {
464
	$('#feedback-ham-<?php echo $post_id; ?>').click( function(e) {
465
		e.preventDefault();
466
		$.post( ajaxurl, {
467
				action: 'grunion_ajax_spam',
468
				post_id: '<?php echo $post_id; ?>',
469
				make_it: 'ham',
470
				sub_menu: jQuery('.subsubsub .current').attr('href'),
471
				_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
472
			},
473
			function( r ) {
474
				$('#post-<?php echo $post_id; ?>')
475
					.css( {backgroundColor:'#59C859'} )
476
					.fadeOut(350, function() {
477
						$(this).remove();
478
						$('.subsubsub').html(r);
479
				});
480
			});
481
	});
482
});
483
</script>
484
485
<?php
486
			}
487
			break;
488
489
		case 'feedback_date':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
490
491
			$date_time_format = _x( '%1$s \a\t %2$s', '{$date_format} \a\t {$time_format}', 'jetpack' );
492
			$date_time_format = sprintf( $date_time_format, get_option( 'date_format' ), get_option( 'time_format' ) );
493
			$time = date_i18n( $date_time_format, get_the_time( 'U' ) );
494
495
			echo $time;
496
			break;
497
	}
498
}
499
500
function grunion_esc_attr( $attr ) {
501
	$out = esc_attr( $attr );
502
	// we also have to entity-encode square brackets so they don't interfere with the shortcode parser
503
	// FIXME: do this better - just stripping out square brackets for now since they mysteriously keep reappearing
504
	$out = str_replace( '[', '', $out );
505
	$out = str_replace( ']', '', $out );
506
	return $out;
507
}
508
509
function grunion_sort_objects( $a, $b ) {
510
	if ( isset($a['order']) && isset($b['order']) )
511
		return $a['order'] - $b['order'];
512
	return 0;
513
}
514
515
// take an array of field types from the form builder, and construct a shortcode form
516
// returns both the shortcode form, and HTML markup representing a preview of the form
517
function grunion_ajax_shortcode() {
518
	check_ajax_referer( 'grunion_shortcode' );
519
520
	if ( ! current_user_can( 'edit_posts' ) ) {
521
		die( '-1' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_ajax_shortcode() 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...
522
	}
523
524
	$attributes = array();
525
526
	foreach ( array( 'subject', 'to' ) as $attribute ) {
527
		if ( isset( $_POST[$attribute] ) && strlen( $_POST[$attribute] ) ) {
528
			$attributes[$attribute] = stripslashes( $_POST[$attribute] );
529
		}
530
	}
531
532
	if ( is_array( $_POST['fields'] ) ) {
533
		$fields = stripslashes_deep( $_POST['fields'] );
534
		usort( $fields, 'grunion_sort_objects' );
535
536
		$field_shortcodes = array();
537
538
		foreach ( $fields as $field ) {
539
			$field_attributes = array();
540
541
			if ( isset( $field['required'] ) && 'true' === $field['required'] ) {
542
				$field_attributes['required'] = 'true';
543
			}
544
545
			foreach ( array( 'options', 'label', 'type' ) as $attribute ) {
546
				if ( isset( $field[$attribute] ) ) {
547
					$field_attributes[$attribute] = $field[$attribute];
548
				}
549
			}
550
551
			$field_shortcodes[] = new Grunion_Contact_Form_Field( $field_attributes );
552
		}
553
	}
554
555
	$grunion = new Grunion_Contact_Form( $attributes, $field_shortcodes );
0 ignored issues
show
Bug introduced by
The variable $field_shortcodes does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
556
557
	die( "\n$grunion\n" );
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_ajax_shortcode() 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...
558
}
559
560
// takes a post_id, extracts the contact-form shortcode from that post (if there is one), parses it,
561
// and constructs a json object representing its contents and attributes
562
function grunion_ajax_shortcode_to_json() {
563
	global $post, $grunion_form;
564
565
	check_ajax_referer( 'grunion_shortcode_to_json' );
566
567
	if ( ! empty( $_POST['post_id'] ) && ! current_user_can( 'edit_post', $_POST['post_id'] ) ) {
568
		die( '-1' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_ajax_shortcode_to_json() 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...
569
	} elseif ( ! current_user_can( 'edit_posts' ) ) {
570
		die( '-1' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_ajax_shortcode_to_json() 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...
571
	}
572
573
	if ( !isset( $_POST['content'] ) || !is_numeric( $_POST['post_id'] ) ) {
574
		die( '-1' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_ajax_shortcode_to_json() 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...
575
	}
576
577
	$content = stripslashes( $_POST['content'] );
578
579
	// doesn't look like a post with a [contact-form] already.
580
	if ( false === has_shortcode( $content, 'contact-form' ) ) {
581
		die( '' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_ajax_shortcode_to_json() 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...
582
	}
583
584
	$post = get_post( $_POST['post_id'] );
585
586
	do_shortcode( $content );
587
588
	$grunion = Grunion_Contact_Form::$last;
0 ignored issues
show
Bug introduced by
The property last cannot be accessed from this context as it is declared private in class Grunion_Contact_Form.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
589
590
	$out = array(
591
		'to'      => '',
592
		'subject' => '',
593
		'fields'  => array(),
594
	);
595
596
	foreach ( $grunion->fields as $field ) {
597
		$out['fields'][$field->get_attribute( 'id' )] = $field->attributes;
598
	}
599
600
	$to = $grunion->get_attribute( 'to' );
0 ignored issues
show
Unused Code introduced by
$to is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
601
	$subject = $grunion->get_attribute( 'subject' );
0 ignored issues
show
Unused Code introduced by
$subject is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
602
	foreach ( array( 'to', 'subject' ) as $attribute ) {
603
		$value = $grunion->get_attribute( $attribute );
604
		if ( isset( $grunion->defaults[$attribute] ) && $value == $grunion->defaults[$attribute] ) {
605
			$value = '';
606
		}
607
		$out[$attribute] = $value;
608
	}
609
610
	die( json_encode( $out ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_ajax_shortcode_to_json() 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...
611
}
612
613
614
add_action( 'wp_ajax_grunion_shortcode', 'grunion_ajax_shortcode' );
615
add_action( 'wp_ajax_grunion_shortcode_to_json', 'grunion_ajax_shortcode_to_json' );
616
617
618
// process row-action spam/not spam clicks
619
add_action( 'wp_ajax_grunion_ajax_spam', 'grunion_ajax_spam' );
620
function grunion_ajax_spam() {
621
	global $wpdb;
622
623
	if ( empty( $_POST['make_it'] ) ) {
624
		return;
625
	}
626
627
	$post_id = (int) $_POST['post_id'];
628
	check_ajax_referer( 'grunion-post-status-' . $post_id );
629
	if ( ! current_user_can( "edit_page", $post_id ) ) {
630
		wp_die( __( 'You are not allowed to manage this item.', 'jetpack' ) );
631
	}
632
633
	require_once dirname( __FILE__ ) . '/grunion-contact-form.php';
634
635
	$current_menu = '';
636
	if ( isset( $_POST['sub_menu'] ) && preg_match( '|post_type=feedback|', $_POST['sub_menu'] ) ) {
637
		if ( preg_match( '|post_status=spam|', $_POST['sub_menu'] ) ) {
638
			$current_menu = 'spam';
639
		}
640
		elseif ( preg_match( '|post_status=trash|', $_POST['sub_menu'] ) ) {
641
			$current_menu = 'trash';
642
		}
643
		else {
644
			$current_menu = 'messages';
645
		}
646
647
	}
648
649
	$post = get_post( $post_id );
650
	$post_type_object = get_post_type_object( $post->post_type );
651
	$akismet_values   = get_post_meta( $post_id, '_feedback_akismet_values', TRUE );
652
	if ( $_POST['make_it'] == 'spam' ) {
653
		$post->post_status = 'spam';
654
		$status = wp_insert_post( $post );
0 ignored issues
show
Unused Code introduced by
$status is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
655
		wp_transition_post_status( 'spam', 'publish', $post );
656
657
		/** This action is already documented in modules/contact-form/admin.php */
658
		do_action( 'contact_form_akismet', 'spam', $akismet_values );
659
	} elseif ( $_POST['make_it'] == 'ham' ) {
660
		$post->post_status = 'publish';
661
		$status = wp_insert_post( $post );
0 ignored issues
show
Unused Code introduced by
$status is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
662
		wp_transition_post_status( 'publish', 'spam', $post );
663
664
		/** This action is already documented in modules/contact-form/admin.php */
665
		do_action( 'contact_form_akismet', 'ham', $akismet_values );
666
667
		$comment_author_email = $reply_to_addr = $message = $to = $headers = false;
0 ignored issues
show
Unused Code introduced by
$headers is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
668
		$blog_url = parse_url( site_url() );
669
670
		// resend the original email
671
		$email = get_post_meta( $post_id, '_feedback_email', TRUE );
672
		$content_fields = Grunion_Contact_Form_Plugin::parse_fields_from_content( $post_id );
673
674
		if ( ! empty( $email ) && !empty( $content_fields ) ) {
675
			if ( isset( $content_fields['_feedback_author_email'] ) ) {
676
				$comment_author_email = $content_fields['_feedback_author_email'];
677
			}
678
679
			if ( isset( $email['to'] ) ) {
680
				$to = $email['to'];
681
			}
682
683
			if ( isset( $email['message'] ) ) {
684
				$message = $email['message'];
685
			}
686
687
			if ( isset( $email['headers'] ) ) {
688
				$headers = $email['headers'];
689
			}
690
			else {
691
				$headers = 'From: "' . $content_fields['_feedback_author'] .'" <wordpress@' . $blog_url['host']  . ">\r\n";
692
693
				if ( ! empty( $comment_author_email ) ){
694
					$reply_to_addr = $comment_author_email;
695
				}
696
				elseif ( is_array( $to ) ) {
697
					$reply_to_addr = $to[0];
698
				}
699
700
				if ( $reply_to_addr ) {
701
					$headers .= 'Reply-To: "' . $content_fields['_feedback_author'] .'" <' . $reply_to_addr . ">\r\n";
702
				}
703
704
				$headers .= "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"";
705
			}
706
707
			/**
708
			 * Filters the subject of the email sent after a contact form submission.
709
			 *
710
			 * @module contact-form
711
			 *
712
			 * @since 3.0.0
713
			 *
714
			 * @param string $content_fields['_feedback_subject'] Feedback's subject line.
715
			 * @param array $content_fields['_feedback_all_fields'] Feedback's data from old fields.
716
			 */
717
			$subject = apply_filters( 'contact_form_subject', $content_fields['_feedback_subject'], $content_fields['_feedback_all_fields'] );
718
719
			Grunion_Contact_Form::wp_mail( $to, $subject, $message, $headers );
720
		}
721
	} elseif( $_POST['make_it'] == 'publish' ) {
722
		if ( ! current_user_can($post_type_object->cap->delete_post, $post_id) ) {
723
			wp_die( __( 'You are not allowed to move this item out of the Trash.', 'jetpack' ) );
724
		}
725
726
		if ( ! wp_untrash_post($post_id) ) {
727
			wp_die( __( 'Error in restoring from Trash.', 'jetpack' ) );
728
		}
729
730
	} elseif( $_POST['make_it'] == 'trash' ) {
731
		if ( ! current_user_can($post_type_object->cap->delete_post, $post_id) ) {
732
			wp_die( __( 'You are not allowed to move this item to the Trash.', 'jetpack' ) );
733
		}
734
735
		if ( ! wp_trash_post($post_id) ) {
736
			wp_die( __( 'Error in moving to Trash.', 'jetpack' ) );
737
		}
738
739
	}
740
741
	$sql = "
742
		SELECT post_status,
743
			COUNT( * ) AS post_count
744
		FROM `{$wpdb->posts}`
745
		WHERE post_type =  'feedback'
746
		GROUP BY post_status
747
	";
748
	$status_count = (array) $wpdb->get_results( $sql, ARRAY_A );
749
750
	$status = array();
751
	$status_html = '';
752
	foreach ( $status_count as $i => $row ) {
753
		$status[$row['post_status']] = $row['post_count'];
754
	}
755
756 View Code Duplication
	if ( isset( $status['publish'] ) ) {
757
		$status_html .= '<li><a href="edit.php?post_type=feedback"';
758
		if ( $current_menu == 'messages' ) {
759
			$status_html .= ' class="current"';
760
		}
761
762
		$status_html .= '>' . __( 'Messages', 'jetpack' ) . ' <span class="count">';
763
		$status_html .= '(' . number_format( $status['publish'] ) . ')';
764
		$status_html .= '</span></a> |</li>';
765
	}
766
767
	if ( isset( $status['trash'] ) ) {
768
		$status_html .= '<li><a href="edit.php?post_status=trash&amp;post_type=feedback"';
769
		if ( $current_menu == 'trash' )
770
			$status_html .= ' class="current"';
771
772
		$status_html .= '>' . __( 'Trash', 'jetpack' ) . ' <span class="count">';
773
		$status_html .= '(' . number_format( $status['trash'] ) . ')';
774
		$status_html .= '</span></a>';
775
		if ( isset( $status['spam'] ) )
776
			$status_html .= ' |';
777
		$status_html .= '</li>';
778
	}
779
780 View Code Duplication
	if ( isset( $status['spam'] ) ) {
781
		$status_html .= '<li><a href="edit.php?post_status=spam&amp;post_type=feedback"';
782
		if ( $current_menu == 'spam' )
783
			$status_html .= ' class="current"';
784
785
		$status_html .= '>' . __( 'Spam', 'jetpack' ) . ' <span class="count">';
786
		$status_html .= '(' . number_format( $status['spam'] ) . ')';
787
		$status_html .= '</span></a></li>';
788
	}
789
790
	echo $status_html;
791
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function grunion_ajax_spam() 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...
792
}
793
794
/**
795
 * Add the scripts that will add the "Check for Spam" button to the Feedbacks dashboard page.
796
 */
797
function grunion_enable_spam_recheck() {
798
	if ( ! defined( 'AKISMET_VERSION' ) ) {
799
		return;
800
	}
801
802
	$screen = get_current_screen();
803
804
	// Only add to feedback, only to non-spam view
805 View Code Duplication
	if ( 'edit-feedback' != $screen->id || ( ! empty( $_GET['post_status'] ) && 'spam' == $_GET['post_status'] ) ) {
806
		return;
807
	}
808
809
	// Add the scripts that handle the spam check event.
810
	wp_register_script(
811
		'grunion-admin',
812
		Jetpack::get_file_url_for_environment(
813
			'_inc/build/contact-form/js/grunion-admin.min.js',
814
			'modules/contact-form/js/grunion-admin.js'
815
		),
816
		array( 'jquery' )
817
	);
818
	wp_enqueue_script( 'grunion-admin' );
819
820
	wp_enqueue_style( 'grunion.css' );
821
822
	// Add the actual "Check for Spam" button.
823
	add_action( 'admin_head', 'grunion_check_for_spam_button' );
824
}
825
826
add_action( 'admin_enqueue_scripts', 'grunion_enable_spam_recheck' );
827
828
/**
829
 * Add the "Check for Spam" button to the Feedbacks dashboard page.
830
 */
831
function grunion_check_for_spam_button() {
832
	// Get HTML for the button
833
	$button_html = get_submit_button(
834
		__( 'Check for Spam', 'jetpack' ),
835
		'secondary',
836
		'jetpack-check-feedback-spam',
837
		false,
838
		array( 'class' => 'jetpack-check-feedback-spam' )
839
	);
840
	$button_html .= '<span class="jetpack-check-feedback-spam-spinner"></span>';
841
842
	// Add the button next to the filter button via js
843
	?>
844
	<script type="text/javascript">
845
		jQuery( function( $ ) {
846
			$( '#posts-filter #post-query-submit' ).after( '<?php echo $button_html; ?>' );
847
		} );
848
	</script>
849
	<?php
850
}
851
852
/**
853
 * Recheck all approved feedbacks for spam.
854
 */
855
function grunion_recheck_queue() {
856
	global $wpdb;
857
858
	$query = 'post_type=feedback&post_status=publish';
859
860
	if ( isset( $_POST['limit'], $_POST['offset'] ) ) {
861
		$query .= '&posts_per_page=' . intval( $_POST['limit'] ) . '&offset=' . intval( $_POST['offset'] );
862
	}
863
864
	$approved_feedbacks = get_posts( $query );
865
866
	foreach ( $approved_feedbacks as $feedback ) {
867
		$meta = get_post_meta( $feedback->ID, '_feedback_akismet_values', true );
868
869
		/**
870
		 * Filter whether the submitted feedback is considered as spam.
871
		 *
872
		 * @module contact-form
873
		 *
874
		 * @since 3.4.0
875
		 *
876
		 * @param bool false Is the submitted feedback spam? Default to false.
877
		 * @param array $meta Feedack values returned by the Akismet plugin.
878
		 */
879
		$is_spam = apply_filters( 'jetpack_contact_form_is_spam', false, $meta );
880
881
		if ( $is_spam ) {
882
			wp_update_post( array( 'ID' => $feedback->ID, 'post_status' => 'spam' ) );
883
			/** This action is already documented in modules/contact-form/admin.php */
884
			do_action( 'contact_form_akismet', 'spam', $akismet_values );
0 ignored issues
show
Bug introduced by
The variable $akismet_values does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
885
		}
886
	}
887
888
	wp_send_json( array(
889
		'processed' => count( $approved_feedbacks ),
890
	) );
891
}
892
893
add_action( 'wp_ajax_grunion_recheck_queue', 'grunion_recheck_queue' );
894