Completed
Push — fix/flickr-shortcode ( f65760...3f23bc )
by
unknown
29:41 queued 22:36
created

admin.php ➔ grunion_add_admin_scripts()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 3
nop 0
dl 0
loc 46
rs 9.1781
c 0
b 0
f 0
1
<?php
2
3
use Automattic\Jetpack\Assets;
4
5
/**
6
 * Add a contact form button to the post composition screen
7
 */
8
add_action( 'media_buttons', 'grunion_media_button', 999 );
9
function grunion_media_button() {
10
	global $post_ID, $temp_ID, $pagenow;
11
12
	if ( 'press-this.php' === $pagenow ) {
13
		return;
14
	}
15
16
	$iframe_post_id = (int) ( 0 == $post_ID ? $temp_ID : $post_ID );
17
	$title          = __( 'Add Contact Form', 'jetpack' );
18
	$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...
19
	$site_url       = esc_url( admin_url( "/admin-ajax.php?post_id={$iframe_post_id}&action=grunion_form_builder&TB_iframe=true&width=768" ) );
20
	?>
21
22
	<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">
23
		<span class="jetpack-contact-form-icon"></span> <?php echo esc_html( $title ); ?>
24
	</a>
25
26
	<?php
27
}
28
29
add_action( 'wp_ajax_grunion_form_builder', 'grunion_display_form_view' );
30
31
function grunion_display_form_view() {
32
	if ( current_user_can( 'edit_posts' ) ) {
33
		require_once GRUNION_PLUGIN_DIR . 'grunion-form-view.php';
34
	}
35
	exit;
36
}
37
38
// feedback specific css items
39
add_action( 'admin_print_styles', 'grunion_admin_css' );
40
function grunion_admin_css() {
41
	global $current_screen;
42
	if ( is_null( $current_screen ) ) {
43
		return;
44
	}
45
	if ( 'edit-feedback' !== $current_screen->id ) {
46
		return;
47
	}
48
49
	wp_enqueue_script( 'wp-lists' );
50
?>
51
52
<style type='text/css'>
53
.add-new-h2, .view-switch, body.no-js .tablenav select[name^=action], body.no-js #doaction, body.no-js #doaction2 {
54
	display: none
55
}
56
57
.column-feedback_from img {
58
	float:left;
59
	margin-right:10px;
60
	margin-top:3px;
61
}
62
63
.widefat .column-feedback_from {
64
	width: 17%;
65
}
66
.widefat .column-feedback_date {
67
	width: 17%;
68
}
69
70
.spam a {
71
	color: #BC0B0B;
72
}
73
74
.untrash a {
75
	color: #D98500;
76
}
77
78
.unspam a {
79
color: #D98500;
80
}
81
82
</style>
83
84
<?php
85
}
86
87
/**
88
 * Hack a 'Bulk Spam' option for bulk edit in other than spam view
89
 * Hack a 'Bulk Delete' option for bulk edit in spam view
90
 *
91
 * There isn't a better way to do this until
92
 * https://core.trac.wordpress.org/changeset/17297 is resolved
93
 */
94
add_action( 'admin_head', 'grunion_add_bulk_edit_option' );
95
function grunion_add_bulk_edit_option() {
96
97
	$screen = get_current_screen();
98
99
	if ( is_null( $screen ) ) {
100
		return;
101
	}
102
103
	if ( 'edit-feedback' != $screen->id ) {
104
		return;
105
	}
106
107
	// When viewing spam we want to be able to be able to bulk delete
108
	// When viewing anything we want to be able to bulk move to spam
109
	if ( isset( $_GET['post_status'] ) && 'spam' == $_GET['post_status'] ) {
110
		// Create Delete Permanently bulk item
111
		$option_val      = 'delete';
112
		$option_txt      = __( 'Delete Permanently', 'jetpack' );
113
		$pseudo_selector = 'last-child';
114
115
	} else {
116
		// Create Mark Spam bulk item
117
		$option_val      = 'spam';
118
		$option_txt      = __( 'Mark as Spam', 'jetpack' );
119
		$pseudo_selector = 'first-child';
120
	}
121
122
	?>
123
		<script type="text/javascript">
124
			jQuery(document).ready(function($) {
125
				$('#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>' );
126
			})
127
		</script>
128
	<?php
129
}
130
131
/**
132
 * Handle a bulk spam report
133
 */
