Completed
Push — develop ( adcc2c...e29763 )
by Zack
17:41
created

GravityView_Entry_Approval::_send_notifications()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5.1502

Importance

Changes 0
Metric Value
cc 5
nc 3
nop 2
dl 0
loc 18
ccs 9
cts 11
cp 0.8182
crap 5.1502
rs 9.3554
c 0
b 0
f 0
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 23 and the first side effect is on line 15.

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-gravityview-entry-approval.php
4
 * @package   GravityView
5
 * @license   GPL2+
6
 * @author    Katz Web Services, Inc.
7
 * @link      https://gravityview.co
8
 * @copyright Copyright 2016, Katz Web Services, Inc.
9
 *
10
 * @since 1.18
11
 */
12
13
/** If this file is called directly, abort. */
14
if ( ! defined( 'ABSPATH' ) ) {
15
	die;
16
}
17
18
/**
19
 * Generate linked list output for a list of entries.
20
 *
21
 * @since 1.18
22
 */
23
class GravityView_Entry_Approval {
24
25
	/**
26
	 * @var string Key used to store approval status in the Gravity Forms entry meta table
27
	 */
28
	const meta_key = 'is_approved';
29
30
	public function __construct() {
31
		$this->add_hooks();
32
	}
33
34
	/**
35
	 * Add actions and filters related to entry approval
36
	 *
37
	 * @return void
38
	 */
39
	private function add_hooks() {
40
41
		// in case entry is edited (on admin or frontend)
42
		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...
43
44
		// when using the User opt-in field, check on entry submission
45
		add_action( 'gform_after_submission', array( $this, 'after_submission' ), 10, 2 );
46
47
		// process ajax approve entry requests
48
		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...
49
50
		// autounapprove
51
		add_action( 'gravityview/edit_entry/after_update', array( __CLASS__, 'autounapprove' ), 10, 4 );
52
53
		add_filter( 'gform_notification_events', array( __CLASS__, 'add_approval_notification_events' ), 10, 2 );
54
55
		add_action( 'gravityview/approve_entries/approved', array( $this, '_trigger_notifications' ) );
56
		add_action( 'gravityview/approve_entries/disapproved', array( $this, '_trigger_notifications' ) );
57
		add_action( 'gravityview/approve_entries/unapproved', array( $this, '_trigger_notifications' ) );
58
		add_action( 'gravityview/approve_entries/updated', array( $this, '_trigger_notifications' ) );
59
	}
60
61
	/**
62
	 * Passes approval notification and action hook to the send_notifications method
63
	 *
64
	 * @see GravityView_Entry_Approval::send_notifications()
65
	 *
66
	 * @internal Developers, do not use!
67
	 *
68
	 * @since 2.1
69
	 *
70
	 * @param int $entry_id ID of entry being updated
71
	 *
72
	 * @return void
73
	 */
74 1
	public function _trigger_notifications( $entry_id = 0 ) {
75 1
		$this->_send_notifications( $entry_id, current_action() );
76 1
	}
77
78
	/**
79
	 * Passes along notification triggers to GFAPI::send_notifications()
80
	 *
81
	 * @since 2.1
82
	 *
83
	 * @param int $entry_id ID of entry being updated
84
	 * @param string $event Hook that triggered the notification. This is used as the key in the GF notifications array.
85
	 *
86
	 * @return void
87
	 */
88 1
	private function _send_notifications( $entry_id = '', $event = '' ) {
89
90 1
		$entry = GFAPI::get_entry( $entry_id );
91
92 1
		if ( ! $entry || is_wp_error( $entry ) ) {
93 1
			gravityview()->log->error( 'Entry not found at ID #{entry_id}', array( 'entry_id' => $entry_id ) );
94 1
			return;
95
		}
96
97 1
		$form = GFAPI::get_form( $entry['form_id'] );
98
99 1
		if ( ! $entry || is_wp_error( $entry ) ) {
100
			gravityview()->log->error( 'Form not found at ID #{form_id} for entry #{entry_id}', array( 'form_id' => $entry['form_id'], 'entry_id' => $entry_id ) );
101
			return;
102
		}
103
104 1
		GFAPI::send_notifications( $form, $entry, $event );
105 1
	}
106
107
	/**
108
	 * Adds entry approval status change custom notification events
109
	 *
110
	 * @since 2.1
111
	 *
112
	 * @param array $notification_events The notification events.
113
	 * @param array $form The current form.
114
	 */
115 1
	public static function add_approval_notification_events( $notification_events = array(), $form = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form 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...
116
117 1
		$notification_events['gravityview/approve_entries/approved'] = 'GravityView - ' . esc_html_x( 'Entry is approved', 'The title for an event in a notifications drop down list.', 'gravityview' );
118 1
		$notification_events['gravityview/approve_entries/disapproved'] = 'GravityView - ' . esc_html_x( 'Entry is disapproved', 'The title for an event in a notifications drop down list.', 'gravityview' );
119 1
		$notification_events['gravityview/approve_entries/unapproved'] = 'GravityView - ' . esc_html_x( 'Entry approval is reset', 'The title for an event in a notifications drop down list.', 'gravityview' );
120 1
		$notification_events['gravityview/approve_entries/updated'] = 'GravityView - ' . esc_html_x( 'Entry approval is changed', 'The title for an event in a notifications drop down list.', 'gravityview' );
121
122 1
		return $notification_events;
123
	}
124
125
	/**
126
	 * Get the approval status for an entry
127
	 *
128
	 * @since 1.18
129
	 * @uses GVCommon::get_entry_id() Accepts entry slug or entry ID
130
	 *
131
	 * @param array|int|string $entry Entry array, entry slug, or entry ID
132
	 * @param string $value_or_label "value" or "label" (default: "label")
133
	 *
134
	 * @return bool|string Return the label or value of entry approval
135
	 */
136 1
	public static function get_entry_status( $entry, $value_or_label = 'label' ) {
137
138 1
		$entry_id = is_array( $entry ) ? $entry['id'] : GVCommon::get_entry_id( $entry, true );
139
140 1
		$status = gform_get_meta( $entry_id, self::meta_key );
141
142 1
		$status = GravityView_Entry_Approval_Status::maybe_convert_status( $status );
143
144 1
		if( 'value' === $value_or_label ) {
145 1
			return $status;
146
		}
147
148
		return GravityView_Entry_Approval_Status::get_label( $status );
149
	}
150
151
	/**
152
	 * Approve/Disapprove entries using the × or ✓ icons in the GF Entries screen
153
	 *
154
	 * @uses wp_send_json_error()
155
	 * @uses wp_send_json_success()
156
	 *
157
	 * Expects a $_POST request with the following $_POST keys and values:
158
	 *
159
	 * @global array $_POST {
160
	 * @type int $form_id ID of the form connected to the entry being updated
161
	 * @type string|int $entry_slug The ID or slug of the entry being updated
162
	 * @type string $approved The value of the entry approval status {@see GravityView_Entry_Approval_Status::is_valid() }
163
	 * }
164
	 *
165
	 * @return void Prints result using wp_send_json_success() and wp_send_json_error()
166
	 */
167
	public function ajax_update_approved() {
168
		
169
		$form_id = intval( \GV\Utils::_POST( 'form_id' ) );
170
171
		// We always want requests from the admin to allow entry IDs, but not from the frontend
172
		// There's another nonce sent when approving entries in the admin that we check
173
		$force_entry_ids = \GV\Utils::_POST( 'admin_nonce' ) && wp_verify_nonce( \GV\Utils::_POST( 'admin_nonce' ), 'gravityview_admin_entry_approval' );
174
		
175
		$entry_id = GVCommon::get_entry_id( \GV\Utils::_POST( 'entry_slug' ), $force_entry_ids );
176
177
		$approval_status = \GV\Utils::_POST( 'approved' );
178
179
		$nonce = \GV\Utils::_POST( 'nonce' );
180
181
		// Valid status
182
		if( ! GravityView_Entry_Approval_Status::is_valid( $approval_status ) ) {
183
184
			gravityview()->log->error( 'Invalid approval status', array( 'data' => $_POST ) );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
185
186
			$result = new WP_Error( 'invalid_status', __( 'The request was invalid. Refresh the page and try again.', 'gravityview' ) );
187
188
		}
189
190
		// Valid values
191
		elseif ( empty( $entry_id ) || empty( $form_id ) ) {
192
193
			gravityview()->log->error( 'entry_id or form_id are empty.', array( 'data' => $_POST ) );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
194
195
			$result = new WP_Error( 'empty_details', __( 'The request was invalid. Refresh the page and try again.', 'gravityview' ) );
196
197
		}
198
199
		// Valid nonce
200
		else if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'gravityview_entry_approval' ) ) {
201
202
			gravityview()->log->error( 'Security check failed.', array( 'data' => $_POST ) );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
203
204
			$result = new WP_Error( 'invalid_nonce', __( 'The request was invalid. Refresh the page and try again.', 'gravityview' ) );
205
206
		}
