Completed
Push — master ( 42374d...0c4fbd )
by Mike
08:16
created

WC_Shortcode_My_Account::edit_address()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 40
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
dl 0
loc 40
rs 4.909
c 0
b 0
f 0
eloc 26
nc 9
nop 1
1
<?php
2
/**
3
 * My Account Shortcodes
4
 *
5
 * Shows the 'my account' section where the customer can view past orders and update their information.
6
 *
7
 * @author 		WooThemes
8
 * @category 	Shortcodes
9
 * @package 	WooCommerce/Shortcodes/My_Account
10
 * @version     2.0.0
11
 */
12
class WC_Shortcode_My_Account {
13
14
	/**
15
	 * Get the shortcode content.
16
	 *
17
	 * @param array $atts
18
	 * @return string
19
	 */
20
	public static function get( $atts ) {
21
		return WC_Shortcodes::shortcode_wrapper( array( __CLASS__, 'output' ), $atts );
22
	}
23
24
	/**
25
	 * Output the shortcode.
26
	 *
27
	 * @param array $atts
28
	 */
29
	public static function output( $atts ) {
30
		global $wp;
31
32
		// Check cart class is loaded or abort
33
		if ( is_null( WC()->cart ) ) {
34
			return;
35
		}
36
37
		if ( ! is_user_logged_in() ) {
38
			$message = apply_filters( 'woocommerce_my_account_message', '' );
39
40
			if ( ! empty( $message ) ) {
41
				wc_add_notice( $message );
42
			}
43
44
			if ( isset( $wp->query_vars['lost-password'] ) ) {
45
				self::lost_password();
46
			} else {
47
				wc_get_template( 'myaccount/form-login.php' );
48
			}
49
	 	} else {
50
			// See if showing an account endpoint
51
			foreach ( $wp->query_vars as $key => $value ) {
52
				// Ignore pagename param.
53
				if ( 'pagename' === $key ) {
54
					continue;
55
				}
56
				if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) {
57
					do_action( 'woocommerce_account_' . $key . '_endpoint', $value );
58
					return;
59
				}
60
			}
61
62
			// No endpoint? Show main account page.
63
			self::my_account( $atts );
64
		}
65
	}
66
67
	/**
68
	 * My account page.
69
	 *
70
	 * @param array $atts
71
	 */
72
	private static function my_account( $atts ) {
73
		extract( shortcode_atts( array(
74
	    	'order_count' => 15 // @deprecated 2.6.0. Keep for backward compatibility.
75
		), $atts ) );
76
77
		wc_get_template( 'myaccount/my-account.php', array(
78
			'current_user' => get_user_by( 'id', get_current_user_id() ),
79
			'order_count'  => 'all' == $order_count ? -1 : $order_count
80
		) );
81
	}
82
83
	/**
84
	 * View order page.
85
	 *
86
	 * @param int $order_id
87
	 */