134
add_action( 'admin_init', 'grunion_handle_bulk_spam' );
135
function grunion_handle_bulk_spam() {
136
	global $pagenow;
137
138
	if ( 'edit.php' != $pagenow
139
	|| ( empty( $_REQUEST['post_type'] ) || 'feedback' != $_REQUEST['post_type'] ) ) {
140
		return;
141
	}
142
143
	// Slip in a success message
144
	if ( ! empty( $_REQUEST['message'] ) && 'marked-spam' == $_REQUEST['message'] ) {
145
		add_action( 'admin_notices', 'grunion_message_bulk_spam' );
146
	}
147
148
	if ( ( empty( $_REQUEST['action'] ) || 'spam' != $_REQUEST['action'] ) && ( empty( $_REQUEST['action2'] ) || 'spam' != $_REQUEST['action2'] ) ) {
149
		return;
150
	}
151
152
	check_admin_referer( 'bulk-posts' );
153
154
	if ( empty( $_REQUEST['post'] ) ) {
155
		wp_safe_redirect( wp_get_referer() );
156
		exit;
157
	}
158
159
	$post_ids = array_map( 'intval', $_REQUEST['post'] );
160
161
	foreach ( $post_ids as $post_id ) {
162
		if ( ! current_user_can( 'edit_page', $post_id ) ) {
163
			wp_die( __( 'You are not allowed to manage this item.', 'jetpack' ) );
164
		}
165
166
		$post           = array(
167
			'ID'          => $post_id,
168
			'post_status' => 'spam',
169
		);
170
		$akismet_values = get_post_meta( $post_id, '_feedback_akismet_values', true );
171
		wp_update_post( $post );
172
173
		/**
174
		 * Fires after a comment has been marked by Akismet.
175
		 *
176
		 * Typically this means the comment is spam.
177
		 *
178
		 * @module contact-form
179
		 *
180
		 * @since 2.2.0
181
		 *
182
		 * @param string $comment_status Usually is 'spam', otherwise 'ham'.
183
		 * @param array $akismet_values From '_feedback_akismet_values' in comment meta
184
		 */
185
		do_action( 'contact_form_akismet', 'spam', $akismet_values );
186
	}
187
188
	$redirect_url = add_query_arg( 'message', 'marked-spam', wp_get_referer() );
189
	wp_safe_redirect( $redirect_url );
190
	exit;
191
}
192
193
function grunion_message_bulk_spam() {
194
	echo '<div class="updated"><p>' . __( 'Feedback(s) marked as spam', 'jetpack' ) . '</p></div>';
195
}
196
197
// remove admin UI parts that we don't support in feedback management
198
add_action( 'admin_menu', 'grunion_admin_menu' );
199
function grunion_admin_menu() {
200
	global $menu, $submenu;
201
	unset( $submenu['edit.php?post_type=feedback'] );
202
}
203
204
add_filter( 'bulk_actions-edit-feedback', 'grunion_admin_bulk_actions' );
205
function grunion_admin_bulk_actions( $actions ) {
206
	global $current_screen;
207
	if ( 'edit-feedback' != $current_screen->id ) {
208
		return $actions;
209
	}
210
211
	unset( $actions['edit'] );
212
	return $actions;
213
}
214
215
add_filter( 'views_edit-feedback', 'grunion_admin_view_tabs' );
216
function grunion_admin_view_tabs( $views ) {
217
	global $current_screen;
218
	if ( 'edit-feedback' != $current_screen->id ) {
219
		return $views;
220
	}
221
222
	unset( $views['publish'] );
223
224
	preg_match( '|post_type=feedback\'( class="current")?\>(.*)\<span class=|', $views['all'], $match );
225
	if ( ! empty( $match[2] ) ) {
226
		$views['all'] = str_replace( $match[2], __( 'Messages', 'jetpack' ) . ' ', $views['all'] );
227
	}
228
229
	return $views;
230
}
231
232
add_filter( 'manage_feedback_posts_columns', 'grunion_post_type_columns_filter' );
233
function grunion_post_type_columns_filter( $cols ) {
234
	$cols = array(
235
		'cb'               => '<input type="checkbox" />',
236
		'feedback_from'    => __( 'From', 'jetpack' ),
237
		'feedback_message' => __( 'Message', 'jetpack' ),
238
		'feedback_date'    => __( 'Date', 'jetpack' ),
239
	);
240
241
	return $cols;
242
}
243
244
add_action( 'manage_posts_custom_column', 'grunion_manage_post_columns', 10, 2 );
245
function grunion_manage_post_columns( $col, $post_id ) {
246
	global $post;
247
248
	/**
249
	 * Only call parse_fields_from_content if we're dealing with a Grunion custom column.
250
	 */
251
	if ( ! in_array( $col, array( 'feedback_date', 'feedback_from', 'feedback_message' ) ) ) {
252
		return;
253
	}
254
255
	$content_fields = Grunion_Contact_Form_Plugin::parse_fields_from_content( $post_id );
256
257
	switch ( $col ) {
258
		case 'feedback_from':
259
			$author_name  = isset( $content_fields['_feedback_author'] ) ? $content_fields['_feedback_author'] : '';
260
			$author_email = isset( $content_fields['_feedback_author_email'] ) ? $content_fields['_feedback_author_email'] : '';
261
			$author_url   = isset( $content_fields['_feedback_author_url'] ) ? $content_fields['_feedback_author_url'] : '';
262
			$author_ip    = isset( $content_fields['_feedback_ip'] ) ? $content_fields['_feedback_ip'] : '';
263
			$form_url     = isset( $post->post_parent ) ? get_permalink( $post->post_parent ) : null;
264
265
			$author_name_line = '';
266
			if ( ! empty( $author_name ) ) {
267
				if ( ! empty( $author_email ) ) {
268
					$author_name_line = get_avatar( $author_email, 32 );
269
				}
270
271
				$author_name_line .= sprintf( '<strong>%s</strong><br />', esc_html( $author_name ) );
272
			}
273
274
			$author_email_line = '';
275
			if ( ! empty( $author_email ) ) {
276
				$author_email_line = sprintf( "<a href='%1\$s' target='_blank'>%2\$s</a><br />", esc_url( 'mailto:' . $author_email ), esc_html( $author_email ) );
277
			}
278
279
			$author_url_line = '';
280
			if ( ! empty( $author_url ) ) {
281
				$author_url_line = sprintf( "<a href='%1\$s'>%1\$s</a><br />", esc_url( $author_url ) );
282
			}
283
284
			echo $author_name_line;
285
			echo $author_email_line;
286
			echo $author_url_line;
287
			echo "<a href='edit.php?post_type=feedback&s=" . urlencode( $author_ip );
288
			echo "&mode=detail'>" . esc_html( $author_ip ) . '</a><br />';
289
			if ( $form_url ) {
290
				echo '<a href="' . esc_url( $form_url ) . '">' . esc_html( $form_url ) . '</a>';
291
			}
292
			break;
293
294
		case 'feedback_message':
295
			$post_type_object = get_post_type_object( $post->post_type );
296
			if ( isset( $content_fields['_feedback_subject'] ) ) {
297
				echo '<strong>';
298
				echo esc_html( $content_fields['_feedback_subject'] );
299
				echo '</strong>';
300
				echo '<br />';
301
			}
302
			echo sanitize_text_field( get_the_content( '' ) );
303
			echo '<br />';
304
305
			$extra_fields = get_post_meta( $post_id, '_feedback_extra_fields', true );
306
			if ( ! empty( $extra_fields ) ) {
307
				echo '<br /><hr />';
308
				echo '<table cellspacing="0" cellpadding="0" style="">' . "\n";
309
				foreach ( (array) $extra_fields as $k => $v ) {
310
					// Remove prefix from exta fields
311
					echo "<tr><td align='right'><b>" . esc_html( preg_replace( '#^\d+_#', '', $k ) ) . '</b></td><td>' . sanitize_text_field( $v ) . "</td></tr>\n";
312
				}
313
				echo '</table>';
314
			}
315
316
			echo '<div class="row-actions">';
317
			if ( $post->post_status == 'trash' ) {
318
				echo '<span class="untrash" id="feedback-restore-' . $post_id;
319
				echo '"><a title="';
320
				echo esc_attr__( 'Restore this item from the Trash', 'jetpack' );
321
				echo '" href="' . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-' . $post->post_type . '_' . $post->ID );
322
				echo '">' . __( 'Restore', 'jetpack' ) . '</a></span> | ';
323
324
				echo "<span class='delete'> <a class='submitdelete' title='";
325
				echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
326
				echo "' href='" . get_delete_post_link( $post->ID, '', true );
327
				echo "'>" . __( 'Delete Permanently', 'jetpack' ) . '</a></span>';
328
?>
329
330
<script>
331
jQuery(document).ready(function($) {
332
$('#feedback-restore-<?php echo $post_id; ?>').click(function(e) {
333
	e.preventDefault();
334
	$.post(ajaxurl, {
335
			action: 'grunion_ajax_spam',
336
			post_id: '<?php echo $post_id; ?>',
337
			make_it: 'publish',
338
			sub_menu: jQuery('.subsubsub .current').attr('href'),
339
			_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
340
		},
341
		function(r) {
342
			$('#post-<?php echo $post_id; ?>')
343
				.css({backgroundColor: '#59C859'})
344
				.fadeOut(350, function() {
345
					$(this).remove();
346
					$('.subsubsub').html(r);
347
				});
348
		}
349
	);
350
});
351
});
352
</script>
353
354
<?php
355
			} elseif ( $post->post_status == 'publish' ) {
356
				echo '<span class="spam" id="feedback-spam-' . $post_id;
357
				echo '"><a title="';
358
				echo __( 'Mark this message as spam', 'jetpack' );
359
				echo '" href="' . wp_nonce_url( admin_url( 'admin-ajax.php?post_id=' . $post_id . '&amp;action=spam' ), 'spam-feedback_' . $post_id );
360
				echo '">Spam</a></span>';
361
				echo ' | ';
362
363
				echo '<span class="delete" id="feedback-trash-' . $post_id;
364
				echo '">';
365
				echo '<a class="submitdelete" title="' . esc_attr__( 'Trash', 'jetpack' );
366
				echo '" href="' . get_delete_post_link( $post_id );
367
				echo '">' . __( 'Trash', 'jetpack' ) . '</a></span>';
368
369
?>
370
371
<script>
372
jQuery(document).ready( function($) {
373
	$('#feedback-spam-<?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: 'spam',
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:'#FF7979'} )
385
					.fadeOut(350, function() {
386
						$(this).remove();
387
						$('.subsubsub').html(r);
388
				});
389
		});
390
	});
