Issues (1282)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/admin/class-give-html-elements.php (11 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * HTML elements
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_HTML_Elements
7
 * @copyright   Copyright (c) 2016, GiveWP
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Give_HTML_Elements Class
19
 *
20
 * A helper class for outputting common HTML elements, such as product drop downs.
21
 *
22
 * @since 1.0
23
 */
24
class Give_HTML_Elements {
0 ignored issues
show
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
25
	/**
26
	 * Instance.
27
	 *
28
	 * @since  1.0
29
	 * @access private
30
	 * @var
31
	 */
32
	static private $instance;
33
34
	/**
35
	 * Singleton pattern.
36
	 *
37
	 * @since  1.0
38
	 * @access private
39
	 */
40
	private function __construct() {
41
	}
42
43
44
	/**
45
	 * Get instance.
46
	 *
47
	 * @since  1.0
48
	 * @access public
49
	 * @return Give_HTML_Elements
50
	 */
51
	public static function get_instance() {
52
		if ( null === static::$instance ) {
53
			self::$instance = new static();
54
		}
55
56
		return self::$instance;
57
	}
58
59
60
	/**
61
	 * Donations Dropdown
62
	 *
63
	 * Renders an HTML Dropdown of all the donations.
64
	 *
65
	 * @since  1.0
66
	 * @access public
67
	 *
68
	 * @param  array $args Arguments for the dropdown.
69
	 *
70
	 * @return string       Donations dropdown.
71
	 */
72
	public function donations_dropdown( $args = array() ) {
73
74
		$defaults = array(
75
			'name'        => 'donations',
76
			'id'          => 'donations',
77
			'class'       => '',
78
			'multiple'    => false,
79
			'selected'    => 0,
80
			'chosen'      => false,
81
			'number'      => 30,
82
			'placeholder' => __( 'Select a donation', 'give' ),
83
		);
84
85
		$args = wp_parse_args( $args, $defaults );
86
87
		$payments = new Give_Payments_Query( array(
88
			'number' => $args['number'],
89
		) );
90
91
		$payments = $payments->get_payments();
92
93
		$options = array();
94
95
		// Provide nice human readable options.
96 View Code Duplication
		if ( $payments ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
			$options[0] = $args['placeholder'];
98
			foreach ( $payments as $payment ) {
99
100
				$options[ absint( $payment->ID ) ] = esc_html( '#' . $payment->ID . ' - ' . $payment->email . ' - ' . $payment->form_title );
101
102
			}
103
		} else {
104
			$options[0] = __( 'No donations found.', 'give' );
105
		}
106
107
		$output = $this->select( array(
108
			'name'             => $args['name'],
109
			'selected'         => $args['selected'],
110
			'id'               => $args['id'],
111
			'class'            => $args['class'],
112
			'options'          => $options,
113
			'chosen'           => $args['chosen'],
114
			'multiple'         => $args['multiple'],
115
			'placeholder'      => $args['placeholder'],
116
			'select_atts'      => $args['select_atts'],
117
			'show_option_all'  => false,
118
			'show_option_none' => false,
119
		) );
120
121
		return $output;
122
	}
123
124
	/**
125
	 * Give Forms Dropdown
126
	 *
127
	 * Renders an HTML Dropdown of all the Give Forms.
128
	 *
129
	 * @since  1.0
130
	 * @access public
131
	 *
132
	 * @param  array $args Arguments for the dropdown.
133
	 *
134
	 * @return string      Give forms dropdown.
135
	 */
136
	public function forms_dropdown( $args = array() ) {
137
138
		$defaults = array(
139
			'name'        => 'forms',
140
			'id'          => 'forms',
141
			'class'       => '',
142
			'multiple'    => false,
143
			'selected'    => 0,
144
			'chosen'      => false,
145
			'number'      => 30,
146
			'placeholder' => esc_attr__( 'All Forms', 'give' ),
147
			'data'        => array(
148
				'search-type' => 'form',
149
			),
150
			'query_args'  => array(),
151
		);
152
153
		$args = wp_parse_args( $args, $defaults );
154
155
		$form_args = wp_parse_args(
156
			$args['query_args'],
157
			array(
158
				'post_type'      => 'give_forms',
159
				'orderby'        => 'ID',
160
				'order'          => 'DESC',
161
				'posts_per_page' => $args['number'],
162
			)
163
		);
164
165
		/**
166
		 * Filter the forms dropdown.
167
		 *
168
		 * @since 2.3.0
169
		 *
170
		 * @param array $form_args Arguments for forms_dropdown query.
171
		 *
172
		 * @return array Arguments for forms_dropdown query.
173
		 */
174
		$form_args = apply_filters( 'give_forms_dropdown_args', $form_args );
175
176
		$cache_key = Give_Cache::get_key( 'give_forms', $form_args, false );
177
178
		// Get forms from cache.
179
		$forms = Give_Cache::get_db_query( $cache_key );
180
181
		if ( is_null( $forms ) ) {
182
			$forms = new WP_Query( $form_args );
183
			$forms = $forms->posts;
184
			Give_Cache::set_db_query( $cache_key, $forms );
185
		}
186
187
		$options = array();
188
189
		// Ensure the selected.
190
		if ( false !== $args['selected'] && $args['selected'] !== 0 ) {
191
			$options[ $args['selected'] ] = get_the_title( $args['selected'] );
192
		}
193
194
		$options[0] = esc_html__( 'No forms found.', 'give' );
195 View Code Duplication
		if ( ! empty( $forms ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
196
			$options[0] = $args['placeholder'];
197
			foreach ( $forms as $form ) {
198
				$form_title = empty( $form->post_title )
199
					? sprintf( __( 'Untitled (#%s)', 'give' ), $form->ID )
200
					: $form->post_title;
201
202
				$options[ absint( $form->ID ) ] = esc_html( $form_title );
203
			}
204
		}
205
206
		$output = $this->select( array(
207
			'name'             => $args['name'],
208
			'selected'         => $args['selected'],
209
			'id'               => $args['id'],
210
			'class'            => $args['class'],
211
			'options'          => $options,
212
			'chosen'           => $args['chosen'],
213
			'multiple'         => $args['multiple'],
214
			'placeholder'      => $args['placeholder'],
215
			'show_option_all'  => false,
216
			'show_option_none' => false,
217
			'data'             => $args['data'],
218
		) );
219
220
		return $output;
221
	}
222
223
	/**
224
	 * Donors Dropdown
225
	 *
226
	 * Renders an HTML Dropdown of all donors.
227
	 *
228
	 * @since  1.0
229
	 * @access public
230
	 *
231
	 * @param  array $args Arguments for the dropdown.
232
	 *
233
	 * @return string      Donors dropdown.
234
	 */
235
	public function donor_dropdown( $args = array() ) {
236
237
		$defaults = array(
238
			'name'        => 'donors',
239
			'id'          => 'donors',
240
			'class'       => '',
241
			'multiple'    => false,
242
			'selected'    => 0,
243
			'chosen'      => true,
244
			'placeholder' => esc_attr__( 'Select a Donor', 'give' ),
245
			'number'      => 30,
246
			'data'        => array(
247
				'search-type' => 'donor',
248
			),
249
		);
250
251
		$args = wp_parse_args( $args, $defaults );
252
253
		$donors = Give()->donors->get_donors( array(
254
			'number' => $args['number'],
255
		) );
256
257
		$options = array();
258
259
		if ( $donors ) {
260
			$options[0] = esc_html__( 'No donor attached', 'give' );
261
			foreach ( $donors as $donor ) {
262
				$donor                           = give_get_name_with_title_prefixes( $donor );
263
				$options[ absint( $donor->id ) ] = esc_html( $donor->name . ' (' . $donor->email . ')' );
264
			}
265
		} else {
266
			$options[0] = esc_html__( 'No donors found.', 'give' );
267
		}
268
269
		if ( ! empty( $args['selected'] ) ) {
270
271
			// If a selected customer has been specified, we need to ensure it's in the initial list of customers displayed.
272
			if ( ! array_key_exists( $args['selected'], $options ) ) {
273
274
				$donor = new Give_Donor( $args['selected'] );
275
276
				if ( $donor ) {
277
					$donor                                  = give_get_name_with_title_prefixes( $donor );
278
					$options[ absint( $args['selected'] ) ] = esc_html( $donor->name . ' (' . $donor->email . ')' );
279
280
				}
281
			}
282
		}
283
284
		$output = $this->select( array(
285
			'name'             => $args['name'],
286
			'selected'         => $args['selected'],
287
			'id'               => $args['id'],
288
			'class'            => $args['class'] . ' give-customer-select',
289
			'options'          => $options,
290
			'multiple'         => $args['multiple'],
291
			'chosen'           => $args['chosen'],
292
			'show_option_all'  => false,
293
			'show_option_none' => false,
294
			'data'             => $args['data'],
295
		) );
296
297
		return $output;
298
	}
299
300
	/**
301
	 * Categories Dropdown
302
	 *
303
	 * Renders an HTML Dropdown of all the Categories.
304
	 *
305
	 * @since  1.0
306
	 * @access public
307
	 *
308
	 * @param  string $name     Name attribute of the dropdown. Default is 'give_forms_categories'.
309
	 * @param  int    $selected Category to select automatically. Default is 0.
310
	 * @param  array  $args     Select box options.
311
	 *
312
	 * @return string           Categories dropdown.
313
	 */
314 View Code Duplication
	public function category_dropdown( $name = 'give_forms_categories', $selected = 0, $args = array() ) {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
315
		$categories = get_terms( 'give_forms_category', apply_filters( 'give_forms_category_dropdown', array() ) );
316
317
		$options = array();
318
319
		foreach ( $categories as $category ) {
320
			$options[ absint( $category->term_id ) ] = esc_html( $category->name );
321
		}
322
323
		$output = $this->select( wp_parse_args( $args, array(
324
			'name'             => $name,
325
			'selected'         => $selected,
326
			'options'          => $options,
327
			'show_option_all'  => esc_html__( 'All Categories', 'give' ),
328
			'show_option_none' => false,
329
		) ) );
330
331
		return $output;
332
	}
333
334
	/**
335
	 * Tags Dropdown
336
	 *
337
	 * Renders an HTML Dropdown of all the Tags.
338
	 *
339
	 * @since  1.8
340
	 * @access public
341
	 *
342
	 * @param  string $name     Name attribute of the dropdown. Default is 'give_forms_tags'.
343
	 * @param  int    $selected Tag to select automatically. Default is 0.
344
	 * @param  array  $args     Select box options.
345
	 *
346
	 * @return string           Tags dropdown.
347
	 */
348 View Code Duplication
	public function tags_dropdown( $name = 'give_forms_tags', $selected = 0, $args = array() ) {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
349
		$tags = get_terms( 'give_forms_tag', apply_filters( 'give_forms_tag_dropdown', array() ) );
350
351
		$options = array();
352
353
		foreach ( $tags as $tag ) {
354
			$options[ absint( $tag->term_id ) ] = esc_html( $tag->name );
355
		}
356
357
		$output = $this->select( wp_parse_args( $args, array(
358
			'name'             => $name,
359
			'selected'         => $selected,
360
			'options'          => $options,
361
			'show_option_all'  => esc_html__( 'All Tags', 'give' ),
362
			'show_option_none' => false,
363
		) ) );
364
365
		return $output;
366
	}
367
368
	/**
369
	 * Years Dropdown
370
	 *
371
	 * Renders an HTML Dropdown of years.
372
	 *
373
	 * @since  1.0
374
	 * @access public
375
	 *
376
	 * @param  string $name         Name attribute of the dropdown. Default is 'year'.
377
	 * @param  int    $selected     Year to select automatically. Default is 0.
378
	 * @param  int    $years_before Number of years before the current year the dropdown should start with. Default is 5.
379
	 * @param  int    $years_after  Number of years after the current year the dropdown should finish at. Default is 0.
380
	 *
381
	 * @return string               Years dropdown.
382
	 */
383
	public function year_dropdown( $name = 'year', $selected = 0, $years_before = 5, $years_after = 0 ) {
384
		$current    = date( 'Y' );
385
		$start_year = $current - absint( $years_before );
386
		$end_year   = $current + absint( $years_after );
387
		$selected   = empty( $selected ) ? date( 'Y' ) : $selected;
388
		$options    = array();
389
390
		while ( $start_year <= $end_year ) {
391
			$options[ absint( $start_year ) ] = $start_year;
392
			$start_year ++;
393
		}
394
395
		$output = $this->select( array(
396
			'name'             => $name,
397
			'selected'         => $selected,
398
			'options'          => $options,
399
			'show_option_all'  => false,
400
			'show_option_none' => false,
401
		) );
402
403
		return $output;
404
	}
405
406
	/**
407
	 * Months Dropdown
408
	 *
409
	 * Renders an HTML Dropdown of months.
410
	 *
411
	 * @since  1.0
412
	 * @access public
413
	 *
414
	 * @param  string $name     Name attribute of the dropdown. Default is 'month'.
415
	 * @param  int    $selected Month to select automatically. Default is 0.
416
	 *
417
	 * @return string           Months dropdown.
418
	 */
419
	public function month_dropdown( $name = 'month', $selected = 0 ) {
420
		$month    = 1;
421
		$options  = array();
422
		$selected = empty( $selected ) ? date( 'n' ) : $selected;
423
424
		while ( $month <= 12 ) {
425
			$options[ absint( $month ) ] = give_month_num_to_name( $month );
426
			$month ++;
427
		}
428
429
		$output = $this->select( array(
430
			'name'             => $name,
431
			'selected'         => $selected,
432
			'options'          => $options,
433
			'show_option_all'  => false,
434
			'show_option_none' => false,
435
		) );
436
437
		return $output;
438
	}
439
440
	/**
441
	 * Dropdown
442
	 *
443
	 * Renders an HTML Dropdown.
444
	 *
445
	 * @since  1.0
446
	 * @access public
447
	 *
448
	 * @param  array $args Arguments for the dropdown.
449
	 *
450
	 * @return string      The dropdown.
451
	 */
452
	public function select( $args = array() ) {
453
		$defaults = array(
454
			'options'          => array(),
455
			'name'             => null,
456
			'class'            => '',
457
			'id'               => '',
458
			'autocomplete'     => 'no',
459
			'selected'         => 0,
460
			'chosen'           => false,
461
			'placeholder'      => null,
462
			'multiple'         => false,
463
			'select_atts'      => false,
464
			'show_option_all'  => __( 'All', 'give' ),
465
			'show_option_none' => __( 'None', 'give' ),
466
			'data'             => array(),
467
			'readonly'         => false,
468
			'disabled'         => false,
469
		);
470
471
		$args = wp_parse_args( $args, $defaults );
472
473
		$data_elements = '';
474
		foreach ( $args['data'] as $key => $value ) {
475
			$data_elements .= ' data-' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
476
		}
477
478
		$multiple = '';
479
		if ( $args['multiple'] ) {
480
			$multiple = 'MULTIPLE';
481
		}
482
483
		if ( $args['chosen'] ) {
484
			$args['class'] .= ' give-select-chosen';
485
		}
486
487
		$placeholder = '';
488
		if ( $args['placeholder'] ) {
489
			$placeholder = $args['placeholder'];
490
		}
491
492
		$output = sprintf(
493
			'<select name="%1$s" id="%2$s" autocomplete="%8$s" class="give-select %3$s" %4$s %5$s placeholder="%6$s" data-placeholder="%6$s" %7$s>',
494
			esc_attr( $args['name'] ),
495
			esc_attr( sanitize_key( str_replace( '-', '_', $args['id'] ) ) ),
496
			esc_attr( $args['class'] ),
497
			$multiple,
498
			$args['select_atts'],
499
			$placeholder,
500
			$data_elements,
501
			$args['autocomplete']
502
		);
503
504 View Code Duplication
		if ( $args['show_option_all'] ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
505
			if ( $args['multiple'] ) {
506
				$selected = selected( true, in_array( 0, $args['selected'] ), false );
507
			} else {
508
				$selected = selected( $args['selected'], 0, false );
509
			}
510
			$output .= '<option value="all"' . $selected . '>' . esc_html( $args['show_option_all'] ) . '</option>';
511
		}
512
513
		if ( ! empty( $args['options'] ) ) {
514
515 View Code Duplication
			if ( $args['show_option_none'] ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
516
				if ( $args['multiple'] ) {
517
					$selected = selected( true, in_array( - 1, $args['selected'] ), false );
518
				} else {
519
					$selected = selected( $args['selected'], - 1, false );
520
				}
521
				$output .= '<option value="-1"' . $selected . '>' . esc_html( $args['show_option_none'] ) . '</option>';
522
			}
523
524
			foreach ( $args['options'] as $key => $option ) {
525
526
				if ( $args['multiple'] && is_array( $args['selected'] ) ) {
527
					$selected = selected( true, in_array( $key, $args['selected'] ), false );
528
				} else {
529
					$selected = selected( $args['selected'], $key, false );
530
				}
531
532
				$output .= '<option value="' . esc_attr( $key ) . '"' . $selected . '>' . esc_html( $option ) . '</option>';
533
			}
534
		}
535
536
		$output .= '</select>';
537
538
		return $output;
539
	}
540
541
	/**
542
	 * Checkbox
543
	 *
544
	 * Renders an HTML Checkbox.
545
	 *
546
	 * @since  1.0
547
	 * @access public
548
	 *
549
	 * @param  array $args Arguments for the Checkbox.
550
	 *
551
	 * @return string      The checkbox.
552
	 */
553
	public function checkbox( $args = array() ) {
554
		$defaults = array(
555
			'name'    => null,
556
			'current' => null,
557
			'class'   => 'give-checkbox',
558
			'options' => array(
559
				'disabled' => false,
560
				'readonly' => false,
561
			),
562
		);
563
564
		$args = wp_parse_args( $args, $defaults );
565
566
		$options = '';
567
		if ( ! empty( $args['options']['disabled'] ) ) {
568
			$options .= ' disabled="disabled"';
569
		} elseif ( ! empty( $args['options']['readonly'] ) ) {
570
			$options .= ' readonly';
571
		}
572
573
		$output = '<input type="checkbox"' . $options . ' name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['name'] ) . '" class="' . $args['class'] . ' ' . esc_attr( $args['name'] ) . '" ' . checked( 1, $args['current'], false ) . ' />';
574
575
		return $output;
576
	}
577
578
	/**
579
	 * Text Field
580
	 *
581
	 * Renders an HTML Text field.
582
	 *
583
	 * @since  1.0
584
	 * @access public
585
	 *
586
	 * @param  array $args Arguments for the text field.
587
	 *
588
	 * @return string      The text field.
589
	 */
590
	public function text( $args = array() ) {
591
		// Backwards compatibility.
592
		if ( func_num_args() > 1 ) {
593
			$args = func_get_args();
594
595
			$name  = $args[0];
596
			$value = isset( $args[1] ) ? $args[1] : '';
597
			$label = isset( $args[2] ) ? $args[2] : '';
598
			$desc  = isset( $args[3] ) ? $args[3] : '';
599
		}
600
601
		$defaults = array(
602
			'name'         => isset( $name ) ? $name : 'text',
603
			'value'        => isset( $value ) ? $value : null,
604
			'label'        => isset( $label ) ? $label : null,
605
			'desc'         => isset( $desc ) ? $desc : null,
606
			'placeholder'  => '',
607
			'class'        => 'regular-text',
608
			'disabled'     => false,
609
			'autocomplete' => '',
610
			'data'         => false,
611
		);
612
613
		$args = wp_parse_args( $args, $defaults );
614
615
		$disabled = '';
616
		if ( $args['disabled'] ) {
617
			$disabled = ' disabled="disabled"';
618
		}
619
620
		$data = '';
621
		if ( ! empty( $args['data'] ) ) {
622
			foreach ( $args['data'] as $key => $value ) {
623
				$data .= 'data-' . $key . '="' . $value . '" ';
624
			}
625
		}
626
627
		$output = '<span id="give-' . sanitize_key( $args['name'] ) . '-wrap">';
628
		
629
		// Don't output label when the label is empty.
630
		if ( ! empty( $args['label'] ) ) {
631
			$output .= '<label class="give-label" for="give-' . sanitize_key( $args['name'] ) . '">' . esc_html( $args['label'] ) . '</label>';
632
		}
633
634 View Code Duplication
		if ( ! empty( $args['desc'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
635
			$output .= '<span class="give-description">' . esc_html( $args['desc'] ) . '</span>';
636
		}
637
638
		$output .= '<input type="text" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['name'] ) . '" autocomplete="' . esc_attr( $args['autocomplete'] ) . '" value="' . esc_attr( $args['value'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" class="' . $args['class'] . '" ' . $data . '' . $disabled . '/>';
639
640
		$output .= '</span>';
641
642
		return $output;
643
	}
644
645
	/**
646
	 * Date Picker
647
	 *
648
	 * Renders a date picker field.
649
	 *
650
	 * @since  1.5
651
	 * @access public
652
	 *
653
	 * @param  array $args Arguments for the date picker.
654
	 *
655
	 * @return string      The date picker.
656
	 */
657
	public function date_field( $args = array() ) {
658
659
		if ( empty( $args['class'] ) ) {
660
			$args['class'] = 'give_datepicker';
661
		} elseif ( ! strpos( $args['class'], 'give_datepicker' ) ) {
662
			$args['class'] .= ' give_datepicker';
663
		}
664
665
		return $this->text( $args );
666
	}
667
668
	/**
669
	 * Textarea
670
	 *
671
	 * Renders an HTML textarea.
672
	 *
673
	 * @since  1.0
674
	 * @access public
675
	 *
676
	 * @param  array $args Arguments for the textarea.
677
	 *
678
	 * @return string      The textarea.
679
	 */
680
	public function textarea( $args = array() ) {
681
		$defaults = array(
682
			'name'     => 'textarea',
683
			'value'    => null,
684
			'label'    => null,
685
			'desc'     => null,
686
			'class'    => 'large-text',
687
			'disabled' => false,
688
		);
689
690
		$args = wp_parse_args( $args, $defaults );
691
692
		$disabled = '';
693
		if ( $args['disabled'] ) {
694
			$disabled = ' disabled="disabled"';
695
		}
696
697
		$output = '<span id="give-' . sanitize_key( $args['name'] ) . '-wrap">';
698
699
		$output .= '<label class="give-label" for="give-' . sanitize_key( $args['name'] ) . '">' . esc_html( $args['label'] ) . '</label>';
700
701
		$output .= '<textarea name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['name'] ) . '" class="' . $args['class'] . '"' . $disabled . '>' . esc_attr( $args['value'] ) . '</textarea>';
702
703 View Code Duplication
		if ( ! empty( $args['desc'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
704
			$output .= '<span class="give-description">' . esc_html( $args['desc'] ) . '</span>';
705
		}
706
707
		$output .= '</span>';
708
709
		return $output;
710
	}
711
712
	/**
713
	 * User Search Field
714
	 *
715
	 * Renders an ajax user search field.
716
	 *
717
	 * @since  1.0
718
	 * @access public
719
	 *
720
	 * @param  array $args Arguments for the search field.
721
	 *
722
	 * @return string      The text field with ajax search.
723
	 */
724
	public function ajax_user_search( $args = array() ) {
725
726
		$defaults = array(
727
			'name'        => 'users',
728
			'id'          => 'users',
729
			'class'       => 'give-ajax-user-search',
730
			'multiple'    => false,
731
			'selected'    => 0,
732
			'chosen'      => true,
733
			'number'      => 30,
734
			'select_atts' => '',
735
			'placeholder' => __( 'Select a user', 'give' ),
736
			'data'        => array(
737
				'search-type' => 'user',
738
			),
739
		);
740
741
		$args = wp_parse_args( $args, $defaults );
742
743
		// Set initial args.
744
		$get_users_args = array(
745
			'number' => $args['number'],
746
		);
747
748
		// Ensure selected user is not included in initial query.
749
		// This is because sites with many users, it's not a guarantee the selected user will be returned.
750
		if ( ! empty( $args['selected'] ) ) {
751
			$get_users_args['exclude'] = $args['selected'];
752
		}
753
754
		// Initial users array.
755
		$users = apply_filters( 'give_ajax_user_search_initial_results', get_users( $get_users_args ), $args );
756
757
		// Now add the selected user to the $users array if the arg is present.
758
		if ( ! empty( $args['selected'] ) ) {
759
			$selected_user = apply_filters( 'give_ajax_user_search_selected_results', get_users( "include={$args['selected']}" ), $args );;
760
			$users = array_merge( $users, $selected_user );
761
		}
762
763
		$options = array();
764
765 View Code Duplication
		if ( $users ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
766
			$options[0] = $args['placeholder'];
767
			foreach ( $users as $user ) {
768
				$options[ absint( $user->ID ) ] = esc_html( $user->user_login . ' (' . $user->user_email . ')' );
769
			}
770
		} else {
771
			$options[0] = __( 'No users found.', 'give' );
772
		}
773
774
		$output = $this->select( array(
775
			'name'             => $args['name'],
776
			'selected'         => $args['selected'],
777
			'id'               => $args['id'],
778
			'class'            => $args['class'],
779
			'options'          => $options,
780
			'chosen'           => $args['chosen'],
781
			'multiple'         => $args['multiple'],
782
			'placeholder'      => $args['placeholder'],
783
			'select_atts'      => $args['select_atts'],
784
			'show_option_all'  => false,
785
			'show_option_none' => false,
786
			'data'             => $args['data'],
787
		) );
788
789
		return $output;
790
791
	}
792
793
}
794