Completed
Pull Request — develop (#1523)
by Zack
19:02
created

enqueue_selectwoo_assets()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
nc 9
nop 0
dl 0
loc 34
ccs 0
cts 15
cp 0
crap 42
rs 8.7537
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @since 1.2
5
 */
6
class GravityView_Change_Entry_Creator {
7
8 1
	/*
9
	 * @var int Number of users to show in the select element
10
	 */
11
	const DEFAULT_NUMBER_OF_USERS = 100;
12
13 1
	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...
14
15
		/**
16 1
		 * @since  1.5.1
17
		 */
18
		add_action( 'gform_user_registered', array( $this, 'assign_new_user_to_lead' ), 10, 4 );
19
20
		// ONLY ADMIN FROM HERE ON.
21
		if ( ! is_admin() ) {
22
			return;
23
		}
24
25
		/**
26
		 * @filter `gravityview_disable_change_entry_creator` Disable the Change Entry Creator functionality
27
		 * @since  1.7.4
28
		 * @param boolean $disable Disable the Change Entry Creator functionality. Default: false.
29
		 */
30
		if ( apply_filters( 'gravityview_disable_change_entry_creator', false ) ) {
31
			return;
32
		}
33
34
		/**
35
		 * Use `init` to fix bbPress warning
36
		 *
37
		 * @see https://bbpress.trac.wordpress.org/ticket/2309
38
		 */
39
		add_action( 'init', array( $this, 'load' ), 100 );
40
41
		add_action( 'plugins_loaded', array( $this, 'prevent_conflicts' ) );
42
43
		// Enqueues selectWoo script and style.
44
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_selectwoo_assets' ) );
45
46
		// Ajax callback to get users to change entry creator.
47
		add_action( 'wp_ajax_entry_creator_get_users', array( $this, 'entry_creator_get_users' ) );
48
49
	}
50
51
	/**
52
	 * Enqueue selectWoo script and style.
53
	 *
54
	 * @since  2.9.1
55
	 */
56
	function enqueue_selectwoo_assets() {
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...
57
58
		global $current_screen;
59
60
		if ( ! $current_screen || 'forms_page_gf_entries' !== $current_screen->base ) {
61
			return;
62
		}
63
64
		$version      = \GV\Plugin::$version;
65
		$script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
66
67
		if ( gravityview()->plugin->is_GF_25() ) {
68
			wp_deregister_script( 'gform_selectwoo' );
69
			wp_dequeue_script( 'gform_selectwoo' );
70
		}
71
72
		wp_enqueue_script( 'gravityview-selectWoo', plugins_url( 'assets/lib/selectWoo/selectWoo.full.min.js', GRAVITYVIEW_FILE ), array(), $version );
73
		wp_enqueue_style( 'gravityview-selectWoo', plugins_url( 'assets/lib/selectWoo/selectWoo.min.css', GRAVITYVIEW_FILE ), array(), $version );
74
75
		wp_enqueue_script( 'gravityview_entry_creator', plugins_url( 'assets/js/admin-entry-creator' . $script_debug . '.js', GRAVITYVIEW_FILE ), array( 'jquery', 'gravityview-selectWoo' ), $version );
76
77
		wp_localize_script(
78
			'gravityview_entry_creator',
79
			'GVEntryCreator',
80
			array(
81
				'ajaxurl'  => admin_url( 'admin-ajax.php' ),
82
				'action'   => 'entry_creator_get_users',
83
				'gf25'    => (bool) gravityview()->plugin->is_GF_25(),
84
				'language' => array(
85
					'search_placeholder' => esc_html__( 'Search by ID, login, email, or name.', 'gravityview' ),
86
				),
87
			)
88
		);
89
	}
90
91
	/**
92
	 * Get users list for entry creator.
93
	 *
94
	 * @since  2.9.1
95
	 *
96
	 */
97
	function entry_creator_get_users() {
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...
98
99
		$post_var = wp_parse_args(
100
			wp_unslash( $_POST ),
101
			array(
102
				'q'        => '',
103
				'gv_nonce' => '',
104
			)
105
		);
106
107
		if ( ! wp_verify_nonce( $post_var['gv_nonce'], 'gv_entry_creator' ) ) {
108
			die();
109
		}
110
111
		$search_string = $post_var['q'];
112
113
		if ( is_numeric( $search_string ) ) {
114
			$user_args = array(
115
				'search'         => $search_string . '*',
116
				'search_columns' => array( 'ID' ),
117
			);
118
		} else {
119
			$user_args = array(
120
				'search'         => '*' . $search_string . '*',
121
				'search_columns' => array( 'user_login', 'user_email', 'user_nicename', 'display_name' ),
122
			);
123
		}
124
125
		$users = GVCommon::get_users( 'change_entry_creator', $user_args );
126
127
		wp_send_json( $users, 200 );
128
	}
129
130
	/**
131
	 * When an user is created using the User Registration add-on, assign the entry to them
132
	 *
133
	 * @since  1.5.1
134
	 * @param int    $user_id  WordPress User ID
135
	 * @param array  $config   User registration feed configuration
136
	 * @param array  $entry    GF Entry array
137
	 * @param string $password User password
138
	 * @return void
139
	 * @uses   RGFormsModel::update_lead_property() Modify the entry `created_by` field
140
	 */
141
	function assign_new_user_to_lead( $user_id, $config, $entry = array(), $password = '' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $password 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...
142
143
		/**
144
		 * Disable assigning the new user to the entry by returning false.
145
		 *
146
		 * @param int   $user_id WordPress User ID
147
		 * @param array $config  User registration feed configuration
148
		 * @param array $entry   GF Entry array
149
		 */
150
		$assign_to_lead = apply_filters( 'gravityview_assign_new_user_to_entry', true, $user_id, $config, $entry );
151
152
		// If filter returns false, do not process
153
		if ( empty( $assign_to_lead ) ) {
154
			return;
155
		}
156
157
		// Update the entry. The `false` prevents checking Akismet; `true` disables the user updated hook from firing
158
		$result = RGFormsModel::update_entry_property( (int) $entry['id'], 'created_by', (int) $user_id, false, true );
159
160
		if ( false === $result ) {
161
			$status = __( 'Error', 'gravityview' );
162
			global $wpdb;
163
			$note = sprintf( '%s: Failed to assign User ID #%d as the entry creator (Last database error: "%s")', $status, $user_id, $wpdb->last_error );
164
		} else {
165
			$status = __( 'Success', 'gravityview' );
166
			$note   = sprintf( _x( '%s: Assigned User ID #%d as the entry creator.', 'First parameter: Success or error of the action. Second: User ID number', 'gravityview' ), $status, $user_id );
167
		}
168
169
		gravityview()->log->debug( 'GravityView_Change_Entry_Creator[assign_new_user_to_lead] - {note}', array( 'note' => $note ) );
170
171
		/**
172
		 * @filter `gravityview_disable_change_entry_creator_note` Disable adding a note when changing the entry creator
173
		 * @since  1.21.5
174
		 * @param boolean $disable Disable the Change Entry Creator note. Default: false.
175
		 */
176
		if ( apply_filters( 'gravityview_disable_change_entry_creator_note', false ) ) {
177
			return;
178
		}
179
180
		GravityView_Entry_Notes::add_note( $entry['id'], - 1, 'GravityView', $note, 'gravityview' );
181
182
	}
183
184
	/**
185
	 * Disable previous functionality; use this one as the canonical.
186
	 *
187
	 * @return void
188
	 */
189
	function prevent_conflicts() {
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...
190
191
		// Plugin that was provided here:
192
		// @link https://gravityview.co/support/documentation/201991205/
193
		remove_action( "gform_entry_info", 'gravityview_change_entry_creator_form', 10 );
194
		remove_action( "gform_after_update_entry", 'gravityview_update_entry_creator', 10 );
195
196
	}
197
198
	/**
199
	 * @since  3.6.3
200
	 * @return void
201
	 */
202 1
	function load() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
203
204 1
		// Does GF exist?
205
		if ( ! class_exists( 'GFCommon' ) ) {
206
			return;
207
		}
208 1
209
		// Can the user edit entries?
210 1
		if ( ! GVCommon::has_cap( array( 'gravityforms_edit_entries', 'gravityview_edit_entries' ) ) ) {
211
			return;
212 1
		}
213
214
		// If screen mode isn't set, then we're in the wrong place.
215 1
		if ( empty( $_REQUEST['screen_mode'] ) ) {
216
			return;
217
		}
218
219
		// Now, no validation is required in the methods; let's hook in.
220
		add_action( 'admin_init', array( &$this, 'set_screen_mode' ) );
221
222 1
		add_action( 'gform_entry_info', array( &$this, 'add_select' ), 10, 2 );
223 1
224 1
		add_action( "gform_after_update_entry", array( &$this, 'update_entry_creator' ), 10, 2 );
225
226
	}
