Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP ]Make form CPT un-public and have own preview functionality #158

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Use standard HTML5 markup to create fully functional forms for WordPress
- Multilingual support with Polylang
- Predefined static HTML forms via filter hooks
- Dynamic values, like %USER_EMAIL% for pre-populating form data
- Simple spam prevention

## Why?

Expand Down Expand Up @@ -157,6 +158,39 @@ function my_email_thankyou( $return ) {
}
```

### Filter: wplf_honeypot

By default, forms has honeypot field to detect spambots. Submissions detected as spam are saved as a trash, so false positives can be detected. WordPress core cleans the trash after 30 days from saving. Turn off dy returning false.

```php
add_filter( 'wplf_honeypot' , '__return_false' );
```

### Filter: wplf_honeypot_field_name

Change the honeypot default field name (send_hugs_to_developers) to something else. Use obsecure but obiviosuly fake name.

```php
add_filter( 'wplf_honeypot_field_name' , 'please_send_candy' );
```

### Filter: wplf_save_spam

Submissions marked as spam are saved as a trash, so false positives can be detected. WordPress core cleans the trash after 30 days from saving. Turn off dy returning false.

```php
add_filter( 'wplf_save_spam' , '__return_false' );
```

#### Form specific hooks

This filter supports form specific hooks:

- `wplf_{form_id}_save_spam`
- `wplf_{form_slug}_save_spam`

These filters are only applied for the target form by ID or slug.

### Filter: wplf_disable_validate_additional_fields

Dynamically generated fields are disabled by default. If you want to allow fields that are not set in the form to be submitted you can use this filter.
Expand Down
86 changes: 80 additions & 6 deletions classes/class-cpt-wplf-form.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public function __construct() {
add_filter( 'the_content', array( $this, 'use_shortcode_for_preview' ), 0 );
add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_frontend_script' ) );

add_filter( 'template_include', array( $this, 'template_include' ) );
add_filter( 'the_content', array( $this, 'the_content' ) );
add_filter( 'the_title', array( $this, 'wp_title' ) );

// default filters for the_content, but we don't want to use actual the_content
add_filter( 'wplf_form', 'convert_smilies' );
add_filter( 'wplf_form', 'convert_chars' );
Expand All @@ -63,6 +67,74 @@ public function __construct() {
add_action( 'before_delete_post', array( $this, 'clean_up_entry' ) );
}

public static function the_content( $content ) {
if ( ! isset( $_GET['wplf-form'] ) ) {
return $content;
}

if ( ! isset( $_GET['wplf-form'] )
|| ! is_numeric( $_GET['wplf-form'] )
|| 'publish' !== get_post_status( $_GET['wplf-form'] )
|| 'wplf-form' !== get_post_type( $_GET['wplf-form'] )
) {
return $content;
}

if ( ! current_user_can( 'edit_posts' ) ) {
return $content;
}

$content = '<p style="background:#f5f5f5;border-left:4px solid #dc3232;padding:6px 12px;">
<strong style="color:#dc3232;">
' . esc_html__( 'This form preview URL is not public and cannot be shared.', 'wp-libre-form' ) . '
</strong>
<br />
' . esc_html__( 'Non-logged in visitors will see a 404 error page instead.', 'wp-libre-form' ) . '
</p>';
$content .= do_shortcode( '[libre-form id="' . $_GET['wplf-form'] . '"]' );
return $content;
}

public static function wp_title( $title ) {
if ( ! isset( $_GET['wplf-form'] ) ) {
return $title;
}

if ( ! isset( $_GET['wplf-form'] )
|| ! is_numeric( $_GET['wplf-form'] )
|| 'publish' !== get_post_status( $_GET['wplf-form'] )
|| 'wplf-form' !== get_post_type( $_GET['wplf-form'] )
) {
return $title;
}

if ( ! current_user_can( 'edit_posts' ) ) {
return $title;
}

return __( 'Libre Form preview', 'wp-libre-form' );
}

public static function template_include( $template ) {
if ( ! isset( $_GET['wplf-form'] ) ) {
return $template;
}

if ( ! isset( $_GET['wplf-form'] )
|| ! is_numeric( $_GET['wplf-form'] )
|| 'publish' !== get_post_status( $_GET['wplf-form'] )
|| 'wplf-form' !== get_post_type( $_GET['wplf-form'] )
) {
return $template;
}

if ( ! current_user_can( 'edit_posts' ) ) {
return $template;
}

return get_page_template();
}

public static function register_cpt() {
$labels = array(
'name' => _x( 'Forms', 'post type general name', 'wp-libre-form' ),
Expand All @@ -82,8 +154,8 @@ public static function register_cpt() {

$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'public' => false,
'publicly_queryable' => false,
'exclude_from_search' => true,
'show_ui' => true,
'show_in_menu' => true,
Expand All @@ -93,9 +165,7 @@ public static function register_cpt() {
'has_archive' => false,
'hierarchical' => false,
'menu_position' => null,
'rewrite' => array(
'slug' => 'libre-forms',
),
'rewrite' => null,
'supports' => array(
'title',
'editor',
Expand Down Expand Up @@ -961,7 +1031,11 @@ class="libre-form libre-form-<?php echo esc_attr( $id . ' ' . $xclass ); ?>"
<input type="hidden" name="referrer" value="<?php the_permalink(); ?>">
<input type="hidden" name="_referrer_id" value="<?php echo esc_attr( get_the_id() ); ?>">
<?php endif; ?>
<input type="hidden" name="_form_id" value="<?php echo esc_attr( $id ); ?>">
<input type="hidden" name="_form_id" value="<?php echo esc_attr( $id ); ?>">
<?php if ( apply_filters( 'wplf_honeypot', true ) ) :
$honeypot_name = apply_filters( 'wplf_honeypot_field_name', 'send_hugs_to_developers' ); ?>
<input type="checkbox" name="<?php echo esc_attr( $honeypot_name ); ?>" value="1" style="display:none !important" tabindex="-1" autocomplete="off">
<?php endif; ?>
</form>
<?php
$output = ob_get_clean();
Expand Down
18 changes: 18 additions & 0 deletions classes/class-cpt-wplf-submission.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public function __construct() {
add_action( 'manage_posts_custom_column', array( $this, 'custom_columns_display_cpt' ), 10, 2 );
add_action( 'restrict_manage_posts', array( $this, 'form_filter_dropdown' ) );
add_filter( 'pre_get_posts', array( $this, 'filter_by_form' ) );
add_filter( 'display_post_states', array( $this, 'post_states' ), 10, 2 );

// add custom bulk actions
add_action( 'admin_notices', array( $this, 'wplf_submission_bulk_action_admin_notice' ) );
Expand Down Expand Up @@ -174,6 +175,23 @@ public function filter_by_form( $query ) {
return $query;
}

/**
* Show if message is marked as spam
*/
public static function post_states( $post_states, $post ) {
if ( 'wplf-submission' !== $post->post_type ) {
return $post_states;
}

$is_spam = get_post_meta( $post->ID, '_is_spam', true );

if ( $is_spam ) {
$post_states['wplf_is_spam'] = __( 'Spam', 'wp-libre-form' );
}

return $post_states;
}

public function register_wplf_submission_bulk_actions( $bulk_actions ) {
$bulk_actions['wplf_resend_copy'] = __( 'Resend email copy', 'wp-libre-form' );
return $bulk_actions;
Expand Down
35 changes: 34 additions & 1 deletion inc/wplf-ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ function wplf_ajax_submit_handler() {

$return = new stdClass();
$return->ok = 1;
$return->spam = false;
$return->spam_save = true;

// allow user to pre-process the post fields
do_action( 'wplf_pre_validate_submission' );
Expand All @@ -26,16 +28,33 @@ function wplf_ajax_submit_handler() {
$return->title = $form->post_title;
$return = apply_filters( "wplf_{$form->post_name}_validate_submission", $return );
$return = apply_filters( "wplf_{$form->ID}_validate_submission", $return );

// allow save spam setting filtering
$return->spam_save = apply_filters( 'wplf_save_spam', $return->spam_save );
$return->spam_save = apply_filters( "wplf_{$form->post_name}_save_spam", $return->spam_save );
$return->spam_save = apply_filters( "wplf_{$form->ID}_save_spam", $return->spam_save );
}

// if message is spam and spam messages should not be saved as trash, return error.
if ( $return->spam && ! $return->spam_save ) {
$return->ok = 0;
$return->error = __( 'Something went wrong, please try again.', 'wp-libre-form' );
}

if ( $return->ok ) {
// the title is the value of whatever the first field was in the form
$title_format = get_post_meta( $form->ID, '_wplf_title_format', true );

// change post status to trash if spam, WP core cleans trash every 30 days
$post_status = 'publish';
if ( $return->spam ) {
$post_status = 'trash';
}

// create submission post
$post_id = wp_insert_post( array(
'post_title' => '',
'post_status' => 'publish',
'post_status' => $post_status,
'post_type' => 'wplf-submission',
) );

Expand Down Expand Up @@ -73,6 +92,20 @@ function wplf_ajax_submit_handler() {
}
}

// bail if spam submission
if ( $return->spam ) {
// mark submission as a spam
add_post_meta( $post_id, '_is_spam', true, true );

// set return
$return->ok = 0;
$return->error = __( 'Something went wrong, please try again.', 'wp-libre-form' );

// respond with json
wp_send_json( $return );
wp_die();
}

// handle files
$uploads_path = wp_upload_dir();
$should_store_images_in_medialibrary = get_post_meta( $form->ID, '_wplf_media_library', true );
Expand Down
28 changes: 26 additions & 2 deletions inc/wplf-form-validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,35 @@ function wplf_validate_form_exists( $return ) {
return $return;
}

/**
* Check simple honeypot form spam
*/
add_filter( 'wplf_validate_submission', 'wplf_validate_check_honeypot', 2 );
function wplf_validate_check_honeypot( $return ) {
// skip this validation if submission has already failed
if ( ! $return->ok ) {
return $return;
}

// skip this validation if honeypot is turned off
if ( ! apply_filters( 'wplf_honeypot', true ) ) {
return $return;
}

// check if honeypot exists and has some value, mark as spam if true
$honeypot_name = apply_filters( 'wplf_honeypot_field_name', 'send_hugs_to_developers' );

if ( ! empty( $_POST[ $honeypot_name ] ) && true === (bool) $_POST[ $honeypot_name ] ) {
$return->spam = true;
}

return $return;
}

/**
* Check for required fields that are empty
*/
add_filter( 'wplf_validate_submission', 'wplf_validate_required_empty', 2 );
add_filter( 'wplf_validate_submission', 'wplf_validate_required_empty', 3 );
function wplf_validate_required_empty( $return ) {
// skip this validation if submission has already failed
if ( ! $return->ok ) {
Expand Down Expand Up @@ -68,7 +92,7 @@ function wplf_validate_required_empty( $return ) {
/**
* Check that submission has only fields that are set in form
*/
add_filter( 'wplf_validate_submission', 'wplf_validate_additional_fields', 3 );
add_filter( 'wplf_validate_submission', 'wplf_validate_additional_fields', 4 );
function wplf_validate_additional_fields( $return ) {
// skip this validation if submission has already failed
if ( ! $return->ok ) {
Expand Down
16 changes: 16 additions & 0 deletions views/preview.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/**
* @Author: Timi Wahalahti, Digitoimisto Dude Oy (https://dude.fi)
* @Date: 2019-02-02 17:14:05
* @Last Modified by: Timi Wahalahti
* @Last Modified time: 2019-02-02 17:19:38
*
* @package content
*/

get_header();

echo do_shortcode( '[libre-form id="' . $_GET['wplf-form'] . '"]' );

get_footer();