391
392
	$('#feedback-trash-<?php echo $post_id; ?>').click(function(e) {
393
		e.preventDefault();
394
		$.post(ajaxurl, {
395
				action: 'grunion_ajax_spam',
396
				post_id: '<?php echo $post_id; ?>',
397
				make_it: 'trash',
398
				sub_menu: jQuery('.subsubsub .current').attr('href'),
399
				_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
400
			},
401
			function(r) {
402
				$('#post-<?php echo $post_id; ?>')
403
					.css({backgroundColor: '#FF7979'})
404
					.fadeOut(350, function() {
405
						$(this).remove();
406
						$('.subsubsub').html(r);
407
					});
408
			}
409
		);
410
	});
411
});
412
</script>
413
414
<?php
415
			} elseif ( $post->post_status == 'spam' ) {
416
				echo '<span class="unspam unapprove" id="feedback-ham-' . $post_id;
417
				echo '"><a title="';
418
				echo __( 'Mark this message as NOT spam', 'jetpack' );
419
				echo '" href="">Not Spam</a></span>';
420
				echo ' | ';
421
422
				echo "<span class='delete' id='feedback-trash-" . $post_id;
423
				echo "'> <a class='submitdelete' title='";
424
				echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
425
				echo "' href='" . get_delete_post_link( $post->ID, '', true );
426
				echo "'>" . __( 'Delete Permanently', 'jetpack' ) . '</a></span>';
427
?>
428
429
<script>
430
jQuery(document).ready( function($) {
431
	$('#feedback-ham-<?php echo $post_id; ?>').click( function(e) {
432
		e.preventDefault();
433
		$.post( ajaxurl, {
434
				action: 'grunion_ajax_spam',
435
				post_id: '<?php echo $post_id; ?>',
436
				make_it: 'ham',
437
				sub_menu: jQuery('.subsubsub .current').attr('href'),
438
				_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
439
			},
440
			function( r ) {
441
				$('#post-<?php echo $post_id; ?>')
442
					.css( {backgroundColor:'#59C859'} )
443
					.fadeOut(350, function() {
444
						$(this).remove();
445
						$('.subsubsub').html(r);
446
				});
447
			});
448
	});
449
});
450
</script>
451
452
<?php
453
			}
