Issues (850)

Security Analysis    4 potential vulnerabilities

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

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

includes/user-functions.php (2 issues)

1
<?php
2
/**
3
 * Contains all user related functions.
4
 *
5
 * @since 1.0.0
6
 * @package GetPaid
7
 */
8
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * Queries the customers database.
13
 *
14
 * @param array $args Query arguments.For a list of all supported args, refer to GetPaid_Customers_Query::prepare_query()
15
 * @param string $return 'results' returns the found customers, $count returns the total count while 'query' returns GetPaid_Customers_Query
16
 *
17
 *
18
 * @return int|array|GetPaid_Customer[]|GetPaid_Customers_Query
19
 */
20
function getpaid_get_customers( $args = array(), $return = 'results' ) {
21
22
	// Do not retrieve all fields if we just want the count.
23
	if ( 'count' === $return ) {
24
		$args['fields'] = 'id';
25
		$args['number'] = 1;
26
	}
27
28
	// Do not count all matches if we just want the results.
29
	if ( 'results' === $return ) {
30
		$args['count_total'] = false;
31
	}
32
33
	$query = new GetPaid_Customers_Query( $args );
34
35
	if ( 'results' === $return ) {
36
		return $query->get_results();
37
	}
38
39
	if ( 'count' === $return ) {
40
		return $query->get_total();
41
	}
42
43
	return $query;
44
}
45
46
/**
47
 * Retrieves a customer.
48
 *
49
 * @param int|string|object|GetPaid_Customer $customer customer id, email or object.
50
 * @return GetPaid_Customer|null
51
 */
52
function getpaid_get_customer( $customer ) {
53
54
    if ( empty( $customer ) ) {
55
        return null;
56
    }
57
58
    // Retrieve the customer.
59
    if ( ! is_a( $customer, 'GetPaid_Customer' ) ) {
60
        $customer = new GetPaid_Customer( $customer );
61
    }
62
63
    // Check if it exists.
64
    if ( $customer->exists() ) {
65
        return $customer;
66
    }
67
68
    return null;
69
}
70
71
/**
72
 * Fetch customer by user ID.
73
 *
74
 * @return GetPaid_Customer|null
75
 * @since 1.0.0
76
 */
77
function getpaid_get_customer_by_user_id( $user_id ) {
78
    return getpaid_get_customer(
79
        GetPaid_Customer::get_customer_id_by( $user_id, 'user_id' )
80
    );
81
}
82
83
/**
84
 *  Generates a users select dropdown.
85
 *
86
 * @since 1.0.0
87
 * @return string|void Users dropdown markup.
88
 * @param array $args
89
 * @see wp_dropdown_users
90
 */
91
function wpinv_dropdown_users( $args = '' ) {
92
93
    if ( is_array( $args ) && ! empty( $args['show'] ) && 'display_name_with_email' == $args['show'] ) {
94
        $args['show'] = 'display_name_with_login';
95
    }
96
97
    return wp_dropdown_users( $args );
98
}
99
100
/**
101
 *  Returns the appropriate capability to check against
102
 *
103
 * @since 1.0.13
104
 * @return string capability to check against
105
 * @param string $capalibilty Optional. The alternative capability to check against.
106
 */
107
function wpinv_get_capability( $capalibilty = 'manage_invoicing' ) {
108
109
	if ( current_user_can( 'manage_options' ) ) {
110
		return 'manage_options';
111
	};
112
113
	return $capalibilty;
114
}
115
116
/**
117
 *  Checks if the current user can manager invoicing
118
 *
119
 * @since 1.0.13
120
 * @return bool
121
 */
122
function wpinv_current_user_can_manage_invoicing() {
123
    return current_user_can( wpinv_get_capability() );
124
}
125
126
/**
127
 * Returns whether the current user has the specified getpaid capability.
128
 *
129
 * @since 2.7.8
130
 *
131
 * @param string $capability Capability name.
132
 * @param mixed  $args    Optional further parameters, typically starting with an object.
133
 * @return bool Whether the current user has the given capability.
134
 */
