Complex classes like GravityView_Edit_Entry_Render often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use GravityView_Edit_Entry_Render, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class GravityView_Edit_Entry_Render { |
||
17 | |||
18 | /** |
||
19 | * @var GravityView_Edit_Entry |
||
20 | */ |
||
21 | protected $loader; |
||
22 | |||
23 | /** |
||
24 | * @var string String used to generate unique nonce for the entry/form/view combination. Allows access to edit page. |
||
25 | */ |
||
26 | static $nonce_key; |
||
27 | |||
28 | /** |
||
29 | * @since 1.9 |
||
30 | * @var string String used for check valid edit entry form submission. Allows saving edit form values. |
||
31 | */ |
||
32 | private static $nonce_field = 'is_gv_edit_entry'; |
||
33 | |||
34 | /** |
||
35 | * @since 1.9 |
||
36 | * @var bool Whether to allow save and continue functionality |
||
37 | */ |
||
38 | private static $supports_save_and_continue = false; |
||
39 | |||
40 | /** |
||
41 | * Gravity Forms entry array |
||
42 | * |
||
43 | * @var array |
||
44 | */ |
||
45 | public $entry; |
||
46 | |||
47 | /** |
||
48 | * Gravity Forms entry array (it won't get changed during this class lifecycle) |
||
49 | * @since 1.17.2 |
||
50 | * @var array |
||
51 | */ |
||
52 | private static $original_entry = array(); |
||
53 | |||
54 | /** |
||
55 | * Gravity Forms form array (GravityView modifies the content through this class lifecycle) |
||
56 | * |
||
57 | * @var array |
||
58 | */ |
||
59 | public $form; |
||
60 | |||
61 | /** |
||
62 | * Gravity Forms form array (it won't get changed during this class lifecycle) |
||
63 | * @since 1.16.2.1 |
||
64 | * @var array |
||
65 | */ |
||
66 | private static $original_form; |
||
67 | |||
68 | /** |
||
69 | * Gravity Forms form array after the form validation process |
||
70 | * @since 1.13 |
||
71 | * @var array |
||
72 | */ |
||
73 | public $form_after_validation = null; |
||
74 | |||
75 | /** |
||
76 | * Hold an array of GF field objects that have calculation rules |
||
77 | * @var array |
||
78 | */ |
||
79 | public $fields_with_calculation = array(); |
||
80 | |||
81 | /** |
||
82 | * Gravity Forms form id |
||
83 | * |
||
84 | * @var int |
||
85 | */ |
||
86 | public $form_id; |
||
87 | |||
88 | /** |
||
89 | * ID of the current view |
||
90 | * |
||
91 | * @var int |
||
92 | */ |
||
93 | public $view_id; |
||
94 | |||
95 | /** |
||
96 | * Updated entry is valid (GF Validation object) |
||
97 | * |
||
98 | * @var array |
||
99 | */ |
||
100 | public $is_valid = NULL; |
||
101 | |||
102 | 3 | function __construct( GravityView_Edit_Entry $loader ) { |
|
105 | |||
106 | 3 | function load() { |
|
107 | |||
108 | /** @define "GRAVITYVIEW_DIR" "../../../" */ |
||
109 | 3 | include_once( GRAVITYVIEW_DIR .'includes/class-admin-approve-entries.php' ); |
|
110 | |||
111 | // Don't display an embedded form when editing an entry |
||
112 | 3 | add_action( 'wp_head', array( $this, 'prevent_render_form' ) ); |
|
113 | 3 | add_action( 'wp_footer', array( $this, 'prevent_render_form' ) ); |
|
114 | |||
115 | // Stop Gravity Forms processing what is ours! |
||
116 | 3 | add_filter( 'wp', array( $this, 'prevent_maybe_process_form'), 8 ); |
|
117 | |||
118 | 3 | add_filter( 'gravityview_is_edit_entry', array( $this, 'is_edit_entry') ); |
|
119 | |||
120 | 3 | add_action( 'gravityview_edit_entry', array( $this, 'init' ) ); |
|
121 | |||
122 | // Disable conditional logic if needed (since 1.9) |
||
123 | 3 | add_filter( 'gform_has_conditional_logic', array( $this, 'manage_conditional_logic' ), 10, 2 ); |
|
124 | |||
125 | // Make sure GF doesn't validate max files (since 1.9) |
||
126 | 3 | add_filter( 'gform_plupload_settings', array( $this, 'modify_fileupload_settings' ), 10, 3 ); |
|
127 | |||
128 | // Add fields expected by GFFormDisplay::validate() |
||
129 | 3 | add_filter( 'gform_pre_validation', array( $this, 'gform_pre_validation') ); |
|
130 | |||
131 | // Fix multiselect value for GF 2.2 |
||
132 | 3 | add_filter( 'gravityview/edit_entry/field_value_multiselect', array( $this, 'fix_multiselect_value_serialization' ), 10, 3 ); |
|
133 | 3 | } |
|
134 | |||
135 | /** |
||
136 | * Don't show any forms embedded on a page when GravityView is in Edit Entry mode |
||
137 | * |
||
138 | * Adds a `__return_empty_string` filter on the Gravity Forms shortcode on the `wp_head` action |
||
139 | * And then removes it on the `wp_footer` action |
||
140 | * |
||
141 | * @since 1.16.1 |
||
142 | * |
||
143 | * @return void |
||
144 | */ |
||
145 | 1 | public function prevent_render_form() { |
|
146 | 1 | if( $this->is_edit_entry() ) { |
|
147 | 1 | if( 'wp_head' === current_filter() ) { |
|
148 | 1 | add_filter( 'gform_shortcode_form', '__return_empty_string' ); |
|
149 | } else { |
||
150 | 1 | remove_filter( 'gform_shortcode_form', '__return_empty_string' ); |
|
151 | } |
||
152 | } |
||
153 | 1 | } |
|
154 | |||
155 | /** |
||
156 | * Because we're mimicking being a front-end Gravity Forms form while using a Gravity Forms |
||
157 | * backend form, we need to prevent them from saving twice. |
||
158 | * @return void |
||
159 | */ |
||
160 | public function prevent_maybe_process_form() { |
||
161 | |||
162 | if( ! empty( $_POST ) ) { |
||
163 | do_action( 'gravityview_log_debug', 'GravityView_Edit_Entry[prevent_maybe_process_form] $_POSTed data (sanitized): ', esc_html( print_r( $_POST, true ) ) ); |
||
164 | } |
||
165 | |||
166 | if( $this->is_edit_entry_submission() ) { |
||
167 | remove_action( 'wp', array( 'RGForms', 'maybe_process_form'), 9 ); |
||
168 | remove_action( 'wp', array( 'GFForms', 'maybe_process_form'), 9 ); |
||
169 | } |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * Is the current page an Edit Entry page? |
||
174 | * @return boolean |
||
175 | */ |
||
176 | 4 | public function is_edit_entry() { |
|
177 | |||
178 | 4 | $is_edit_entry = GravityView_frontend::is_single_entry() && ! empty( $_GET['edit'] ); |
|
179 | |||
180 | 4 | return ( $is_edit_entry || $this->is_edit_entry_submission() ); |
|
181 | } |
||
182 | |||
183 | /** |
||
184 | * Is the current page an Edit Entry page? |
||
185 | * @since 1.9 |
||
186 | * @return boolean |
||
187 | */ |
||
188 | 3 | public function is_edit_entry_submission() { |
|
189 | 3 | return !empty( $_POST[ self::$nonce_field ] ); |
|
190 | } |
||
191 | |||
192 | /** |
||
193 | * When Edit entry view is requested setup the vars |
||
194 | */ |
||
195 | 3 | private function setup_vars() { |
|
196 | 3 | $gravityview_view = GravityView_View::getInstance(); |
|
197 | |||
198 | |||
199 | 3 | $entries = $gravityview_view->getEntries(); |
|
200 | 3 | self::$original_entry = $entries[0]; |
|
201 | 3 | $this->entry = $entries[0]; |
|
202 | |||
203 | 3 | self::$original_form = $gravityview_view->getForm(); |
|
204 | 3 | $this->form = $gravityview_view->getForm(); |
|
205 | 3 | $this->form_id = $gravityview_view->getFormId(); |
|
206 | 3 | $this->view_id = $gravityview_view->getViewId(); |
|
207 | |||
208 | 3 | self::$nonce_key = GravityView_Edit_Entry::get_nonce_key( $this->view_id, $this->form_id, $this->entry['id'] ); |
|
209 | 3 | } |
|
210 | |||
211 | |||
212 | /** |
||
213 | * Load required files and trigger edit flow |
||
214 | * |
||
215 | * Run when the is_edit_entry returns true. |
||
216 | * |
||
217 | * @param GravityView_View_Data $gv_data GravityView Data object |
||
218 | * @return void |
||
219 | */ |
||
220 | 4 | public function init( $gv_data ) { |
|
221 | |||
222 | 4 | require_once( GFCommon::get_base_path() . '/form_display.php' ); |
|
223 | 4 | require_once( GFCommon::get_base_path() . '/entry_detail.php' ); |
|
224 | |||
225 | 4 | $this->setup_vars(); |
|
226 | |||
227 | // Multiple Views embedded, don't proceed if nonce fails |
||
228 | 4 | $multiple_views = defined( 'GRAVITYVIEW_FUTURE_CORE_LOADED' ) ? gravityview()->views->count() > 1 : $gv_data->has_multiple_views(); |
|
229 | 4 | if( $multiple_views && ! wp_verify_nonce( $_GET['edit'], self::$nonce_key ) ) { |
|
230 | do_action('gravityview_log_error', __METHOD__ . ': Nonce validation failed for the Edit Entry request; returning' ); |
||
231 | return; |
||
232 | } |
||
233 | |||
234 | // Sorry, you're not allowed here. |
||
235 | 4 | if( false === $this->user_can_edit_entry( true ) ) { |
|
236 | 1 | do_action('gravityview_log_error', __METHOD__ . ': User is not allowed to edit this entry; returning', $this->entry ); |
|
237 | 1 | return; |
|
238 | } |
||
239 | |||
240 | 4 | $this->print_scripts(); |
|
241 | |||
242 | 4 | $this->process_save(); |
|
243 | |||
244 | 4 | $this->edit_entry_form(); |
|
245 | |||
246 | 4 | } |
|
247 | |||
248 | |||
249 | /** |
||
250 | * Force Gravity Forms to output scripts as if it were in the admin |
||
251 | * @return void |
||
252 | */ |
||
253 | 3 | private function print_scripts() { |
|
254 | 3 | $gravityview_view = GravityView_View::getInstance(); |
|
255 | |||
256 | 3 | wp_register_script( 'gform_gravityforms', GFCommon::get_base_url().'/js/gravityforms.js', array( 'jquery', 'gform_json', 'gform_placeholder', 'sack', 'plupload-all', 'gravityview-fe-view' ) ); |
|
257 | |||
258 | 3 | GFFormDisplay::enqueue_form_scripts($gravityview_view->getForm(), false); |
|
259 | |||
260 | // Sack is required for images |
||
261 | 3 | wp_print_scripts( array( 'sack', 'gform_gravityforms' ) ); |
|
262 | 3 | } |
|
263 | |||
264 | |||
265 | /** |
||
266 | * Process edit entry form save |
||
267 | */ |
||
268 | 4 | private function process_save() { |
|
269 | |||
270 | 4 | if( empty( $_POST ) || ! isset( $_POST['lid'] ) ) { |
|
271 | 4 | return; |
|
272 | } |
||
273 | |||
274 | // Make sure the entry, view, and form IDs are all correct |
||
275 | 4 | $valid = $this->verify_nonce(); |
|
276 | |||
277 | 4 | if( !$valid ) { |
|
278 | do_action('gravityview_log_error', __METHOD__ . ' Nonce validation failed.' ); |
||
279 | return; |
||
280 | } |
||
281 | |||
282 | 4 | if( $this->entry['id'] !== $_POST['lid'] ) { |
|
283 | do_action('gravityview_log_error', __METHOD__ . ' Entry ID did not match posted entry ID.' ); |
||
284 | return; |
||
285 | } |
||
286 | |||
287 | 4 | do_action('gravityview_log_debug', __METHOD__ . ': $_POSTed data (sanitized): ', esc_html( print_r( $_POST, true ) ) ); |
|
288 | |||
289 | 4 | $this->process_save_process_files( $this->form_id ); |
|
290 | |||
291 | 4 | $this->validate(); |
|
292 | |||
293 | 4 | if( $this->is_valid ) { |
|
294 | |||
295 | 4 | do_action('gravityview_log_debug', __METHOD__ . ': Submission is valid.' ); |
|
296 | |||
297 | /** |
||
298 | * @hack This step is needed to unset the adminOnly from form fields, to add the calculation fields |
||
299 | */ |
||
300 | 4 | $form = $this->form_prepare_for_save(); |
|
301 | |||
302 | /** |
||
303 | * @hack to avoid the capability validation of the method save_lead for GF 1.9+ |
||
304 | */ |
||
305 | 4 | unset( $_GET['page'] ); |
|
306 | |||
307 | 4 | $date_created = $this->entry['date_created']; |
|
308 | |||
309 | /** |
||
310 | * @hack to force Gravity Forms to use $read_value_from_post in GFFormsModel::save_lead() |
||
311 | * @since 1.17.2 |
||
312 | */ |
||
313 | 4 | unset( $this->entry['date_created'] ); |
|
314 | |||
315 | 4 | GFFormsModel::save_lead( $form, $this->entry ); |
|
316 | |||
317 | // Delete the values for hidden inputs |
||
318 | 4 | $this->unset_hidden_field_values(); |
|
319 | |||
320 | 4 | $this->entry['date_created'] = $date_created; |
|
321 | |||
322 | // Process calculation fields |
||
323 | 4 | $this->update_calculation_fields(); |
|
324 | |||
325 | // Perform actions normally performed after updating a lead |
||
326 | 4 | $this->after_update(); |
|
327 | |||
328 | /** |
||
329 | * Must be AFTER after_update()! |
||
330 | * @see https://github.com/gravityview/GravityView/issues/764 |
||
331 | */ |
||
332 | 4 | $this->maybe_update_post_fields( $form ); |
|
333 | |||
334 | /** |
||
335 | * @action `gravityview/edit_entry/after_update` Perform an action after the entry has been updated using Edit Entry |
||
336 | * @param array $form Gravity Forms form array |
||
337 | * @param string $entry_id Numeric ID of the entry that was updated |
||
338 | * @param GravityView_Edit_Entry_Render $this This object |
||
339 | */ |
||
340 | 4 | do_action( 'gravityview/edit_entry/after_update', $this->form, $this->entry['id'], $this ); |
|
341 | |||
342 | } else { |
||
343 | do_action('gravityview_log_error', __METHOD__ . ': Submission is NOT valid.', $this->entry ); |
||
344 | } |
||
345 | |||
346 | 4 | } // process_save |
|
347 | |||
348 | /** |
||
349 | * Delete the value of fields hidden by conditional logic when the entry is edited |
||
350 | * |
||
351 | * @uses GFFormsModel::update_lead_field_value() |
||
352 | * |
||
353 | * @since 1.17.4 |
||
354 | * |
||
355 | * @return void |
||
356 | */ |
||
357 | 3 | private function unset_hidden_field_values() { |
|
358 | 3 | global $wpdb; |
|
359 | |||
360 | 3 | $lead_detail_table = GFFormsModel::get_lead_details_table_name(); |
|
361 | 3 | $current_fields = $wpdb->get_results( $wpdb->prepare( "SELECT id, field_number FROM $lead_detail_table WHERE lead_id=%d", $this->entry['id'] ) ); |
|
362 | |||
363 | 3 | foreach ( $this->entry as $input_id => $field_value ) { |
|
364 | |||
365 | 3 | $field = RGFormsModel::get_field( $this->form, $input_id ); |
|
366 | |||
367 | // Reset fields that are hidden |
||
368 | // Don't pass $entry as fourth parameter; force using $_POST values to calculate conditional logic |
||
369 | 3 | if ( GFFormsModel::is_field_hidden( $this->form, $field, array(), NULL ) ) { |
|
370 | |||
371 | // List fields are stored as empty arrays when empty |
||
372 | $empty_value = $this->is_field_json_encoded( $field ) ? '[]' : ''; |
||
373 | |||
374 | $lead_detail_id = GFFormsModel::get_lead_detail_id( $current_fields, $input_id ); |
||
375 | |||
376 | GFFormsModel::update_lead_field_value( $this->form, $this->entry, $field, $lead_detail_id, $input_id, $empty_value ); |
||
377 | |||
378 | // Prevent the $_POST values of hidden fields from being used as default values when rendering the form |
||
379 | // after submission |
||
380 | $post_input_id = 'input_' . str_replace( '.', '_', $input_id ); |
||
381 | 3 | $_POST[ $post_input_id ] = ''; |
|
382 | } |
||
383 | } |
||
384 | 3 | } |
|
385 | |||
386 | /** |
||
387 | * Have GF handle file uploads |
||
388 | * |
||
389 | * Copy of code from GFFormDisplay::process_form() |
||
390 | * |
||
391 | * @param int $form_id |
||
392 | */ |
||
393 | 3 | private function process_save_process_files( $form_id ) { |
|
394 | |||
395 | //Loading files that have been uploaded to temp folder |
||
396 | 3 | $files = GFCommon::json_decode( stripslashes( RGForms::post( 'gform_uploaded_files' ) ) ); |
|
397 | 3 | if ( ! is_array( $files ) ) { |
|
398 | 2 | $files = array(); |
|
399 | } |
||
400 | |||
401 | /** |
||
402 | * Make sure the fileuploads are not overwritten if no such request was done. |
||
403 | * @since 1.20.1 |
||
404 | */ |
||
405 | 3 | add_filter( "gform_save_field_value_$form_id", array( $this, 'save_field_value' ), 99, 5 ); |
|
406 | |||
407 | 3 | RGFormsModel::$uploaded_files[ $form_id ] = $files; |
|
408 | 3 | } |
|
409 | |||
410 | /** |
||
411 | * Make sure the fileuploads are not overwritten if no such request was done. |
||
412 | * |
||
413 | * TO ONLY BE USED INTERNALLY; DO NOT DEVELOP ON; MAY BE REMOVED AT ANY TIME. |
||
414 | * |
||
415 | * @since 1.20.1 |
||
416 | * |
||
417 | * @param string $value Field value |
||
418 | * @param array $entry GF entry array |
||
419 | * @param GF_Field_FileUpload $field |
||
420 | * @param array $form GF form array |
||
421 | * @param string $input_id ID of the input being saved |
||
422 | * |
||
423 | * @return string |
||
424 | */ |
||
425 | 3 | public function save_field_value( $value = '', $entry = array(), $field = null, $form = array(), $input_id = '' ) { |
|
426 | |||
427 | 3 | if ( ! $field || $field->type != 'fileupload' ) { |
|
428 | 3 | return $value; |
|
429 | } |
||
430 | |||
431 | 1 | $input_name = 'input_' . str_replace( '.', '_', $input_id ); |
|
432 | |||
433 | 1 | if ( $field->multipleFiles ) { |
|
434 | if ( empty( $value ) ) { |
||
435 | return json_decode( $entry[ $input_id ], true ); |
||
436 | } |
||
437 | return $value; |
||
438 | } |
||
439 | |||
440 | /** No file is being uploaded. */ |
||
441 | 1 | if ( empty( $_FILES[ $input_name ]['name'] ) ) { |
|
442 | /** So return the original upload */ |
||
443 | 1 | return $entry[ $input_id ]; |
|
444 | } |
||
445 | |||
446 | 1 | return $value; |
|
447 | } |
||
448 | |||
449 | /** |
||
450 | * Remove max_files validation (done on gravityforms.js) to avoid conflicts with GravityView |
||
451 | * Late validation done on self::custom_validation |
||
452 | * |
||
453 | * @param $plupload_init array Plupload settings |
||
454 | * @param $form_id |
||
455 | * @param $instance |
||
456 | * @return mixed |
||
457 | */ |
||
458 | 1 | public function modify_fileupload_settings( $plupload_init, $form_id, $instance ) { |
|
459 | 1 | if( ! $this->is_edit_entry() ) { |
|
460 | return $plupload_init; |
||
461 | } |
||
462 | |||
463 | 1 | $plupload_init['gf_vars']['max_files'] = 0; |
|
464 | |||
465 | 1 | return $plupload_init; |
|
466 | } |
||
467 | |||
468 | |||
469 | /** |
||
470 | * Unset adminOnly and convert field input key to string |
||
471 | * @return array $form |
||
472 | */ |
||
473 | 3 | private function form_prepare_for_save() { |
|
474 | |||
475 | 3 | $form = $this->form; |
|
476 | |||
477 | /** @var GF_Field $field */ |
||
478 | 3 | foreach( $form['fields'] as $k => &$field ) { |
|
479 | |||
480 | /** |
||
481 | * Remove the fields with calculation formulas before save to avoid conflicts with GF logic |
||
482 | * @since 1.16.3 |
||
483 | * @var GF_Field $field |
||
484 | */ |
||
485 | 3 | if( $field->has_calculation() ) { |
|
486 | unset( $form['fields'][ $k ] ); |
||
487 | } |
||
488 | |||
489 | 3 | $field->adminOnly = false; |
|
490 | |||
491 | 3 | if( isset( $field->inputs ) && is_array( $field->inputs ) ) { |
|
492 | foreach( $field->inputs as $key => $input ) { |
||
493 | 3 | $field->inputs[ $key ][ 'id' ] = (string)$input['id']; |
|
494 | } |
||
495 | } |
||
496 | } |
||
497 | |||
498 | 3 | return $form; |
|
499 | } |
||
500 | |||
501 | 3 | private function update_calculation_fields() { |
|
502 | |||
503 | 3 | $form = self::$original_form; |
|
504 | 3 | $update = false; |
|
505 | |||
506 | // get the most up to date entry values |
||
507 | 3 | $entry = GFAPI::get_entry( $this->entry['id'] ); |
|
508 | |||
509 | 3 | if( !empty( $this->fields_with_calculation ) ) { |
|
510 | $update = true; |
||
511 | foreach ( $this->fields_with_calculation as $calc_field ) { |
||
512 | $inputs = $calc_field->get_entry_inputs(); |
||
513 | if ( is_array( $inputs ) ) { |
||
514 | foreach ( $inputs as $input ) { |
||
515 | $input_name = 'input_' . str_replace( '.', '_', $input['id'] ); |
||
516 | $entry[ strval( $input['id'] ) ] = RGFormsModel::prepare_value( $form, $calc_field, '', $input_name, $entry['id'], $entry ); |
||
517 | } |
||
518 | } else { |
||
519 | $input_name = 'input_' . str_replace( '.', '_', $calc_field->id); |
||
520 | $entry[ strval( $calc_field->id ) ] = RGFormsModel::prepare_value( $form, $calc_field, '', $input_name, $entry['id'], $entry ); |
||
521 | } |
||
522 | } |
||
523 | |||
524 | } |
||
525 | |||
526 | 3 | if( $update ) { |
|
527 | |||
528 | $return_entry = GFAPI::update_entry( $entry ); |
||
529 | |||
530 | if( is_wp_error( $return_entry ) ) { |
||
531 | do_action( 'gravityview_log_error', 'Updating the entry calculation fields failed', $return_entry ); |
||
532 | } else { |
||
533 | do_action( 'gravityview_log_debug', 'Updating the entry calculation fields succeeded' ); |
||
534 | } |
||
535 | } |
||
536 | 3 | } |
|
537 | |||
538 | /** |
||
539 | * Handle updating the Post Image field |
||
540 | * |
||
541 | * Sets a new Featured Image if configured in Gravity Forms; otherwise uploads/updates media |
||
542 | * |
||
543 | * @since 1.17 |
||
544 | * |
||
545 | * @uses GFFormsModel::media_handle_upload |
||
546 | * @uses set_post_thumbnail |
||
547 | * |
||
548 | * @param array $form GF Form array |
||
549 | * @param GF_Field $field GF Field |
||
550 | * @param string $field_id Numeric ID of the field |
||
551 | * @param string $value |
||
552 | * @param array $entry GF Entry currently being edited |
||
553 | * @param int $post_id ID of the Post being edited |
||
554 | * |
||
555 | * @return mixed|string |
||
556 | */ |
||
557 | 1 | private function update_post_image( $form, $field, $field_id, $value, $entry, $post_id ) { |
|
558 | |||
559 | 1 | $input_name = 'input_' . $field_id; |
|
560 | |||
561 | 1 | if ( !empty( $_FILES[ $input_name ]['name'] ) ) { |
|
562 | |||
563 | // We have a new image |
||
564 | |||
565 | $value = RGFormsModel::prepare_value( $form, $field, $value, $input_name, $entry['id'] ); |
||
566 | |||
567 | $ary = ! empty( $value ) ? explode( '|:|', $value ) : array(); |
||
568 | $img_url = rgar( $ary, 0 ); |
||
569 | |||
570 | $img_title = count( $ary ) > 1 ? $ary[1] : ''; |
||
571 | $img_caption = count( $ary ) > 2 ? $ary[2] : ''; |
||
572 | $img_description = count( $ary ) > 3 ? $ary[3] : ''; |
||
573 | |||
574 | $image_meta = array( |
||
575 | 'post_excerpt' => $img_caption, |
||
576 | 'post_content' => $img_description, |
||
577 | ); |
||
578 | |||
579 | //adding title only if it is not empty. It will default to the file name if it is not in the array |
||
580 | if ( ! empty( $img_title ) ) { |
||
581 | $image_meta['post_title'] = $img_title; |
||
582 | } |
||
583 | |||
584 | /** |
||
585 | * todo: As soon as \GFFormsModel::media_handle_upload becomes a public method, move this call to \GFFormsModel::media_handle_upload and remove the hack from this class. |
||
586 | * Note: the method became public in GF 1.9.17.7, but we don't require that version yet. |
||
587 | */ |
||
588 | require_once GRAVITYVIEW_DIR . 'includes/class-gravityview-gfformsmodel.php'; |
||
589 | $media_id = GravityView_GFFormsModel::media_handle_upload( $img_url, $post_id, $image_meta ); |
||
590 | |||
591 | // is this field set as featured image? |
||
592 | if ( $media_id && $field->postFeaturedImage ) { |
||
593 | set_post_thumbnail( $post_id, $media_id ); |
||
594 | } |
||
595 | |||
596 | 1 | } elseif ( !empty( $_POST[ $input_name ] ) && is_array( $value ) ) { |
|
597 | |||
598 | 1 | $img_url = $_POST[ $input_name ]; |
|
599 | |||
600 | 1 | $img_title = rgar( $_POST, $input_name.'_1' ); |
|
601 | 1 | $img_caption = rgar( $_POST, $input_name .'_4' ); |
|
602 | 1 | $img_description = rgar( $_POST, $input_name .'_7' ); |
|
603 | |||
604 | 1 | $value = ! empty( $img_url ) ? $img_url . "|:|" . $img_title . "|:|" . $img_caption . "|:|" . $img_description : ''; |
|
605 | |||
606 | 1 | if ( $field->postFeaturedImage ) { |
|
607 | |||
608 | $image_meta = array( |
||
609 | 1 | 'ID' => get_post_thumbnail_id( $post_id ), |
|
610 | 1 | 'post_title' => $img_title, |
|
611 | 1 | 'post_excerpt' => $img_caption, |
|
612 | 1 | 'post_content' => $img_description, |
|
613 | ); |
||
614 | |||
615 | // update image title, caption or description |
||
616 | 1 | wp_update_post( $image_meta ); |
|
617 | } |
||
618 | } else { |
||
619 | |||
620 | // if we get here, image was removed or not set. |
||
621 | $value = ''; |
||
622 | |||
623 | if ( $field->postFeaturedImage ) { |
||
624 | delete_post_thumbnail( $post_id ); |
||
625 | } |
||
626 | } |
||
627 | |||
628 | 1 | return $value; |
|
629 | } |
||
630 | |||
631 | /** |
||
632 | * Loop through the fields being edited and if they include Post fields, update the Entry's post object |
||
633 | * |
||
634 | * @param array $form Gravity Forms form |
||
635 | * |
||
636 | * @return void |
||
637 | */ |
||
638 | 3 | private function maybe_update_post_fields( $form ) { |
|
639 | |||
640 | 3 | if( empty( $this->entry['post_id'] ) ) { |
|
641 | 2 | do_action( 'gravityview_log_debug', __METHOD__ . ': This entry has no post fields. Continuing...' ); |
|
642 | 2 | return; |
|
643 | } |
||
644 | |||
645 | 1 | $post_id = $this->entry['post_id']; |
|
646 | |||
647 | // Security check |
||
648 | 1 | if( false === GVCommon::has_cap( 'edit_post', $post_id ) ) { |
|
649 | do_action( 'gravityview_log_error', 'The current user does not have the ability to edit Post #'.$post_id ); |
||
650 | return; |
||
651 | } |
||
652 | |||
653 | 1 | $update_entry = false; |
|
654 | |||
655 | 1 | $updated_post = $original_post = get_post( $post_id ); |
|
656 | |||
657 | 1 | foreach ( $this->entry as $field_id => $value ) { |
|
658 | |||
659 | 1 | $field = RGFormsModel::get_field( $form, $field_id ); |
|
660 | |||
661 | 1 | if( ! $field ) { |
|
662 | 1 | continue; |
|
663 | } |
||
664 | |||
665 | 1 | if( GFCommon::is_post_field( $field ) && 'post_category' !== $field->type ) { |
|
666 | |||
667 | // Get the value of the field, including $_POSTed value |
||
668 | 1 | $value = RGFormsModel::get_field_value( $field ); |
|
669 | |||
670 | // Use temporary entry variable, to make values available to fill_post_template() and update_post_image() |
||
671 | 1 | $entry_tmp = $this->entry; |
|
672 | 1 | $entry_tmp["{$field_id}"] = $value; |
|
673 | |||
674 | 1 | switch( $field->type ) { |
|
675 | |||
676 | 1 | case 'post_title': |
|
677 | $post_title = $value; |
||
678 | if( rgar( $form, 'postTitleTemplateEnabled' ) ) { |
||
679 | $post_title = $this->fill_post_template( $form['postTitleTemplate'], $form, $entry_tmp ); |
||
680 | } |
||
681 | $updated_post->post_title = $post_title; |
||
682 | $updated_post->post_name = $post_title; |
||
683 | unset( $post_title ); |
||
684 | break; |
||
685 | |||
686 | 1 | case 'post_content': |
|
687 | $post_content = $value; |
||
688 | if( rgar( $form, 'postContentTemplateEnabled' ) ) { |
||
689 | $post_content = $this->fill_post_template( $form['postContentTemplate'], $form, $entry_tmp, true ); |
||
690 | } |
||
691 | $updated_post->post_content = $post_content; |
||
692 | unset( $post_content ); |
||
693 | break; |
||
694 | 1 | case 'post_excerpt': |
|
695 | $updated_post->post_excerpt = $value; |
||
696 | break; |
||
697 | 1 | case 'post_tags': |
|
698 | wp_set_post_tags( $post_id, $value, false ); |
||
699 | break; |
||
700 | 1 | case 'post_category': |
|
701 | break; |
||
702 | 1 | case 'post_custom_field': |
|
703 | if( ! empty( $field->customFieldTemplateEnabled ) ) { |
||
704 | $value = $this->fill_post_template( $field->customFieldTemplate, $form, $entry_tmp, true ); |
||
705 | } |
||
706 | |||
707 | if ( $this->is_field_json_encoded( $field ) && ! is_string( $value ) ) { |
||
708 | $value = function_exists('wp_json_encode') ? wp_json_encode( $value ) : json_encode( $value ); |
||
709 | } |
||
710 | |||
711 | update_post_meta( $post_id, $field->postCustomFieldName, $value ); |
||
712 | break; |
||
713 | |||
714 | 1 | case 'post_image': |
|
715 | 1 | $value = $this->update_post_image( $form, $field, $field_id, $value, $this->entry, $post_id ); |
|
716 | 1 | break; |
|
717 | |||
718 | } |
||
719 | |||
720 | // update entry after |
||
721 | 1 | $this->entry["{$field_id}"] = $value; |
|
722 | |||
723 | 1 | $update_entry = true; |
|
724 | |||
725 | 1 | unset( $entry_tmp ); |
|
726 | } |
||
727 | |||
728 | } |
||
729 | |||
730 | 1 | if( $update_entry ) { |
|
731 | |||
732 | 1 | $return_entry = GFAPI::update_entry( $this->entry ); |
|
733 | |||
734 | 1 | if( is_wp_error( $return_entry ) ) { |
|
735 | do_action( 'gravityview_log_error', 'Updating the entry post fields failed', array( '$this->entry' => $this->entry, '$return_entry' => $return_entry ) ); |
||
736 | } else { |
||
737 | 1 | do_action( 'gravityview_log_debug', 'Updating the entry post fields for post #'.$post_id.' succeeded' ); |
|
738 | } |
||
739 | |||
740 | } |
||
741 | |||
742 | 1 | $return_post = wp_update_post( $updated_post, true ); |
|
743 | |||
744 | 1 | if( is_wp_error( $return_post ) ) { |
|
745 | $return_post->add_data( $updated_post, '$updated_post' ); |
||
746 | do_action( 'gravityview_log_error', 'Updating the post content failed', compact( 'updated_post', 'return_post' ) ); |
||
747 | } else { |
||
748 | 1 | do_action( 'gravityview_log_debug', 'Updating the post content for post #'.$post_id.' succeeded', $updated_post ); |
|
749 | } |
||
750 | 1 | } |
|
751 | |||
752 | /** |
||
753 | * Is the field stored in a JSON-encoded manner? |
||
754 | * |
||
755 | * @param GF_Field $field |
||
756 | * |
||
757 | * @return bool True: stored in DB json_encode()'d; False: not encoded |
||
758 | */ |
||
759 | private function is_field_json_encoded( $field ) { |
||
760 | |||
761 | $json_encoded = false; |
||
762 | |||
763 | $input_type = RGFormsModel::get_input_type( $field ); |
||
764 | |||
765 | // Only certain custom field types are supported |
||
766 | switch( $input_type ) { |
||
767 | case 'fileupload': |
||
768 | case 'list': |
||
769 | case 'multiselect': |
||
770 | $json_encoded = true; |
||
771 | break; |
||
772 | } |
||
773 | |||
774 | return $json_encoded; |
||
775 | } |
||
776 | |||
777 | /** |
||
778 | * Convert a field content template into prepared output |
||
779 | * |
||
780 | * @uses GravityView_GFFormsModel::get_post_field_images() |
||
781 | * |
||
782 | * @since 1.17 |
||
783 | * |
||
784 | * @param string $template The content template for the field |
||
785 | * @param array $form Gravity Forms form |
||
786 | * @param bool $do_shortcode Whether to process shortcode inside content. In GF, only run on Custom Field and Post Content fields |
||
787 | * |
||
788 | * @return string |
||
789 | */ |
||
790 | private function fill_post_template( $template, $form, $entry, $do_shortcode = false ) { |
||
791 | |||
792 | require_once GRAVITYVIEW_DIR . 'includes/class-gravityview-gfformsmodel.php'; |
||
793 | |||
794 | $post_images = GravityView_GFFormsModel::get_post_field_images( $form, $entry ); |
||
795 | |||
796 | //replacing post image variables |
||
797 | $output = GFCommon::replace_variables_post_image( $template, $post_images, $entry ); |
||
798 | |||
799 | //replacing all other variables |
||
800 | $output = GFCommon::replace_variables( $output, $form, $entry, false, false, false ); |
||
801 | |||
802 | // replace conditional shortcodes |
||
803 | if( $do_shortcode ) { |
||
804 | $output = do_shortcode( $output ); |
||
805 | } |
||
806 | |||
807 | return $output; |
||
808 | } |
||
809 | |||
810 | |||
811 | /** |
||
812 | * Perform actions normally performed after updating a lead |
||
813 | * |
||
814 | * @since 1.8 |
||
815 | * |
||
816 | * @see GFEntryDetail::lead_detail_page() |
||
817 | * |
||
818 | * @return void |
||
819 | */ |
||
820 | 3 | private function after_update() { |
|
821 | |||
822 | 3 | do_action( 'gform_after_update_entry', $this->form, $this->entry['id'], self::$original_entry ); |
|
823 | 3 | do_action( "gform_after_update_entry_{$this->form['id']}", $this->form, $this->entry['id'], self::$original_entry ); |
|
824 | |||
825 | // Re-define the entry now that we've updated it. |
||
826 | 3 | $entry = RGFormsModel::get_lead( $this->entry['id'] ); |
|
827 | |||
828 | 3 | $entry = GFFormsModel::set_entry_meta( $entry, $this->form ); |
|
829 | |||
830 | // We need to clear the cache because Gravity Forms caches the field values, which |
||
831 | // we have just updated. |
||
832 | 3 | foreach ($this->form['fields'] as $key => $field) { |
|
833 | 3 | GFFormsModel::refresh_lead_field_value( $entry['id'], $field->id ); |
|
834 | } |
||
835 | |||
836 | 3 | $this->entry = $entry; |
|
837 | 3 | } |
|
838 | |||
839 | |||
840 | /** |
||
841 | * Display the Edit Entry form |
||
842 | * |
||
843 | * @return void |
||
844 | */ |
||
845 | 3 | public function edit_entry_form() { |
|
846 | |||
847 | ?> |
||
848 | |||
849 | <div class="gv-edit-entry-wrapper"><?php |
||
850 | |||
851 | 3 | $javascript = gravityview_ob_include( GravityView_Edit_Entry::$file .'/partials/inline-javascript.php', $this ); |
|
852 | |||
853 | /** |
||
854 | * Fixes weird wpautop() issue |
||
855 | * @see https://github.com/katzwebservices/GravityView/issues/451 |
||
856 | */ |
||
857 | 3 | echo gravityview_strip_whitespace( $javascript ); |
|
858 | |||
859 | ?><h2 class="gv-edit-entry-title"> |
||
860 | <span><?php |
||
861 | |||
862 | /** |
||
863 | * @filter `gravityview_edit_entry_title` Modify the edit entry title |
||
864 | * @param string $edit_entry_title Modify the "Edit Entry" title |
||
865 | * @param GravityView_Edit_Entry_Render $this This object |
||
866 | */ |
||
867 | 3 | $edit_entry_title = apply_filters('gravityview_edit_entry_title', __('Edit Entry', 'gravityview'), $this ); |
|
868 | |||
869 | 3 | echo esc_attr( $edit_entry_title ); |
|
870 | ?></span> |
||
871 | </h2> |
||
872 | |||
873 | <?php $this->maybe_print_message(); ?> |
||
874 | |||
875 | <?php // The ID of the form needs to be `gform_{form_id}` for the pluploader ?> |
||
876 | |||
877 | <form method="post" id="gform_<?php echo $this->form_id; ?>" enctype="multipart/form-data"> |
||
878 | |||
879 | <?php |
||
880 | |||
881 | 3 | wp_nonce_field( self::$nonce_key, self::$nonce_key ); |
|
882 | |||
883 | 3 | wp_nonce_field( self::$nonce_field, self::$nonce_field, false ); |
|
884 | |||
885 | // Print the actual form HTML |
||
886 | 3 | $this->render_edit_form(); |
|
887 | |||
888 | ?> |
||
889 | 3 | </form> |
|
890 | |||
891 | <script> |
||
892 | gform.addFilter('gform_reset_pre_conditional_logic_field_action', function ( reset, formId, targetId, defaultValues, isInit ) { |
||
893 | return false; |
||
894 | }); |
||
895 | </script> |
||
896 | |||
897 | </div> |
||
898 | |||
899 | <?php |
||
900 | 3 | } |
|
901 | |||
902 | /** |
||
903 | * Display success or error message if the form has been submitted |
||
904 | * |
||
905 | * @uses GVCommon::generate_notice |
||
906 | * |
||
907 | * @since 1.16.2.2 |
||
908 | * |
||
909 | * @return void |
||
910 | */ |
||
911 | 3 | private function maybe_print_message() { |
|
912 | |||
913 | 3 | if( rgpost('action') === 'update' ) { |
|
914 | |||
915 | $back_link = esc_url( remove_query_arg( array( 'page', 'view', 'edit' ) ) ); |
||
916 | |||
917 | if( ! $this->is_valid ){ |
||
918 | |||
919 | // Keeping this compatible with Gravity Forms. |
||
920 | $validation_message = "<div class='validation_error'>" . __('There was a problem with your submission.', 'gravityview') . " " . __('Errors have been highlighted below.', 'gravityview') . "</div>"; |
||
921 | $message = apply_filters("gform_validation_message_{$this->form['id']}", apply_filters("gform_validation_message", $validation_message, $this->form), $this->form); |
||
922 | |||
923 | echo GVCommon::generate_notice( $message , 'gv-error' ); |
||
924 | |||
925 | } else { |
||
926 | $entry_updated_message = sprintf( esc_attr__('Entry Updated. %sReturn to Entry%s', 'gravityview'), '<a href="'. $back_link .'">', '</a>' ); |
||
927 | |||
928 | /** |
||
929 | * @filter `gravityview/edit_entry/success` Modify the edit entry success message (including the anchor link) |
||
930 | * @since 1.5.4 |
||
931 | * @param string $entry_updated_message Existing message |
||
932 | * @param int $view_id View ID |
||
933 | * @param array $entry Gravity Forms entry array |
||
934 | * @param string $back_link URL to return to the original entry. @since 1.6 |
||
935 | */ |
||
936 | $message = apply_filters( 'gravityview/edit_entry/success', $entry_updated_message , $this->view_id, $this->entry, $back_link ); |
||
937 | |||
938 | echo GVCommon::generate_notice( $message ); |
||
939 | } |
||
940 | |||
941 | } |
||
942 | 3 | } |
|
943 | |||
944 | /** |
||
945 | * Display the Edit Entry form in the original Gravity Forms format |
||
946 | * |
||
947 | * @since 1.9 |
||
948 | * |
||
949 | * @return void |
||
950 | */ |
||
951 | 3 | private function render_edit_form() { |
|
952 | |||
953 | /** |
||
954 | * @action `gravityview/edit-entry/render/before` Before rendering the Edit Entry form |
||
955 | * @since 1.17 |
||
956 | * @param GravityView_Edit_Entry_Render $this |
||
957 | */ |
||
958 | 3 | do_action( 'gravityview/edit-entry/render/before', $this ); |
|
959 | |||
960 | 3 | add_filter( 'gform_pre_render', array( $this, 'filter_modify_form_fields'), 5000, 3 ); |
|
961 | 3 | add_filter( 'gform_submit_button', array( $this, 'render_form_buttons') ); |
|
962 | 3 | add_filter( 'gform_disable_view_counter', '__return_true' ); |
|
963 | |||
964 | 3 | add_filter( 'gform_field_input', array( $this, 'verify_user_can_edit_post' ), 5, 5 ); |
|
965 | 3 | add_filter( 'gform_field_input', array( $this, 'modify_edit_field_input' ), 10, 5 ); |
|
966 | |||
967 | // We need to remove the fake $_GET['page'] arg to avoid rendering form as if in admin. |
||
968 | 3 | unset( $_GET['page'] ); |
|
969 | |||
970 | // TODO: Verify multiple-page forms |
||
971 | |||
972 | 3 | ob_start(); // Prevent PHP warnings possibly caused by prefilling list fields for conditional logic |
|
973 | |||
974 | 3 | $html = GFFormDisplay::get_form( $this->form['id'], false, false, true, $this->entry ); |
|
975 | |||
976 | 3 | ob_get_clean(); |
|
977 | |||
978 | 3 | remove_filter( 'gform_pre_render', array( $this, 'filter_modify_form_fields' ), 5000 ); |
|
979 | 3 | remove_filter( 'gform_submit_button', array( $this, 'render_form_buttons' ) ); |
|
980 | 3 | remove_filter( 'gform_disable_view_counter', '__return_true' ); |
|
981 | 3 | remove_filter( 'gform_field_input', array( $this, 'verify_user_can_edit_post' ), 5 ); |
|
982 | 3 | remove_filter( 'gform_field_input', array( $this, 'modify_edit_field_input' ), 10 ); |
|
983 | |||
984 | 3 | echo $html; |
|
985 | |||
986 | /** |
||
987 | * @action `gravityview/edit-entry/render/after` After rendering the Edit Entry form |
||
988 | * @since 1.17 |
||
989 | * @param GravityView_Edit_Entry_Render $this |
||
990 | */ |
||
991 | 3 | do_action( 'gravityview/edit-entry/render/after', $this ); |
|
992 | 3 | } |
|
993 | |||
994 | /** |
||
995 | * Display the Update/Cancel/Delete buttons for the Edit Entry form |
||
996 | * @since 1.8 |
||
997 | * @return string |
||
998 | */ |
||
999 | 3 | public function render_form_buttons() { |
|
1000 | 3 | return gravityview_ob_include( GravityView_Edit_Entry::$file .'/partials/form-buttons.php', $this ); |
|
1001 | } |
||
1002 | |||
1003 | |||
1004 | /** |
||
1005 | * Modify the form fields that are shown when using GFFormDisplay::get_form() |
||
1006 | * |
||
1007 | * By default, all fields will be shown. We only want the Edit Tab configured fields to be shown. |
||
1008 | * |
||
1009 | * @param array $form |
||
1010 | * @param boolean $ajax Whether in AJAX mode |
||
1011 | * @param array|string $field_values Passed parameters to the form |
||
1012 | * |
||
1013 | * @since 1.9 |
||
1014 | * |
||
1015 | * @return array Modified form array |
||
1016 | */ |
||
1017 | 3 | public function filter_modify_form_fields( $form, $ajax = false, $field_values = '' ) { |
|
1018 | |||
1019 | // In case we have validated the form, use it to inject the validation results into the form render |
||
1020 | 3 | if( isset( $this->form_after_validation ) ) { |
|
1021 | 3 | $form = $this->form_after_validation; |
|
1022 | } else { |
||
1023 | 3 | $form['fields'] = $this->get_configured_edit_fields( $form, $this->view_id ); |
|
1024 | } |
||
1025 | |||
1026 | 3 | $form = $this->filter_conditional_logic( $form ); |
|
1027 | |||
1028 | 3 | $form = $this->prefill_conditional_logic( $form ); |
|
1029 | |||
1030 | // for now we don't support Save and Continue feature. |
||
1031 | 3 | if( ! self::$supports_save_and_continue ) { |
|
1032 | 3 | unset( $form['save'] ); |
|
1033 | } |
||
1034 | |||
1035 | 3 | return $form; |
|
1036 | } |
||
1037 | |||
1038 | /** |
||
1039 | * When displaying a field, check if it's a Post Field, and if so, make sure the post exists and current user has edit rights. |
||
1040 | * |
||
1041 | * @since 1.16.2.2 |
||
1042 | * |
||
1043 | * @param string $field_content Always empty. Returning not-empty overrides the input. |
||
1044 | * @param GF_Field $field |
||
1045 | * @param string|array $value If array, it's a field with multiple inputs. If string, single input. |
||
1046 | * @param int $lead_id Lead ID. Always 0 for the `gform_field_input` filter. |
||
1047 | * @param int $form_id Form ID |
||
1048 | * |
||
1049 | * @return string If error, the error message. If no error, blank string (modify_edit_field_input() runs next) |
||
1050 | */ |
||
1051 | 3 | public function verify_user_can_edit_post( $field_content = '', $field, $value, $lead_id = 0, $form_id ) { |
|
1052 | |||
1053 | 3 | if( GFCommon::is_post_field( $field ) ) { |
|
1054 | |||
1055 | 1 | $message = null; |
|
1056 | |||
1057 | // First, make sure they have the capability to edit the post. |
||
1058 | 1 | if( false === current_user_can( 'edit_post', $this->entry['post_id'] ) ) { |
|
1059 | |||
1060 | /** |
||
1061 | * @filter `gravityview/edit_entry/unsupported_post_field_text` Modify the message when someone isn't able to edit a post |
||
1062 | * @param string $message The existing "You don't have permission..." text |
||
1063 | */ |
||
1064 | $message = apply_filters('gravityview/edit_entry/unsupported_post_field_text', __('You don’t have permission to edit this post.', 'gravityview') ); |
||
1065 | |||
1066 | 1 | } elseif( null === get_post( $this->entry['post_id'] ) ) { |
|
1067 | /** |
||
1068 | * @filter `gravityview/edit_entry/no_post_text` Modify the message when someone is editing an entry attached to a post that no longer exists |
||
1069 | * @param string $message The existing "This field is not editable; the post no longer exists." text |
||
1070 | */ |
||
1071 | $message = apply_filters('gravityview/edit_entry/no_post_text', __('This field is not editable; the post no longer exists.', 'gravityview' ) ); |
||
1072 | } |
||
1073 | |||
1074 | 1 | if( $message ) { |
|
1075 | $field_content = sprintf('<div class="ginput_container ginput_container_' . $field->type . '">%s</div>', wpautop( $message ) ); |
||
1076 | } |
||
1077 | } |
||
1078 | |||
1079 | 3 | return $field_content; |
|
1080 | } |
||
1081 | |||
1082 | /** |
||
1083 | * |
||
1084 | * Fill-in the saved values into the form inputs |
||
1085 | * |
||
1086 | * @param string $field_content Always empty. Returning not-empty overrides the input. |
||
1087 | * @param GF_Field $field |
||
1088 | * @param string|array $value If array, it's a field with multiple inputs. If string, single input. |
||
1089 | * @param int $lead_id Lead ID. Always 0 for the `gform_field_input` filter. |
||
1090 | * @param int $form_id Form ID |
||
1091 | * |
||
1092 | * @return mixed |
||
1093 | */ |
||
1094 | 3 | public function modify_edit_field_input( $field_content = '', $field, $value, $lead_id = 0, $form_id ) { |
|
1095 | |||
1096 | 3 | $gv_field = GravityView_Fields::get_associated_field( $field ); |
|
1097 | |||
1098 | // If the form has been submitted, then we don't need to pre-fill the values, |
||
1099 | // Except for fileupload type and when a field input is overridden- run always!! |
||
1100 | if( |
||
1101 | 3 | ( $this->is_edit_entry_submission() && !in_array( $field->type, array( 'fileupload', 'post_image' ) ) ) |
|
1102 | 3 | && false === ( $gv_field && is_callable( array( $gv_field, 'get_field_input' ) ) ) |
|
1103 | && ! GFCommon::is_product_field( $field->type ) |
||
1104 | 3 | || ! empty( $field_content ) |
|
1105 | 3 | || in_array( $field->type, array( 'honeypot' ) ) |
|
1106 | ) { |
||
1107 | return $field_content; |
||
1108 | } |
||
1109 | |||
1110 | // SET SOME FIELD DEFAULTS TO PREVENT ISSUES |
||
1111 | 3 | $field->adminOnly = false; /** @see GFFormDisplay::get_counter_init_script() need to prevent adminOnly */ |
|
1112 | |||
1113 | 3 | $field_value = $this->get_field_value( $field ); |
|
1114 | |||
1115 | // Prevent any PHP warnings, like undefined index |
||
1116 | 3 | ob_start(); |
|
1117 | |||
1118 | 3 | $return = null; |
|
1119 | |||
1120 | /** @var GravityView_Field $gv_field */ |
||
1121 | 3 | if( $gv_field && is_callable( array( $gv_field, 'get_field_input' ) ) ) { |
|
1122 | 2 | $return = $gv_field->get_field_input( $this->form, $field_value, $this->entry, $field ); |
|
1123 | } else { |
||
1124 | 3 | $return = $field->get_field_input( $this->form, $field_value, $this->entry ); |
|
1125 | } |
||
1126 | |||
1127 | // If there was output, it's an error |
||
1128 | 3 | $warnings = ob_get_clean(); |
|
1129 | |||
1130 | 3 | if( !empty( $warnings ) ) { |
|
1131 | do_action( 'gravityview_log_error', __METHOD__ . $warnings, $field_value ); |
||
1132 | } |
||
1133 | |||
1134 | 3 | return $return; |
|
1135 | } |
||
1136 | |||
1137 | /** |
||
1138 | * Modify the value for the current field input |
||
1139 | * |
||
1140 | * @param GF_Field $field |
||
1141 | * |
||
1142 | * @return array|mixed|string |
||
1143 | */ |
||
1144 | 3 | private function get_field_value( $field ) { |
|
1145 | |||
1146 | /** |
||
1147 | * @filter `gravityview/edit_entry/pre_populate/override` Allow the pre-populated value to override saved value in Edit Entry form. By default, pre-populate mechanism only kicks on empty fields. |
||
1148 | * @param boolean True: override saved values; False: don't override (default) |
||
1149 | * @param $field GF_Field object Gravity Forms field object |
||
1150 | * @since 1.13 |
||
1151 | */ |
||
1152 | 3 | $override_saved_value = apply_filters( 'gravityview/edit_entry/pre_populate/override', false, $field ); |
|
1153 | |||
1154 | // We're dealing with multiple inputs (e.g. checkbox) but not time or date (as it doesn't store data in input IDs) |
||
1155 | 3 | if( isset( $field->inputs ) && is_array( $field->inputs ) && !in_array( $field->type, array( 'time', 'date' ) ) ) { |
|
1156 | |||
1157 | $field_value = array(); |
||
1158 | |||
1159 | // only accept pre-populated values if the field doesn't have any choice selected. |
||
1160 | $allow_pre_populated = $field->allowsPrepopulate; |
||
1161 | |||
1162 | foreach ( (array)$field->inputs as $input ) { |
||
1163 | |||
1164 | $input_id = strval( $input['id'] ); |
||
1165 | |||
1166 | if ( isset( $this->entry[ $input_id ] ) && ! gv_empty( $this->entry[ $input_id ], false, false ) ) { |
||
1167 | $field_value[ $input_id ] = 'post_category' === $field->type ? GFCommon::format_post_category( $this->entry[ $input_id ], true ) : $this->entry[ $input_id ]; |
||
1168 | $allow_pre_populated = false; |
||
1169 | } |
||
1170 | |||
1171 | } |
||
1172 | |||
1173 | $pre_value = $field->get_value_submission( array(), false ); |
||
1174 | |||
1175 | $field_value = ! $allow_pre_populated && ! ( $override_saved_value && !gv_empty( $pre_value, false, false ) ) ? $field_value : $pre_value; |
||
1176 | |||
1177 | } else { |
||
1178 | |||
1179 | 3 | $id = intval( $field->id ); |
|
1180 | |||
1181 | // get pre-populated value if exists |
||
1182 | 3 | $pre_value = $field->allowsPrepopulate ? GFFormsModel::get_parameter_value( $field->inputName, array(), $field ) : ''; |
|
1183 | |||
1184 | // saved field entry value (if empty, fallback to the pre-populated value, if exists) |
||
1185 | // or pre-populated value if not empty and set to override saved value |
||
1186 | 3 | $field_value = !gv_empty( $this->entry[ $id ], false, false ) && ! ( $override_saved_value && !gv_empty( $pre_value, false, false ) ) ? $this->entry[ $id ] : $pre_value; |
|
1187 | |||
1188 | // in case field is post_category but inputType is select, multi-select or radio, convert value into array of category IDs. |
||
1189 | 3 | if ( 'post_category' === $field->type && !gv_empty( $field_value, false, false ) ) { |
|
1190 | $categories = array(); |
||
1191 | foreach ( explode( ',', $field_value ) as $cat_string ) { |
||
1192 | $categories[] = GFCommon::format_post_category( $cat_string, true ); |
||
1193 | } |
||
1194 | $field_value = 'multiselect' === $field->get_input_type() ? $categories : implode( '', $categories ); |
||
1195 | } |
||
1196 | |||
1197 | } |
||
1198 | |||
1199 | // if value is empty get the default value if defined |
||
1200 | 3 | $field_value = $field->get_value_default_if_empty( $field_value ); |
|
1201 | |||
1202 | /** |
||
1203 | * @filter `gravityview/edit_entry/field_value` Change the value of an Edit Entry field, if needed |
||
1204 | * @since 1.11 |
||
1205 | * @since 1.20 Added third param |
||
1206 | * @param mixed $field_value field value used to populate the input |
||
1207 | * @param object $field Gravity Forms field object ( Class GF_Field ) |
||
1208 | * @param GravityView_Edit_Entry_Render $this Current object |
||
1209 | */ |
||
1210 | 3 | $field_value = apply_filters( 'gravityview/edit_entry/field_value', $field_value, $field, $this ); |
|
1211 | |||
1212 | /** |
||
1213 | * @filter `gravityview/edit_entry/field_value_{field_type}` Change the value of an Edit Entry field for a specific field type |
||
1214 | * @since 1.17 |
||
1215 | * @since 1.20 Added third param |
||
1216 | * @param mixed $field_value field value used to populate the input |
||
1217 | * @param GF_Field $field Gravity Forms field object |
||
1218 | * @param GravityView_Edit_Entry_Render $this Current object |
||
1219 | */ |
||
1220 | 3 | $field_value = apply_filters( 'gravityview/edit_entry/field_value_' . $field->type , $field_value, $field, $this ); |
|
1221 | |||
1222 | 3 | return $field_value; |
|
1223 | } |
||
1224 | |||
1225 | |||
1226 | // ---- Entry validation |
||
1227 | |||
1228 | /** |
||
1229 | * Add field keys that Gravity Forms expects. |
||
1230 | * |
||
1231 | * @see GFFormDisplay::validate() |
||
1232 | * @param array $form GF Form |
||
1233 | * @return array Modified GF Form |
||
1234 | */ |
||
1235 | 3 | public function gform_pre_validation( $form ) { |
|
1236 | |||
1237 | 3 | if( ! $this->verify_nonce() ) { |
|
1238 | return $form; |
||
1239 | } |
||
1240 | |||
1241 | // Fix PHP warning regarding undefined index. |
||
1242 | 3 | foreach ( $form['fields'] as &$field) { |
|
1243 | |||
1244 | // This is because we're doing admin form pretending to be front-end, so Gravity Forms |
||
1245 | // expects certain field array items to be set. |
||
1246 | 3 | foreach ( array( 'noDuplicates', 'adminOnly', 'inputType', 'isRequired', 'enablePrice', 'inputs', 'allowedExtensions' ) as $key ) { |
|
1247 | 3 | $field->{$key} = isset( $field->{$key} ) ? $field->{$key} : NULL; |
|
1248 | } |
||
1249 | |||
1250 | 3 | switch( RGFormsModel::get_input_type( $field ) ) { |
|
1251 | |||
1252 | /** |
||
1253 | * this whole fileupload hack is because in the admin, Gravity Forms simply doesn't update any fileupload field if it's empty, but it DOES in the frontend. |
||
1254 | * |
||
1255 | * What we have to do is set the value so that it doesn't get overwritten as empty on save and appears immediately in the Edit Entry screen again. |
||
1256 | * |
||
1257 | * @hack |
||
1258 | */ |
||
1259 | 3 | case 'fileupload': |
|
1260 | |||
1261 | // Set the previous value |
||
1262 | 1 | $entry = $this->get_entry(); |
|
1263 | |||
1264 | 1 | $input_name = 'input_'.$field->id; |
|
1265 | 1 | $form_id = $form['id']; |
|
1266 | |||
1267 | 1 | $value = NULL; |
|
1268 | |||
1269 | // Use the previous entry value as the default. |
||
1270 | 1 | if( isset( $entry[ $field->id ] ) ) { |
|
1271 | 1 | $value = $entry[ $field->id ]; |
|
1272 | } |
||
1273 | |||
1274 | // If this is a single upload file |
||
1275 | 1 | if( !empty( $_FILES[ $input_name ] ) && !empty( $_FILES[ $input_name ]['name'] ) ) { |
|
1276 | 1 | $file_path = GFFormsModel::get_file_upload_path( $form['id'], $_FILES[ $input_name ]['name'] ); |
|
1277 | 1 | $value = $file_path['url']; |
|
1278 | |||
1279 | } else { |
||
1280 | |||
1281 | // Fix PHP warning on line 1498 of form_display.php for post_image fields |
||
1282 | // Fix PHP Notice: Undefined index: size in form_display.php on line 1511 |
||
1283 | 1 | $_FILES[ $input_name ] = array('name' => '', 'size' => '' ); |
|
1284 | |||
1285 | } |
||
1286 | |||
1287 | 1 | if( rgar($field, "multipleFiles") ) { |
|
1288 | |||
1289 | // If there are fresh uploads, process and merge them. |
||
1290 | // Otherwise, use the passed values, which should be json-encoded array of URLs |
||
1291 | 1 | if( isset( GFFormsModel::$uploaded_files[$form_id][$input_name] ) ) { |
|
1292 | $value = empty( $value ) ? '[]' : $value; |
||
1293 | $value = stripslashes_deep( $value ); |
||
1294 | 1 | $value = GFFormsModel::prepare_value( $form, $field, $value, $input_name, $entry['id'], array()); |
|
1295 | } |
||
1296 | |||
1297 | } else { |
||
1298 | |||
1299 | // A file already exists when editing an entry |
||
1300 | // We set this to solve issue when file upload fields are required. |
||
1301 | 1 | GFFormsModel::$uploaded_files[ $form_id ][ $input_name ] = $value; |
|
1302 | |||
1303 | } |
||
1304 | |||
1305 | 1 | $this->entry[ $input_name ] = $value; |
|
1306 | 1 | $_POST[ $input_name ] = $value; |
|
1307 | |||
1308 | 1 | break; |
|
1309 | |||
1310 | 3 | case 'number': |
|
1311 | // Fix "undefined index" issue at line 1286 in form_display.php |
||
1312 | 1 | if( !isset( $_POST['input_'.$field->id ] ) ) { |
|
1313 | $_POST['input_'.$field->id ] = NULL; |
||
1314 | } |
||
1315 | 3 | break; |
|
1316 | } |
||
1317 | |||
1318 | } |
||
1319 | |||
1320 | 3 | return $form; |
|
1321 | } |
||
1322 | |||
1323 | |||
1324 | /** |
||
1325 | * Process validation for a edit entry submission |
||
1326 | * |
||
1327 | * Sets the `is_valid` object var |
||
1328 | * |
||
1329 | * @return void |
||
1330 | */ |
||
1331 | 4 | private function validate() { |
|
1332 | |||
1333 | /** |
||
1334 | * If using GF User Registration Add-on, remove the validation step, otherwise generates error when updating the entry |
||
1335 | * GF User Registration Add-on version > 3.x has a different class name |
||
1336 | * @since 1.16.2 |
||
1337 | */ |
||
1338 | 4 | if ( class_exists( 'GF_User_Registration' ) ) { |
|
1339 | 4 | remove_filter( 'gform_validation', array( GF_User_Registration::get_instance(), 'validate' ) ); |
|
1340 | } else if ( class_exists( 'GFUser' ) ) { |
||
1341 | remove_filter( 'gform_validation', array( 'GFUser', 'user_registration_validation' ) ); |
||
1342 | } |
||
1343 | |||
1344 | |||
1345 | /** |
||
1346 | * For some crazy reason, Gravity Forms doesn't validate Edit Entry form submissions. |
||
1347 | * You can enter whatever you want! |
||
1348 | * We try validating, and customize the results using `self::custom_validation()` |
||
1349 | */ |
||
1350 | 4 | add_filter( 'gform_validation_'. $this->form_id, array( $this, 'custom_validation' ), 10, 4); |
|
1351 | |||
1352 | // Needed by the validate funtion |
||
1353 | 4 | $failed_validation_page = NULL; |
|
1354 | 4 | $field_values = RGForms::post( 'gform_field_values' ); |
|
1355 | |||
1356 | // Prevent entry limit from running when editing an entry, also |
||
1357 | // prevent form scheduling from preventing editing |
||
1358 | 4 | unset( $this->form['limitEntries'], $this->form['scheduleForm'] ); |
|
1359 | |||
1360 | // Hide fields depending on Edit Entry settings |
||
1361 | 4 | $this->form['fields'] = $this->get_configured_edit_fields( $this->form, $this->view_id ); |
|
1362 | |||
1363 | 4 | $this->is_valid = GFFormDisplay::validate( $this->form, $field_values, 1, $failed_validation_page ); |
|
1364 | |||
1365 | 4 | remove_filter( 'gform_validation_'. $this->form_id, array( $this, 'custom_validation' ), 10 ); |
|
1366 | 4 | } |
|
1367 | |||
1368 | |||
1369 | /** |
||
1370 | * Make validation work for Edit Entry |
||
1371 | * |
||
1372 | * Because we're calling the GFFormDisplay::validate() in an unusual way (as a front-end |
||
1373 | * form pretending to be a back-end form), validate() doesn't know we _can't_ edit post |
||
1374 | * fields. This goes through all the fields and if they're an invalid post field, we |
||
1375 | * set them as valid. If there are still issues, we'll return false. |
||
1376 | * |
||
1377 | * @param [type] $validation_results [description] |
||
1378 | * @return [type] [description] |
||
1379 | */ |
||
1380 | 4 | public function custom_validation( $validation_results ) { |
|
1381 | |||
1382 | 4 | do_action('gravityview_log_debug', 'GravityView_Edit_Entry[custom_validation] Validation results: ', $validation_results ); |
|
1383 | |||
1384 | 4 | do_action('gravityview_log_debug', 'GravityView_Edit_Entry[custom_validation] $_POSTed data (sanitized): ', esc_html( print_r( $_POST, true ) ) ); |
|
1385 | |||
1386 | 4 | $gv_valid = true; |
|
1387 | |||
1388 | 4 | foreach ( $validation_results['form']['fields'] as $key => &$field ) { |
|
1389 | |||
1390 | 4 | $value = RGFormsModel::get_field_value( $field ); |
|
1391 | 4 | $field_type = RGFormsModel::get_input_type( $field ); |
|
1392 | |||
1393 | // Validate always |
||
1394 | switch ( $field_type ) { |
||
1395 | |||
1396 | |||
1397 | 4 | case 'fileupload' : |
|
1398 | 4 | case 'post_image': |
|
1399 | |||
1400 | // in case nothing is uploaded but there are already files saved |
||
1401 | 2 | if( !empty( $field->failed_validation ) && !empty( $field->isRequired ) && !empty( $value ) ) { |
|
1402 | $field->failed_validation = false; |
||
1403 | unset( $field->validation_message ); |
||
1404 | } |
||
1405 | |||
1406 | // validate if multi file upload reached max number of files [maxFiles] => 2 |
||
1407 | 2 | if( rgobj( $field, 'maxFiles') && rgobj( $field, 'multipleFiles') ) { |
|
1408 | |||
1409 | $input_name = 'input_' . $field->id; |
||
1410 | //uploaded |
||
1411 | $file_names = isset( GFFormsModel::$uploaded_files[ $validation_results['form']['id'] ][ $input_name ] ) ? GFFormsModel::$uploaded_files[ $validation_results['form']['id'] ][ $input_name ] : array(); |
||
1412 | |||
1413 | //existent |
||
1414 | $entry = $this->get_entry(); |
||
1415 | $value = NULL; |
||
1416 | if( isset( $entry[ $field->id ] ) ) { |
||
1417 | $value = json_decode( $entry[ $field->id ], true ); |
||
1418 | } |
||
1419 | |||
1420 | // count uploaded files and existent entry files |
||
1421 | $count_files = count( $file_names ) + count( $value ); |
||
1422 | |||
1423 | if( $count_files > $field->maxFiles ) { |
||
1424 | $field->validation_message = __( 'Maximum number of files reached', 'gravityview' ); |
||
1425 | $field->failed_validation = 1; |
||
1426 | $gv_valid = false; |
||
1427 | |||
1428 | // in case of error make sure the newest upload files are removed from the upload input |
||
1429 | GFFormsModel::$uploaded_files[ $validation_results['form']['id'] ] = null; |
||
1430 | } |
||
1431 | |||
1432 | } |
||
1433 | |||
1434 | |||
1435 | 2 | break; |
|
1436 | |||
1437 | } |
||
1438 | |||
1439 | // This field has failed validation. |
||
1440 | 4 | if( !empty( $field->failed_validation ) ) { |
|
1441 | |||
1442 | 1 | do_action( 'gravityview_log_debug', 'GravityView_Edit_Entry[custom_validation] Field is invalid.', array( 'field' => $field, 'value' => $value ) ); |
|
1443 | |||
1444 | switch ( $field_type ) { |
||
1445 | |||
1446 | // Captchas don't need to be re-entered. |
||
1447 | 1 | case 'captcha': |
|
1448 | |||
1449 | // Post Image fields aren't editable, so we un-fail them. |
||
1450 | 1 | case 'post_image': |
|
1451 | $field->failed_validation = false; |
||
1452 | unset( $field->validation_message ); |
||
1453 | break; |
||
1454 | |||
1455 | } |
||
1456 | |||
1457 | // You can't continue inside a switch, so we do it after. |
||
1458 | 1 | if( empty( $field->failed_validation ) ) { |
|
1459 | continue; |
||
1460 | } |
||
1461 | |||
1462 | // checks if the No Duplicates option is not validating entry against itself, since |
||
1463 | // we're editing a stored entry, it would also assume it's a duplicate. |
||
1464 | 1 | if( !empty( $field->noDuplicates ) ) { |
|
1465 | |||
1466 | $entry = $this->get_entry(); |
||
1467 | |||
1468 | // If the value of the entry is the same as the stored value |
||
1469 | // Then we can assume it's not a duplicate, it's the same. |
||
1470 | if( !empty( $entry ) && $value == $entry[ $field->id ] ) { |
||
1471 | //if value submitted was not changed, then don't validate |
||
1472 | $field->failed_validation = false; |
||
1473 | |||
1474 | unset( $field->validation_message ); |
||
1475 | |||
1476 | do_action('gravityview_log_debug', 'GravityView_Edit_Entry[custom_validation] Field not a duplicate; it is the same entry.', $entry ); |
||
1477 | |||
1478 | continue; |
||
1479 | } |
||
1480 | } |
||
1481 | |||
1482 | // if here then probably we are facing the validation 'At least one field must be filled out' |
||
1483 | 1 | if( GFFormDisplay::is_empty( $field, $this->form_id ) && empty( $field->isRequired ) ) { |
|
1484 | unset( $field->validation_message ); |
||
1485 | $field->validation_message = false; |
||
1486 | continue; |
||
1487 | } |
||
1488 | |||
1489 | 4 | $gv_valid = false; |
|
1490 | |||
1491 | } |
||
1492 | |||
1493 | } |
||
1494 | |||
1495 | 4 | $validation_results['is_valid'] = $gv_valid; |
|
1496 | |||
1497 | 4 | do_action('gravityview_log_debug', 'GravityView_Edit_Entry[custom_validation] Validation results.', $validation_results ); |
|
1498 | |||
1499 | // We'll need this result when rendering the form ( on GFFormDisplay::get_form ) |
||
1500 | 4 | $this->form_after_validation = $validation_results['form']; |
|
1501 | |||
1502 | 4 | return $validation_results; |
|
1503 | } |
||
1504 | |||
1505 | |||
1506 | /** |
||
1507 | * TODO: This seems to be hacky... we should remove it. Entry is set when updating the form using setup_vars()! |
||
1508 | * Get the current entry and set it if it's not yet set. |
||
1509 | * @return array Gravity Forms entry array |
||
1510 | */ |
||
1511 | 1 | public function get_entry() { |
|
1512 | |||
1513 | 1 | if( empty( $this->entry ) ) { |
|
1514 | // Get the database value of the entry that's being edited |
||
1515 | 1 | $this->entry = gravityview_get_entry( GravityView_frontend::is_single_entry() ); |
|
1516 | } |
||
1517 | |||
1518 | 1 | return $this->entry; |
|
1519 | } |
||
1520 | |||
1521 | |||
1522 | |||
1523 | // --- Filters |
||
1524 | |||
1525 | /** |
||
1526 | * Get the Edit Entry fields as configured in the View |
||
1527 | * |
||
1528 | * @since 1.8 |
||
1529 | * |
||
1530 | * @param int $view_id |
||
1531 | * |
||
1532 | * @return array Array of fields that are configured in the Edit tab in the Admin |
||
1533 | */ |
||
1534 | 4 | private function get_configured_edit_fields( $form, $view_id ) { |
|
1535 | |||
1536 | // Get all fields for form |
||
1537 | 4 | if ( defined( 'GRAVITYVIEW_FUTURE_CORE_LOADED' ) ) { |
|
1538 | 4 | if ( \GV\View::exists( $view_id ) ) { |
|
1539 | 4 | $view = \GV\View::by_id( $view_id ); |
|
1540 | 4 | $properties = $view->fields->as_configuration(); |
|
1541 | } |
||
1542 | } else { |
||
1543 | /** GravityView_View_Data is deprecated. */ |
||
1544 | $properties = GravityView_View_Data::getInstance()->get_fields( $view_id ); |
||
1545 | } |
||
1546 | |||
1547 | // If edit tab not yet configured, show all fields |
||
1548 | 4 | $edit_fields = !empty( $properties['edit_edit-fields'] ) ? $properties['edit_edit-fields'] : NULL; |
|
1549 | |||
1550 | // Hide fields depending on admin settings |
||
1551 | 4 | $fields = $this->filter_fields( $form['fields'], $edit_fields ); |
|
1552 | |||
1553 | // If Edit Entry fields are configured, remove adminOnly field settings. Otherwise, don't. |
||
1554 | 4 | $fields = $this->filter_admin_only_fields( $fields, $edit_fields, $form, $view_id ); |
|
1555 | |||
1556 | /** |
||
1557 | * @filter `gravityview/edit_entry/form_fields` Modify the fields displayed in Edit Entry form |
||
1558 | * @since 1.17 |
||
1559 | * @param GF_Field[] $fields Gravity Forms form fields |
||
1560 | * @param array|null $edit_fields Fields for the Edit Entry tab configured in the View Configuration |
||
1561 | * @param array $form GF Form array (`fields` key modified to have only fields configured to show in Edit Entry) |
||
1562 | * @param int $view_id View ID |
||
1563 | */ |
||
1564 | 4 | $fields = apply_filters( 'gravityview/edit_entry/form_fields', $fields, $edit_fields, $form, $view_id ); |
|
1565 | |||
1566 | 4 | return $fields; |
|
1567 | } |
||
1568 | |||
1569 | |||
1570 | /** |
||
1571 | * Filter area fields based on specified conditions |
||
1572 | * - This filter removes the fields that have calculation configured |
||
1573 | * |
||
1574 | * @uses GravityView_Edit_Entry::user_can_edit_field() Check caps |
||
1575 | * @access private |
||
1576 | * @param GF_Field[] $fields |
||
1577 | * @param array $configured_fields |
||
1578 | * @since 1.5 |
||
1579 | * @return array $fields |
||
1580 | */ |
||
1581 | 3 | private function filter_fields( $fields, $configured_fields ) { |
|
1629 | |||
1630 | /** |
||
1631 | * Override GF Form field properties with the ones defined on the View |
||
1632 | * @param GF_Field $field GF Form field object |
||
1633 | * @param array $field_setting GV field options |
||
1634 | * @since 1.5 |
||
1635 | * @return array|GF_Field |
||
1636 | */ |
||
1637 | private function merge_field_properties( $field, $field_setting ) { |
||
1660 | |||
1661 | /** |
||
1662 | * Remove fields that shouldn't be visible based on the Gravity Forms adminOnly field property |
||
1663 | * |
||
1664 | * @since 1.9.1 |
||
1665 | * |
||
1666 | * @param array|GF_Field[] $fields Gravity Forms form fields |
||
1667 | * @param array|null $edit_fields Fields for the Edit Entry tab configured in the View Configuration |
||
1668 | * @param array $form GF Form array |
||
1669 | * @param int $view_id View ID |
||
1670 | * |
||
1671 | * @return array Possibly modified form array |
||
1672 | */ |
||
1673 | 3 | private function filter_admin_only_fields( $fields = array(), $edit_fields = null, $form = array(), $view_id = 0 ) { |
|
1701 | |||
1702 | // --- Conditional Logic |
||
1703 | |||
1704 | /** |
||
1705 | * Conditional logic isn't designed to work with forms that already have content. When switching input values, |
||
1706 | * the dependent fields will be blank. |
||
1707 | * |
||
1708 | * Note: This is because GF populates a JavaScript variable with the input values. This is tough to filter at the input level; |
||
1709 | * via the `gform_field_value` filter; it requires lots of legwork. Doing it at the form level is easier. |
||
1710 | * |
||
1711 | * @since 1.17.4 |
||
1712 | * |
||
1713 | * @param array $form Gravity Forms array object |
||
1714 | * |
||
1715 | * @return array $form, modified to fix conditional |
||
1716 | */ |
||
1717 | 3 | function prefill_conditional_logic( $form ) { |
|
1765 | |||
1766 | /** |
||
1767 | * Remove the conditional logic rules from the form button and the form fields, if needed. |
||
1768 | * |
||
1769 | * @todo Merge with caller method |
||
1770 | * @since 1.9 |
||
1771 | * |
||
1772 | * @param array $form Gravity Forms form |
||
1773 | * @return array Modified form, if not using Conditional Logic |
||
1774 | */ |
||
1775 | 3 | private function filter_conditional_logic( $form ) { |
|
1799 | |||
1800 | /** |
||
1801 | * Disable the Gravity Forms conditional logic script and features on the Edit Entry screen |
||
1802 | * |
||
1803 | * @since 1.9 |
||
1804 | * |
||
1805 | * @param $has_conditional_logic |
||
1806 | * @param $form |
||
1807 | * @return mixed |
||
1808 | */ |
||
1809 | 3 | public function manage_conditional_logic( $has_conditional_logic, $form ) { |
|
1818 | |||
1819 | |||
1820 | // --- User checks and nonces |
||
1821 | |||
1822 | /** |
||
1823 | * Check if the user can edit the entry |
||
1824 | * |
||
1825 | * - Is the nonce valid? |
||
1826 | * - Does the user have the right caps for the entry |
||
1827 | * - Is the entry in the trash? |
||
1828 | * |
||
1829 | * @todo Move to GVCommon |
||
1830 | * |
||
1831 | * @param boolean $echo Show error messages in the form? |
||
1832 | * @return boolean True: can edit form. False: nope. |
||
1833 | */ |
||
1834 | 4 | private function user_can_edit_entry( $echo = false ) { |
|
1898 | |||
1899 | |||
1900 | /** |
||
1901 | * Check whether a field is editable by the current user, and optionally display an error message |
||
1902 | * @uses GravityView_Edit_Entry->check_user_cap_edit_field() Check user capabilities |
||
1903 | * @param array $field Field or field settings array |
||
1904 | * @param boolean $echo Whether to show error message telling user they aren't allowed |
||
1905 | * @return boolean True: user can edit the current field; False: nope, they can't. |
||
1906 | */ |
||
1907 | private function user_can_edit_field( $field, $echo = false ) { |
||
1929 | |||
1930 | |||
1931 | /** |
||
1932 | * checks if user has permissions to edit a specific field |
||
1933 | * |
||
1934 | * Needs to be used combined with GravityView_Edit_Entry::user_can_edit_field for maximum security!! |
||
1935 | * |
||
1936 | * @param [type] $field [description] |
||
1937 | * @return bool |
||
1938 | */ |
||
1939 | private function check_user_cap_edit_field( $field ) { |
||
1955 | |||
1956 | |||
1957 | /** |
||
1958 | * Is the current nonce valid for editing the entry? |
||
1959 | * @return boolean |
||
1960 | */ |
||
1961 | 3 | public function verify_nonce() { |
|
1987 | |||
1988 | |||
1989 | /** |
||
1990 | * Multiselect in GF 2.2 became a json_encoded value. Fix it. |
||
1991 | * |
||
1992 | * As a hack for now we'll implode it back. |
||
1993 | */ |
||
1994 | public function fix_multiselect_value_serialization( $field_value, $field, $_this ) { |
||
1995 | if ( empty ( $field->storageType ) || $field->storageType != 'json' ) { |
||
1996 | return $field_value; |
||
1997 | } |
||
1998 | |||
1999 | $maybe_json = @json_decode( $field_value, true ); |
||
2000 | |||
2001 | if ( $maybe_json ) { |
||
2002 | return implode( ',', $maybe_json ); |
||
2003 | } |
||
2004 | |||
2005 | return $field_value; |
||
2006 | } |
||
2007 | |||
2008 | |||
2009 | |||
2010 | } //end class |
||
2011 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.