227
228 1
	/**
229 1
	 * Allows for edit links to work with a link instead of a form (GET instead of POST)
230
	 *
231
	 * @return void
232
	 */
233 1
	function set_screen_mode() {
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...
234 1
235 1
		if ( 'view' === \GV\Utils::_POST( 'screen_mode' ) ) {
236 1
			return;
237
		}
238 1
239 1
		// If $_GET['screen_mode'] is set to edit, set $_POST value
240
		if ( \GV\Utils::_GET( 'screen_mode' ) === 'edit' ) {
241 1
			$_POST["screen_mode"] = 'edit';
242
		}
243 1
244 1
	}
245
246
	/**
247
	 * When the entry creator is changed, add a note to the entry
248
	 *
249
	 * @param array $form     GF entry array
250
	 * @param int   $entry_id Entry ID
251
	 * @return void
252
	 */
253
	function update_entry_creator( $form, $entry_id ) {
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...
254
255
		global $current_user;
256
257
		// Update the entry
258
		$created_by = absint( \GV\Utils::_POST( 'created_by' ) );
259
260
		RGFormsModel::update_lead_property( $entry_id, 'created_by', $created_by );
261
262
		// If the creator has changed, let's add a note about who it used to be.
263
		$originally_created_by = \GV\Utils::_POST( 'originally_created_by' );
264
265
		// If there's no owner and there didn't used to be, keep going
266
		if ( empty( $originally_created_by ) && empty( $created_by ) ) {
267
			return;
268
		}
269
270
		// If the values have changed
271
		if ( absint( $originally_created_by ) !== absint( $created_by ) ) {
272
273
			$user_data = get_userdata( $current_user->ID );
274
275
			$user_format = _x( '%s (ID #%d)', 'The name and the ID of users who initiated changes to entry ownership', 'gravityview' );
276
277
			$original_name = $created_by_name = esc_attr_x( 'No User', 'To show that the entry was unassigned from an actual user to no user.', 'gravityview' );
278
279
			if ( ! empty( $originally_created_by ) ) {
280
				$originally_created_by_user_data = get_userdata( $originally_created_by );
281
				$original_name                   = sprintf( $user_format, $originally_created_by_user_data->display_name, $originally_created_by_user_data->ID );
282
			}
283
284
			if ( ! empty( $created_by ) ) {
285
				$created_by_user_data = get_userdata( $created_by );
286
				$created_by_name      = sprintf( $user_format, $created_by_user_data->display_name, $created_by_user_data->ID );
287
			}
288
289
			GravityView_Entry_Notes::add_note( $entry_id, $current_user->ID, $user_data->display_name, sprintf( __( 'Changed entry creator from %s to %s', 'gravityview' ), $original_name, $created_by_name ), 'note' );
290
		}
291
292
	}
