Completed
Push — develop ( d6e54c...488d60 )
by Zack
17:10
created

GravityView_Edit_Entry_Render   D

Complexity

Total Complexity 273

Size/Duplication

Total Lines 2128
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 60.68%

Importance

Changes 0
Metric Value
dl 0
loc 2128
ccs 412
cts 679
cp 0.6068
rs 4.4102
c 0
b 0
f 0
wmc 273
lcom 1
cbo 8

How to fix   Complexity   

Complex Class

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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 102 and the first side effect is on line 13.

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.

Loading history...
2
/**
3
 * GravityView Edit Entry - render frontend
4
 *
5
 * @package   GravityView
6
 * @license   GPL2+
7
 * @author    Katz Web Services, Inc.
8
 * @link      http://gravityview.co
9
 * @copyright Copyright 2014, Katz Web Services, Inc.
10
 */
11
12
if ( ! defined( 'WPINC' ) ) {
13
	die;
14
}
15
16
class GravityView_Edit_Entry_Render {
0 ignored issues
show
Coding Style introduced by
Possible parse error: class missing opening or closing brace
Loading history...
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;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
101
102 3
	function __construct( GravityView_Edit_Entry $loader ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
103 3
		$this->loader = $loader;
104 3
	}
105
106 3
	function load() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
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 );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
117
118 3
		add_filter( 'gravityview_is_edit_entry', array( $this, 'is_edit_entry') );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
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') );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
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 ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
163
	        gravityview()->log->debug( 'GravityView_Edit_Entry[prevent_maybe_process_form] $_POSTed data (sanitized): ', array( 'data' => esc_html( print_r( $_POST, true ) ) ) );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
164
		}
165
166
		if( $this->is_edit_entry_submission() ) {
167
			remove_action( 'wp',  array( 'RGForms', 'maybe_process_form'), 9 );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
168
	        remove_action( 'wp',  array( 'GFForms', 'maybe_process_form'), 9 );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
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'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
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 ] );
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
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
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
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
		if ( ! $gv_data ) {
228 4
			$gv_data = GravityView_View_Data::getInstance();
229 4
		}
230
231
		// Multiple Views embedded, don't proceed if nonce fails
232
		if ( $gv_data->has_multiple_views() && ! wp_verify_nonce( $_GET['edit'], self::$nonce_key ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_GET
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
233
			gravityview()->log->error( 'Nonce validation failed for the Edit Entry request; returning' );
234
			return;
235 4
		}
236 1
237 1
		// Sorry, you're not allowed here.
238
		if( false === $this->user_can_edit_entry( true ) ) {
239
			gravityview()->log->error( 'User is not allowed to edit this entry; returning', array( 'data' => $this->entry ) );
240 4
			return;
241
		}
242 4
243
		$this->print_scripts();
244 4
245
		$this->process_save();
246 4
247
		$this->edit_entry_form();
248
249
	}
250
251
252
	/**
253 3
	 * Force Gravity Forms to output scripts as if it were in the admin
254 3
	 * @return void
255
	 */
256 3
	private function print_scripts() {
257
		$gravityview_view = GravityView_View::getInstance();
258 3
259
		wp_register_script( 'gform_gravityforms', GFCommon::get_base_url().'/js/gravityforms.js', array( 'jquery', 'gform_json', 'gform_placeholder', 'sack', 'plupload-all', 'gravityview-fe-view' ) );
260
261 3
		GFFormDisplay::enqueue_form_scripts($gravityview_view->getForm(), false);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
262 3
263
		// Sack is required for images
264
		wp_print_scripts( array( 'sack', 'gform_gravityforms' ) );
265
	}
266
267
268 4
	/**
269
	 * Process edit entry form save
270 4
	 */
