Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Create a new [wc_order] Contact Form 7 field tag which can only accept a valid WooCommerce order number.
<?php
/**
* Plugin Name: Contact Form 7 WooCommerce Order Select Field
* Description: Use the <code>[wc_order]</code> field in CF7 forms
* Author: Pierre Saïkali
* Author URI: https://saika.li
* Text Domain: cf7wcp
* Domain Path: /languages/
* Version: 1.0.0
*/
namespace CF7_Woocommerce_Order_Field;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Register the [wc_order] CF7 tag
*
* @return void
*/
function register_cf7_wc_order_tag() {
wpcf7_add_form_tag(
[ 'wc_order', 'wc_order*' ],
__NAMESPACE__ . '\\output_cf7_wc_order_tag',
[ 'name-attr' => true ]
);
}
add_action( 'wpcf7_init', __NAMESPACE__ . '\\register_cf7_wc_order_tag', 10, 0 );
/**
* Output the wc_order select field in a CF7 form
*
* @param object $tag
* @return string HTML to output
*/
function output_cf7_wc_order_tag( $tag ) {
if ( empty( $tag->name ) ) {
return '';
}
$validation_error = wpcf7_get_validation_error( $tag->name );
$class = wpcf7_form_controls_class( $tag->type, 'wpcf7-wc_order' );
$atts = [];
$value = (string) reset( $tag->values );
if ( $validation_error ) {
$class .= ' wpcf7-not-valid';
}
$atts['type'] = 'text';
$atts['name'] = $tag->name;
$atts['class'] = $tag->get_class_option( $class );
$atts['id'] = $tag->get_id_option();
$atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true );
$atts['autocomplete'] = $tag->get_option( 'autocomplete', '[-0-9a-zA-Z]+', true );
$atts['aria-invalid'] = $validation_error ? 'true' : 'false';
$atts['size'] = $tag->get_size_option( '10' );
$atts['maxlength'] = $tag->get_maxlength_option();
$atts['minlength'] = $tag->get_minlength_option();
if ( $tag->has_option( 'readonly' ) ) {
$atts['readonly'] = 'readonly';
}
if ( $tag->is_required() ) {
$atts['aria-required'] = 'true';
}
if ( $tag->has_option( 'placeholder' ) || $tag->has_option( 'watermark' ) ) {
$atts['placeholder'] = $value;
$value = '';
}
$value = $tag->get_default_option( $value );
$value = wpcf7_get_hangover( $tag->name, $value );
if ( isset( $_GET['wc_order' ] ) && ! empty( $_GET['wc_order' ]) ) {
$value = (int) $_GET['wc_order' ];
}
$atts['value'] = $value;
$atts = wpcf7_format_atts( $atts );
$html = sprintf(
'<span class="wpcf7-form-control-wrap %1$s"><input %2$s />%3$s</span>',
sanitize_html_class( $tag->name ),
$atts,
$validation_error
);
return $html;
}
/**
* Handle the validation for our WooCommerce select input field
*
* @param object $result
* @param object $tag
* @return object
*/
function validate_wc_order_input_value( $result, $tag ) {
$name = $tag->name;
if ( $tag->basetype !== 'wc_order' ) {
return $result;
}
$value = isset( $_POST[ $name ] ) ? trim( wp_unslash( strtr( (string) $_POST[$name], "\n", ' ' ) ) ) : '';
$value = strtoupper( $value );
// Check if value is empty?
if ( $tag->is_required() && empty( $value ) ) {
$result->invalidate( $tag, wpcf7_get_message( 'wc_order_field_required' ) );
}
// Check if we're dealing with a correct WooCommerce Order?
if ( ! $order = wc_get_order( $value ) ) {
$result->invalidate( $tag, wpcf7_get_message( 'wc_order_field_invalid' ) );
}
return $result;
}
add_filter( 'wpcf7_validate_wc_order', __NAMESPACE__ . '\\validate_wc_order_input_value', 10, 2 );
add_filter( 'wpcf7_validate_wc_order*', __NAMESPACE__ . '\\validate_wc_order_input_value', 10, 2 );
/**
* Extend CF7 error messages to be customized
*
* @param array $messages
* @return array
*/
function add_new_error_messages_for_wc_order_cf7_field( $messages ) {
$messages = array_merge(
$messages,
[
'wc_order_field_required' => [
'description' => __( 'The order number is missing.', 'cf7wcp' ),
'default' => __( 'You need to provide your order number.', 'cf7wcp' ),
],
'wc_order_field_invalid' => [
'description' => __( 'The selected order number is not valid.', 'cf7wcp' ),
'default' => __( 'Your order number is not valid.', 'cf7wcp' ),
],
]
);
return $messages;
}
add_filter( 'wpcf7_messages', __NAMESPACE__ . '\\add_new_error_messages_for_wc_order_cf7_field', 10, 1 );
/**
* Everytime a CF7 form is sent with a [wc_order] field selected,
* add a note on the corresponding WC_Order to save the feedback on the order.
* In my case, the order number field name is "your-order-number" and the user
* feedback field name is "your-feedback".
*
* @return void
*/
function update_wc_order_meta_after_form_submission() {
$submission = \WPCF7_Submission::get_instance();
if ( ! $submission ) {
return;
}
$posted_data = $submission->get_posted_data();
$order_id = (int) $posted_data['your-order-number'];
$order = wc_get_order( $order_id );
$order->add_order_note( sanitize_textarea_field( $posted_data['your-feedback'] ) );
$order->save();
}
add_action( 'wpcf7_mail_sent', __NAMESPACE__ . '\\update_wc_order_meta_after_form_submission' );
add_action( 'wpcf7_mail_failed', __NAMESPACE__ . '\\update_wc_order_meta_after_form_submission' );
@psaikali

This comment has been minimized.

Copy link
Owner Author

psaikali commented Dec 27, 2019

Full tutorial:

Tutorial (in French) available at https://mosaika.fr/creation-champ-formulaire-cf7/

@psaikali

This comment has been minimized.

Copy link
Owner Author

psaikali commented Dec 27, 2019

End result:

create-new-contact-form7-tag-field

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.