135
function wpinv_current_user_can( $capability, $args = array() ) {
136
	$can = wpinv_current_user_can_manage_invoicing();
137
138
	return apply_filters( 'getpaid_current_user_can', $can, $capability, $args );
139
}
140
141
/**
142
 *  Given an email address, it creates a new user.
143
 *
144
 * @since 1.0.19
145
 * @return int|WP_Error
146
 */
147
function wpinv_create_user( $email, $prefix = '' ) {
148
149
    // Prepare user values.
150
    $prefix = preg_replace( '/\s+/', '', $prefix );
151
    $prefix = empty( $prefix ) ? $email : $prefix;
152
	$args   = array(
153
		'user_login' => wpinv_generate_user_name( $prefix ),
154
		'user_pass'  => wp_generate_password(),
155
		'user_email' => $email,
156
        'role'       => 'subscriber',
157
    );
158
159
    return wp_insert_user( $args );
160
161
}
162
163
/**
164
 *  Generates a unique user name from an email.
165
 *
166
 * @since 1.0.19
167
 * @return bool|WP_User
168
 */
169
function wpinv_generate_user_name( $prefix = '' ) {
170
171
    // If prefix is an email, retrieve the part before the email.
172
	$prefix = strtok( $prefix, '@' );
173
    $prefix = trim( $prefix, '.' );
174
175
	// Sanitize the username.
176
	$prefix = sanitize_user( $prefix, true );
177
178
	$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
179
	if ( empty( $prefix ) || in_array( strtolower( $prefix ), array_map( 'strtolower', $illegal_logins ), true ) ) {
180
		$prefix = 'gtp_' . zeroise( wp_rand( 0, 9999 ), 4 );
181
	}
182
183
    $username = $prefix;
184
    $postfix  = 2;
185
186
    while ( username_exists( $username ) ) {
187
        $username = "{$prefix}{$postfix}";
188
        $postfix ++;
189
    }
190
191
    return $username;
192
}
193
194
/**
195
 * Returns an array of user content tabs.
196
 *
197
 * @since 1.0.19
198
 * @return array
199
 */
200
function getpaid_get_user_content_tabs() {
201
202
    $tabs = array(
203
204
        'gp-invoices'      => array(
205
            'label'   => __( 'Invoices', 'invoicing' ), // Name of the tab.
206
            'content' => '[wpinv_history]', // Content of the tab. Or specify "callback" to provide a callback instead.
207
            'icon'    => 'fas fa-file-invoice', // Shown on some profile plugins.
208
        ),
209
210
        'gp-subscriptions' => array(
211
            'label'   => __( 'Subscriptions', 'invoicing' ),
212
            'content' => '[wpinv_subscriptions]',
213
            'icon'    => 'fas fa-redo',
214
        ),
215
216
        'gp-edit-address'  => array(
217
            'label'    => __( 'Billing Address', 'invoicing' ),
218
            'callback' => 'getpaid_display_address_edit_tab',
219
            'icon'     => 'fas fa-credit-card',
220
        ),
221
222
    );
223
224
    $tabs = apply_filters( 'getpaid_user_content_tabs', $tabs );
225
226
    // Make sure address editing is last on the list.
227
    if ( isset( $tabs['gp-edit-address'] ) ) {
228
        $address = $tabs['gp-edit-address'];
229
        unset( $tabs['gp-edit-address'] );
230
        $tabs['gp-edit-address'] = $address;
231
    }
232
233
    return $tabs;
234
}
235
236
/**
237
 * Prepares the contents of a tab.
238
 *
239
 * @since 1.0.19
240
 * @param array $tab
241
 * @return array
242
 */
243
function getpaid_prepare_user_content_tab( $tab ) {
244
245
    if ( ! empty( $tab['callback'] ) ) {
246
        return call_user_func( $tab['callback'] );
247
    }
248
249
    if ( ! empty( $tab['content'] ) ) {
250
        return convert_smilies( capital_P_dangit( wp_filter_content_tags( do_shortcode( shortcode_unautop( wpautop( wptexturize( do_blocks( $tab['content'] ) ) ) ) ) ) ) );
251
    }
252
253
    $notice = aui()->alert(
254
        array(
255
            'content' => __( 'This tab has no content or content callback.', 'invoicing' ),
256
            'type'    => 'error',
257
        )
258
    );
259
260
    return "<div class='bsui'>$notice</div>";
261
}
262
263
/**
264
 * Generates the current integrations tab URL.
265
 *
266
 * @since 1.0.19
267
 * @param string $tab
268
 * @param string $default
269
 * @return array
270
 */