271 4
	private function process_save() {
272
273
		if( empty( $_POST ) || ! isset( $_POST['lid'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
274
			return;
275 4
		}
276
277 4
		// Make sure the entry, view, and form IDs are all correct
278
		$valid = $this->verify_nonce();
279
280
		if( !$valid ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
281
			gravityview()->log->error( 'Nonce validation failed.' );
282 4
			return;
283
		}
284
285
		if( $this->entry['id'] !== $_POST['lid'] ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
286
			gravityview()->log->error( 'Entry ID did not match posted entry ID.' );
287 4
			return;
288
		}
289 4
290
		gravityview()->log->debug( '$_POSTed data (sanitized): ', array( 'data' => esc_html( print_r( $_POST, true ) ) ) );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
291 4
292
		$this->process_save_process_files( $this->form_id );
293 4
294
		$this->validate();
295 4
296
		if( $this->is_valid ) {
297
298
			gravityview()->log->debug( 'Submission is valid.' );
299
300 4
			/**
301
			 * @hack This step is needed to fix field visibility, to add the calculation fields
302
			 */
303
			$form = $this->form_prepare_for_save();
304
305 4
			/**
306
			 * @hack This step is needed to unset the adminOnly from form fields, to add the calculation fields
307 4
			 */
308
			$form = $this->form_prepare_for_save();
309
310
			/**
311
			 * @hack to avoid the capability validation of the method save_lead for GF 1.9+
312
			 */
313 4
			unset( $_GET['page'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
314
315 4
			$date_created = $this->entry['date_created'];
316
317
			/**
318 4
			 * @hack to force Gravity Forms to use $read_value_from_post in GFFormsModel::save_lead()
319
			 * @since 1.17.2
320 4
			 */
321
			unset( $this->entry['date_created'] );
322
323 4
			GFFormsModel::save_lead( $form, $this->entry );
324
325
	        // Delete the values for hidden inputs
326 4
	        $this->unset_hidden_field_values();
327
			
328
			$this->entry['date_created'] = $date_created;
329
330
			// Process calculation fields
331
			$this->update_calculation_fields();
332 4
333
			// Perform actions normally performed after updating a lead
334
			$this->after_update();
335
336
	        /**
337
			 * Must be AFTER after_update()!
338
			 * @see https://github.com/gravityview/GravityView/issues/764
339
			 */
340 4
			$this->maybe_update_post_fields( $form );
341
342
			/**
343
			 * @action `gravityview/edit_entry/after_update` Perform an action after the entry has been updated using Edit Entry
344
			 * @param array $form Gravity Forms form array
345
			 * @param string $entry_id Numeric ID of the entry that was updated
346 4
			 * @param GravityView_Edit_Entry_Render $this This object
347
			 */
348
			do_action( 'gravityview/edit_entry/after_update', $this->form, $this->entry['id'], $this );
349
350
		} else {
351
			gravityview()->log->error( 'Submission is NOT valid.', array( 'entry' => $this->entry ) );
352
		}
353
354
	} // process_save
355
356
	/**
357 3
	 * Delete the value of fields hidden by conditional logic when the entry is edited
358 3
	 *
359
	 * @uses GFFormsModel::update_lead_field_value()
360
	 *
361
	 * @since 1.17.4
362
	 *
363
	 * @return void
364
	 */
365
	private function unset_hidden_field_values() {
366 3
	    global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
367
368 3
		/**
369
		 * @filter `gravityview/edit_entry/unset_hidden_field_values` Whether to delete values of fields hidden by conditional logic
370
		 * @since 1.22.2
371
		 * @param bool $unset_hidden_field_values Default: true
372 3
		 * @param GravityView_Edit_Entry_Render $this This object
373
		 */
374
		$unset_hidden_field_values = apply_filters( 'gravityview/edit_entry/unset_hidden_field_values', true, $this );
375
376 3
		if( ! $unset_hidden_field_values ) {
377 3
			return;
378
		}
379
380 3
		if ( version_compare( GravityView_GFFormsModel::get_database_version(), '2.3-dev-1', '>=' ) && method_exists( 'GFFormsModel', 'get_entry_meta_table_name' ) ) {
381
			$entry_meta_table = GFFormsModel::get_entry_meta_table_name();
382 3
			$current_fields = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM $entry_meta_table WHERE entry_id=%d", $this->entry['id'] ) );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
383
		} else {
384
			$lead_detail_table = GFFormsModel::get_lead_details_table_name();
385
			$current_fields = $wpdb->get_results( $wpdb->prepare( "SELECT id, field_number FROM $lead_detail_table WHERE lead_id=%d", $this->entry['id'] ) );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
386 3
		}
387
388
	    foreach ( $this->entry as $input_id => $field_value ) {
389
390
		    $field = RGFormsModel::get_field( $this->form, $input_id );
391
392
		    // Reset fields that are hidden
393
		    // Don't pass $entry as fourth parameter; force using $_POST values to calculate conditional logic
394
		    if ( GFFormsModel::is_field_hidden( $this->form, $field, array(), NULL ) ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
395
396
		        // List fields are stored as empty arrays when empty
397
			    $empty_value = $this->is_field_json_encoded( $field ) ? '[]' : '';
398 3
399
			    $lead_detail_id = GFFormsModel::get_lead_detail_id( $current_fields, $input_id );
400
401 3
			    GFFormsModel::update_lead_field_value( $this->form, $this->entry, $field, $lead_detail_id, $input_id, $empty_value );
402
403
			    // Prevent the $_POST values of hidden fields from being used as default values when rendering the form
404
				// after submission
405
			    $post_input_id = 'input_' . str_replace( '.', '_', $input_id );
406
			    $_POST[ $post_input_id ] = '';
407
		    }
408
	    }
409
	}
410 3
411
	/**
412
	 * Have GF handle file uploads
413 3
	 *
414 3
	 * Copy of code from GFFormDisplay::process_form()
415 2
	 *
416
	 * @param int $form_id
417
	 */
418
	private function process_save_process_files( $form_id ) {
419
420
		//Loading files that have been uploaded to temp folder
421
		$files = GFCommon::json_decode( stripslashes( RGForms::post( 'gform_uploaded_files' ) ) );
422 3
		if ( ! is_array( $files ) ) {
423
			$files = array();
424 3
		}
425 3
426
		/**
427
		 * Make sure the fileuploads are not overwritten if no such request was done.
428
		 * @since 1.20.1
429
		 */
430
		add_filter( "gform_save_field_value_$form_id", array( $this, 'save_field_value' ), 99, 5 );
431
432
		RGFormsModel::$uploaded_files[ $form_id ] = $files;
433
	}
434
435
	/**
436
	 * Make sure the fileuploads are not overwritten if no such request was done.
437
	 *
438
	 * TO ONLY BE USED INTERNALLY; DO NOT DEVELOP ON; MAY BE REMOVED AT ANY TIME.
439
	 *
440
	 * @since 1.20.1
441
	 *
442 3
	 * @param string $value Field value
443
	 * @param array $entry GF entry array
444 3
	 * @param GF_Field_FileUpload $field
445 3
	 * @param array $form GF form array
446
	 * @param string $input_id ID of the input being saved
447
	 *
448 1
	 * @return string
449
	 */
450 1
	public function save_field_value( $value = '', $entry = array(), $field = null, $form = array(), $input_id = '' ) {
451
452
		if ( ! $field || $field->type != 'fileupload' ) {
0 ignored issues
show
introduced by
Found "!= '". Use Yoda Condition checks, you must
Loading history...
453
			return $value;
454
		}
455
456
		$input_name = 'input_' . str_replace( '.', '_', $input_id );
457
458 1
		if ( $field->multipleFiles ) {
459
			if ( empty( $value ) ) {
460 1
				return json_decode( $entry[ $input_id ], true );
461
			}
462
			return $value;
463 1
		}
464
465
		/** No file is being uploaded. */
466
		if ( empty( $_FILES[ $input_name ]['name'] ) ) {
467
			/** So return the original upload */
468
			return $entry[ $input_id ];
469
		}
470
471
		return $value;
472
	}
473
474
	/**
475 1
	 * Remove max_files validation (done on gravityforms.js) to avoid conflicts with GravityView
476 1
	 * Late validation done on self::custom_validation
477
	 *
478
	 * @param $plupload_init array Plupload settings
479
	 * @param $form_id
480 1
	 * @param $instance
481
	 * @return mixed
482 1
	 */
483
	public function modify_fileupload_settings( $plupload_init, $form_id, $instance ) {
484
		if( ! $this->is_edit_entry() ) {
485
			return $plupload_init;
486
		}
487
488
		$plupload_init['gf_vars']['max_files'] = 0;
489
490 3
		return $plupload_init;
491
	}
492 3
493
494
	/**
495 3
	 * Set visibility to visible and convert field input key to string
496
	 * @return array $form
497
	 */
498
	private function form_prepare_for_save() {
499
500
		$form = $this->form;
501
502 3
	    /** @var GF_Field $field */
503
		foreach( $form['fields'] as $k => &$field ) {
504
505
			/**
506 3
			 * Remove the fields with calculation formulas before save to avoid conflicts with GF logic
507
			 * @since 1.16.3
508 3
			 * @var GF_Field $field
509
			 */
510 3
			if( $field->has_calculation() ) {
511
				unset( $form['fields'][ $k ] );
512
			}
513
514
			$field->adminOnly = false;
515 3
516
			if( isset( $field->inputs ) && is_array( $field->inputs ) ) {
517
				foreach( $field->inputs as $key => $input ) {
518 3
				    $field->inputs[ $key ][ 'id' ] = (string)$input['id'];
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
519
				}
520 3
			}
521 3
		}
522
523
		return $form;
524 3
	}
525
526 3
	private function update_calculation_fields() {
527
528
		$form = self::$original_form;
529
		$update = false;
530
531
		// get the most up to date entry values
532
		$entry = GFAPI::get_entry( $this->entry['id'] );
533
534
		if( !empty( $this->fields_with_calculation ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
535
			$update = true;
536
			foreach ( $this->fields_with_calculation as $calc_field ) {
537
				$inputs = $calc_field->get_entry_inputs();
538
				if ( is_array( $inputs ) ) {
539
				    foreach ( $inputs as $input ) {
540
				        $input_name = 'input_' . str_replace( '.', '_', $input['id'] );
541
				        $entry[ strval( $input['id'] ) ] = RGFormsModel::prepare_value( $form, $calc_field, '', $input_name, $entry['id'], $entry );
542
				    }
543
				} else {
544
				    $input_name = 'input_' . str_replace( '.', '_', $calc_field->id);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
545
				    $entry[ strval( $calc_field->id ) ] = RGFormsModel::prepare_value( $form, $calc_field, '', $input_name, $entry['id'], $entry );
546
				}
547
			}
548
549
		}
550
551
		if( $update ) {
552
553
			$return_entry = GFAPI::update_entry( $entry );
554
555
			if( is_wp_error( $return_entry ) ) {
556
				gravityview()->log->error( 'Updating the entry calculation fields failed', array( 'data' => $return_entry ) );
557
			} else {
558
				gravityview()->log->debug( 'Updating the entry calculation fields succeeded' );
559
			}
560 3
		}
561
	}
562
563
	/**
564
	 * Handle updating the Post Image field
565
	 *
566
	 * Sets a new Featured Image if configured in Gravity Forms; otherwise uploads/updates media
567
	 *
568
	 * @since 1.17
569
	 *
570 3
	 * @uses GFFormsModel::media_handle_upload
571
	 * @uses set_post_thumbnail
572
	 * 
573
	 * @param array $form GF Form array
574
	 * @param GF_Field $field GF Field
575
	 * @param string $field_id Numeric ID of the field
576
	 * @param string $value
577
	 * @param array $entry GF Entry currently being edited
578
	 * @param int $post_id ID of the Post being edited
579
	 *
580
	 * @return mixed|string
581
	 */
582
	private function update_post_image( $form, $field, $field_id, $value, $entry, $post_id ) {
583
584
		$input_name = 'input_' . $field_id;
585
586
		if ( !empty( $_FILES[ $input_name ]['name'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
587
588
			// We have a new image
589
590
			$value = RGFormsModel::prepare_value( $form, $field, $value, $input_name, $entry['id'] );
591 1
592
			$ary = ! empty( $value ) ? explode( '|:|', $value ) : array();
593 1
	        $ary = stripslashes_deep( $ary );
594
			$img_url = \GV\Utils::get( $ary, 0 );
595 1
596
			$img_title       = count( $ary ) > 1 ? $ary[1] : '';
597
			$img_caption     = count( $ary ) > 2 ? $ary[2] : '';
598
			$img_description = count( $ary ) > 3 ? $ary[3] : '';
599
600
			$image_meta = array(
601
				'post_excerpt' => $img_caption,
602
				'post_content' => $img_description,
603
			);
604
605
			//adding title only if it is not empty. It will default to the file name if it is not in the array
606
			if ( ! empty( $img_title ) ) {
607
				$image_meta['post_title'] = $img_title;
608
			}
609
610
			/**
611
			 * 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.
612
			 * Note: the method became public in GF 1.9.17.7, but we don't require that version yet.
613
			 */
614
			require_once GRAVITYVIEW_DIR . 'includes/class-gravityview-gfformsmodel.php';
615
			$media_id = GravityView_GFFormsModel::media_handle_upload( $img_url, $post_id, $image_meta );
616
617
			// is this field set as featured image?
618
			if ( $media_id && $field->postFeaturedImage ) {
619
				set_post_thumbnail( $post_id, $media_id );
620
			}
621
622
		} elseif ( ! empty( $_POST[ $input_name ] ) && is_array( $value ) ) {
623
624
			$img_url         = stripslashes_deep( $_POST[ $input_name ] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
625
			$img_title       = stripslashes_deep( \GV\Utils::_POST( $input_name . '_1' ) );
626
			$img_caption     = stripslashes_deep( \GV\Utils::_POST( $input_name . '_4' ) );
627
			$img_description = stripslashes_deep( \GV\Utils::_POST( $input_name . '_7' ) );
628
629
			$value = ! empty( $img_url ) ? $img_url . "|:|" . $img_title . "|:|" . $img_caption . "|:|" . $img_description : '';
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal |:| does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
630 1
631
			if ( $field->postFeaturedImage ) {
632 1
633 1
				$image_meta = array(
634 1
					'ID' => get_post_thumbnail_id( $post_id ),
635 1
					'post_title' => $img_title,
636
					'post_excerpt' => $img_caption,
637 1
					'post_content' => $img_description,
638
				);
639 1
640
				// update image title, caption or description
641
				wp_update_post( $image_meta );
642 1
			}
643 1
		} else {
644 1
645 1
			// if we get here, image was removed or not set.
646
			$value = '';
647
648
			if ( $field->postFeaturedImage ) {
649 1
				delete_post_thumbnail( $post_id );
650
			}
651
		}
652
653
		return $value;
654
	}
655
656
	/**
657
	 * Loop through the fields being edited and if they include Post fields, update the Entry's post object
658
	 *
659
	 * @param array $form Gravity Forms form
660
	 *
661 1
	 * @return void
662
	 */
663
	private function maybe_update_post_fields( $form ) {
664
665
		if( empty( $this->entry['post_id'] ) ) {
666
	        gravityview()->log->debug( 'This entry has no post fields. Continuing...' );
667
			return;
668
		}
669
670
		$post_id = $this->entry['post_id'];
671 3
672
		// Security check
673 3
		if( false === GVCommon::has_cap( 'edit_post', $post_id ) ) {
674 2
			gravityview()->log->error( 'The current user does not have the ability to edit Post #{post_id}', array( 'post_id' => $post_id ) );
675 2
			return;
676
		}
677
678 1
		$update_entry = false;
679
680
		$updated_post = $original_post = get_post( $post_id );
681 1
682
		foreach ( $this->entry as $field_id => $value ) {
683
684
			$field = RGFormsModel::get_field( $form, $field_id );
685
686 1
			if( ! $field ) {
687
				continue;
688 1
			}
689
690 1
			if( GFCommon::is_post_field( $field ) && 'post_category' !== $field->type ) {
691
692 1
				// Get the value of the field, including $_POSTed value
693
				$value = RGFormsModel::get_field_value( $field );
694 1
695 1
				// Use temporary entry variable, to make values available to fill_post_template() and update_post_image()
696
				$entry_tmp = $this->entry;
697
				$entry_tmp["{$field_id}"] = $value;
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
698 1
699
				switch( $field->type ) {
700
701 1
				    case 'post_title':
702
				        $post_title = $value;
703
				        if ( \GV\Utils::get( $form, 'postTitleTemplateEnabled' ) ) {
704 1
				            $post_title = $this->fill_post_template( $form['postTitleTemplate'], $form, $entry_tmp );
705 1
				        }
706
				        $updated_post->post_title = $post_title;
707 1
				        $updated_post->post_name  = $post_title;
708
				        unset( $post_title );
709 1
				        break;
710
711
				    case 'post_content':
712
				        $post_content = $value;
713
				        if ( \GV\Utils::get( $form, 'postContentTemplateEnabled' ) ) {
714
				            $post_content = $this->fill_post_template( $form['postContentTemplate'], $form, $entry_tmp, true );
715
				        }
716
				        $updated_post->post_content = $post_content;
717
				        unset( $post_content );
718
				        break;
719 1
				    case 'post_excerpt':
720
				        $updated_post->post_excerpt = $value;
721
				        break;
722
				    case 'post_tags':
723
				        wp_set_post_tags( $post_id, $value, false );
724
				        break;
725
				    case 'post_category':
726
				        break;
727 1
				    case 'post_custom_field':
728
						if ( is_array( $value ) && ( floatval( $field_id ) !== floatval( $field->id ) ) ) {
729
							$value = $value[ $field_id ];
730 1
						}
731
732
				        if( ! empty( $field->customFieldTemplateEnabled ) ) {
733 1
				            $value = $this->fill_post_template( $field->customFieldTemplate, $form, $entry_tmp, true );
734
				        }
735 1
736
	                    if ( $this->is_field_json_encoded( $field ) && ! is_string( $value ) ) {
737
		                    $value = function_exists('wp_json_encode') ? wp_json_encode( $value ) : json_encode( $value );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
738
	                    }
739
740
				        update_post_meta( $post_id, $field->postCustomFieldName, $value );
741
				        break;
742
743
				    case 'post_image':
744
				        $value = $this->update_post_image( $form, $field, $field_id, $value, $this->entry, $post_id );
745
				        break;
746
747
				}
748
749
				// update entry after
750
				$this->entry["{$field_id}"] = $value;
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
751 1
752 1
				$update_entry = true;
753 1
754
				unset( $entry_tmp );
755
			}
756
757
		}
758 1
759
		if( $update_entry ) {
760 1
761
			$return_entry = GFAPI::update_entry( $this->entry );
762 1
763
			if( is_wp_error( $return_entry ) ) {
764
				gravityview()->log->error( 'Updating the entry post fields failed', array( 'data' => array( '$this->entry' => $this->entry, '$return_entry' => $return_entry ) ) );
765
			} else {
766
				gravityview()->log->debug( 'Updating the entry post fields for post #{post_id} succeeded', array( 'post_id' => $post_id ) );
767 1
			}
768
769 1
		}
770
771 1
		$return_post = wp_update_post( $updated_post, true );
772
773
		if( is_wp_error( $return_post ) ) {
774 1
			$return_post->add_data( $updated_post, '$updated_post' );
775
			gravityview()->log->error( 'Updating the post content failed', array( 'data' => compact( 'updated_post', 'return_post' ) ) );
776
		} else {
777
			gravityview()->log->debug( 'Updating the post content for post #{post_id} succeeded', array( 'post_id' => $post_id, 'data' => $updated_post ) );
778
		}
779 1
	}
780
781 1
	/**
782
	 * Is the field stored in a JSON-encoded manner?
783
	 *
784
	 * @param GF_Field $field
785 1
	 *
786
	 * @return bool True: stored in DB json_encode()'d; False: not encoded
787 1
	 */
788
	private function is_field_json_encoded( $field ) {
789
790
	    $json_encoded = false;
791
792
		$input_type = RGFormsModel::get_input_type( $field );
793
794
	    // Only certain custom field types are supported
795
	    switch( $input_type ) {
796
		    case 'fileupload':
797
		    case 'list':
798
		    case 'multiselect':
799
			    $json_encoded = true;
800
			    break;
801
	    }
802
803
	    return $json_encoded;
804
	}
805
806
	/**
807
	 * Convert a field content template into prepared output
808
	 *
809
	 * @uses GravityView_GFFormsModel::get_post_field_images()
810
	 *
811
	 * @since 1.17
812
	 *
813
	 * @param string $template The content template for the field
814
	 * @param array $form Gravity Forms form
815
	 * @param bool $do_shortcode Whether to process shortcode inside content. In GF, only run on Custom Field and Post Content fields
816
	 *
817
	 * @return string
818
	 */
819
	private function fill_post_template( $template, $form, $entry, $do_shortcode = false ) {
820
821
		require_once GRAVITYVIEW_DIR . 'includes/class-gravityview-gfformsmodel.php';
822
823
		$post_images = GravityView_GFFormsModel::get_post_field_images( $form, $entry );
824
825
		//replacing post image variables
826
		$output = GFCommon::replace_variables_post_image( $template, $post_images, $entry );
827
828
		//replacing all other variables
829
		$output = GFCommon::replace_variables( $output, $form, $entry, false, false, false );
830
831
		// replace conditional shortcodes
832
		if( $do_shortcode ) {
833
			$output = do_shortcode( $output );
834
		}
835
836
		return $output;
837
	}
838
839
840
	/**
841
	 * Perform actions normally performed after updating a lead
842
	 *
843
	 * @since 1.8
844
	 *
845
	 * @see GFEntryDetail::lead_detail_page()
846
	 *
847
	 * @return void
848
	 */
849
	private function after_update() {
850
851
		do_action( 'gform_after_update_entry', $this->form, $this->entry['id'], self::$original_entry );
852
		do_action( "gform_after_update_entry_{$this->form['id']}", $this->form, $this->entry['id'], self::$original_entry );
853
854
		// Re-define the entry now that we've updated it.
855
		$entry = RGFormsModel::get_lead( $this->entry['id'] );
856
857 3
		$entry = GFFormsModel::set_entry_meta( $entry, $this->form );
858
859 3
		if ( version_compare( GFFormsModel::get_database_version(), '2.3-dev-1', '<' ) ) {
860 3
			// We need to clear the cache because Gravity Forms caches the field values, which
861
			// we have just updated.
862
			foreach ($this->form['fields'] as $key => $field) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
863 3
				GFFormsModel::refresh_lead_field_value( $entry['id'], $field->id );
864
			}
865 3
		}
866
867 3
		$this->entry = $entry;
868
	}
869
870 3
871 3
	/**
872
	 * Display the Edit Entry form
873
	 *
874
	 * @return void
875 3
	 */
876 3
	public function edit_entry_form() {
877
878
		?>
879
880
		<div class="gv-edit-entry-wrapper"><?php
881
882
			$javascript = gravityview_ob_include( GravityView_Edit_Entry::$file .'/partials/inline-javascript.php', $this );
883
884 3
			/**
885
			 * Fixes weird wpautop() issue
886
			 * @see https://github.com/katzwebservices/GravityView/issues/451
887
			 */
888
			echo gravityview_strip_whitespace( $javascript );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'gravityview_strip_whitespace'
Loading history...
889
890 3
			?><h2 class="gv-edit-entry-title">
891
				<span><?php
892
893
				    /**
894
				     * @filter `gravityview_edit_entry_title` Modify the edit entry title
895
				     * @param string $edit_entry_title Modify the "Edit Entry" title
896 3
				     * @param GravityView_Edit_Entry_Render $this This object
897
				     */
898
				    $edit_entry_title = apply_filters('gravityview_edit_entry_title', __('Edit Entry', 'gravityview'), $this );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
899
900
				    echo esc_attr( $edit_entry_title );
901
			?></span>
902
			</h2>
903
904
			<?php $this->maybe_print_message(); ?>
905
906 3
			<?php // The ID of the form needs to be `gform_{form_id}` for the pluploader ?>
907
908 3
			<form method="post" id="gform_<?php echo $this->form_id; ?>" enctype="multipart/form-data">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
909
910
				<?php
911
912
				wp_nonce_field( self::$nonce_key, self::$nonce_key );
913
914
				wp_nonce_field( self::$nonce_field, self::$nonce_field, false );
915
916
				// Print the actual form HTML
917
				$this->render_edit_form();
918
919
				?>
920 3
			</form>
921
922 3
			<script>
923
				gform.addFilter('gform_reset_pre_conditional_logic_field_action', function ( reset, formId, targetId, defaultValues, isInit ) {
924
				    return false;
925 3
				});
926
			</script>
927
928 3
		</div>
929
930
	<?php
931
	}
932
933
	/**
934
	 * Display success or error message if the form has been submitted
935
	 *
936
	 * @uses GVCommon::generate_notice
937
	 *
938
	 * @since 1.16.2.2
939 3
	 *
940
	 * @return void
941
	 */
942
	private function maybe_print_message() {
943
944
		if ( \GV\Utils::_POST( 'action' ) === 'update' ) {
0 ignored issues
show
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
945
946
			$back_link = esc_url( remove_query_arg( array( 'page', 'view', 'edit' ) ) );
947
948
			if( ! $this->is_valid ){
949
950 3
				// Keeping this compatible with Gravity Forms.
951
				$validation_message = "<div class='validation_error'>" . __('There was a problem with your submission.', 'gravityview') . " " . __('Errors have been highlighted below.', 'gravityview') . "</div>";
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
Coding Style Comprehensibility introduced by
The string literal </div> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
952 3
				$message = apply_filters("gform_validation_message_{$this->form['id']}", apply_filters("gform_validation_message", $validation_message, $this->form), $this->form);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
Coding Style Comprehensibility introduced by
The string literal gform_validation_message does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
953
954
				echo GVCommon::generate_notice( $message , 'gv-error' );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'GVCommon'
Loading history...
955
956
			} else {
957
				$entry_updated_message = sprintf( esc_attr__('Entry Updated. %sReturn to Entry%s', 'gravityview'), '<a href="'. $back_link .'">', '</a>' );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
958
959
				/**
960
				 * @filter `gravityview/edit_entry/success` Modify the edit entry success message (including the anchor link)
961
				 * @since 1.5.4
962
				 * @param string $entry_updated_message Existing message
963
				 * @param int $view_id View ID
964
				 * @param array $entry Gravity Forms entry array
965
				 * @param string $back_link URL to return to the original entry. @since 1.6
966
				 */
967
				$message = apply_filters( 'gravityview/edit_entry/success', $entry_updated_message , $this->view_id, $this->entry, $back_link );
968
969
				echo GVCommon::generate_notice( $message );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'GVCommon'
Loading history...
970
			}
971
972
		}
973
	}
974
975
	/**
976
	 * Display the Edit Entry form in the original Gravity Forms format
977
	 *
978
	 * @since 1.9
979
	 *
980
	 * @return void
981 3
	 */
982
	private function render_edit_form() {
983
984
		/**
985
		 * @action `gravityview/edit-entry/render/before` Before rendering the Edit Entry form
986
		 * @since 1.17
987
		 * @param GravityView_Edit_Entry_Render $this
988
		 */
989
		do_action( 'gravityview/edit-entry/render/before', $this );
990 3
991
		add_filter( 'gform_pre_render', array( $this, 'filter_modify_form_fields'), 5000, 3 );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
992
		add_filter( 'gform_submit_button', array( $this, 'render_form_buttons') );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
993
		add_filter( 'gform_disable_view_counter', '__return_true' );
994
995
		add_filter( 'gform_field_input', array( $this, 'verify_user_can_edit_post' ), 5, 5 );
996
		add_filter( 'gform_field_input', array( $this, 'modify_edit_field_input' ), 10, 5 );
997 3
998
		// We need to remove the fake $_GET['page'] arg to avoid rendering form as if in admin.
999 3
		unset( $_GET['page'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
1000 3
1001 3
		// TODO: Verify multiple-page forms
1002
1003 3
		ob_start(); // Prevent PHP warnings possibly caused by prefilling list fields for conditional logic
1004 3
1005
		$html = GFFormDisplay::get_form( $this->form['id'], false, false, true, $this->entry );
1006
1007 3
		ob_get_clean();
1008
1009
	    remove_filter( 'gform_pre_render', array( $this, 'filter_modify_form_fields' ), 5000 );
1010
		remove_filter( 'gform_submit_button', array( $this, 'render_form_buttons' ) );
1011 3
		remove_filter( 'gform_disable_view_counter', '__return_true' );
1012
		remove_filter( 'gform_field_input', array( $this, 'verify_user_can_edit_post' ), 5 );
1013 3
		remove_filter( 'gform_field_input', array( $this, 'modify_edit_field_input' ), 10 );
1014
1015 3
		echo $html;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$html'
Loading history...
1016
1017 3
		/**
1018 3
		 * @action `gravityview/edit-entry/render/after` After rendering the Edit Entry form
1019 3
		 * @since 1.17
1020 3
		 * @param GravityView_Edit_Entry_Render $this
1021 3
		 */
1022
		do_action( 'gravityview/edit-entry/render/after', $this );
1023 3
	}
1024
1025
	/**
1026
	 * Display the Update/Cancel/Delete buttons for the Edit Entry form
1027
	 * @since 1.8
1028
	 * @return string
1029
	 */
1030 3
	public function render_form_buttons() {
1031 3
		return gravityview_ob_include( GravityView_Edit_Entry::$file .'/partials/form-buttons.php', $this );
1032
	}
1033
1034
1035
	/**
1036
	 * Modify the form fields that are shown when using GFFormDisplay::get_form()
1037
	 *
1038 3
	 * By default, all fields will be shown. We only want the Edit Tab configured fields to be shown.
1039 3
	 *
1040
	 * @param array $form
1041
	 * @param boolean $ajax Whether in AJAX mode
1042
	 * @param array|string $field_values Passed parameters to the form
1043
	 *
1044
	 * @since 1.9
1045
	 *
1046
	 * @return array Modified form array
1047
	 */
1048
	public function filter_modify_form_fields( $form, $ajax = false, $field_values = '' ) {
1049
1050
		// In case we have validated the form, use it to inject the validation results into the form render
1051
		if( isset( $this->form_after_validation ) ) {
1052
			$form = $this->form_after_validation;
1053
		} else {
1054
			$form['fields'] = $this->get_configured_edit_fields( $form, $this->view_id );
1055
		}
1056 3
1057
		$form = $this->filter_conditional_logic( $form );
1058
1059 3
		$form = $this->prefill_conditional_logic( $form );
1060 3
1061
		// for now we don't support Save and Continue feature.
1062 3
		if( ! self::$supports_save_and_continue ) {
1063
	        unset( $form['save'] );
1064
		}
1065 3
1066
		return $form;
1067 3
	}
1068
1069
	/**
1070 3
	 * 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.
1071 3
	 *
1072
	 * @since 1.16.2.2
1073
	 *
1074 3
	 * @param string $field_content Always empty. Returning not-empty overrides the input.
1075
	 * @param GF_Field $field
1076
	 * @param string|array $value If array, it's a field with multiple inputs. If string, single input.
1077
	 * @param int $lead_id Lead ID. Always 0 for the `gform_field_input` filter.
1078
	 * @param int $form_id Form ID
1079
	 *
1080
	 * @return string If error, the error message. If no error, blank string (modify_edit_field_input() runs next)
1081
	 */
1082
	public function verify_user_can_edit_post( $field_content = '', $field, $value, $lead_id = 0, $form_id ) {
1083
1084
		if( GFCommon::is_post_field( $field ) ) {
1085
1086
			$message = null;
1087
1088
			// First, make sure they have the capability to edit the post.
1089
			if( false === current_user_can( 'edit_post', $this->entry['post_id'] ) ) {
1090 3
1091
				/**
1092 3
				 * @filter `gravityview/edit_entry/unsupported_post_field_text` Modify the message when someone isn't able to edit a post
1093
				 * @param string $message The existing "You don't have permission..." text
1094 1
				 */
1095
				$message = apply_filters('gravityview/edit_entry/unsupported_post_field_text', __('You don&rsquo;t have permission to edit this post.', 'gravityview') );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
1096
1097 1
			} elseif( null === get_post( $this->entry['post_id'] ) ) {
1098
				/**
1099
				 * @filter `gravityview/edit_entry/no_post_text` Modify the message when someone is editing an entry attached to a post that no longer exists
1100
				 * @param string $message The existing "This field is not editable; the post no longer exists." text
1101
				 */
1102
				$message = apply_filters('gravityview/edit_entry/no_post_text', __('This field is not editable; the post no longer exists.', 'gravityview' ) );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
1103
			}
1104
1105 1
			if( $message ) {
1106
				$field_content = sprintf('<div class="ginput_container ginput_container_' . $field->type . '">%s</div>', wpautop( $message ) );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
1107
			}
1108
		}
1109
1110
		return $field_content;
1111
	}
1112
1113 1
	/**
1114
	 *
1115
	 * Fill-in the saved values into the form inputs
1116
	 *
1117
	 * @param string $field_content Always empty. Returning not-empty overrides the input.
1118 3
	 * @param GF_Field $field
1119
	 * @param string|array $value If array, it's a field with multiple inputs. If string, single input.
1120
	 * @param int $lead_id Lead ID. Always 0 for the `gform_field_input` filter.
1121
	 * @param int $form_id Form ID
1122
	 *
1123
	 * @return mixed
1124
	 */
1125
	public function modify_edit_field_input( $field_content = '', $field, $value, $lead_id = 0, $form_id ) {
1126
1127
		$gv_field = GravityView_Fields::get_associated_field( $field );
1128
1129
		// If the form has been submitted, then we don't need to pre-fill the values,
1130
		// Except for fileupload type and when a field input is overridden- run always!!
1131
		if(
1132
			( $this->is_edit_entry_submission() && !in_array( $field->type, array( 'fileupload', 'post_image' ) ) )
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1133 3
			&& false === ( $gv_field && is_callable( array( $gv_field, 'get_field_input' ) ) )
1134
			&& ! GFCommon::is_product_field( $field->type )
1135 3
			|| ! empty( $field_content )
1136
			|| in_array( $field->type, array( 'honeypot' ) )
1137
		) {
1138
	        return $field_content;
1139
		}
1140 3
1141 3
		// SET SOME FIELD DEFAULTS TO PREVENT ISSUES
1142
		$field->adminOnly = false; /** @see GFFormDisplay::get_counter_init_script() need to prevent adminOnly */
1143 3
1144 3
		$field_value = $this->get_field_value( $field );
1145
1146
	    // Prevent any PHP warnings, like undefined index
1147
	    ob_start();
1148
1149
	    $return = null;
1150 3
1151
		/** @var GravityView_Field $gv_field */
1152 3
		if( $gv_field && is_callable( array( $gv_field, 'get_field_input' ) ) ) {
1153
			$return = $gv_field->get_field_input( $this->form, $field_value, $this->entry, $field );
1154
		} else {
1155 3
	        $return = $field->get_field_input( $this->form, $field_value, $this->entry );
1156
	    }
1157 3
1158
	    // If there was output, it's an error
1159
	    $warnings = ob_get_clean();
1160 3
1161 2
	    if( !empty( $warnings ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1162
		    gravityview()->log->error( '{warning}', array( 'warning' => $warnings, 'data' => $field_value ) );
1163 3
	    }
1164
1165
		return $return;
1166
	}
1167 3
1168
	/**
1169 3
	 * Modify the value for the current field input
1170
	 *
1171
	 * @param GF_Field $field
1172
	 *
1173 3
	 * @return array|mixed|string
1174
	 */
1175
	private function get_field_value( $field ) {
1176
1177
		/**
1178
		 * @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.
1179
		 * @param boolean True: override saved values; False: don't override (default)
1180
		 * @param $field GF_Field object Gravity Forms field object
1181
		 * @since 1.13
1182
		 */
1183 3
		$override_saved_value = apply_filters( 'gravityview/edit_entry/pre_populate/override', false, $field );
1184
1185
		// We're dealing with multiple inputs (e.g. checkbox) but not time or date (as it doesn't store data in input IDs)
1186
		if( isset( $field->inputs ) && is_array( $field->inputs ) && !in_array( $field->type, array( 'time', 'date' ) ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1187
1188
			$field_value = array();
1189
1190
			// only accept pre-populated values if the field doesn't have any choice selected.
1191 3
			$allow_pre_populated = $field->allowsPrepopulate;
1192
1193
			foreach ( (array)$field->inputs as $input ) {
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
1194 3
1195
				$input_id = strval( $input['id'] );
1196
				
1197
				if ( isset( $this->entry[ $input_id ] ) && ! gv_empty( $this->entry[ $input_id ], false, false ) ) {
1198
				    $field_value[ $input_id ] =  'post_category' === $field->type ? GFCommon::format_post_category( $this->entry[ $input_id ], true ) : $this->entry[ $input_id ];
0 ignored issues
show
introduced by
Expected 1 space after "="; 2 found
Loading history...
1199
				    $allow_pre_populated = false;
1200
				}
1201
1202
			}
1203
1204
			$pre_value = $field->get_value_submission( array(), false );
1205
1206
			$field_value = ! $allow_pre_populated && ! ( $override_saved_value && !gv_empty( $pre_value, false, false ) ) ? $field_value : $pre_value;
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1207
1208
		} else {
1209
1210
			$id = intval( $field->id );
1211
1212
			// get pre-populated value if exists
1213
			$pre_value = $field->allowsPrepopulate ? GFFormsModel::get_parameter_value( $field->inputName, array(), $field ) : '';
1214
1215
			// saved field entry value (if empty, fallback to the pre-populated value, if exists)
1216
			// or pre-populated value if not empty and set to override saved value
1217
			$field_value = !gv_empty( $this->entry[ $id ], false, false ) && ! ( $override_saved_value && !gv_empty( $pre_value, false, false ) ) ? $this->entry[ $id ] : $pre_value;
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1218 3
1219
			// in case field is post_category but inputType is select, multi-select or radio, convert value into array of category IDs.
1220
			if ( 'post_category' === $field->type && !gv_empty( $field_value, false, false ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1221 3
				$categories = array();
1222
				foreach ( explode( ',', $field_value ) as $cat_string ) {
1223
				    $categories[] = GFCommon::format_post_category( $cat_string, true );
1224
				}
1225 3
				$field_value = 'multiselect' === $field->get_input_type() ? $categories : implode( '', $categories );
1226
			}
1227
1228 3
		}
1229
1230
		// if value is empty get the default value if defined
1231
		$field_value = $field->get_value_default_if_empty( $field_value );
1232
1233
	    /**
1234
	     * @filter `gravityview/edit_entry/field_value` Change the value of an Edit Entry field, if needed
1235
	     * @since 1.11
1236
	     * @since 1.20 Added third param
1237
	     * @param mixed $field_value field value used to populate the input
1238
	     * @param object $field Gravity Forms field object ( Class GF_Field )
1239 3
	     * @param GravityView_Edit_Entry_Render $this Current object
1240
	     */
1241
	    $field_value = apply_filters( 'gravityview/edit_entry/field_value', $field_value, $field, $this );
1242
1243
	    /**
1244
	     * @filter `gravityview/edit_entry/field_value_{field_type}` Change the value of an Edit Entry field for a specific field type
1245
	     * @since 1.17
1246
	     * @since 1.20 Added third param
1247
	     * @param mixed $field_value field value used to populate the input
1248
	     * @param GF_Field $field Gravity Forms field object
1249 3
	     * @param GravityView_Edit_Entry_Render $this Current object
1250
	     */
1251
	    $field_value = apply_filters( 'gravityview/edit_entry/field_value_' . $field->type , $field_value, $field, $this );
1252
1253
		return $field_value;
1254
	}
1255
1256
1257
	// ---- Entry validation
1258
1259 3
	/**
1260
	 * Add field keys that Gravity Forms expects.
1261 3
	 *
1262
	 * @see GFFormDisplay::validate()
1263
	 * @param  array $form GF Form
1264
	 * @return array       Modified GF Form
1265
	 */
1266
	public function gform_pre_validation( $form ) {
1267
1268
		if( ! $this->verify_nonce() ) {
1269
			return $form;
1270
		}
1271
1272
		// Fix PHP warning regarding undefined index.
1273
		foreach ( $form['fields'] as &$field) {
0 ignored issues
show
introduced by
No space before closing parenthesis is prohibited
Loading history...
1274 3
1275
			// This is because we're doing admin form pretending to be front-end, so Gravity Forms
1276 3
			// expects certain field array items to be set.
1277
			foreach ( array( 'noDuplicates', 'adminOnly', 'inputType', 'isRequired', 'enablePrice', 'inputs', 'allowedExtensions' ) as $key ) {
1278
	            $field->{$key} = isset( $field->{$key} ) ? $field->{$key} : NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
1279
			}
1280
1281 3
			switch( RGFormsModel::get_input_type( $field ) ) {
1282
1283
				/**
1284
				 * 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.
1285 3
				 *
1286 3
				 * 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.
1287
				 *
1288
				 * @hack
1289
				 */
1290 3
				case 'fileupload':
1291
1292
				    // Set the previous value
1293
				    $entry = $this->get_entry();
1294 3
1295
				    $input_name = 'input_'.$field->id;
1296
				    $form_id = $form['id'];
1297
1298
				    $value = NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
1299
1300
				    // Use the previous entry value as the default.
1301
				    if( isset( $entry[ $field->id ] ) ) {
1302
				        $value = $entry[ $field->id ];
1303 3
				    }
1304
1305
				    // If this is a single upload file
1306 1
				    if( !empty( $_FILES[ $input_name ] ) && !empty( $_FILES[ $input_name ]['name'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1307
				        $file_path = GFFormsModel::get_file_upload_path( $form['id'], $_FILES[ $input_name ]['name'] );
1308 1
				        $value = $file_path['url'];
1309 1
1310
				    } else {
1311 1
1312
				        // Fix PHP warning on line 1498 of form_display.php for post_image fields
1313
				        // Fix PHP Notice:  Undefined index:  size in form_display.php on line 1511
1314 1
				        $_FILES[ $input_name ] = array('name' => '', 'size' => '' );
0 ignored issues
show
introduced by
No space after opening parenthesis of array is bad style
Loading history...
1315 1
1316
				    }
1317
1318
				    if ( \GV\Utils::get( $field, "multipleFiles" ) ) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal multipleFiles does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
1319 1
1320 1
				        // If there are fresh uploads, process and merge them.
1321 1
				        // Otherwise, use the passed values, which should be json-encoded array of URLs
1322
				        if( isset( GFFormsModel::$uploaded_files[$form_id][$input_name] ) ) {
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
1323
				            $value = empty( $value ) ? '[]' : $value;
1324
				            $value = stripslashes_deep( $value );
1325
				            $value = GFFormsModel::prepare_value( $form, $field, $value, $input_name, $entry['id'], array());
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
1326
				        }
1327 1
1328
				    } else {
1329
1330
				        // A file already exists when editing an entry
1331 1
				        // We set this to solve issue when file upload fields are required.
1332
				        GFFormsModel::$uploaded_files[ $form_id ][ $input_name ] = $value;
1333
1334
				    }
1335 1
1336
				    $this->entry[ $input_name ] = $value;
1337
				    $_POST[ $input_name ] = $value;
1338 1
1339
				    break;
1340
1341
				case 'number':
1342
				    // Fix "undefined index" issue at line 1286 in form_display.php
1343
				    if( !isset( $_POST['input_'.$field->id ] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
1344
				        $_POST['input_'.$field->id ] = NULL;
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
1345 1
				    }
1346
				    break;
1347
			}
1348
1349 1
		}
1350 1
1351
		return $form;
1352 1
	}
1353
1354 3
1355
	/**
1356 1
	 * Process validation for a edit entry submission
1357
	 *
1358
	 * Sets the `is_valid` object var
1359 3
	 *
1360
	 * @return void
1361
	 */
1362
	private function validate() {
1363
1364 3
		/**
1365
		 * If using GF User Registration Add-on, remove the validation step, otherwise generates error when updating the entry
1366
		 * GF User Registration Add-on version > 3.x has a different class name
1367
		 * @since 1.16.2
1368
		 */
1369
		if ( class_exists( 'GF_User_Registration' ) ) {
1370
			remove_filter( 'gform_validation', array( GF_User_Registration::get_instance(), 'validate' ) );
1371
		} else  if ( class_exists( 'GFUser' ) ) {
1372
			remove_filter( 'gform_validation', array( 'GFUser', 'user_registration_validation' ) );
1373
		}
1374
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1375 4
1376
		/**
1377
		 * For some crazy reason, Gravity Forms doesn't validate Edit Entry form submissions.
1378
		 * You can enter whatever you want!
1379
		 * We try validating, and customize the results using `self::custom_validation()`
1380
		 */
1381
		add_filter( 'gform_validation_'. $this->form_id, array( $this, 'custom_validation' ), 10, 4);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
1382 4
1383 4
		// Needed by the validate funtion
1384
		$failed_validation_page = NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
1385
		$field_values = RGForms::post( 'gform_field_values' );
1386
1387
		// Prevent entry limit from running when editing an entry, also
1388 4
		// prevent form scheduling from preventing editing
1389
		unset( $this->form['limitEntries'], $this->form['scheduleForm'] );
1390
1391
		// Hide fields depending on Edit Entry settings
1392
		$this->form['fields'] = $this->get_configured_edit_fields( $this->form, $this->view_id );
1393
1394
		$this->is_valid = GFFormDisplay::validate( $this->form, $field_values, 1, $failed_validation_page );
1395
1396
		remove_filter( 'gform_validation_'. $this->form_id, array( $this, 'custom_validation' ), 10 );
1397
	}
1398
1399 4
1400
	/**
1401
	 * Make validation work for Edit Entry
1402 4
	 *
1403 4
	 * Because we're calling the GFFormDisplay::validate() in an unusual way (as a front-end
1404
	 * form pretending to be a back-end form), validate() doesn't know we _can't_ edit post
1405
	 * fields. This goes through all the fields and if they're an invalid post field, we
1406
	 * set them as valid. If there are still issues, we'll return false.
1407 4
	 *
1408
	 * @param  [type] $validation_results [description]
1409
	 * @return [type]                     [description]
1410 4
	 */
1411
	public function custom_validation( $validation_results ) {
1412 4
1413
		gravityview()->log->debug( 'GravityView_Edit_Entry[custom_validation] Validation results: ', array( 'data' => $validation_results ) );
1414 4
1415 4
		gravityview()->log->debug( 'GravityView_Edit_Entry[custom_validation] $_POSTed data (sanitized): ', array( 'data' => esc_html( print_r( $_POST, true ) ) ) );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
1416 4
1417
		$gv_valid = true;
1418
1419
		foreach ( $validation_results['form']['fields'] as $key => &$field ) {
1420
1421
			$value = RGFormsModel::get_field_value( $field );
1422
			$field_type = RGFormsModel::get_input_type( $field );
1423
1424
			// Validate always
1425
			switch ( $field_type ) {
1426
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1427 3
1428 3
				case 'fileupload' :
1429
				case 'post_image':
1430 3
1431 3
				    // in case nothing is uploaded but there are already files saved
1432
				    if( !empty( $field->failed_validation ) && !empty( $field->isRequired ) && !empty( $value ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1433 3
				        $field->failed_validation = false;
1434
				        unset( $field->validation_message );
1435
				    }
1436
1437 3
				    // validate if multi file upload reached max number of files [maxFiles] => 2
1438 3
				    if( rgobj( $field, 'maxFiles') && rgobj( $field, 'multipleFiles') ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
1439
1440 3
				        $input_name = 'input_' . $field->id;
1441 3
				        //uploaded
1442
				        $file_names = isset( GFFormsModel::$uploaded_files[ $validation_results['form']['id'] ][ $input_name ] ) ? GFFormsModel::$uploaded_files[ $validation_results['form']['id'] ][ $input_name ] : array();
1443 3
1444 3
				        //existent
1445
				        $entry = $this->get_entry();
1446
				        $value = NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
1447
				        if( isset( $entry[ $field->id ] ) ) {
1448
				            $value = json_decode( $entry[ $field->id ], true );
1449
				        }
1450 3
1451 3
				        // count uploaded files and existent entry files
1452
				        $count_files = count( $file_names ) + count( $value );
1453
1454
				        if( $count_files > $field->maxFiles ) {
1455
				            $field->validation_message = __( 'Maximum number of files reached', 'gravityview' );
1456
				            $field->failed_validation = 1;
1457
				            $gv_valid = false;
1458 3
1459
				            // in case of error make sure the newest upload files are removed from the upload input
1460 3
				            GFFormsModel::$uploaded_files[ $validation_results['form']['id'] ] = null;
1461
				        }
1462
1463
				    }
1464
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1465
1466
				    break;
1467
1468
			}
1469
1470
			// This field has failed validation.
1471
			if( !empty( $field->failed_validation ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1472
1473
				gravityview()->log->debug( 'GravityView_Edit_Entry[custom_validation] Field is invalid.', array( 'data' => array( 'field' => $field, 'value' => $value ) ) );
1474 4
1475
				switch ( $field_type ) {
1476 4
1477
				    // Captchas don't need to be re-entered.
1478 4
				    case 'captcha':
1479
1480 4
				        // Post Image fields aren't editable, so we un-fail them.
1481
				    case 'post_image':
1482 4
				        $field->failed_validation = false;
1483
				        unset( $field->validation_message );
1484 4
				        break;
1485 4
1486
				}
1487
1488
				// You can't continue inside a switch, so we do it after.
1489
				if( empty( $field->failed_validation ) ) {
1490
				    continue;
1491 4
				}
1492 4
1493
				// checks if the No Duplicates option is not validating entry against itself, since
1494
				// we're editing a stored entry, it would also assume it's a duplicate.
1495 2
				if( !empty( $field->noDuplicates ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1496
1497
				    $entry = $this->get_entry();
1498
1499
				    // If the value of the entry is the same as the stored value
1500
				    // Then we can assume it's not a duplicate, it's the same.
1501 2
				    if( !empty( $entry ) && $value == $entry[ $field->id ] ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1502
				        //if value submitted was not changed, then don't validate
1503
				        $field->failed_validation = false;
1504
1505
				        unset( $field->validation_message );
1506
1507
				        gravityview()->log->debug( 'GravityView_Edit_Entry[custom_validation] Field not a duplicate; it is the same entry.', array( 'data' => $entry ) );
1508
1509
				        continue;
1510
				    }
1511
				}
1512
1513
				// if here then probably we are facing the validation 'At least one field must be filled out'
1514
				if( GFFormDisplay::is_empty( $field, $this->form_id  ) && empty( $field->isRequired ) ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 2 found
Loading history...
1515
				    unset( $field->validation_message );
1516
	                $field->validation_message = false;
1517
				    continue;
1518
				}
1519
1520
				$gv_valid = false;
1521
1522
			}
1523
1524
		}
1525
1526
		$validation_results['is_valid'] = $gv_valid;
1527
1528
		gravityview()->log->debug( 'GravityView_Edit_Entry[custom_validation] Validation results.', array( 'data' => $validation_results ) );
1529 2
1530
		// We'll need this result when rendering the form ( on GFFormDisplay::get_form )
1531
		$this->form_after_validation = $validation_results['form'];
1532
1533
		return $validation_results;
1534 4
	}
1535
1536 1
1537
	/**
1538
	 * TODO: This seems to be hacky... we should remove it. Entry is set when updating the form using setup_vars()!
1539
	 * Get the current entry and set it if it's not yet set.
1540
	 * @return array Gravity Forms entry array
1541 1
	 */
1542
	public function get_entry() {
1543
1544 1
		if( empty( $this->entry ) ) {
1545
			// Get the database value of the entry that's being edited
1546
			$this->entry = gravityview_get_entry( GravityView_frontend::is_single_entry() );
1547
		}
1548
1549
		return $this->entry;
1550
	}
1551
1552 1
1553
1554
	// --- Filters
1555
1556
	/**
1557
	 * Get the Edit Entry fields as configured in the View
1558 1
	 *
1559
	 * @since 1.8
1560
	 *
1561
	 * @param int $view_id
1562
	 *
1563
	 * @return array Array of fields that are configured in the Edit tab in the Admin
1564
	 */
1565
	private function get_configured_edit_fields( $form, $view_id ) {
1566
1567
		// Get all fields for form
1568
		if ( \GV\View::exists( $view_id ) ) {
1569
			$view = \GV\View::by_id( $view_id );
1570
			$properties = $view->fields ? $view->fields->as_configuration() : array();
1571
		} else {
1572
			$properties = null;
1573
		}
1574
1575
		// If edit tab not yet configured, show all fields
1576
		$edit_fields = !empty( $properties['edit_edit-fields'] ) ? $properties['edit_edit-fields'] : NULL;
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
1577 1
1578
		// Hide fields depending on admin settings
1579
		$fields = $this->filter_fields( $form['fields'], $edit_fields );
1580
1581
	    // If Edit Entry fields are configured, remove adminOnly field settings. Otherwise, don't.
1582
	    $fields = $this->filter_admin_only_fields( $fields, $edit_fields, $form, $view_id );
1583 4
1584
		/**
1585
		 * @filter `gravityview/edit_entry/form_fields` Modify the fields displayed in Edit Entry form
1586
		 * @since 1.17
1587
		 * @param GF_Field[] $fields Gravity Forms form fields
1588
		 * @param array|null $edit_fields Fields for the Edit Entry tab configured in the View Configuration
1589 4
		 * @param array $form GF Form array (`fields` key modified to have only fields configured to show in Edit Entry)
1590
		 * @param int $view_id View ID
1591 4
		 */
1592
		$fields = apply_filters( 'gravityview/edit_entry/form_fields', $fields, $edit_fields, $form, $view_id );
1593
1594 4
		return $fields;
1595
	}
1596 4
1597
1598
	/**
1599
	 * Filter area fields based on specified conditions
1600
	 *  - This filter removes the fields that have calculation configured
1601
	 *
1602
	 * @uses GravityView_Edit_Entry::user_can_edit_field() Check caps
1603
	 * @access private
1604
	 * @param GF_Field[] $fields
1605 3
	 * @param array $configured_fields
1606
	 * @since  1.5
1607 3
	 * @return array $fields
1608
	 */
1609 1
	private function filter_fields( $fields, $configured_fields ) {
1610
1611
		if( empty( $fields ) || !is_array( $fields ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1612 3
			return $fields;
1613
		}
1614
1615
		$edit_fields = array();
1616
1617
		$field_type_blacklist = $this->loader->get_field_blacklist( $this->entry );
1618
1619
		// First, remove blacklist or calculation fields
1620
		foreach ( $fields as $key => $field ) {
1621
1622
			// Remove the fields that have calculation properties and keep them to be used later
1623
			// @since 1.16.2
1624
			if( $field->has_calculation() ) {
1625
				$this->fields_with_calculation[] = $field;
1626
				// don't remove the calculation fields on form render.
1627
			}
1628 4
1629
			if( in_array( $field->type, $field_type_blacklist ) ) {
1630
				unset( $fields[ $key ] );
1631 4
			}
1632 4
		}
1633 4
1634 4
		// The Edit tab has not been configured, so we return all fields by default.
1635
		if( empty( $configured_fields ) ) {
1636
			return $fields;
1637
		}
1638
1639
		// The edit tab has been configured, so we loop through to configured settings
1640
		foreach ( $configured_fields as $configured_field ) {
1641
1642 4
	        /** @var GF_Field $field */
1643
	        foreach ( $fields as $field ) {
1644
1645 4
				if( intval( $configured_field['id'] ) === intval( $field->id ) && $this->user_can_edit_field( $configured_field, false ) ) {
1646
				    $edit_fields[] = $this->merge_field_properties( $field, $configured_field );
1647
				    break;
1648 4
				}
1649
1650
			}
1651
1652
		}
1653
1654
		return $edit_fields;
1655
1656
	}
1657
1658 4
	/**
1659
	 * Override GF Form field properties with the ones defined on the View
1660 4
	 * @param  GF_Field $field GF Form field object
1661
	 * @param  array $field_setting  GV field options
1662
	 * @since  1.5
1663
	 * @return array|GF_Field
1664
	 */
1665
	private function merge_field_properties( $field, $field_setting ) {
1666
1667
		$return_field = $field;
1668
1669
		if( empty( $field_setting['show_label'] ) ) {
1670
			$return_field->label = '';
1671
		} elseif ( !empty( $field_setting['custom_label'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1672
			$return_field->label = $field_setting['custom_label'];
1673
		}
1674
1675 3
		if( !empty( $field_setting['custom_class'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1676
			$return_field->cssClass .= ' '. gravityview_sanitize_html_class( $field_setting['custom_class'] );
1677 3
		}
1678
1679
		/**
1680
		 * Normalize page numbers - avoid conflicts with page validation
1681 3
		 * @since 1.6
1682
		 */
1683 3
		$return_field->pageNumber = 1;
1684
1685
		return $return_field;
1686 3
1687
	}
1688
1689
	/**
1690 3
	 * Remove fields that shouldn't be visible based on the Gravity Forms adminOnly field property
1691
	 *
1692
	 * @since 1.9.1
1693
	 *
1694
	 * @param array|GF_Field[] $fields Gravity Forms form fields
1695 3
	 * @param array|null $edit_fields Fields for the Edit Entry tab configured in the View Configuration
1696 3
	 * @param array $form GF Form array
1697
	 * @param int $view_id View ID
1698
	 *
1699
	 * @return array Possibly modified form array
1700
	 */
1701 3
	private function filter_admin_only_fields( $fields = array(), $edit_fields = null, $form = array(), $view_id = 0 ) {
1702 3
1703
	    /**
1704
		 * @filter `gravityview/edit_entry/use_gf_admin_only_setting` When Edit tab isn't configured, should the Gravity Forms "Admin Only" field settings be used to control field display to non-admins? Default: true
1705
	     * If the Edit Entry tab is not configured, adminOnly fields will not be shown to non-administrators.
1706
	     * If the Edit Entry tab *is* configured, adminOnly fields will be shown to non-administrators, using the configured GV permissions
1707
	     * @since 1.9.1
1708
	     * @param boolean $use_gf_adminonly_setting True: Hide field if set to Admin Only in GF and the user is not an admin. False: show field based on GV permissions, ignoring GF permissions.
1709
	     * @param array $form GF Form array
1710
	     * @param int $view_id View ID
1711
	     */
1712
	    $use_gf_adminonly_setting = apply_filters( 'gravityview/edit_entry/use_gf_admin_only_setting', empty( $edit_fields ), $form, $view_id );
1713
1714
	    if( $use_gf_adminonly_setting && false === GVCommon::has_cap( 'gravityforms_edit_entries', $this->entry['id'] ) ) {
1715
			foreach( $fields as $k => $field ) {
1716
				if( $field->adminOnly ) {
1717
				    unset( $fields[ $k ] );
1718
				}
1719
			}
1720
			return $fields;
1721
		}
1722
1723
	    foreach( $fields as &$field ) {
1724
		    $field->adminOnly = false;
1725
		}
1726
1727
		return $fields;
1728
	}
1729
1730
	// --- Conditional Logic
1731
1732
	/**
1733
	 * Conditional logic isn't designed to work with forms that already have content. When switching input values,
1734
	 * the dependent fields will be blank.
1735
	 *
1736
	 * Note: This is because GF populates a JavaScript variable with the input values. This is tough to filter at the input level;
1737
	 * via the `gform_field_value` filter; it requires lots of legwork. Doing it at the form level is easier.
1738
	 *
1739
	 * @since 1.17.4
1740
	 *
1741
	 * @param array $form Gravity Forms array object
1742
	 *
1743
	 * @return array $form, modified to fix conditional
1744
	 */
1745
	function prefill_conditional_logic( $form ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1746
1747
		if( ! GFFormDisplay::has_conditional_logic( $form ) ) {
1748
			return $form;
1749
		}
1750
1751
		// Have Conditional Logic pre-fill fields as if the data were default values
1752
		/** @var GF_Field $field */
1753
		foreach ( $form['fields'] as &$field ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
1754
1755
			if( 'checkbox' === $field->type ) {
1756
				foreach ( $field->get_entry_inputs() as $key => $input ) {
1757
				    $input_id = $input['id'];
1758
				    $choice = $field->choices[ $key ];
1759
				    $value = \GV\Utils::get( $this->entry, $input_id );
1760
				    $match = RGFormsModel::choice_value_match( $field, $choice, $value );
1761
				    if( $match ) {
1762
				        $field->choices[ $key ]['isSelected'] = true;
1763
				    }
1764
				}
1765
			} else {
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
1766
1767 3
				// We need to run through each field to set the default values
1768
				foreach ( $this->entry as $field_id => $field_value ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
1769
1770
				    if( floatval( $field_id ) === floatval( $field->id ) ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
1771
1772
				        if( 'list' === $field->type ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
1773
				            $list_rows = maybe_unserialize( $field_value );
1774
1775
				            $list_field_value = array();
1776
				            foreach ( (array) $list_rows as $row ) {
1777
				                foreach ( (array) $row as $column ) {
1778
				                    $list_field_value[] = $column;
1779
				                }
1780 3
				            }
1781
1782
<<<<<<< HEAD
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_SL
Loading history...
introduced by
Expected 1 space after "<<"; 0 found
Loading history...
introduced by
Expected 1 space before "<<"; 0 found
Loading history...
1783
							$field->defaultValue = serialize( $list_field_value ) ? : $field->defaultValue;
1784
						} else {
1785
							$field->defaultValue = $field_value ? : $field->defaultValue;
1786
						}
1787
					}
1788
=======
1789
				            $field->defaultValue = serialize( $list_field_value );
1790
				        } else {
1791 3
				            $field->defaultValue = $field_value;
1792
				        }
1793 3
				    }
1794
>>>>>>> master
1795
				}
1796
			}
1797
		}
1798
1799
		return $form;
1800
	}
1801
1802
	/**
1803
	 * Remove the conditional logic rules from the form button and the form fields, if needed.
1804
	 *
1805
	 * @todo Merge with caller method
1806
	 * @since 1.9
1807
	 *
1808
	 * @param array $form Gravity Forms form
1809 3
	 * @return array Modified form, if not using Conditional Logic
1810
	 */
1811
	private function filter_conditional_logic( $form ) {
1812 3
1813
		/**
1814
		 * @filter `gravityview/edit_entry/conditional_logic` Should the Edit Entry form use Gravity Forms conditional logic showing/hiding of fields?
1815
		 * @since 1.9
1816
		 * @param bool $use_conditional_logic True: Gravity Forms will show/hide fields just like in the original form; False: conditional logic will be disabled and fields will be shown based on configuration. Default: true
1817
		 * @param array $form Gravity Forms form
1818
		 */
1819
		$use_conditional_logic = apply_filters( 'gravityview/edit_entry/conditional_logic', true, $form );
1820
1821
		if( $use_conditional_logic ) {
1822
			return $form;
1823
		}
1824
1825
		foreach( $form['fields'] as &$field ) {
1826 3
			/* @var GF_Field $field */
1827
			$field->conditionalLogic = null;
1828 3
		}
1829
1830
		unset( $form['button']['conditionalLogic'] );
1831
1832 3
		return $form;
1833
1834
	}
1835
1836
	/**
1837
	 * Disable the Gravity Forms conditional logic script and features on the Edit Entry screen
1838
	 *
1839
	 * @since 1.9
1840
	 *
1841
	 * @param $has_conditional_logic
1842
	 * @param $form
1843
	 * @return mixed
1844
	 */
1845
	public function manage_conditional_logic( $has_conditional_logic, $form ) {
1846
1847
		if( ! $this->is_edit_entry() ) {
1848
			return $has_conditional_logic;
1849
		}
1850 3
1851
	    /** @see GravityView_Edit_Entry_Render::filter_conditional_logic for filter documentation */
1852 3
		return apply_filters( 'gravityview/edit_entry/conditional_logic', $has_conditional_logic, $form );
1853 3
	}
1854
1855
1856
	// --- User checks and nonces
1857
1858
	/**
1859
	 * Check if the user can edit the entry
1860
	 *
1861
	 * - Is the nonce valid?
1862
	 * - Does the user have the right caps for the entry
1863
	 * - Is the entry in the trash?
1864
	 *
1865
	 * @todo Move to GVCommon
1866
	 *
1867
	 * @param  boolean $echo Show error messages in the form?
1868
	 * @return boolean        True: can edit form. False: nope.
1869
	 */
1870
	private function user_can_edit_entry( $echo = false ) {
1871
1872
		$error = NULL;
1873
1874
		/**
1875
		 *  1. Permalinks are turned off
1876
		 *  2. There are two entries embedded using oEmbed
1877
		 *  3. One of the entries has just been saved
1878
		 */
1879
		if( !empty( $_POST['lid'] ) && !empty( $_GET['entry'] ) && ( $_POST['lid'] !== $_GET['entry'] ) ) {
1880
1881
			$error = true;
1882
1883
		}
1884
1885
		if( !empty( $_GET['entry'] ) && (string)$this->entry['id'] !== $_GET['entry'] ) {
1886
1887
			$error = true;
1888
1889
		} elseif( ! $this->verify_nonce() ) {
1890
1891
			/**
1892
			 * If the Entry is embedded, there may be two entries on the same page.
1893
			 * If that's the case, and one is being edited, the other should fail gracefully and not display an error.
1894
			 */
1895
			if( GravityView_oEmbed::getInstance()->get_entry_id() ) {
1896
				$error = true;
1897
			} else {
1898
				$error = __( 'The link to edit this entry is not valid; it may have expired.', 'gravityview');
1899
			}
1900
1901
		}
1902
1903
		if( ! GravityView_Edit_Entry::check_user_cap_edit_entry( $this->entry ) ) {
1904
			$error = __( 'You do not have permission to edit this entry.', 'gravityview');
1905
		}
1906
1907
		if( $this->entry['status'] === 'trash' ) {
1908 3
			$error = __('You cannot edit the entry; it is in the trash.', 'gravityview' );
1909
		}
1910
1911
		// No errors; everything's fine here!
1912
		if( empty( $error ) ) {
1913
			return true;
1914
		}
1915
1916 3
		if( $echo && $error !== true ) {
1917
1918 3
	        $error = esc_html( $error );
1919 3
1920
	        /**
1921
	         * @since 1.9
1922
	         */
1923
	        if ( ! empty( $this->entry ) ) {
1924
		        $error .= ' ' . gravityview_get_link( '#', _x('Go back.', 'Link shown when invalid Edit Entry link is clicked', 'gravityview' ), array( 'onclick' => "window.history.go(-1); return false;" ) );
1925
	        }
1926
1927
			echo GVCommon::generate_notice( wpautop( $error ), 'gv-error error');
1928
		}
1929
1930
		gravityview()->log->error( '{error}', array( 'error' => $error ) );
1931
1932
		return false;
1933
	}
1934
1935
1936
	/**
1937
	 * Check whether a field is editable by the current user, and optionally display an error message
1938
	 * @uses  GravityView_Edit_Entry->check_user_cap_edit_field() Check user capabilities
1939
	 * @param  array  $field Field or field settings array
1940
	 * @param  boolean $echo  Whether to show error message telling user they aren't allowed
1941
	 * @return boolean         True: user can edit the current field; False: nope, they can't.
1942 3
	 */
1943
	private function user_can_edit_field( $field, $echo = false ) {
1944 3
1945
		$error = NULL;
1946
1947
		if( ! $this->check_user_cap_edit_field( $field ) ) {
1948
			$error = __( 'You do not have permission to edit this field.', 'gravityview');
1949 3
		}
1950
1951
		// No errors; everything's fine here!
1952
		if( empty( $error ) ) {
1953
			return true;
1954
		}
1955
1956
		if( $echo ) {
1957
			echo GVCommon::generate_notice( wpautop( esc_html( $error ) ), 'gv-error error');
1958
		}
1959
1960
		gravityview()->log->error( '{error}', array( 'error' => $error ) );
1961
1962
		return false;
1963
1964
	}
1965
1966
1967 4
	/**
1968
	 * checks if user has permissions to edit a specific field
1969 4
	 *
1970
	 * Needs to be used combined with GravityView_Edit_Entry::user_can_edit_field for maximum security!!
1971
	 *
1972
	 * @param  [type] $field [description]
1973
	 * @return bool
1974
	 */
1975
	private function check_user_cap_edit_field( $field ) {
1976 4
1977
		// If they can edit any entries (as defined in Gravity Forms), we're good.
1978
		if( GVCommon::has_cap( array( 'gravityforms_edit_entries', 'gravityview_edit_others_entries' ) ) ) {
1979
			return true;
1980
		}
1981
1982 4
		$field_cap = isset( $field['allow_edit_cap'] ) ? $field['allow_edit_cap'] : false;
1983
1984
		if( $field_cap ) {
1985
			return GVCommon::has_cap( $field['allow_edit_cap'] );
1986 4
		}
1987
1988
		return false;
1989
	}
1990
1991
1992
	/**
1993
	 * Is the current nonce valid for editing the entry?
1994
	 * @return boolean
1995
	 */
1996
	public function verify_nonce() {
1997
1998
		// Verify form submitted for editing single
1999
		if( $this->is_edit_entry_submission() ) {
2000 4
			$valid = wp_verify_nonce( $_POST[ self::$nonce_field ], self::$nonce_field );
2001 1
		}
2002
2003
		// Verify
2004 4
		else if( ! $this->is_edit_entry() ) {
2005
			$valid = false;
2006
		}
2007
2008
		else {
2009 4
			$valid = wp_verify_nonce( $_GET['edit'], self::$nonce_key );
2010 4
		}
2011
2012
		/**
2013 1
		 * @filter `gravityview/edit_entry/verify_nonce` Override Edit Entry nonce validation. Return true to declare nonce valid.
2014
		 * @since 1.13
2015 1
		 * @param int|boolean $valid False if invalid; 1 or 2 when nonce was generated
2016
		 * @param string $nonce_field Key used when validating submissions. Default: is_gv_edit_entry
2017
		 */
2018
		$valid = apply_filters( 'gravityview/edit_entry/verify_nonce', $valid, self::$nonce_field );
2019
2020 1
		return $valid;
2021 1
	}
2022
2023
2024 1
	/**
2025
	 * Multiselect in GF 2.2 became a json_encoded value. Fix it.
2026
	 *
2027 1
	 * As a hack for now we'll implode it back.
2028
	 */
2029 1
	public function fix_multiselect_value_serialization( $field_value, $field, $_this ) {
2030
		if ( empty ( $field->storageType ) || $field->storageType != 'json' ) {
2031
			return $field_value;
2032
		}
2033
2034
		$maybe_json = @json_decode( $field_value, true );
2035
2036
		if ( $maybe_json ) {
2037
			return implode( ',', $maybe_json );
2038
		}
2039
2040
		return $field_value;
2041
	}
2042
2043
2044
2045
} //end class
2046