mariovalney / cf7-to-zapier

[WordPress Plugin] Use Contact Form 7 as a trigger to Webhooks.
https://wordpress.org/plugins/cf7-to-zapier
GNU General Public License v2.0
11 stars 10 forks source link

Is there a way to submit files? #3

Closed ptivy closed 6 years ago

ptivy commented 6 years ago

Hi,

I had a question regarding your Contact Form 7 to Zapier Application.

Is there a way to send file uploads to zapier by using your plugin? Thanks.

mariovalney commented 6 years ago

Hi! How are you?

There is already this topic about this question: https://wordpress.org/support/topic/send-files/.

I don’t know if is possible to send files to Zapier Webhook. But, if you can provide us with any link about sending files to Zapier (official documentation) we can try to add this feature into next version of the plugin.

For now, you can try change the data/header sended by plugin in the way I wrote in the support topic.

Regards and thanks for using our plugin.

ptivy commented 6 years ago

Is there a way to send the link that it creates in the WordPress media file?

Thanks,

Peter T 778.968.1842 | @PeterTivy

Director of Marketing – Voss Helmets vosshelmetsusa.com

mariovalney commented 6 years ago

Well... CF7 do not save the file in media directory.

As you can read here: https://contactform7.com/file-uploading-and-attachment/#How-your-uploaded-files-are-managed

(...) At this point, Contact Form 7 attaches the file to the mail and sends it. After these procedures, Contact Form 7 then removes the file from the temporary folder.

It happens in wpcf7_cleanup_upload_files filter.

But we can hack CF7 using the wpcf7_validate_file before CF7 to handle the uploaded file (should be before because it moves it when validating) and add a URL to send to Zapier using our filter ctz_get_data_from_contact_form :

<?php
// functions.php

add_filter( 'wpcf7_validate_file', 'ptivy_wpcf7_file_validation_filter', 1, 2 );
add_filter( 'wpcf7_validate_file*', 'ptivy_wpcf7_file_validation_filter', 1, 2 );

function ptivy_wpcf7_file_validation_filter( $result, $tag ) {
    global $ctz_uploaded_files;

    if ( ! is_array( $ctz_uploaded_files ) ) {
        $ctz_uploaded_files = array();
    }

    // Get the File
    $file = isset( $_FILES[ $tag->name ] ) ? $_FILES[ $tag->name ] : null;

    // Just to be sure
    if ( ! function_exists( 'wp_handle_upload' ) ) {
        require_once( ABSPATH . 'wp-admin/includes/file.php' );
    }

    // The uploaded $_FILE
    $file = $_FILES[ $tag->name ];

    /**
     * You can handle the file as you want.
     * Let's use 'wp_handle_upload' because it's easy
     *
     * Remember to validate, sanitize and everything else...
     */
    $upload_overrides = array( 'test_form' => false );

    $uploaded_file = wp_handle_upload( $file, $upload_overrides );

    if ( $uploaded_file && ! isset( $uploaded_file['error'] ) ) {
        $ctz_uploaded_files[ $tag->name ] = $uploaded_file['url'];
    } else {
        $ctz_uploaded_files[ $tag->name ] = '';

        // You can check the error:
        // $uploaded_file['error'];
    }

    return $result;
}

// Add File data
add_filter( 'ctz_get_data_from_contact_form', 'ptivy_add_files_to_data', 10, 2 );
function ptivy_add_files_to_data( $data, $contact_form ) {
    global $ctz_uploaded_files;

    $tags = $contact_form->scan_form_tags();

    foreach ( $tags as $tag ) {
        if ( empty( $tag->name ) || $tag->basetype != 'file' ) continue;

        $data[ $tag->name ] = ( empty( $ctz_uploaded_files[ $tag->name ] ) ) ? '' : $ctz_uploaded_files[ $tag->name ];
    }

    return $data;
}

I hope this can help you.

mariovalney commented 6 years ago

Closed due to inactivity. If you need more help, we'll be happy to help and reopen it.

ggirotto commented 5 years ago

Hi @mariovalney. Is this code still updated? I'm facing the same issue

mariovalney commented 5 years ago

I don't know for sure but probably yes.

Please, test and if not work tell me. I can take a look.

ggirotto commented 5 years ago

Just to understand a little better the situation, I found the wpcf7_file_validation_filter function inside modules/file.php, but the code differs a lot from what you've posted above. I just didn't get if the code from this file should be replaced by yours or you've made some changes from the code that was released at Feb, 2018?