271
function getpaid_get_tab_url( $tab, $default ) {
272
    global $getpaid_tab_url;
273
274
    if ( empty( $getpaid_tab_url ) ) {
275
        return $default;
276
    }
277
278
    return sprintf( $getpaid_tab_url, $tab );
279
280
}
281
282
/**
283
 * Generates the address edit tab.
284
 *
285
 * @since 2.1.4
286
 * @return string
287
 */
288
function getpaid_display_address_edit_tab() {
289
290
    if ( 0 === get_current_user_id() ) {
291
        return '<div class="bsui">' . aui()->alert(
292
            array(
293
                'type'        => 'error',
294
                'content'     => __( 'Your must be logged in to view this section', 'invoicing' ),
295
                'dismissible' => false,
296
            )
297
        ) . '</div>';
298
    }
299
300
    $customer = getpaid_get_customer_by_user_id( get_current_user_id() );
301
302
    if ( empty( $customer ) ) {
303
        $customer = new GetPaid_Customer( 0 );
304
        $customer->clone_user( get_current_user_id() );
305
        $customer->save();
306
    }
307
308
    ob_start();
309
    ?>
310
        <div class="bsui">
311
            <?php wpinv_print_errors(); ?>
312
            <form method="post" class="getpaid-address-edit-form">
313
314
                <?php
315
316
                    foreach ( getpaid_user_address_fields() as $key => $label ) {
317
318
                        $value = $customer->get( $key );
319
320
					// Display the country.
321
					if ( 'country' == $key ) {
322
323
						aui()->select(
324
							array(
325
								'options'     => wpinv_get_country_list(),
326
								'name'        => 'getpaid_address[' . esc_attr( $key ) . ']',
327
								'id'          => 'wpinv-' . sanitize_html_class( $key ),
328
								'value'       => sanitize_text_field( $value ),
329
								'placeholder' => $label,
330
								'label'       => wp_kses_post( $label ),
331
								'label_type'  => 'vertical',
332
								'class'       => 'getpaid-address-field',
333
                            ),
334
                            true
335
						);
336
337
					}
338
339
					// Display the state.
340
					elseif ( 'state' == $key ) {
341
342
						getpaid_get_states_select_markup(
343
                            $customer->get( 'country' ),
344
							$value,
345
							$label,
346
							$label,
347
							'',
348
							false,
349
							'',
350
							'getpaid_address[' . esc_attr( $key ) . ']',
351
                            true
352
						);
353
354
                        } else {
355
356
						aui()->input(
357
                            array(
358
                                'name'        => 'getpaid_address[' . esc_attr( $key ) . ']',
359
                                'id'          => 'wpinv-' . sanitize_html_class( $key ),
360
                                'placeholder' => $label,
361
                                'label'       => wp_kses_post( $label ),
362
                                'label_type'  => 'vertical',
363
                                'type'        => 'text',
364
                                'value'       => sanitize_text_field( $value ),
365
                                'class'       => 'getpaid-address-field',
366
                            ),
367
                            true
368
						);
369
370
                        }
371
                    }
372
373
                    aui()->input(
374
                        array(
375
                            'name'        => 'getpaid_address[email_cc]',
376
                            'id'          => 'wpinv-email_cc',
377
                            'placeholder' => '[email protected], [email protected]',
378
                            'label'       => __( 'Other email addresses', 'invoicing' ),
379
                            'label_type'  => 'vertical',
380
                            'type'        => 'text',
381
                            'value'       => sanitize_text_field( $customer->get( 'email_cc' ) ),
382
                            'class'       => 'getpaid-address-field',
383
                            'help_text'   => __( 'Optionally provide other email addresses where we should send payment notifications', 'invoicing' ),
384
                        ),
385
                        true
386
                    );
387
388
                    do_action( 'getpaid_display_address_edit_tab' );
389
390
                    aui()->input(
391
                        array(
392
                            'name'      => 'getpaid_profile_edit_submit_button',
393
                            'id'        => 'getpaid_profile_edit_submit_button',
394
                            'value'     => __( 'Save Address', 'invoicing' ),
395
                            'help_text' => __( 'New invoices will use this address as the billing address.', 'invoicing' ),
396
                            'type'      => 'submit',
397
                            'class'     => 'btn btn-primary btn-block submit-button',
398
                        ),
399
                        true
400
                    );
401
402
                    wp_nonce_field( 'getpaid-nonce', 'getpaid-nonce' );
403
                    getpaid_hidden_field( 'getpaid-action', 'edit_billing_details' );
404
                ?>
405
406
            </form>
407
408
        </div>
409
    <?php
410
411
    return ob_get_clean();
412
}
413
add_shortcode( 'getpaid_edit_address', 'getpaid_display_address_edit_tab' );
414
415
/**
416
 * Saves the billing address edit tab.
417
 *
418
 * @since 2.1.4
419
 * @param array $data
420
 */