207
208
		// Has capability
209
		elseif ( ! GVCommon::has_cap( 'gravityview_moderate_entries', $entry_id ) ) {
210
211
			gravityview()->log->error( 'User does not have the `gravityview_moderate_entries` capability.' );
212
213
			$result = new WP_Error( 'Missing Cap: gravityview_moderate_entries', __( 'You do not have permission to edit this entry.', 'gravityview') );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
214
215
		}
216
217
		// All checks passed
218
		else {
219
220
			$result = self::update_approved( $entry_id, $approval_status, $form_id );
221
222
		}
223
224
		if ( is_wp_error( $result ) ) {
225
			gravityview()->log->error( 'Error updating approval: {error}', array( 'error' =>  $result->get_error_message() ) );
0 ignored issues
show
introduced by
Expected 1 space between double arrow and "$result"; 2 found
Loading history...
introduced by
Expected 1 space after "=>"; 2 found
Loading history...
226
227
			wp_send_json_error( $result );
228
		}
229
230
		$current_status = self::get_entry_status( $entry_id, 'value' );
231
232
		wp_send_json_success( array(
233
			'status' => $current_status
0 ignored issues
show
introduced by
Each line in an array declaration must end in a comma
Loading history...
234
		) );
235
	}
236
237
	/**
238
	 * Update the is_approved meta whenever the entry is submitted (and it contains a User Opt-in field)
239
	 *
240
	 * @since 1.16.6
241
	 * @since 2.0.14 Set the default approval `is_approved` value upon submission
242
	 *
243
	 * @param $entry array Gravity Forms entry object
244
	 * @param $form array Gravity Forms form object
245
	 */
