PluginProbe
Repeater Fields for Gravity Forms / 3.2.2
Repeater Fields for Gravity Forms v3.2.2
3.2.2 3.2.1 3.2.0 3.1.1 3.1.0 3.0.4 3.0.3 3.0.2 3.0.1 3.0.0 2.5.1 2.5.0 2.4.6 trunk 2.0.5 2.0.9 2.1.0 2.3.2 2.3.7 2.4.1 2.4.3 2.4.4 2.4.5
← All changes | fields/repeater_field.php +113 -5 3.1.0 → 3.2.2 View file →
@@ -114,12 +114,46 @@
114 114 {
115 115 if (is_array($value)) {
116 116 $value = '';
117 117 }
118 + $id = intval($this->id);
119 +
120 + // If resuming draft submission via Save & Continue and $value doesn't have saved_values,
121 + // attempt to restore from draft $entry if available
122 + if (empty($value) || (is_string($value) && strpos($value, 'saved_values') === false)) {
123 + if (!empty($entry) && is_array($entry) && !empty($entry[$id])) {
124 + $entry_data = maybe_unserialize($entry[$id]);
125 + if (is_array($entry_data) && !empty($entry_data)) {
126 + $decoded_value = !empty($value) ? json_decode($value, true) : array();
127 + if (!is_array($decoded_value)) {
128 + $decoded_value = array();
129 + }
130 + $row_ids = array_keys($entry_data);
131 + $decoded_value['count'] = count($row_ids);
132 + $decoded_value['id'] = $row_ids;
133 + $saved_rows = array();
134 + foreach ($entry_data as $row_id => $row_inputs) {
135 + if (is_array($row_inputs)) {
136 + foreach ($row_inputs as $in_name => $in_val) {
137 + if (is_array($in_val)) {
138 + foreach ($in_val as $sub_k => $sub_v) {
139 + $saved_rows[$row_id]['input_' . str_replace('.', '_', $sub_k) . '__' . $row_id] = $sub_v;
140 + }
141 + } else {
142 + $saved_rows[$row_id][$in_name] = $in_val;
143 + }
144 + }
145 + }
146 + }
147 + $decoded_value['saved_values'] = $saved_rows;
148 + $value = wp_json_encode($decoded_value);
149 + }
150 + }
151 + }
152 +
118 153 $is_entry_detail = $this->is_entry_detail();
119 154 $is_form_editor = $this->is_form_editor();
120 155 $form_id = $form['id'];
121 - $id = intval($this->id);
122 156 $field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
123 157 $size = $this->size;
124 158 $disabled_text = $is_form_editor ? "disabled='disabled'" : '';
125 159 $class_suffix = $is_entry_detail ? '_admin' : '';
@@ -145,10 +179,10 @@
145 179 $limit = 9999;
146 180 }
147 181 $limit = apply_filters("yeeaddons_gf_repeater_limit", 5, $limit);
148 182 $initial_rows = apply_filters("yeeaddons_gf_repeater_initial_rows", 1, $initial_rows);
149 - $input = "<input data-initial_rows_map_check='" . $this->repeater_initial_rows_map . "' data-initial_rows_map='input_{$form_id}_" . $this->repeater_initial_rows_map . "' data-map_id='field_" . $form_id . "_" . $id . "' name='input_{$id}' id='{$field_id}' type='{$html_input_type}' value='{$value}' class='{$class}' {$tabindex} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>";
150 - $html = '<div data-initial_rows_map_check="' . $this->repeater_initial_rows_map . '" class="repeater-field-warp-item-data" data-initial_rows="' . $initial_rows . '" data-limit="' . $limit . '" data-initial_rows_map="input_' . $form_id . '_' . $this->repeater_initial_rows_map . '" data-map_id="field_' . $form_id . '_' . $id . '">
183 + $input = "<input data-initial_rows_map_check='" . esc_attr($this->repeater_initial_rows_map) . "' data-initial_rows_map='input_{$form_id}_" . esc_attr($this->repeater_initial_rows_map) . "' data-map_id='field_" . $form_id . "_" . $id . "' name='input_{$id}' id='{$field_id}' type='{$html_input_type}' value='" . esc_attr($value) . "' class='{$class}' {$tabindex} {$placeholder_attribute} {$required_attribute} {$invalid_attribute} {$disabled_text}/>";
184 + $html = '<div data-initial_rows_map_check="' . esc_attr($this->repeater_initial_rows_map) . '" class="repeater-field-warp-item-data" data-initial_rows="' . $initial_rows . '" data-limit="' . $limit . '" data-initial_rows_map="input_' . $form_id . '_' . esc_attr($this->repeater_initial_rows_map) . '" data-map_id="field_' . $form_id . '_' . $id . '">
151 185 <div class="repeater-field-warp-item">
152 186 </div>
153 187 <div class="repeater-field-footer"><a href="#"" class="gf-repeater-field-button-add" >' . $repeater_add_button . '</a></div>
154 188 ' . $input . '
@@ -160,8 +194,72 @@
160 194 } else {
161 195 return sprintf("<div class='ginput_container'>%s</div>", $html);
162 196 }
163 197 }
198 + public static function save_draft_submission_values($submitted_values, $form)
199 + {
200 + if (empty($form['fields']) || !is_array($form['fields'])) {
201 + return $submitted_values;
202 + }
203 +
204 + foreach ($form['fields'] as $field) {
205 + if ($field->type !== 'repeater_end') {
206 + continue;
207 + }
208 +
209 + $raw_value = rgar($submitted_values, $field->id);
210 + if (empty($raw_value)) {
211 + $raw_value = rgpost('input_' . $field->id);
212 + }
213 +
214 + if (empty($raw_value)) {
215 + continue;
216 + }
217 +
218 + $repeater_data = is_array($raw_value) ? $raw_value : json_decode($raw_value, true);
219 + if (!is_array($repeater_data) || empty($repeater_data['id']) || !is_array($repeater_data['id'])) {
220 + continue;
221 + }
222 +
223 + // Capture all $_POST values for each repeater row
224 + $saved_rows = array();
225 + foreach ($repeater_data['id'] as $id_rand) {
226 + $row_data = array();
227 + foreach ($_POST as $post_key => $post_val) {
228 + if (strpos($post_key, '__' . $id_rand) !== false) {
229 + $row_data[$post_key] = wp_unslash($post_val);
230 + }
231 + }
232 +
233 + // Also check if any file was uploaded in this row
234 + $transient_keys = array();
235 + $unique_id = rgpost('gform_unique_id');
236 + if (!empty($unique_id)) {
237 + $transient_keys[] = 'gf_repeater_files_' . $unique_id;
238 + }
239 + $transient_keys[] = 'gf_repeater_files_' . $form['id'];
240 + $transient_keys[] = 'gf_repeater_files_1';
241 +
242 + foreach ($transient_keys as $t_key) {
243 + $transient_files = get_transient($t_key);
244 + if (is_array($transient_files)) {
245 + foreach ($transient_files as $tk => $tv) {
246 + if (strpos($tk, '__' . $id_rand) !== false && !empty($tv)) {
247 + $row_data[$tk] = $tv;
248 + }
249 + }
250 + }
251 + }
252 +
253 + $saved_rows[$id_rand] = $row_data;
254 + }
255 +
256 + $repeater_data['saved_values'] = $saved_rows;
257 + $submitted_values[$field->id] = wp_json_encode($repeater_data);
258 + }
259 +
260 + return $submitted_values;
261 + }
164 262 public static function remove_validation($form)
165 263 {
166 264 $zo = false;
167 265 $zo_datas = array();
@@ -257,17 +355,27 @@
257 355 } else {
258 356 $failedValidation = true;
259 357 }
260 358 break;
359 + case 'radio':
360 + if (rgblank($getInputData)) {
361 + $failedValidation = true;
362 + } elseif ($getInputData === 'gf_other_choice') {
363 + $other_val = rgpost($field . "_other__" . $id);
364 + if (rgblank($other_val)) {
365 + $failedValidation = true;
366 + }
367 + }
368 + break;
261 369 default:
262 370 if (is_array($getInputData)) {
263 371 foreach ($getInputData as $vl) {
264 - if (empty($vl)) {
372 + if (rgblank($vl)) {
265 373 $failedValidation = true;
266 374 }
267 375 }
268 376 } else {
269 - if (empty($getInputData)) {
377 + if (rgblank($getInputData)) {
270 378 $failedValidation = true;
271 379 }
272 380 }
273 381 break;