421
function getpaid_save_address_edit_tab( $data ) {
422
423
    if ( empty( $data['getpaid_address'] ) || ! is_array( $data['getpaid_address'] ) ) {
424
        return;
425
    }
426
427
    $data     = $data['getpaid_address'];
428
    $customer = getpaid_get_customer_by_user_id( get_current_user_id() );
429
430
    if ( empty( $customer ) ) {
431
        $customer = new GetPaid_Customer( 0 );
432
        $customer->clone_user( get_current_user_id() );
433
    }
434
435
    foreach ( array_keys( getpaid_user_address_fields() ) as $field ) {
436
437
        if ( isset( $data[ $field ] ) ) {
438
            $customer->set( $field, sanitize_text_field( $data[ $field ] ) );
439
        }
440
    }
441
442
    if ( isset( $data['email_cc'] ) ) {
443
        $customer->set( 'email_cc', sanitize_text_field( $data['email_cc'] ) );
444
    }
445
446
    $customer->save();
447
    wpinv_set_error( 'address_updated' );
448
}
449
add_action( 'getpaid_authenticated_action_edit_billing_details', 'getpaid_save_address_edit_tab' );
450
451
452
/*
453
 |--------------------------------------------------------------------------
454
 | UsersWP
455
 |--------------------------------------------------------------------------
456
 |
457
 | Functions that integrate GetPaid and UsersWP.
458
*/
459
460
/**
461
 * Add our tabs to UsersWP account tabs.
462
 *
463
 * @since 1.0.19
464
 * @param  array $tabs
465
 * @return array
466
 */
467
function getpaid_filter_userswp_account_tabs( $tabs ) {
468
469
    // Abort if the integration is inactive.
470
    if ( ! getpaid_is_userswp_integration_active() ) {
471
        return $tabs;
472
    }
473
474
    $new_tabs   = array();
475
476
    foreach ( getpaid_get_user_content_tabs() as $slug => $tab ) {
477
478
        $new_tabs[ $slug ] = array(
479
            'title' => $tab['label'],
480
            'icon'  => $tab['icon'],
481
        );
482
483
    }
484
485
    return array_merge( $tabs, $new_tabs );
486
}
487
add_filter( 'uwp_account_available_tabs', 'getpaid_filter_userswp_account_tabs' );
488
489
/**
490
 * Display our UsersWP account tabs.
491
 *
492
 * @since 1.0.19
493
 * @param  array $tabs
494
 * @return array
495
 */