88
	public static function view_order( $order_id ) {
89
90
		$user_id = get_current_user_id();
0 ignored issues
show
Unused Code introduced by
$user_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
91
		$order   = wc_get_order( $order_id );
92
93 View Code Duplication
		if ( ! current_user_can( 'view_order', $order_id ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
94
			echo '<div class="woocommerce-error">' . __( 'Invalid order.', 'woocommerce' ) . ' <a href="' . wc_get_page_permalink( 'myaccount' ).'" class="wc-forward">'. __( 'My Account', 'woocommerce' ) .'</a>' . '</div>';
95
			return;
96
		}
97
98
		// Backwards compatibility
99
		$status       = new stdClass();
100
		$status->name = wc_get_order_status_name( $order->get_status() );
101
102
		wc_get_template( 'myaccount/view-order.php', array(
103
	        'status'    => $status, // @deprecated 2.2
104
	        'order'     => wc_get_order( $order_id ),
105
	        'order_id'  => $order_id
106
	    ) );
107
	}
108
109
	/**
110
	 * Edit account details page.
111
	 */
112
	public static function edit_account() {
113
		wc_get_template( 'myaccount/form-edit-account.php', array( 'user' => get_user_by( 'id', get_current_user_id() ) ) );
114
	}
115
116
	/**
117
	 * Edit address page.
118
	 *
119
	 * @param string $load_address
120
	 */
121
	public static function edit_address( $load_address = 'billing' ) {
122
		$current_user = wp_get_current_user();
123
		$load_address = sanitize_key( $load_address );
124
125
		$address = WC()->countries->get_address_fields( get_user_meta( get_current_user_id(), $load_address . '_country', true ), $load_address . '_' );
126
127
		// Enqueue scripts
128
		wp_enqueue_script( 'wc-country-select' );
129
		wp_enqueue_script( 'wc-address-i18n' );
130
131
		// Prepare values
132
		foreach ( $address as $key => $field ) {
133
134
			$value = get_user_meta( get_current_user_id(), $key, true );
135
136
			if ( ! $value ) {
137
				switch( $key ) {
138
					case 'billing_email' :
139
					case 'shipping_email' :
140
						$value = $current_user->user_email;
141
					break;
142
					case 'billing_country' :
143
					case 'shipping_country' :
144
						$value = WC()->countries->get_base_country();
145
					break;
146
					case 'billing_state' :
147
					case 'shipping_state' :
148
						$value = WC()->countries->get_base_state();
149
					break;
150
				}
151
			}
152
153
			$address[ $key ]['value'] = apply_filters( 'woocommerce_my_account_edit_address_field_value', $value, $key, $load_address );
154
		}
155
156
		wc_get_template( 'myaccount/form-edit-address.php', array(
157
			'load_address' 	=> $load_address,
158
			'address'		=> apply_filters( 'woocommerce_address_to_edit', $address )
159
		) );
160
	}
161
162
	/**
163
	 * Lost password page handling.
164
	 */
165
	public static function lost_password() {
166
		/**
167
		 * Process reset key / login from email confirmation link
168
		 */
169
		if ( ! empty( $_GET['key'] ) && ! empty( $_GET['login'] ) ) {
170
171
			$user = self::check_password_reset_key( $_GET['key'], $_GET['login'] );
172
173
			// reset key / login is correct, display reset password form with hidden key / login values
174
			if ( is_object( $user ) ) {
175
				return wc_get_template( 'myaccount/form-reset-password.php', array(
176
					'key'   => wc_clean( $_GET['key'] ),
177
					'login' => wc_clean( $_GET['login'] ),
178
				) );
179
			}
180
181
		/**
182
		 * After sending the reset link, don't show the form again.
183
		 */
184
	 	} elseif ( ! empty( $_GET['reset-link-sent'] ) ) {
185
			return wc_get_template( 'myaccount/lost-password-confirmation.php' );
186
187
		/**
188
		 * After reset, show confirmation message.
189
		 */
190
	 	} elseif ( ! empty( $_GET['reset'] ) ) {
191
			wc_add_notice( __( 'Your password has been reset.', 'woocommerce' ) . ' <a class="button" href="' . esc_url( wc_get_page_permalink( 'myaccount' ) ) . '">' . __( 'Log in', 'woocommerce' ) . '</a>' );
192
		}
193
194
		// Show lost password form by default
195
		wc_get_template( 'myaccount/form-lost-password.php', array(
196
			'form'  => 'lost_password',
197
		) );
198
	}
199
200
	/**
201
	 * Handles sending password retrieval email to customer.
202
	 *
203
	 * Based on retrieve_password() in core wp-login.php.
204
	 *
205
	 * @uses $wpdb WordPress Database object
206
	 * @return bool True: when finish. False: on error
207
	 */
208
	public static function retrieve_password() {
209
		global $wpdb, $wp_hasher;
210
211
		$login = trim( $_POST['user_login'] );
212
213
		if ( empty( $login ) ) {
214
215
			wc_add_notice( __( 'Enter a username or e-mail address.', 'woocommerce' ), 'error' );
216
			return false;
217
218
		} else {
219
			// Check on username first, as customers can use emails as usernames.
220
			$user_data = get_user_by( 'login', $login );
221
		}
222
223
		// If no user found, check if it login is email and lookup user based on email.
224
		if ( ! $user_data && is_email( $login ) && apply_filters( 'woocommerce_get_username_from_email', true ) ) {
225
			$user_data = get_user_by( 'email', $login );
226
		}
227
228
		do_action( 'lostpassword_post' );
229
230
		if ( ! $user_data ) {
231
			wc_add_notice( __( 'Invalid username or e-mail.', 'woocommerce' ), 'error' );
232
			return false;
233
		}
234
235
		if ( is_multisite() && ! is_user_member_of_blog( $user_data->ID, get_current_blog_id() ) ) {
236
			wc_add_notice( __( 'Invalid username or e-mail.', 'woocommerce' ), 'error' );
237
			return false;
238
		}
239
240
		// redefining user_login ensures we return the right case in the email
241
		$user_login = $user_data->user_login;
242
243
		do_action( 'retrieve_password', $user_login );
244
245
		$allow = apply_filters( 'allow_password_reset', true, $user_data->ID );
246
247
		if ( ! $allow ) {
248
249
			wc_add_notice( __( 'Password reset is not allowed for this user', 'woocommerce' ), 'error' );
250
			return false;
251
252
		} elseif ( is_wp_error( $allow ) ) {
253
254
			wc_add_notice( $allow->get_error_message(), 'error' );
255
			return false;
256
		}
257
258
		$key = wp_generate_password( 20, false );
259
260
		do_action( 'retrieve_password_key', $user_login, $key );
261
262
		// Now insert the key, hashed, into the DB.
263
		if ( empty( $wp_hasher ) ) {
264
			require_once ABSPATH . 'wp-includes/class-phpass.php';
265
			$wp_hasher = new PasswordHash( 8, true );
266
		}
267
268
		$hashed = $wp_hasher->HashPassword( $key );
269
270
		$wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user_login ) );