454
			break;
455
456
		case 'feedback_date':
457
			$date_time_format = _x( '%1$s \a\t %2$s', '{$date_format} \a\t {$time_format}', 'jetpack' );
458
			$date_time_format = sprintf( $date_time_format, get_option( 'date_format' ), get_option( 'time_format' ) );
459
			$time             = date_i18n( $date_time_format, get_the_time( 'U' ) );
460
461
			echo $time;
462
			break;
463
	}
464
}
465
466
function grunion_esc_attr( $attr ) {
467
	$out = esc_attr( $attr );
468
	// we also have to entity-encode square brackets so they don't interfere with the shortcode parser
469
	// FIXME: do this better - just stripping out square brackets for now since they mysteriously keep reappearing
470
	$out = str_replace( '[', '', $out );
471
	$out = str_replace( ']', '', $out );
472
	return $out;
473
}
474
475
function grunion_sort_objects( $a, $b ) {
476
	if ( isset( $a['order'] ) && isset( $b['order'] ) ) {
477
		return $a['order'] - $b['order'];
478
	}
479
	return 0;
480
}
481
482
// take an array of field types from the form builder, and construct a shortcode form
483
// returns both the shortcode form, and HTML markup representing a preview of the form
484
function grunion_ajax_shortcode() {
485
	check_ajax_referer( 'grunion_shortcode' );
486
487
	if ( ! current_user_can( 'edit_posts' ) ) {
488
		die( '-1' );
489
	}
490
491
	$attributes = array();
492
493
	foreach ( array( 'subject', 'to' ) as $attribute ) {
494
		if ( isset( $_POST[ $attribute ] ) && strlen( $_POST[ $attribute ] ) ) {
495
			$attributes[ $attribute ] = stripslashes( $_POST[ $attribute ] );
496
		}
497
	}
498
499
	if ( is_array( $_POST['fields'] ) ) {
500
		$fields = stripslashes_deep( $_POST['fields'] );
501
		usort( $fields, 'grunion_sort_objects' );
502
503
		$field_shortcodes = array();
504
505
		foreach ( $fields as $field ) {
506
			$field_attributes = array();
507
508
			if ( isset( $field['required'] ) && 'true' === $field['required'] ) {
509
				$field_attributes['required'] = 'true';
510
			}
511
512
			foreach ( array( 'options', 'label', 'type' ) as $attribute ) {
513
				if ( isset( $field[ $attribute ] ) ) {
514
					$field_attributes[ $attribute ] = $field[ $attribute ];
515
				}
516
			}
517
518
			$field_shortcodes[] = new Grunion_Contact_Form_Field( $field_attributes );
519
		}
520
	}
521
522
	$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...
523
524
	die( "\n$grunion\n" );
525
}
526
527
// takes a post_id, extracts the contact-form shortcode from that post (if there is one), parses it,
528
// and constructs a json object representing its contents and attributes
529
function grunion_ajax_shortcode_to_json() {
530
	global $post, $grunion_form;
531
532
	check_ajax_referer( 'grunion_shortcode_to_json' );
533
534
	if ( ! empty( $_POST['post_id'] ) && ! current_user_can( 'edit_post', $_POST['post_id'] ) ) {
535
		die( '-1' );
536
	} elseif ( ! current_user_can( 'edit_posts' ) ) {
537
		die( '-1' );
538
	}
539
540
	if ( ! isset( $_POST['content'] ) || ! is_numeric( $_POST['post_id'] ) ) {
541
		die( '-1' );
542
	}
543
544
	$content = stripslashes( $_POST['content'] );
545
546
	// doesn't look like a post with a [contact-form] already.
547
	if ( false === has_shortcode( $content, 'contact-form' ) ) {
548
		die( '' );
549
	}
550
551
	$post = get_post( $_POST['post_id'] );
552
553
	do_shortcode( $content );
554
555
	$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...
556
557
	$out = array(
558
		'to'      => '',
559
		'subject' => '',
560
		'fields'  => array(),
561
	);
562
563
	foreach ( $grunion->fields as $field ) {
564
		$out['fields'][ $field->get_attribute( 'id' ) ] = $field->attributes;
565
	}
566
567
	$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...
568
	$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...
569
	foreach ( array( 'to', 'subject' ) as $attribute ) {
570
		$value = $grunion->get_attribute( $attribute );
571
		if ( isset( $grunion->defaults[ $attribute ] ) && $value == $grunion->defaults[ $attribute ] ) {
572
			$value = '';
573
		}
574
		$out[ $attribute ] = $value;
575
	}
576
577
	die( json_encode( $out ) );
578
}
579
580
581
add_action( 'wp_ajax_grunion_shortcode', 'grunion_ajax_shortcode' );
582
add_action( 'wp_ajax_grunion_shortcode_to_json', 'grunion_ajax_shortcode_to_json' );
583
584
585
// process row-action spam/not spam clicks
586
add_action( 'wp_ajax_grunion_ajax_spam', 'grunion_ajax_spam' );
587
function grunion_ajax_spam() {
588
	global $wpdb;
589
590
	if ( empty( $_POST['make_it'] ) ) {
591
		return;
592
	}
593
594
	$post_id = (int) $_POST['post_id'];
595
	check_ajax_referer( 'grunion-post-status-' . $post_id );
596
	if ( ! current_user_can( 'edit_page', $post_id ) ) {
597
		wp_die( __( 'You are not allowed to manage this item.', 'jetpack' ) );
598
	}
599
600
	require_once dirname( __FILE__ ) . '/grunion-contact-form.php';
601
602
	$current_menu = '';
603
	if ( isset( $_POST['sub_menu'] ) && preg_match( '|post_type=feedback|', $_POST['sub_menu'] ) ) {
604
		if ( preg_match( '|post_status=spam|', $_POST['sub_menu'] ) ) {
605
			$current_menu = 'spam';
606
		} elseif ( preg_match( '|post_status=trash|', $_POST['sub_menu'] ) ) {
607
			$current_menu = 'trash';
608
		} else {
609
			$current_menu = 'messages';
610
		}
611
	}
612
613
	$post             = get_post( $post_id );
614
	$post_type_object = get_post_type_object( $post->post_type );
615
	$akismet_values   = get_post_meta( $post_id, '_feedback_akismet_values', true );
616
	if ( $_POST['make_it'] == 'spam' ) {
617
		$post->post_status = 'spam';
618
		$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...
619
		wp_transition_post_status( 'spam', 'publish', $post );
620
621
		/** This action is already documented in modules/contact-form/admin.php */
622
		do_action( 'contact_form_akismet', 'spam', $akismet_values );
623
	} elseif ( $_POST['make_it'] == 'ham' ) {
624
		$post->post_status = 'publish';
625
		$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...
626
		wp_transition_post_status( 'publish', 'spam', $post );
627
628
		/** This action is already documented in modules/contact-form/admin.php */
629
		do_action( 'contact_form_akismet', 'ham', $akismet_values );
630
631
		$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...
632
		$blog_url             = wp_parse_url( site_url() );
633
634
		// resend the original email
635
		$email          = get_post_meta( $post_id, '_feedback_email', true );
636
		$content_fields = Grunion_Contact_Form_Plugin::parse_fields_from_content( $post_id );
637
638
		if ( ! empty( $email ) && ! empty( $content_fields ) ) {
639
			if ( isset( $content_fields['_feedback_author_email'] ) ) {
640
				$comment_author_email = $content_fields['_feedback_author_email'];
641
			}
642
643
			if ( isset( $email['to'] ) ) {
644
				$to = $email['to'];
645
			}
646
647
			if ( isset( $email['message'] ) ) {
648
				$message = $email['message'];
649
			}
650
651
			if ( isset( $email['headers'] ) ) {
652
				$headers = $email['headers'];
653
			} else {
654
				$headers = 'From: "' . $content_fields['_feedback_author'] . '" <wordpress@' . $blog_url['host'] . ">\r\n";
655
656
				if ( ! empty( $comment_author_email ) ) {
657
					$reply_to_addr = $comment_author_email;
658
				} elseif ( is_array( $to ) ) {
659
					$reply_to_addr = $to[0];
660
				}
661
662
				if ( $reply_to_addr ) {
663
					$headers .= 'Reply-To: "' . $content_fields['_feedback_author'] . '" <' . $reply_to_addr . ">\r\n";
664
				}
665
666
				$headers .= 'Content-Type: text/plain; charset="' . get_option( 'blog_charset' ) . '"';
667
			}
668
669
			/**
670
			 * Filters the subject of the email sent after a contact form submission.
671
			 *
672
			 * @module contact-form
673
			 *
674
			 * @since 3.0.0
675
			 *
676
			 * @param string $content_fields['_feedback_subject'] Feedback's subject line.
677
			 * @param array $content_fields['_feedback_all_fields'] Feedback's data from old fields.
678
			 */
679
			$subject = apply_filters( 'contact_form_subject', $content_fields['_feedback_subject'], $content_fields['_feedback_all_fields'] );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $content_fields['_feedback_all_fields'].

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
680
681
			Grunion_Contact_Form::wp_mail( $to, $subject, $message, $headers );
682
		}
683
	} elseif ( $_POST['make_it'] == 'publish' ) {
684
		if ( ! current_user_can( $post_type_object->cap->delete_post, $post_id ) ) {
685
			wp_die( __( 'You are not allowed to move this item out of the Trash.', 'jetpack' ) );
686
		}
687
688
		if ( ! wp_untrash_post( $post_id ) ) {
689
			wp_die( __( 'Error in restoring from Trash.', 'jetpack' ) );
690
		}
691
	} elseif ( $_POST['make_it'] == 'trash' ) {
692
		if ( ! current_user_can( $post_type_object->cap->delete_post, $post_id ) ) {
693
			wp_die( __( 'You are not allowed to move this item to the Trash.', 'jetpack' ) );
694
		}
695
696
		if ( ! wp_trash_post( $post_id ) ) {
697
			wp_die( __( 'Error in moving to Trash.', 'jetpack' ) );
698
		}
699
	}
700
701
	$sql          = "
702
		SELECT post_status,
703
			COUNT( * ) AS post_count
704
		FROM `{$wpdb->posts}`
705
		WHERE post_type =  'feedback'
706
		GROUP BY post_status
707
	";
708
	$status_count = (array) $wpdb->get_results( $sql, ARRAY_A );
709
710
	$status      = array();
711
	$status_html = '';
712
	foreach ( $status_count as $i => $row ) {
713
		$status[ $row['post_status'] ] = $row['post_count'];
714
	}
715
716 View Code Duplication
	if ( isset( $status['publish'] ) ) {
717
		$status_html .= '<li><a href="edit.php?post_type=feedback"';
718
		if ( $current_menu == 'messages' ) {
719
			$status_html .= ' class="current"';
720
		}
721
722
		$status_html .= '>' . __( 'Messages', 'jetpack' ) . ' <span class="count">';
723
		$status_html .= '(' . number_format( $status['publish'] ) . ')';
724
		$status_html .= '</span></a> |</li>';
725
	}
726
727
	if ( isset( $status['trash'] ) ) {
728
		$status_html .= '<li><a href="edit.php?post_status=trash&amp;post_type=feedback"';
729
		if ( $current_menu == 'trash' ) {
730
			$status_html .= ' class="current"';
731
		}
732
733
		$status_html .= '>' . __( 'Trash', 'jetpack' ) . ' <span class="count">';
734
		$status_html .= '(' . number_format( $status['trash'] ) . ')';
735
		$status_html .= '</span></a>';
736
		if ( isset( $status['spam'] ) ) {
737
			$status_html .= ' |';
738
		}
739
		$status_html .= '</li>';
740
	}
741
742 View Code Duplication
	if ( isset( $status['spam'] ) ) {
743
		$status_html .= '<li><a href="edit.php?post_status=spam&amp;post_type=feedback"';
744
		if ( $current_menu == 'spam' ) {
745
			$status_html .= ' class="current"';
746
		}
747
748
		$status_html .= '>' . __( 'Spam', 'jetpack' ) . ' <span class="count">';
749
		$status_html .= '(' . number_format( $status['spam'] ) . ')';
750
		$status_html .= '</span></a></li>';
751
	}
752
753
	echo $status_html;
754
	exit;
755
}
756
757
/**
758
 * Add the scripts that will add the "Check for Spam" button to the Feedbacks dashboard page.
759
 */
