PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 8.1.1
Jetpack – WP Security, Backup, Speed, & Growth v8.1.1
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 All 500 releases
jetpack / modules / contact-form / admin.php
admin.php
898 lines 26.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 );
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 * Hack an 'Empty Spam' button to spam view
133 *
134 * Leverages core's delete_all functionality
135 */
136 add_action( 'admin_head', 'grunion_add_empty_spam_button' );
137 function grunion_add_empty_spam_button() {
138 $screen = get_current_screen();
139
140 if ( is_null( $screen ) ) {
141 return;
142 }
143
144 // Only add to feedback, only to spam view
145 if ( 'edit-feedback' != $screen->id
146 || empty( $_GET['post_status'] )
147 || 'spam' !== $_GET['post_status'] ) {
148 return;
149 }
150
151 // Get HTML for the button
152 $button_html = wp_nonce_field( 'bulk-destroy', '_destroy_nonce', true, false );
153 $button_html .= get_submit_button( __( 'Empty Spam', 'jetpack' ), 'apply', 'delete_all', false );
154
155 // Add the button next to the filter button via js
156 ?>
157 <script type="text/javascript">
158 jQuery(document).ready(function($) {
159 $('#posts-filter #post-query-submit').after('<?php echo $button_html; ?>' );
160 })
161 </script>
162 <?php
163 }
164
165 /**
166 * Handle a bulk spam report
167 */
168 add_action( 'admin_init', 'grunion_handle_bulk_spam' );
169 function grunion_handle_bulk_spam() {
170 global $pagenow;
171
172 if ( 'edit.php' != $pagenow
173 || ( empty( $_REQUEST['post_type'] ) || 'feedback' != $_REQUEST['post_type'] ) ) {
174 return;
175 }
176
177 // Slip in a success message
178 if ( ! empty( $_REQUEST['message'] ) && 'marked-spam' == $_REQUEST['message'] ) {
179 add_action( 'admin_notices', 'grunion_message_bulk_spam' );
180 }
181
182 if ( ( empty( $_REQUEST['action'] ) || 'spam' != $_REQUEST['action'] ) && ( empty( $_REQUEST['action2'] ) || 'spam' != $_REQUEST['action2'] ) ) {
183 return;
184 }
185
186 check_admin_referer( 'bulk-posts' );
187
188 if ( empty( $_REQUEST['post'] ) ) {
189 wp_safe_redirect( wp_get_referer() );
190 exit;
191 }
192
193 $post_ids = array_map( 'intval', $_REQUEST['post'] );
194
195 foreach ( $post_ids as $post_id ) {
196 if ( ! current_user_can( 'edit_page', $post_id ) ) {
197 wp_die( __( 'You are not allowed to manage this item.', 'jetpack' ) );
198 }
199
200 $post = array(
201 'ID' => $post_id,
202 'post_status' => 'spam',
203 );
204 $akismet_values = get_post_meta( $post_id, '_feedback_akismet_values', true );
205 wp_update_post( $post );
206
207 /**
208 * Fires after a comment has been marked by Akismet.
209 *
210 * Typically this means the comment is spam.
211 *
212 * @module contact-form
213 *
214 * @since 2.2.0
215 *
216 * @param string $comment_status Usually is 'spam', otherwise 'ham'.
217 * @param array $akismet_values From '_feedback_akismet_values' in comment meta
218 */
219 do_action( 'contact_form_akismet', 'spam', $akismet_values );
220 }
221
222 $redirect_url = add_query_arg( 'message', 'marked-spam', wp_get_referer() );
223 wp_safe_redirect( $redirect_url );
224 exit;
225 }
226
227 function grunion_message_bulk_spam() {
228 echo '<div class="updated"><p>' . __( 'Feedback(s) marked as spam', 'jetpack' ) . '</p></div>';
229 }
230
231 // remove admin UI parts that we don't support in feedback management
232 add_action( 'admin_menu', 'grunion_admin_menu' );
233 function grunion_admin_menu() {
234 global $menu, $submenu;
235 unset( $submenu['edit.php?post_type=feedback'] );
236 }
237
238 add_filter( 'bulk_actions-edit-feedback', 'grunion_admin_bulk_actions' );
239 function grunion_admin_bulk_actions( $actions ) {
240 global $current_screen;
241 if ( 'edit-feedback' != $current_screen->id ) {
242 return $actions;
243 }
244
245 unset( $actions['edit'] );
246 return $actions;
247 }
248
249 add_filter( 'views_edit-feedback', 'grunion_admin_view_tabs' );
250 function grunion_admin_view_tabs( $views ) {
251 global $current_screen;
252 if ( 'edit-feedback' != $current_screen->id ) {
253 return $views;
254 }
255
256 unset( $views['publish'] );
257
258 preg_match( '|post_type=feedback\'( class="current")?\>(.*)\<span class=|', $views['all'], $match );
259 if ( ! empty( $match[2] ) ) {
260 $views['all'] = str_replace( $match[2], __( 'Messages', 'jetpack' ) . ' ', $views['all'] );
261 }
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
305 $author_name_line .= sprintf( '<strong>%s</strong><br />', esc_html( $author_name ) );
306 }
307
308 $author_email_line = '';
309 if ( ! empty( $author_email ) ) {
310 $author_email_line = sprintf( "<a href='%1\$s' target='_blank'>%2\$s</a><br />", esc_url( 'mailto:' . $author_email ), esc_html( $author_email ) );
311 }
312
313 $author_url_line = '';
314 if ( ! empty( $author_url ) ) {
315 $author_url_line = sprintf( "<a href='%1\$s'>%1\$s</a><br />", esc_url( $author_url ) );
316 }
317
318 echo $author_name_line;
319 echo $author_email_line;
320 echo $author_url_line;
321 echo "<a href='edit.php?post_type=feedback&s=" . urlencode( $author_ip );
322 echo "&mode=detail'>" . esc_html( $author_ip ) . '</a><br />';
323 if ( $form_url ) {
324 echo '<a href="' . esc_url( $form_url ) . '">' . esc_html( $form_url ) . '</a>';
325 }
326 break;
327
328 case 'feedback_message':
329 $post_type_object = get_post_type_object( $post->post_type );
330 if ( isset( $content_fields['_feedback_subject'] ) ) {
331 echo '<strong>';
332 echo esc_html( $content_fields['_feedback_subject'] );
333 echo '</strong>';
334 echo '<br />';
335 }
336 echo sanitize_text_field( get_the_content( '' ) );
337 echo '<br />';
338
339 $extra_fields = get_post_meta( $post_id, '_feedback_extra_fields', true );
340 if ( ! empty( $extra_fields ) ) {
341 echo '<br /><hr />';
342 echo '<table cellspacing="0" cellpadding="0" style="">' . "\n";
343 foreach ( (array) $extra_fields as $k => $v ) {
344 // Remove prefix from exta fields
345 echo "<tr><td align='right'><b>" . esc_html( preg_replace( '#^\d+_#', '', $k ) ) . '</b></td><td>' . sanitize_text_field( $v ) . "</td></tr>\n";
346 }
347 echo '</table>';
348 }
349
350 echo '<div class="row-actions">';
351 if ( $post->post_status == 'trash' ) {
352 echo '<span class="untrash" id="feedback-restore-' . $post_id;
353 echo '"><a title="';
354 echo esc_attr__( 'Restore this item from the Trash', 'jetpack' );
355 echo '" href="' . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-' . $post->post_type . '_' . $post->ID );
356 echo '">' . __( 'Restore', 'jetpack' ) . '</a></span> | ';
357
358 echo "<span class='delete'> <a class='submitdelete' title='";
359 echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
360 echo "' href='" . get_delete_post_link( $post->ID, '', true );
361 echo "'>" . __( 'Delete Permanently', 'jetpack' ) . '</a></span>';
362 ?>
363
364 <script>
365 jQuery(document).ready(function($) {
366 $('#feedback-restore-<?php echo $post_id; ?>').click(function(e) {
367 e.preventDefault();
368 $.post(ajaxurl, {
369 action: 'grunion_ajax_spam',
370 post_id: '<?php echo $post_id; ?>',
371 make_it: 'publish',
372 sub_menu: jQuery('.subsubsub .current').attr('href'),
373 _ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
374 },
375 function(r) {
376 $('#post-<?php echo $post_id; ?>')
377 .css({backgroundColor: '#59C859'})
378 .fadeOut(350, function() {
379 $(this).remove();
380 $('.subsubsub').html(r);
381 });
382 }
383 );
384 });
385 });
386 </script>
387
388 <?php
389 } elseif ( $post->post_status == 'publish' ) {
390 echo '<span class="spam" id="feedback-spam-' . $post_id;
391 echo '"><a title="';
392 echo __( 'Mark this message as spam', 'jetpack' );
393 echo '" href="' . wp_nonce_url( admin_url( 'admin-ajax.php?post_id=' . $post_id . '&amp;action=spam' ), 'spam-feedback_' . $post_id );
394 echo '">Spam</a></span>';
395 echo ' | ';
396
397 echo '<span class="delete" id="feedback-trash-' . $post_id;
398 echo '">';
399 echo '<a class="submitdelete" title="' . esc_attr__( 'Trash', 'jetpack' );
400 echo '" href="' . get_delete_post_link( $post_id );
401 echo '">' . __( 'Trash', 'jetpack' ) . '</a></span>';
402
403 ?>
404
405 <script>
406 jQuery(document).ready( function($) {
407 $('#feedback-spam-<?php echo $post_id; ?>').click( function(e) {
408 e.preventDefault();
409 $.post( ajaxurl, {
410 action: 'grunion_ajax_spam',
411 post_id: '<?php echo $post_id; ?>',
412 make_it: 'spam',
413 sub_menu: jQuery('.subsubsub .current').attr('href'),
414 _ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
415 },
416 function( r ) {
417 $('#post-<?php echo $post_id; ?>')
418 .css( {backgroundColor:'#FF7979'} )
419 .fadeOut(350, function() {
420 $(this).remove();
421 $('.subsubsub').html(r);
422 });
423 });
424 });
425
426 $('#feedback-trash-<?php echo $post_id; ?>').click(function(e) {
427 e.preventDefault();
428 $.post(ajaxurl, {
429 action: 'grunion_ajax_spam',
430 post_id: '<?php echo $post_id; ?>',
431 make_it: 'trash',
432 sub_menu: jQuery('.subsubsub .current').attr('href'),
433 _ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
434 },
435 function(r) {
436 $('#post-<?php echo $post_id; ?>')
437 .css({backgroundColor: '#FF7979'})
438 .fadeOut(350, function() {
439 $(this).remove();
440 $('.subsubsub').html(r);
441 });
442 }
443 );
444 });
445 });
446 </script>
447
448 <?php
449 } elseif ( $post->post_status == 'spam' ) {
450 echo '<span class="unspam unapprove" id="feedback-ham-' . $post_id;
451 echo '"><a title="';
452 echo __( 'Mark this message as NOT spam', 'jetpack' );
453 echo '" href="">Not Spam</a></span>';
454 echo ' | ';
455
456 echo "<span class='delete' id='feedback-trash-" . $post_id;
457 echo "'> <a class='submitdelete' title='";
458 echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
459 echo "' href='" . get_delete_post_link( $post->ID, '', true );
460 echo "'>" . __( 'Delete Permanently', 'jetpack' ) . '</a></span>';
461 ?>
462
463 <script>
464 jQuery(document).ready( function($) {
465 $('#feedback-ham-<?php echo $post_id; ?>').click( function(e) {
466 e.preventDefault();
467 $.post( ajaxurl, {
468 action: 'grunion_ajax_spam',
469 post_id: '<?php echo $post_id; ?>',
470 make_it: 'ham',
471 sub_menu: jQuery('.subsubsub .current').attr('href'),
472 _ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
473 },
474 function( r ) {
475 $('#post-<?php echo $post_id; ?>')
476 .css( {backgroundColor:'#59C859'} )
477 .fadeOut(350, function() {
478 $(this).remove();
479 $('.subsubsub').html(r);
480 });
481 });
482 });
483 });
484 </script>
485
486 <?php
487 }
488 break;
489
490 case 'feedback_date':
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 }
513 return 0;
514 }
515
516 // take an array of field types from the form builder, and construct a shortcode form
517 // returns both the shortcode form, and HTML markup representing a preview of the form
518 function grunion_ajax_shortcode() {
519 check_ajax_referer( 'grunion_shortcode' );
520
521 if ( ! current_user_can( 'edit_posts' ) ) {
522 die( '-1' );
523 }
524
525 $attributes = array();
526
527 foreach ( array( 'subject', 'to' ) as $attribute ) {
528 if ( isset( $_POST[ $attribute ] ) && strlen( $_POST[ $attribute ] ) ) {
529 $attributes[ $attribute ] = stripslashes( $_POST[ $attribute ] );
530 }
531 }
532
533 if ( is_array( $_POST['fields'] ) ) {
534 $fields = stripslashes_deep( $_POST['fields'] );
535 usort( $fields, 'grunion_sort_objects' );
536
537 $field_shortcodes = array();
538
539 foreach ( $fields as $field ) {
540 $field_attributes = array();
541
542 if ( isset( $field['required'] ) && 'true' === $field['required'] ) {
543 $field_attributes['required'] = 'true';
544 }
545
546 foreach ( array( 'options', 'label', 'type' ) as $attribute ) {
547 if ( isset( $field[ $attribute ] ) ) {
548 $field_attributes[ $attribute ] = $field[ $attribute ];
549 }
550 }
551
552 $field_shortcodes[] = new Grunion_Contact_Form_Field( $field_attributes );
553 }
554 }
555
556 $grunion = new Grunion_Contact_Form( $attributes, $field_shortcodes );
557
558 die( "\n$grunion\n" );
559 }
560
561 // takes a post_id, extracts the contact-form shortcode from that post (if there is one), parses it,
562 // and constructs a json object representing its contents and attributes
563 function grunion_ajax_shortcode_to_json() {
564 global $post, $grunion_form;
565
566 check_ajax_referer( 'grunion_shortcode_to_json' );
567
568 if ( ! empty( $_POST['post_id'] ) && ! current_user_can( 'edit_post', $_POST['post_id'] ) ) {
569 die( '-1' );
570 } elseif ( ! current_user_can( 'edit_posts' ) ) {
571 die( '-1' );
572 }
573
574 if ( ! isset( $_POST['content'] ) || ! is_numeric( $_POST['post_id'] ) ) {
575 die( '-1' );
576 }
577
578 $content = stripslashes( $_POST['content'] );
579
580 // doesn't look like a post with a [contact-form] already.
581 if ( false === has_shortcode( $content, 'contact-form' ) ) {
582 die( '' );
583 }
584
585 $post = get_post( $_POST['post_id'] );
586
587 do_shortcode( $content );
588
589 $grunion = Grunion_Contact_Form::$last;
590
591 $out = array(
592 'to' => '',
593 'subject' => '',
594 'fields' => array(),
595 );
596
597 foreach ( $grunion->fields as $field ) {
598 $out['fields'][ $field->get_attribute( 'id' ) ] = $field->attributes;
599 }
600
601 $to = $grunion->get_attribute( 'to' );
602 $subject = $grunion->get_attribute( 'subject' );
603 foreach ( array( 'to', 'subject' ) as $attribute ) {
604 $value = $grunion->get_attribute( $attribute );
605 if ( isset( $grunion->defaults[ $attribute ] ) && $value == $grunion->defaults[ $attribute ] ) {
606 $value = '';
607 }
608 $out[ $attribute ] = $value;
609 }
610
611 die( json_encode( $out ) );
612 }
613
614
615 add_action( 'wp_ajax_grunion_shortcode', 'grunion_ajax_shortcode' );
616 add_action( 'wp_ajax_grunion_shortcode_to_json', 'grunion_ajax_shortcode_to_json' );
617
618
619 // process row-action spam/not spam clicks
620 add_action( 'wp_ajax_grunion_ajax_spam', 'grunion_ajax_spam' );
621 function grunion_ajax_spam() {
622 global $wpdb;
623
624 if ( empty( $_POST['make_it'] ) ) {
625 return;
626 }
627
628 $post_id = (int) $_POST['post_id'];
629 check_ajax_referer( 'grunion-post-status-' . $post_id );
630 if ( ! current_user_can( 'edit_page', $post_id ) ) {
631 wp_die( __( 'You are not allowed to manage this item.', 'jetpack' ) );
632 }
633
634 require_once dirname( __FILE__ ) . '/grunion-contact-form.php';
635
636 $current_menu = '';
637 if ( isset( $_POST['sub_menu'] ) && preg_match( '|post_type=feedback|', $_POST['sub_menu'] ) ) {
638 if ( preg_match( '|post_status=spam|', $_POST['sub_menu'] ) ) {
639 $current_menu = 'spam';
640 } elseif ( preg_match( '|post_status=trash|', $_POST['sub_menu'] ) ) {
641 $current_menu = 'trash';
642 } else {
643 $current_menu = 'messages';
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 );
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 );
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;
666 $blog_url = wp_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 } else {
688 $headers = 'From: "' . $content_fields['_feedback_author'] . '" <wordpress@' . $blog_url['host'] . ">\r\n";
689
690 if ( ! empty( $comment_author_email ) ) {
691 $reply_to_addr = $comment_author_email;
692 } elseif ( is_array( $to ) ) {
693 $reply_to_addr = $to[0];
694 }
695
696 if ( $reply_to_addr ) {
697 $headers .= 'Reply-To: "' . $content_fields['_feedback_author'] . '" <' . $reply_to_addr . ">\r\n";
698 }
699
700 $headers .= 'Content-Type: text/plain; charset="' . get_option( 'blog_charset' ) . '"';
701 }
702
703 /**
704 * Filters the subject of the email sent after a contact form submission.
705 *
706 * @module contact-form
707 *
708 * @since 3.0.0
709 *
710 * @param string $content_fields['_feedback_subject'] Feedback's subject line.
711 * @param array $content_fields['_feedback_all_fields'] Feedback's data from old fields.
712 */
713 $subject = apply_filters( 'contact_form_subject', $content_fields['_feedback_subject'], $content_fields['_feedback_all_fields'] );
714
715 Grunion_Contact_Form::wp_mail( $to, $subject, $message, $headers );
716 }
717 } elseif ( $_POST['make_it'] == 'publish' ) {
718 if ( ! current_user_can( $post_type_object->cap->delete_post, $post_id ) ) {
719 wp_die( __( 'You are not allowed to move this item out of the Trash.', 'jetpack' ) );
720 }
721
722 if ( ! wp_untrash_post( $post_id ) ) {
723 wp_die( __( 'Error in restoring from Trash.', 'jetpack' ) );
724 }
725 } elseif ( $_POST['make_it'] == 'trash' ) {
726 if ( ! current_user_can( $post_type_object->cap->delete_post, $post_id ) ) {
727 wp_die( __( 'You are not allowed to move this item to the Trash.', 'jetpack' ) );
728 }
729
730 if ( ! wp_trash_post( $post_id ) ) {
731 wp_die( __( 'Error in moving to Trash.', 'jetpack' ) );
732 }
733 }
734
735 $sql = "
736 SELECT post_status,
737 COUNT( * ) AS post_count
738 FROM `{$wpdb->posts}`
739 WHERE post_type = 'feedback'
740 GROUP BY post_status
741 ";
742 $status_count = (array) $wpdb->get_results( $sql, ARRAY_A );
743
744 $status = array();
745 $status_html = '';
746 foreach ( $status_count as $i => $row ) {
747 $status[ $row['post_status'] ] = $row['post_count'];
748 }
749
750 if ( isset( $status['publish'] ) ) {
751 $status_html .= '<li><a href="edit.php?post_type=feedback"';
752 if ( $current_menu == 'messages' ) {
753 $status_html .= ' class="current"';
754 }
755
756 $status_html .= '>' . __( 'Messages', 'jetpack' ) . ' <span class="count">';
757 $status_html .= '(' . number_format( $status['publish'] ) . ')';
758 $status_html .= '</span></a> |</li>';
759 }
760
761 if ( isset( $status['trash'] ) ) {
762 $status_html .= '<li><a href="edit.php?post_status=trash&amp;post_type=feedback"';
763 if ( $current_menu == 'trash' ) {
764 $status_html .= ' class="current"';
765 }
766
767 $status_html .= '>' . __( 'Trash', 'jetpack' ) . ' <span class="count">';
768 $status_html .= '(' . number_format( $status['trash'] ) . ')';
769 $status_html .= '</span></a>';
770 if ( isset( $status['spam'] ) ) {
771 $status_html .= ' |';
772 }
773 $status_html .= '</li>';
774 }
775
776 if ( isset( $status['spam'] ) ) {
777 $status_html .= '<li><a href="edit.php?post_status=spam&amp;post_type=feedback"';
778 if ( $current_menu == 'spam' ) {
779 $status_html .= ' class="current"';
780 }
781
782 $status_html .= '>' . __( 'Spam', 'jetpack' ) . ' <span class="count">';
783 $status_html .= '(' . number_format( $status['spam'] ) . ')';
784 $status_html .= '</span></a></li>';
785 }
786
787 echo $status_html;
788 exit;
789 }
790
791 /**
792 * Add the scripts that will add the "Check for Spam" button to the Feedbacks dashboard page.
793 */
794 function grunion_enable_spam_recheck() {
795 if ( ! defined( 'AKISMET_VERSION' ) ) {
796 return;
797 }
798
799 $screen = get_current_screen();
800
801 // Only add to feedback, only to non-spam view
802 if ( 'edit-feedback' != $screen->id || ( ! empty( $_GET['post_status'] ) && 'spam' == $_GET['post_status'] ) ) {
803 return;
804 }
805
806 // Add the scripts that handle the spam check event.
807 wp_register_script(
808 'grunion-admin',
809 Assets::get_file_url_for_environment(
810 '_inc/build/contact-form/js/grunion-admin.min.js',
811 'modules/contact-form/js/grunion-admin.js'
812 ),
813 array( 'jquery' )
814 );
815 wp_enqueue_script( 'grunion-admin' );
816
817 wp_enqueue_style( 'grunion.css' );
818
819 // Add the actual "Check for Spam" button.
820 add_action( 'admin_head', 'grunion_check_for_spam_button' );
821 }
822
823 add_action( 'admin_enqueue_scripts', 'grunion_enable_spam_recheck' );
824
825 /**
826 * Add the "Check for Spam" button to the Feedbacks dashboard page.
827 */
828 function grunion_check_for_spam_button() {
829 // Get HTML for the button
830 $button_html = get_submit_button(
831 __( 'Check for Spam', 'jetpack' ),
832 'secondary',
833 'jetpack-check-feedback-spam',
834 false,
835 array( 'class' => 'jetpack-check-feedback-spam' )
836 );
837 $button_html .= '<span class="jetpack-check-feedback-spam-spinner"></span>';
838
839 // Add the button next to the filter button via js
840 ?>
841 <script type="text/javascript">
842 jQuery( function( $ ) {
843 $( '#posts-filter #post-query-submit' ).after( '<?php echo $button_html; ?>' );
844 } );
845 </script>
846 <?php
847 }
848
849 /**
850 * Recheck all approved feedbacks for spam.
851 */
852 function grunion_recheck_queue() {
853 global $wpdb;
854
855 $query = 'post_type=feedback&post_status=publish';
856
857 if ( isset( $_POST['limit'], $_POST['offset'] ) ) {
858 $query .= '&posts_per_page=' . intval( $_POST['limit'] ) . '&offset=' . intval( $_POST['offset'] );
859 }
860
861 $approved_feedbacks = get_posts( $query );
862
863 foreach ( $approved_feedbacks as $feedback ) {
864 $meta = get_post_meta( $feedback->ID, '_feedback_akismet_values', true );
865
866 /**
867 * Filter whether the submitted feedback is considered as spam.
868 *
869 * @module contact-form
870 *
871 * @since 3.4.0
872 *
873 * @param bool false Is the submitted feedback spam? Default to false.
874 * @param array $meta Feedack values returned by the Akismet plugin.
875 */
876 $is_spam = apply_filters( 'jetpack_contact_form_is_spam', false, $meta );
877
878 if ( $is_spam ) {
879 wp_update_post(
880 array(
881 'ID' => $feedback->ID,
882 'post_status' => 'spam',
883 )
884 );
885 /** This action is already documented in modules/contact-form/admin.php */
886 do_action( 'contact_form_akismet', 'spam', $meta );
887 }
888 }
889
890 wp_send_json(
891 array(
892 'processed' => count( $approved_feedbacks ),
893 )
894 );
895 }
896
897 add_action( 'wp_ajax_grunion_recheck_queue', 'grunion_recheck_queue' );
898