271
272
		// Send email notification
273
		WC()->mailer(); // load email classes
274
		do_action( 'woocommerce_reset_password_notification', $user_login, $key );
275
276
		return true;
277
	}
278
279
	/**
280
	 * Retrieves a user row based on password reset key and login.
281
	 *
282
	 * @uses $wpdb WordPress Database object
283
	 *
284
	 * @param string $key Hash to validate sending user's password
285
	 * @param string $login The user login
286
	 * @return WP_USER|bool User's database row on success, false for invalid keys
287
	 */
288
	public static function check_password_reset_key( $key, $login ) {
289
		global $wpdb, $wp_hasher;
290
291
		$key = preg_replace( '/[^a-z0-9]/i', '', $key );
292
293 View Code Duplication
		if ( empty( $key ) || ! is_string( $key ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
294
			wc_add_notice( __( 'Invalid key', 'woocommerce' ), 'error' );
295
			return false;
296
		}
297
298 View Code Duplication
		if ( empty( $login ) || ! is_string( $login ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
299
			wc_add_notice( __( 'Invalid key', 'woocommerce' ), 'error' );
300
			return false;
301
		}
302
303
		$user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE user_login = %s", $login ) );
304
305
		if ( ! empty( $user ) ) {
306
			if ( empty( $wp_hasher ) ) {
307
				require_once ABSPATH . 'wp-includes/class-phpass.php';
308
				$wp_hasher = new PasswordHash( 8, true );
309
			}
310
311
			$valid = $wp_hasher->CheckPassword( $key, $user->user_activation_key );
312
		}
313
314 View Code Duplication
		if ( empty( $user ) || empty( $valid ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
315
			wc_add_notice( __( 'Invalid key', 'woocommerce' ), 'error' );
316
			return false;
317
		}
318
319
		return get_userdata( $user->ID );
320
	}
321
322
	/**
323
	 * Handles resetting the user's password.
324
	 *
325
	 * @param object $user The user
326
	 * @param string $new_pass New password for the user in plaintext
327
	 */
328
	public static function reset_password( $user, $new_pass ) {
329
		do_action( 'password_reset', $user, $new_pass );
330
331
		wp_set_password( $new_pass, $user->ID );
332
333
		wp_password_change_notification( $user );
334
	}
335
336
	/**
337
	 * Show the add payment method page.
338
	 */
339
	public static function add_payment_method() {
340
341
		if ( ! is_user_logged_in() ) {
342
343
			wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) );
344
			exit();
345
346
		} else {
347
348
			do_action( 'before_woocommerce_add_payment_method' );
349
350
			wc_print_notices();
351
352
			wc_get_template( 'myaccount/form-add-payment-method.php' );
353
354
			do_action( 'after_woocommerce_add_payment_method' );
355
356
		}
357
358
	}
359
360
}
361