Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 143 additions & 44 deletions gp-nested-forms/gpnf-auto-attach-child-files.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,68 +11,167 @@
* Plugin URI: http://gravitywiz.com/documentation/gravity-forms-nested-forms/
* Description: Auto-attach Uploaded Files from Child to Parent Notifications
* Author: Gravity Wiz
* Version: 0.1
* Version: 0.2
* Author URI: https://gravitywiz.com/
*/
add_filter( 'gform_notification', function( $notification, $form, $entry ) {
// Notes:
// - If notifications IDs are specified this snippet will only work for those specific forms.
// - If the parent form has upload fields, they will be attached instead of the child form's fields.
// - If neither of these conditions are present, child form uploads will be attached by default.
// Configuration:
// 1) Ensure that the parent form's notification has the "Attach uploaded fields to notification" checked.
// 2) [Optional] Modify the following array to limit the snippet to specific notification IDs.
// Notification IDs can be retrieved from the nid parameter in the URL when editing a notification.
// Example: $notification_ids = array( '5daaedb49dc32', '5dbce25cc21c2' );
$notification_ids = array();

if ( ! class_exists( 'GPNF_Entry' ) ) {
return $notification;
class GPNF_Auto_Attach_Child_Files {
/**
* The ID of the parent form to apply this to (optional).
*/
private $parent_form_id = null;

/**
* The IDs of the child form field to apply this to (optional).
*/
private $child_form_field_ids = null;

/**
* The IDs of the parent form notifications to which child uploads should be attached (optional).
*/
private $notification_ids = array();

/**
* The IDs of child form fields whose files should be attached to notifications (optional).
*/
private $child_form_upload_field_ids = array();

function __construct( $config = array() ) {
$this->set_config_data( $config );
$this->init_hooks();
}

$upload_fields = GFCommon::get_fields_by_type( $form, array( 'fileupload' ) );
function init_hooks() {
add_filter( 'gform_notification', array( $this, 'handle_notification_attachments' ), 10, 3 );
}

if ( ! empty( $notification_ids ) && ! in_array( $notification['id'], $notification_ids ) ) {
return $notification;
} else {
// If parent form has upload fields, rely on the notification's Attachments setting.
if ( ! empty( $upload_fields ) ) {
if ( ! rgar( $notification, 'enableAttachments', false ) ) {
return $notification;
}
function set_config_data( $config ) {
if ( ! empty( $config['parent_form_id'] ) ) {
$this->parent_form_id = $config['parent_form_id'];
}

if ( ! empty( $config['child_form_field_ids'] ) ) {
$this->child_form_field_ids = $config['child_form_field_ids'];
}

if ( ! empty( $config['notification_ids'] ) ) {
$this->notification_ids = $config['notification_ids'];
}

if ( ! empty( $config['child_form_upload_field_ids'] ) ) {
$this->child_form_upload_field_ids = $config['child_form_upload_field_ids'];
}
}

$attachments =& $notification['attachments'];
$parent_entry = new GPNF_Entry( $entry );
function handle_notification_attachments( $notification, $form, $entry ) {
if ( ! class_exists( 'GPNF_Entry' ) ) {
return $notification;
}

foreach ( $form['fields'] as $field ) {
if ( $this->parent_form_id && $form['id'] != $this->parent_form_id ) {
return $notification;
}

if ( $field->get_input_type() !== 'form' ) {
continue;
$upload_fields = GFCommon::get_fields_by_type( $form, array( 'fileupload' ) );

if ( ! $this->is_applicable_notification( $notification ) ) {
return $notification;
}

$upload_root = GFFormsModel::get_upload_root();
$upload_fields = GFCommon::get_fields_by_type( GFAPI::get_form( $field->gpnfForm ), array( 'fileupload' ) );
$child_entries = $parent_entry->get_child_entries( $field->id );
// If parent form has upload fields, rely on the notification's Attachments setting.
if ( ! empty( $upload_fields ) && ! rgar( $notification, 'enableAttachments', false ) ) {
return $notification;
}

foreach ( $child_entries as $child_entry ) {
foreach ( $upload_fields as $upload_field ) {
$attachments =& $notification['attachments'];
$parent_entry = new GPNF_Entry( $entry );

$attachment_urls = rgar( $child_entry, $upload_field->id );
if ( empty( $attachment_urls ) ) {
continue;
}
foreach ( $form['fields'] as $field ) {
if ( $field->get_input_type() !== 'form' ) {
continue;
}

$attachment_urls = $upload_field->multipleFiles ? json_decode( $attachment_urls, true ) : array( $attachment_urls );
if ( $this->child_form_field_ids && ! in_array( $field['id'], $this->child_form_field_ids ) ) {
continue;
}

$upload_fields = GFCommon::get_fields_by_type( GFAPI::get_form( $field->gpnfForm ), array( 'fileupload' ) );
$child_entries = $parent_entry->get_child_entries( $field->id );
$upload_root = GFFormsModel::get_upload_root();

foreach ( $child_entries as $child_entry ) {
foreach ( $upload_fields as $upload_field ) {
if ( ! $this->is_applicable_upload_field( $upload_field ) ) {
continue;
}

foreach ( $attachment_urls as $attachment_url ) {
$attachment_url = preg_replace( '|^(.*?)/gravity_forms/|', $upload_root, $attachment_url );
$attachments[] = $attachment_url;
$attachment_urls = rgar( $child_entry, $upload_field->id );
if ( empty( $attachment_urls ) ) {
continue;
}

$attachment_urls = $upload_field->multipleFiles ? json_decode( $attachment_urls, true ) : array( $attachment_urls );

foreach ( $attachment_urls as $attachment_url ) {
$attachment_url = preg_replace( '|^(.*?)/gravity_forms/|', $upload_root, $attachment_url );
$attachments[] = $attachment_url;
}
}
}
}

return $notification;
}

function is_applicable_notification( $notification ) {
return empty( $this->notification_ids ) || in_array( $notification['id'], $this->notification_ids );
}

function is_applicable_upload_field( $upload_field ) {
return empty( $this->child_form_upload_field_ids ) || in_array( $upload_field->id, $this->child_form_upload_field_ids );
}
}

/**
* Notes:
* - If notifications IDs are specified this snippet will only work for those specific forms.
* - If child form upload field IDs are specified, only files from those fields will be attached.
* - If the parent form has upload fields, they will be attached instead of the child form's fields.
* - If none of these conditions are present, child form uploads will be attached by default.
*
* Configuration:
*
* 1) Ensure that the parent form's notification has the "Attach uploaded fields to notification" checked.
* 2) [Optional] Modify one ore more of the following examples to limit the snippet to specific notification IDs or child form upload field IDs.
*
* 💡 Notification IDs can be retrieved from the nid parameter in the URL when editing a notification.
*/

# -------------------------------------------------
# Examples
# -------------------------------------------------

# Attach all child form uploads to all notifications.
// new GPNF_Auto_Attach_Child_Files();

# Attach all uploads from child forms to *only* the notification with id "63331f3fcf7f0".
// new GPNF_Auto_Attach_Child_Files( array(
// 'notification_ids' => array( '63331f3fcf7f0' ),
// ) );

# Attach child form upload from field with ID 3 to all notifications.
// new GPNF_Auto_Attach_Child_Files( array(
// 'child_form_upload_field_ids' => array( 3 ),
// ) );


# Attach child form upload from field with ID 3 to only notification with id "63331f3fcf7f0".
// new GPNF_Auto_Attach_Child_Files( array(
// 'notification_ids' => array( '63331f3fcf7f0' ),
// 'child_form_upload_field_ids' => array( 3 ),
// ) );

return $notification;
}, 10, 3 );
# Attach all child form uploads only on the child form with field ID of 2 on the parent form with ID of 1
// new GPNF_Auto_Attach_Child_Files( array(
// 'parent_form_id' => 1,
// 'child_form_field_ids' => array( 2 ),
// ) );