· 3 years ago · Nov 16, 2021, 11:01 AM
1<?php
2
3if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5}
6
7class WPF_EDD extends WPF_Integrations_Base {
8
9 /**
10 * The slug for WP Fusion's module tracking.
11 *
12 * @since 3.38.14
13 * @var string $slug
14 */
15
16 public $slug = 'edd';
17
18 /**
19 * The plugin name for WP Fusion's module tracking.
20 *
21 * @since 3.38.14
22 * @var string $name
23 */
24 public $name = 'Easy Digital Downloads';
25
26 /**
27 * The link to the documentation on the WP Fusion website.
28 *
29 * @since 3.38.14
30 * @var string $docs_url
31 */
32 public $docs_url = 'https://wpfusion.com/documentation/ecommerce/edd/';
33
34 /**
35 * Get things started
36 *
37 * @access public
38 * @return void
39 */
40
41 public function init() {
42
43 add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
44 add_filter( 'wpf_meta_field_groups', array( $this, 'add_meta_field_group' ), 10 );
45 add_filter( 'wpf_meta_fields', array( $this, 'prepare_meta_fields' ), 20 );
46 add_action( 'save_post', array( $this, 'save_meta_box_data' ) );
47
48 // Payment status
49 add_Action( 'edd_view_order_details_sidebar_after', array( $this, 'order_details_sidebar' ) );
50 add_action( 'edd_wpf_process', array( $this, 'process_order_again' ) );
51
52 // Payment stuff
53 add_action( 'edd_complete_purchase', array( $this, 'complete_purchase' ) );
54 add_action( 'edd_free_downloads_post_complete_payment', array( $this, 'complete_purchase' ) );
55 add_action( 'wpf_edd_async_checkout', array( $this, 'complete_purchase' ), 10, 2 );
56 add_action( 'edd_post_refund_payment', array( $this, 'refund_complete' ), 10 );
57
58 // Discounts
59 add_action( 'edd_add_discount_form_bottom', array( $this, 'discount_fields' ), 10 );
60 add_action( 'edd_edit_discount_form_bottom', array( $this, 'discount_fields' ), 10 );
61 add_action( 'edd_post_insert_discount', array( $this, 'save_discount' ), 10, 2 );
62 add_action( 'edd_post_update_discount', array( $this, 'save_discount' ), 10, 2 );
63
64 // Discount validity
65 add_filter( 'edd_is_discount_valid', array( $this, 'is_discount_valid' ), 10, 4 );
66
67 // Auto-applied discounts
68 add_action( 'init', array( $this, 'maybe_auto_apply_discounts' ) );
69
70 // Auto-register addon
71 add_action( 'edd_auto_register_insert_user', array( $this, 'auto_register_insert_user' ), 10, 3 );
72
73 // Admin settings.
74 add_filter( 'wpf_configure_settings', array( $this, 'register_settings' ), 15, 2 );
75
76 // WPF hooks
77 add_filter( 'wpf_bypass_profile_update', array( $this, 'bypass_profile_update' ), 10, 2 );
78 add_filter( 'wpf_user_register', array( $this, 'user_register' ) );
79 add_filter( 'wpf_user_update', array( $this, 'user_update' ), 10, 2 );
80
81 // Export functions
82 add_filter( 'wpf_export_options', array( $this, 'export_options' ) );
83 add_filter( 'wpf_batch_edd_init', array( $this, 'batch_init' ) );
84 add_action( 'wpf_batch_edd', array( $this, 'batch_step' ) );
85
86 // Variable price column fields
87 add_action( 'edd_download_price_table_row', array( $this, 'download_table_price_row' ), 10, 3 );
88 add_filter( 'edd_purchase_variable_prices', array( $this, 'purchase_variable_prices' ), 10, 2 );
89
90 // Super secret admin / debugging tools
91 add_action( 'wpf_settings_page_init', array( $this, 'settings_page_init' ) );
92
93 // Email optin
94 add_action( 'edd_purchase_form_user_info_fields', array( $this, 'add_optin_field' ) );
95 add_filter( 'edd_payment_meta', array( $this, 'save_optin_field' ) );
96
97 }
98
99 /**
100 * Save optin field.
101 *
102 * @since 3.37.30
103 *
104 * @return array The payment meta.
105 */
106 public function save_optin_field( $payment_meta ) {
107
108 if ( isset( $_POST['edd_email_optin'] ) ) {
109 $payment_meta['edd_email_optin'] = isset( $_POST['edd_email_optin'] ) ? filter_var( $_POST['edd_email_optin'], FILTER_VALIDATE_BOOLEAN ) : '';
110 }
111
112 return $payment_meta;
113 }
114
115 /**
116 * Add optin field in checkout.
117 *
118 * @since 3.37.30
119 *
120 * @return mixed HTML Output.
121 */
122 public function add_optin_field() {
123
124 if ( ! wpf_get_option( 'edd_email_optin' ) ) {
125 return;
126 }
127
128 if ( 'unchecked' == wpf_get_option( 'edd_email_optin_default' ) ) {
129 $default = false;
130 } else {
131 $default = true;
132 }
133
134 $message = wpf_get_option( 'edd_email_optin_message', __( 'I consent to receive marketing emails', 'wp-fusion' ) );
135
136 echo '
137 <div class="edd-email-optin">
138 <input name="edd_email_optin" type="checkbox" id="edd_email_optin" ' . checked( 1, $default, false ) . '>
139 <label for="edd_email_optin">' . esc_html( $message ) . '</label>
140 </div>
141 ';
142
143 }
144
145
146 /**
147 * Registers additional EDD settings
148 *
149 * @access public
150 * @return array Settings
151 */
152
153 public function register_settings( $settings, $options ) {
154
155 $settings['edd_header'] = array(
156 'title' => __( 'Easy Digital Downloads Integration', 'wp-fusion' ),
157 'type' => 'heading',
158 'section' => 'integrations',
159 );
160
161 $settings['edd_tags'] = array(
162 'title' => __( 'Apply Tags to Customers', 'wp-fusion' ),
163 'desc' => __( 'These tags will be applied to all EDD customers.', 'wp-fusion' ),
164 'std' => array(),
165 'type' => 'assign_tags',
166 'section' => 'integrations',
167 );
168
169 $settings['edd_async'] = array(
170 'title' => __( 'Asynchronous Checkout', 'wp-fusion' ),
171 'desc' => __( 'Runs WP Fusion post-checkout actions asynchronously to speed up load times.', 'wp-fusion' ),
172 'type' => 'checkbox',
173 'section' => 'integrations',
174 );
175
176 $settings['edd_email_optin'] = array(
177 'title' => __( 'Email Optin', 'wp-fusion' ),
178 'desc' => __( 'Display a checkbox on the checkout page where customers can opt-in to receive email marketing.', 'wp-fusion' ),
179 'type' => 'checkbox',
180 'section' => 'integrations',
181 'unlock' => array( 'edd_email_optin_message', 'edd_email_optin_default', 'edd_email_optin_tags' ),
182 );
183
184 $settings['edd_email_optin_message'] = array(
185 'title' => __( 'Email Optin Message', 'wp-fusion' ),
186 'placeholder' => __( 'I consent to receive marketing emails', 'wp-fusion' ),
187 'type' => 'text',
188 'format' => 'html',
189 'section' => 'integrations',
190 );
191
192 $settings['edd_email_optin_default'] = array(
193 'title' => __( 'Email Optin Default', 'wp-fusion' ),
194 'type' => 'select',
195 'std' => 'checked',
196 'choices' => array(
197 'checked' => __( 'Checked', 'wp-fusion' ),
198 'unchecked' => __( 'Un-Checked', 'wp-fusion' ),
199 ),
200 'section' => 'integrations',
201 );
202
203 $settings['edd_email_optin_tags'] = array(
204 'title' => __( 'Email Optin Tags', 'wp-fusion' ),
205 'desc' => __( 'Apply these tags to the customer when the email optin box is checked.', 'wp-fusion' ),
206 'std' => array(),
207 'type' => 'assign_tags',
208 'section' => 'integrations',
209 );
210
211 return $settings;
212
213 }
214
215
216 /**
217 * Adds EDD field group to meta fields list
218 *
219 * @access public
220 * @return array Field groups
221 */
222
223 public function add_meta_field_group( $field_groups ) {
224
225 $field_groups['edd'] = array(
226 'title' => 'Easy Digital Downloads',
227 'fields' => array(),
228 );
229
230 return $field_groups;
231
232 }
233
234 /**
235 * Sets field labels and types for EDD custom fields
236 *
237 * @access public
238 * @return array Meta fields
239 */
240
241 public function prepare_meta_fields( $meta_fields ) {
242
243 $meta_fields['billing_address_1'] = array(
244 'label' => 'Billing Address 1',
245 'type' => 'text',
246 'group' => 'edd',
247 );
248
249 $meta_fields['billing_address_2'] = array(
250 'label' => 'Billing Address 2',
251 'type' => 'text',
252 'group' => 'edd',
253 );
254
255 $meta_fields['billing_city'] = array(
256 'label' => 'Billing City',
257 'type' => 'text',
258 'group' => 'edd',
259 );
260
261 $meta_fields['billing_state'] = array(
262 'label' => 'Billing State',
263 'type' => 'text',
264 'group' => 'edd',
265 );
266
267 $meta_fields['billing_country'] = array(
268 'label' => 'Billing Country',
269 'type' => 'text',
270 'group' => 'edd',
271 );
272
273 $meta_fields['billing_postcode'] = array(
274 'label' => 'Billing Postcode',
275 'type' => 'text',
276 'group' => 'edd',
277 );
278
279 $meta_fields['customer_id'] = array(
280 'label' => 'Customer ID',
281 'type' => 'integer',
282 'group' => 'edd',
283 'pseudo' => true,
284 );
285
286 $meta_fields['order_date'] = array(
287 'label' => 'Last Order Date',
288 'type' => 'date',
289 'group' => 'edd',
290 'pseudo' => true,
291 );
292
293 $meta_fields['edd_email_optin'] = array(
294 'label' => 'Email Optin',
295 'type' => 'checkbox',
296 'group' => 'edd',
297 'pseudo' => true,
298 );
299
300 return $meta_fields;
301
302 }
303
304 /**
305 * Triggered at user registration to adapt EDD fields to WP standard
306 *
307 * @access public
308 * @return array Post Data
309 */
310
311 public function user_register( $post_data ) {
312
313 // Trim "edd_" from the beginning of each key
314 foreach ( $post_data as $key => $value ) {
315 if ( substr( $key, 0, 4 ) == 'edd_' ) {
316 $key = substr( $key, 4 );
317 $post_data[ $key ] = $value;
318 unset( $post_data[ 'edd_' . $key ] );
319 }
320 }
321
322 $field_map = array(
323 'email' => 'user_email',
324 'first' => 'first_name',
325 'last' => 'last_name',
326 );
327
328 $post_data = $this->map_meta_fields( $post_data, $field_map );
329
330 return $post_data;
331
332 }
333
334 /**
335 * Extracts EDD payment fields from EDD meta array and explodes for use in pushing meta data
336 *
337 * @access public
338 * @return array User Meta
339 */
340
341 public function user_update( $user_meta, $user_id ) {
342
343 if ( ! empty( $user_meta['_edd_user_address'] ) ) {
344
345 $edd_user_address = maybe_unserialize( $user_meta['_edd_user_address'] );
346
347 $user_meta['billing_address_1'] = $edd_user_address['line1'];
348 $user_meta['billing_address_2'] = $edd_user_address['line2'];
349 $user_meta['billing_city'] = $edd_user_address['city'];
350 $user_meta['billing_state'] = $edd_user_address['state'];
351 $user_meta['billing_country'] = $edd_user_address['country'];
352 $user_meta['billing_postcode'] = $edd_user_address['zip'];
353
354 } else {
355
356 $field_map = array(
357 'edd_first_name' => 'first_name',
358 'edd_last_name' => 'last_name',
359 'edd_display_name' => 'display_name',
360 'edd_email' => 'user_email',
361 'edd_address_line1' => 'billing_address_1',
362 'edd_address_line2' => 'billing_address_2',
363 'edd_address_city' => 'billing_city',
364 'edd_address_state' => 'billing_state',
365 'edd_address_zip' => 'billing_postcode',
366 'edd_address_country' => 'billing_country',
367 'edd_new_user_pass1' => 'user_pass',
368 );
369
370 $user_meta = $this->map_meta_fields( $user_meta, $field_map );
371
372 }
373
374 return $user_meta;
375
376 }
377
378 /**
379 * Maybe bypass the profile_update hook in WPF_User if it's an EDD checkout
380 *
381 * @access public
382 * @return bool Bypass
383 */
384
385 public function bypass_profile_update( $bypass, $request ) {
386
387 if ( ! empty( $request ) && isset( $request['edd_action'] ) && $request['edd_action'] == 'purchase' ) {
388 $bypass = true;
389 }
390
391 return $bypass;
392
393 }
394
395 /**
396 * Triggered when an order is completed. Updates contact record (or creates it) and applies tags
397 *
398 * @access public
399 * @return void
400 */
401
402 public function complete_purchase( $payment_id, $doing_async = false, $force = false ) {
403
404 // Defer until next page if async checkout is enabled
405 if ( ! is_admin() && wpf_get_option( 'edd_async' ) == true && $doing_async == false ) {
406
407 wp_fusion()->batch->quick_add( 'wpf_edd_async_checkout', array( $payment_id, true ) );
408 return;
409
410 }
411
412 $payment = new EDD_Payment( $payment_id );
413
414 if ( empty( $payment->downloads ) ) { // EDD Free Downloads runs a bit later than normal, for some reason
415 return;
416 }
417
418 // Prevents the API calls being sent multiple times for the same order
419 $wpf_complete = $payment->get_meta( 'wpf_complete', true );
420
421 if ( ! empty( $wpf_complete ) && $force == false ) {
422 return true;
423 }
424 // We don't need to sync the meta data during a renewal order
425 $send_meta = true;
426
427 if ( 'edd_subscription' == get_post_status( $payment_id ) && ! wpf_is_field_active( 'order_date' ) ) {
428 $send_meta = false;
429 }
430
431 // Get user info
432 $payment_meta = $payment->get_meta();
433
434 $user_meta = array(
435 'user_email' => $payment_meta['email'],
436 'first_name' => $payment_meta['user_info']['first_name'],
437 'last_name' => $payment_meta['user_info']['last_name'],
438 'customer_id' => $payment->customer_id,
439 'order_date' => $payment->get_meta( '_edd_completed_date' ),
440 'edd_email_optin' => ! empty( $payment_meta['edd_email_optin'] ) ? true : false,
441 );
442
443 // Address fields
444 if ( ! empty( $payment_meta['user_info']['address'] ) ) {
445
446 $user_meta['billing_address_1'] = $payment_meta['user_info']['address']['line1'];
447 $user_meta['billing_address_2'] = $payment_meta['user_info']['address']['line2'];
448 $user_meta['billing_city'] = $payment_meta['user_info']['address']['city'];
449 $user_meta['billing_state'] = $payment_meta['user_info']['address']['state'];
450 $user_meta['billing_country'] = $payment_meta['user_info']['address']['country'];
451 $user_meta['billing_postcode'] = $payment_meta['user_info']['address']['zip'];
452
453 }
454
455 // See if the user already exists locally
456 $user_id = $payment->user_id;
457
458 // Make sure user exists
459 $user = get_userdata( $user_id );
460
461 if ( $user === false ) {
462 $user_id = 0;
463 }
464
465 if ( (int) $user_id < 1 ) {
466
467 // Guest checkouts
468 $contact_id = wp_fusion()->crm->get_contact_id( $user_meta['user_email'] );
469
470 if ( empty( $contact_id ) ) {
471
472 // New contact
473 wpf_log(
474 'info',
475 0,
476 'New EDD guest checkout. Order <a href="' . admin_url( 'edit.php?post_type=download&page=edd-payment-history&view=view-order-details&id=' . $payment_id ) . '">#' . $payment_id . '</a> ',
477 array(
478 'meta_array' => $user_meta,
479 'source' => 'edd',
480 )
481 );
482
483 // Create contact and add note
484 $contact_id = wp_fusion()->crm->add_contact( $user_meta );
485
486 if ( is_wp_error( $contact_id ) ) {
487
488 $payment->add_note( 'Error creating contact in ' . wp_fusion()->crm->name . ': ' . $contact_id->get_error_message() );
489
490 wpf_log( 'error', 0, 'Error creating contact in ' . wp_fusion()->crm->name . ': ' . $contact_id->get_error_message() );
491
492 return false;
493
494 } else {
495
496 $payment->add_note( wp_fusion()->crm->name . ' contact ID ' . $contact_id . ' created via guest checkout.' );
497
498 }
499 } else {
500
501 // Existing contact
502 wpf_log(
503 'info',
504 0,
505 'New EDD guest checkout. Order <a href="' . admin_url( 'edit.php?post_type=download&page=edd-payment-history&view=view-order-details&id=' . $payment_id ) . '">#' . $payment_id . '</a>, for existing contact ID ' . $contact_id . ': ',
506 array(
507 'meta_array' => $user_meta,
508 'source' => 'edd',
509 )
510 );
511
512 wp_fusion()->crm->update_contact( $contact_id, $user_meta );
513
514 }
515 } else {
516
517 // Registered user checkouts
518 wpf_log( 'info', $user_id, 'New EDD order <a href="' . admin_url( 'edit.php?post_type=download&page=edd-payment-history&view=view-order-details&id=' . $payment_id ) . '">#' . $payment_id . '</a>', array( 'source' => 'edd' ) );
519
520 $contact_id = wp_fusion()->user->get_contact_id( $user_id );
521
522 if ( empty( $contact_id ) ) {
523
524 // If no contact record for the user, create one
525 $contact_id = wp_fusion()->user->user_register( $user_id, $user_meta, true );
526
527 $payment->add_note( wp_fusion()->crm->name . ' contact ID ' . $contact_id . ' created.' );
528
529 } elseif ( true == $send_meta ) {
530
531 // If contact is found for user, update their info (but not during a renewal payment)
532 wp_fusion()->user->push_user_meta( $user_id, $user_meta );
533
534 }
535 }
536
537 // Store the contact ID for future operations
538 $payment->update_meta( wp_fusion()->crm->slug . '_contact_id', $contact_id );
539
540 // Apply tags
541 $apply_tags = array();
542
543 $global_tags = wpf_get_option( 'edd_tags', array() );
544
545 if ( ! empty( $global_tags ) ) {
546 $apply_tags = array_merge( $apply_tags, $global_tags );
547 }
548
549 foreach ( $payment_meta['cart_details'] as $item ) {
550
551 $wpf_settings = get_post_meta( $item['id'], 'wpf-settings-edd', true );
552
553 if ( empty( $wpf_settings ) ) {
554 continue;
555 }
556
557 if ( isset( $wpf_settings['apply_tags'] ) ) {
558 $apply_tags = array_merge( $apply_tags, $wpf_settings['apply_tags'] );
559 }
560
561 // Variable pricing tags
562 if ( isset( $wpf_settings['apply_tags_price'] ) && ! empty( $item['item_number']['options']['price_id'] ) ) {
563
564 $price_id = $item['item_number']['options']['price_id'];
565
566 if ( isset( $wpf_settings['apply_tags_price'][ $price_id ] ) ) {
567
568 $apply_tags = array_merge( $apply_tags, $wpf_settings['apply_tags_price'][ $price_id ] );
569
570 }
571 }
572 }
573
574 if ( function_exists( 'edd_get_adjustment_meta' ) ) {
575
576 $discounts = $payment->discounts;
577
578 if ( ! is_array( $discounts ) ) {
579 $discounts = explode( ',', $discounts );
580 }
581
582 foreach ( $discounts as $code ) {
583
584 if ( $code == 'none' || ! edd_get_discount_by_code( $code ) ) {
585 continue;
586 }
587
588 $disc = edd_get_discount_by_code( $code );
589
590 $settings = edd_get_adjustment_meta( $disc->ID, 'wpf_settings', true );
591
592 if ( empty( $settings ) || empty( $settings['apply_tags'] ) ) {
593 continue;
594 }
595
596 $apply_tags = array_merge( $apply_tags, $settings['apply_tags'] );
597
598 }
599 }
600
601 // Email optin.
602 if ( wpf_get_option( 'edd_email_optin' ) && ! empty( $payment_meta['edd_email_optin'] ) ) {
603 $apply_tags = array_merge( $apply_tags, wpf_get_option( 'edd_email_optin_tags', array() ) );
604 }
605
606 // Remove duplicates and empties
607 $apply_tags = array_filter( array_unique( $apply_tags ) );
608
609 // Filter
610 $apply_tags = apply_filters( 'wpf_edd_apply_tags_checkout', $apply_tags, $payment );
611
612 // Guest checkout
613 if ( (int) $user_id < 1 ) {
614
615 if ( ! empty( $apply_tags ) ) {
616
617 // Logging
618 wpf_log(
619 'info',
620 0,
621 'EDD guest checkout applying tags: ',
622 array(
623 'tag_array' => $apply_tags,
624 'source' => 'edd',
625 )
626 );
627
628 wp_fusion()->crm->apply_tags( $apply_tags, $contact_id );
629
630 }
631 } else {
632
633 wp_fusion()->user->apply_tags( $apply_tags, $user_id );
634
635 }
636
637 // Denotes that the WPF actions have already run for this payment
638 $payment->update_meta( 'wpf_complete', true );
639
640 // Run payment complete action
641 do_action( 'wpf_edd_payment_complete', $payment_id, $contact_id );
642
643 }
644
645 /**
646 * Output settings on the discount add / edit screen
647 *
648 * @access public
649 * @return bool
650 */
651
652 public function discount_fields( $discount_id = false ) {
653
654 $defaults = array(
655 'allow_tags' => array(),
656 'auto_apply_tags' => array(),
657 'discount_label' => false,
658 'apply_tags' => array(),
659 );
660
661 if ( false != $discount_id ) {
662
663 // Compatible with pre and > 3.0
664
665 $discount = edd_get_discount( $discount_id );
666 $settings = $discount->get_meta( 'wpf_settings', true );
667
668 }
669
670 if ( empty( $settings ) ) {
671 $settings = array();
672 }
673
674 $settings = array_merge( $defaults, $settings );
675
676 ?>
677
678 <hr />
679
680 <h2><?php _e( 'WP Fusion - Discount Settings', 'wp-fusion' ); ?></h2>
681
682 <table class="form-table">
683
684 <tr>
685 <th scope="row" valign="top">
686 <label for="wpf_settings-allow_tags"><?php _e( 'Required Tags', 'wp-fusion' ); ?></label>
687 </th>
688 <td>
689
690 <?php
691
692 $args = array(
693 'setting' => $settings['allow_tags'],
694 'meta_name' => 'wpf_settings',
695 'field_id' => 'allow_tags',
696 'read_only' => true,
697 );
698
699 wpf_render_tag_multiselect( $args );
700
701 ?>
702
703 <p class="description"><?php _e( 'If specified a user must be logged in and have the selected tags to use the discount.', 'wp-fusion' ); ?></p>
704 </td>
705 </tr>
706
707 <tr>
708 <th scope="row" valign="top">
709 <label for="wpf_settings-auto_apply_tags"><?php _e( 'Auto-apply Tags', 'wp-fusion' ); ?></label>
710 </th>
711 <td>
712
713 <?php
714
715 $args = array(
716 'setting' => $settings['auto_apply_tags'],
717 'meta_name' => 'wpf_settings',
718 'field_id' => 'auto_apply_tags',
719 'read_only' => true,
720 );
721
722 wpf_render_tag_multiselect( $args );
723
724 ?>
725
726 <p class="description"><?php _e( 'If the user has any of the tags specified here, the discount will automatically be applied to their cart.', 'wp-fusion' ); ?></p>
727 </td>
728 </tr>
729
730 <tr>
731 <th scope="row" valign="top">
732 <label for="wpf_settings-auto_apply_tags"><?php _e( 'Discount Label', 'wp-fusion' ); ?></label>
733 </th>
734 <td>
735
736 <input type="text" class="short" style="" name="wpf_settings[discount_label]" value="<?php echo $settings['discount_label']; ?>" >
737
738 <p class="description"><?php _e( 'When using auto-applied coupons you can enter an alternative label here and it will be displayed instead of the coupon code at checkout (for example "Loyalty Discount").', 'wp-fusion' ); ?></p>
739 </td>
740 </tr>
741
742 <tr>
743 <th scope="row" valign="top">
744 <label for="wpf_settings-apply_tags"><?php _e( 'Apply Tags', 'wp-fusion' ); ?></label>
745 </th>
746 <td>
747
748 <?php
749
750 $args = array(
751 'setting' => $settings['apply_tags'],
752 'meta_name' => 'wpf_settings',
753 'field_id' => 'apply_tags',
754 );
755
756 wpf_render_tag_multiselect( $args );
757
758 ?>
759
760 <p class="description"><?php echo sprintf( __( 'The selected tags will be applied in %s when the discount is used.', 'wp-fusion' ), wp_fusion()->crm->name ); ?></p>
761 </td>
762 </tr>
763
764 </table>
765
766 <hr />
767
768 <?php
769
770 }
771
772 /**
773 * Save changes to discount settings
774 *
775 * @access public
776 * @return void
777 */
778
779 public function save_discount( $meta, $discount_id ) {
780
781 if ( ! empty( $_POST['wpf_settings'] ) ) {
782
783 // Compatible with pre and > 3.0
784
785 $discount = edd_get_discount( $discount_id );
786 $discount->update_meta( 'wpf_settings', $_POST['wpf_settings'] );
787
788 } else {
789
790 // There isn't yet a $discount->delete_meta() so we'll wait for 3.0
791
792 delete_post_meta( $discount_id, '_edd_discount_wpf_settings' );
793
794 }
795
796 }
797
798 /**
799 * Allows using tags to restrict access to EDD discounts
800 *
801 * @access public
802 * @return bool
803 */
804
805 public function is_discount_valid( $is_valid, $discount_id, $code, $lookup_user ) {
806
807 // If no user, EDD is checking general validity, not specific user's access
808 if ( ! $lookup_user ) {
809 return $is_valid;
810 }
811
812 // If it's already not valid, we don't need to ask WPF about it
813 if ( ! $is_valid ) {
814 return $is_valid;
815 }
816
817 $discount = edd_get_discount( $discount_id );
818 $settings = $discount->get_meta( 'wpf_settings', true );
819
820 if ( empty( $settings ) || empty( $settings['allow_tags'] ) ) {
821 return $is_valid;
822 }
823
824 $is_valid = false;
825
826 if ( ! wpf_is_user_logged_in() ) {
827
828 edd_set_error(
829 'edd-discount-error',
830 __( 'You must be logged in to use this discount code.', 'wp-fusion' )
831 );
832
833 } else {
834
835 $user_tags = wp_fusion()->user->get_tags();
836
837 if ( ! empty( array_intersect( $user_tags, $settings['allow_tags'] ) ) ) {
838
839 $is_valid = true;
840
841 } else {
842
843 edd_set_error(
844 'edd-discount-error',
845 __( 'You do not have access to use this discount code.', 'wp-fusion' )
846 );
847
848 }
849 }
850
851 return $is_valid;
852
853 }
854
855 /**
856 * Applies any auto-applied discounts based on the user's tags.
857 *
858 * @since 3.37.22
859 *
860 * @param bool|Arrat $user_tags The user's tags.
861 */
862
863 public function maybe_auto_apply_discounts( $user_tags = false ) {
864
865 $cart_items = edd_get_cart_contents();
866 $user_id = wpf_get_current_user_id();
867
868 if ( empty( $cart_items ) || ( false == $user_id && false == $user_tags ) ) {
869 return;
870 }
871
872 if ( false == $user_tags ) {
873 $user_tags = wp_fusion()->user->get_tags();
874 }
875
876 if ( empty( $user_tags ) ) {
877 return;
878 }
879
880 $args = array(
881 'post_status' => 'active',
882 'fields' => 'ids',
883 'meta_query' => array(
884 array(
885 'key' => '_edd_discount_wpf_settings',
886 'compare' => 'EXISTS',
887 ),
888 ),
889 );
890
891 $discounts = edd_get_discounts( $args );
892
893 if ( empty( $discounts ) ) {
894 return;
895 }
896
897 foreach ( $discounts as $discount_id ) {
898
899 $discount = edd_get_discount( $discount_id );
900 $settings = $discount->get_meta( 'wpf_settings', true );
901
902 if ( empty( $settings['auto_apply_tags'] ) ) {
903 continue;
904 }
905
906 if ( ! empty( array_intersect( $user_tags, $settings['auto_apply_tags'] ) ) ) {
907
908 // The user has the tag
909
910 $should_apply = apply_filters( 'wpf_auto_apply_coupon_for_user', true, $discount_id, wpf_get_current_user_id() );
911
912 if ( $should_apply && edd_is_discount_valid( $discount->get_code(), wpf_get_current_user_id() ) ) {
913
914 edd_set_cart_discount( $discount->get_code() );
915
916 // Maybe override the label
917
918 if ( ! empty( $settings['discount_label'] ) ) {
919
920 add_filter(
921 'edd_get_cart_discount_html',
922 function( $discount_html, $discount, $rate, $remove_url ) use ( &$settings ) {
923
924 return str_replace( $discount, $settings['discount_label'], $discount_html );
925
926 },
927 10,
928 4
929 );
930
931 }
932
933 return;
934 }
935 }
936 }
937
938 }
939
940 /**
941 * Triggered when an order is refunded. Updates contact record and removes original purchase tags / applies refund tags if applicable
942 *
943 * @access public
944 * @return void
945 */
946
947 public function refund_complete( $payment ) {
948
949 $remove_tags = array();
950 $apply_tags_refunded = array();
951
952 $payment_meta = $payment->get_meta();
953
954 foreach ( $payment_meta['cart_details'] as $item ) {
955
956 $wpf_settings = get_post_meta( $item['id'], 'wpf-settings-edd', true );
957
958 if ( empty( $wpf_settings ) ) {
959 continue;
960 }
961
962 if ( isset( $wpf_settings['apply_tags'] ) ) {
963 $remove_tags = array_merge( $remove_tags, $wpf_settings['apply_tags'] );
964
965 }
966
967 if ( isset( $wpf_settings['apply_tags_refunded'] ) ) {
968 $apply_tags_refunded = array_merge( $apply_tags_refunded, $wpf_settings['apply_tags_refunded'] );
969 }
970
971 // Variable pricing tags
972 if ( isset( $wpf_settings['apply_tags_price'] ) && ! empty( $item['item_number']['options']['price_id'] ) ) {
973
974 $price_id = $item['item_number']['options']['price_id'];
975
976 if ( isset( $wpf_settings['apply_tags_price'][ $price_id ] ) ) {
977
978 $remove_tags = array_merge( $remove_tags, $wpf_settings['apply_tags_price'][ $price_id ] );
979
980 }
981 }
982
983 // Variable pricing tags: refund tag
984 if ( isset( $wpf_settings['apply_tags_refund_price'] ) && ! empty( $item['item_number']['options']['price_id'] ) ) {
985
986 $price_id = $item['item_number']['options']['price_id'];
987
988 if ( isset( $wpf_settings['apply_tags_refund_price'][ $price_id ] ) ) {
989
990 $apply_tags_refunded = array_merge( $apply_tags_refunded, $wpf_settings['apply_tags_refund_price'][ $price_id ] );
991
992 }
993 }
994 }
995
996 $user_id = $payment->user_id;
997
998 // Guest checkout
999 if ( (int) $user_id < 1 ) {
1000
1001 $contact_id = $payment->get_meta( wp_fusion()->crm->slug . '_contact_id', true );
1002
1003 if ( empty( $contact_id ) ) {
1004
1005 $user_email = $payment_meta['email'];
1006 $contact_id = wp_fusion()->crm->get_contact_id( $user_email );
1007
1008 }
1009
1010 if ( ! is_wp_error( $contact_id ) && ! empty( $contact_id ) ) {
1011
1012 if ( ! empty( $remove_tags ) ) {
1013 wp_fusion()->crm->remove_tags( $remove_tags, $contact_id );
1014 }
1015
1016 if ( ! empty( $apply_tags_refunded ) ) {
1017 wp_fusion()->crm->apply_tags( $apply_tags_refunded, $contact_id );
1018 }
1019 }
1020 } else {
1021
1022 if ( ! empty( $remove_tags ) ) {
1023 wp_fusion()->user->remove_tags( $remove_tags, $user_id );
1024 }
1025
1026 if ( ! empty( $apply_tags_refunded ) ) {
1027 wp_fusion()->user->apply_tags( $apply_tags_refunded, $user_id );
1028 }
1029 }
1030
1031 }
1032
1033 /**
1034 * Sync data from auto registered users
1035 *
1036 * @access public
1037 * @return void
1038 */
1039
1040 public function auto_register_insert_user( $user_id, $user_args, $payment_id ) {
1041
1042 wp_fusion()->user->push_user_meta( $user_id, array( 'user_pass' => $user_args['user_pass'] ) );
1043
1044 }
1045
1046
1047 /**
1048 * Outputs WPF fields to variable price rows
1049 *
1050 * @access public
1051 * @return mixed HTML Output
1052 */
1053
1054 public function download_table_price_row( $post_id, $key, $args ) {
1055
1056 echo '<div class="edd-custom-price-option-section">';
1057
1058 echo '<span class="edd-custom-price-option-section-title">' . __( 'WP Fusion Settings', 'wp-fusion' ) . '</span>';
1059
1060 $settings = array(
1061 'apply_tags_price' => array(),
1062 'apply_tags_refund_price' => array(),
1063 );
1064
1065 if ( get_post_meta( $post_id, 'wpf-settings-edd', true ) ) {
1066 $settings = array_merge( $settings, get_post_meta( $post_id, 'wpf-settings-edd', true ) );
1067 }
1068
1069 if ( empty( $settings['apply_tags_price'][ $key ] ) ) {
1070 $settings['apply_tags_price'][ $key ] = array();
1071 }
1072
1073 if ( empty( $settings['apply_tags_refund_price'][ $key ] ) ) {
1074 $settings['apply_tags_refund_price'][ $key ] = array();
1075 }
1076
1077 if ( empty( $settings['allow_tags_price'][ $key ] ) ) {
1078 $settings['allow_tags_price'][ $key ] = array();
1079 }
1080
1081 echo '<div style="width:48%; padding: 0px; display:inline-block;">';
1082 echo '<label>' . __( 'Apply tags when purchased', 'wp-fusion' ) . ':</label>';
1083 wpf_render_tag_multiselect(
1084 array(
1085 'setting' => $settings['apply_tags_price'][ $key ],
1086 'meta_name' => "wpf-settings-edd[apply_tags_price][{$key}]",
1087 )
1088 );
1089 echo '</div>';
1090
1091 echo '<div style="width:48%; padding: 0px; display:inline-block;">';
1092 echo '<label>' . __( 'Apply tags when refunded', 'wp-fusion' ) . ':</label>';
1093 wpf_render_tag_multiselect(
1094 array(
1095 'setting' => $settings['apply_tags_refund_price'][ $key ],
1096 'meta_name' => "wpf-settings-edd[apply_tags_refund_price][{$key}]",
1097 )
1098 );
1099 echo '</div>';
1100
1101 echo '<div style="width:48%; padding: 0px; display:inline-block; margin-top: 10px;">';
1102 echo '<label>' . __( 'Restrict access tags', 'wp-fusion' ) . ':</label>';
1103 wpf_render_tag_multiselect(
1104 array(
1105 'setting' => $settings['allow_tags_price'][ $key ],
1106 'meta_name' => "wpf-settings-edd[allow_tags_price][{$key}]",
1107 )
1108 );
1109 echo '<span class="description"><em>' . __( 'If the user doesn\'t have <em>any</em> of these tags, the price ID will not show as an option for purchase.', 'wp-fusion' ) . '</em></span>';
1110 echo '</div>';
1111
1112 echo '</div>';
1113
1114 }
1115
1116
1117 /**
1118 * Allow hiding a price ID by tag
1119 *
1120 * @access public
1121 * @return array Prices
1122 */
1123
1124 public function purchase_variable_prices( $prices, $download_id ) {
1125
1126 $settings = get_post_meta( $download_id, 'wpf-settings-edd', true );
1127
1128 foreach ( $prices as $price_id => $data ) {
1129
1130 if ( isset( $settings['allow_tags_price'] ) && ! empty( $settings['allow_tags_price'][ $price_id ] ) ) {
1131
1132 $can_access = true;
1133
1134 if ( ! wpf_is_user_logged_in() ) {
1135
1136 $can_access = false;
1137
1138 } else {
1139
1140 $user_tags = wp_fusion()->user->get_tags();
1141
1142 if ( empty( array_intersect( $user_tags, $settings['allow_tags_price'][ $price_id ] ) ) ) {
1143 $can_access = false;
1144 }
1145 }
1146
1147 if ( current_user_can( 'manage_options' ) && wpf_get_option( 'exclude_admins' ) == true ) {
1148 $can_access = true;
1149 }
1150
1151 $can_access = apply_filters( 'wpf_user_can_access', $can_access, wpf_get_current_user_id(), $price_id );
1152
1153 if ( ! $can_access ) {
1154 unset( $prices[ $price_id ] );
1155 }
1156 }
1157 }
1158
1159 return $prices;
1160
1161 }
1162
1163
1164 /**
1165 * Registers meta box
1166 *
1167 * @access public
1168 * @return voic
1169 */
1170
1171 public function add_meta_box() {
1172
1173 add_meta_box(
1174 'wpf-edd-meta',
1175 __( 'WP Fusion Download Settings', 'wp-fusion' ),
1176 array(
1177 $this,
1178 'meta_box_callback',
1179 ),
1180 'download',
1181 'normal',
1182 'default'
1183 );
1184
1185 }
1186
1187 /**
1188 * Displays meta box content
1189 *
1190 * @access public
1191 * @return mixed
1192 */
1193
1194 public function meta_box_callback( $post ) {
1195
1196 // Add an nonce field so we can check for it later.
1197 wp_nonce_field( 'wpf_meta_box_edd', 'wpf_meta_box_edd_nonce' );
1198
1199 $settings = array(
1200 'apply_tags' => array(),
1201 'apply_tags_refunded' => array(),
1202 );
1203
1204 if ( get_post_meta( $post->ID, 'wpf-settings-edd', true ) ) {
1205 $settings = array_merge( $settings, get_post_meta( $post->ID, 'wpf-settings-edd', true ) );
1206 }
1207
1208 echo '<table class="form-table wpf-edd-settings"><tbody>';
1209
1210 echo '<tr>';
1211
1212 echo '<th scope="row"><label for="apply_tags">' . __( 'Apply Tags', 'wp-fusion' ) . ':</label></th>';
1213 echo '<td>';
1214 wpf_render_tag_multiselect(
1215 array(
1216 'setting' => $settings['apply_tags'],
1217 'meta_name' => 'wpf-settings-edd',
1218 'field_id' => 'apply_tags',
1219 )
1220 );
1221 echo '<span class="description">' . sprintf( __( 'Apply these tags in %s when purchased.', 'wp-fusion' ), wp_fusion()->crm->name ) . '</span>';
1222 echo '</td>';
1223
1224 echo '</tr>';
1225
1226 echo '<tr>';
1227
1228 echo '<th scope="row"><label for="apply_tags_refunded">' . __( 'Refund Tags', 'wp-fusion' ) . ':</label></th>';
1229 echo '<td>';
1230 wpf_render_tag_multiselect(
1231 array(
1232 'setting' => $settings['apply_tags_refunded'],
1233 'meta_name' => 'wpf-settings-edd',
1234 'field_id' => 'apply_tags_refunded',
1235 )
1236 );
1237 echo '<span class="description">' . sprintf( __( 'Apply these tags in %s when refunded.', 'wp-fusion' ), wp_fusion()->crm->name ) . '</span>';
1238 echo '</td>';
1239
1240 echo '</tr>';
1241
1242 do_action( 'wpf_edd_meta_box_inner', $post, $settings );
1243
1244 echo '</tbody></table>';
1245
1246 // Allows other plugins to add additional fields to meta box
1247 do_action( 'wpf_edd_meta_box', $post, $settings );
1248
1249 }
1250
1251 /**
1252 * Saves WPF configuration to product
1253 *
1254 * @access public
1255 * @return mixed
1256 */
1257
1258 public function save_meta_box_data( $post_id ) {
1259
1260 // Check if our nonce is set.
1261 if ( ! isset( $_POST['wpf_meta_box_edd_nonce'] ) ) {
1262 return;
1263 }
1264
1265 // Verify that the nonce is valid.
1266 if ( ! wp_verify_nonce( $_POST['wpf_meta_box_edd_nonce'], 'wpf_meta_box_edd' ) ) {
1267 return;
1268 }
1269
1270 // If this is an autosave, our form has not been submitted, so we don't want to do anything.
1271 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
1272 return;
1273 }
1274
1275 // Don't update on revisions
1276 if ( $_POST['post_type'] == 'revision' ) {
1277 return;
1278 }
1279
1280 if ( isset( $_POST['wpf-settings-edd'] ) ) {
1281 $data = $_POST['wpf-settings-edd'];
1282
1283 } else {
1284 $data = array();
1285 }
1286
1287 // Update the meta field in the database.
1288 update_post_meta( $post_id, 'wpf-settings-edd', $data );
1289
1290 }
1291
1292
1293 /**
1294 * Outputs WP Fusion details to the payment meta box.
1295 *
1296 * @since 3.36
1297 *
1298 * @param int $payment_id The payment identifier.
1299 */
1300 public function order_details_sidebar( $payment_id ) {
1301
1302 $payment = new EDD_Payment( $payment_id );
1303
1304 ?>
1305
1306 <div id="edd-wpf-status" class="postbox edd-wpf-status">
1307
1308 <h3 class="hndle">
1309 <span><?php _e( 'WP Fusion', 'wp-fusion' ); ?></span>
1310 </h3>
1311 <div class="edd-admin-box">
1312
1313 <div class="edd-order-wpf-status edd-admin-box-inside">
1314
1315 <p>
1316 <span class="label"><?php printf( __( 'Synced to %s:', 'wp-fusion' ), wp_fusion()->crm->name ); ?></span>
1317
1318 <?php if ( get_post_meta( $payment_id, 'wpf_complete', true ) ) : ?>
1319 <span><?php _e( 'Yes', 'wp-fusion' ); ?></span>
1320 <span class="dashicons dashicons-yes-alt"></span>
1321 <?php else : ?>
1322 <span><?php _e( 'No', 'wp-fusion' ); ?></span>
1323 <span class="dashicons dashicons-no"></span>
1324 <?php endif; ?>
1325 </p>
1326
1327 </div>
1328
1329 <?php $contact_id = $payment->get_meta( wp_fusion()->crm->slug . '_contact_id' ); ?>
1330
1331 <?php if ( $contact_id ) : ?>
1332
1333 <div class="edd-order-wpf-status edd-admin-box-inside">
1334
1335 <p>
1336 <span class="label"><?php _e( 'Contact ID:', 'wp-fusion' ); ?></span>
1337 <span><?php echo $contact_id; ?></span>
1338
1339 <?php $url = wp_fusion()->crm_base->get_contact_edit_url( $contact_id ); ?>
1340 <?php if ( false !== $url ) : ?>
1341 - <a href="<?php echo $url; ?>" target="_blank"><?php _e( 'View', 'wp-fusion' ); ?> →</a>
1342 <?php endif; ?>
1343
1344 </p>
1345
1346 </div>
1347
1348 <?php endif; ?>
1349
1350 <?php if ( wpf_get_option( 'edd_email_optin' ) ) : ?>
1351
1352 <div class="edd-order-wpf-status edd-admin-box-inside">
1353 <p>
1354 <span class="label"><?php _e( 'Opted In:', 'wp-fusion' ); ?></span>
1355
1356 <?php if ( get_post_meta( $payment_id, 'edd_email_optin', true ) ) : ?>
1357 <span><?php _e( 'Yes', 'wp-fusion' ); ?></span>
1358 <span class="dashicons dashicons-yes-alt"></span>
1359 <?php else : ?>
1360 <span><?php _e( 'No', 'wp-fusion' ); ?></span>
1361 <span class="dashicons dashicons-no"></span>
1362 <?php endif; ?>
1363 </p>
1364 </div>
1365
1366 <?php endif; ?>
1367
1368 <?php if ( class_exists( 'WP_Fusion_Ecommerce' ) ) : ?>
1369
1370 <div class="edd-order-wpf-status edd-admin-box-inside">
1371
1372 <p>
1373 <span class="label"><?php printf( __( 'Enhanced Ecommerce:', 'wp-fusion' ), wp_fusion()->crm->name ); ?></span>
1374
1375 <?php if ( $payment->get_meta( 'wpf_ec_complete', true ) ) : ?>
1376 <span><?php _e( 'Yes', 'wp-fusion' ); ?></span>
1377 <span class="dashicons dashicons-yes-alt"></span>
1378 <?php else : ?>
1379 <span><?php _e( 'No', 'wp-fusion' ); ?></span>
1380 <span class="dashicons dashicons-no"></span>
1381 <?php endif; ?>
1382 </p>
1383
1384 </div>
1385
1386 <?php $invoice_id = $payment->get_meta( 'wpf_ec_' . wp_fusion()->crm->slug . '_invoice_id' ); ?>
1387
1388 <?php if ( $invoice_id ) : ?>
1389
1390 <div class="edd-order-wpf-status edd-admin-box-inside">
1391
1392 <p>
1393 <span class="label"><?php _e( 'Invoice ID:', 'wp-fusion' ); ?></span>
1394 <span><?php echo $invoice_id; ?></span>
1395 </p>
1396
1397 </div>
1398
1399
1400 <?php endif; ?>
1401
1402 <?php endif; ?>
1403
1404 <div class="edd-order-wpf-status edd-admin-box-inside">
1405
1406 <p>
1407 <a href="
1408 <?php
1409 echo esc_url(
1410 add_query_arg(
1411 array(
1412 'edd-action' => 'wpf_process',
1413 'purchase_id' => $payment_id,
1414 )
1415 )
1416 );
1417 ?>
1418 " class="wpf-action-button button-secondary"><?php _e( 'Process WP Fusion actions again ', 'wp-fusion' ); ?></a>
1419 </p>
1420
1421 </div>
1422
1423 </div>
1424
1425 </div>
1426
1427
1428 <?php
1429
1430 }
1431
1432 /**
1433 * Re-processes a single payment.
1434 *
1435 * @since 3.36
1436 *
1437 * @param array $data The data
1438 */
1439 public function process_order_again( $data ) {
1440
1441 $payment_id = absint( $data['purchase_id'] );
1442
1443 if ( empty( $payment_id ) ) {
1444 return;
1445 }
1446
1447 if ( ! current_user_can( 'edit_shop_payments' ) ) {
1448 wp_die( __( 'You do not have permission to edit this payment record', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
1449 }
1450
1451 $payment = new EDD_Payment( $payment_id );
1452
1453 $payment->delete_meta( 'wpf_complete' );
1454 $payment->delete_meta( 'wpf_ec_complete' );
1455
1456 $this->complete_purchase( $payment_id );
1457
1458 }
1459
1460 /**
1461 * //
1462 * // EXPORT TOOLS
1463 * //
1464 **/
1465
1466 /**
1467 * Adds EDD checkbox to available export options
1468 *
1469 * @access public
1470 * @return array Options
1471 */
1472
1473 public function export_options( $options ) {
1474
1475 $options['edd'] = array(
1476 'label' => __( 'Easy Digital Downloads orders', 'wp-fusion' ),
1477 'title' => __( 'Orders', 'wp-fusion' ),
1478 'tooltip' => __( 'Finds EDD orders that have not been processed by WP Fusion, and adds/updates contacts while applying tags based on the products purchased', 'wp-fusion' ),
1479 );
1480
1481 return $options;
1482
1483 }
1484
1485 /**
1486 * Counts total number of orders to be processed
1487 *
1488 * @access public
1489 * @return array Payments
1490 */
1491
1492 public function batch_init() {
1493
1494 $args = array(
1495 'number' => -1,
1496 'fields' => 'ids',
1497 'meta_query' => array(
1498 array(
1499 'key' => 'wpf_complete',
1500 'compare' => 'NOT EXISTS',
1501 ),
1502 ),
1503 );
1504
1505 $payments = edd_get_payments( $args );
1506
1507 return $payments;
1508
1509 }
1510
1511 /**
1512 * Processes payments actions in batches
1513 *
1514 * @access public
1515 * @return void
1516 */
1517
1518 public function batch_step( $payment_id ) {
1519
1520 $this->complete_purchase( $payment_id );
1521
1522 }
1523
1524
1525 /**
1526 * Support utilities
1527 *
1528 * @access public
1529 * @return void
1530 */
1531
1532 public function settings_page_init() {
1533
1534 if ( isset( $_GET['edd_reset_wpf_complete'] ) ) {
1535
1536 $args = array(
1537 'number' => -1,
1538 'fields' => 'ids',
1539 'meta_query' => array(
1540 array(
1541 'key' => 'wpf_complete',
1542 'compare' => 'EXISTS',
1543 ),
1544 ),
1545 );
1546
1547 $payments = edd_get_payments( $args );
1548
1549 foreach ( $payments as $payment_id ) {
1550 delete_post_meta( $payment_id, 'wpf_complete' );
1551 }
1552
1553 echo '<div id="setting-error-settings_updated" class="updated settings-error"><p><strong>Success:</strong><code>wpf_complete</code> meta key removed from ' . count( $payments ) . ' orders.</p></div>';
1554
1555 }
1556
1557 }
1558
1559}
1560
1561new WPF_EDD();
1562