293
294
	/**
295
	 * Output select element used to change the entry creator
296
	 *
297
	 * @param int   $form_id GF Form ID
298
	 * @param array $entry   GF entry array
299
	 *
300
	 * @return void
301
	 */
302
	function add_select( $form_id, $entry ) {
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...
303
304
		if ( 'edit' !== \GV\Utils::_POST( 'screen_mode' ) ) {
305
			return;
306
		}
307
308
		$output = '<label for="change_created_by">';
309
		$output .= esc_html__( 'Change Entry Creator:', 'gravityview' );
310
		$output .= '</label>';
311
		$output .= '<select name="created_by" id="change_created_by" class="widefat">';
312
313
		$entry_creator_user_id = \GV\Utils::get( $entry, 'created_by' );
314
315
		$entry_creator_user = GVCommon::get_users( 'change_entry_creator', array( 'include' => $entry_creator_user_id ) );
316
		$entry_creator_user = isset( $entry_creator_user[0] ) ? $entry_creator_user[0] : array();
317
318
		if ( empty( $entry_creator_user ) ) {
319
			$output .= '<option value="0"> &mdash; ' . esc_attr_x( 'No User', 'No user assigned to the entry', 'gravityview' ) . ' &mdash; </option>';
320
		} else {
321
			$output .= '<option value="' . $entry_creator_user->ID . '" "selected">' . esc_attr( $entry_creator_user->display_name . ' (' . $entry_creator_user->user_nicename . ')' ) . '</option>';
322
		}
323
324
		$all_users = GVCommon::get_users( 'change_entry_creator', array( 'number' => self::DEFAULT_NUMBER_OF_USERS ) );
325
		foreach ( $all_users as $user ) {
326
			if ( $entry_creator_user_id === $user->ID ) {
327
				continue;
328
			}
329
330
			$output .= '<option value="' . $user->ID . '">' . esc_attr( $user->display_name . ' (' . $user->user_nicename . ')' ) . '</option>';
331
		}
332
333
		$user_count      = count_users();
334
		$user_count      = $user_count['total_users'];
335
		$users_displayed = self::DEFAULT_NUMBER_OF_USERS + ( ! empty( $entry_creator_user ) ? 1 : 0 );
336
		if ( $user_count > $users_displayed ) {
337
			$remaining_users = $user_count - $users_displayed;
338
			$user_users = _n( esc_html__('user', 'gravityview' ), esc_html__('users', 'gravityview' ), $remaining_users );
339
			$message = esc_html_x( 'Use the input above to search the remaining %d %s.', '%d is replaced with user count %s is replaced with "user" or "users"', 'gravityview' );
340
			$message = sprintf( $message, $remaining_users, $user_users );
341
			$output  .= '<option value="_user_count" disabled="disabled">' . esc_html( $message ) . '</option>';
342
		}
343
344
		$output .= '</select>';
345
		$output .= '<input name="originally_created_by" value="' . esc_attr( $entry['created_by'] ) . '" type="hidden" />';
346
		$output .= wp_nonce_field( 'gv_entry_creator', 'gv_entry_creator_nonce', false, false );
347
348
		echo $output;
349
	}
350
}
351
352
new GravityView_Change_Entry_Creator;
353