PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.16.9
GiveWP – Donation Plugin and Fundraising Platform v4.16.9
4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 All 255 releases
← All changes | includes/shortcodes.php +411 -239 2.3.24.16.9 View file →
@@ -9,8 +9,15 @@
9 9 * @since 1.0
10 10 */
11 11
12 12 // Exit if accessed directly.
13 +use Give\DonationForms\DonationQuery;
14 +use Give\Helpers\Form\Template\Utils\Frontend as FrontendFormTemplateUtils;
15 +use Give\Helpers\Form\Utils as FormUtils;
16 +use Give\Helpers\Frontend\ConfirmDonation;
17 +use Give\Helpers\Frontend\Shortcode as ShortcodeUtils;
18 +use Give\Views\IframeView;
19 +
13 20 if ( ! defined( 'ABSPATH' ) ) {
14 21 exit;
15 22 }
16 23
@@ -18,8 +25,10 @@
18 25 * Donation History Shortcode
19 26 *
20 27 * Displays a user's donation history.
21 28 *
29 + * @since 3.7.0 Sanitize attributes
30 + * @since 3.1.0 pass form id by reference in give_totals shortcode.
22 31 * @since 1.0
23 32 *
24 33 * @param array $atts
25 34 * @param string|bool $content
@@ -26,18 +35,22 @@
26 35 *
27 36 * @return string|bool
28 37 */
29 38 function give_donation_history( $atts, $content = false ) {
39 + $atts = give_clean($atts);
40 + $donation_history_args = shortcode_atts(
41 + [
42 + 'id' => true,
43 + 'date' => true,
44 + 'donor' => false,
45 + 'amount' => true,
46 + 'status' => false,
47 + 'payment_method' => false,
48 + ],
49 + $atts,
50 + 'donation_history'
51 + );
30 52
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 53 // Always show receipt link.
41 54 $donation_history_args['details'] = true;
42 55
43 56 // Set Donation History Shortcode Arguments in session variable.
@@ -42,19 +55,27 @@
42 55
43 56 // Set Donation History Shortcode Arguments in session variable.
44 57 Give()->session->set( 'give_donation_history_args', $donation_history_args );
45 58
59 + $get_data = give_clean( filter_input_array( INPUT_GET ) );
60 +
46 61 // If payment_key query arg exists, return receipt instead of donation history.
47 - if ( isset( $_GET['donation_id'] ) ) {
62 + if (
63 + ! empty( $get_data['donation_id'] ) ||
64 + (
65 + ! empty( $get_data['action'] ) &&
66 + 'view_in_browser' === $get_data['action']
67 + )
68 + ) {
48 69 ob_start();
49 70
50 - echo give_receipt_shortcode( array() );
71 + echo do_shortcode( ShortcodeUtils::getReceiptShortcodeFromConfirmationPage() );
51 72
52 73 // Display donation history link only if Receipt Access Session is available.
53 - if ( give_get_receipt_session() ) {
74 + if ( give_get_receipt_session() || is_user_logged_in() ) {
54 75 echo sprintf(
55 76 '<a href="%s">%s</a>',
56 - esc_url( give_get_history_page_uri() ),
77 + esc_url($_SERVER['HTTP_REFERER'] ),
57 78 __( '&laquo; Return to All Donations', 'give' )
58 79 );
59 80 }
60 81
@@ -87,9 +108,9 @@
87 108 give_get_template_part( 'email', 'login-form' );
88 109
89 110 } else {
90 111
91 - 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 ) );
112 + 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 ) );
92 113 echo do_shortcode( '[give_login]' );
93 114 }
94 115
95 116 /**
@@ -112,32 +133,77 @@
112 133 * Donation Form Shortcode
113 134 *
114 135 * Show the Give donation form.
115 136 *
137 + * @since 4.3.0 Add check for 'modal' in display_style to allow v2 forms to be shown in a modal.
138 + * @since 3.7.0 Sanitize attributes
139 + * @since 3.4.0 Add additional validations to check if the form is valid and has the 'published' status.
140 + * @since 2.30.0 Add short-circuit filter to allow for custom output.
116 141 * @since 1.0
117 142 *
118 - * @param array $atts Shortcode attributes
143 +
144 + * @param array $atts Shortcode attributes
119 145 *
120 146 * @return string
121 147 */
122 148 function give_form_shortcode( $atts ) {
123 - $atts = shortcode_atts( array(
124 - 'id' => '',
125 - 'show_title' => true,
126 - 'show_goal' => true,
127 - 'show_content' => '',
128 - 'float_labels' => '',
129 - 'display_style' => '',
130 - 'continue_button_title' => '',
131 - ), $atts, 'give_form' );
149 + $atts = give_clean($atts);
150 + $atts = shortcode_atts( give_get_default_form_shortcode_args(), $atts, 'give_form' );
132 151
152 + if('fullForm' === $atts['display_style']) {
153 + $atts['display_style'] = 'onpage';
154 + }
155 +
133 156 // Convert string to bool.
134 157 $atts['show_title'] = filter_var( $atts['show_title'], FILTER_VALIDATE_BOOLEAN );
135 158 $atts['show_goal'] = filter_var( $atts['show_goal'], FILTER_VALIDATE_BOOLEAN );
136 159
160 + // Set form id.
161 + $atts['id'] = $atts['id'] ?: FrontendFormTemplateUtils::getFormId();
162 + $formId = absint($atts['id']);
163 +
164 + if ( ! ShortcodeUtils::isValidForm($formId)) {
165 + ob_start();
166 + Give_Notices::print_frontend_notice(__('The shortcode is missing a valid Donation Form ID attribute.', 'give'),
167 + true);
168 +
169 + return ob_get_clean();
170 + }
171 +
172 + if ( ! ShortcodeUtils::isPublishedForm($formId)) {
173 + ob_start();
174 + Give_Notices::print_frontend_notice(__('The form is not published.', 'give'), true);
175 +
176 + return ob_get_clean();
177 + }
178 +
179 + _give_redirect_form_id($formId, $atts['id']);
180 +
181 + // Short-circuit the shortcode output if the filter returns a non-empty string.
182 + $output = apply_filters('givewp_form_shortcode_output', '', $atts);
183 +
184 + if ($output) {
185 + return $output;
186 + }
187 +
137 188 // Fetch the Give Form.
138 189 ob_start();
139 - give_get_donation_form( $atts );
190 +
191 + if ( ! FormUtils::isLegacyForm( $formId ) ) {
192 + $showIframeInModal = 'button' === $atts['display_style'] || 'modal' === $atts['display_style'];
193 + $iframeView = new IframeView();
194 +
195 + ConfirmDonation::storePostedDataInDonationSession();
196 +
197 + echo $iframeView->setFormId( $formId )
198 + ->showInModal( $showIframeInModal )
199 + ->setButtonTitle( $atts['continue_button_title'] )
200 + ->setButtonColor( $atts['button_color'] )
201 + ->render();
202 + } else {
203 + give_get_donation_form( $atts );
204 + }
205 +
140 206 $final_output = ob_get_clean();
141 207
142 208 return apply_filters( 'give_donate_form', $final_output, $atts );
143 209 }
@@ -148,8 +214,11 @@
148 214 * Donation Form Goal Shortcode.
149 215 *
150 216 * Show the Give donation form goals.
151 217 *
218 + * @since 3.12.0 add start_date and end_date attributes
219 + * @since 3.7.0 Sanitize attributes
220 + * @since 3.4.0 Add additional validations to check if the form is valid and has the 'published' status.
152 221 * @since 1.0
153 222 *
154 223 * @param array $atts Shortcode attributes.
155 224 *
@@ -155,26 +224,40 @@
155 224 *
156 225 * @return string
157 226 */
158 227 function give_goal_shortcode( $atts ) {
159 - $atts = shortcode_atts( array(
160 - 'id' => '',
161 - 'show_text' => true,
162 - 'show_bar' => true,
163 - ), $atts, 'give_goal' );
228 + $atts = give_clean($atts);
229 + $atts = shortcode_atts(
230 + [
231 + 'id' => '',
232 + 'show_text' => true,
233 + 'show_bar' => true,
234 + 'color' => '#66BB6A',
235 + 'start_date' => '',
236 + 'end_date' => '',
237 + ],
238 + $atts,
239 + 'give_goal'
240 + );
164 241
242 + _give_redirect_form_id($atts['id']);
243 +
165 244 // get the Give Form.
166 245 ob_start();
167 246
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 - }
247 + $formId = (int)$atts['id'];
172 248
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 ) ) ) {
249 + // Sanity check 1: ensure there is an ID Provided.
250 + if ( ! ShortcodeUtils::isValidForm($formId)) {
251 + Give_Notices::print_frontend_notice(__('The shortcode is missing a valid Donation Form ID attribute.', 'give'),
252 + true);
253 + } elseif // Sanity check 2: ensure the form is published.
254 + ( ! ShortcodeUtils::isPublishedForm($formId)) {
255 + Give_Notices::print_frontend_notice(__('The form is not published.', 'give'), true);
256 + } elseif // Sanity check 3: Check the form even has Goals enabled.
257 + ( ! give_is_setting_enabled(give_get_meta($atts['id'], '_give_goal_option', true))) {
175 258
176 - Give()->notices->print_frontend_notice( __( 'The form does not have Goals enabled.', 'give' ), true );
259 + Give_Notices::print_frontend_notice( __( 'The form does not have Goals enabled.', 'give' ), true );
177 260 } else {
178 261 // Passed all sanity checks: output Goal.
179 262 give_show_goal_progress( $atts['id'], $atts );
180 263 }
@@ -192,8 +275,9 @@
192 275 *
193 276 * Shows a login form allowing users to users to log in. This function simply
194 277 * calls the give_login_form function to display the login form.
195 278 *
279 + * @since 3.7.0 Sanitize attributes
196 280 * @since 1.0
197 281 *
198 282 * @param array $atts Shortcode attributes.
199 283 *
@@ -201,16 +285,20 @@
201 285 *
202 286 * @return string
203 287 */
204 288 function give_login_form_shortcode( $atts ) {
289 + $atts = give_clean($atts);
290 + $atts = shortcode_atts(
291 + [
292 + // Add backward compatibility for redirect attribute.
293 + 'redirect' => '',
294 + 'login-redirect' => '',
295 + 'logout-redirect' => '',
296 + ],
297 + $atts,
298 + 'give_login'
299 + );
205 300
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 301 // 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 302 $atts['login-redirect'] = ! empty( $atts['login-redirect'] ) ? $atts['login-redirect'] : ( ! empty( $atts['redirect'] ) ? $atts['redirect'] : '' );
215 303
216 304 return give_login_form( $atts['login-redirect'], $atts['logout-redirect'] );
@@ -222,8 +310,9 @@
222 310 * Register Shortcode.
223 311 *
224 312 * Shows a registration form allowing users to users to register for the site.
225 313 *
314 + * @since 3.7.0 Sanitize attributes
226 315 * @since 1.0
227 316 *
228 317 * @param array $atts Shortcode attributes.
229 318 *
@@ -231,11 +320,16 @@
231 320 *
232 321 * @return string
233 322 */
234 323 function give_register_form_shortcode( $atts ) {
235 - $atts = shortcode_atts( array(
236 - 'redirect' => '',
237 - ), $atts, 'give_register' );
324 + $atts = give_clean($atts);
325 + $atts = shortcode_atts(
326 + [
327 + 'redirect' => '',
328 + ],
329 + $atts,
330 + 'give_register'
331 + );
238 332
239 333 return give_register_form( $atts['redirect'] );
240 334 }
241 335
@@ -245,8 +339,10 @@
245 339 * Receipt Shortcode.
246 340 *
247 341 * Shows a donation receipt.
248 342 *
343 + * @since 3.16.0 add give_donation_confirmation_page_enqueue_scripts
344 + * @since 3.7.0 Sanitize and escape attributes
249 345 * @since 1.0
250 346 *
251 347 * @param array $atts Shortcode attributes.
252 348 *
@@ -255,26 +351,38 @@
255 351 function give_receipt_shortcode( $atts ) {
256 352
257 353 global $give_receipt_args;
258 354
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' );
355 + $atts = give_clean($atts);
270 356
271 - $donation_id = false;
272 - $session = give_get_purchase_session();
357 + $give_receipt_args = shortcode_atts(
358 + [
359 + 'error' => __( 'You are missing the donation id to view this donation receipt.', 'give' ),
360 + 'price' => true,
361 + 'donor' => true,
362 + 'date' => true,
363 + 'payment_method' => true,
364 + 'payment_id' => true,
365 + 'payment_status' => false,
366 + 'company_name' => false,
367 + 'status_notice' => true,
368 + ],
369 + $atts,
370 + 'give_receipt'
371 + );
273 372
274 - // Set donation id.
275 - if ( isset( $_GET['donation_id'] ) ) {
276 - $donation_id = give_clean( $_GET['donation_id'] );
373 + ob_start();
374 +
375 + $donation_id = false;
376 + $receipt_type = false;
377 + $get_data = give_clean( filter_input_array( INPUT_GET ) );
378 + $session = give_get_purchase_session();
379 +
380 + if ( ! empty( $get_data['donation_id'] ) ) {
381 + $donation_id = $get_data['donation_id'];
382 + } elseif ( ! empty( $get_data['action'] ) && 'view_in_browser' === $get_data['action'] ) {
383 + $receipt_type = 'view_in_browser';
384 + $donation_id = $get_data['_give_hash'];
277 385 } elseif ( isset( $session['donation_id'] ) ) {
278 386 $donation_id = $session['donation_id'];
279 387 } elseif ( ! empty( $give_receipt_args['id'] ) ) {
280 388 $donation_id = $give_receipt_args['id'];
@@ -279,92 +387,24 @@
279 387 } elseif ( ! empty( $give_receipt_args['id'] ) ) {
280 388 $donation_id = $give_receipt_args['id'];
281 389 }
282 390
283 - $email_access = give_get_option( 'email_access' );
284 - $is_email_access = give_is_setting_enabled( $email_access ) && ! Give()->email_access->token_exists;
285 -
286 - ob_start();
287 -
288 - // No donation id found & Email Access is Turned on.
289 - if ( ! $donation_id ) {
290 -
291 - if( $is_email_access ){
292 - give_get_template_part( 'email-login-form' );
293 - } else{
294 - echo Give()->notices->print_frontend_notice( $give_receipt_args['error'], false, 'error' );
295 - }
296 -
297 - return ob_get_clean();
298 - }
299 -
300 - // Donation id provided, but user is logged out. Offer them the ability to login and view the receipt.
301 - if ( ! ( $user_can_view = give_can_view_receipt( $donation_id ) ) ) {
302 -
303 - if( true === Give()->session->get( 'donor_donation_mismatch' ) ) {
304 -
305 - /**
306 - * This filter will be used to modify the donor mismatch text for front end error notice.
307 - *
308 - * @since 2.3.1
309 - */
310 - $donor_mismatch_text = apply_filters( 'give_receipt_donor_mismatch_notice_text', __( 'You are trying to access invalid donation receipt. Please try again.', 'give' ) );
311 -
312 - echo Give()->notices->print_frontend_notice(
313 - $donor_mismatch_text,
314 - false,
315 - 'error'
316 - );
317 -
318 - } elseif( $is_email_access ) {
319 -
320 - give_get_template_part( 'email-login-form' );
321 -
322 - }else{
323 -
324 - global $give_login_redirect;
325 -
326 - $give_login_redirect = give_get_current_page_url();
327 -
328 - Give()->notices->print_frontend_notice(
329 - apply_filters( 'give_must_be_logged_in_error_message',
330 - __( 'You must be logged in to view this donation receipt.', 'give' )
331 - )
332 - );
333 -
334 - give_get_template_part( 'shortcode', 'login' );
335 - }
336 -
337 - return ob_get_clean();
338 - }
339 -
340 - /**
341 - * Check if the user has permission to view the receipt.
342 - *
343 - * If user is logged in, user ID is compared to user ID of ID stored in payment meta
344 - * or if user is logged out and donation was made as a guest, the donation session is checked for
345 - * or if user is logged in and the user can view sensitive shop data.
346 - */
347 - if ( ! apply_filters( 'give_user_can_view_receipt', $user_can_view, $give_receipt_args ) ) {
348 - return Give()->notices->print_frontend_notice( $give_receipt_args['error'], false, 'error' );
349 - }
350 -
351 391 // Display donation receipt placeholder while loading receipt via AJAX.
352 392 if ( ! wp_doing_ajax() ) {
353 393 give_get_template_part( 'receipt/placeholder' );
354 394
355 - return sprintf(
356 - '<div id="give-receipt" data-shortcode="%s" data-donation-key="%s">%s</div>',
357 - urlencode_deep( wp_json_encode( $atts ) ),
358 - $donation_id,
395 + do_action('give_donation_confirmation_page_enqueue_scripts');
396 +
397 + return apply_filters('give_receipt_shortcode_output', sprintf(
398 + '<div id="give-receipt" data-shortcode="%1$s" data-receipt-type="%2$s" data-donation-key="%3$s" >%4$s</div>',
399 + htmlspecialchars( wp_json_encode( $give_receipt_args ) ),
400 + esc_attr($receipt_type),
401 + esc_attr($donation_id),
359 402 ob_get_clean()
360 - );
403 + ));
361 404 }
362 405
363 -
364 - give_get_template_part( 'shortcode', 'receipt' );
365 -
366 - return ob_get_clean();
406 + return give_display_donation_receipt( $atts );
367 407 }
368 408
369 409 add_shortcode( 'give_receipt', 'give_receipt_shortcode' );
370 410
@@ -373,13 +413,14 @@
373 413 *
374 414 * Outputs the Give Profile Editor to allow users to amend their details from the
375 415 * front-end. This function uses the Give templating system allowing users to
376 416 * override the default profile editor template. The profile editor template is located
377 - * under templates/profile-editor.php, however, it can be altered by creating a
378 - * file called profile-editor.php in the give_template directory in your active theme's
417 + * under templates/shortcode-profile-editor.php, however, it can be altered by creating a
418 + * file called shortcode-profile-editor.php in the give_template directory in your active theme's
379 419 * folder. Please visit the Give Documentation for more information on how the
380 420 * templating system is used.
381 421 *
422 + * @since 3.7.0 Sanitize attributes
382 423 * @since 1.0
383 424 *
384 425 * @param array $atts Shortcode attributes.
385 426 *
@@ -386,14 +427,16 @@
386 427 * @return string Output generated from the profile editor
387 428 */
388 429 function give_profile_editor_shortcode( $atts ) {
389 430
431 + $atts = give_clean($atts);
432 +
390 433 ob_start();
391 434
392 435 // Restrict access to donor profile, if donor and user are disconnected.
393 436 $is_donor_disconnected = get_user_meta( get_current_user_id(), '_give_is_donor_disconnected', true );
394 437 if ( is_user_logged_in() && $is_donor_disconnected ) {
395 - Give()->notices->print_frontend_notice( __( 'Your Donor and User profile are no longer connected. Please contact the site administrator.', 'give' ), true, 'error' );
438 + Give_Notices::print_frontend_notice( __( 'Your Donor and User profile are no longer connected. Please contact the site administrator.', 'give' ), true, 'error' );
396 439
397 440 return false;
398 441 }
399 442
@@ -398,11 +441,9 @@
398 441 }
399 442
400 443 give_get_template_part( 'shortcode', 'profile-editor' );
401 444
402 - $display = ob_get_clean();
403 -
404 - return $display;
445 + return ob_get_clean();
405 446 }
406 447
407 448 add_shortcode( 'give_profile_editor', 'give_profile_editor_shortcode' );
408 449
@@ -442,9 +483,9 @@
442 483 $email = isset( $data['give_email'] ) ? sanitize_email( $data['give_email'] ) : $old_user_data->user_email;
443 484 $password = ! empty( $data['give_new_user_pass1'] ) ? $data['give_new_user_pass1'] : '';
444 485 $confirm_password = ! empty( $data['give_new_user_pass2'] ) ? $data['give_new_user_pass2'] : '';
445 486
446 - $userdata = array(
487 + $userdata = [
447 488 'ID' => $user_id,
448 489 'first_name' => $first_name,
449 490 'last_name' => $last_name,
450 491 'display_name' => $display_name,
@@ -450,9 +491,9 @@
450 491 'display_name' => $display_name,
451 492 'user_email' => $email,
452 493 'user_pass' => $password,
453 494 'company_name' => $company_name,
454 - );
495 + ];
455 496
456 497 /**
457 498 * Fires before updating user profile.
458 499 *
@@ -499,11 +540,14 @@
499 540 give_die();
500 541 }
501 542
502 543 // Update Donor First Name and Last Name.
503 - Give()->donors->update( $donor->id, array(
504 - 'name' => trim( "{$first_name} {$last_name}" ),
505 - ) );
544 + Give()->donors->update(
545 + $donor->id,
546 + [
547 + 'name' => trim( "{$first_name} {$last_name}" ),
548 + ]
549 + );
506 550 Give()->donor_meta->update_meta( $donor->id, '_give_donor_first_name', $first_name );
507 551 Give()->donor_meta->update_meta( $donor->id, '_give_donor_last_name', $last_name );
508 552 Give()->donor_meta->update_meta( $donor->id, '_give_donor_company', $company_name );
509 553
@@ -561,12 +605,12 @@
561 605 * @param array $userdata User info, including ID, first name, last name, display name and email.
562 606 */
563 607 do_action( 'give_user_profile_updated', $user_id, $userdata );
564 608
565 - $profile_edit_redirect_args = array(
609 + $profile_edit_redirect_args = [
566 610 'updated' => 'true',
567 611 'update_code' => $update_code,
568 - );
612 + ];
569 613
570 614 /**
571 615 * Update codes '2' and '3' indicate a password change.
572 616 * If the password is changed, then logout and redirect to the same page.
@@ -571,11 +615,11 @@
571 615 * Update codes '2' and '3' indicate a password change.
572 616 * If the password is changed, then logout and redirect to the same page.
573 617 */
574 618 if ( '2' === $update_code || '3' === $update_code ) {
575 - wp_logout( wp_redirect( add_query_arg( $profile_edit_redirect_args, $data['give_redirect'] ) ) );
619 + wp_logout();
576 620 } else {
577 - wp_redirect( add_query_arg( $profile_edit_redirect_args, $data['give_redirect'] ) );
621 + wp_redirect( esc_url_raw( add_query_arg( $profile_edit_redirect_args, $data['give_redirect'] ) ) );
578 622 }
579 623
580 624 give_die();
581 625 }
@@ -589,8 +633,10 @@
589 633 * Give totals Shortcode.
590 634 *
591 635 * Shows a donation total.
592 636 *
637 + * @since 3.14.0 Replace "_give_form_earnings" form meta with $query->form($post)->sumAmount()
638 + * @since 3.7.0 Sanitize attributes
593 639 * @since 2.1
594 640 *
595 641 * @param array $atts Shortcode attributes.
596 642 *
@@ -600,25 +646,32 @@
600 646 $total = get_option( 'give_earnings_total', false );
601 647
602 648 $message = apply_filters( 'give_totals_message', __( 'Hey! We\'ve raised {total} of the {total_goal} we are trying to raise for this campaign!', 'give' ) );
603 649
604 - $atts = shortcode_atts( array(
605 - 'total_goal' => 0, // integer.
606 - 'ids' => 0, // integer|array.
607 - 'cats' => 0, // integer|array.
608 - 'tags' => 0, // integer|array.
609 - 'message' => $message,
610 - 'link' => '', // URL.
611 - 'link_text' => __( 'Donate Now', 'give' ), // string,
612 - 'progress_bar' => true, // boolean.
613 - ), $atts, 'give_totals' );
650 + $atts = shortcode_atts(
651 + [
652 + 'total_goal' => 0, // integer.
653 + 'ids' => 0, // integer|array.
654 + 'cats' => 0, // integer|array.
655 + 'tags' => 0, // integer|array.
656 + 'message' => $message,
657 + 'link' => '', // URL.
658 + 'link_text' => __( 'Donate Now', 'give' ), // string,
659 + 'progress_bar' => true, // boolean.
660 + ],
661 + $atts,
662 + 'give_totals'
663 + );
614 664
615 665 // Total Goal.
616 666 $total_goal = give_maybe_sanitize_amount( $atts['total_goal'] );
617 667
668 + $atts = give_clean($atts);
669 +
618 670 /**
619 671 * Give Action fire before the shortcode is rendering is started.
620 672 *
673 + * @since 3.1.0 Use static function on array_map callback to pass the id as reference for _give_redirect_form_id to prevent warnings on PHP 8.0.1 or plus
621 674 * @since 2.1.4
622 675 *
623 676 * @param array $atts shortcode attribute.
624 677 */
@@ -626,13 +679,22 @@
626 679
627 680 // Build query based on cat, tag and Form ids.
628 681 if ( ! empty( $atts['cats'] ) || ! empty( $atts['tags'] ) || ! empty( $atts['ids'] ) ) {
629 682
630 - $form_ids = array();
683 + $form_ids = [];
631 684 if ( ! empty( $atts['ids'] ) ) {
632 685 $form_ids = array_filter( array_map( 'trim', explode( ',', $atts['ids'] ) ) );
633 686 }
634 687
688 + $form_ids = array_map(
689 + static function ($id) {
690 + _give_redirect_form_id($id);
691 +
692 + return $id;
693 + },
694 + $form_ids
695 + );
696 +
635 697 /**
636 698 * Filter to modify WP Query for Total Goal.
637 699 *
638 700 * @since 2.1.4
@@ -638,33 +700,33 @@
638 700 * @since 2.1.4
639 701 *
640 702 * @param array WP query argument for Total Goal.
641 703 */
642 - $form_args = array(
704 + $form_args = [
643 705 'post_type' => 'give_forms',
644 706 'post_status' => 'publish',
645 707 'post__in' => $form_ids,
646 708 'posts_per_page' => - 1,
647 709 'fields' => 'ids',
648 - 'tax_query' => array(
710 + 'tax_query' => [
649 711 'relation' => 'AND',
650 - ),
651 - );
712 + ],
713 + ];
652 714
653 715 if ( ! empty( $atts['cats'] ) ) {
654 716 $cats = array_filter( array_map( 'trim', explode( ',', $atts['cats'] ) ) );
655 - $form_args['tax_query'][] = array(
717 + $form_args['tax_query'][] = [
656 718 'taxonomy' => 'give_forms_category',
657 719 'terms' => $cats,
658 - );
720 + ];
659 721 }
660 722
661 723 if ( ! empty( $atts['tags'] ) ) {
662 724 $tags = array_filter( array_map( 'trim', explode( ',', $atts['tags'] ) ) );
663 - $form_args['tax_query'][] = array(
725 + $form_args['tax_query'][] = [
664 726 'taxonomy' => 'give_forms_tag',
665 727 'terms' => $tags,
666 - );
728 + ];
667 729 }
668 730
669 731 /**
670 732 * Filter to modify WP Query for Total Goal.
@@ -681,9 +743,10 @@
681 743
682 744 if ( isset( $forms->posts ) ) {
683 745 $total = 0;
684 746 foreach ( $forms->posts as $post ) {
685 - $form_earning = give_get_meta( $post, '_give_form_earnings', true );
747 + $query = new DonationQuery();
748 + $form_earning = $query->form($post)->sumAmount();
686 749 $form_earning = ! empty( $form_earning ) ? $form_earning : 0;
687 750
688 751 /**
689 752 * Update Form earnings.
@@ -705,20 +768,30 @@
705 768 $donate_link = sprintf( ' <a class="give-totals-text-link" href="%1$s">%2$s</a>', esc_url( $atts['link'] ), esc_html( $atts['link_text'] ) );
706 769 }
707 770
708 771 // Replace {total} in message.
709 - $message = str_replace( '{total}', give_currency_filter(
710 - give_format_amount( $total,
711 - array( 'sanitize' => false )
712 - )
713 - ), esc_html( $atts['message'] ) );
772 + $message = str_replace(
773 + '{total}',
774 + give_currency_filter(
775 + give_format_amount(
776 + $total,
777 + [ 'sanitize' => false ]
778 + )
779 + ),
780 + esc_html( $atts['message'] )
781 + );
714 782
715 783 // Replace {total_goal} in message.
716 - $message = str_replace( '{total_goal}', give_currency_filter(
717 - give_format_amount( $total_goal,
718 - array( 'sanitize' => true )
719 - )
720 - ), $message );
784 + $message = str_replace(
785 + '{total_goal}',
786 + give_currency_filter(
787 + give_format_amount(
788 + $total_goal,
789 + [ 'sanitize' => true ]
790 + )
791 + ),
792 + $message
793 + );
721 794
722 795 /**
723 796 * Update Give totals shortcode output.
724 797 *
@@ -744,9 +817,8 @@
744 817 </div>
745 818 <?php
746 819 $give_totals_output = ob_get_clean();
747 820
748 -
749 821 /**
750 822 * Give Action fire after the total goal shortcode rendering is end.
751 823 *
752 824 * @since 2.1.4
@@ -772,10 +844,22 @@
772 844
773 845 /**
774 846 * Displays donation forms in a grid layout.
775 847 *
848 + * @since 3.7.0 Sanitize attributes
776 849 * @since 2.1.0
777 850 *
851 + * @since 3.1.0 Use static function on array_map callback to pass the id as reference for _give_redirect_form_id to prevent warnings on PHP 8.0.1 or plus
852 + * @since 2.23.1 Updated the default text color for the donate button, see #6591.
853 + * @since 2.21.2 change tag_background_color, progress_bar_color to official green color #69b868.
854 + * change tag_text_color color to #333333.
855 + * @since 2.20.0 $show_donate_button Option to show donate button
856 + * @since 2.20.0 $donate_button_text Default Donate
857 + * @since 2.20.0 $donate_button_background_color Default #66bb6a
858 + * @since 2.20.0 $donate_button_text_color Default #fff
859 + * @since 2.20.0 $show_bar Default false
860 + * @since 2.22.2 remove $show_bar attribute in favor of show_goal
861 + *
778 862 * @param array $atts {
779 863 * Optional. Attributes of the form grid shortcode.
780 864 *
781 865 * @type int $forms_per_page Number of forms per page. Default '12'.
@@ -789,38 +873,49 @@
789 873 * @type bool $show_title Whether to display form title. Default 'true'.
790 874 * @type bool $show_goal Whether to display form goal. Default 'true'.
791 875 * @type bool $show_excerpt Whether to display form excerpt. Default 'true'.
792 876 * @type bool $show_featured_image Whether to display featured image. Default 'true'.
793 - * @type string $image_size Featured image size. Default 'medium'. Accepts WordPress image sizes.
877 + * @type string $image_size Featured image size. Default 'medium'. Accepts WordPress image sizes.
794 878 * @type string $image_height Featured image height. Default 'auto'. Accepts valid CSS heights.
795 879 * @type int $excerpt_length Number of words before excerpt is truncated. Default '16'.
796 - * @type string $display_style How the form is displayed, either in new page or modal popup.
880 + * @type string $display_style How the form is displayed, either in new page or modal popup.
797 881 * Default 'redirect'. Accepts 'redirect', 'modal'.
798 - * }
882 + *
799 883 * @return string|bool The markup of the form grid or false.
800 884 */
801 885 function give_form_grid_shortcode( $atts ) {
802 -
886 + $atts = give_clean($atts);
803 887 $give_settings = give_get_settings();
804 888
805 - $atts = shortcode_atts( array(
806 - 'forms_per_page' => 12,
807 - 'paged' => true,
808 - 'ids' => '',
809 - 'exclude' => '',
810 - 'cats' => '',
811 - 'tags' => '',
812 - 'columns' => 'best-fit',
813 - 'show_title' => true,
814 - 'show_goal' => true,
815 - 'show_excerpt' => true,
816 - 'show_featured_image' => true,
817 - 'image_size' => 'medium',
818 - 'image_height' => 'auto',
819 - 'excerpt_length' => 16,
820 - 'display_style' => 'modal_reveal',
821 - 'status' => '', // open or closed.
822 - ), $atts );
889 + $atts = shortcode_atts(
890 + [
891 + 'forms_per_page' => 12,
892 + 'paged' => true,
893 + 'ids' => '',
894 + 'exclude' => '',
895 + 'orderby' => 'date',
896 + 'order' => 'DESC',
897 + 'cats' => '',
898 + 'tags' => '',
899 + 'columns' => '1',
900 + 'show_title' => true,
901 + 'show_goal' => true,
902 + 'show_excerpt' => true,
903 + 'show_featured_image' => true,
904 + 'show_donate_button' => true,
905 + 'donate_button_text' => '',
906 + 'tag_background_color' => '#69b868',
907 + 'tag_text_color' => '#333333',
908 + 'donate_button_text_color' => '#000000',
909 + 'image_size' => 'medium',
910 + 'image_height' => 'auto',
911 + 'excerpt_length' => 16,
912 + 'display_style' => 'modal_reveal',
913 + 'progress_bar_color' => '#69b868',
914 + 'status' => '', // open or closed.
915 + ],
916 + $atts
917 + );
823 918
824 919 // Validate integer attributes.
825 920 $atts['forms_per_page'] = intval( $atts['forms_per_page'] );
826 921 $atts['excerpt_length'] = intval( $atts['excerpt_length'] );
@@ -825,15 +920,15 @@
825 920 $atts['forms_per_page'] = intval( $atts['forms_per_page'] );
826 921 $atts['excerpt_length'] = intval( $atts['excerpt_length'] );
827 922
828 923 // Validate boolean attributes.
829 - $boolean_attributes = array(
924 + $boolean_attributes = [
830 925 'paged',
831 926 'show_title',
832 927 'show_goal',
833 928 'show_excerpt',
834 929 'show_featured_image',
835 - );
930 + ];
836 931
837 932 foreach ( $boolean_attributes as $att ) {
838 933 $atts[ $att ] = filter_var( $atts[ $att ], FILTER_VALIDATE_BOOLEAN );
839 934 }
@@ -838,27 +933,30 @@
838 933 $atts[ $att ] = filter_var( $atts[ $att ], FILTER_VALIDATE_BOOLEAN );
839 934 }
840 935
841 936 // Set default form query args.
842 - $form_args = array(
937 + $form_args = [
843 938 'post_type' => 'give_forms',
844 939 'post_status' => 'publish',
845 940 'posts_per_page' => $atts['forms_per_page'],
846 - 'tax_query' => array(
941 + 'orderby' => $atts['orderby'],
942 + 'order' => $atts['order'],
943 + 'paged' => $atts['paged'],
944 + 'tax_query' => [
847 945 'relation' => 'AND',
848 - ),
849 - );
946 + ],
947 + ];
850 948
851 949 // Filter results of form grid based on form status.
852 950 $form_closed_status = trim( $atts['status'] );
853 951
854 952 if ( ! empty( $form_closed_status ) ) {
855 - $form_args['meta_query'] = array(
856 - array(
953 + $form_args['meta_query'] = [
954 + [
857 955 'key' => '_give_form_status',
858 956 'value' => $form_closed_status,
859 - ),
860 - );
957 + ],
958 + ];
861 959 }
862 960
863 961 // Maybe add pagination.
864 962 if ( true === $atts['paged'] ) {
@@ -866,38 +964,111 @@
866 964 }
867 965
868 966 // Maybe filter forms by IDs.
869 967 if ( ! empty( $atts['ids'] ) ) {
870 - $form_args['post__in'] = array_filter( array_map( 'trim', explode( ',', $atts['ids'] ) ) );
968 + $form_args['post__in'] = array_map(
969 + static function ($id) {
970 + _give_redirect_form_id($id);
971 +
972 + return $id;
973 + }, array_filter(array_map('trim', explode(',', $atts['ids'])))
974 + );
871 975 }
872 976
873 977 // Convert comma-separated form IDs into array.
874 978 if ( ! empty( $atts['exclude'] ) ) {
875 - $form_args['post__not_in'] = array_filter( array_map( function( $item ) {
876 - return intval( trim( $item ) );
877 - }, explode( ',', $atts['exclude'] ) ) );
979 + $form_args['post__not_in'] = array_filter(
980 + array_map(
981 + function( $item ) {
982 + return intval( trim( $item ) );
983 + },
984 + explode( ',', $atts['exclude'] )
985 + )
986 + );
878 987 }
879 988
880 989 // Maybe filter by form category.
881 990 if ( ! empty( $atts['cats'] ) ) {
882 - $cats = array_filter( array_map( 'trim', explode( ',', $atts['cats'] ) ) );
883 - $tax_query = array(
884 - 'taxonomy' => 'give_forms_category',
885 - 'terms' => $cats,
886 - );
887 - $form_args['tax_query'][] = $tax_query;
991 + $cats = array_filter( array_map( 'trim', explode( ',', $atts['cats'] ) ) );
992 +
993 + // Backward compatibility for term_ids.
994 + $term_ids = array_unique( array_filter( $cats, 'is_numeric' ) );
995 + if ( $term_ids ) {
996 + $form_args['tax_query'][] = [
997 + 'taxonomy' => 'give_forms_category',
998 + 'terms' => $term_ids,
999 + ];
1000 +
1001 + }
1002 +
1003 + $term_slug = array_unique( array_filter( array_diff( $cats, $term_ids ) ) );
1004 + if ( $term_slug ) {
1005 + $form_args['tax_query'][] = [
1006 + 'taxonomy' => 'give_forms_category',
1007 + 'field' => 'slug',
1008 + 'terms' => $term_slug,
1009 + ];
1010 +
1011 + }
888 1012 }
889 1013
890 1014 // Maybe filter by form tag.
891 1015 if ( ! empty( $atts['tags'] ) ) {
892 - $tags = array_filter( array_map( 'trim', explode( ',', $atts['tags'] ) ) );
893 - $tax_query = array(
894 - 'taxonomy' => 'give_forms_tag',
895 - 'terms' => $tags,
896 - );
897 - $form_args['tax_query'][] = $tax_query;
1016 + $tags = array_filter( array_map( 'trim', explode( ',', $atts['tags'] ) ) );
1017 +
1018 + // Backward compatibility for term_ids.
1019 + $tag_ids = array_unique( array_filter( $tags, 'is_numeric' ) );
1020 + if ( $tag_ids ) {
1021 + $form_args['tax_query'][] = [
1022 + 'taxonomy' => 'give_forms_tag',
1023 + 'terms' => $tag_ids,
1024 + ];
1025 +
1026 + }
1027 +
1028 + $tag_slug = array_unique( array_filter( array_diff( $tags, $tag_ids ) ) );
1029 + if ( $tag_slug ) {
1030 + $form_args['tax_query'][] = [
1031 + 'taxonomy' => 'give_forms_tag',
1032 + 'field' => 'slug',
1033 + 'terms' => $tag_slug,
1034 + ];
1035 +
1036 + }
898 1037 }
899 1038
1039 + /**
1040 + * Filter to modify WP Query for Total Goal.
1041 + *
1042 + * @since 2.1.4
1043 + *
1044 + * @param array $form_args WP query argument for Grid.
1045 + *
1046 + * @return array $form_args WP query argument for Grid.
1047 + */
1048 + $form_args = (array) apply_filters( 'give_form_grid_shortcode_query_args', $form_args );
1049 +
1050 + // Maybe filter by form Amount Donated or Number of Donations.
1051 + switch ( $atts['orderby'] ) {
1052 + case 'amount_donated':
1053 + $form_args['meta_key'] = '_give_form_earnings';
1054 + $form_args['orderby'] = 'meta_value_num';
1055 + break;
1056 + case 'number_donations':
1057 + $form_args['meta_key'] = '_give_form_sales';
1058 + $form_args['orderby'] = 'meta_value_num';
1059 + break;
1060 + case 'random':
1061 + $form_args['orderby'] = 'rand';
1062 + break;
1063 + case 'closest_to_goal':
1064 + if ( give_has_upgrade_completed( 'v240_update_form_goal_progress' ) ) {
1065 + $form_args['meta_key'] = '_give_form_goal_progress';
1066 + $form_args['orderby'] = 'meta_value_num';
1067 + }
1068 + break;
1069 + }
1070 +
900 1071 // Query to output donation forms.
901 1072 $form_query = new WP_Query( $form_args );
902 1073
903 1074 if ( $form_query->have_posts() ) {
@@ -914,9 +1085,9 @@
914 1085 while ( $form_query->have_posts() ) {
915 1086 $form_query->the_post();
916 1087
917 1088 // Give/templates/shortcode-form-grid.php.
918 - give_get_template( 'shortcode-form-grid', array( $give_settings, $atts ) );
1089 + give_get_template( 'shortcode-form-grid', [ $give_settings, $atts ] );
919 1090
920 1091 }
921 1092
922 1093 wp_reset_postdata();
@@ -928,9 +1099,9 @@
928 1099 remove_filter( 'give_form_wrap_classes', 'add_class_for_form_grid', 10 );
929 1100 remove_action( 'give_donation_form_top', 'give_is_form_grid_page_hidden_field', 10 );
930 1101
931 1102 if ( false !== $atts['paged'] ) {
932 - $paginate_args = array(
1103 + $paginate_args = [
933 1104 'current' => max( 1, get_query_var( 'paged' ) ),
934 1105 'total' => $form_query->max_num_pages,
935 1106 'show_all' => false,
936 1107 'end_size' => 1,
@@ -935,13 +1106,13 @@
935 1106 'show_all' => false,
936 1107 'end_size' => 1,
937 1108 'mid_size' => 2,
938 1109 'prev_next' => true,
939 - 'prev_text' => __( '« Previous', 'give' ),
940 - 'next_text' => __( 'Next »', 'give' ),
1110 + 'prev_text' => __( '&laquo; Previous', 'give' ),
1111 + 'next_text' => __( 'Next &raquo;', 'give' ),
941 1112 'type' => 'plain',
942 1113 'add_args' => false,
943 - );
1114 + ];
944 1115
945 1116 printf(
946 1117 '<div class="give-page-numbers">%s</div>',
947 1118 paginate_links( $paginate_args )
@@ -953,4 +1124,5 @@
953 1124 } // End if().
954 1125 }
955 1126
956 1127 add_shortcode( 'give_form_grid', 'give_form_grid_shortcode' );
1128 +