That's how the function looks nowadays

function wpcf7_file_validation_filter( $result, $tag ) {
    $name = $tag->name;
    $id = $tag->get_id_option();

    $file = isset( $_FILES[$name] ) ? $_FILES[$name] : null;

    if ( $file['error'] and UPLOAD_ERR_NO_FILE != $file['error'] ) {
        $result->invalidate( $tag, wpcf7_get_message( 'upload_failed_php_error' ) );
        return $result;
    }

    if ( empty( $file['tmp_name'] ) and $tag->is_required() ) {
        $result->invalidate( $tag, wpcf7_get_message( 'invalid_required' ) );
        return $result;
    }

    if ( ! is_uploaded_file( $file['tmp_name'] ) ) {
        return $result;
    }

    /* File type validation */

    $file_type_pattern = wpcf7_acceptable_filetypes(
        $tag->get_option( 'filetypes' ), 'regex' );

    $file_type_pattern = '/\.(' . $file_type_pattern . ')$/i';

    if ( ! preg_match( $file_type_pattern, $file['name'] ) ) {
        $result->invalidate( $tag,
            wpcf7_get_message( 'upload_file_type_invalid' ) );
        return $result;
    }

    /* File size validation */

    $allowed_size = 1048576; // default size 1 MB

    if ( $file_size_a = $tag->get_option( 'limit' ) ) {
        $limit_pattern = '/^([1-9][0-9]*)([kKmM]?[bB])?$/';

        foreach ( $file_size_a as $file_size ) {
            if ( preg_match( $limit_pattern, $file_size, $matches ) ) {
                $allowed_size = (int) $matches[1];

                if ( ! empty( $matches[2] ) ) {
                    $kbmb = strtolower( $matches[2] );

                    if ( 'kb' == $kbmb ) {
                        $allowed_size *= 1024;
                    } elseif ( 'mb' == $kbmb ) {
                        $allowed_size *= 1024 * 1024;
                    }
                }

                break;
            }
        }
    }

    if ( $file['size'] > $allowed_size ) {
        $result->invalidate( $tag, wpcf7_get_message( 'upload_file_too_large' ) );
        return $result;
    }

    wpcf7_init_uploads(); // Confirm upload dir
    $uploads_dir = wpcf7_upload_tmp_dir();
    $uploads_dir = wpcf7_maybe_add_random_dir( $uploads_dir );

    $filename = $file['name'];
    $filename = wpcf7_canonicalize( $filename, 'as-is' );
    $filename = wpcf7_antiscript_file_name( $filename );

    $filename = apply_filters( 'wpcf7_upload_file_name', $filename,
        $file['name'], $tag );

    $filename = wp_unique_filename( $uploads_dir, $filename );
    $new_file = path_join( $uploads_dir, $filename );

    if ( false === @move_uploaded_file( $file['tmp_name'], $new_file ) ) {
        $result->invalidate( $tag, wpcf7_get_message( 'upload_failed' ) );
        return $result;
    }

    // Make sure the uploaded file is only readable for the owner process
    chmod( $new_file, 0400 );

    if ( $submission = WPCF7_Submission::get_instance() ) {
        $submission->add_uploaded_file( $name, $new_file );
    }

    return $result;
}
mariovalney commented 5 years ago

No. Never touch the core of WordPress (or plugins or themes).

A filter is a way to change the behaviour of something. You can check more here and here.

In sumary, just add this code to your functions.php or create a new plugin.

ggirotto commented 5 years ago

Hi @mariovalney, sorry about the delayed response, but I still have no success with this. I'm currently using this plugin to upload multiple files: Multiline files upload, and just using your code above inside functions.php still send no URL to Zapier hook. Do you think this may have something with this other plugin? I mean, it works only with native CF7 upload system? Because the images are successfully going to the email, but the URL is not going through the Zapier Hook.

mariovalney commented 5 years ago

Yes. This code was tested with native CF7.

mariovalney commented 5 years ago

Hey guys! How are you?

The new version (2.0.0) supports file upload nativally. Please, update and remove your custom code as it's not needed.

And thanks for using our plugin.

carl-r-kelly commented 4 years ago

Hey @mariovalney sorry im a bit late to this, im looking to do the same thing as @ggirotto and im struggling to send multiple uploaded files using the Multiline files upload any help would be appreciated. the files get sent in the CF7 post request and then nothing gets passed to Zapier, i have read that the Multiline files upload plugin zips all of the files so i think we might just have to wait for that to finish then make the call to Zapier.