Give_Notices::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0
1
<?php
2
/**
3
 * Admin Notices Class.
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Notices
7
 * @copyright   Copyright (c) 2016, GiveWP
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( 'admin_footer', array( $this, '__reveal_notices' ) );
58
		add_action( 'give_dismiss_notices', array( $this, 'dismiss_notices' ) );
59
60
		add_action( 'give_frontend_notices', array( $this, 'render_frontend_notices' ), 999 );
61
		add_action( 'give_pre_form_output', array( $this, 'render_frontend_form_notices' ), 10, 1 );
62
		add_action( 'give_ajax_donation_errors', array( $this, 'render_frontend_notices' ) );
63
64
		/**
65
		 * Backward compatibility for deprecated params.
66
		 *
67
		 * @since 1.8.14
68
		 */
69
		add_filter( 'give_register_notice_args', array( $this, 'bc_deprecated_params' ) );
70
		add_filter( 'give_frontend_errors_args', array( $this, 'bc_deprecated_params' ) );
71
		add_filter( 'give_frontend_notice_args', array( $this, 'bc_deprecated_params' ) );
72
	}
73
74
	/**
75
	 * Add backward compatibility to deprecated params.
76
	 *
77
	 * @since  1.8.14
78
	 * @access public
79
	 *
80
	 * @param array $args Array of notice params
81
	 *
82
	 * @return array
83
	 */
84
	public function bc_deprecated_params( $args ) {
85
		/**
86
		 *  Param: auto_dismissible
87
		 *  deprecated in 1.8.14
88
		 *
89
		 *  Check if auto_dismissible is set and it true then unset and change dismissible parameter value to auto
90
		 */
91
		if ( isset( $args['auto_dismissible'] ) ) {
92
			if ( ! empty( $args['auto_dismissible'] ) ) {
93
				$args['dismissible'] = 'auto';
94
			}
95
			// unset auto_dismissible as it has been deprecated.
96
			unset( $args['auto_dismissible'] );
97
		}
98
99
		return $args;
100
	}
101
102
	/**
103
	 * Register notice.
104
	 *
105
	 * @since  1.8.9
106
	 * @access public
107
	 *
108
	 * @param $notice_args
109
	 *
110
	 * @return bool
111
	 */
112
	public function register_notice( $notice_args ) {
113
		// Bailout.
114
		if ( empty( $notice_args['id'] ) || array_key_exists( $notice_args['id'], self::$notices ) ) {
115
			return false;
116
		}
117
118
		$notice_args = wp_parse_args(
119
			$notice_args,
120
			array(
121
				'id'                    => '',
122
				'description'           => '',
123
124
				/*
125
				 * Add custom notice html
126
				 * Note: This param has more priority then description, so if you have  both param then this one will be use
127
				 *       for generating notice html. Most of feature of notice attach to core generated html, so if you set
128
				 *       custom html then please add required classes and data attribute which help to apply feature on notice.
129
				 *
130
				 * @since 1.8.16
131
				 */
132
				'description_html'      => '',
133
134
				/*
135
				 * Add New Parameter and remove the auto_dismissible parameter.
136
				 * Value: auto/true/false
137
				 *
138
				 * @since 1.8.14
139
				 */
140
				'dismissible'           => true,
141
142
				// Value: error/warning/success/info/updated
143
				'type'                  => 'error',
144
145
				// Value: null/user/all
146
				'dismissible_type'      => null,
147
148
				// Value: shortly/permanent/null/custom
149
				'dismiss_interval'      => null,
150
151
				// Only set it when custom is defined.
152
				'dismiss_interval_time' => null,
153
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
154
155
			)
156
		);
157
158
		/**
159
		 * Filter to modify Notice args before it get add
160
		 *
161
		 * @since 1.8.14
162
		 */
163
		$notice_args = apply_filters( 'give_register_notice_args', $notice_args );
164
165
		// Set extra dismiss links if any.
166
		if ( false !== strpos( $notice_args['description'], 'data-dismiss-interval' ) ) {
167
168
			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...
169
170
			if ( ! empty( $extra_notice_dismiss_link ) ) {
171
				$extra_notice_dismiss_links = array_chunk( current( $extra_notice_dismiss_link ), 3 );
172
				foreach ( $extra_notice_dismiss_links as $extra_notice_dismiss_link ) {
173
					// Create array og key ==> value by parsing query string created after renaming data attributes.
174
					$data_attribute_query_str = str_replace( array( 'data-', '-', '"' ), array(
175
						'',
176
						'_',
177
						'',
178
					), implode( '&', $extra_notice_dismiss_link ) );
179
180
					$notice_args['extra_links'][] = wp_parse_args( $data_attribute_query_str );
181
				}
182
			}
183
		}
184
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
185
186
		self::$notices[ $notice_args['id'] ] = $notice_args;
187
188
		// Auto set show param if not already set.
189
		if ( ! isset( self::$notices[ $notice_args['id'] ]['show'] ) ) {
190
			self::$notices[ $notice_args['id'] ]['show'] = $this->is_notice_dismissed( $notice_args ) ? false : true;
191
		}
192
193
		// Auto set time interval for shortly.
194
		if ( 'shortly' === self::$notices[ $notice_args['id'] ]['dismiss_interval'] ) {
195
			self::$notices[ $notice_args['id'] ]['dismiss_interval_time'] = DAY_IN_SECONDS;
196
		}
197
198
		return true;
199
	}
