shortcodes.php ➔ give_process_profile_editor_updates()   F
last analyzed

Complexity

Conditions 34
Paths > 20000

Size

Total Lines 165

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 34
nc 11796482
nop 1
dl 0
loc 165
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Give Shortcodes
4
 *
5
 * @package     Give
6
 * @subpackage  Shortcodes
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
 * Donation History Shortcode
19
 *
20
 * Displays a user's donation history.
21
 *
22
 * @since  1.0
23
 *
24
 * @param array       $atts
25
 * @param string|bool $content
26
 *
27
 * @return string|bool
28
 */
29
function give_donation_history( $atts, $content = false ) {
30
31
	$donation_history_args = shortcode_atts( array(
32
		'id'             => true,
33
		'date'           => true,
34
		'donor'          => false,
35
		'amount'         => true,
36
		'status'         => false,
37
		'payment_method' => false,
38
	), $atts, 'donation_history' );
39
40
	// Always show receipt link.
41
	$donation_history_args['details'] = true;
42
43
	// Set Donation History Shortcode Arguments in session variable.
44
	Give()->session->set( 'give_donation_history_args', $donation_history_args );
45
	
46
	$get_data = give_clean( filter_input_array( INPUT_GET ) );
47
	
48
	// If payment_key query arg exists, return receipt instead of donation history.
49
	if (
50
        ! empty( $get_data['donation_id'] ) ||
51
        (
52
            ! empty( $get_data['action'] ) &&
53
            'view_in_browser' === $get_data['action']
54
        )
55
    ) {
56
		ob_start();
57
58
		echo give_receipt_shortcode( array( ) );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'give_receipt_shortcode'
Loading history...
introduced by
Empty array declaration must have no space between the parentheses
Loading history...
59
60
		// Display donation history link only if Receipt Access Session is available.
61
		if ( give_get_receipt_session() || is_user_logged_in() ) {
62
			echo sprintf(
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
63
				'<a href="%s">%s</a>',
64
				esc_url( give_get_history_page_uri() ),
65
				__( '&laquo; Return to All Donations', 'give' )
66
			);
67
		}
68
69
		return ob_get_clean();
70
	}
71
72
	$email_access = give_get_option( 'email_access' );
73
74
	ob_start();
75
76
	/**
77
	 * Determine access
78
	 *
79
	 * A. Check if a user is logged in or does a session exists.
80
	 * B. Does an email-access token exist?
81
	 */
82
	if (
83
		is_user_logged_in()
84
		|| false !== Give()->session->get_session_expiration()
85
		|| ( give_is_setting_enabled( $email_access ) && Give()->email_access->token_exists )
86
		|| true === give_get_history_session()
87
	) {
88
		give_get_template_part( 'history', 'donations' );
89
90
		if ( ! empty( $content ) ) {
91
			echo do_shortcode( $content );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'do_shortcode'
Loading history...
92
		}
93
	} elseif ( give_is_setting_enabled( $email_access ) ) {
94
		// Is Email-based access enabled?
95
		give_get_template_part( 'email', 'login-form' );
96
97
	} else {
98
99
		echo apply_filters( 'give_donation_history_nonuser_message', Give()->notices->print_frontend_notice( __( 'You must be logged in to view your donation history. Please login using your account or create an account using the same email you used to donate with.', 'give' ), false ) );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'apply_filters'
Loading history...
100
		echo do_shortcode( '[give_login]' );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'do_shortcode'
Loading history...
101
	}
102
103
	/**
104
	 * Filter to modify donation history HTMl
105
	 *
106
	 * @since 2.1
107
	 *
108
	 * @param string HTML content
109
	 * @param array  $atts
110
	 * @param string $content content pass between enclose content
111
	 *
112
	 * @return string HTML content
113
	 */
114
	return apply_filters( 'give_donation_history_shortcode_html', ob_get_clean(), $atts, $content );
115
}
116
117
add_shortcode( 'donation_history', 'give_donation_history' );
118
119
/**
120
 * Donation Form Shortcode
121
 *
122
 * Show the Give donation form.
123
 *
124
 * @since  1.0
125
 *
126
 * @param  array $atts Shortcode attributes
127
 *
128
 * @return string
129
 */
