CustomerSyncService.php
| 1 | <?php |
| 2 | |
| 3 | |
| 4 | namespace SureCart\Background; |
| 5 | |
| 6 | use SureCart\Models\Customer; |
| 7 | use SureCart\Models\Purchase; |
| 8 | use SureCart\Models\User; |
| 9 | |
| 10 | /** |
| 11 | * Syncs customer records to WordPress users. |
| 12 | */ |
| 13 | class CustomerSyncService { |
| 14 | /** |
| 15 | * Bootstrap any actions. |
| 16 | * |
| 17 | * @return void |
| 18 | */ |
| 19 | public function bootstrap() { |
| 20 | add_action( 'surecart/sync/customers', [ $this, 'sync' ], 10, 4 ); |
| 21 | add_action( 'admin_notices', [ $this, 'showSyncNotice' ] ); |
| 22 | } |
| 23 | |
| 24 | /** |
| 25 | * Is this sync running. |
| 26 | * |
| 27 | * @return boolean |
| 28 | */ |
| 29 | public function isRunning() { |
| 30 | return as_has_scheduled_action( 'surecart/sync/customer' ) || as_has_scheduled_action( 'surecart/sync/customers' ); |
| 31 | } |
| 32 | |
| 33 | /** |
| 34 | * Show an admin notice if customers are being synced. |
| 35 | * |
| 36 | * @return void |
| 37 | */ |
| 38 | public function showSyncNotice() { |
| 39 | if ( ! $this->isRunning() ) { |
| 40 | return; |
| 41 | } |
| 42 | |
| 43 | echo wp_kses_post( |
| 44 | \SureCart::notices()->render( |
| 45 | [ |
| 46 | 'type' => 'info', |
| 47 | 'title' => esc_html__( 'SureCart customer sync in progress', 'surecart' ), |
| 48 | 'text' => '<p>' . esc_html__( 'SureCart is syncing customers in the background. The process may take a little while, so please be patient.', 'surecart' ) . '</p>', |
| 49 | ] |
| 50 | ) |
| 51 | ); |
| 52 | } |
| 53 | |
| 54 | /** |
| 55 | * Sync customers. |
| 56 | * |
| 57 | * @param string $page Current page. |
| 58 | * @param integer $batch_size Batch size. |
| 59 | * @param boolean $create_user Create user. |
| 60 | * @param boolean $run_actions Run actions. |
| 61 | * |
| 62 | * @return void |
| 63 | */ |
| 64 | public function sync( $page, $batch_size, $create_user, $run_actions ) { |
| 65 | // get customers. |
| 66 | $customers = Customer::with( [ 'purchases' ] )->paginate( |
| 67 | [ |
| 68 | 'per_page' => $batch_size, |
| 69 | 'page' => $page, |
| 70 | ] |
| 71 | ); |
| 72 | |
| 73 | // enqueue actions to sync an individual customer. |
| 74 | foreach ( $customers->data as $customer ) { |
| 75 | $this->syncCustomer( $customer, $create_user, $run_actions ); |
| 76 | } |
| 77 | |
| 78 | $total_pages = ceil( $customers->pagination->count / $customers->pagination->limit ); |
| 79 | // if the total number of pages less than or equal to the current page, we don't have another page. |
| 80 | if ( $total_pages <= $customers->pagination->page ) { |
| 81 | // we don't have another page. |
| 82 | return; |
| 83 | } |
| 84 | |
| 85 | // get the next batch. |
| 86 | return as_enqueue_async_action( |
| 87 | 'surecart/sync/customers', |
| 88 | [ |
| 89 | 'page' => $page + 1, |
| 90 | 'batch_size' => $batch_size, |
| 91 | 'create_user' => $create_user, |
| 92 | 'run_actions' => $run_actions, |
| 93 | ], |
| 94 | 'surecart' |
| 95 | ); |
| 96 | } |
| 97 | |
| 98 | /** |
| 99 | * Sync an individual customer. |
| 100 | * |
| 101 | * @param \SureCart\Models\Customer $customer Customer. |
| 102 | * @param boolean $create_user Create user. |
| 103 | * @param boolean $run_actions Run actions. |
| 104 | * |
| 105 | * @return \SureCart\Models\Customer|\WP_Error |
| 106 | */ |
| 107 | public function syncCustomer( $customer, $create_user, $run_actions ) { |
| 108 | if ( ! $customer || is_wp_error( $customer ) ) { |
| 109 | return $customer; |
| 110 | } |
| 111 | |
| 112 | // Create or link a user. |
| 113 | $user = $customer->getUser(); |
| 114 | if ( ! $user ) { |
| 115 | $user = User::getUserBy( 'email', $customer->email ); |
| 116 | if ( $user ) { |
| 117 | $user->setCustomerId( $customer->id, $customer->live_mode ? 'live' : 'test', true ); // force update. |
| 118 | } elseif ( $create_user ) { |
| 119 | $customer->createUser(); |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | // run purchase actions. |
| 124 | if ( $run_actions ) { |
| 125 | $unrevoked_purchases = array_filter( |
| 126 | $customer->purchases->data ?? [], |
| 127 | function( $purchase ) { |
| 128 | return ! $purchase->revoked; |
| 129 | } |
| 130 | ); |
| 131 | |
| 132 | // A customer has more than the 20 purchases that are expanded, we need to fetch the rest. |
| 133 | if ( ! empty( $customer->purchases->pagination->count ) && $customer->purchases->pagination->count > $customer->purchases->pagination->limit ) { |
| 134 | // get 100 purchases. |
| 135 | $unrevoked_purchases = Purchase::where( |
| 136 | [ |
| 137 | 'customer_id' => $customer->id, |
| 138 | 'revoked' => false, |
| 139 | ] |
| 140 | )->get(); |
| 141 | } |
| 142 | |
| 143 | foreach ( $unrevoked_purchases as $purchase ) { |
| 144 | if ( $purchase->getWPUser() ) { |
| 145 | do_action( 'surecart/purchase_invoked', $purchase ); |
| 146 | } |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | return $customer; |
| 151 | } |
| 152 | } |
| 153 |