PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/includes/shortcodes/class-wc-shortcode-my-account.php

https://gitlab.com/0072016/woocommerce
PHP | 412 lines | 233 code | 84 blank | 95 comment | 40 complexity | 27e305fd1a17f9761fa2c5a8755a51e7 MD5 | raw file
  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. * Get the shortcode content.
  15. *
  16. * @param array $atts
  17. * @return string
  18. */
  19. public static function get( $atts ) {
  20. return WC_Shortcodes::shortcode_wrapper( array( __CLASS__, 'output' ), $atts );
  21. }
  22. /**
  23. * Output the shortcode.
  24. *
  25. * @param array $atts
  26. */
  27. public static function output( $atts ) {
  28. global $wp;
  29. // Check cart class is loaded or abort
  30. if ( is_null( WC()->cart ) ) {
  31. return;
  32. }
  33. if ( ! is_user_logged_in() ) {
  34. $message = apply_filters( 'woocommerce_my_account_message', '' );
  35. if ( ! empty( $message ) ) {
  36. wc_add_notice( $message );
  37. }
  38. if ( isset( $wp->query_vars['lost-password'] ) ) {
  39. self::lost_password();
  40. } else {
  41. wc_get_template( 'myaccount/form-login.php' );
  42. }
  43. } else {
  44. // See if showing an account endpoint
  45. foreach ( $wp->query_vars as $key => $value ) {
  46. // Ignore pagename param.
  47. if ( 'pagename' === $key ) {
  48. continue;
  49. }
  50. if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) {
  51. do_action( 'woocommerce_account_' . $key . '_endpoint', $value );
  52. return;
  53. }
  54. }
  55. // No endpoint? Show main account page.
  56. self::my_account( $atts );
  57. }
  58. }
  59. /**
  60. * My account page.
  61. *
  62. * @param array $atts
  63. */
  64. private static function my_account( $atts ) {
  65. extract( shortcode_atts( array(
  66. 'order_count' => 15 // @deprecated 2.6.0. Keep for backward compatibility.
  67. ), $atts ) );
  68. wc_get_template( 'myaccount/my-account.php', array(
  69. 'current_user' => get_user_by( 'id', get_current_user_id() ),
  70. 'order_count' => 'all' == $order_count ? -1 : $order_count
  71. ) );
  72. }
  73. /**
  74. * View order page.
  75. *
  76. * @param int $order_id
  77. */
  78. public static function view_order( $order_id ) {
  79. $user_id = get_current_user_id();
  80. $order = wc_get_order( $order_id );
  81. if ( ! current_user_can( 'view_order', $order_id ) ) {
  82. echo '<div class="woocommerce-error">' . __( 'Invalid order.', 'woocommerce' ) . ' <a href="' . wc_get_page_permalink( 'myaccount' ).'" class="wc-forward">'. __( 'My Account', 'woocommerce' ) .'</a>' . '</div>';
  83. return;
  84. }
  85. // Backwards compatibility
  86. $status = new stdClass();
  87. $status->name = wc_get_order_status_name( $order->get_status() );
  88. wc_get_template( 'myaccount/view-order.php', array(
  89. 'status' => $status, // @deprecated 2.2
  90. 'order' => wc_get_order( $order_id ),
  91. 'order_id' => $order_id
  92. ) );
  93. }
  94. /**
  95. * Edit account details page.
  96. */
  97. public static function edit_account() {
  98. wc_get_template( 'myaccount/form-edit-account.php', array( 'user' => get_user_by( 'id', get_current_user_id() ) ) );
  99. }
  100. /**
  101. * Edit address page.
  102. *
  103. * @param string $load_address
  104. */
  105. public static function edit_address( $load_address = 'billing' ) {
  106. $current_user = wp_get_current_user();
  107. $load_address = sanitize_key( $load_address );
  108. $address = WC()->countries->get_address_fields( get_user_meta( get_current_user_id(), $load_address . '_country', true ), $load_address . '_' );
  109. // Enqueue scripts
  110. wp_enqueue_script( 'wc-country-select' );
  111. wp_enqueue_script( 'wc-address-i18n' );
  112. // Prepare values
  113. foreach ( $address as $key => $field ) {
  114. $value = get_user_meta( get_current_user_id(), $key, true );
  115. if ( ! $value ) {
  116. switch( $key ) {
  117. case 'billing_email' :
  118. case 'shipping_email' :
  119. $value = $current_user->user_email;
  120. break;
  121. case 'billing_country' :
  122. case 'shipping_country' :
  123. $value = WC()->countries->get_base_country();
  124. break;
  125. case 'billing_state' :
  126. case 'shipping_state' :
  127. $value = WC()->countries->get_base_state();
  128. break;
  129. }
  130. }
  131. $address[ $key ]['value'] = apply_filters( 'woocommerce_my_account_edit_address_field_value', $value, $key, $load_address );
  132. }
  133. wc_get_template( 'myaccount/form-edit-address.php', array(
  134. 'load_address' => $load_address,
  135. 'address' => apply_filters( 'woocommerce_address_to_edit', $address )
  136. ) );
  137. }
  138. /**
  139. * Lost password page.
  140. */
  141. public static function lost_password() {
  142. // arguments to pass to template
  143. $args = array( 'form' => 'lost_password' );
  144. // process reset key / login from email confirmation link
  145. if ( isset( $_GET['key'] ) && isset( $_GET['login'] ) ) {
  146. $user = self::check_password_reset_key( $_GET['key'], $_GET['login'] );
  147. // reset key / login is correct, display reset password form with hidden key / login values
  148. if ( is_object( $user ) ) {
  149. $args['form'] = 'reset_password';
  150. $args['key'] = esc_attr( $_GET['key'] );
  151. $args['login'] = esc_attr( $_GET['login'] );
  152. }
  153. } elseif ( isset( $_GET['reset'] ) ) {
  154. wc_add_notice( __( 'Your password has been reset.', 'woocommerce' ) . ' <a href="' . wc_get_page_permalink( 'myaccount' ) . '">' . __( 'Log in', 'woocommerce' ) . '</a>' );
  155. }
  156. wc_get_template( 'myaccount/form-lost-password.php', $args );
  157. }
  158. /**
  159. * Handles sending password retrieval email to customer.
  160. *
  161. * Based on retrieve_password() in core wp-login.php.
  162. *
  163. * @uses $wpdb WordPress Database object
  164. * @return bool True: when finish. False: on error
  165. */
  166. public static function retrieve_password() {
  167. global $wpdb, $wp_hasher;
  168. $login = trim( $_POST['user_login'] );
  169. if ( empty( $login ) ) {
  170. wc_add_notice( __( 'Enter a username or e-mail address.', 'woocommerce' ), 'error' );
  171. return false;
  172. } else {
  173. // Check on username first, as customers can use emails as usernames.
  174. $user_data = get_user_by( 'login', $login );
  175. }
  176. // If no user found, check if it login is email and lookup user based on email.
  177. if ( ! $user_data && is_email( $login ) && apply_filters( 'woocommerce_get_username_from_email', true ) ) {
  178. $user_data = get_user_by( 'email', $login );
  179. }
  180. do_action( 'lostpassword_post' );
  181. if ( ! $user_data ) {
  182. wc_add_notice( __( 'Invalid username or e-mail.', 'woocommerce' ), 'error' );
  183. return false;
  184. }
  185. if ( is_multisite() && ! is_user_member_of_blog( $user_data->ID, get_current_blog_id() ) ) {
  186. wc_add_notice( __( 'Invalid username or e-mail.', 'woocommerce' ), 'error' );
  187. return false;
  188. }
  189. // redefining user_login ensures we return the right case in the email
  190. $user_login = $user_data->user_login;
  191. do_action( 'retrieve_password', $user_login );
  192. $allow = apply_filters( 'allow_password_reset', true, $user_data->ID );
  193. if ( ! $allow ) {
  194. wc_add_notice( __( 'Password reset is not allowed for this user', 'woocommerce' ), 'error' );
  195. return false;
  196. } elseif ( is_wp_error( $allow ) ) {
  197. wc_add_notice( $allow->get_error_message(), 'error' );
  198. return false;
  199. }
  200. $key = wp_generate_password( 20, false );
  201. do_action( 'retrieve_password_key', $user_login, $key );
  202. // Now insert the key, hashed, into the DB.
  203. if ( empty( $wp_hasher ) ) {
  204. require_once ABSPATH . 'wp-includes/class-phpass.php';
  205. $wp_hasher = new PasswordHash( 8, true );
  206. }
  207. $hashed = $wp_hasher->HashPassword( $key );
  208. $wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user_login ) );
  209. // Send email notification
  210. WC()->mailer(); // load email classes
  211. do_action( 'woocommerce_reset_password_notification', $user_login, $key );
  212. wc_add_notice( __( 'Check your e-mail for the confirmation link.', 'woocommerce' ) );
  213. return true;
  214. }
  215. /**
  216. * Retrieves a user row based on password reset key and login.
  217. *
  218. * @uses $wpdb WordPress Database object
  219. *
  220. * @param string $key Hash to validate sending user's password
  221. * @param string $login The user login
  222. * @return WP_USER|bool User's database row on success, false for invalid keys
  223. */
  224. public static function check_password_reset_key( $key, $login ) {
  225. global $wpdb, $wp_hasher;
  226. $key = preg_replace( '/[^a-z0-9]/i', '', $key );
  227. if ( empty( $key ) || ! is_string( $key ) ) {
  228. wc_add_notice( __( 'Invalid key', 'woocommerce' ), 'error' );
  229. return false;
  230. }
  231. if ( empty( $login ) || ! is_string( $login ) ) {
  232. wc_add_notice( __( 'Invalid key', 'woocommerce' ), 'error' );
  233. return false;
  234. }
  235. $user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE user_login = %s", $login ) );
  236. if ( ! empty( $user ) ) {
  237. if ( empty( $wp_hasher ) ) {
  238. require_once ABSPATH . 'wp-includes/class-phpass.php';
  239. $wp_hasher = new PasswordHash( 8, true );
  240. }
  241. $valid = $wp_hasher->CheckPassword( $key, $user->user_activation_key );
  242. }
  243. if ( empty( $user ) || empty( $valid ) ) {
  244. wc_add_notice( __( 'Invalid key', 'woocommerce' ), 'error' );
  245. return false;
  246. }
  247. return get_userdata( $user->ID );
  248. }
  249. /**
  250. * Handles resetting the user's password.
  251. *
  252. * @param object $user The user
  253. * @param string $new_pass New password for the user in plaintext
  254. */
  255. public static function reset_password( $user, $new_pass ) {
  256. do_action( 'password_reset', $user, $new_pass );
  257. wp_set_password( $new_pass, $user->ID );
  258. wp_password_change_notification( $user );
  259. }
  260. /**
  261. * Show the add payment method page.
  262. */
  263. public static function add_payment_method() {
  264. if ( ! is_user_logged_in() ) {
  265. wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) );
  266. exit();
  267. } else {
  268. do_action( 'before_woocommerce_add_payment_method' );
  269. wc_print_notices();
  270. wc_get_template( 'myaccount/form-add-payment-method.php' );
  271. do_action( 'after_woocommerce_add_payment_method' );
  272. }
  273. }
  274. /**
  275. * Deletes a payment method from a users list and displays a message to the user
  276. *
  277. * @since 2.6
  278. * @param int $id Payment Token ID
  279. */
  280. public static function delete_payment_method( $id ) {
  281. $token = WC_Payment_Tokens::get( $id );
  282. if ( is_null( $token ) ) {
  283. wc_add_notice( __( 'Invalid payment method', 'woocommerce' ), 'error' );
  284. woocommerce_account_payment_methods();
  285. return false;
  286. }
  287. if ( get_current_user_id() !== $token->get_user_id() ) {
  288. wc_add_notice( __( 'Invalid payment method', 'woocommerce' ), 'error' );
  289. woocommerce_account_payment_methods();
  290. return false;
  291. }
  292. if ( false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'delete-payment-method-' . $id ) ) {
  293. wc_add_notice( __( 'Invalid payment method', 'woocommerce' ), 'error' );
  294. woocommerce_account_payment_methods();
  295. return false;
  296. }
  297. WC_Payment_Tokens::delete( $id );
  298. wc_add_notice( __( 'Payment method deleted.', 'woocommerce' ) );
  299. woocommerce_account_payment_methods();
  300. }
  301. /**
  302. * Sets a payment method as default and displays a message to the user
  303. *
  304. * @since 2.6
  305. * @param int $id Payment Token ID
  306. */
  307. public static function set_default_payment_method( $id ) {
  308. $token = WC_Payment_Tokens::get( $id );
  309. if ( is_null( $token ) ) {
  310. wc_add_notice( __( 'Invalid payment method', 'woocommerce' ), 'error' );
  311. woocommerce_account_payment_methods();
  312. return false;
  313. }
  314. if ( get_current_user_id() !== $token->get_user_id() ) {
  315. wc_add_notice( __( 'Invalid payment method', 'woocommerce' ), 'error' );
  316. woocommerce_account_payment_methods();
  317. return false;
  318. }
  319. if ( false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'set-default-payment-method-' . $id ) ) {
  320. wc_add_notice( __( 'Invalid payment method', 'woocommerce' ), 'error' );
  321. woocommerce_account_payment_methods();
  322. return false;
  323. }
  324. WC_Payment_Tokens::set_users_default( $token->get_user_id(), intval( $id ) );
  325. wc_add_notice( __( 'This payment method was successfully set as your default.', 'woocommerce' ) );
  326. woocommerce_account_payment_methods();
  327. }
  328. }