200
201
	/**
202
	 * Display notice.
203
	 *
204
	 * @since 1.8.9
205
	 *
206
	 */
207
	public function render_admin_notices() {
208
		/* @var WP_Screen $wp_screen */
209
		$wp_screen = get_current_screen();
210
211
		// Bailout.
212
		if ( empty( self::$notices ) ) {
213
			return;
214
		}
215
216
		// Do not render notice on Gutenberg editor page.
217
		if (
218
			method_exists( $wp_screen, 'is_block_editor' )
219
			&& $wp_screen->is_block_editor()
220
		) {
221
			return;
222
		}
223
224
		$output = '';
225
226
		foreach ( self::$notices as $notice_id => $notice ) {
227
			// Check flag set to true to show notice.
228
			if ( ! $notice['show'] ) {
229
				continue;
230
			}
231
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
232
233
			// Render custom html.
234
			if( ! empty( $notice['description_html'] ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
235
				$output .= "{$notice['description_html']} \n";
236
				continue;
237
			}
238
239
			// Check if notice dismissible or not.
240
			if ( ! self::$has_auto_dismissible_notice ) {
241
				self::$has_auto_dismissible_notice = ( 'auto' === $notice['dismissible'] );
242
			}
243
244
			// Check if notice dismissible or not.
245
			if ( ! self::$has_dismiss_interval_notice ) {
246
				self::$has_dismiss_interval_notice = $notice['dismiss_interval'];
247
			}
248
249
			$css_id = ( false === strpos( $notice['id'], 'give' ) ? "give-{$notice['id']}" : $notice['id'] );
250
251
			$css_class = 'give-notice notice ' . ( empty( $notice['dismissible'] ) ? 'non' : 'is' ) . "-dismissible {$notice['type']} notice-{$notice['type']}";
252
			$output    .= sprintf(
253
				'<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",
254
				$css_id,
255
				$css_class,
256
				give_clean( $notice['dismissible'] ),
257
				$notice['dismissible_type'],
258
				$notice['dismiss_interval'],
259
				$notice['id'],
260
				empty( $notice['dismissible_type'] ) ? '' : wp_create_nonce( "give_edit_{$notice_id}_notice" ),
261
				$notice['dismiss_interval_time']
262
			);
263
264
			$output .= ( 0 === strpos( $notice['description'], '<div' ) || 0 === strpos( $notice['description'], '<p' ) ? $notice['description'] : "<p>{$notice['description']}</p>" );
265
			$output .= "</div> \n";
266
		}
267
268
		echo $output;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$output'
Loading history...
269
270
		$this->print_js();
271
	}
272
273
274
	/**
275
	 * Render give frontend notices.
276
	 *
277
	 * @since  1.8.9
278
	 * @access public
279
	 *
280
	 * @param int $form_id
281
	 */
282
	public function render_frontend_notices( $form_id = 0 ) {
283
		$errors = give_get_errors();
284
285
		$request_form_id = isset( $_REQUEST['form-id'] ) ? absint( $_REQUEST['form-id'] ) : 0;
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
286
287
		// Sanity checks first: Ensure that gateway returned errors display on the appropriate form.
288
		if ( ! isset( $_POST['give_ajax'] ) && $request_form_id !== $form_id ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
289
			return;
290
		}
291
292
		if ( $errors ) {
293
			self::print_frontend_errors( $errors );
0 ignored issues
show
Bug introduced by
It seems like $errors defined by give_get_errors() on line 283 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...
294
295
			give_clear_errors();
296
		}
297
	}
298
299
	/**
300
	 * Renders notices for different actions depending on
301
	 * the type of form display option.
302
	 *
303
	 * @since 2.2
304
	 * @access public
305
	 *
306
	 * @param int $form_id Form ID.
307
	 *
308
	 * @return void
309
	 */
310
	public function render_frontend_form_notices( $form_id ) {
311
		$display_option = give_get_meta( $form_id, '_give_payment_display', true );
312
313
		if ( 'modal' === $display_option ) {
314
			add_action( 'give_payment_mode_top', array( $this, 'render_frontend_notices' ) );
315
		} else {
316
			add_action( 'give_pre_form', array( $this, 'render_frontend_notices' ), 11 );
317
		}
318
	}
319
320
	/**
321
	 * Print notice js.
322
	 *
323
	 * @since  1.8.9
324
	 * @access private
325
	 */
326
	private function print_js() {
327
		if ( self::$has_auto_dismissible_notice ) :
328
			?>
329
			<script>
330
				jQuery(document).ready(function () {
331
					// auto hide setting message in 5 seconds.
332
					window.setTimeout(
333
						function () {
334
							jQuery('.give-notice[data-dismissible="auto"]').slideUp();
335
						},
336
						5000
337
					);
338
				})
339
			</script>
340
			<?php
341
		endif;
342
343
		if ( self::$has_dismiss_interval_notice ) :
344
			?>
345
			<script>
346
				jQuery(document).ready(function () {
347
					var $body = jQuery('body');
348
349
					$body.on('click', '.give_dismiss_notice', function (e) {
350
						var $parent            = jQuery(this).parents('.give-notice'),
351
							custom_notice_data = {
352
								'dismissible_type': jQuery(this).data('dismissible-type'),
353
								'dismiss_interval': jQuery(this).data('dismiss-interval'),
354
								'dismiss_interval_time': jQuery(this).data('dismiss-interval-time')
355
							};
356
357
						$parent.find('button.notice-dismiss').trigger('click', [custom_notice_data]);
358
						return false;
359
					});
360
361
					$body.on('click', 'button.notice-dismiss', function (e, custom_notice_data) {
362
						var $parent            = jQuery(this).parents('.give-notice'),
363
							custom_notice_data = custom_notice_data || {};
364
365
						e.preventDefault();
366
367
						var data = {
368
							'give-action': 'dismiss_notices',
369
							'notice_id': $parent.data('notice-id'),
370
							'dismissible_type': $parent.data('dismissible-type'),
371
							'dismiss_interval': $parent.data('dismiss-interval'),
372
							'dismiss_interval_time': $parent.data('dismiss-interval-time'),
373
							'_wpnonce': $parent.data('security')
374
						};
375
376
						if (Object.keys(custom_notice_data).length) {
377
							jQuery.extend(data, custom_notice_data);
378
						}
379
380
						// Bailout.
381
						if (
382
							!data.dismiss_interval ||
383
							!data.dismissible_type
384
						) {
385
							return false;
386
						}
387
388
						jQuery.post(
389
							'<?php echo admin_url(); ?>admin-ajax.php',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'admin_url'
Loading history...
390
							data,
391
							function (response) {
392
393
							})
394
					})
395
				});
396
			</script>
397
			<?php
398
		endif;
399
	}
400
401
	/**
402
	 * Show notices
403
	 * Note: only for internal use
404
	 *
405
	 * @since 2.3.0
406
	 */
407
	public function __reveal_notices(){
0 ignored issues
show
Coding Style introduced by
Method name "Give_Notices::__reveal_notices" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
408
		?>
409
		<script>
410
			jQuery(document).ready(function($){
411
				// Fix notice appearance issue.
412
				window.setTimeout(
413
					function(){
414
						var give_notices = $('.give-notice');
415
416
						if( give_notices.length ) {
417
							give_notices.slideDown();
418
						}
419
					},
420
					1000
421
				);
422
			});
423
		</script>
424
		<?php
425
	}
426
427
428
	/**
429
	 * Hide notice.
430
	 *
431
	 * @since  1.8.9
432
	 * @access public
433
	 */
434
	public function dismiss_notices() {
435
		$_post     = give_clean( $_POST );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
436
		$notice_id = esc_attr( $_post['notice_id'] );
437
438
		// Bailout.
439
		if (
440
			empty( $notice_id ) ||
441
			empty( $_post['dismissible_type'] ) ||
442
			empty( $_post['dismiss_interval'] ) ||
443
			! check_ajax_referer( "give_edit_{$notice_id}_notice", '_wpnonce' )
444
		) {
445
			wp_send_json_error();
446
		}
447
448
		$notice_key = Give()->notices->get_notice_key( $notice_id, $_post['dismiss_interval'] );
449 View Code Duplication
		if ( 'user' === $_post['dismissible_type'] ) {
0 ignored issues
show
Duplication introduced by
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...
450
			$current_user = wp_get_current_user();
451
			$notice_key   = Give()->notices->get_notice_key( $notice_id, $_post['dismiss_interval'], $current_user->ID );
452
		}
453
454
		$notice_dismiss_time = ! empty( $_post['dismiss_interval_time'] ) ? $_post['dismiss_interval_time'] : null;
455
456
		// Save option to hide notice.
457
		Give_Cache::set( $notice_key, true, $notice_dismiss_time, true );
458
459
		/**
460
		 * Fire the action when notice dismissed
461
		 *
462
		 * @since 2.2.0
463
		 */
464
		do_action( 'give_notice_dismissed', $_post );
465
466
		wp_send_json_success();
467
	}
468
469
470
	/**
471
	 * Get notice key.
472
	 *
473
	 * @since  1.8.9
474
	 * @access public
475
	 *
476
	 * @param string $notice_id
477
	 * @param string $dismiss_interval
478
	 * @param int    $user_id
479
	 *
480
	 * @return string
481
	 */
482
	public function get_notice_key( $notice_id, $dismiss_interval = null, $user_id = 0 ) {
483
		$notice_key = "_give_notice_{$notice_id}";
484
485
		if ( ! empty( $dismiss_interval ) ) {
486
			$notice_key .= "_{$dismiss_interval}";
487
		}
488
489
		if ( $user_id ) {
490
			$notice_key .= "_{$user_id}";
491
		}
492
493
		$notice_key = sanitize_key( $notice_key );
494
495
		return $notice_key;
496
	}
497
498
499
	/**
500
	 * Get notice dismiss link.
501
	 *
502
	 * @param $notice_args
503
	 *
504
	 * @return string
505
	 */
506
	public function get_dismiss_link( $notice_args ) {
507
		$notice_args = wp_parse_args(
508
			$notice_args,
509
			array(
510
				'title'                 => __( 'Click here', 'give' ),
511
				'dismissible_type'      => '',
512
				'dismiss_interval'      => '',
513
				'dismiss_interval_time' => null,
514
			)
515
		);
516
517
		return sprintf(
518
			'<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>',
519
			$notice_args['dismissible_type'],
520
			$notice_args['dismiss_interval'],
521
			$notice_args['dismiss_interval_time'],
522
			$notice_args['title']
523
		);
524
	}
525
526
527
	/**
528
	 * Check if notice dismissed or not
529
	 *
530
	 * @since  1.8.9
531
	 * @access public
532
	 *
533
	 * @param array $notice
534
	 *
535
	 * @return bool|null
536
	 */
537
	public function is_notice_dismissed( $notice ) {
538
		$notice_key          = $this->get_notice_key( $notice['id'], $notice['dismiss_interval'] );
539
		$is_notice_dismissed = false;
0 ignored issues
show
Unused Code introduced by
$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...
540
541 View Code Duplication
		if ( 'user' === $notice['dismissible_type'] ) {
0 ignored issues
show
Duplication introduced by
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...
542
			$current_user = wp_get_current_user();
543
			$notice_key   = Give()->notices->get_notice_key( $notice['id'], $notice['dismiss_interval'], $current_user->ID );
544
		}
545
546
		$notice_data = Give_Cache::get( $notice_key, true );
547
548
		// Find notice dismiss link status if notice has extra dismissible links.
549
		if ( ( empty( $notice_data ) || is_wp_error( $notice_data ) ) && ! empty( $notice['extra_links'] ) ) {
550
551
			foreach ( $notice['extra_links'] as $extra_link ) {
552
				$new_notice_data = wp_parse_args( $extra_link, $notice );
553
				unset( $new_notice_data['extra_links'] );
554
555
				if ( $is_notice_dismissed = $this->is_notice_dismissed( $new_notice_data ) ) {
556
					return $is_notice_dismissed;
557
				}
558
			}
559
		}
560
561
		$is_notice_dismissed = ! empty( $notice_data ) && ! is_wp_error( $notice_data );
562
563
		return $is_notice_dismissed;
564
	}
565
566
567
	/**
568
	 * Print frontend errors.
569
	 *
570
	 * @since  1.8.9
571
	 * @access public
572
	 *
573
	 * @param array $errors
574
	 */
575
	public static function print_frontend_errors( $errors ) {
576
		// Bailout.
577
		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...
578
			return;
579
		}
580
581
		/**
582
		 * Change auto_dismissible to dismissible and set the value to true
583
		 *
584
		 * @since 1.8.14
585
		 */
586
		$default_notice_args = array(
587
			'dismissible'      => true,
588
			'dismiss_interval' => 5000,
589
		);
590
591
		// Note: we will remove give_errors class in future.
592
		$classes = apply_filters( 'give_error_class', array( 'give_notices', 'give_errors' ) );
593
594
		echo sprintf( '<div class="%s">', implode( ' ', $classes ) );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
595
596
		// Loop error codes and display errors.
597
		foreach ( $errors as $error_id => $error ) {
598
			// Backward compatibility v<1.8.11
599
			if ( is_string( $error ) ) {
600
				$error = array(
601
					'message'     => $error,
602
					'notice_args' => array(),
603
				);
604
			}
605
606
			$notice_args = wp_parse_args( $error['notice_args'], $default_notice_args );
607
608
			/**
609
			 * Filter to modify Frontend Errors args before errors is display.
610
			 *
611
			 * @since 1.8.14
612
			 */
613
			$notice_args = apply_filters( 'give_frontend_errors_args', $notice_args );
614
615
			echo sprintf(
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
616
				'<div class="give_error give_notice" id="give_error_%1$s" data-dismissible="%2$s" data-dismiss-interval="%3$d">
617
						<p><strong>%4$s</strong>: %5$s</p>
618
					</div>',
619
				$error_id,
620
				give_clean( $notice_args['dismissible'] ),
621
				absint( $notice_args['dismiss_interval'] ),
622
				esc_html__( 'Error', 'give' ),
623
				$error['message']
624
			);
625
		}
626
627
		echo '</div>';
628
	}