246 1
	public function after_submission( $entry, $form ) {
247
248 1
		$default_status = GravityView_Entry_Approval_Status::UNAPPROVED;
249
250
		/**
251
		 * @filter `gravityview/approve_entries/after_submission/default_status` Modify the default approval status for newly submitted entries
252
		 * @since 2.0.14
253
		 * @param int $default_status See GravityView_Entry_Approval_Status() for valid statuses.
254
		 */
255 1
		$filtered_status = apply_filters( 'gravityview/approve_entries/after_submission/default_status', $default_status );
256
257 1
		if ( GravityView_Entry_Approval_Status::is_valid( $filtered_status ) ) {
258 1
			$default_status = $filtered_status;
259
		} else {
260 1
			gravityview()->log->error( 'Invalid approval status returned by `gravityview/approve_entries/after_submission/default_status` filter: {status}', array( 'status' => $filtered_status ) );
261
		}
262
263
		// Set default
264 1
		self::update_approved_meta( $entry['id'], $default_status, $entry['form_id'] );
265
266
		// Then check for if there is an approval column, and use that value instead
267 1
		$this->after_update_entry_update_approved_meta( $form , $entry['id'] );
268 1
	}
269
270
	/**
271
	 * Update the is_approved meta whenever the entry is updated
272
	 *
273
	 * @since 1.7.6.1 Was previously named `update_approved_meta`
274
	 *
275
	 * @param  array $form     Gravity Forms form array
276
	 * @param  int $entry_id ID of the Gravity Forms entry
277
	 * @return void
278
	 */