130
function give_form_shortcode( $atts ) {
131
	$atts = shortcode_atts( give_get_default_form_shortcode_args(), $atts, 'give_form' );
132
133
	// Convert string to bool.
134
	$atts['show_title'] = filter_var( $atts['show_title'], FILTER_VALIDATE_BOOLEAN );
135
	$atts['show_goal']  = filter_var( $atts['show_goal'], FILTER_VALIDATE_BOOLEAN );
136
137
	// Fetch the Give Form.
138
	ob_start();
139
	give_get_donation_form( $atts );
140
	$final_output = ob_get_clean();
141
142
	return apply_filters( 'give_donate_form', $final_output, $atts );
143
}
144
145
add_shortcode( 'give_form', 'give_form_shortcode' );
146
147
/**
148
 * Donation Form Goal Shortcode.
149
 *
150
 * Show the Give donation form goals.
151
 *
152
 * @since  1.0
153
 *
154
 * @param  array $atts Shortcode attributes.
155
 *
156
 * @return string
157
 */
158
function give_goal_shortcode( $atts ) {
159
	$atts = shortcode_atts( array(
160
		'id'        => '',
161
		'show_text' => true,
162
		'show_bar'  => true,
163
	), $atts, 'give_goal' );
164
165
	// get the Give Form.
166
	ob_start();
167
168
	// Sanity check 1: ensure there is an ID Provided.
169
	if ( empty( $atts['id'] ) ) {
170
		Give()->notices->print_frontend_notice( __( 'The shortcode is missing Donation Form ID attribute.', 'give' ), true );
171
	}
172
173
	// Sanity check 2: Check the form even has Goals enabled.
174
	if ( ! give_is_setting_enabled( give_get_meta( $atts['id'], '_give_goal_option', true ) ) ) {
175
176
		Give()->notices->print_frontend_notice( __( 'The form does not have Goals enabled.', 'give' ), true );
177
	} else {
178
		// Passed all sanity checks: output Goal.
179
		give_show_goal_progress( $atts['id'], $atts );
180
	}
181
182
	$final_output = ob_get_clean();
183
184
	return apply_filters( 'give_goal_shortcode_output', $final_output, $atts );
185
}
186
187
add_shortcode( 'give_goal', 'give_goal_shortcode' );
188
189
190
/**
191
 * Login Shortcode.
192
 *
193
 * Shows a login form allowing users to users to log in. This function simply
194
 * calls the give_login_form function to display the login form.
195
 *
196
 * @since  1.0
197
 *
198
 * @param  array $atts Shortcode attributes.
199
 *
200
 * @uses   give_login_form()
201
 *
202
 * @return string
203
 */
204
function give_login_form_shortcode( $atts ) {
205
206
	$atts = shortcode_atts( array(
207
		// Add backward compatibility for redirect attribute.
208
		'redirect'        => '',
209
		'login-redirect'  => '',
210
		'logout-redirect' => '',
211
	), $atts, 'give_login' );
212
213
	// Check login-redirect attribute first, if it empty or not found then check for redirect attribute and add value of this to login-redirect attribute.
214
	$atts['login-redirect'] = ! empty( $atts['login-redirect'] ) ? $atts['login-redirect'] : ( ! empty( $atts['redirect'] ) ? $atts['redirect'] : '' );
215
216
	return give_login_form( $atts['login-redirect'], $atts['logout-redirect'] );
217
}
218
219
add_shortcode( 'give_login', 'give_login_form_shortcode' );
220
221
/**
222
 * Register Shortcode.
223
 *
224
 * Shows a registration form allowing users to users to register for the site.
225
 *
226
 * @since  1.0
227
 *
228
 * @param  array $atts Shortcode attributes.
229
 *
230
 * @uses   give_register_form()
231
 *
232
 * @return string
233
 */
234
function give_register_form_shortcode( $atts ) {
235
	$atts = shortcode_atts( array(
236
		'redirect' => '',
237
	), $atts, 'give_register' );
238
239
	return give_register_form( $atts['redirect'] );
240
}
241
242
add_shortcode( 'give_register', 'give_register_form_shortcode' );
243
244
/**
245
 * Receipt Shortcode.
246
 *
247
 * Shows a donation receipt.
248
 *
249
 * @since  1.0
250
 *
251
 * @param  array $atts Shortcode attributes.
252
 *
253
 * @return string
254
 */