629
630
	/**
631
	 * Print frontend notice.
632
	 * Notice: notice type can be success/error/warning
633
	 *
634
	 * @since  1.8.9
635
	 * @access public
636
	 *
637
	 * @param string $message
638
	 * @param bool   $echo
639
	 * @param string $notice_type
640
	 * @param array  $notice_args
641
	 *
642
	 * @return  string
643
	 */
644
	public static function print_frontend_notice( $message, $echo = true, $notice_type = 'warning', $notice_args = array() ) {
645
		if ( empty( $message ) ) {
646
			return '';
647
		}
648
649
		/**
650
		 * Change auto_dismissible to dismissible and set the value to true
651
		 *
652
		 * @since 1.8.14
653
		 */
654
		$default_notice_args = array(
655
			'dismissible'      => false,
656
			'dismiss_type'     => 'auto',
657
			'dismiss_interval' => 5000,
658
		);
659
660
		$notice_args = wp_parse_args( $notice_args, $default_notice_args );
661
662
		// Notice dismissible must be true for dismiss type.
663
		$notice_args['dismiss_type'] = ! $notice_args['dismissible'] ? '' : $notice_args['dismiss_type'];
664
665
		/**
666
		 * Filter to modify Frontend notice args before notices is display.
667
		 *
668
		 * @since 1.8.14
669
		 */
670
		$notice_args = apply_filters( 'give_frontend_notice_args', $notice_args );
671
672
		$close_icon = 'manual' === $notice_args['dismiss_type'] ?
673
			sprintf(
674
				'<img class="notice-dismiss give-notice-close" src="%s" />',
675
				esc_url( GIVE_PLUGIN_URL . 'assets/dist/images/close.svg' )
676
0 ignored issues
show
Coding Style introduced by
There should be no empty lines in a multi-line function call.
Loading history...
677
			) :
678
			'';
679
680
		// Note: we will remove give_errors class in future.
681
		$error = sprintf(
682
			'<div class="give_notices give_errors" id="give_error_%1$s">
683
						<p class="give_notice give_%1$s" data-dismissible="%2$s" data-dismiss-interval="%3$d" data-dismiss-type="%4$s">
684
							%5$s
685
						</p>
686
						%6$s
687
					</div>',
688
			$notice_type,
689
			give_clean( $notice_args['dismissible'] ),
690
			absint( $notice_args['dismiss_interval'] ),
691
			give_clean( $notice_args['dismiss_type'] ),
692
			$message,
693
			$close_icon
694
0 ignored issues
show
Coding Style introduced by
There should be no empty lines in a multi-line function call.
Loading history...
695
		);
696
697
		if ( ! $echo ) {
698
			return $error;
699
		}
700
701
		echo $error;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$error'
Loading history...
702
	}
