Skip to content

Instantly share code, notes, and snippets.

@damiencarbery
Last active December 19, 2022 13:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save damiencarbery/12963a78b1b80e3826417f7bd5f6df18 to your computer and use it in GitHub Desktop.
Save damiencarbery/12963a78b1b80e3826417f7bd5f6df18 to your computer and use it in GitHub Desktop.
Attach WooCommerce product docs to Contact Form 7 email - Create a brochure request form to send documents to a customer. https://www.damiencarbery.com/2022/12/attach-woocommerce-product-docs-to-contact-form-7-email/
<?php
/*
Plugin Name: Attach WooCommerce product docs to Contact Form 7 email
Plugin URI: https://www.damiencarbery.com/2022/12/attach-woocommerce-product-docs-to-contact-form-7-email/
Description: Create a brochure request form to send documents to a customer.
Author: Damien Carbery
Version: 0.1
WC tested up to: 7.2.0
*/
class AttachProductDocsToCF7Email {
private $cf7_form_id;
// Returns an instance of this class.
public static function get_instance() {
if ( null == self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
// Initialize the plugin variables.
public function __construct() {
$this->cf7_form_id = 79;
$this->init();
}
// Set up WordPress specfic actions.
public function init() {
// Verify that CMB2 plugin is active.
add_action( 'admin_notices', array( $this, 'verify_cmb2_active' ) );
// Add the metabox to add files to attach to the CF7 email.
add_action( 'cmb2_admin_init', array( $this, 'product_files_metabox' ) );
// Ensure the Description tab is present as it is needed by the_content filter.
add_filter( 'woocommerce_product_tabs', array( $this, 'add_description_tab' ), 20 );
// Add CF7 form to all product pages.
add_filter( 'the_content', array( $this, 'cf7_form_to_all_products' ) );
// Add files to email as an attachment
add_filter( 'wpcf7_mail_components', array( $this, 'attach_product_files' ), 10, 3 );
// Test the code - list the paths to the attachments on the product page.
//add_action( 'woocommerce_after_single_product_summary', array( $this, 'testing_product_docs_code' ), 30 );
}
// Verify that CMB2 plugin is active.
public function verify_cmb2_active() {
if ( ! defined( 'CMB2_LOADED' ) ) {
$plugin_data = get_plugin_data( __FILE__ );
$plugin_name = $plugin_data['Name'];
?>
<div class="notice notice-warning is-dismissible"><p>Plugin <strong><?php echo $plugin_name; ?></strong> requires <a href="https://wordpress.org/plugins/cmb2/">CMB2 plugin</a>.</p></div>
<?php
//error_log( 'CMB2 is not active.' );
}
}
// Add the metabox to add files to attach to the CF7 email.
public function product_files_metabox() {
$cmb = new_cmb2_box( array(
'id' => 'product_docs',
'title' => 'Product documentation',
'object_types' => array( 'product', ), // Limit to Product post type
'context' => 'side',
'priority' => 'high',
'show_names' => true, // Show field names on the left
) );
$cmb->add_field( array(
'desc' => 'Upload the files that will be sent to a customer on request.',
'id' => 'product_file_list',
'type' => 'file_list',
//'preview_size' => array( 100, 100 ), // Default: array( 50, 50 )
'query_args' => array( 'type' => array( 'application/pdf' ) ), // Set to only allow PDF attachments. This can be disabled or edited.
) );
}
private function get_product_file_list( $post_id ) {
return get_post_meta( $post_id, 'product_file_list', true );
}
// Add CF7 form to all product pages (though only if the product has attached files).
public function cf7_form_to_all_products( $content ) {
if ( class_exists( 'woocommerce' ) && is_product() && is_main_query() ) { // Check suggested by: https://pippinsplugins.com/playing-nice-with-the-content-filter/
$files = $this->get_product_file_list( get_the_ID() );
// Only add the form if the product has files attached.
if ( !empty( $files ) ) {
return $content . '[contact-form-7 id="' . $this->cf7_form_id . '" title="Product Enquiry"]';
}
}
return $content;
}
// Ensure the Description tab is present as it is needed by the_content filter.
public function add_description_tab( $tabs ) {
global $product, $post;
$files = $this->get_product_file_list( get_the_ID() );
// Do not add the tab if no files attached.
if ( empty( $files ) ) {
return $tabs;
}
// Description tab - add if there is no post content (i.e. if the Description is empty)
// because woocommerce_default_product_tabs() in woocommerce/includes/wc-template-functions.php
// excludes it if the post content is empty.
if ( ! $post->post_content ) {
$tabs['description'] = array(
'title' => __( 'Description', 'woocommerce' ),
'priority' => 10,
'callback' => 'woocommerce_product_description_tab',
);
}
return $tabs;
}
public function attach_product_files( $components, $current_cf7_form, $form_object ) {
// Verify that the we are processing the correct form.
if ( $this->cf7_form_id != $current_cf7_form->id() ) {
//error_log( 'Form ID mismatch: Is ' . $current_cf7_form->id() . '; expecting: ' . $this->cf7_form_id );
return $components;
}
// Ensure that a match was found.
if ( 1 !== preg_match( '/Product ID: (\d+)/m', $components[ 'body' ], $matches ) ) {
//error_log( 'Product ID regex error: ' . var_export( $components[ 'body' ], true ) );
return $components;
}
$product_id = $matches[1];
// Check that the matched product ID is a number.
if ( !is_numeric( $product_id ) || $product_id < 0 ) {
//error_log( 'Product ID error: ' . var_export( $product_id, true ) );
return $components;
}
//error_log( '$components: ' . var_export( $components, true ) );
$files = $this->get_product_file_list( $product_id );
// Return if no files attached.
if ( empty( $files ) ) {
return $components;
}
foreach ( (array) $files as $attachment_id => $attachment_url ) {
$components[ 'attachments' ][] = get_attached_file( $attachment_id );
}
//error_log( 'Attachments: ' . var_export( $components[ 'attachments' ], true ) );
// Remove the Product ID line.
$components[ 'body' ] = str_replace( 'Product ID: '.$product_id, '', $components[ 'body' ] );
return $components;
}
// Test the code - list the paths to the attachments on the product page.
public function testing_product_docs_code() {
$files = $this->get_product_file_list( get_the_ID() );
// Return if no files attached.
if ( empty( $files ) ) {
return;
}
echo '<pre>', var_export( $files, true ), '</pre>';
$product_docs = array();
foreach ( (array) $files as $attachment_id => $attachment_url ) {
$product_docs[] = get_attached_file( $attachment_id );
}
echo '<ul><li>', implode( '</li><li>', $product_docs, ), '</li></ul>';
}
}
$AttachProductDocsToCF7Email = new AttachProductDocsToCF7Email();
Subject:
Product documents: [product-title]
Body:
[your-name],
Please find attached the product information documents for [product-title].
Product ID: [product-id]
[dynamichidden product-id "CF7_get_post_var key='ID'"]
[dynamichidden product-title "CF7_get_post_var key='title'"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment