Completed
Push — master ( ebef7a...94d09a )
by Zack
20:55 queued 16:56
created

process_bulk_action()   C

Complexity

Conditions 17
Paths 73

Size

Total Lines 70
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 17
eloc 33
c 3
b 1
f 0
nc 73
nop 0
dl 0
loc 70
rs 5.5823

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 15 and the first side effect is on line 831.

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
 * @file class-admin-approve-entries.php
4
 * @package   GravityView
5
 * @license   GPL2+
6
 * @author    Katz Web Services, Inc.
7
 * @link      http://gravityview.co
8
 * @copyright Copyright 2014, Katz Web Services, Inc.
9
 *
10
 * @since 1.0.0
11
 */
12
13
14
15
class GravityView_Admin_ApproveEntries {
16
17
	// hold notification messages
18
	public $bulk_update_message = '';
19
20
	/**
21
	 * @var array Set the prefixes here instead of spread across the class
22
	 * @since 1.17
23
	 */
24
	private $bulk_action_prefixes = array(
25
		'approve' => 'gvapprove',
26
		'unapprove' => 'gvunapprove',
27
	);
28
29
	function __construct() {
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...
30
31
		$this->add_hooks();
32
33
	}
34
35
	private function add_hooks() {
36
		/** Edit Gravity Form page */
37
38
		// Add button to left menu
39
		add_filter( 'gform_add_field_buttons', array( $this, 'add_field_buttons' ) );
40
		// Set defaults
41
		add_action( 'gform_editor_js_set_default_values', array( $this, 'set_defaults' ) );
42
43
		/** gf_entries page - entries table screen */
44
45
		// capture bulk actions
46
		add_action( 'gform_loaded', array( $this, 'process_bulk_action') );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
47
48
		// add hidden field with approve status
49
		add_action( 'gform_entries_first_column_actions', array( $this, 'add_entry_approved_hidden_input' ), 1, 5 );
50
51
		// process ajax approve entry requests
52
		add_action('wp_ajax_gv_update_approved', array( $this, 'ajax_update_approved'));
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...
introduced by
No space before closing parenthesis of array is bad style
Loading history...
53
54
		// when using the User opt-in field, check on entry submission
55
		add_action( 'gform_after_submission', array( $this, 'after_submission' ), 10, 2 );
56
57
		// in case entry is edited (on admin or frontend)
58
		add_action( 'gform_after_update_entry', array( $this, 'after_update_entry_update_approved_meta' ), 10, 2);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
59
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
60
61
		add_filter( 'gravityview_tooltips', array( $this, 'tooltips' ) );
62
63
		// adding styles and scripts
64
		add_action( 'admin_enqueue_scripts', array( $this, 'add_scripts_and_styles') );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
65
		// bypass Gravity Forms no-conflict mode
66
		add_filter( 'gform_noconflict_scripts', array( $this, 'register_gform_noconflict_script' ) );
67
		add_filter( 'gform_noconflict_styles', array( $this, 'register_gform_noconflict_style' ) );
68
69
		add_filter( 'gform_filter_links_entry_list', array( $this, 'filter_links_entry_list' ), 10, 3 );
70
	}
71
72
	/**
73
	 * Add filter links to the Entries page
74
	 *
75
	 * Can be disabled by returning false on the `gravityview/approve_entries/show_filter_links_entry_list` filter
76
	 *
77
	 * @since 1.17.1
78
	 *
79
	 * @param array $filter_links Array of links to include in the subsubsub filter list. Includes `id`, `field_filters`, `count`, and `label` keys
80
	 * @param array $form GF Form object of current form
81
	 * @param bool $include_counts Whether to include counts in the output
82
	 *
83
	 * @return array Filter links, with GravityView approved/disapproved links added
84
	 */
85
	public function filter_links_entry_list( $filter_links = array(), $form = array(), $include_counts = true ) {
86
87
		/**
88
		 * @filter `gravityview/approve_entries/show_filter_links_entry_list` Disable filter links
89
		 * @since 1.17.1
90
		 * @param bool $show_filter_links True: show the "approved"/"disapproved" filter links. False: hide them.
91
		 * @param array $form GF Form object of current form
92
		 */
93
		if( false === apply_filters( 'gravityview/approve_entries/show_filter_links_entry_list', true, $form ) ) {
94
			return $filter_links;
95
		}
96
97
		$field_filters_approved = array(
98
			array(
99
				'key' => 'is_approved',
100
				'value' => 'Approved'
0 ignored issues
show
introduced by
Each line in an array declaration must end in a comma
Loading history...
101
			),
102
		);
103
104
		$field_filters_disapproved = array(
105
			array(
106
				'key'      => 'is_approved',
107
				'value'    => '0',
108
			),
109
		);
110
111
		$approved_count = $disapproved_count = 0;
112
113
		// Only count if necessary
114
		if( $include_counts ) {
115
			$approved_count = count( gravityview_get_entry_ids( $form['id'], array( 'status' => 'active', 'field_filters' => $field_filters_approved ) ) );
116
			$disapproved_count = count( gravityview_get_entry_ids( $form['id'], array( 'status' => 'active', 'field_filters' => $field_filters_disapproved ) ) );
117
		}
118
119
		$filter_links[] = array(
120
			'id'            => 'gv_approved',
121
			'field_filters' => $field_filters_approved,
122
			'count'         => $approved_count,
123
			'label'         => esc_html__( 'Approved', 'gravityview' ),
124
		);
125
126
		$filter_links[] = array(
127
			'id'            => 'gv_disapproved',
128
			'field_filters' => $field_filters_disapproved,
129
			'count'         => $disapproved_count,
130
			'label'         => esc_html__( 'Disapproved', 'gravityview' ),
131
		);
132
133
		return $filter_links;
134
	}
135
136
	/**
137
	 * Add the GravityView Fields group tooltip
138
	 *
139
	 * @param $tooltips
140
	 *
141
	 * @return array Tooltips array with GravityView fields tooltip
142
	 */
143
	function tooltips( $tooltips ) {
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...
144
145
		$tooltips['form_gravityview_fields'] = array(
146
			'title' => __('GravityView Fields', '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...
147
			'value' => __( 'Allow administrators to approve or reject entries and users to opt-in or opt-out of their entries being displayed.', 'gravityview'),
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
148
		);
149
150
		return $tooltips;
151
	}
152
153
154
	/**
155
	 * Inject new add field buttons in the gravity form editor page
156
	 *
157
	 * @access public
158
	 * @param mixed $field_groups
159
	 * @return array Array of fields
160
	 */
161
	function add_field_buttons( $field_groups ) {
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...
162
163
		$gravityview_fields = array(
164
			'name' => 'gravityview_fields',
165
			'label' => 'GravityView',
166
			'fields' => array(
167
				array(
168
					'class' => 'button',
169
					'value' => __( 'Approve/Reject', 'gravityview' ),
170
					'onclick' => "StartAddField('gravityviewapproved_admin');",
171
					'data-type' => 'gravityviewapproved_admin'
0 ignored issues
show
introduced by
Each line in an array declaration must end in a comma
Loading history...
172
				),
173
				array(
174
					'class' => 'button',
175
					'value' => __( 'User Opt-In', 'gravityview' ),
176
					'onclick' => "StartAddField('gravityviewapproved');",
177
					'data-type' => 'gravityviewapproved'
0 ignored issues
show
introduced by
Each line in an array declaration must end in a comma
Loading history...
178
				),
179
			)
180
		);
181
182
		array_push( $field_groups, $gravityview_fields );
183
184
		return $field_groups;
185
	}
186
187
188
189
	/**
190
	 * At edit form page, set the field Approve defaults
191
	 *
192
	 * @todo Convert to a partial include file
193
	 * @access public
194
	 * @return void
195
	 */
196
	function set_defaults() {
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...
197
		?>
198
		case 'gravityviewapproved_admin':
199
			field.label = "<?php echo esc_js( __( 'Approved? (Admin-only)', 'gravityview' ) ); ?>";
200
201
			field.adminLabel = "<?php echo esc_js( __( 'Approved?', 'gravityview' ) ); ?>";
202
			field.adminOnly = true;
203
204
			field.choices = null;
205
			field.inputs = null;
206
207
			if( !field.choices ) {
208
				field.choices = new Array( new Choice("<?php _e( 'Approved', 'gravityview' ); ?>") );
209
			}
210
211
			field.inputs = new Array();
212
			for( var i=1; i<=field.choices.length; i++ ) {
213
				field.inputs.push(new Input(field.id + (i/10), field.choices[i-1].text));
214
			}
215
216
			field.type = 'checkbox';
217
			field.gravityview_approved = 1;
218
219
			break;
220
		case 'gravityviewapproved':
221
			field.label = "<?php echo esc_js( __( 'Show Entry on Website', 'gravityview' ) ); ?>";
222
223
			field.adminLabel = "<?php echo esc_js( __( 'Opt-In', 'gravityview' ) ); ?>";
224
			field.adminOnly = false;
225
226
			field.choices = null;
227
			field.inputs = null;
228
229
			if( !field.choices ) {
230
				field.choices = new Array(
231
					new Choice("<?php echo esc_js( __( 'Yes, display my entry on the website', 'gravityview' ) ); ?>")
232
				);
233
			}
234
235
			field.inputs = new Array();
236
			for( var i=1; i<=field.choices.length; i++ ) {
237
				field.inputs.push(new Input(field.id + (i/10), field.choices[i-1].text));
238
			}
239
240
			field.type = 'checkbox';
241
			field.gravityview_approved = 1;
242
243
			break;
244
		<?php
245
	}
246
247
	/**
248
	 * Get the Bulk Action submitted value if it is a GravityView Approve/Unapprove action
249
	 *
250
	 * @since 1.17.1
251
	 *
252
	 * @return string|false If the bulk action was GravityView Approve/Unapprove, return the full string (gvapprove-16, gvunapprove-16). Otherwise, return false.
253
	 */
254
	private function get_gv_bulk_action() {
255
256
		$gv_bulk_action = false;
257
258
		if( version_compare( GFForms::$version, '2.0', '>=' ) ) {
259
			$bulk_action = ( '-1' !== rgpost('action') ) ? rgpost('action') : rgpost('action2');
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...
260
		} else {
261
			// GF 1.9.x - Bulk action 2 is the bottom bulk action select form.
262
			$bulk_action = rgpost('bulk_action') ? rgpost('bulk_action') : rgpost('bulk_action2');
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...
263
		}
264
265
		// Check the $bulk_action value against GV actions, see if they're the same. I hate strpos().
266
		if( ! empty( $bulk_action ) && preg_match( '/^('. implode( '|', $this->bulk_action_prefixes ) .')/ism', $bulk_action ) ) {
267
			$gv_bulk_action = $bulk_action;
268
		}
269
270
		return $gv_bulk_action;
271
	}
272
273
	/**
274
	 * Capture bulk actions - gf_entries table
275
	 *
276
	 * @uses  GravityView_frontend::get_search_criteria() Convert the $_POST search request into a properly formatted request.
277
	 * @access public
278
	 * @return void|boolean
279
	 */
280
	public function process_bulk_action() {
281
282
		if ( ! is_admin() || ! class_exists( 'GFForms' ) || empty( $_POST ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
283
			return false;
284
		}
285
286
		// The action is formatted like: gvapprove-16 or gvunapprove-16, where the first word is the name of the action and the second is the ID of the form.
287
		$bulk_action = $this->get_gv_bulk_action();
288
		
289
		// gforms_entry_list is the nonce that confirms we're on the right page
290
		// gforms_update_note is sent when bulk editing entry notes. We don't want to process then.
291
		if ( $bulk_action && rgpost('gforms_entry_list') && empty( $_POST['gforms_update_note'] ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $bulk_action of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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...
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
292
293
			check_admin_referer( 'gforms_entry_list', 'gforms_entry_list' );
294
295
			/**
296
			 * The extra '-' is to make sure that there are at *least* two items in array.
297
			 * @see https://github.com/katzwebservices/GravityView/issues/370
298
			 */
299
			$bulk_action .= '-';
300
301
			list( $approved_status, $form_id ) = explode( '-', $bulk_action );
302
303
			if ( empty( $form_id ) ) {
304
				do_action( 'gravityview_log_error', '[process_bulk_action] Form ID is empty from parsing bulk action.', $bulk_action );
305
				return false;
306
			}
307
308
			// All entries are set to be updated, not just the visible ones
309
			if ( ! empty( $_POST['all_entries'] ) ) {
310
311
				// Convert the current entry search into GF-formatted search criteria
312
				$search = array(
313
					'search_field' => isset( $_POST['f'] ) ? $_POST['f'][0] : 0,
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...
314
					'search_value' => isset( $_POST['v'][0] ) ? $_POST['v'][0] : '',
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...
315
					'search_operator' => isset( $_POST['o'][0] ) ? $_POST['o'][0] : 'contains',
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...
316
				);
317
318
				$search_criteria = GravityView_frontend::get_search_criteria( $search, $form_id );
319
320
				// Get all the entry IDs for the form
321
				$entries = gravityview_get_entry_ids( $form_id, $search_criteria );
322
323
			} else {
324
325
				// Changed from 'lead' to 'entry' in 2.0
326
				$entries = isset( $_POST['lead'] ) ? $_POST['lead'] : $_POST['entry'];
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...
327
328
			}
329
330
			if ( empty( $entries ) ) {
331
				do_action( 'gravityview_log_error', '[process_bulk_action] Entries are empty' );
332
				return false;
333
			}
334
335
			$entry_count = count( $entries ) > 1 ? sprintf( __( '%d entries', 'gravityview' ), count( $entries ) ) : __( '1 entry', 'gravityview' );
336
337
			switch ( $approved_status ) {
338
				case $this->bulk_action_prefixes['approve']:
339
					self::update_bulk( $entries, 1, $form_id );
340
					$this->bulk_update_message = sprintf( __( '%s approved.', 'gravityview' ), $entry_count );
341
					break;
342
343
				case $this->bulk_action_prefixes['unapprove']:
344
					self::update_bulk( $entries, 0, $form_id );
345
					$this->bulk_update_message = sprintf( __( '%s disapproved.', 'gravityview' ), $entry_count );
346
					break;
347
			}
348
		}
349
	}
350
351
352
353
354
355
	/**
356
	 * Process a bulk of entries to update the approve field/property
357
	 *
358
	 * @access private
359
	 * @static
360
	 * @param array|boolean $entries If array, array of entry IDs that are to be updated. If true: update all entries.
361
	 * @param int $approved Approved status. If `0`: unapproved, if not empty, `Approved`
362
	 * @param int $form_id The Gravity Forms Form ID
363
	 * @return boolean|void
364
	 */
365
	private static function update_bulk( $entries, $approved, $form_id ) {
366
367
		if( empty($entries) || ( $entries !== true && !is_array($entries) ) ) {
0 ignored issues
show
introduced by
Found "!== true". Use Yoda Condition checks, you must
Loading history...
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...
introduced by
Expected 1 space after "!"; 0 found
Loading history...
368
			do_action( 'gravityview_log_error', __METHOD__ . ' Entries were empty or malformed.', $entries );
369
			return false;
370
		}
371
372
		if( ! GVCommon::has_cap( 'gravityview_moderate_entries' ) ) {
373
			do_action( 'gravityview_log_error', __METHOD__ . ' User does not have the `gravityview_moderate_entries` capability.' );
374
			return false;
375
		}
376
377
		$approved = empty( $approved ) ? 0 : 'Approved';
378
379
		// calculate approved field id once instead of looping through in the update_approved() method
380
		$approved_column_id = self::get_approved_column( $form_id );
381
382
		foreach( $entries as $entry_id ) {
0 ignored issues
show
Bug introduced by
The expression $entries of type boolean|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
383
			self::update_approved( (int)$entry_id, $approved, $form_id, $approved_column_id );
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
384
		}
385
	}
386
387
388
389
390
	/**
391
	 * update_approved function.
392
	 *
393
	 * @access public
394
	 * @static
395
	 * @param int $entry_id (default: 0)
396
	 * @param int $approved (default: 0)
397
	 * @param int $form_id (default: 0)
398
	 * @param int $approvedcolumn (default: 0)
399
	 * @return boolean True: It worked; False: it failed
400
	 */
401
	public static function update_approved( $entry_id = 0, $approved = 0, $form_id = 0, $approvedcolumn = 0) {
402
403
		if( !class_exists( 'GFAPI' ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
404
			do_action( 'gravityview_log_error', __METHOD__ . 'GFAPI does not exist' );
405
			return false;
406
		}
407
408
		if( empty( $approvedcolumn ) ) {
409
			$approvedcolumn = self::get_approved_column( $form_id );
410
		}
411
412
		//get the entry
413
		$entry = GFAPI::get_entry( $entry_id );
414
415
		//update entry
416
		$entry[ (string)$approvedcolumn ] = $approved;
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
417
418
		/** @var bool|WP_Error $result */
419
		$result = GFAPI::update_entry( $entry );
420
421
		/**
422
		 * GFAPI::update_entry() doesn't trigger `gform_after_update_entry`, so we trigger updating the meta ourselves.
423
		 */
424
		self::update_approved_meta( $entry_id, $approved, $form_id );
425
426
		// add note to entry
427
		if( $result === true ) {
0 ignored issues
show
introduced by
Found "=== true". Use Yoda Condition checks, you must
Loading history...
428
429
			$note = empty( $approved ) ? __( 'Disapproved the Entry for GravityView', 'gravityview' ) : __( 'Approved the Entry for GravityView', 'gravityview' );
430
431
			/**
432
			 * @filter `gravityview/approve_entries/add-note` Add a note when the entry has been approved or disapproved?
433
			 * @since 1.16.3
434
			 * @param bool $add_note True: Yep, add that note! False: Do not, under any circumstances, add that note!
435
			 */
436
			$add_note = apply_filters( 'gravityview/approve_entries/add-note', true );
437
438
			if( $add_note && class_exists( 'GravityView_Entry_Notes' ) ) {
439
				$current_user = wp_get_current_user();
440
				GravityView_Entry_Notes::add_note( $entry_id, $current_user->ID, $current_user->display_name, $note );
441
			}
442
443
			/**
444
			 * Destroy the cache for this form
445
			 * @see class-cache.php
446
			 * @since 1.5.1
447
			 */
448
			do_action( 'gravityview_clear_form_cache', $form_id );
449
450
		} else if( is_wp_error( $result ) ) {
451
452
			do_action( 'gravityview_log_error', __METHOD__ . sprintf( ' - Entry approval not updated: %s', $result->get_error_message() ) );
453
454
			$result = false;
455
		}
456
457
		return $result;
458
459
	}
460
461
462
	/**
463
	 * Update the is_approved meta whenever the entry is submitted (and it contains a User Opt-in field)
464
	 *
465
	 * @since 1.16.6
466
	 *
467
	 * @param $entry array Gravity Forms entry object
468
	 * @param $form array Gravity Forms form object
469
	 */
470
	public function after_submission( $entry, $form ) {
471
		$this->after_update_entry_update_approved_meta( $form , $entry['id'] );
472
	}
473
474
475
476
	/**
477
	 * Update the is_approved meta whenever the entry is updated
478
	 *
479
	 * @since 1.7.6.1 Was previously named `update_approved_meta`
480
	 *
481
	 * @param  array $form     Gravity Forms form array
482
	 * @param  int $entry_id ID of the Gravity Forms entry
483
	 * @return void
484
	 */
485
	public function after_update_entry_update_approved_meta( $form, $entry_id = NULL ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
486
487
		$approvedcolumn = self::get_approved_column( $form['id'] );
488
489
        /**
490
         * If the form doesn't contain the approve field, don't assume anything.
491
         */
492
        if( empty( $approvedcolumn ) ) {
493
            return;
494
        }
495
496
		$entry = GFAPI::get_entry( $entry_id );
497
498
		self::update_approved_meta( $entry_id, $entry[ (string)$approvedcolumn ], $form['id'] );
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
499
500
	}
501
502
	/**
503
	 * Update the `is_approved` entry meta value
504
	 *
505
	 * @since 1.7.6.1 `after_update_entry_update_approved_meta` was previously to be named `update_approved_meta`
506
	 * @since 1.17.1 Added $form_id parameter
507
	 *
508
	 * @param  int $entry_id ID of the Gravity Forms entry
509
	 * @param  string $is_approved String whether entry is approved or not. `0` for not approved, `Approved` for approved.
510
	 * @param int $form_id ID of the form of the entry being updated. Improves query performance.
511
	 *
512
	 * @return void
513
	 */
514
	private static function update_approved_meta( $entry_id, $is_approved, $form_id = 0 ) {
515
516
		/**
517
		 * Make sure that the "User Opt-in" and the Admin Approve/Reject entry set the same meta value
518
		 * @since 1.16.6
519
		 */
520
		$is_approved = empty( $is_approved ) ? 0 : 'Approved';
521
522
		// update entry meta
523
		if( function_exists('gform_update_meta') ) {
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...
524
525
			gform_update_meta( $entry_id, 'is_approved', $is_approved, $form_id );
526
527
			/**
528
			 * @action `gravityview/approve_entries/updated` Triggered when an entry approval is updated
529
			 * @since 1.7.6.1
530
			 * @param  int $entry_id ID of the Gravity Forms entry
531
			 * @param  string $is_approved String whether entry is approved or not. `0` for not approved, `Approved` for approved.
532
			 */
533
			do_action( 'gravityview/approve_entries/updated', $entry_id, $is_approved );
534
535
			if( empty( $is_approved ) ) {
536
537
				/**
538
				 * @action `gravityview/approve_entries/disapproved` Triggered when an entry is rejected
539
				 * @since 1.7.6.1
540
				 * @param  int $entry_id ID of the Gravity Forms entry
541
				 */
542
				do_action( 'gravityview/approve_entries/disapproved', $entry_id );
543
544
			} else {
545
546
				/**
547
				 * @action `gravityview/approve_entries/approved` Triggered when an entry is approved
548
				 * @since 1.7.6.1
549
				 * @param  int $entry_id ID of the Gravity Forms entry
550
				 */
551
				do_action( 'gravityview/approve_entries/approved', $entry_id );
552
553
			}
1 ignored issue
show
introduced by
Blank line found after control structure
Loading history...
554
555
		} else {
556
557
			do_action('gravityview_log_error', __METHOD__ . ' - `gform_update_meta` does not exist.' );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
558
559
		}
560
	}
561
562
563
	/**
564
	 * Approve/Disapprove entries using the × or ✓ icons in the GF Entries screen
565
	 * @return void
566
	 */
567
	public function ajax_update_approved() {
568
569
		if( empty( $_POST['entry_id'] ) || empty( $_POST['form_id'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
570
571
			do_action( 'gravityview_log_error', __METHOD__ . ' entry_id or form_id are empty.', $_POST );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
572
573
			$result = false;
574
		}
575
576
		else if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'gravityview_ajaxgfentries' ) ) {
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...
577
578
			do_action( 'gravityview_log_error', __METHOD__ . ' Security check failed.', $_POST );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
579
580
			$result = false;
581
		}
582
583
		else if( ! GVCommon::has_cap( 'gravityview_moderate_entries', $_POST['entry_id'] ) ) {
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...
584
585
			do_action( 'gravityview_log_error', __METHOD__ . ' User does not have the `gravityview_moderate_entries` capability.' );
586
587
			$result = false;
588
		}
589
590
		else {
591
592
			$result = self::update_approved( $_POST['entry_id'], $_POST['approved'], $_POST['form_id'] );
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...
introduced by
Detected usage of a non-validated input variable: $_POST
Loading history...
593
594
			if( is_wp_error( $result ) ) {
595
				/** @var WP_Error $result */
596
				do_action( 'gravityview_log_error', __METHOD__ .' Error updating approval: ' . $result->get_error_message() );
597
				$result = false;
598
			}
1 ignored issue
show
introduced by
Blank line found after control structure
Loading history...
599
600
		}
601
602
		exit( $result );
0 ignored issues
show
Coding Style Compatibility introduced by
The method ajax_update_approved() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
603
	}
604
605
606
	/**
607
	 * Calculate the approve field.input id
608
	 *
609
	 * @access public
610
	 * @static
611
	 * @param mixed $form GF Form or Form ID
612
	 * @return false|null|string Returns the input ID of the approved field. Returns NULL if no approved fields were found. Returns false if $form_id wasn't set.
613
	 */
614
	static public function get_approved_column( $form ) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
615
616
        if( empty( $form ) ) {
617
            return null;
618
        }
619
620
        if( !is_array( $form ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
621
            $form = GVCommon::get_form( $form );
622
        }
623
624
		foreach( $form['fields'] as $key => $field ) {
625
626
            $field = (array) $field;
627
628
			if( !empty( $field['gravityview_approved'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
629
				if( !empty($field['inputs'][0]['id']) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
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...
630
					return $field['inputs'][0]['id'];
631
				}
632
			}
633
634
            // Note: This is just for backward compatibility from GF Directory plugin and old GV versions - when using i18n it may not work..
635
            if( 'checkbox' == $field['type'] && isset( $field['inputs'] ) && is_array( $field['inputs'] ) ) {
636
                foreach ( $field['inputs'] as $key2 => $input ) {
637
                    if ( strtolower( $input['label'] ) == 'approved' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
638
                        return $input['id'];
639
                    }
640
                }
641
            }
642
		}
643
644
		return null;
645
	}
646
647
	/**
648
	 * Add a hidden input that is used in the Javascript to show approved/disapproved entries checkbox
649
	 *
650
	 * See the /assets/js/admin-entries-list.js setInitialApprovedEntries method
651
	 *
652
	 * @param $form_id
653
	 * @param $field_id
654
	 * @param $value
655
	 * @param $entry
656
	 * @param $query_string
657
	 *
658
	 * @return void
659
	 */
660
	static public function add_entry_approved_hidden_input(  $form_id, $field_id, $value, $entry, $query_string ) {
0 ignored issues
show
Unused Code introduced by
The parameter $query_string is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
661
662
		if( ! GVCommon::has_cap( 'gravityview_moderate_entries', $entry['id'] ) ) {
663
			return;
664
		}
665
666
		if( empty( $entry['id'] ) ) {
667
			return;
668
		}
669
670
		if( gform_get_meta( $entry['id'], 'is_approved' ) ) {
671
			echo '<input type="hidden" class="entry_approved" id="entry_approved_'. $entry['id'] .'" value="true" />';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$entry'
Loading history...
672
		}
673
	}
674
675
	/**
676
	 * Get the form ID of the form currently being displayed
677
	 *
678
	 * @since 1.17.1
679
	 *
680
	 * @return int ID of the current form being displayed
681
	 */
682
	private function get_form_id() {
683
684
		$form_id = GFForms::get('id');
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...
685
686
		// If there are no forms identified, use the first form. That's how GF does it.
687
		if( empty( $form_id ) && class_exists('RGFormsModel') ) {
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...
688
			$forms = gravityview_get_forms();
689
			if( !empty( $forms ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
690
				$form_id = $forms[0]['id'];
691
			}
692
		}
693
694
		return absint( $form_id );
695
	}
696
697
698
	function add_scripts_and_styles( $hook ) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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...
699
700
		if( ! class_exists( 'RGForms' ) ) {
701
702
			do_action( 'gravityview_log_error', 'GravityView_Admin_ApproveEntries[add_scripts_and_styles] RGForms does not exist.' );
703
704
			return;
705
		}
706
707
		// enqueue styles & scripts gf_entries
708
		// But only if we're on the main Entries page, not on reports pages
709
		if( GFForms::get_page() !== 'entry_list' ) {
0 ignored issues
show
introduced by
Found "!== '". Use Yoda Condition checks, you must
Loading history...
710
			return;
711
		}
712
713
		$form_id = $this->get_form_id();
714
715
		wp_enqueue_style( 'gravityview_entries_list', plugins_url('assets/css/admin-entries-list.css', GRAVITYVIEW_FILE), array(), GravityView_Plugin::version );
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...
716
717
		$script_debug = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
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...
718
719
		wp_enqueue_script( 'gravityview_gf_entries_scripts', plugins_url('assets/js/admin-entries-list'.$script_debug.'.js', GRAVITYVIEW_FILE), array( 'jquery' ), GravityView_Plugin::version );
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...
720
721
		wp_localize_script( 'gravityview_gf_entries_scripts', 'gvGlobals', array(
722
			'nonce' => wp_create_nonce( 'gravityview_ajaxgfentries'),
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
723
			'form_id' => $form_id,
724
			'show_column' => (int)$this->show_approve_entry_column( $form_id ),
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
725
			'add_bulk_action' => (int)GVCommon::has_cap( 'gravityview_moderate_entries' ),
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
726
			'bulk_actions' => $this->get_bulk_actions( $form_id ),
727
			'bulk_message' => $this->bulk_update_message,
728
			'approve_title' => __( 'Entry not approved for directory viewing. Click to approve this entry.', 'gravityview'),
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
729
			'unapprove_title' => __( 'Entry approved for directory viewing. Click to disapprove this entry.', 'gravityview'),
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
730
			'column_title' => __( 'Show entry in directory view?', 'gravityview'),
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
731
			'column_link' => esc_url( add_query_arg( array('sort' => self::get_approved_column( $form_id ) ) ) ),
0 ignored issues
show
introduced by
No space after opening parenthesis of array is bad style
Loading history...
732
		) );
733
734
	}
735
736
	/**
737
	 * Get an array of options to be added to the Gravity Forms "Bulk action" dropdown in a "GravityView" option group
738
	 *
739
	 * @since 1.16.3
740
	 *
741
	 * @param int $form_id  ID of the form currently being displayed
742
	 *
743
	 * @return array Array of actions to be added to the GravityView option group
744
	 */
745
	private function get_bulk_actions( $form_id ) {
746
747
		$bulk_actions = array(
748
			'GravityView' => array(
749
				array(
750
					'label' => __( 'Approve', 'gravityview' ),
751
					'value' => sprintf( '%s-%d', $this->bulk_action_prefixes['approve'], $form_id ),
752
				),
753
				array(
754
					'label' => __( 'Disapprove', 'gravityview' ),
755
					'value' => sprintf( '%s-%d', $this->bulk_action_prefixes['unapprove'], $form_id ),
756
				),
757
			),
758
		);
759
760
		/**
761
		 * @filter `gravityview/approve_entries/bulk_actions` Modify the GravityView "Bulk action" dropdown list. Return an empty array to hide.
762
		 * @see https://gist.github.com/zackkatz/82785402c996b51b4dc9 for an example of how to use this filter
763
		 * @since 1.16.3
764
		 * @param array $bulk_actions Associative array of actions to be added to "Bulk action" dropdown inside GravityView `<optgroup>`. Parent array key is the `<optgroup>` label, then each child array must have `label` (displayed text) and `value` (input value) keys
765
		 * @param int $form_id ID of the form currently being displayed
766
		 */
767
		$bulk_actions = apply_filters( 'gravityview/approve_entries/bulk_actions', $bulk_actions, $form_id );
768
769
		// Sanitize the values, just to be sure.
770
		foreach ( $bulk_actions as $key => $group ) {
771
			foreach ( $group as $i => $action ) {
772
				$bulk_actions[ $key ][ $i ]['label'] = esc_html( $bulk_actions[ $key ][ $i ]['label'] );
773
				$bulk_actions[ $key ][ $i ]['value'] = esc_attr( $bulk_actions[ $key ][ $i ]['value'] );
774
			}
775
		}
776
777
		return $bulk_actions;
778
	}
779
780
	/**
781
	 * Should the Approve/Reject Entry column be shown in the GF Entries page?
782
	 *
783
	 * @since 1.7.2
784
	 *
785
	 * @param int $form_id The ID of the Gravity Forms form for which entries are being shown
786
	 *
787
	 * @return bool True: Show column; False: hide column
788
	 */
789
	private function show_approve_entry_column( $form_id ) {
790
791
		$show_approve_column = GVCommon::has_cap( 'gravityview_moderate_entries' );
792
793
		/**
794
		 * @filter `gravityview/approve_entries/hide-if-no-connections` Return true to hide reject/approve if there are no connected Views
795
		 * @since 1.7.2
796
		 * @param boolean $hide_if_no_connections
797
		 */
798
		$hide_if_no_connections = apply_filters('gravityview/approve_entries/hide-if-no-connections', false );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
799
800
		if( $hide_if_no_connections ) {
801
802
			$connected_views = gravityview_get_connected_views( $form_id );
803
804
			if( empty( $connected_views ) ) {
805
				$show_approve_column = false;
806
			}
807
		}
808
809
		/**
810
		 * @filter `gravityview/approve_entries/show-column` Override whether the column is shown
811
		 * @param boolean $show_approve_column Whether the column will be shown
812
		 * @param int $form_id The ID of the Gravity Forms form for which entries are being shown
813
		 */
814
		$show_approve_column = apply_filters('gravityview/approve_entries/show-column', $show_approve_column, $form_id );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
815
816
		return $show_approve_column;
817
	}
818
819
	function register_gform_noconflict_script( $scripts ) {
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...
820
		$scripts[] = 'gravityview_gf_entries_scripts';
821
		return $scripts;
822
	}
823
824
	function register_gform_noconflict_style( $styles ) {
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...
825
		$styles[] = 'gravityview_entries_list';
826
		return $styles;
827
	}
828
829
}
830
831
new GravityView_Admin_ApproveEntries;
832