1
|
|
|
<?php |
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); |
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')); |
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
|
3 |
|
public function _trigger_notifications( $entry_id = 0 ) { |
75
|
3 |
|
$this->_send_notifications( $entry_id, current_action() ); |
76
|
3 |
|
} |
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
|
3 |
|
private function _send_notifications( $entry_id = '', $event = '' ) { |
89
|
|
|
|
90
|
3 |
|
$entry = GFAPI::get_entry( $entry_id ); |
91
|
|
|
|
92
|
3 |
|
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
|
3 |
|
$form = GFAPI::get_form( $entry['form_id'] ); |
98
|
|
|
|
99
|
3 |
|
if ( ! $form ) { |
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
|
3 |
|
GFAPI::send_notifications( $form, $entry, $event ); |
105
|
3 |
|
} |
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() ) { |
|
|
|
|
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 ) ); |
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 ) ); |
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 ) ); |
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') ); |
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() ) ); |
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 |
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
|
|
|
/** |
249
|
|
|
* @filter `gravityview/approve_entries/after_submission` Modify whether to run the after_submission process |
250
|
|
|
* @since 2.3 |
251
|
|
|
* @param bool $process_after_submission default: true |
252
|
|
|
*/ |
253
|
1 |
|
$process_after_submission = apply_filters( 'gravityview/approve_entries/after_submission', true ); |
254
|
|
|
|
255
|
1 |
|
if ( ! $process_after_submission ) { |
256
|
|
|
return; |
257
|
|
|
} |
258
|
|
|
|
259
|
1 |
|
$default_status = GravityView_Entry_Approval_Status::UNAPPROVED; |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* @filter `gravityview/approve_entries/after_submission/default_status` Modify the default approval status for newly submitted entries |
263
|
|
|
* @since 2.0.14 |
264
|
|
|
* @param int $default_status See GravityView_Entry_Approval_Status() for valid statuses. |
265
|
|
|
*/ |
266
|
1 |
|
$filtered_status = apply_filters( 'gravityview/approve_entries/after_submission/default_status', $default_status ); |
267
|
|
|
|
268
|
1 |
|
if ( GravityView_Entry_Approval_Status::is_valid( $filtered_status ) ) { |
269
|
1 |
|
$default_status = $filtered_status; |
270
|
|
|
} else { |
271
|
1 |
|
gravityview()->log->error( 'Invalid approval status returned by `gravityview/approve_entries/after_submission/default_status` filter: {status}', array( 'status' => $filtered_status ) ); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
// Set default |
275
|
1 |
|
self::update_approved_meta( $entry['id'], $default_status, $entry['form_id'] ); |
276
|
|
|
|
277
|
|
|
// Then check for if there is an approval column, and use that value instead |
278
|
1 |
|
$this->after_update_entry_update_approved_meta( $form , $entry['id'] ); |
279
|
1 |
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* Update the is_approved meta whenever the entry is updated |
283
|
|
|
* |
284
|
|
|
* @since 1.7.6.1 Was previously named `update_approved_meta` |
285
|
|
|
* |
286
|
|
|
* @param array $form Gravity Forms form array |
287
|
|
|
* @param int $entry_id ID of the Gravity Forms entry |
288
|
|
|
* @return void |
289
|
|
|
*/ |
290
|
21 |
|
public function after_update_entry_update_approved_meta( $form, $entry_id = NULL ) { |
291
|
|
|
|
292
|
21 |
|
$approved_column = self::get_approved_column( $form['id'] ); |
293
|
|
|
|
294
|
|
|
/** |
295
|
|
|
* If the form doesn't contain the approve field, don't assume anything. |
296
|
|
|
*/ |
297
|
21 |
|
if( empty( $approved_column ) ) { |
298
|
20 |
|
return; |
299
|
|
|
} |
300
|
|
|
|
301
|
1 |
|
$entry = GFAPI::get_entry( $entry_id ); |
302
|
|
|
|
303
|
|
|
// If the checkbox is blank, it's disapproved, regardless of the label |
304
|
1 |
|
if ( '' === \GV\Utils::get( $entry, $approved_column ) ) { |
305
|
1 |
|
$value = GravityView_Entry_Approval_Status::DISAPPROVED; |
306
|
|
|
} else { |
307
|
|
|
// If the checkbox is not blank, it's approved |
308
|
1 |
|
$value = GravityView_Entry_Approval_Status::APPROVED; |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
/** |
312
|
|
|
* @filter `gravityview/approve_entries/update_unapproved_meta` Filter the approval status on entry update. |
313
|
|
|
* @param[in,out] string $value The approval status. |
314
|
|
|
* @param array $form The form. |
315
|
|
|
* @param array $entry The entry. |
316
|
|
|
*/ |
317
|
1 |
|
$value = apply_filters( 'gravityview/approve_entries/update_unapproved_meta', $value, $form, $entry ); |
318
|
|
|
|
319
|
1 |
|
self::update_approved_meta( $entry_id, $value, $form['id'] ); |
320
|
1 |
|
} |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* Process a bulk of entries to update the approve field/property |
324
|
|
|
* |
325
|
|
|
* @since 1.18 Moved to GravityView_Entry_Approval |
326
|
|
|
* @since 1.18 Made public |
327
|
|
|
* |
328
|
|
|
* @access public |
329
|
|
|
* @static |
330
|
|
|
* @param array|boolean $entries If array, array of entry IDs that are to be updated. If true: update all entries. |
331
|
|
|
* @param int $approved Approved status. If `0`: unapproved, if not empty, `Approved` |
332
|
|
|
* @param int $form_id The Gravity Forms Form ID |
333
|
|
|
* @return boolean|null True: successfully updated all entries. False: there was an error updating at least one entry. NULL: an error occurred (see log) |
334
|
|
|
*/ |
335
|
1 |
|
public static function update_bulk( $entries = array(), $approved, $form_id ) { |
336
|
|
|
|
337
|
1 |
|
if( empty($entries) || ( $entries !== true && !is_array($entries) ) ) { |
338
|
|
|
gravityview()->log->error( 'Entries were empty or malformed.', array( 'data' => $entries ) ); |
339
|
|
|
return NULL; |
340
|
|
|
} |
341
|
|
|
|
342
|
1 |
|
if( ! GVCommon::has_cap( 'gravityview_moderate_entries' ) ) { |
343
|
1 |
|
gravityview()->log->error( 'User does not have the `gravityview_moderate_entries` capability.' ); |
344
|
1 |
|
return NULL; |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
|
348
|
1 |
|
if ( ! GravityView_Entry_Approval_Status::is_valid( $approved ) ) { |
349
|
|
|
gravityview()->log->error( 'Invalid approval status', array( 'data' => $approved ) ); |
350
|
|
|
return NULL; |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
// calculate approved field id once instead of looping through in the update_approved() method |
354
|
1 |
|
$approved_column_id = self::get_approved_column( $form_id ); |
355
|
|
|
|
356
|
1 |
|
$success = true; |
357
|
1 |
|
foreach( $entries as $entry_id ) { |
|
|
|
|
358
|
1 |
|
$update_success = self::update_approved( (int)$entry_id, $approved, $form_id, $approved_column_id ); |
359
|
|
|
|
360
|
1 |
|
if( ! $update_success ) { |
361
|
1 |
|
$success = false; |
362
|
|
|
} |
363
|
|
|
} |
364
|
|
|
|
365
|
1 |
|
return $success; |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
/** |
369
|
|
|
* update_approved function. |
370
|
|
|
* |
371
|
|
|
* @since 1.18 Moved to GravityView_Entry_Approval class |
372
|
|
|
* |
373
|
|
|
* @access public |
374
|
|
|
* @static |
375
|
|
|
* @param int $entry_id (default: 0) |
376
|
|
|
* @param int $approved (default: 2) |
377
|
|
|
* @param int $form_id (default: 0) |
378
|
|
|
* @param int $approvedcolumn (default: 0) |
379
|
|
|
* |
380
|
|
|
* @return boolean True: It worked; False: it failed |
381
|
|
|
*/ |
382
|
2 |
|
public static function update_approved( $entry_id = 0, $approved = 2, $form_id = 0, $approvedcolumn = 0 ) { |
383
|
|
|
|
384
|
2 |
|
if( !class_exists( 'GFAPI' ) ) { |
385
|
|
|
gravityview()->log->error( 'GFAPI does not exist' ); |
386
|
|
|
return false; |
387
|
|
|
} |
388
|
|
|
|
389
|
2 |
|
if( ! GravityView_Entry_Approval_Status::is_valid( $approved ) ) { |
390
|
|
|
gravityview()->log->error( 'Not a valid approval value.' ); |
391
|
|
|
return false; |
392
|
|
|
} |
393
|
|
|
|
394
|
2 |
|
$approved = GravityView_Entry_Approval_Status::maybe_convert_status( $approved ); |
395
|
|
|
|
396
|
2 |
|
$entry = GFAPI::get_entry( $entry_id ); |
397
|
|
|
|
398
|
2 |
|
if ( is_wp_error( $entry ) ) { |
399
|
1 |
|
gravityview()->log->error( 'Entry does not exist' ); |
400
|
1 |
|
return false; |
401
|
|
|
} |
402
|
|
|
|
403
|
|
|
// If the form has an Approve/Reject field, update that value |
404
|
2 |
|
$result = self::update_approved_column( $entry_id, $approved, $form_id, $approvedcolumn ); |
405
|
|
|
|
406
|
2 |
|
if( is_wp_error( $result ) ) { |
407
|
|
|
gravityview()->log->error( 'Entry approval not updated: {error}', array( 'error' => $result->get_error_message() ) ); |
408
|
|
|
return false; |
409
|
|
|
} |
410
|
|
|
|
411
|
2 |
|
$form_id = intval( $form_id ); |
412
|
|
|
|
413
|
|
|
// Update the entry meta |
414
|
2 |
|
self::update_approved_meta( $entry_id, $approved, $form_id ); |
415
|
|
|
|
416
|
|
|
// add note to entry if approval field updating worked or there was no approved field |
417
|
|
|
// There's no validation for the meta |
418
|
2 |
|
if( true === $result ) { |
419
|
|
|
|
420
|
|
|
// Add an entry note |
421
|
2 |
|
self::add_approval_status_updated_note( $entry_id, $approved ); |
422
|
|
|
|
423
|
|
|
/** |
424
|
|
|
* Destroy the cache for this form |
425
|
|
|
* @see class-cache.php |
426
|
|
|
* @since 1.5.1 |
427
|
|
|
*/ |
428
|
2 |
|
do_action( 'gravityview_clear_form_cache', $form_id ); |
429
|
|
|
|
430
|
|
|
} |
431
|
|
|
|
432
|
2 |
|
return $result; |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
/** |
436
|
|
|
* Add a note when an entry is approved |
437
|
|
|
* |
438
|
|
|
* @see GravityView_Entry_Approval::update_approved |
439
|
|
|
* |
440
|
|
|
* @since 1.18 |
441
|
|
|
* |
442
|
|
|
* @param int $entry_id Gravity Forms entry ID |
443
|
|
|
* @param int $approved Approval status |
444
|
|
|
* |
445
|
|
|
* @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 |
446
|
|
|
*/ |
447
|
2 |
|
private static function add_approval_status_updated_note( $entry_id, $approved = 0 ) { |
448
|
2 |
|
$note = ''; |
449
|
|
|
|
450
|
2 |
|
switch ( $approved ) { |
451
|
|
|
case GravityView_Entry_Approval_Status::APPROVED: |
452
|
1 |
|
$note = __( 'Approved the Entry for GravityView', 'gravityview' ); |
453
|
1 |
|
break; |
454
|
|
|
case GravityView_Entry_Approval_Status::UNAPPROVED: |
455
|
|
|
$note = __( 'Reset Entry approval for GravityView', 'gravityview' ); |
456
|
|
|
break; |
457
|
|
|
case GravityView_Entry_Approval_Status::DISAPPROVED: |
458
|
1 |
|
$note = __( 'Disapproved the Entry for GravityView', 'gravityview' ); |
459
|
1 |
|
break; |
460
|
|
|
} |
461
|
|
|
|
462
|
|
|
/** |
463
|
|
|
* @filter `gravityview/approve_entries/add-note` Add a note when the entry has been approved or disapproved? |
464
|
|
|
* @since 1.16.3 |
465
|
|
|
* @param bool $add_note True: Yep, add that note! False: Do not, under any circumstances, add that note! |
466
|
|
|
*/ |
467
|
2 |
|
$add_note = apply_filters( 'gravityview/approve_entries/add-note', true ); |
468
|
|
|
|
469
|
2 |
|
$note_id = false; |
470
|
|
|
|
471
|
2 |
|
if( $add_note && class_exists( 'GravityView_Entry_Notes' ) ) { |
472
|
|
|
|
473
|
2 |
|
$current_user = wp_get_current_user(); |
474
|
|
|
|
475
|
2 |
|
$note_id = GravityView_Entry_Notes::add_note( $entry_id, $current_user->ID, $current_user->display_name, $note ); |
476
|
|
|
} |
477
|
|
|
|
478
|
2 |
|
return $note_id; |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
/** |
482
|
|
|
* Update the Approve/Disapproved field value |
483
|
|
|
* |
484
|
|
|
* @param int $entry_id ID of the Gravity Forms entry |
485
|
|
|
* @param string $status String whether entry is approved or not. `0` for not approved, `Approved` for approved. |
486
|
|
|
* @param int $form_id ID of the form of the entry being updated. Improves query performance. |
487
|
|
|
* @param string $approvedcolumn Gravity Forms Field ID |
488
|
|
|
* |
489
|
|
|
* @return true|WP_Error |
490
|
|
|
*/ |
491
|
1 |
|
private static function update_approved_column( $entry_id = 0, $status = '0', $form_id = 0, $approvedcolumn = 0 ) { |
492
|
|
|
|
493
|
1 |
|
if( empty( $approvedcolumn ) ) { |
494
|
1 |
|
$approvedcolumn = self::get_approved_column( $form_id ); |
495
|
|
|
} |
496
|
|
|
|
497
|
1 |
|
if ( empty( $approvedcolumn ) ) { |
498
|
1 |
|
return true; |
499
|
|
|
} |
500
|
|
|
|
501
|
|
|
if ( ! GravityView_Entry_Approval_Status::is_valid( $status ) ) { |
502
|
|
|
return new WP_Error( 'invalid_status', 'Invalid entry approval status', $status ); |
503
|
|
|
} |
504
|
|
|
|
505
|
|
|
//get the entry |
506
|
|
|
$entry = GFAPI::get_entry( $entry_id ); |
507
|
|
|
|
508
|
|
|
// Entry doesn't exist |
509
|
|
|
if ( is_wp_error( $entry ) ) { |
510
|
|
|
return $entry; |
511
|
|
|
} |
512
|
|
|
|
513
|
|
|
$status = GravityView_Entry_Approval_Status::maybe_convert_status( $status ); |
514
|
|
|
|
515
|
|
|
$new_value = ''; |
516
|
|
|
if( GravityView_Entry_Approval_Status::APPROVED === $status ) { |
517
|
|
|
$new_value = self::get_approved_column_input_label( $form_id, $approvedcolumn ); |
518
|
|
|
} |
519
|
|
|
|
520
|
|
|
//update entry |
521
|
|
|
$entry["{$approvedcolumn}"] = $new_value; |
522
|
|
|
|
523
|
|
|
/** |
524
|
|
|
* Note: GFAPI::update_entry() doesn't trigger `gform_after_update_entry`, so we trigger updating the meta ourselves |
525
|
|
|
* @see GravityView_Entry_Approval::after_update_entry_update_approved_meta |
526
|
|
|
* @var true|WP_Error $result |
527
|
|
|
*/ |
528
|
|
|
$result = GFAPI::update_entry( $entry ); |
529
|
|
|
|
530
|
|
|
return $result; |
531
|
|
|
} |
532
|
|
|
|
533
|
|
|
/** |
534
|
|
|
* Get the value for the approved field checkbox |
535
|
|
|
* |
536
|
|
|
* When approving a field via the entry meta, use the correct value for the new approved column input |
537
|
|
|
* |
538
|
|
|
* @since 1.19 |
539
|
|
|
* |
540
|
|
|
* @param array|int $form Form ID or form array |
541
|
|
|
* @param string $approved_column Approved column field ID |
542
|
|
|
* |
543
|
|
|
* @return string|null |
544
|
|
|
*/ |
545
|
|
|
private static function get_approved_column_input_label( $form, $approved_column ) { |
546
|
|
|
|
547
|
|
|
$field = gravityview_get_field( $form, $approved_column ); |
548
|
|
|
|
549
|
|
|
// If the user has enabled a different value than the label (for some reason), use it. |
550
|
|
|
// This is highly unlikely |
551
|
|
|
if ( is_array( $field->choices ) && ! empty( $field->choices ) ) { |
552
|
|
|
return isset( $field->choices[0]['value'] ) ? $field->choices[0]['value'] : $field->choices[0]['text']; |
553
|
|
|
} |
554
|
|
|
|
555
|
|
|
// Otherwise, fall back on the inputs array |
556
|
|
|
if ( is_array( $field->inputs ) && ! empty( $field->inputs ) ) { |
557
|
|
|
return $field->inputs[0]['label']; |
558
|
|
|
} |
559
|
|
|
|
560
|
|
|
return null; |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
/** |
564
|
|
|
* Update the `is_approved` entry meta value |
565
|
|
|
* |
566
|
|
|
* @since 1.7.6.1 `after_update_entry_update_approved_meta` was previously to be named `update_approved_meta` |
567
|
|
|
* @since 1.17.1 Added $form_id parameter |
568
|
|
|
* |
569
|
|
|
* @param int $entry_id ID of the Gravity Forms entry |
570
|
|
|
* @param string $status String whether entry is approved or not. `0` for not approved, `Approved` for approved. |
571
|
|
|
* @param int $form_id ID of the form of the entry being updated. Improves query performance. |
572
|
|
|
* |
573
|
|
|
* @return void |
574
|
|
|
*/ |
575
|
2 |
|
private static function update_approved_meta( $entry_id, $status, $form_id = 0 ) { |
576
|
|
|
|
577
|
2 |
|
if ( ! GravityView_Entry_Approval_Status::is_valid( $status ) ) { |
578
|
|
|
gravityview()->log->error( '$is_approved not valid value', array( 'data' => $status ) ); |
579
|
|
|
return; |
580
|
|
|
} |
581
|
|
|
|
582
|
2 |
|
if ( ! function_exists( 'gform_update_meta' ) ) { |
583
|
|
|
gravityview()->log->error( '`gform_update_meta` does not exist.' ); |
584
|
|
|
return; |
585
|
|
|
} |
586
|
|
|
|
587
|
2 |
|
$status = GravityView_Entry_Approval_Status::maybe_convert_status( $status ); |
588
|
|
|
|
589
|
|
|
// update entry meta |
590
|
2 |
|
gform_update_meta( $entry_id, self::meta_key, $status, $form_id ); |
591
|
|
|
|
592
|
|
|
/** |
593
|
|
|
* @action `gravityview/approve_entries/updated` Triggered when an entry approval is updated |
594
|
|
|
* @since 1.7.6.1 |
595
|
|
|
* @param int $entry_id ID of the Gravity Forms entry |
596
|
|
|
* @param string|int $status String whether entry is approved or not. See GravityView_Entry_Approval_Status for valid statuses. |
597
|
|
|
*/ |
598
|
2 |
|
do_action( 'gravityview/approve_entries/updated', $entry_id, $status ); |
599
|
|
|
|
600
|
2 |
|
$action = GravityView_Entry_Approval_Status::get_key( $status ); |
601
|
|
|
|
602
|
|
|
/** |
603
|
|
|
* @action `gravityview/approve_entries/{$action}` Triggered when an entry approval is set. {$action} can be 'approved', 'unapproved', or 'disapproved' |
604
|
|
|
* 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. |
605
|
|
|
* @since 1.7.6.1 |
606
|
|
|
* @since 1.18 Added "unapproved" |
607
|
|
|
* @param int $entry_id ID of the Gravity Forms entry |
608
|
|
|
*/ |
609
|
2 |
|
do_action( 'gravityview/approve_entries/' . $action , $entry_id ); |
610
|
2 |
|
} |
611
|
|
|
|
612
|
|
|
/** |
613
|
|
|
* Calculate the approve field.input id |
614
|
|
|
* |
615
|
|
|
* @access public |
616
|
|
|
* @static |
617
|
|
|
* @param mixed $form GF Form or Form ID |
618
|
|
|
* @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. |
619
|
|
|
*/ |
620
|
22 |
|
static public function get_approved_column( $form ) { |
621
|
|
|
|
622
|
22 |
|
if( empty( $form ) ) { |
623
|
1 |
|
return null; |
624
|
|
|
} |
625
|
|
|
|
626
|
21 |
|
if( !is_array( $form ) ) { |
627
|
21 |
|
$form = GVCommon::get_form( $form ); |
628
|
|
|
} |
629
|
|
|
|
630
|
21 |
|
$approved_column_id = null; |
631
|
|
|
|
632
|
|
|
/** |
633
|
|
|
* @var string $key |
634
|
|
|
* @var GF_Field $field |
635
|
|
|
*/ |
636
|
21 |
|
foreach( $form['fields'] as $key => $field ) { |
637
|
|
|
|
638
|
21 |
|
$inputs = $field->get_entry_inputs(); |
639
|
|
|
|
640
|
21 |
|
if( !empty( $field->gravityview_approved ) ) { |
641
|
1 |
|
if ( ! empty( $inputs ) && !empty( $inputs[0]['id'] ) ) { |
642
|
1 |
|
$approved_column_id = $inputs[0]['id']; |
643
|
1 |
|
break; |
644
|
|
|
} |
645
|
|
|
} |
646
|
|
|
|
647
|
|
|
// Note: This is just for backward compatibility from GF Directory plugin and old GV versions - when using i18n it may not work.. |
648
|
21 |
|
if( 'checkbox' === $field->type && ! empty( $inputs ) ) { |
649
|
2 |
|
foreach ( $inputs as $input ) { |
650
|
2 |
|
if ( 'approved' === strtolower( $input['label'] ) ) { |
651
|
|
|
$approved_column_id = $input['id']; |
652
|
|
|
break; |
653
|
|
|
} |
654
|
|
|
} |
655
|
|
|
} |
656
|
|
|
} |
657
|
|
|
|
658
|
21 |
|
return $approved_column_id; |
659
|
|
|
} |
660
|
|
|
|
661
|
|
|
/** |
662
|
|
|
* Maybe unapprove entry on edit. |
663
|
|
|
* |
664
|
|
|
* Called from gravityview/edit_entry/after_update |
665
|
|
|
* |
666
|
|
|
* @param array $form Gravity Forms form array |
667
|
|
|
* @param string $entry_id Numeric ID of the entry that was updated |
668
|
|
|
* @param GravityView_Edit_Entry_Render $edit This object |
669
|
|
|
* @param GravityView_View_Data $gv_data The View data |
670
|
|
|
* |
671
|
|
|
* @return void |
672
|
|
|
*/ |
673
|
22 |
|
public static function autounapprove( $form, $entry_id, $edit, $gv_data ) { |
674
|
|
|
|
675
|
22 |
|
$view_keys = array_keys( $gv_data->get_views() ); |
|
|
|
|
676
|
|
|
|
677
|
22 |
|
$view = \GV\View::by_id( $view_keys[0] ); |
678
|
|
|
|
679
|
22 |
|
if ( ! $view->settings->get( 'unapprove_edit' ) ) { |
680
|
22 |
|
return; |
681
|
|
|
} |
682
|
|
|
|
683
|
1 |
|
if ( GVCommon::has_cap( 'gravityview_moderate_entries' ) ) { |
684
|
1 |
|
return; |
685
|
|
|
} |
686
|
|
|
|
687
|
|
|
/** |
688
|
|
|
* @filter `gravityview/approve_entries/autounapprove/status` |
689
|
|
|
* @since 2.2.2 |
690
|
|
|
* @param[in,out] int|false $approval_status Approval status integer, or false if you want to not update status. Use GravityView_Entry_Approval_Status constants. Default: 3 (GravityView_Entry_Approval_Status::UNAPPROVED) |
691
|
|
|
* @param array $form Gravity Forms form array |
692
|
|
|
* @param string $entry_id Numeric ID of the entry that was updated |
693
|
|
|
* @param \GV\View $view Current View where the entry was edited |
694
|
|
|
*/ |
695
|
1 |
|
$approval_status = apply_filters( 'gravityview/approve_entries/autounapprove/status', GravityView_Entry_Approval_Status::UNAPPROVED, $form, $entry_id, $view ); |
696
|
|
|
|
697
|
|
|
// Allow returning false to exit |
698
|
1 |
|
if ( false === $approval_status ) { |
699
|
|
|
return; |
700
|
|
|
} |
701
|
|
|
|
702
|
1 |
|
if( ! GravityView_Entry_Approval_Status::is_valid( $approval_status ) ) { |
703
|
|
|
$approval_status = GravityView_Entry_Approval_Status::UNAPPROVED; |
704
|
|
|
} |
705
|
|
|
|
706
|
1 |
|
self::update_approved_meta( $entry_id, $approval_status, $form['id'] ); |
707
|
1 |
|
} |
708
|
|
|
|
709
|
|
|
/** |
710
|
|
|
* Where should the popover be placed? |
711
|
|
|
* |
712
|
|
|
* @since 2.3.1 |
713
|
|
|
* |
714
|
|
|
* @return string Where to place the popover; 'right' (default ltr), 'left' (default rtl), 'top', or 'bottom' |
715
|
|
|
*/ |
716
|
1 |
|
public static function get_popover_placement() { |
717
|
|
|
|
718
|
1 |
|
$placement = is_rtl() ? 'left' : 'right'; |
719
|
|
|
|
720
|
|
|
/** |
721
|
|
|
* @filter `gravityview/approve_entries/popover_placement` Where should the popover be placed? |
722
|
|
|
* @since 2.3.1 |
723
|
|
|
* @param string $placement Where to place the popover; 'right' (default ltr), 'left' (default rtl), 'top', or 'bottom' |
724
|
|
|
*/ |
725
|
1 |
|
$placement = apply_filters( 'gravityview/approve_entries/popover_placement', $placement ); |
726
|
|
|
|
727
|
1 |
|
return $placement; |
728
|
|
|
} |
729
|
|
|
|
730
|
|
|
/** |
731
|
|
|
* Get HTML template for a popover used to display approval statuses |
732
|
|
|
* |
733
|
|
|
* @since 2.3.1 |
734
|
|
|
* |
735
|
|
|
* @internal For internal use only! |
736
|
|
|
* |
737
|
|
|
* @return string HTML code |
738
|
|
|
*/ |
739
|
1 |
|
public static function get_popover_template() { |
740
|
|
|
|
741
|
1 |
|
$choices = GravityView_Entry_Approval_Status::get_all(); |
742
|
|
|
|
743
|
|
|
return <<<TEMPLATE |
744
|
1 |
|
<a href="#" data-approved="{$choices['approved']['value']}" aria-role="button" aria-live="polite" class="gv-approval-toggle gv-approval-approved popover" title="{$choices['approved']['action']}"><span class="screen-reader-text">{$choices['approved']['action']}</span></a> |
745
|
1 |
|
<a href="#" data-approved="{$choices['disapproved']['value']}" aria-role="button" aria-live="polite" class="gv-approval-toggle gv-approval-disapproved popover" title="{$choices['disapproved']['action']}"><span class="screen-reader-text">{$choices['disapproved']['action']}</span></a> |
746
|
1 |
|
<a href="#" data-approved="{$choices['unapproved']['value']}" aria-role="button" aria-live="polite" class="gv-approval-toggle gv-approval-unapproved popover" title="{$choices['unapproved']['action']}"><span class="screen-reader-text">{$choices['unapproved']['action']}</span></a> |
747
|
|
|
TEMPLATE; |
748
|
|
|
} |
749
|
|
|
} |
750
|
|
|
|
751
|
|
|
new GravityView_Entry_Approval; |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.