woocommerce /
woocommerce-gateway-stripe
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | if ( ! defined( 'ABSPATH' ) ) { |
||
| 3 | exit; |
||
| 4 | } |
||
| 5 | |||
| 6 | /** |
||
| 7 | * WC_Stripe_Customer class. |
||
| 8 | * |
||
| 9 | * Represents a Stripe Customer. |
||
| 10 | */ |
||
| 11 | class WC_Stripe_Customer { |
||
| 12 | |||
| 13 | /** |
||
| 14 | * Stripe customer ID |
||
| 15 | * @var string |
||
| 16 | */ |
||
| 17 | private $id = ''; |
||
| 18 | |||
| 19 | /** |
||
| 20 | * WP User ID |
||
| 21 | * @var integer |
||
| 22 | */ |
||
| 23 | private $user_id = 0; |
||
| 24 | |||
| 25 | /** |
||
| 26 | * Data from API |
||
| 27 | * @var array |
||
| 28 | */ |
||
| 29 | private $customer_data = array(); |
||
| 30 | |||
| 31 | /** |
||
| 32 | * Constructor |
||
| 33 | * @param int $user_id The WP user ID |
||
| 34 | */ |
||
| 35 | public function __construct( $user_id = 0 ) { |
||
| 36 | if ( $user_id ) { |
||
| 37 | $this->set_user_id( $user_id ); |
||
| 38 | $this->set_id( get_user_meta( $user_id, '_stripe_customer_id', true ) ); |
||
| 39 | } |
||
| 40 | } |
||
| 41 | |||
| 42 | /** |
||
| 43 | * Get Stripe customer ID. |
||
| 44 | * @return string |
||
| 45 | */ |
||
| 46 | public function get_id() { |
||
| 47 | return $this->id; |
||
| 48 | } |
||
| 49 | |||
| 50 | /** |
||
| 51 | * Set Stripe customer ID. |
||
| 52 | * @param [type] $id [description] |
||
| 53 | */ |
||
| 54 | public function set_id( $id ) { |
||
| 55 | $this->id = wc_clean( $id ); |
||
| 56 | } |
||
| 57 | |||
| 58 | /** |
||
| 59 | * User ID in WordPress. |
||
| 60 | * @return int |
||
| 61 | */ |
||
| 62 | public function get_user_id() { |
||
| 63 | return absint( $this->user_id ); |
||
| 64 | } |
||
| 65 | |||
| 66 | /** |
||
| 67 | * Set User ID used by WordPress. |
||
| 68 | * @param int $user_id |
||
| 69 | */ |
||
| 70 | public function set_user_id( $user_id ) { |
||
| 71 | $this->user_id = absint( $user_id ); |
||
| 72 | } |
||
| 73 | |||
| 74 | /** |
||
| 75 | * Get user object. |
||
| 76 | * @return WP_User |
||
| 77 | */ |
||
| 78 | protected function get_user() { |
||
| 79 | return $this->get_user_id() ? get_user_by( 'id', $this->get_user_id() ) : false; |
||
| 80 | } |
||
| 81 | |||
| 82 | /** |
||
| 83 | * Store data from the Stripe API about this customer |
||
| 84 | */ |
||
| 85 | public function set_customer_data( $data ) { |
||
| 86 | $this->customer_data = $data; |
||
| 87 | } |
||
| 88 | |||
| 89 | /** |
||
| 90 | * Get data from the Stripe API about this customer |
||
| 91 | */ |
||
| 92 | public function get_customer_data() { |
||
| 93 | $this->customer_data = get_transient( 'stripe_customer_' . $this->get_id() ); |
||
| 94 | |||
| 95 | if ( empty( $this->customer_data ) && $this->get_id() && false === $this->customer_data ) { |
||
| 96 | $response = WC_Stripe_API::request( array(), 'customers/' . $this->get_id() ); |
||
| 97 | |||
| 98 | if ( empty( $response->error ) ) { |
||
| 99 | $this->set_customer_data( $response ); |
||
| 100 | set_transient( 'stripe_customer_' . $this->get_id(), $response, HOUR_IN_SECONDS * 48 ); |
||
| 101 | } |
||
| 102 | } |
||
| 103 | |||
| 104 | return $this->customer_data; |
||
| 105 | } |
||
| 106 | |||
| 107 | /** |
||
| 108 | * Get default card/source |
||
| 109 | * @return string |
||
| 110 | */ |
||
| 111 | public function get_default_source() { |
||
| 112 | $data = $this->get_customer_data(); |
||
| 113 | $source = ''; |
||
| 114 | |||
| 115 | if ( $data ) { |
||
| 116 | $source = $data->default_source; |
||
| 117 | } |
||
| 118 | |||
| 119 | return $source; |
||
| 120 | } |
||
| 121 | |||
| 122 | /** |
||
| 123 | * Create a customer via API. |
||
| 124 | * @param array $args |
||
| 125 | * @return WP_Error|int |
||
| 126 | */ |
||
| 127 | public function create_customer( $args = array() ) { |
||
| 128 | $billing_email = filter_var( $_POST['billing_email'], FILTER_SANITIZE_EMAIL ); |
||
| 129 | $user = $this->get_user(); |
||
| 130 | |||
| 131 | if ( $user ) { |
||
| 132 | $billing_first_name = get_user_meta( $user->ID, 'billing_first_name', true ); |
||
| 133 | $billing_last_name = get_user_meta( $user->ID, 'billing_last_name', true ); |
||
| 134 | |||
| 135 | $defaults = array( |
||
| 136 | 'email' => $user->user_email, |
||
| 137 | 'description' => $billing_first_name . ' ' . $billing_last_name, |
||
| 138 | ); |
||
| 139 | } else { |
||
| 140 | $defaults = array( |
||
| 141 | 'email' => ! empty( $billing_email ) ? $billing_email : '', |
||
| 142 | 'description' => '', |
||
| 143 | ); |
||
| 144 | } |
||
| 145 | |||
| 146 | $metadata = array(); |
||
| 147 | |||
| 148 | $defaults['metadata'] = apply_filters( 'wc_stripe_customer_metadata', $metadata, $user ); |
||
| 149 | |||
| 150 | $args = wp_parse_args( $args, $defaults ); |
||
| 151 | $response = WC_Stripe_API::request( apply_filters( 'wc_stripe_create_customer_args', $args ), 'customers' ); |
||
| 152 | |||
| 153 | if ( ! empty( $response->error ) ) { |
||
| 154 | throw new Exception( $response->error->message ); |
||
| 155 | } |
||
| 156 | |||
| 157 | $this->set_id( $response->id ); |
||
| 158 | $this->clear_cache(); |
||
| 159 | $this->set_customer_data( $response ); |
||
| 160 | |||
| 161 | if ( $this->get_user_id() ) { |
||
| 162 | update_user_meta( $this->get_user_id(), '_stripe_customer_id', $response->id ); |
||
| 163 | } |
||
| 164 | |||
| 165 | do_action( 'woocommerce_stripe_add_customer', $args, $response ); |
||
| 166 | |||
| 167 | return $response->id; |
||
| 168 | } |
||
| 169 | |||
| 170 | /** |
||
| 171 | * Add a source for this stripe customer. |
||
| 172 | * @param string $source_id |
||
| 173 | * @param bool $retry |
||
| 174 | * @return WP_Error|int |
||
| 175 | */ |
||
| 176 | public function add_source( $source_id, $retry = true ) { |
||
|
0 ignored issues
–
show
|
|||
| 177 | if ( ! $this->get_id() ) { |
||
| 178 | $this->create_customer(); |
||
| 179 | } |
||
| 180 | |||
| 181 | $response = WC_Stripe_API::request( array( |
||
|
0 ignored issues
–
show
|
|||
| 182 | 'source' => $source_id, |
||
| 183 | ), 'customers/' . $this->get_id() . '/sources' ); |
||
| 184 | |||
| 185 | if ( ! empty( $response->error ) ) { |
||
| 186 | // It is possible the WC user once was linked to a customer on Stripe |
||
| 187 | // but no longer exists. Instead of failing, lets try to create a |
||
| 188 | // new customer. |
||
| 189 | if ( preg_match( '/No such customer/i', $response->error->message ) ) { |
||
| 190 | delete_user_meta( $this->get_user_id(), '_stripe_customer_id' ); |
||
| 191 | $this->create_customer(); |
||
| 192 | return $this->add_source( $source_id, false ); |
||
| 193 | } else { |
||
| 194 | return $response; |
||
| 195 | } |
||
| 196 | } elseif ( empty( $response->id ) ) { |
||
| 197 | return new WP_Error( 'error', __( 'Unable to add payment source.', 'woocommerce-gateway-stripe' ) ); |
||
| 198 | } |
||
| 199 | |||
| 200 | // Add token to WooCommerce. |
||
| 201 | if ( $this->get_user_id() && class_exists( 'WC_Payment_Token_CC' ) ) { |
||
| 202 | if ( ! empty( $response->type ) ) { |
||
| 203 | switch ( $response->type ) { |
||
| 204 | case 'alipay': |
||
| 205 | break; |
||
| 206 | case 'sepa_debit': |
||
| 207 | $wc_token = new WC_Payment_Token_SEPA(); |
||
| 208 | $wc_token->set_token( $response->id ); |
||
| 209 | $wc_token->set_gateway_id( 'stripe_sepa' ); |
||
| 210 | $wc_token->set_last4( $response->sepa_debit->last4 ); |
||
| 211 | break; |
||
| 212 | default: |
||
| 213 | if ( 'source' === $response->object && 'card' === $response->type ) { |
||
| 214 | $wc_token = new WC_Payment_Token_CC(); |
||
| 215 | $wc_token->set_token( $response->id ); |
||
| 216 | $wc_token->set_gateway_id( 'stripe' ); |
||
| 217 | $wc_token->set_card_type( strtolower( $response->card->brand ) ); |
||
| 218 | $wc_token->set_last4( $response->card->last4 ); |
||
| 219 | $wc_token->set_expiry_month( $response->card->exp_month ); |
||
| 220 | $wc_token->set_expiry_year( $response->card->exp_year ); |
||
| 221 | } |
||
| 222 | break; |
||
| 223 | } |
||
| 224 | } else { |
||
| 225 | // Legacy. |
||
| 226 | $wc_token = new WC_Payment_Token_CC(); |
||
| 227 | $wc_token->set_token( $response->id ); |
||
| 228 | $wc_token->set_gateway_id( 'stripe' ); |
||
| 229 | $wc_token->set_card_type( strtolower( $response->brand ) ); |
||
| 230 | $wc_token->set_last4( $response->last4 ); |
||
| 231 | $wc_token->set_expiry_month( $response->exp_month ); |
||
| 232 | $wc_token->set_expiry_year( $response->exp_year ); |
||
| 233 | } |
||
| 234 | |||
| 235 | $wc_token->set_user_id( $this->get_user_id() ); |
||
|
0 ignored issues
–
show
The variable
$wc_token does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
Loading history...
|
|||
| 236 | $wc_token->save(); |
||
| 237 | } |
||
| 238 | |||
| 239 | $this->clear_cache(); |
||
| 240 | |||
| 241 | do_action( 'woocommerce_stripe_add_source', $this->get_id(), $wc_token, $response, $source_id ); |
||
| 242 | |||
| 243 | return $response->id; |
||
| 244 | } |
||
| 245 | |||
| 246 | /** |
||
| 247 | * Get a customers saved sources using their Stripe ID. Cached. |
||
| 248 | * |
||
| 249 | * @param string $customer_id |
||
| 250 | * @return array |
||
| 251 | */ |
||
| 252 | public function get_sources() { |
||
| 253 | $sources = get_transient( 'stripe_sources_' . $this->get_id() ); |
||
| 254 | |||
| 255 | if ( false === $sources ) { |
||
| 256 | $response = WC_Stripe_API::request( array( |
||
| 257 | 'limit' => 100, |
||
| 258 | ), 'customers/' . $this->get_id() . '/sources', 'GET' ); |
||
| 259 | |||
| 260 | if ( ! empty( $response->error ) ) { |
||
| 261 | return array(); |
||
| 262 | } |
||
| 263 | |||
| 264 | if ( is_array( $response->data ) ) { |
||
| 265 | $sources = $response->data; |
||
| 266 | } |
||
| 267 | |||
| 268 | set_transient( 'stripe_sources_' . $this->get_id(), $sources, HOUR_IN_SECONDS * 24 ); |
||
| 269 | } |
||
| 270 | |||
| 271 | return empty( $sources ) ? array() : $sources; |
||
| 272 | } |
||
| 273 | |||
| 274 | /** |
||
| 275 | * Delete a source from stripe. |
||
| 276 | * @param string $source_id |
||
| 277 | */ |
||
| 278 | View Code Duplication | public function delete_source( $source_id ) { |
|
| 279 | $response = WC_Stripe_API::request( array(), 'customers/' . $this->get_id() . '/sources/' . sanitize_text_field( $source_id ), 'DELETE' ); |
||
| 280 | |||
| 281 | $this->clear_cache(); |
||
| 282 | |||
| 283 | if ( empty( $response->error ) ) { |
||
| 284 | do_action( 'wc_stripe_delete_source', $this->get_id(), $response ); |
||
| 285 | |||
| 286 | return true; |
||
| 287 | } |
||
| 288 | |||
| 289 | return false; |
||
| 290 | } |
||
| 291 | |||
| 292 | /** |
||
| 293 | * Set default source in Stripe |
||
| 294 | * @param string $source_id |
||
| 295 | */ |
||
| 296 | View Code Duplication | public function set_default_source( $source_id ) { |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 297 | $response = WC_Stripe_API::request( array( |
||
| 298 | 'default_source' => sanitize_text_field( $source_id ), |
||
| 299 | ), 'customers/' . $this->get_id(), 'POST' ); |
||
| 300 | |||
| 301 | $this->clear_cache(); |
||
| 302 | |||
| 303 | if ( empty( $response->error ) ) { |
||
| 304 | do_action( 'wc_stripe_set_default_source', $this->get_id(), $response ); |
||
| 305 | |||
| 306 | return true; |
||
| 307 | } |
||
| 308 | |||
| 309 | return false; |
||
| 310 | } |
||
| 311 | |||
| 312 | /** |
||
| 313 | * Deletes caches for this users cards. |
||
| 314 | */ |
||
| 315 | public function clear_cache() { |
||
| 316 | delete_transient( 'stripe_sources_' . $this->get_id() ); |
||
| 317 | delete_transient( 'stripe_customer_' . $this->get_id() ); |
||
| 318 | $this->customer_data = array(); |
||
| 319 | } |
||
| 320 | } |
||
| 321 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.