279 3
	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...
280
281 3
		$approved_column = self::get_approved_column( $form['id'] );
282
283
		/**
284
		 * If the form doesn't contain the approve field, don't assume anything.
285
		 */
286 3
		if( empty( $approved_column ) ) {
287 3
			return;
288
		}
289
290
		$entry = GFAPI::get_entry( $entry_id );
291
292
		// If the checkbox is blank, it's disapproved, regardless of the label
293
		if ( '' === \GV\Utils::get( $entry, $approved_column ) ) {
294
			$value = GravityView_Entry_Approval_Status::DISAPPROVED;
295
		} else {
296
			// If the checkbox is not blank, it's approved
297
			$value = GravityView_Entry_Approval_Status::APPROVED;
298
		}
299
300
		self::update_approved_meta( $entry_id, $value, $form['id'] );
301
	}
302
303
	/**
304
	 * Process a bulk of entries to update the approve field/property
305
	 *
306
	 * @since 1.18 Moved to GravityView_Entry_Approval
307
	 * @since 1.18 Made public
308
	 *
309
	 * @access public
310
	 * @static
311
	 * @param array|boolean $entries If array, array of entry IDs that are to be updated. If true: update all entries.
312
	 * @param int $approved Approved status. If `0`: unapproved, if not empty, `Approved`
313
	 * @param int $form_id The Gravity Forms Form ID
314
	 * @return boolean|null True: successfully updated all entries. False: there was an error updating at least one entry. NULL: an error occurred (see log)
315
	 */
316 1
	public static function update_bulk( $entries = array(), $approved, $form_id ) {
317
318 1
		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...
319
			gravityview()->log->error( 'Entries were empty or malformed.', array( 'data' => $entries ) );
320
			return NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
321
		}
322
323 1
		if( ! GVCommon::has_cap( 'gravityview_moderate_entries' ) ) {
324 1
			gravityview()->log->error( 'User does not have the `gravityview_moderate_entries` capability.' );
325 1
			return NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
326
		}
327
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
328
329 1
		if ( ! GravityView_Entry_Approval_Status::is_valid( $approved ) ) {
330
			gravityview()->log->error( 'Invalid approval status', array( 'data' => $approved ) );
331
			return NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
332
		}
333
334
		// calculate approved field id once instead of looping through in the update_approved() method
335 1
		$approved_column_id = self::get_approved_column( $form_id );
336
337 1
		$success = true;
338 1
		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...
339 1
			$update_success = 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...
340
341 1
			if( ! $update_success ) {
342 1
				$success = false;
343
			}
344
		}
345
346 1
		return $success;
347
	}
348
349
	/**
350
	 * update_approved function.
351
	 *
352
	 * @since 1.18 Moved to GravityView_Entry_Approval class
353
	 *
354
	 * @access public
355
	 * @static
356
	 * @param int $entry_id (default: 0)
357
	 * @param int $approved (default: 2)
358
	 * @param int $form_id (default: 0)
359
	 * @param int $approvedcolumn (default: 0)
360
	 *
361
	 * @return boolean True: It worked; False: it failed
362
	 */
