-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathgpnf-auto-attach-child-files.php
196 lines (160 loc) · 7.05 KB
/
gpnf-auto-attach-child-files.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<?php
/**
* Gravity Perks // Nested Forms // Auto-attach Uploaded Files from Child to Parent Notifications
* http://gravitywiz.com/documentation/gravity-forms-nested-forms/
*
* This snippet automatically attaches files uploaded onto the child form to the parent form notifications.
* If parent form has any File Upload fields, this snippet will rely on the "Attachments" setting for each parent notification.
* Otherwise, you must specify a list of notifications by ID to which child uploads should be attached.
*
* Plugin Name: GP Nested Forms - Auto-attach Uploaded Files from Child to Parent Notifications
* 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.3
* Author URI: https://gravitywiz.com/
*/
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();
}
function init_hooks() {
add_filter( 'gform_notification', array( $this, 'handle_notification_attachments' ), 10, 3 );
}
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'];
}
}
function handle_notification_attachments( $notification, $form, $entry ) {
if ( ! class_exists( 'GPNF_Entry' ) ) {
return $notification;
}
if ( $this->parent_form_id && $form['id'] != $this->parent_form_id ) {
return $notification;
}
$upload_fields = GFCommon::get_fields_by_type( $form, array( 'fileupload', 'image_hopper', 'image_hopper_post' ) );
if ( ! $this->is_applicable_notification( $notification ) ) {
return $notification;
}
// If parent form has upload fields, rely on the notification's Attachments setting.
if ( ! empty( $upload_fields ) && ! rgar( $notification, 'enableAttachments', false ) ) {
return $notification;
}
$attachments =& $notification['attachments'];
$parent_entry = new GPNF_Entry( $entry );
foreach ( $form['fields'] as $field ) {
if ( $field->get_input_type() !== 'form' ) {
continue;
}
if ( $this->child_form_field_ids && ! in_array( $field['id'], $this->child_form_field_ids ) ) {
continue;
}
$child_form = GFAPI::get_form( $field->gpnfForm );
$upload_fields = GFCommon::get_fields_by_type( $child_form, array( 'fileupload', 'image_hopper', 'image_hopper_post' ) );
$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;
}
/*
* Handle GP Media Library as handle_attachments won't work as expected for the parent form since
* these file upload fields do not exist in the parent form, and it will fail to find the IDs.
*/
if ( function_exists( 'gp_media_library' ) ) {
$gpml_file_ids = gp_media_library()->get_file_ids_by_entry( $child_entry, $child_form );
/*
* gp_media_library()->get_file_ids_by_entry() returns a structure with array<fieldId, array<fileId>>
* so this is a cheap way to flatten it and avoid PHP errors at the same time.
*/
$gpml_ids = ( count( $gpml_file_ids ) > 0 ) ? call_user_func_array( 'array_merge', $gpml_file_ids ) : array();
foreach ( $gpml_ids as $gpml_id ) {
$attachments[] = get_attached_file( $gpml_id );
}
}
$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 ),
// ) );
# 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 ),
// ) );