Completed
Push — branch-4.0 ( fc0d6f...bf547c )
by
unknown
08:22
created

admin.php ➔ grunion_ajax_spam()   F

Complexity

Conditions 32
Paths > 20000

Size

Total Lines 173
Code Lines 97

Duplication

Lines 19
Ratio 10.98 %

Importance

Changes 0
Metric Value
cc 32
eloc 97
nc 48241
nop 0
dl 19
loc 173
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
276
	$cols = array(
277
		'cb'	=> '<input type="checkbox" />',
278
		'feedback_from'		=> __( 'From', 'jetpack' ),
279
		'feedback_message'		=> __( 'Message', 'jetpack' ),
280
		'feedback_date'			=> __( 'Date', 'jetpack' )
281
	);
282
283
	return $cols;
284
}
285
286
add_action( 'manage_posts_custom_column', 'grunion_manage_post_columns', 10, 2 );
287
function grunion_manage_post_columns( $col, $post_id ) {
288
	global $post;
289
290
	/**
291
	 * Only call parse_fields_from_content if we're dealing with a Grunion custom column.
292
	 */
293
	if ( ! in_array( $col, array( 'feedback_date', 'feedback_from', 'feedback_message' ) ) ) {
294
		return;
295
	}
296
297
	$content_fields = Grunion_Contact_Form_Plugin::parse_fields_from_content( $post_id );
298
299
	switch ( $col ) {
300
		case 'feedback_from':
301
			$author_name  = isset( $content_fields['_feedback_author'] ) ? $content_fields['_feedback_author'] : '';
302
			$author_email = isset( $content_fields['_feedback_author_email'] ) ? $content_fields['_feedback_author_email'] : '';
303
			$author_url   = isset( $content_fields['_feedback_author_url'] ) ? $content_fields['_feedback_author_url'] : '';
304
			$author_ip    = isset( $content_fields['_feedback_ip'] ) ? $content_fields['_feedback_ip'] : '';
305
			$form_url     = isset( $post->post_parent ) ? get_permalink( $post->post_parent ) : null;
306
307
			$author_name_line = '';
308
			if ( !empty( $author_name ) ) {
309
				if ( !empty( $author_email ) )
310
					$author_name_line = get_avatar( $author_email, 32 );
311
312
				$author_name_line .= sprintf( "<strong>%s</strong><br />", esc_html( $author_name ) );
313
			}
314
315
			$author_email_line = '';
316
			if ( !empty( $author_email ) ) {
317
				$author_email_line = sprintf( "<a href='%1\$s' target='_blank'>%2\$s</a><br />", esc_url( "mailto:" . $author_email ) , esc_html( $author_email ) );
318
			}
319
320
			$author_url_line = '';
321
			if ( !empty( $author_url ) ) {
322
				$author_url_line = sprintf( "<a href='%1\$s'>%1\$s</a><br />", esc_url( $author_url ) );
323
			}
324
325
			echo $author_name_line;
326
			echo $author_email_line;
327
			echo $author_url_line;
328
			echo "<a href='edit.php?post_type=feedback&s=" . urlencode( $author_ip );
329
			echo "&mode=detail'>" . esc_html( $author_ip ) . "</a><br />";
330
			if ( $form_url ) {
331
				echo '<a href="' . esc_url( $form_url ) . '">' . esc_html( $form_url ) . '</a>';
332
			}
333
			break;
334
335
		case 'feedback_message':
336
			$post_type_object = get_post_type_object( $post->post_type );
337
			if ( isset( $content_fields['_feedback_subject'] ) ) {
338
				echo '<strong>';
339
				echo esc_html( $content_fields['_feedback_subject'] );
340
				echo '</strong>';
341
				echo '<br />';
342
			}
343
			echo sanitize_text_field( get_the_content( '' ) );
344
			echo '<br />';
345
346
			$extra_fields = get_post_meta( $post_id, '_feedback_extra_fields', TRUE );
347
			if ( !empty( $extra_fields ) ) {
348
				echo '<br /><hr />';
349
				echo '<table cellspacing="0" cellpadding="0" style="">' . "\n";
350
				foreach ( (array) $extra_fields as $k => $v ) {
351
					// Remove prefix from exta fields
352
					echo "<tr><td align='right'><b>". esc_html( preg_replace( '#^\d+_#', '', $k ) ) ."</b></td><td>". sanitize_text_field( $v ) ."</td></tr>\n";
353
				}
354
				echo '</table>';
355
			}
356
357
			echo '<div class="row-actions">';
358
			if ( $post->post_status == 'trash' ) {
359
				echo '<span class="untrash" id="feedback-restore-' . $post_id;
360
				echo '"><a title="';
361
				echo esc_attr__( 'Restore this item from the Trash', 'jetpack' );
362
				echo '" href="' . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-' . $post->post_type . '_' . $post->ID );
363
				echo '">' . __( 'Restore', 'jetpack' ) . '</a></span> | ';
364
365
				echo "<span class='delete'> <a class='submitdelete' title='";
366
				echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
367
				echo "' href='" . get_delete_post_link( $post->ID, '', true );
368
				echo "'>" . __( 'Delete Permanently', 'jetpack' ) . "</a></span>";
369
?>
370
371
<script>
372
jQuery(document).ready(function($) {
373
$('#feedback-restore-<?php echo $post_id; ?>').click(function(e) {
374
	e.preventDefault();
375
	$.post(ajaxurl, {
376
			action: 'grunion_ajax_spam',
377
			post_id: '<?php echo $post_id; ?>',
378
			make_it: 'publish',
379
			sub_menu: jQuery('.subsubsub .current').attr('href'),
380
			_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
381
		},
382
		function(r) {
383
			$('#post-<?php echo $post_id; ?>')
384
				.css({backgroundColor: '#59C859'})
385
				.fadeOut(350, function() {
386
					$(this).remove();
387
					$('.subsubsub').html(r);
388
				});
389
		}
390
	);
391
});
392
});
393
</script>
394
395
<?php
396
			} elseif ( $post->post_status == 'publish' ) {
397
				echo '<span class="spam" id="feedback-spam-' . $post_id;
398
				echo '"><a title="';
399
				echo __( 'Mark this message as spam', 'jetpack' );
400
				echo '" href="' . wp_nonce_url( admin_url( 'admin-ajax.php?post_id=' . $post_id . '&amp;action=spam' ), 'spam-feedback_' . $post_id );
401
				echo '">Spam</a></span>';
402
				echo ' | ';
403
404
				echo '<span class="delete" id="feedback-trash-' . $post_id;
405
				echo '">';
406
				echo '<a class="submitdelete" title="' . esc_attr__( 'Trash', 'jetpack' );
407
				echo '" href="' . get_delete_post_link( $post_id );
408
				echo '">' . __( 'Trash', 'jetpack' ) . '</a></span>';
409
410
?>
411
412
<script>
413
jQuery(document).ready( function($) {
414
	$('#feedback-spam-<?php echo $post_id; ?>').click( function(e) {
415
		e.preventDefault();
416
		$.post( ajaxurl, {
417
				action: 'grunion_ajax_spam',
418
				post_id: '<?php echo $post_id; ?>',
419
				make_it: 'spam',
420
				sub_menu: jQuery('.subsubsub .current').attr('href'),
421
				_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
422
			},
423
			function( r ) {
424
				$('#post-<?php echo $post_id; ?>')
425
					.css( {backgroundColor:'#FF7979'} )
426
					.fadeOut(350, function() {
427
						$(this).remove();
428
						$('.subsubsub').html(r);
429
				});
430
		});
431
	});
432
433
	$('#feedback-trash-<?php echo $post_id; ?>').click(function(e) {
434
		e.preventDefault();
435
		$.post(ajaxurl, {
436
				action: 'grunion_ajax_spam',
437
				post_id: '<?php echo $post_id; ?>',
438
				make_it: 'trash',
439
				sub_menu: jQuery('.subsubsub .current').attr('href'),
440
				_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
441
			},
442
			function(r) {
443
				$('#post-<?php echo $post_id; ?>')
444
					.css({backgroundColor: '#FF7979'})
445
					.fadeOut(350, function() {
446
						$(this).remove();
447
						$('.subsubsub').html(r);
448
					});
449
			}
450
		);
451
	});
452
});
453
</script>
454
455
<?php
456
			} elseif ( $post->post_status == 'spam' ) {
457
				echo '<span class="unspam unapprove" id="feedback-ham-' . $post_id;
458
				echo '"><a title="';
459
				echo __( 'Mark this message as NOT spam', 'jetpack' );
460
				echo '" href="">Not Spam</a></span>';
461
				echo ' | ';
462
463
				echo "<span class='delete' id='feedback-trash-" . $post_id;
464
				echo "'> <a class='submitdelete' title='";
465
				echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
466
				echo "' href='" . get_delete_post_link( $post->ID, '', true );
467
				echo "'>" . __( 'Delete Permanently', 'jetpack' ) . "</a></span>";
468
?>
469
470
<script>
471
jQuery(document).ready( function($) {
472
	$('#feedback-ham-<?php echo $post_id; ?>').click( function(e) {
473
		e.preventDefault();
474
		$.post( ajaxurl, {
475
				action: 'grunion_ajax_spam',
476
				post_id: '<?php echo $post_id; ?>',
477
				make_it: 'ham',
478
				sub_menu: jQuery('.subsubsub .current').attr('href'),
479
				_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
480
			},
481
			function( r ) {
482
				$('#post-<?php echo $post_id; ?>')
483
					.css( {backgroundColor:'#59C859'} )
484
					.fadeOut(350, function() {
485
						$(this).remove();
486
						$('.subsubsub').html(r);
487
				});
488
			});
489
	});
490
});
491
</script>
492
493
<?php
494
			}
495
			break;
496
497
		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...
498
499
			$date_time_format = _x( '%1$s \a\t %2$s', '{$date_format} \a\t {$time_format}', 'jetpack' );
500
			$date_time_format = sprintf( $date_time_format, get_option( 'date_format' ), get_option( 'time_format' ) );
501
			$time = date_i18n( $date_time_format, get_the_time( 'U' ) );
502
503
			echo $time;
504
			break;
505
	}
506
}
507
508
function grunion_esc_attr( $attr ) {
509
	$out = esc_attr( $attr );
510
	// we also have to entity-encode square brackets so they don't interfere with the shortcode parser
511
	// FIXME: do this better - just stripping out square brackets for now since they mysteriously keep reappearing
512
	$out = str_replace( '[', '', $out );
513
	$out = str_replace( ']', '', $out );
514
	return $out;
515
}
516
517
function grunion_sort_objects( $a, $b ) {
518
	if ( isset($a['order']) && isset($b['order']) )
519
		return $a['order'] - $b['order'];
520
	return 0;
521
}
522
523
// take an array of field types from the form builder, and construct a shortcode form
524
// returns both the shortcode form, and HTML markup representing a preview of the form
525
function grunion_ajax_shortcode() {
526
	check_ajax_referer( 'grunion_shortcode' );
527
528
	$attributes = array();
529
530
	foreach ( array( 'subject', 'to' ) as $attribute ) {
531
		if ( isset( $_POST[$attribute] ) && strlen( $_POST[$attribute] ) ) {
532
			$attributes[$attribute] = stripslashes( $_POST[$attribute] );
533
		}
534
	}
535
536
	if ( is_array( $_POST['fields'] ) ) {
537
		$fields = stripslashes_deep( $_POST['fields'] );
538
		usort( $fields, 'grunion_sort_objects' );
539
540
		$field_shortcodes = array();
541
542
		foreach ( $fields as $field ) {
543
			$field_attributes = array();
544
545
			if ( isset( $field['required'] ) && 'true' === $field['required'] ) {
546
				$field_attributes['required'] = 'true';
547
			}
548
549
			foreach ( array( 'options', 'label', 'type' ) as $attribute ) {
550
				if ( isset( $field[$attribute] ) ) {
551
					$field_attributes[$attribute] = $field[$attribute];
552
				}
553
			}
554
555
			$field_shortcodes[] = new Grunion_Contact_Form_Field( $field_attributes );
556
		}
557
	}
558
559
	$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...
560
561
	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...
562
}
563
564
// takes a post_id, extracts the contact-form shortcode from that post (if there is one), parses it,
565
// and constructs a json object representing its contents and attributes
566
function grunion_ajax_shortcode_to_json() {
567
	global $post, $grunion_form;
568
569
	check_ajax_referer( 'grunion_shortcode_to_json' );
570
571
	if ( !isset( $_POST['content'] ) || !is_numeric( $_POST['post_id'] ) ) {
572
		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...
573
	}
574
575
	$content = stripslashes( $_POST['content'] );
576
577
	// doesn't look like a post with a [contact-form] already.
578
	if ( false === has_shortcode( $content, 'contact-form' ) ) {
579
		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...
580
	}
581
582
	$post = get_post( $_POST['post_id'] );
583
584
	do_shortcode( $content );
585
586
	$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...
587
588
	$out = array(
589
		'to'      => '',
590
		'subject' => '',
591
		'fields'  => array(),
592
	);
593
594
	foreach ( $grunion->fields as $field ) {
595
		$out['fields'][$field->get_attribute( 'id' )] = $field->attributes;
596
	}
597
598
	$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...
599
	$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...
600
	foreach ( array( 'to', 'subject' ) as $attribute ) {
601
		$value = $grunion->get_attribute( $attribute );
602
		if ( isset( $grunion->defaults[$attribute] ) && $value == $grunion->defaults[$attribute] ) {
603
			$value = '';
604
		}
605
		$out[$attribute] = $value;
606
	}
607
608
	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...
609
}
610
611
612
add_action( 'wp_ajax_grunion_shortcode', 'grunion_ajax_shortcode' );
613
add_action( 'wp_ajax_grunion_shortcode_to_json', 'grunion_ajax_shortcode_to_json' );
614
615
616
// process row-action spam/not spam clicks
617
add_action( 'wp_ajax_grunion_ajax_spam', 'grunion_ajax_spam' );
618
function grunion_ajax_spam() {
619
	global $wpdb;
620
621
	if ( empty( $_POST['make_it'] ) ) {
622
		return;
623
	}
624
625
	$post_id = (int) $_POST['post_id'];
626
	check_ajax_referer( 'grunion-post-status-' . $post_id );
627
	if ( ! current_user_can( "edit_page", $post_id ) ) {
628
		wp_die( __( 'You are not allowed to manage this item.', 'jetpack' ) );
629
	}
630
631
	require_once dirname( __FILE__ ) . '/grunion-contact-form.php';
632
633
	$current_menu = '';
634
	if ( isset( $_POST['sub_menu'] ) && preg_match( '|post_type=feedback|', $_POST['sub_menu'] ) ) {
635
		if ( preg_match( '|post_status=spam|', $_POST['sub_menu'] ) ) {
636
			$current_menu = 'spam';
637
		}
638
		elseif ( preg_match( '|post_status=trash|', $_POST['sub_menu'] ) ) {
639
			$current_menu = 'trash';
640
		}
641
		else {
642
			$current_menu = 'messages';
643
		}
644
645
	}
646
647
	$post = get_post( $post_id );
648
	$post_type_object = get_post_type_object( $post->post_type );
649
	$akismet_values   = get_post_meta( $post_id, '_feedback_akismet_values', TRUE );
650
	if ( $_POST['make_it'] == 'spam' ) {
651
		$post->post_status = 'spam';
652
		$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...
653
		wp_transition_post_status( 'spam', 'publish', $post );
654
655
		/** This action is already documented in modules/contact-form/admin.php */
656
		do_action( 'contact_form_akismet', 'spam', $akismet_values );
657
	} elseif ( $_POST['make_it'] == 'ham' ) {
658
		$post->post_status = 'publish';
659
		$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...
660
		wp_transition_post_status( 'publish', 'spam', $post );
661
662
		/** This action is already documented in modules/contact-form/admin.php */
663
		do_action( 'contact_form_akismet', 'ham', $akismet_values );
664
665
		$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...
666
		$blog_url = parse_url( site_url() );
667
668
		// resend the original email
669
		$email = get_post_meta( $post_id, '_feedback_email', TRUE );
670
		$content_fields = Grunion_Contact_Form_Plugin::parse_fields_from_content( $post_id );
671
672
		if ( ! empty( $email ) && !empty( $content_fields ) ) {
673
			if ( isset( $content_fields['_feedback_author_email'] ) ) {
674
				$comment_author_email = $content_fields['_feedback_author_email'];
675
			}
676
677
			if ( isset( $email['to'] ) ) {
678
				$to = $email['to'];
679
			}
680
681
			if ( isset( $email['message'] ) ) {
682
				$message = $email['message'];
683
			}
684
685
			if ( isset( $email['headers'] ) ) {
686
				$headers = $email['headers'];
687
			}
688
			else {
689
				$headers = 'From: "' . $content_fields['_feedback_author'] .'" <wordpress@' . $blog_url['host']  . ">\r\n";
690
691
				if ( ! empty( $comment_author_email ) ){
692
					$reply_to_addr = $comment_author_email;
693
				}
694
				elseif ( is_array( $to ) ) {
695
					$reply_to_addr = $to[0];
696
				}
697
698
				if ( $reply_to_addr ) {
699
					$headers .= 'Reply-To: "' . $content_fields['_feedback_author'] .'" <' . $reply_to_addr . ">\r\n";
700
				}
701
702
				$headers .= "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"";
703
			}
704
705
			/**
706
			 * Filters the subject of the email sent after a contact form submission.
707
			 *
708
			 * @module contact-form
709
			 *
710
			 * @since 3.0.0
711
			 *
712
			 * @param string $content_fields['_feedback_subject'] Feedback's subject line.
713
			 * @param array $content_fields['_feedback_all_fields'] Feedback's data from old fields.
714
			 */
715
			$subject = apply_filters( 'contact_form_subject', $content_fields['_feedback_subject'], $content_fields['_feedback_all_fields'] );
716
717
			wp_mail( $to, $subject, $message, $headers );
718
		}
719
	} elseif( $_POST['make_it'] == 'publish' ) {
720
		if ( ! current_user_can($post_type_object->cap->delete_post, $post_id) ) {
721
			wp_die( __( 'You are not allowed to move this item out of the Trash.', 'jetpack' ) );
722
		}
723
724
		if ( ! wp_untrash_post($post_id) ) {
725
			wp_die( __( 'Error in restoring from Trash.', 'jetpack' ) );
726
		}
727
728
	} elseif( $_POST['make_it'] == 'trash' ) {
729
		if ( ! current_user_can($post_type_object->cap->delete_post, $post_id) ) {
730
			wp_die( __( 'You are not allowed to move this item to the Trash.', 'jetpack' ) );
731
		}
732
733
		if ( ! wp_trash_post($post_id) ) {
734
			wp_die( __( 'Error in moving to Trash.', 'jetpack' ) );
735
		}
736
737
	}
738
739
	$sql = "
740
		SELECT post_status,
741
			COUNT( * ) AS post_count
742
		FROM `{$wpdb->posts}`
743
		WHERE post_type =  'feedback'
744
		GROUP BY post_status
745
	";
746
	$status_count = (array) $wpdb->get_results( $sql, ARRAY_A );
747
748
	$status = array();
749
	$status_html = '';
750
	foreach ( $status_count as $i => $row ) {
751
		$status[$row['post_status']] = $row['post_count'];
752
	}
753
754 View Code Duplication
	if ( isset( $status['publish'] ) ) {
755
		$status_html .= '<li><a href="edit.php?post_type=feedback"';
756
		if ( $current_menu == 'messages' ) {
757
			$status_html .= ' class="current"';
758
		}
759
760
		$status_html .= '>' . __( 'Messages', 'jetpack' ) . ' <span class="count">';
761
		$status_html .= '(' . number_format( $status['publish'] ) . ')';
762
		$status_html .= '</span></a> |</li>';
763
	}
764
765
	if ( isset( $status['trash'] ) ) {
766
		$status_html .= '<li><a href="edit.php?post_status=trash&amp;post_type=feedback"';
767
		if ( $current_menu == 'trash' )
768
			$status_html .= ' class="current"';
769
770
		$status_html .= '>' . __( 'Trash', 'jetpack' ) . ' <span class="count">';
771
		$status_html .= '(' . number_format( $status['trash'] ) . ')';
772
		$status_html .= '</span></a>';
773
		if ( isset( $status['spam'] ) )
774
			$status_html .= ' |';
775
		$status_html .= '</li>';
776
	}
777
778 View Code Duplication
	if ( isset( $status['spam'] ) ) {
779
		$status_html .= '<li><a href="edit.php?post_status=spam&amp;post_type=feedback"';
780
		if ( $current_menu == 'spam' )
781
			$status_html .= ' class="current"';
782
783
		$status_html .= '>' . __( 'Spam', 'jetpack' ) . ' <span class="count">';
784
		$status_html .= '(' . number_format( $status['spam'] ) . ')';
785
		$status_html .= '</span></a></li>';
786
	}
787
788
	echo $status_html;
789
	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...
790
}
791
792
add_action( 'omnisearch_add_providers', 'grunion_omnisearch_add_providers' );
793
function grunion_omnisearch_add_providers() {
794
	// Feedback uses capability_type 'page'
795
	if ( current_user_can( 'edit_pages' ) ) {
796
		require_once( GRUNION_PLUGIN_DIR . '/grunion-omnisearch.php' );
797
		new Jetpack_Omnisearch_Grunion;
798
	}
799
}
800
801
/**
802
 * Add the scripts that will add the "Check for Spam" button to the Feedbacks dashboard page.
803
 */
804
function grunion_enable_spam_recheck() {
805
	if ( ! defined( 'AKISMET_VERSION' ) ) {
806
		return;
807
	}
808
809
	$screen = get_current_screen();
810
811
	// Only add to feedback, only to non-spam view
812 View Code Duplication
	if ( 'edit-feedback' != $screen->id || ( ! empty( $_GET['post_status'] ) && 'spam' == $_GET['post_status'] ) ) {
813
		return;
814
	}
815
816
	// Add the scripts that handle the spam check event.
817
	wp_register_script( 'grunion-admin', plugin_dir_url( __FILE__ ) . 'js/grunion-admin.js', array( 'jquery' ) );
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