255
function give_receipt_shortcode( $atts ) {
256
257
	global $give_receipt_args;
258
259
	$give_receipt_args = shortcode_atts( array(
260
		'error'          => __( 'You are missing the donation id to view this donation receipt.', 'give' ),
261
		'price'          => true,
262
		'donor'          => true,
263
		'date'           => true,
264
		'payment_method' => true,
265
		'payment_id'     => true,
266
		'payment_status' => false,
267
		'company_name'   => false,
268
		'status_notice'  => true,
269
	), $atts, 'give_receipt' );
270
	
271
	ob_start();
272
	
273
	$donation_id  = false;
274
	$receipt_type = false;
275
	$get_data     = give_clean( filter_input_array( INPUT_GET ) );
276
	$session      = give_get_purchase_session();
277
	
278
	if ( ! empty( $get_data['donation_id'] ) ) {
279
	    $donation_id = $get_data['donation_id'];
280
    } else if ( ! empty( $get_data['action'] ) && 'view_in_browser' === $get_data['action'] ) {
281
		$receipt_type = 'view_in_browser';
282
	    $donation_id  = give_get_donation_id_by_key( $get_data['_give_hash'] );
283
    } else if ( isset( $session['donation_id'] ) ) {
284
		$donation_id = $session['donation_id'];
285
	} else if ( ! empty( $give_receipt_args['id'] ) ) {
286
		$donation_id = $give_receipt_args['id'];
287
	}
288
	
289
	// Display donation receipt placeholder while loading receipt via AJAX.
290
	if ( ! wp_doing_ajax() ) {
291
		give_get_template_part( 'receipt/placeholder' );
292
293
		return sprintf(
294
			'<div id="give-receipt" data-shortcode="%1$s" data-receipt-type="%2$s" data-donation-key="%3$s" >%4$s</div>',
295
            htmlspecialchars( wp_json_encode( $give_receipt_args ) ),
296
			$receipt_type,
297
			$donation_id,
298
			ob_get_clean()
299
		);
300
	}
301
302
	return give_display_donation_receipt( $atts );
303
}
304
305
add_shortcode( 'give_receipt', 'give_receipt_shortcode' );
306
307
/**
308
 * Profile Editor Shortcode.
309
 *
310
 * Outputs the Give Profile Editor to allow users to amend their details from the
311
 * front-end. This function uses the Give templating system allowing users to
312
 * override the default profile editor template. The profile editor template is located
313
 * under templates/profile-editor.php, however, it can be altered by creating a
314
 * file called profile-editor.php in the give_template directory in your active theme's
315
 * folder. Please visit the Give Documentation for more information on how the
316
 * templating system is used.
317
 *
318
 * @since  1.0
319
 *
320
 * @param  array $atts Shortcode attributes.
321
 *
322
 * @return string Output generated from the profile editor
323
 */
324
function give_profile_editor_shortcode( $atts ) {
0 ignored issues
show
Unused Code introduced by
The parameter $atts 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...
325
326
	ob_start();
327
328
	// Restrict access to donor profile, if donor and user are disconnected.
329
	$is_donor_disconnected = get_user_meta( get_current_user_id(), '_give_is_donor_disconnected', true );
0 ignored issues
show
introduced by
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
330
	if ( is_user_logged_in() && $is_donor_disconnected ) {
331
		Give()->notices->print_frontend_notice( __( 'Your Donor and User profile are no longer connected. Please contact the site administrator.', 'give' ), true, 'error' );
332
333
		return false;
334
	}
335
336
	give_get_template_part( 'shortcode', 'profile-editor' );
337
338
	$display = ob_get_clean();
339
340
	return $display;
341
}
342
343
add_shortcode( 'give_profile_editor', 'give_profile_editor_shortcode' );
344
345
/**
346
 * Process Profile Updater Form.
347
 *
348
 * Processes the profile updater form by updating the necessary fields.
349
 *
350
 * @since  1.0
351
 *
352
 * @param  array $data Data sent from the profile editor.
353
 *
354
 * @return bool
355
 */