496
function getpaid_display_userswp_account_tabs( $tab ) {
497
    global $getpaid_tab_url;
498
499
    $our_tabs = getpaid_get_user_content_tabs();
500
501
    if ( getpaid_is_userswp_integration_active() && isset( $our_tabs[ $tab ] ) ) {
502
        $getpaid_tab_url = add_query_arg( 'type', '%s', uwp_get_account_page_url() );
503
        echo wp_kses( getpaid_prepare_user_content_tab( $our_tabs[ $tab ] ), getpaid_allowed_html() );
504
    }
505
506
}
507
add_action( 'uwp_account_form_display', 'getpaid_display_userswp_account_tabs' );
508
509
function getpaid_allowed_html() {
510
    $allowed_html = wp_kses_allowed_html( 'post' );
511
512
	// form fields
513
    $allowed_html['form'] = array(
514
        'action'         => true,
515
        'accept'         => true,
516
        'accept-charset' => true,
517
        'enctype'        => true,
518
        'method'         => true,
519
        'name'           => true,
520
        'target'         => true,
521
    );
522
523
    // - input
524
	$allowed_html['input'] = array(
525
		'class'        => array(),
526
		'id'           => array(),
527
		'name'         => array(),
528
		'value'        => array(),
529
		'type'         => array(),
530
        'placeholder'  => array(),
531
        'autocomplete' => array(),
532
        'autofocus'    => array(),
533
        'required'     => array(),
534
        'disabled'     => array(),
535
        'readonly'     => array(),
536
        'checked'      => array(),
537
        'maxlength'    => array(),
538
        'pattern'      => array(),
539
        'min'          => array(),
540
        'max'          => array(),
541
        'step'         => array(),
542
        'size'         => array(),
543
	);
544
545
    // - input
546
	$allowed_html['textarea'] = array(
547
		'class' => array(),
548
		'id'    => array(),
549
		'name'  => array(),
550
		'value' => array(),
551
	);
552
553
	// select
554
	$allowed_html['select'] = array(
555
		'class'        => array(),
556
		'id'           => array(),
557
		'name'         => array(),
558
        'autocomplete' => array(),
559
        'multiple'     => array(),
560
	);
561
562
	// select options
563
	$allowed_html['option'] = array(
564
		'selected' => array(),
565
        'disabled' => array(),
566
        'value'    => array(),
567
	);
568
569
	return $allowed_html;
570
571
}
572
573
/**
574
 * Filters the account page title.
575
 *
576
 * @since  1.0.19
577
 * @param  string $title Current title.
578
 * @param  string $tab   Current tab.
579
 * @return string Title.
580
 */
581
function getpaid_filter_userswp_account_title( $title, $tab ) {
582
583
    $our_tabs   = getpaid_get_user_content_tabs();
584
585
    if ( getpaid_is_userswp_integration_active() && isset( $our_tabs[ $tab ] ) ) {
586
        return $our_tabs[ $tab ]['label'];
587
    }
588
589
    return $title;
590
}
591
add_filter( 'uwp_account_page_title', 'getpaid_filter_userswp_account_title', 10, 2 );
592
593
/**
594
 * Registers the UsersWP integration settings.
595
 *
596
 * @since  1.0.19
597
 * @param  array $settings An array of integration settings.
598
 * @return array
599
 */
600
function getpaid_register_userswp_settings( $settings ) {
601
602
    if ( defined( 'USERSWP_PLUGIN_FILE' ) ) {
603
604
        $settings[] = array(
605
606
            'id'       => 'userswp',
607
            'label'    => __( 'UsersWP', 'invoicing' ),
608
            'settings' => array(
609
610
                'userswp_settings' => array(
611
                    'id'   => 'userswp_settings',
612
                    'name' => '<h3>' . __( 'UsersWP', 'invoicing' ) . '</h3>',
613
                    'type' => 'header',
614
                ),
615
616
                'enable_userswp'   => array(
617
                    'id'   => 'enable_userswp',
618
                    'name' => __( 'Enable Integration', 'invoicing' ),
619
                    'desc' => __( 'Display GetPaid items on UsersWP account page.', 'invoicing' ),
620
                    'type' => 'checkbox',
621
                    'std'  => 1,
622
                ),
623
624
            ),
625
626
        );
627
628
    }
629
630
    return $settings;
631
}
632
add_filter( 'getpaid_integration_settings', 'getpaid_register_userswp_settings' );
633
634
/**
635
 * Ovewrites the invoices history page to UsersWP.
636
 *
637
 * @since  2.3.1
638
 * @return bool
639
 */