703
704
	/**
705
	 * Print Inline Notice.
706
	 * Note: dismissible feature will note work if notice will add to dom by javascript after document load.
707
	 *
708
	 * @param array $notice_args An array of notice arguments.
709
	 *
710
	 * @todo   Implement render_admin_notices function within this function in future.
711
	 *
712
	 * @access public
713
	 * @since  1.8.17
714
	 *
715
	 * @return string
716
	 */
717
	public function print_admin_notices( $notice_args = array() ) {
718
		// Bailout.
719
		if ( empty( $notice_args['description'] ) ) {
720
			return '';
721
		}
722
723
		$defaults    = array(
724
			'id'          => '',
725
			'echo'        => true,
726
			'notice_type' => 'warning',
727
			'dismissible' => true,
728
		);
729
		$notice_args = wp_parse_args( $notice_args, $defaults );
730
731
		$output    = '';
732
		$css_id    = ! empty( $notice_args['id'] ) ? $notice_args['id'] : uniqid( 'give-inline-notice-' );
733
		$css_class = "notice-{$notice_args['notice_type']} give-notice notice inline";
734
		$css_class .= ( $notice_args['dismissible'] ) ? ' is-dismissible' : '';
735
		$output    .= sprintf(
736
			'<div id="%1$s" class="%2$s"><p>%3$s</p></div>',
737
			$css_id,
738
			$css_class,
739
			$notice_args['description']
740
		);
741
742
		if ( ! $notice_args['echo'] ) {
743
			return $output;
744
		}
745
746
		echo $output;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$output'
Loading history...
747
	}
748
}
749