356
function give_process_profile_editor_updates( $data ) {
357
	// Profile field change request.
358
	if ( empty( $_POST['give_profile_editor_submit'] ) && ! is_user_logged_in() ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
359
		return false;
360
	}
361
362
	// Nonce security.
363
	if ( ! wp_verify_nonce( $data['give_profile_editor_nonce'], 'give-profile-editor-nonce' ) ) {
364
		return false;
365
	}
366
367
	$user_id       = get_current_user_id();
368
	$old_user_data = get_userdata( $user_id );
369
370
	/* @var Give_Donor $donor */
371
	$donor            = new Give_Donor( $user_id, true );
372
	$old_company_name = $donor->get_company_name();
373
374
	$display_name     = isset( $data['give_display_name'] ) ? sanitize_text_field( $data['give_display_name'] ) : $old_user_data->display_name;
375
	$first_name       = isset( $data['give_first_name'] ) ? sanitize_text_field( $data['give_first_name'] ) : $old_user_data->first_name;
376
	$last_name        = isset( $data['give_last_name'] ) ? sanitize_text_field( $data['give_last_name'] ) : $old_user_data->last_name;
377
	$company_name     = ! empty( $data['give_company_name'] ) ? sanitize_text_field( $data['give_company_name'] ) : $old_company_name;
378
	$email            = isset( $data['give_email'] ) ? sanitize_email( $data['give_email'] ) : $old_user_data->user_email;
379
	$password         = ! empty( $data['give_new_user_pass1'] ) ? $data['give_new_user_pass1'] : '';
380
	$confirm_password = ! empty( $data['give_new_user_pass2'] ) ? $data['give_new_user_pass2'] : '';
381
382
	$userdata = array(
383
		'ID'           => $user_id,
384
		'first_name'   => $first_name,
385
		'last_name'    => $last_name,
386
		'display_name' => $display_name,
387
		'user_email'   => $email,
388
		'user_pass'    => $password,
389
		'company_name' => $company_name,
390
	);
391
392
	/**
393
	 * Fires before updating user profile.
394
	 *
395
	 * @since 1.0
396
	 *
397
	 * @param int   $user_id  The ID of the user.
398
	 * @param array $userdata User info, including ID, first name, last name, display name and email.
399
	 */
400
	do_action( 'give_pre_update_user_profile', $user_id, $userdata );
401
402
	// Make sure to validate first name of existing donors.
403
	if ( empty( $first_name ) ) {
404
		// Empty First Name.
405
		give_set_error( 'empty_first_name', __( 'Please enter your first name.', 'give' ) );
406
	}
407
408
	// Make sure to validate passwords for existing Donors.
409
	give_validate_user_password( $password, $confirm_password );
410
411
	if ( empty( $email ) ) {
412
		// Make sure email should not be empty.
413
		give_set_error( 'email_empty', __( 'The email you entered is empty.', 'give' ) );
414
415
	} elseif ( ! is_email( $email ) ) {
416
		// Make sure email should be valid.
417
		give_set_error( 'email_not_valid', __( 'The email you entered is not valid. Please use another', 'give' ) );
418
419
	} elseif ( $email !== $old_user_data->user_email ) {
420
		// Make sure the new email doesn't belong to another user.
421
		if ( email_exists( $email ) ) {
422
			give_set_error( 'user_email_exists', __( 'The email you entered belongs to another user. Please use another.', 'give' ) );
423
		} elseif ( Give()->donors->get_donor_by( 'email', $email ) ) {
424
			// Make sure the new email doesn't belong to another user.
425
			give_set_error( 'donor_email_exists', __( 'The email you entered belongs to another donor. Please use another.', 'give' ) );
426
		}
427
	}
428
429
	// Check for errors.
430
	$errors = give_get_errors();
431
432
	if ( $errors ) {
433
		// Send back to the profile editor if there are errors.
434
		wp_redirect( $data['give_redirect'] );
435
		give_die();
436
	}
437
438
	// Update Donor First Name and Last Name.
439
	Give()->donors->update( $donor->id, array(
440
		'name' => trim( "{$first_name} {$last_name}" ),
441
	) );
442
	Give()->donor_meta->update_meta( $donor->id, '_give_donor_first_name', $first_name );
443
	Give()->donor_meta->update_meta( $donor->id, '_give_donor_last_name', $last_name );
444
	Give()->donor_meta->update_meta( $donor->id, '_give_donor_company', $company_name );
445
446
	$current_user = wp_get_current_user();
447
448
	// Compares new values with old values to detect change in values.
449
	$email_update        = ( $email !== $current_user->user_email ) ? true : false;
450
	$display_name_update = ( $display_name !== $current_user->display_name ) ? true : false;
451
	$first_name_update   = ( $first_name !== $current_user->first_name ) ? true : false;
452
	$last_name_update    = ( $last_name !== $current_user->last_name ) ? true : false;
453
	$company_name_update = ( $company_name !== $old_company_name ) ? true : false;
454
	$update_code         = 0;
455
456
	/**
457
	 * True if update is done in display name, first name, last name or email.
458
	 *
459
	 * @var boolean
460
	 */
461
	$profile_update = ( $email_update || $display_name_update || $first_name_update || $last_name_update || $company_name_update );
462
463
	/**
464
	 * True if password fields are filled.
465
	 *
466
	 * @var boolean
467
	 */
468
	$password_update = ( ! empty( $password ) && ! empty( $confirm_password ) );
469
470
	if ( $profile_update ) {
471
472
		// If only profile fields are updated.
473
		$update_code = '1';
474
475
		if ( $password_update ) {
476
477
			// If profile fields AND password both are updated.
478
			$update_code = '2';
479
		}
480
	} elseif ( $password_update ) {
481
482
		// If only password is updated.
483
		$update_code = '3';
484
	}
485
486
	// Update the user.
487
	$updated = wp_update_user( $userdata );
488
489
	if ( $updated ) {
490
491
		/**
492
		 * Fires after updating user profile.
493
		 *
494
		 * @since 1.0
495
		 *
496
		 * @param int   $user_id  The ID of the user.
497
		 * @param array $userdata User info, including ID, first name, last name, display name and email.
498
		 */
499
		do_action( 'give_user_profile_updated', $user_id, $userdata );
500
501
		$profile_edit_redirect_args = array(
502
			'updated'     => 'true',
503
			'update_code' => $update_code,
504
		);
505
506
		/**
507
		 * Update codes '2' and '3' indicate a password change.
508
		 * If the password is changed, then logout and redirect to the same page.
509
		 */
510
		if ( '2' === $update_code || '3' === $update_code ) {
511
			wp_logout( wp_redirect( add_query_arg( $profile_edit_redirect_args, $data['give_redirect'] ) ) );
512
		} else {
513
			wp_redirect( add_query_arg( $profile_edit_redirect_args, $data['give_redirect'] ) );
514
		}
515
516
		give_die();
517
	}
518
519
	return false;
520
}
521
522
add_action( 'give_edit_user_profile', 'give_process_profile_editor_updates' );
523
524
/**
525
 * Give totals Shortcode.
526
 *
527
 * Shows a donation total.
528
 *
529
 * @since  2.1
530
 *
531
 * @param  array $atts Shortcode attributes.
532
 *
533
 * @return string
534
 */