363 1
	public static function update_approved( $entry_id = 0, $approved = 2, $form_id = 0, $approvedcolumn = 0 ) {
364
365 1
		if( !class_exists( 'GFAPI' ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
366
			gravityview()->log->error( 'GFAPI does not exist' );
367
			return false;
368
		}
369
370 1
		if( ! GravityView_Entry_Approval_Status::is_valid( $approved ) ) {
371
			gravityview()->log->error( 'Not a valid approval value.' );
372
			return false;
373
		}
374
375 1
		$approved = GravityView_Entry_Approval_Status::maybe_convert_status( $approved );
376
377 1
		$entry = GFAPI::get_entry( $entry_id );
378
379 1
		if ( is_wp_error( $entry ) ) {
380 1
			gravityview()->log->error( 'Entry does not exist' );
381 1
			return false;
382
		}
383
384
		// If the form has an Approve/Reject field, update that value
385 1
		$result = self::update_approved_column( $entry_id, $approved, $form_id, $approvedcolumn );
386
387 1
		if( is_wp_error( $result ) ) {
388
			gravityview()->log->error( 'Entry approval not updated: {error}', array( 'error' => $result->get_error_message() ) );
389
			return false;
390
		}
391
392 1
		$form_id = intval( $form_id );
393
394
		// Update the entry meta
395 1
		self::update_approved_meta( $entry_id, $approved, $form_id );
396
397
		// add note to entry if approval field updating worked or there was no approved field
398
		// There's no validation for the meta
399 1
		if( true === $result ) {
400
401
			// Add an entry note
402 1
			self::add_approval_status_updated_note( $entry_id, $approved );
403
404
			/**
405
			 * Destroy the cache for this form
406
			 * @see class-cache.php
407
			 * @since 1.5.1
408
			 */
409 1
			do_action( 'gravityview_clear_form_cache', $form_id );
410
411
		}
412
413 1
		return $result;
414
	}
415
416
	/**
417
	 * Add a note when an entry is approved
418
	 *
419
	 * @see GravityView_Entry_Approval::update_approved
420
	 *
421
	 * @since 1.18
422
	 *
423
	 * @param int $entry_id Gravity Forms entry ID
424
	 * @param int $approved Approval status
425
	 *
426
	 * @return false|int|WP_Error Note ID if successful; WP_Error if error when adding note, FALSE if note not updated because of `gravityview/approve_entries/add-note` filter or `GravityView_Entry_Notes` class not existing
427
	 */
428 1
	private static function add_approval_status_updated_note( $entry_id, $approved = 0 ) {
429 1
		$note = '';
430
431 1
		switch ( $approved ) {
432
			case GravityView_Entry_Approval_Status::APPROVED:
433 1
				$note = __( 'Approved the Entry for GravityView', 'gravityview' );
434 1
				break;
435
			case GravityView_Entry_Approval_Status::UNAPPROVED:
436
				$note = __( 'Reset Entry approval for GravityView', 'gravityview' );
437
				break;
438
			case GravityView_Entry_Approval_Status::DISAPPROVED:
439
				$note = __( 'Disapproved the Entry for GravityView', 'gravityview' );
440
				break;
441
		}
442
443
		/**
444
		 * @filter `gravityview/approve_entries/add-note` Add a note when the entry has been approved or disapproved?
445
		 * @since 1.16.3
446
		 * @param bool $add_note True: Yep, add that note! False: Do not, under any circumstances, add that note!
447
		 */
448 1
		$add_note = apply_filters( 'gravityview/approve_entries/add-note', true );
449
450 1
		$note_id = false;
451
452 1
		if( $add_note && class_exists( 'GravityView_Entry_Notes' ) ) {
453
454 1
			$current_user = wp_get_current_user();
455
456 1
			$note_id = GravityView_Entry_Notes::add_note( $entry_id, $current_user->ID, $current_user->display_name, $note );
457
		}
458
459 1
		return $note_id;
460
	}
461
462
	/**
463
	 * Update the Approve/Disapproved field value
464
	 *
465
	 * @param  int $entry_id ID of the Gravity Forms entry
466
	 * @param  string $status String whether entry is approved or not. `0` for not approved, `Approved` for approved.
467
	 * @param int $form_id ID of the form of the entry being updated. Improves query performance.
468
	 * @param string $approvedcolumn Gravity Forms Field ID
469
	 *
470
	 * @return true|WP_Error
471
	 */
472
	private static function update_approved_column( $entry_id = 0, $status = '0', $form_id = 0, $approvedcolumn = 0 ) {
473
474
		if( empty( $approvedcolumn ) ) {
475
			$approvedcolumn = self::get_approved_column( $form_id );
476
		}
477
478
		if ( empty( $approvedcolumn ) ) {
479
			return true;
480
		}
481
482
		if ( ! GravityView_Entry_Approval_Status::is_valid( $status ) ) {
483
			return new WP_Error( 'invalid_status', 'Invalid entry approval status', $status );
484
		}
485
486
		//get the entry
487
		$entry = GFAPI::get_entry( $entry_id );
488
489
		// Entry doesn't exist
490
		if ( is_wp_error( $entry ) ) {
491
			return $entry;
492
		}
493
494
		$status = GravityView_Entry_Approval_Status::maybe_convert_status( $status );
495
496
		$new_value = '';
497
		if( GravityView_Entry_Approval_Status::APPROVED === $status ) {
498
			$new_value = self::get_approved_column_input_label( $form_id, $approvedcolumn );
499
		}
500
501
		//update entry
502
		$entry["{$approvedcolumn}"] = $new_value;
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
503
504
		/**
505
		 * Note: GFAPI::update_entry() doesn't trigger `gform_after_update_entry`, so we trigger updating the meta ourselves
506
		 * @see GravityView_Entry_Approval::after_update_entry_update_approved_meta
507
		 * @var true|WP_Error $result
508
		 */
509
		$result = GFAPI::update_entry( $entry );
510
		
511
		return $result;
512
	}
513
514
	/**
515
	 * Get the value for the approved field checkbox
516
	 *
517
	 * When approving a field via the entry meta, use the correct value for the new approved column input
518
	 *
519
	 * @since 1.19
520
	 *
521
	 * @param array|int $form Form ID or form array
522
	 * @param string $approved_column Approved column field ID
523
	 *
524
	 * @return string|null
525
	 */
526
	private static function get_approved_column_input_label( $form, $approved_column ) {
527
528
		$field = gravityview_get_field( $form, $approved_column );
529
530
		// If the user has enabled a different value than the label (for some reason), use it.
531
		// This is highly unlikely
532
		if ( is_array( $field->choices ) && ! empty( $field->choices ) ) {
533
			return isset( $field->choices[0]['value'] ) ? $field->choices[0]['value'] : $field->choices[0]['text'];
534
		}
535
536
		// Otherwise, fall back on the inputs array
537
		if ( is_array( $field->inputs ) && ! empty( $field->inputs ) ) {
538
			return $field->inputs[0]['label'];
539
		}
540
541
		return null;
542
	}
543
544
	/**
545
	 * Update the `is_approved` entry meta value
546
	 *
547
	 * @since 1.7.6.1 `after_update_entry_update_approved_meta` was previously to be named `update_approved_meta`
548
	 * @since 1.17.1 Added $form_id parameter
549
	 *
550
	 * @param  int $entry_id ID of the Gravity Forms entry
551
	 * @param  string $status String whether entry is approved or not. `0` for not approved, `Approved` for approved.
552
	 * @param int $form_id ID of the form of the entry being updated. Improves query performance.
553
	 *
554
	 * @return void
555
	 */
556
	private static function update_approved_meta( $entry_id, $status, $form_id = 0 ) {
557
558
		if ( ! GravityView_Entry_Approval_Status::is_valid( $status ) ) {
559
			gravityview()->log->error( '$is_approved not valid value', array( 'data' => $status ) );
560
			return;
561
		}
562
563
		if ( ! function_exists( 'gform_update_meta' ) ) {
564
			gravityview()->log->error( '`gform_update_meta` does not exist.' );
565
			return;
566
		}
567
568
		$status = GravityView_Entry_Approval_Status::maybe_convert_status( $status );
569
570
		// update entry meta
571
		gform_update_meta( $entry_id, self::meta_key, $status, $form_id );
572
573
		/**
574
		 * @action `gravityview/approve_entries/updated` Triggered when an entry approval is updated
575
		 * @since 1.7.6.1
576
		 * @param  int $entry_id ID of the Gravity Forms entry
577
		 * @param  string|int $status String whether entry is approved or not. See GravityView_Entry_Approval_Status for valid statuses.
578
		 */
579
		do_action( 'gravityview/approve_entries/updated', $entry_id, $status );
580
581
		$action = GravityView_Entry_Approval_Status::get_key( $status );
582
583
		/**
584
		 * @action `gravityview/approve_entries/{$action}` Triggered when an entry approval is set. {$action} can be 'approved', 'unapproved', or 'disapproved'
585
		 * Note: If you want this to work with Bulk Actions, run in a plugin rather than a theme; the bulk updates hook runs before themes are loaded.
586
		 * @since 1.7.6.1
587
		 * @since 1.18 Added "unapproved"
588
		 * @param  int $entry_id ID of the Gravity Forms entry
589
		 */
590
		do_action( 'gravityview/approve_entries/' . $action , $entry_id );
591
	}
592
593
	/**
594
	 * Calculate the approve field.input id
595
	 *
596
	 * @access public
597
	 * @static
598
	 * @param mixed $form GF Form or Form ID
599
	 * @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.
600
	 */
601 3
	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...
602
603 3
		if( empty( $form ) ) {
604
			return null;
605
		}
606
607 3
		if( !is_array( $form ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
608 3
			$form = GVCommon::get_form( $form );
609
		}
610
611 3
		$approved_column_id = null;
612
613
		/**
614
		 * @var string $key
615
		 * @var GF_Field $field
616
		 */
617 3
		foreach( $form['fields'] as $key => $field ) {
618
619 3
			$inputs = $field->get_entry_inputs();
620
621 3
			if( !empty( $field->gravityview_approved ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
622
				if ( ! empty( $inputs ) && !empty( $inputs[0]['id'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
623
					$approved_column_id = $inputs[0]['id'];
624
					break;
625
				}
626
			}
627
628
			// Note: This is just for backward compatibility from GF Directory plugin and old GV versions - when using i18n it may not work..
629 3
			if( 'checkbox' === $field->type && ! empty( $inputs ) ) {
630
				foreach ( $inputs as $input ) {
631
					if ( 'approved' === strtolower( $input['label'] ) ) {
632
						$approved_column_id = $input['id'];
633 3
						break;
634
					}
635
				}
636
			}
637
		}
638
639 3
		return $approved_column_id;
640
	}
641
642
	/**
643
	 * Maybe unapprove entry on edit.
644
	 *
645
	 * Called from gravityview/edit_entry/after_update
646
	 *
647
	 * @param array $form Gravity Forms form array
648
	 * @param string $entry_id Numeric ID of the entry that was updated
649
	 * @param GravityView_Edit_Entry_Render $edit This object
650
	 * @param GravityView_View_Data $gv_data The View data
651
	 *
652
	 * @return void
653
	 */
654 4
	public static function autounapprove( $form, $entry_id, $edit, $gv_data ) {
655
656 4
		$view_keys = array_keys( $gv_data->get_views() );
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_View_Data::get_views() has been deprecated.

This method has been deprecated.

Loading history...
657
658 4
		$view = \GV\View::by_id( $view_keys[0] );
659
660 4
		if ( ! $view->settings->get( 'unapprove_edit' ) ) {
661 4
			return;
662
		}
663
664 1
		if ( GVCommon::has_cap( 'gravityview_moderate_entries' ) ) {
665 1
			return;
666
		}
667
668 1
		self::update_approved_meta( $entry_id, GravityView_Entry_Approval_Status::UNAPPROVED, $form['id'] );
669 1
	}
670
671
}
672
673
new GravityView_Entry_Approval;