760
function grunion_enable_spam_recheck() {
761
	if ( ! defined( 'AKISMET_VERSION' ) ) {
762
		return;
763
	}
764
765
	$screen = get_current_screen();
766
767
	// Only add to feedback, only to non-spam view
768
	if ( 'edit-feedback' != $screen->id || ( ! empty( $_GET['post_status'] ) && 'spam' == $_GET['post_status'] ) ) {
769
		return;
770
	}
771
772
	// Add the actual "Check for Spam" button.
773
	add_action( 'admin_head', 'grunion_check_for_spam_button' );
774
}
775
776
add_action( 'admin_enqueue_scripts', 'grunion_enable_spam_recheck' );
777
778
/**
779
 * Add the JS and CSS necessary for the Feedback admin page to function.
780
 */
781
function grunion_add_admin_scripts() {
782
	$screen = get_current_screen();
783
784
	if ( 'edit-feedback' !== $screen->id ) {
785
		return;
786
	}
787
788
	// Add the scripts that handle the spam check event.
789
	wp_register_script(
790
		'grunion-admin',
791
		Assets::get_file_url_for_environment(
792
			'_inc/build/contact-form/js/grunion-admin.min.js',
793
			'modules/contact-form/js/grunion-admin.js'
794
		),
795
		array( 'jquery' ),
796
		JETPACK__VERSION,
797
		true
798
	);
799
800
	wp_enqueue_script( 'grunion-admin' );
801
802
	wp_enqueue_style( 'grunion.css' );
803
804
	// Only add to feedback, only to spam view.
805
	if ( empty( $_GET['post_status'] ) || 'spam' !== $_GET['post_status'] ) {
806
		return;
807
	}
808
809
	$feedbacks_count = wp_count_posts( 'feedback' );
810
	$nonce           = wp_create_nonce( 'jetpack_delete_spam_feedbacks' );
811
	$success_url     = remove_query_arg( array( 'jetpack_empty_feedback_spam_error', 'post_status' ) ); // Go to the "All Feedback" page.
812
	$failure_url     = add_query_arg( 'jetpack_empty_feedback_spam_error', '1' ); // Refresh the current page and show an error.
813
	$spam_count      = $feedbacks_count->spam;
814
815
	$button_parameters = array(
816
		/* translators: The placeholder is for showing how much of the process has completed, as a percent. e.g., "Emptying Spam (40%)" */
817
		'progress_label' => __( 'Emptying Spam (%1$s%)', 'jetpack' ),
818
		'success_url'    => $success_url,
819
		'failure_url'    => $failure_url,
820
		'spam_count'     => $spam_count,
821
		'nonce'          => $nonce,
822
		'label'          => __( 'Empty Spam', 'jetpack' ),
823
	);
824
825
	wp_localize_script( 'grunion-admin', 'jetpack_empty_spam_button_parameters', $button_parameters );
826
}
827
828
add_action( 'admin_enqueue_scripts', 'grunion_add_admin_scripts' );
829
830
/**
831
 * Add the "Check for Spam" button to the Feedbacks dashboard page.
832
 */