640
function getpaid_userswp_overwrite_invoice_history_page( $url, $post_type ) {
641
642
    $our_tabs = getpaid_get_user_content_tabs();
643
    $tab      = "gp-{$post_type}s";
644
    if ( getpaid_is_userswp_integration_active() && isset( $our_tabs[ $tab ] ) ) {
645
        return add_query_arg( 'type', $tab, uwp_get_account_page_url() );
646
    }
647
648
    return $url;
649
650
}
651
add_filter( 'wpinv_get_history_page_uri', 'getpaid_userswp_overwrite_invoice_history_page', 10, 2 );
652
653
/**
654
 * Checks if the integration is enabled.
655
 *
656
 * @since  1.0.19
657
 * @return bool
658
 */
659
function getpaid_is_userswp_integration_active() {
660
    $enabled = wpinv_get_option( 'enable_userswp', 1 );
661
    return defined( 'USERSWP_PLUGIN_FILE' ) && ! empty( $enabled );
662
}
663
664
/*
665
 |--------------------------------------------------------------------------
666
 | BuddyPress
667
 |--------------------------------------------------------------------------
668
 |
669
 | Functions that integrate GetPaid and BuddyPress.
670
*/
671
672
/**
673
 * Registers the BuddyPress integration settings.
674
 *
675
 * @since  2.1.5
676
 * @param  array $settings An array of integration settings.
677
 * @return array
678
 */
679
function getpaid_register_buddypress_settings( $settings ) {
680
681
    if ( class_exists( 'BuddyPress' ) ) {
682
683
        $settings[] = array(
684
685
            'id'       => 'buddypress',
686
            'label'    => __( 'BuddyPress', 'invoicing' ),
687
            'settings' => array(
688
689
                'buddypress_settings' => array(
690
                    'id'   => 'buddypress_settings',
691
                    'name' => '<h3>' . __( 'BuddyPress', 'invoicing' ) . '</h3>',
692
                    'type' => 'header',
693
                ),
694
695
                'enable_buddypress'   => array(
696
                    'id'   => 'enable_buddypress',
697
                    'name' => __( 'Enable Integration', 'invoicing' ),
698
                    'desc' => __( 'Display GetPaid items on BuddyPress account pages.', 'invoicing' ),
699
                    'type' => 'checkbox',
700
                    'std'  => 1,
701
                ),
702
703
            ),
704
705
        );
706
707
    }
708
709
    return $settings;
710
}
711
add_filter( 'getpaid_integration_settings', 'getpaid_register_buddypress_settings' );
712
713
/**
714
 * Checks if the integration is enabled.
715
 *
716
 * @since  2.1.5
717
 * @return bool
718
 */
719
function getpaid_is_buddypress_integration_active() {
720
    $enabled = wpinv_get_option( 'enable_buddypress', 1 );
721
    return class_exists( 'BuddyPress' ) && ! empty( $enabled );
722
}
723
724
/**
725
 * Loads the BuddyPress component.
726
 *
727
 * @since  2.1.5
728
 * @return bool
729
 */
730
function getpaid_setup_buddypress_integration() {
731
732
    if ( getpaid_is_buddypress_integration_active() ) {
733
        require_once WPINV_PLUGIN_DIR . 'includes/class-bp-getpaid-component.php';
734
        buddypress()->getpaid = new BP_GetPaid_Component();
735
    }
736
737
}
738
add_action( 'bp_setup_components', 'getpaid_setup_buddypress_integration' );
739
740
/**
741
 * Checks if a given user has purchased a given item.
742
 *
743
 * @since 2.7.3
744
 * @param int $item_id The item id.
745
 * @return int The IDs of users who purchased the item.
746
 */
747
function getpaid_user_ids_who_purchased_item( $item_id ) {
748
    global $wpdb;
749
750
    if ( empty( $item_id ) ) {
751
        return false;
752
    }
753
754
    $ids = $wpdb->get_col(
755
        $wpdb->prepare(
756
            "SELECT DISTINCT invoices.post_author FROM {$wpdb->prefix}getpaid_invoice_items AS items
757
            INNER JOIN {$wpdb->posts} AS invoices ON invoices.ID = items.post_id
758
            WHERE items.item_id = %d AND invoices.post_status = 'publish'",
759
            $item_id
760
        )
761
    );
762
763
    return wp_parse_id_list( $ids );
764
}
765
766
/**
767
 * Returns an array of user IDs who purchased a given item.
768
 *
769
 * @since 2.6.17
770
 * @param int $user_id The user id.
771
 */