535
function give_totals_shortcode( $atts ) {
536
	$total = get_option( 'give_earnings_total', false );
537
538
	$message = apply_filters( 'give_totals_message', __( 'Hey! We\'ve raised {total} of the {total_goal} we are trying to raise for this campaign!', 'give' ) );
539
540
	$atts = shortcode_atts( array(
541
		'total_goal'   => 0, // integer.
542
		'ids'          => 0, // integer|array.
543
		'cats'         => 0, // integer|array.
544
		'tags'         => 0, // integer|array.
545
		'message'      => $message,
546
		'link'         => '', // URL.
547
		'link_text'    => __( 'Donate Now', 'give' ), // string,
548
		'progress_bar' => true, // boolean.
549
	), $atts, 'give_totals' );
550
551
	// Total Goal.
552
	$total_goal = give_maybe_sanitize_amount( $atts['total_goal'] );
553
554
	/**
555
	 * Give Action fire before the shortcode is rendering is started.
556
	 *
557
	 * @since 2.1.4
558
	 *
559
	 * @param array $atts shortcode attribute.
560
	 */
561
	do_action( 'give_totals_goal_shortcode_before_render', $atts );
562
563
	// Build query based on cat, tag and Form ids.
564
	if ( ! empty( $atts['cats'] ) || ! empty( $atts['tags'] ) || ! empty( $atts['ids'] ) ) {
565
566
		$form_ids = array();
567 View Code Duplication
		if ( ! empty( $atts['ids'] ) ) {
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...
568
			$form_ids = array_filter( array_map( 'trim', explode( ',', $atts['ids'] ) ) );
569
		}
570
571
		/**
572
		 * Filter to modify WP Query for Total Goal.
573
		 *
574
		 * @since 2.1.4
575
		 *
576
		 * @param array WP query argument for Total Goal.
577
		 */
578
		$form_args = array(
579
			'post_type'      => 'give_forms',
580
			'post_status'    => 'publish',
581
			'post__in'       => $form_ids,
582
			'posts_per_page' => - 1,
583
			'fields'         => 'ids',
584
			'tax_query'      => array(
0 ignored issues
show
introduced by
Detected usage of tax_query, possible slow query.
Loading history...
585
				'relation' => 'AND',
586
			),
587
		);
588
589 View Code Duplication
		if ( ! empty( $atts['cats'] ) ) {
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...
590
			$cats                     = array_filter( array_map( 'trim', explode( ',', $atts['cats'] ) ) );
591
			$form_args['tax_query'][] = array(
592
				'taxonomy' => 'give_forms_category',
593
				'terms'    => $cats,
594
			);
595
		}
596
597 View Code Duplication
		if ( ! empty( $atts['tags'] ) ) {
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...
598
			$tags                     = array_filter( array_map( 'trim', explode( ',', $atts['tags'] ) ) );
599
			$form_args['tax_query'][] = array(
600
				'taxonomy' => 'give_forms_tag',
601
				'terms'    => $tags,
602
			);
603
		}
604
605
		/**
606
		 * Filter to modify WP Query for Total Goal.
607
		 *
608
		 * @since 2.1.4
609
		 *
610
		 * @param array $form_args WP query argument for Total Goal.
611
		 *
612
		 * @return array $form_args WP query argument for Total Goal.
613
		 */
614
		$form_args = (array) apply_filters( 'give_totals_goal_shortcode_query_args', $form_args );
615
616
		$forms = new WP_Query( $form_args );
617
618
		if ( isset( $forms->posts ) ) {
619
			$total = 0;
620
			foreach ( $forms->posts as $post ) {
621
				$form_earning = give_get_meta( $post, '_give_form_earnings', true );
622
				$form_earning = ! empty( $form_earning ) ? $form_earning : 0;
623
624
				/**
625
				 * Update Form earnings.
626
				 *
627
				 * @since 2.1
628
				 *
629
				 * @param int    $post         Form ID.
630
				 * @param string $form_earning Total earning of Form.
631
				 * @param array $atts shortcode attributes.
632
				 */
633
				$total += apply_filters( 'give_totals_form_earning', $form_earning, $post, $atts );
634
			}
635
		}
636
	} // End if().
637
638
	// Append link with text.
639
	$donate_link = '';
640
	if ( ! empty( $atts['link'] ) ) {
641
		$donate_link = sprintf( ' <a class="give-totals-text-link" href="%1$s">%2$s</a>', esc_url( $atts['link'] ), esc_html( $atts['link_text'] ) );
642
	}
643
644
	// Replace {total} in message.
645
	$message = str_replace( '{total}', give_currency_filter(
646
		give_format_amount( $total,
647
			array( 'sanitize' => false )
648
		)
649
	), esc_html( $atts['message'] ) );
650
651
	// Replace {total_goal} in message.
652
	$message = str_replace( '{total_goal}', give_currency_filter(
653
		give_format_amount( $total_goal,
654
			array( 'sanitize' => true )
655
		)
656
	), $message );
657
658
	/**
659
	 * Update Give totals shortcode output.
660
	 *
661
	 * @since 2.1
662
	 *
663
	 * @param string $message Shortcode Message.
664
	 * @param array $atts ShortCode attributes.
665
	 */
666
	$message = apply_filters( 'give_totals_shortcode_message', $message, $atts );
667
668
	ob_start();
669
	?>
670
	<div class="give-totals-shortcode-wrap">
671
		<?php
672
		// Show Progress Bar if progress_bar set true.
673
		$show_progress_bar = isset( $atts['progress_bar'] ) ? filter_var( $atts['progress_bar'], FILTER_VALIDATE_BOOLEAN ) : true;
674
		if ( $show_progress_bar ) {
675
			give_show_goal_totals_progress( $total, $total_goal );
676
		}
677
678
		echo sprintf( $message ) . $donate_link;
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
introduced by
Expected next thing to be a escaping function, not '$donate_link'
Loading history...
679
		?>
680
	</div>
681
	<?php
682
	$give_totals_output = ob_get_clean();
683
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
684
685
	/**
686
	 * Give Action fire after the total goal shortcode rendering is end.
687
	 *
688
	 * @since 2.1.4
689
	 *
690
	 * @param array  $atts               shortcode attribute.
691
	 * @param string $give_totals_output shortcode output.
692
	 */
693
	do_action( 'give_totals_goal_shortcode_after_render', $atts, $give_totals_output );
694
695
	/**
696
	 * Give Totals Shortcode output.
697
	 *
698
	 * @since 2.1
699
	 *
700
	 * @param string $give_totals_output
701
	 */
702
	return apply_filters( 'give_totals_shortcode_output', $give_totals_output );
703
704
}
705
706
add_shortcode( 'give_totals', 'give_totals_shortcode' );
707
708
709
/**
710
 * Displays donation forms in a grid layout.
711
 *
712
 * @since  2.1.0
713
 *
714
 * @param array $atts                {
715
 *                                   Optional. Attributes of the form grid shortcode.
716
 *
717
 * @type int    $forms_per_page      Number of forms per page. Default '12'.
718
 * @type bool   $paged               Whether to paginate forms. Default 'true'.
719
 * @type string $ids                 A comma-separated list of form IDs to display. Default empty.
720
 * @type string exclude              A comma-separated list of form IDs to exclude from display. Default empty.
721
 * @type string $cats                A comma-separated list of form categories to display. Default empty.
722
 * @type string $tags                A comma-separated list of form tags to display. Default empty.
723
 * @type string $columns             Maximum columns to display. Default 'best-fit'.
724
 *                                       Accepts 'best-fit', '1', '2', '3', '4'.
725
 * @type bool   $show_title          Whether to display form title. Default 'true'.
726
 * @type bool   $show_goal           Whether to display form goal. Default 'true'.
727
 * @type bool   $show_excerpt        Whether to display form excerpt. Default 'true'.
728
 * @type bool   $show_featured_image Whether to display featured image. Default 'true'.
729
 * @type string $image_size          Featured image size. Default 'medium'. Accepts WordPress image sizes.
730
 * @type string $image_height        Featured image height. Default 'auto'. Accepts valid CSS heights.
731
 * @type int    $excerpt_length      Number of words before excerpt is truncated. Default '16'.
732
 * @type string $display_style       How the form is displayed, either in new page or modal popup.
733
 *                                       Default 'redirect'. Accepts 'redirect', 'modal'.
734
 * }
735
 * @return string|bool The markup of the form grid or false.
736
 */
