Issues (4296)

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/class-notices.php (24 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
 * Admin Notices Class.
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Notices
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.8.9
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Give_Notices Class
19
 *
20
 * @since 1.8.9
21
 */
22
class Give_Notices {
23
	/**
24
	 * List of notices
25
	 * @var array
26
	 * @since  1.8.9
27
	 * @access private
28
	 */
29
	private static $notices = array();
30
31
32
	/**
33
	 * Flag to check if any notice auto dismissible among all notices
34
	 *
35
	 * @since  1.8.9
36
	 * @access private
37
	 * @var bool
38
	 */
39
	private static $has_auto_dismissible_notice = false;
40
41
	/**
42
	 * Flag to check if any notice has dismiss interval among all notices
43
	 *
44
	 * @since  1.8.9
45
	 * @access private
46
	 * @var bool
47
	 */
48
	private static $has_dismiss_interval_notice = false;
49
50
	/**
51
	 * Get things started.
52
	 *
53
	 * @since 1.8.9
54
	 */
55
	public function __construct() {
56
		add_action( 'admin_notices', array( $this, 'render_admin_notices' ), 999 );
57
		add_action( 'give_dismiss_notices', array( $this, 'dismiss_notices' ) );
58
59
		add_action( 'give_frontend_notices', array( $this, 'render_frontend_notices' ), 999 );
60
		add_action( 'give_pre_form_output', array( $this, 'render_frontend_form_notices' ), 10, 1 );
61
		add_action( 'give_ajax_donation_errors', array( $this, 'render_frontend_notices' ) );
62
63
		/**
64
		 * Backward compatibility for deprecated params.
65
		 *
66
		 * @since 1.8.14
67
		 */
68
		add_filter( 'give_register_notice_args', array( $this, 'bc_deprecated_params' ) );
69
		add_filter( 'give_frontend_errors_args', array( $this, 'bc_deprecated_params' ) );
70
		add_filter( 'give_frontend_notice_args', array( $this, 'bc_deprecated_params' ) );
71
	}
72
73
	/**
74
	 * Add backward compatibility to deprecated params.
75
	 *
76
	 * @since  1.8.14
77
	 * @access public
78
	 *
79
	 * @param array $args Array of notice params
80
	 *
81
	 * @return array
82
	 */
83
	public function bc_deprecated_params( $args ) {
84
		/**
85
		 *  Param: auto_dismissible
86
		 *  deprecated in 1.8.14
87
		 *
88
		 *  Check if auto_dismissible is set and it true then unset and change dismissible parameter value to auto
89
		 */
90
		if ( isset( $args['auto_dismissible'] ) ) {
91
			if ( ! empty( $args['auto_dismissible'] ) ) {
92
				$args['dismissible'] = 'auto';
93
			}
94
			// unset auto_dismissible as it has been deprecated.
95
			unset( $args['auto_dismissible'] );
96
		}
97
98
		return $args;
99
	}
100
101
	/**
102
	 * Register notice.
103
	 *
104
	 * @since  1.8.9
105
	 * @access public
106
	 *
107
	 * @param $notice_args
108
	 *
109
	 * @return bool
110
	 */
111
	public function register_notice( $notice_args ) {
112
		// Bailout.
113
		if ( empty( $notice_args['id'] ) || array_key_exists( $notice_args['id'], self::$notices ) ) {
114
			return false;
115
		}
116
117
		$notice_args = wp_parse_args(
118
			$notice_args,
119
			array(
120
				'id'                    => '',
121
				'description'           => '',
122
123
				/*
124
				 * Add custom notice html
125
				 * Note: This param has more priority then description, so if you have  both param then this one will be use
126
				 *       for generating notice html. Most of feature of notice attach to core generated html, so if you set
127
				 *       custom html then please add required classes and data attribute which help to apply feature on notice.
128
				 *
129
				 * @since 1.8.16
130
				 */
131
				'description_html'      => '',
132
133
				/*
134
				 * Add New Parameter and remove the auto_dismissible parameter.
135
				 * Value: auto/true/false
136
				 *
137
				 * @since 1.8.14
138
				 */
139
				'dismissible'           => true,
140
141
				// Value: error/warning/success/info/updated
142
				'type'                  => 'error',
143
144
				// Value: null/user/all
145
				'dismissible_type'      => null,
146
147
				// Value: shortly/permanent/null/custom
148
				'dismiss_interval'      => null,
149
150
				// Only set it when custom is defined.
151
				'dismiss_interval_time' => null,
152
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
153
154
			)
155
		);
156
157
		/**
158
		 * Filter to modify Notice args before it get add
159
		 *
160
		 * @since 1.8.14
161
		 */
162
		$notice_args = apply_filters( 'give_register_notice_args', $notice_args );
163
164
		// Set extra dismiss links if any.
165
		if ( false !== strpos( $notice_args['description'], 'data-dismiss-interval' ) ) {
166
167
			preg_match_all( "/data-([^\"]*)=\"([^\"]*)\"/", $notice_args['description'], $extra_notice_dismiss_link );
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal /data-([^\"]*)=\"([^\"]*)\"/ does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
168
169
			if ( ! empty( $extra_notice_dismiss_link ) ) {
170
				$extra_notice_dismiss_links = array_chunk( current( $extra_notice_dismiss_link ), 3 );
171
				foreach ( $extra_notice_dismiss_links as $extra_notice_dismiss_link ) {
172
					// Create array og key ==> value by parsing query string created after renaming data attributes.
173
					$data_attribute_query_str = str_replace( array( 'data-', '-', '"' ), array(
174
						'',
175
						'_',
176
						'',
177
					), implode( '&', $extra_notice_dismiss_link ) );
178
179
					$notice_args['extra_links'][] = wp_parse_args( $data_attribute_query_str );
180
				}
181
			}
182
		}
183
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
184
185
		self::$notices[ $notice_args['id'] ] = $notice_args;
186
187
		// Auto set show param if not already set.
188
		if ( ! isset( self::$notices[ $notice_args['id'] ]['show'] ) ) {
189
			self::$notices[ $notice_args['id'] ]['show'] = $this->is_notice_dismissed( $notice_args ) ? false : true;
190
		}
191
192
		// Auto set time interval for shortly.
193
		if ( 'shortly' === self::$notices[ $notice_args['id'] ]['dismiss_interval'] ) {
194
			self::$notices[ $notice_args['id'] ]['dismiss_interval_time'] = DAY_IN_SECONDS;
195
		}
196
197
		return true;
198
	}
199
200
	/**
201
	 * Display notice.
202
	 *
203
	 * @since 1.8.9
204
	 *
205
	 */
206
	public function render_admin_notices() {
207
		// Bailout.
208
		if ( empty( self::$notices ) ) {
209
			return;
210
		}
211
212
		// Do not render notice on Gutenberg editor page.
213
		if (
214
			function_exists('is_gutenberg_page')
0 ignored issues
show
Expected 1 spaces after opening bracket; 0 found
Loading history...
Expected 1 spaces before closing bracket; 0 found
Loading history...
215
			&& is_gutenberg_page()
216
		) {
217
			return;
218
		}
219
220
		$output = '';
221
222
		foreach ( self::$notices as $notice_id => $notice ) {
223
			// Check flag set to true to show notice.
224
			if ( ! $notice['show'] ) {
225
				continue;
226
			}
227
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
228
229
			// Render custom html.
230
			if( ! empty( $notice['description_html'] ) ) {
0 ignored issues
show
Space after opening control structure is required
Loading history...
No space before opening parenthesis is prohibited
Loading history...
231
				$output .= "{$notice['description_html']} \n";
232
				continue;
233
			}
234
235
			// Check if notice dismissible or not.
236
			if ( ! self::$has_auto_dismissible_notice ) {
237
				self::$has_auto_dismissible_notice = ( 'auto' === $notice['dismissible'] );
238
			}
239
240
			// Check if notice dismissible or not.
241
			if ( ! self::$has_dismiss_interval_notice ) {
242
				self::$has_dismiss_interval_notice = $notice['dismiss_interval'];
243
			}
244
245
			$css_id = ( false === strpos( $notice['id'], 'give' ) ? "give-{$notice['id']}" : $notice['id'] );
246
247
			$css_class = 'give-notice notice ' . ( empty( $notice['dismissible'] ) ? 'non' : 'is' ) . "-dismissible {$notice['type']} notice-{$notice['type']}";
248
			$output    .= sprintf(
249
				'<div id="%1$s" class="%2$s" data-dismissible="%3$s" data-dismissible-type="%4$s" data-dismiss-interval="%5$s" data-notice-id="%6$s" data-security="%7$s" data-dismiss-interval-time="%8$s" style="display: none">' . " \n",
250
				$css_id,
251
				$css_class,
252
				give_clean( $notice['dismissible'] ),
253
				$notice['dismissible_type'],
254
				$notice['dismiss_interval'],
255
				$notice['id'],
256
				empty( $notice['dismissible_type'] ) ? '' : wp_create_nonce( "give_edit_{$notice_id}_notice" ),
257
				$notice['dismiss_interval_time']
258
			);
259
260
			$output .= ( 0 === strpos( $notice['description'], '<div' ) || 0 === strpos( $notice['description'], '<p' ) ? $notice['description'] : "<p>{$notice['description']}</p>" );
261
			$output .= "</div> \n";
262
		}
263
264
		echo $output;
0 ignored issues
show
Expected next thing to be a escaping function, not '$output'
Loading history...
265
266
		$this->print_js();
267
	}
268
269
270
	/**
271
	 * Render give frontend notices.
272
	 *
273
	 * @since  1.8.9
274
	 * @access public
275
	 *
276
	 * @param int $form_id
277
	 */
278
	public function render_frontend_notices( $form_id = 0 ) {
279
		$errors = give_get_errors();
280
281
		$request_form_id = isset( $_REQUEST['form-id'] ) ? absint( $_REQUEST['form-id'] ) : 0;
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
282
283
		// Sanity checks first: Ensure that gateway returned errors display on the appropriate form.
284
		if ( ! isset( $_POST['give_ajax'] ) && $request_form_id !== $form_id ) {
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
285
			return;
286
		}
287
288
		if ( $errors ) {
289
			self::print_frontend_errors( $errors );
0 ignored issues
show
It seems like $errors defined by give_get_errors() on line 279 can also be of type string; however, Give_Notices::print_frontend_errors() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
290
291
			give_clear_errors();
292
		}
293
	}
294
295
	/**
296
	 * Renders notices for different actions depending on
297
	 * the type of form display option.
298
	 *
299
	 * @since 2.2
300
	 * @access public
301
	 *
302
	 * @param int $form_id Form ID.
303
	 *
304
	 * @return void
305
	 */
306
	public function render_frontend_form_notices( $form_id ) {
307
		$display_option = give_get_meta( $form_id, '_give_payment_display', true );
308
309
		if ( 'modal' === $display_option ) {
310
			add_action( 'give_payment_mode_top', array( $this, 'render_frontend_notices' ) );
311
		} else {
312
			add_action( 'give_pre_form', array( $this, 'render_frontend_notices' ), 11 );
313
		}
314
	}
315
316
	/**
317
	 * Print notice js.
318
	 *
319
	 * @since  1.8.9
320
	 * @access private
321
	 */
322
	private function print_js() {
323
		if ( self::$has_auto_dismissible_notice ) :
324
			?>
325
			<script>
326
				jQuery(document).ready(function () {
327
					// auto hide setting message in 5 seconds.
328
					window.setTimeout(
329
						function () {
330
							jQuery('.give-notice[data-dismissible="auto"]').slideUp();
331
						},
332
						5000
333
					);
334
				})
335
			</script>
336
			<?php
337
		endif;
338
339
		if ( self::$has_dismiss_interval_notice ) :
340
			?>
341
			<script>
342
				jQuery(document).ready(function () {
343
					var $body = jQuery('body');
344
345
					$body.on('click', '.give_dismiss_notice', function (e) {
346
						var $parent            = jQuery(this).parents('.give-notice'),
347
							custom_notice_data = {
348
								'dismissible_type': jQuery(this).data('dismissible-type'),
349
								'dismiss_interval': jQuery(this).data('dismiss-interval'),
350
								'dismiss_interval_time': jQuery(this).data('dismiss-interval-time')
351
							};
352
353
						$parent.find('button.notice-dismiss').trigger('click', [custom_notice_data]);
354
						return false;
355
					});
356
357
					$body.on('click', 'button.notice-dismiss', function (e, custom_notice_data) {
358
						var $parent            = jQuery(this).parents('.give-notice'),
359
							custom_notice_data = custom_notice_data || {};
360
361
						e.preventDefault();
362
363
						var data = {
364
							'give-action': 'dismiss_notices',
365
							'notice_id': $parent.data('notice-id'),
366
							'dismissible_type': $parent.data('dismissible-type'),
367
							'dismiss_interval': $parent.data('dismiss-interval'),
368
							'dismiss_interval_time': $parent.data('dismiss-interval-time'),
369
							'_wpnonce': $parent.data('security')
370
						};
371
372
						if (Object.keys(custom_notice_data).length) {
373
							jQuery.extend(data, custom_notice_data);
374
						}
375
376
						// Bailout.
377
						if (
378
							!data.dismiss_interval ||
379
							!data.dismissible_type
380
						) {
381
							return false;
382
						}
383
384
						jQuery.post(
385
							'<?php echo admin_url(); ?>admin-ajax.php',
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'admin_url'
Loading history...
386
							data,
387
							function (response) {
388
389
							})
390
					})
391
				});
392
			</script>
393
			<?php
394
		endif;
395
		?>
396
		<script>
397
			jQuery(document).ready(function($){
398
				// Fix notice appearance issue.
399
				window.setTimeout(
400
					function(){
401
						$('.give-notice').slideDown();
402
					},
403
					1000
404
				);
405
			});
406
		</script>
407
		<?php
408
	}
409
410
411
	/**
412
	 * Hide notice.
413
	 *
414
	 * @since  1.8.9
415
	 * @access public
416
	 */
417
	public function dismiss_notices() {
418
		$_post     = give_clean( $_POST );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
419
		$notice_id = esc_attr( $_post['notice_id'] );
420
421
		// Bailout.
422
		if (
423
			empty( $notice_id ) ||
424
			empty( $_post['dismissible_type'] ) ||
425
			empty( $_post['dismiss_interval'] ) ||
426
			! check_ajax_referer( "give_edit_{$notice_id}_notice", '_wpnonce' )
427
		) {
428
			wp_send_json_error();
429
		}
430
431
		$notice_key = Give()->notices->get_notice_key( $notice_id, $_post['dismiss_interval'] );
432 View Code Duplication
		if ( 'user' === $_post['dismissible_type'] ) {
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...
433
			$current_user = wp_get_current_user();
434
			$notice_key   = Give()->notices->get_notice_key( $notice_id, $_post['dismiss_interval'], $current_user->ID );
435
		}
436
437
		$notice_dismiss_time = ! empty( $_post['dismiss_interval_time'] ) ? $_post['dismiss_interval_time'] : null;
438
439
		// Save option to hide notice.
440
		Give_Cache::set( $notice_key, true, $notice_dismiss_time, true );
441
442
		/**
443
		 * Fire the action when notice dismissed
444
		 *
445
		 * @since 2.2.0
446
		 */
447
		do_action( 'give_notice_dismissed', $_post );
448
449
		wp_send_json_success();
450
	}
451
452
453
	/**
454
	 * Get notice key.
455
	 *
456
	 * @since  1.8.9
457
	 * @access public
458
	 *
459
	 * @param string $notice_id
460
	 * @param string $dismiss_interval
461
	 * @param int    $user_id
462
	 *
463
	 * @return string
464
	 */
465
	public function get_notice_key( $notice_id, $dismiss_interval = null, $user_id = 0 ) {
466
		$notice_key = "_give_notice_{$notice_id}";
467
468
		if ( ! empty( $dismiss_interval ) ) {
469
			$notice_key .= "_{$dismiss_interval}";
470
		}
471
472
		if ( $user_id ) {
473
			$notice_key .= "_{$user_id}";
474
		}
475
476
		$notice_key = sanitize_key( $notice_key );
477
478
		return $notice_key;
479
	}
480
481
482
	/**
483
	 * Get notice dismiss link.
484
	 *
485
	 * @param $notice_args
486
	 *
487
	 * @return string
488
	 */
489
	public function get_dismiss_link( $notice_args ) {
490
		$notice_args = wp_parse_args(
491
			$notice_args,
492
			array(
493
				'title'                 => __( 'Click here', 'give' ),
494
				'dismissible_type'      => '',
495
				'dismiss_interval'      => '',
496
				'dismiss_interval_time' => null,
497
			)
498
		);
499
500
		return sprintf(
501
			'<a href="#" class="give_dismiss_notice" data-dismissible-type="%1$s" data-dismiss-interval="%2$s" data-dismiss-interval-time="%3$s">%4$s</a>',
502
			$notice_args['dismissible_type'],
503
			$notice_args['dismiss_interval'],
504
			$notice_args['dismiss_interval_time'],
505
			$notice_args['title']
506
		);
507
	}
508
509
510
	/**
511
	 * Check if notice dismissed or not
512
	 *
513
	 * @since  1.8.9
514
	 * @access public
515
	 *
516
	 * @param array $notice
517
	 *
518
	 * @return bool|null
519
	 */
520
	public function is_notice_dismissed( $notice ) {
521
		$notice_key          = $this->get_notice_key( $notice['id'], $notice['dismiss_interval'] );
522
		$is_notice_dismissed = false;
0 ignored issues
show
$is_notice_dismissed is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
523
524 View Code Duplication
		if ( 'user' === $notice['dismissible_type'] ) {
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...
525
			$current_user = wp_get_current_user();
526
			$notice_key   = Give()->notices->get_notice_key( $notice['id'], $notice['dismiss_interval'], $current_user->ID );
527
		}
528
529
		$notice_data = Give_Cache::get( $notice_key, true );
530
531
		// Find notice dismiss link status if notice has extra dismissible links.
532
		if ( ( empty( $notice_data ) || is_wp_error( $notice_data ) ) && ! empty( $notice['extra_links'] ) ) {
533
534
			foreach ( $notice['extra_links'] as $extra_link ) {
535
				$new_notice_data = wp_parse_args( $extra_link, $notice );
536
				unset( $new_notice_data['extra_links'] );
537
538
				if ( $is_notice_dismissed = $this->is_notice_dismissed( $new_notice_data ) ) {
539
					return $is_notice_dismissed;
540
				}
541
			}
542
		}
543
544
		$is_notice_dismissed = ! empty( $notice_data ) && ! is_wp_error( $notice_data );
545
546
		return $is_notice_dismissed;
547
	}
548
549
550
	/**
551
	 * Print frontend errors.
552
	 *
553
	 * @since  1.8.9
554
	 * @access public
555
	 *
556
	 * @param array $errors
557
	 */
558
	public static function print_frontend_errors( $errors ) {
559
		// Bailout.
560
		if ( ! $errors ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $errors 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...
561
			return;
562
		}
563
564
		/**
565
		 * Change auto_dismissible to dismissible and set the value to true
566
		 *
567
		 * @since 1.8.14
568
		 */
569
		$default_notice_args = array(
570
			'dismissible'      => true,
571
			'dismiss_interval' => 5000,
572
		);
573
574
		// Note: we will remove give_errors class in future.
575
		$classes = apply_filters( 'give_error_class', array( 'give_notices', 'give_errors' ) );
576
577
		echo sprintf( '<div class="%s">', implode( ' ', $classes ) );
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
578
579
		// Loop error codes and display errors.
580
		foreach ( $errors as $error_id => $error ) {
581
			// Backward compatibility v<1.8.11
582
			if ( is_string( $error ) ) {
583
				$error = array(
584
					'message'     => $error,
585
					'notice_args' => array(),
586
				);
587
			}
588
589
			$notice_args = wp_parse_args( $error['notice_args'], $default_notice_args );
590
591
			/**
592
			 * Filter to modify Frontend Errors args before errors is display.
593
			 *
594
			 * @since 1.8.14
595
			 */
596
			$notice_args = apply_filters( 'give_frontend_errors_args', $notice_args );
597
598
			echo sprintf(
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
599
				'<div class="give_error give_notice" id="give_error_%1$s" data-dismissible="%2$s" data-dismiss-interval="%3$d">
600
						<p><strong>%4$s</strong>: %5$s</p>
601
					</div>',
602
				$error_id,
603
				give_clean( $notice_args['dismissible'] ),
604
				absint( $notice_args['dismiss_interval'] ),
605
				esc_html__( 'Error', 'give' ),
606
				$error['message']
607
			);
608
		}
609
610
		echo '</div>';
611
	}
612
613
	/**
614
	 * Print frontend notice.
615
	 * Notice: notice type can be success/error/warning
616
	 *
617
	 * @since  1.8.9
618
	 * @access public
619
	 *
620
	 * @param string $message
621
	 * @param bool   $echo
622
	 * @param string $notice_type
623
	 * @param array  $notice_args
624
	 *
625
	 * @return  string
626
	 */
627
	public static function print_frontend_notice( $message, $echo = true, $notice_type = 'warning', $notice_args = array() ) {
628
		if ( empty( $message ) ) {
629
			return '';
630
		}
631
632
		/**
633
		 * Change auto_dismissible to dismissible and set the value to true
634
		 *
635
		 * @since 1.8.14
636
		 */
637
		$default_notice_args = array(
638
			'dismissible'      => false,
639
			'dismiss_type'     => 'auto',
640
			'dismiss_interval' => 5000,
641
		);
642
643
		$notice_args = wp_parse_args( $notice_args, $default_notice_args );
644
645
		// Notice dismissible must be true for dismiss type.
646
		$notice_args['dismiss_type'] = ! $notice_args['dismissible'] ? '' : $notice_args['dismiss_type'];
647
648
		/**
649
		 * Filter to modify Frontend notice args before notices is display.
650
		 *
651
		 * @since 1.8.14
652
		 */
653
		$notice_args = apply_filters( 'give_frontend_notice_args', $notice_args );
654
655
		$close_icon = 'manual' === $notice_args['dismiss_type'] ?
656
			sprintf(
657
				'<img class="notice-dismiss give-notice-close" src="%s" />',
658
				esc_url( GIVE_PLUGIN_URL . 'assets/dist/images/close.svg' )
659
0 ignored issues
show
There should be no empty lines in a multi-line function call.
Loading history...
660
			) :
661
			'';
662
663
		// Note: we will remove give_errors class in future.
664
		$error = sprintf(
665
			'<div class="give_notices give_errors" id="give_error_%1$s">
666
						<p class="give_notice give_%1$s" data-dismissible="%2$s" data-dismiss-interval="%3$d" data-dismiss-type="%4$s">
667
							%5$s
668
						</p>
669
						%6$s
670
					</div>',
671
			$notice_type,
672
			give_clean( $notice_args['dismissible'] ),
673
			absint( $notice_args['dismiss_interval'] ),
674
			give_clean( $notice_args['dismiss_type'] ),
675
			$message,
676
			$close_icon
677
0 ignored issues
show
There should be no empty lines in a multi-line function call.
Loading history...
678
		);
679
680
		if ( ! $echo ) {
681
			return $error;
682
		}
683
684
		echo $error;
0 ignored issues
show
Expected next thing to be a escaping function, not '$error'
Loading history...
685
	}
686
687
	/**
688
	 * Print Inline Notice.
689
	 * Note: dismissible feature will note work if notice will add to dom by javascript after document load.
690
	 *
691
	 * @param array $notice_args An array of notice arguments.
692
	 *
693
	 * @todo   Implement render_admin_notices function within this function in future.
694
	 *
695
	 * @access public
696
	 * @since  1.8.17
697
	 *
698
	 * @return string
699
	 */
700
	public function print_admin_notices( $notice_args = array() ) {
701
		// Bailout.
702
		if ( empty( $notice_args['description'] ) ) {
703
			return '';
704
		}
705
706
		$defaults    = array(
707
			'id'          => '',
708
			'echo'        => true,
709
			'notice_type' => 'warning',
710
			'dismissible' => true,
711
		);
712
		$notice_args = wp_parse_args( $notice_args, $defaults );
713
714
		$output    = '';
715
		$css_id    = ! empty( $notice_args['id'] ) ? $notice_args['id'] : uniqid( 'give-inline-notice-' );
716
		$css_class = "notice-{$notice_args['notice_type']} give-notice notice inline";
717
		$css_class .= ( $notice_args['dismissible'] ) ? ' is-dismissible' : '';
718
		$output    .= sprintf(
719
			'<div id="%1$s" class="%2$s"><p>%3$s</p></div>',
720
			$css_id,
721
			$css_class,
722
			$notice_args['description']
723
		);
724
725
		if ( ! $notice_args['echo'] ) {
726
			return $output;
727
		}
728
729
		echo $output;
0 ignored issues
show
Expected next thing to be a escaping function, not '$output'
Loading history...
730
	}
731
}
732