772
function getpaid_has_user_purchased_item( $user_id, $item_id ) {
773
    global $wpdb;
774
775
    if ( empty( $user_id ) ) {
776
        return false;
777
    }
778
779
    $count = $wpdb->get_var(
780
        $wpdb->prepare(
781
            "SELECT COUNT(*) FROM {$wpdb->prefix}getpaid_invoice_items AS items
782
            INNER JOIN {$wpdb->posts} AS invoices ON invoices.ID = items.post_id
783
            WHERE items.item_id = %d AND invoices.post_author = %d AND invoices.post_status = 'publish'
784
            LIMIT 1",
785
            $item_id,
786
            $user_id
787
        )
788
    );
789
790
    return ! empty( $count );
791
}
792
793
/**
794
 * Queries the db for the total spend by a given user ID.
795
 *
796
 * @since 2.6.17
797
 * @param int $user_id The user id.
798
 */
799
function getpaid_get_user_total_spend( $user_id ) {
800
    $args = array(
801
        'data'           => array(
802
803
            'total' => array(
804
                'type'     => 'invoice_data',
805
                'function' => 'SUM',
806
                'name'     => 'total_sales',
807
            ),
808
809
        ),
810
        'where'          => array(
811
812
            'author' => array(
813
                'type'     => 'post_data',
814
                'value'    => absint( $user_id ),
815
                'key'      => 'posts.post_author',
816
                'operator' => '=',
817
            ),
818
819
        ),
820
        'query_type'     => 'get_var',
821
        'invoice_status' => array( 'wpi-renewal', 'wpi-processing', 'publish' ),
822
    );
823
824
    return wpinv_round_amount( GetPaid_Reports_Helper::get_invoice_report_data( $args ) );
825
}
826
827
/**
828
 * Queries the db for the total invoices by a given user ID.
829
 *
830
 * @since 2.6.17
831
 * @param int $user_id The user id.
832
 */
833
function getpaid_count_user_invoices( $user_id ) {
834
    $args = array(
835
        'data'           => array(
836
837
            'ID' => array(
838
                'type'     => 'post_data',
839
                'function' => 'COUNT',
840
                'name'     => 'count',
841
                'distinct' => true,
842
            ),
843
844
        ),
845
        'where'          => array(
846
847
            'author' => array(
848
                'type'     => 'post_data',
849
                'value'    => absint( $user_id ),
850
                'key'      => 'posts.post_author',
851
                'operator' => '=',
852
            ),
853
854
        ),
855
        'query_type'     => 'get_var',
856
        'invoice_status' => array_keys( wpinv_get_invoice_statuses() ),
857
    );
858
859
    return absint( GetPaid_Reports_Helper::get_invoice_report_data( $args ) );
860
}
861
862
/**
863
 * When a user is deleted in WordPress, delete corresponding GetPaid data.
864
 *
865
 * @since 2.8.8
866
 *
867
 * @param int $user_id User ID being deleted.
868
 * @param int|null $reassign ID of the user to reassign posts and links to.
869
 *                           Default null, for no reassignment.
870
 * @param WP_User  $user     WP_User object of the user to delete.
871
 */
872
function getpaid_delete_user_data( $user_id, $reassign, $user ) {
0 ignored issues
show
The parameter $reassign is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

872
function getpaid_delete_user_data( $user_id, /** @scrutinizer ignore-unused */ $reassign, $user ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $user is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

872
function getpaid_delete_user_data( $user_id, $reassign, /** @scrutinizer ignore-unused */ $user ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
873
	global $wpdb;
874
875
	// Delete customer data.
876
	$wpdb->delete(
877
		$wpdb->prefix . 'getpaid_customers',
878
		array(
879
			'user_id' => (int) $user_id,
880
		)
881
	);
882
}
883
add_action( 'delete_user', 'getpaid_delete_user_data', 10, 3 );