737
function give_form_grid_shortcode( $atts ) {
738
739
	$give_settings = give_get_settings();
740
741
	$atts = shortcode_atts( array(
742
		'forms_per_page'      => 12,
743
		'paged'               => true,
744
		'ids'                 => '',
745
		'exclude'             => '',
746
		'orderby'             => 'date',
747
		'order'               => 'DESC',
748
		'cats'                => '',
749
		'tags'                => '',
750
		'columns'             => 'best-fit',
751
		'show_title'          => true,
752
		'show_goal'           => true,
753
		'show_excerpt'        => true,
754
		'show_featured_image' => true,
755
		'image_size'          => 'medium',
756
		'image_height'        => 'auto',
757
		'excerpt_length'      => 16,
758
		'display_style'       => 'modal_reveal',
759
		'status'              => '', // open or closed.
760
	), $atts );
761
762
	// Validate integer attributes.
763
	$atts['forms_per_page'] = intval( $atts['forms_per_page'] );
764
	$atts['excerpt_length'] = intval( $atts['excerpt_length'] );
765
766
	// Validate boolean attributes.
767
	$boolean_attributes = array(
768
		'paged',
769
		'show_title',
770
		'show_goal',
771
		'show_excerpt',
772
		'show_featured_image',
773
	);
774
775
	foreach ( $boolean_attributes as $att ) {
776
		$atts[ $att ] = filter_var( $atts[ $att ], FILTER_VALIDATE_BOOLEAN );
777
	}
778
779
	// Set default form query args.
780
	$form_args = array(
781
		'post_type'      => 'give_forms',
782
		'post_status'    => 'publish',
783
		'posts_per_page' => $atts['forms_per_page'],
784
		'orderby'        => $atts['orderby'],
785
		'order'          => $atts['order'],
786
		'tax_query'      => array(
0 ignored issues
show
introduced by
Detected usage of tax_query, possible slow query.
Loading history...
787
			'relation' => 'AND',
788
		),
789
	);
790
791
	// Filter results of form grid based on form status.
792
	$form_closed_status = trim( $atts['status'] );
793
794
	if ( ! empty( $form_closed_status ) ) {
795
		$form_args['meta_query'] = array(
0 ignored issues
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
796
			array(
797
				'key'   => '_give_form_status',
798
				'value' => $form_closed_status,
799
			),
800
		);
801
	}
802
803
	// Maybe add pagination.
804
	if ( true === $atts['paged'] ) {
805
		$form_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
806
	}
807
808
	// Maybe filter forms by IDs.
809 View Code Duplication
	if ( ! empty( $atts['ids'] ) ) {
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...
810
		$form_args['post__in'] = array_filter( array_map( 'trim', explode( ',', $atts['ids'] ) ) );
811
	}
812
813
	// Convert comma-separated form IDs into array.
814
	if ( ! empty( $atts['exclude'] ) ) {
815
		$form_args['post__not_in'] = array_filter( array_map( function( $item ) {
816
			return intval( trim( $item ) );
817
		}, explode( ',', $atts['exclude'] ) ) );
818
	}
819
820
	// Maybe filter by form category.
821 View Code Duplication
	if ( ! empty( $atts['cats'] ) ) {
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...
822
		$cats                     = array_filter( array_map( 'trim', explode( ',', $atts['cats'] ) ) );
823
		$tax_query                = array(
824
			'taxonomy' => 'give_forms_category',
825
			'terms'    => $cats,
826
		);
827
		$form_args['tax_query'][] = $tax_query;
828
	}
829
830
	// Maybe filter by form tag.
831 View Code Duplication
	if ( ! empty( $atts['tags'] ) ) {
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...
832
		$tags                     = array_filter( array_map( 'trim', explode( ',', $atts['tags'] ) ) );
833
		$tax_query                = array(
834
			'taxonomy' => 'give_forms_tag',
835
			'terms'    => $tags,
836
		);
837
		$form_args['tax_query'][] = $tax_query;
838
	}
839
	
840
	/**
841
	 * Filter to modify WP Query for Total Goal.
842
	 *
843
	 * @since 2.1.4
844
	 *
845
	 * @param array $form_args WP query argument for Grid.
846
	 *
847
	 * @return array $form_args WP query argument for Grid.
848
	 */
849
	$form_args = (array) apply_filters( 'give_form_grid_shortcode_query_args', $form_args );
850
851
	// Maybe filter by form Amount Donated or Number of Donations.
852
	switch ( $atts['orderby'] ) {
853
		case 'amount_donated':
854
			$form_args['meta_key'] = '_give_form_earnings';
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
855
			$form_args['orderby']  = 'meta_value_num';
856
			break;
857
		case 'number_donations':
858
			$form_args['meta_key'] = '_give_form_sales';
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
859
			$form_args['orderby']  = 'meta_value_num';
860
			break;
861
		case 'closest_to_goal':
862
			if( give_has_upgrade_completed( 'v240_update_form_goal_progress' ) ) {
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...
863
				$form_args['meta_key'] = '_give_form_goal_progress';
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
864
				$form_args['orderby']  = 'meta_value_num';
865
			}
866
			break;
867
	}
868
869
	// Query to output donation forms.
870
	$form_query = new WP_Query( $form_args );
871
872
	if ( $form_query->have_posts() ) {
873
		ob_start();
874
875
		add_filter( 'add_give_goal_progress_class', 'add_give_goal_progress_class', 10, 1 );
876
		add_filter( 'add_give_goal_progress_bar_class', 'add_give_goal_progress_bar_class', 10, 1 );
877
		add_filter( 'give_form_wrap_classes', 'add_class_for_form_grid', 10, 3 );
878
		add_action( 'give_donation_form_top', 'give_is_form_grid_page_hidden_field', 10, 3 );
879
880
		echo '<div class="give-wrap">';
881
		echo '<div class="give-grid give-grid--' . esc_attr( $atts['columns'] ) . '">';
882
883
		while ( $form_query->have_posts() ) {
884
			$form_query->the_post();
885
886
			// Give/templates/shortcode-form-grid.php.
887
			give_get_template( 'shortcode-form-grid', array( $give_settings, $atts ) );
888
889
		}
890
891
		wp_reset_postdata();
892
893
		echo '</div><!-- .give-grid -->';
894
895
		remove_filter( 'add_give_goal_progress_class', 'add_give_goal_progress_class' );
896
		remove_filter( 'add_give_goal_progress_bar_class', 'add_give_goal_progress_bar_class' );
897
		remove_filter( 'give_form_wrap_classes', 'add_class_for_form_grid', 10 );
898
		remove_action( 'give_donation_form_top', 'give_is_form_grid_page_hidden_field', 10 );
899
900
		if ( false !== $atts['paged'] ) {
901
			$paginate_args = array(
902
				'current'   => max( 1, get_query_var( 'paged' ) ),
903
				'total'     => $form_query->max_num_pages,
904
				'show_all'  => false,
905
				'end_size'  => 1,
906
				'mid_size'  => 2,
907
				'prev_next' => true,
908
				'prev_text' => __( '« Previous', 'give' ),
909
				'next_text' => __( 'Next »', 'give' ),
910
				'type'      => 'plain',
911
				'add_args'  => false,
912
			);
913
914
			printf(
915
				'<div class="give-page-numbers">%s</div>',
916
				paginate_links( $paginate_args )
917
			);
918
		}
919
		echo '</div><!-- .give-wrap -->';
920
921
		return ob_get_clean();
922
	} // End if().
923
}
924
925
add_shortcode( 'give_form_grid', 'give_form_grid_shortcode' );
926