833
function grunion_check_for_spam_button() {
834
	// Get HTML for the button
835
	$button_html  = get_submit_button(
836
		__( 'Check for Spam', 'jetpack' ),
837
		'secondary',
838
		'jetpack-check-feedback-spam',
839
		false,
840
		array( 'class' => 'jetpack-check-feedback-spam' )
841
	);
842
	$button_html .= '<span class="jetpack-check-feedback-spam-spinner"></span>';
843
844
	// Add the button next to the filter button via js
845
	?>
846
	<script type="text/javascript">
847
		jQuery( function( $ ) {
848
			$( '#posts-filter #post-query-submit' ).after( '<?php echo $button_html; ?>' );
849
		} );
850
	</script>
851
	<?php
852
}
853
854
/**
855
 * Recheck all approved feedbacks for spam.
856
 */
857
function grunion_recheck_queue() {
858
	global $wpdb;
859
860
	$query = 'post_type=feedback&post_status=publish';
861
862
	if ( isset( $_POST['limit'], $_POST['offset'] ) ) {
863
		$query .= '&posts_per_page=' . intval( $_POST['limit'] ) . '&offset=' . intval( $_POST['offset'] );
864
	}
865
866
	$approved_feedbacks = get_posts( $query );
867
868
	foreach ( $approved_feedbacks as $feedback ) {
869
		$meta = get_post_meta( $feedback->ID, '_feedback_akismet_values', true );
870
871
		if ( ! $meta ) {
872
			// _feedback_akismet_values is eventually deleted when it's no longer
873
			// within a reasonable time period to check the feedback for spam, so
874
			// if it's gone, don't attempt a spam recheck.
875
			continue;
876
		}
877
		
878
		$meta['recheck_reason'] = 'recheck_queue';
879
880
		/**
881
		 * Filter whether the submitted feedback is considered as spam.
882
		 *
883
		 * @module contact-form
884
		 *
885
		 * @since 3.4.0
886
		 *
887
		 * @param bool false Is the submitted feedback spam? Default to false.
888
		 * @param array $meta Feedack values returned by the Akismet plugin.
889
		 */
890
		$is_spam = apply_filters( 'jetpack_contact_form_is_spam', false, $meta );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $meta.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
891
892
		if ( $is_spam ) {
893
			wp_update_post(
894
				array(
895
					'ID'          => $feedback->ID,
896
					'post_status' => 'spam',
897
				)
898
			);
899
			/** This action is already documented in modules/contact-form/admin.php */
900
			do_action( 'contact_form_akismet', 'spam', $meta );
901
		}
902
	}
903
904
	wp_send_json(
905
		array(
906
			'processed' => count( $approved_feedbacks ),
907
		)
908
	);
909
}
910
911
add_action( 'wp_ajax_grunion_recheck_queue', 'grunion_recheck_queue' );
912
913
/**
914
 * Delete a number of spam feedbacks via an AJAX request.
915
 */
916
function grunion_delete_spam_feedbacks() {
917
	if ( ! wp_verify_nonce( $_POST['nonce'], 'jetpack_delete_spam_feedbacks' ) ) {
918
		wp_send_json_error(
919
			__( 'You aren&#8217;t authorized to do that.', 'jetpack' ),
920
			403
921
		);
922
923
		return;
924
	}
925
926
	if ( ! current_user_can( 'delete_others_posts' ) ) {
927
		wp_send_json_error(
928
			__( 'You don&#8217;t have permission to do that.', 'jetpack' ),
929
			403
930
		);
931
932
		return;
933
	}
934
935
	$deleted_feedbacks = 0;
936
937
	$delete_limit = 25;
938
	/**
939
	 * Filter the amount of Spam feedback one can delete at once.
940
	 *
941
	 * @module contact-form
942
	 *
943
	 * @since 8.7.0
944
	 *
945
	 * @param int $delete_limit Number of spam to process at once. Default to 25.
946
	 */
947
	$delete_limit = apply_filters( 'jetpack_delete_spam_feedbacks_limit', $delete_limit );
948
	$delete_limit = intval( $delete_limit );
949
	$delete_limit = max( 1, min( 100, $delete_limit ) ); // Allow a range of 1-100 for the delete limit.
950
951
	$query_args = array(
952
		'post_type'      => 'feedback',
953
		'post_status'    => 'spam',
954
		'posts_per_page' => $delete_limit,
955
	);
956
957
	$query          = new WP_Query( $query_args );
958
	$spam_feedbacks = $query->get_posts();
959
960
	foreach ( $spam_feedbacks as $feedback ) {
961
		wp_delete_post( $feedback->ID, true );
962
963
		$deleted_feedbacks++;
964
	}
965
966
	wp_send_json(
967
		array(
968
			'success' => true,
969
			'data'    => array(
970
				'counts' => array(
971
					'deleted' => $deleted_feedbacks,
972
					'limit'   => $delete_limit,
973
				),
974
			),
975
		)
976
	);
977
}
978
979
add_action( 'wp_ajax_jetpack_delete_spam_feedbacks', 'grunion_delete_spam_feedbacks' );
980
981
/**
982
 * Show an admin notice if the "Empty Spam" process was unable to complete, probably due to a permissions error.
983
 */
984
function grunion_spam_emptied_admin_notice() {
985
	if ( isset( $_GET['jetpack_empty_feedback_spam_error'] ) ) {
986
		echo '<div class="notice notice-error"><p>' . esc_html( __( 'An error occurred while trying to empty the Feedback spam folder.', 'jetpack' ) ) . '</p></div>';
987
	}
988
}
989
990
add_action( 'admin_notices', 'grunion_spam_emptied_admin_notice' );
991