/** * WooCommerce Customer Functions * * Functions for customers. * * @package WooCommerce\Functions * @version 2.2.0 */ use Automattic\WooCommerce\Enums\OrderInternalStatus; use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore; use Automattic\WooCommerce\Internal\Utilities\Users; use Automattic\WooCommerce\Utilities\OrderUtil; defined( 'ABSPATH' ) || exit; /** * Prevent any user who cannot 'edit_posts' (subscribers, customers etc) from seeing the admin bar. * * Note: get_option( 'woocommerce_lock_down_admin', true ) is a deprecated option here for backwards compatibility. Defaults to true. * * @param bool $show_admin_bar If should display admin bar. * @return bool */ function wc_disable_admin_bar( $show_admin_bar ) { /** * Controls whether the WooCommerce admin bar should be disabled. * * @since 3.0.0 * * @param bool $enabled */ if ( apply_filters( 'woocommerce_disable_admin_bar', true ) && ! ( current_user_can( 'edit_posts' ) || current_user_can( 'manage_woocommerce' ) ) ) { $show_admin_bar = false; } return $show_admin_bar; } add_filter( 'show_admin_bar', 'wc_disable_admin_bar', 10, 1 ); // phpcs:ignore WordPress.VIP.AdminBarRemoval.RemovalDetected if ( ! function_exists( 'wc_create_new_customer' ) ) { /** * Create a new customer. * * @since 9.4.0 Moved woocommerce_registration_error_email_exists filter to the shortcode checkout class. * @since 9.4.0 Removed handling for generating username/password based on settings--this is consumed at form level. Here, if data is missing it will be generated. * * @param string $email Customer email. * @param string $username Customer username. * @param string $password Customer password. * @param array $args List of arguments to pass to `wp_insert_user()`. * @return int|WP_Error Returns WP_Error on failure, Int (user ID) on success. */ function wc_create_new_customer( $email, $username = '', $password = '', $args = array() ) { if ( empty( $email ) || ! is_email( $email ) ) { return new WP_Error( 'registration-error-invalid-email', __( 'Please provide a valid email address.', 'woocommerce' ) ); } if ( email_exists( $email ) ) { return new WP_Error( 'registration-error-email-exists', sprintf( // Translators: %s Email address. esc_html__( 'An account is already registered with %s. Please log in or use a different email address.', 'woocommerce' ), esc_html( $email ) ) ); } if ( empty( $username ) ) { $username = wc_create_new_customer_username( $email, $args ); } $username = sanitize_user( $username ); if ( empty( $username ) || ! validate_username( $username ) ) { return new WP_Error( 'registration-error-invalid-username', __( 'Please provide a valid account username.', 'woocommerce' ) ); } if ( username_exists( $username ) ) { return new WP_Error( 'registration-error-username-exists', __( 'An account is already registered with that username. Please choose another.', 'woocommerce' ) ); } // Handle password creation. $password_generated = false; if ( empty( $password ) ) { $password = wp_generate_password(); $password_generated = true; } if ( empty( $password ) ) { return new WP_Error( 'registration-error-missing-password', __( 'Please create a password for your account.', 'woocommerce' ) ); } // Use WP_Error to handle registration errors. $errors = new WP_Error(); /** * Fires before a customer account is registered. * * This hook fires before customer accounts are created and passes the form data (username, email) and an array * of errors. * * This could be used to add extra validation logic and append errors to the array. * * @since 7.2.0 * * @internal Matches filter name in WooCommerce core. * * @param string $username Customer username. * @param string $user_email Customer email address. * @param \WP_Error $errors Error object. */ do_action( 'woocommerce_register_post', $username, $email, $errors ); /** * Filters registration errors before a customer account is registered. * * This hook filters registration errors. This can be used to manipulate the array of errors before * they are displayed. * * @since 7.2.0 * * @internal Matches filter name in WooCommerce core. * * @param \WP_Error $errors Error object. * @param string $username Customer username. * @param string $user_email Customer email address. * @return \WP_Error */ $errors = apply_filters( 'woocommerce_registration_errors', $errors, $username, $email ); if ( is_wp_error( $errors ) && $errors->get_error_code() ) { return $errors; } // Merged passed args with sanitized username, email, and password. $customer_data = array_merge( $args, array( 'user_login' => $username, 'user_pass' => $password, 'user_email' => $email, 'role' => 'customer', ) ); /** * Filters customer data before a customer account is registered. * * This hook filters customer data. It allows user data to be changed, for example, username, password, email, * first name, last name, and role. * * @since 7.2.0 * * @param array $customer_data An array of customer (user) data. * @return array */ $new_customer_data = apply_filters( 'woocommerce_new_customer_data', wp_parse_args( $customer_data, array( 'first_name' => '', 'last_name' => '', 'source' => 'unknown', ) ) ); $customer_id = wp_insert_user( $new_customer_data ); if ( is_wp_error( $customer_id ) ) { return $customer_id; } // Set account flag to remind customer to update generated password. if ( $password_generated ) { update_user_option( $customer_id, 'default_password_nag', true, true ); } /** * Fires after a customer account has been registered. * * This hook fires after customer accounts are created and passes the customer data. * * @since 7.2.0 * * @internal Matches filter name in WooCommerce core. * * @param integer $customer_id New customer (user) ID. * @param array $new_customer_data Array of customer (user) data. * @param string $password_generated The generated password for the account. */ do_action( 'woocommerce_created_customer', $customer_id, $new_customer_data, $password_generated ); return $customer_id; } } /** * Create a unique username for a new customer. * * @since 3.6.0 * @param string $email New customer email address. * @param array $new_user_args Array of new user args, maybe including first and last names. * @param string $suffix Append string to username to make it unique. * @return string Generated username. */ function wc_create_new_customer_username( $email, $new_user_args = array(), $suffix = '' ) { $username_parts = array(); if ( isset( $new_user_args['first_name'] ) ) { $username_parts[] = sanitize_user( $new_user_args['first_name'], true ); } if ( isset( $new_user_args['last_name'] ) ) { $username_parts[] = sanitize_user( $new_user_args['last_name'], true ); } // Remove empty parts. $username_parts = array_filter( $username_parts ); // If there are no parts, e.g. name had unicode chars, or was not provided, fallback to email. if ( empty( $username_parts ) ) { $email_parts = explode( '@', $email ); $email_username = $email_parts[0]; // Exclude common prefixes. if ( in_array( $email_username, array( 'sales', 'hello', 'mail', 'contact', 'info', ), true ) ) { // Get the domain part. $email_username = $email_parts[1]; } $username_parts[] = sanitize_user( $email_username, true ); } $username = wc_strtolower( implode( '.', $username_parts ) ); if ( $suffix ) { $username .= $suffix; } /** * WordPress 4.4 - filters the list of blocked usernames. * * @since 3.7.0 * @param array $usernames Array of blocked usernames. */ $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); // Stop illegal logins and generate a new random username. if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ), true ) ) { $new_args = array(); /** * Filter generated customer username. * * @since 3.7.0 * @param string $username Generated username. * @param string $email New customer email address. * @param array $new_user_args Array of new user args, maybe including first and last names. * @param string $suffix Append string to username to make it unique. */ $new_args['first_name'] = apply_filters( 'woocommerce_generated_customer_username', 'woo_user_' . zeroise( wp_rand( 0, 9999 ), 4 ), $email, $new_user_args, $suffix ); return wc_create_new_customer_username( $email, $new_args, $suffix ); } if ( username_exists( $username ) ) { // Generate something unique to append to the username in case of a conflict with another user. $suffix = '-' . zeroise( wp_rand( 0, 9999 ), 4 ); return wc_create_new_customer_username( $email, $new_user_args, $suffix ); } /** * Filter new customer username. * * @since 3.7.0 * @param string $username Customer username. * @param string $email New customer email address. * @param array $new_user_args Array of new user args, maybe including first and last names. * @param string $suffix Append string to username to make it unique. */ return apply_filters( 'woocommerce_new_customer_username', $username, $email, $new_user_args, $suffix ); } /** * Login a customer (set auth cookie and set global user object). * * @param int $customer_id Customer ID. */ function wc_set_customer_auth_cookie( $customer_id ) { wp_set_current_user( $customer_id ); wp_set_auth_cookie( $customer_id, true ); // Update session. if ( is_callable( array( WC()->session, 'init_session_cookie' ) ) ) { WC()->session->init_session_cookie(); } } /** * Get past orders (by email) and update them. * * @param int $customer_id Customer ID. * @return int */ function wc_update_new_customer_past_orders( $customer_id ) { $linked = 0; $complete = 0; $customer = get_user_by( 'id', absint( $customer_id ) ); $customer_orders = wc_get_orders( array( 'limit' => -1, 'customer' => array( array( 0, $customer->user_email ) ), 'return' => 'ids', ) ); if ( ! empty( $customer_orders ) ) { foreach ( $customer_orders as $order_id ) { $order = wc_get_order( $order_id ); if ( ! $order ) { continue; } $order->set_customer_id( $customer->ID ); $order->save(); if ( $order->has_downloadable_item() ) { $data_store = WC_Data_Store::load( 'customer-download' ); $data_store->delete_by_order_id( $order->get_id() ); wc_downloadable_product_permissions( $order->get_id(), true ); } do_action( 'woocommerce_update_new_customer_past_order', $order_id, $customer ); if ( $order->get_status() === OrderInternalStatus::COMPLETED ) { ++$complete; } ++$linked; } } if ( $complete ) { update_user_meta( $customer_id, 'paying_customer', 1 ); Users::update_site_user_meta( $customer_id, 'wc_order_count', '' ); Users::update_site_user_meta( $customer_id, 'wc_money_spent', '' ); Users::delete_site_user_meta( $customer_id, 'wc_last_order' ); } return $linked; } /** * Order payment completed - This is a paying customer. * * @param int $order_id Order ID. */ function wc_paying_customer( $order_id ) { $order = wc_get_order( $order_id ); $customer_id = $order->get_customer_id(); if ( $customer_id > 0 && 'shop_order_refund' !== $order->get_type() ) { $customer = new WC_Customer( $customer_id ); if ( ! $customer->get_is_paying_customer() ) { $customer->set_is_paying_customer( true ); $customer->save(); } } } add_action( 'woocommerce_payment_complete', 'wc_paying_customer' ); add_action( 'woocommerce_order_status_completed', 'wc_paying_customer' ); /** * Checks if a user (by email or ID or both) has bought an item. * * @param string $customer_email Customer email to check. * @param int $user_id User ID to check. * @param int $product_id Product ID to check. * @return bool */ function wc_customer_bought_product( $customer_email, $user_id, $product_id ) { global $wpdb; $result = apply_filters( 'woocommerce_pre_customer_bought_product', null, $customer_email, $user_id, $product_id ); if ( null !== $result ) { return $result; } /** * Whether to use lookup tables - it can optimize performance, but correctness depends on the frequency of the AS job. * * @since 9.7.0 * * @param bool $enabled * @param string $customer_email Customer email to check. * @param int $user_id User ID to check. * @param int $product_id Product ID to check. * @return bool */ $use_lookup_tables = apply_filters( 'woocommerce_customer_bought_product_use_lookup_tables', false, $customer_email, $user_id, $product_id ); $transient_name = 'wc_customer_bought_product_' . md5( $customer_email . $user_id . $use_lookup_tables ); if ( $use_lookup_tables ) { // Lookup tables get refreshed along with the `woocommerce_reports` transient version. $transient_version = WC_Cache_Helper::get_transient_version( 'woocommerce_reports' ); } else { $transient_version = WC_Cache_Helper::get_transient_version( 'orders' ); } $transient_value = get_transient( $transient_name ); if ( isset( $transient_value['value'], $transient_value['version'] ) && $transient_value['version'] === $transient_version ) { $result = $transient_value['value']; } else { $customer_data = array( $user_id ); if ( $user_id ) { $user = get_user_by( 'id', $user_id ); if ( isset( $user->user_email ) ) { $customer_data[] = $user->user_email; } } if ( is_email( $customer_email ) ) { $customer_data[] = $customer_email; } $customer_data = array_map( 'esc_sql', array_filter( array_unique( $customer_data ) ) ); $statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() ); if ( count( $customer_data ) === 0 ) { return false; } if ( OrderUtil::custom_orders_table_usage_is_enabled() ) { $statuses = array_map( function ( $status ) { return "wc-$status"; }, $statuses ); $order_table = OrdersTableDataStore::get_orders_table_name(); $user_id_clause = ''; if ( $user_id ) { $user_id_clause = 'OR o.customer_id = ' . absint( $user_id ); } if ( $use_lookup_tables ) { // HPOS: yes, Lookup table: yes. $sql = " SELECT DISTINCT product_or_variation_id FROM ( SELECT CASE WHEN product_id != 0 THEN product_id ELSE variation_id END AS product_or_variation_id FROM {$wpdb->prefix}wc_order_product_lookup lookup INNER JOIN $order_table AS o ON lookup.order_id = o.ID WHERE o.status IN ('" . implode( "','", $statuses ) . "') AND ( o.billing_email IN ('" . implode( "','", $customer_data ) . "') $user_id_clause ) ) AS subquery WHERE product_or_variation_id != 0 "; } else { // HPOS: yes, Lookup table: no. $sql = " SELECT DISTINCT im.meta_value FROM $order_table AS o INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON o.id = i.order_id INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id WHERE o.status IN ('" . implode( "','", $statuses ) . "') AND im.meta_key IN ('_product_id', '_variation_id' ) AND im.meta_value != 0 AND ( o.billing_email IN ('" . implode( "','", $customer_data ) . "') $user_id_clause ) "; } $result = $wpdb->get_col( $sql ); } elseif ( $use_lookup_tables ) { // HPOS: no, Lookup table: yes. $result = $wpdb->get_col( " SELECT DISTINCT product_or_variation_id FROM ( SELECT CASE WHEN lookup.product_id != 0 THEN lookup.product_id ELSE lookup.variation_id END AS product_or_variation_id FROM {$wpdb->prefix}wc_order_product_lookup AS lookup INNER JOIN {$wpdb->posts} AS p ON p.ID = lookup.order_id INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' ) AND pm.meta_key IN ( '_billing_email', '_customer_user' ) AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' ) ) AS subquery WHERE product_or_variation_id != 0 " ); // WPCS: unprepared SQL ok. } else { // HPOS: no, Lookup table: no. // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared $result = $wpdb->get_col( " SELECT DISTINCT im.meta_value FROM {$wpdb->posts} AS p INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON p.ID = i.order_id INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' ) AND pm.meta_key IN ( '_billing_email', '_customer_user' ) AND im.meta_key IN ( '_product_id', '_variation_id' ) AND im.meta_value != 0 AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' ) " ); // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared } $result = array_map( 'absint', $result ); $transient_value = array( 'version' => $transient_version, 'value' => $result, ); set_transient( $transient_name, $transient_value, DAY_IN_SECONDS * 30 ); } return in_array( absint( $product_id ), $result, true ); } /** * Checks if the current user has a role. * * @param string $role The role. * @return bool */ function wc_current_user_has_role( $role ) { return wc_user_has_role( wp_get_current_user(), $role ); } /** * Checks if a user has a role. * * @param int|\WP_User $user The user. * @param string $role The role. * @return bool */ function wc_user_has_role( $user, $role ) { if ( ! is_object( $user ) ) { $user = get_userdata( $user ); } if ( ! $user || ! $user->exists() ) { return false; } return in_array( $role, $user->roles, true ); } /** * Checks if a user has a certain capability. * * @param array $allcaps All capabilities. * @param array $caps Capabilities. * @param array $args Arguments. * * @return array The filtered array of all capabilities. */ function wc_customer_has_capability( $allcaps, $caps, $args ) { if ( isset( $caps[0] ) ) { switch ( $caps[0] ) { case 'view_order': $user_id = intval( $args[1] ); $order = wc_get_order( $args[2] ); if ( $order && $user_id === $order->get_user_id() ) { $allcaps['view_order'] = true; } break; case 'pay_for_order': $user_id = intval( $args[1] ); $order_id = isset( $args[2] ) ? $args[2] : null; // When no order ID, we assume it's a new order // and thus, customer can pay for it. if ( ! $order_id ) { $allcaps['pay_for_order'] = true; break; } $order = wc_get_order( $order_id ); if ( $order && ( $user_id === $order->get_user_id() || ! $order->get_user_id() ) ) { $allcaps['pay_for_order'] = true; } break; case 'order_again': $user_id = intval( $args[1] ); $order = wc_get_order( $args[2] ); if ( $order && $user_id === $order->get_user_id() ) { $allcaps['order_again'] = true; } break; case 'cancel_order': $user_id = intval( $args[1] ); $order = wc_get_order( $args[2] ); if ( $order && $user_id === $order->get_user_id() ) { $allcaps['cancel_order'] = true; } break; case 'download_file': $user_id = intval( $args[1] ); $download = $args[2]; if ( $download && $user_id === $download->get_user_id() ) { $allcaps['download_file'] = true; } break; } } return $allcaps; } add_filter( 'user_has_cap', 'wc_customer_has_capability', 10, 3 ); /** * Safe way of allowing shop managers restricted capabilities that will remove * access to the capabilities if WooCommerce is deactivated. * * @since 3.5.4 * @param bool[] $allcaps Array of key/value pairs where keys represent a capability name and boolean values * represent whether the user has that capability. * @param string[] $caps Required primitive capabilities for the requested capability. * @param array $args Arguments that accompany the requested capability check. * @param WP_User $user The user object. * @return bool[] */ function wc_shop_manager_has_capability( $allcaps, $caps, $args, $user ) { if ( wc_user_has_role( $user, 'shop_manager' ) ) { // @see wc_modify_map_meta_cap, which limits editing to customers. $allcaps['edit_users'] = true; } return $allcaps; } add_filter( 'user_has_cap', 'wc_shop_manager_has_capability', 10, 4 ); /** * Modify the list of editable roles to prevent non-admin adding admin users. * * @param array $roles Roles. * @return array */ function wc_modify_editable_roles( $roles ) { if ( is_multisite() && is_super_admin() ) { return $roles; } if ( ! wc_current_user_has_role( 'administrator' ) ) { unset( $roles['administrator'] ); if ( wc_current_user_has_role( 'shop_manager' ) ) { $shop_manager_editable_roles = apply_filters( 'woocommerce_shop_manager_editable_roles', array( 'customer' ) ); return array_intersect_key( $roles, array_flip( $shop_manager_editable_roles ) ); } } return $roles; } add_filter( 'editable_roles', 'wc_modify_editable_roles' ); /** * Modify capabilities to prevent non-admin users editing admin users. * * $args[0] will be the user being edited in this case. * * @param array $caps Array of caps. * @param string $cap Name of the cap we are checking. * @param int $user_id ID of the user being checked against. * @param array $args Arguments. * @return array */ function wc_modify_map_meta_cap( $caps, $cap, $user_id, $args ) { if ( is_multisite() && is_super_admin() ) { return $caps; } switch ( $cap ) { case 'edit_user': case 'remove_user': case 'promote_user': case 'delete_user': if ( ! isset( $args[0] ) || $args[0] === $user_id ) { break; } elseif ( ! wc_current_user_has_role( 'administrator' ) ) { if ( wc_user_has_role( $args[0], 'administrator' ) ) { $caps[] = 'do_not_allow'; } elseif ( wc_current_user_has_role( 'shop_manager' ) ) { // Shop managers can only edit customer info. $userdata = get_userdata( $args[0] ); $shop_manager_editable_roles = apply_filters( 'woocommerce_shop_manager_editable_roles', array( 'customer' ) ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment if ( property_exists( $userdata, 'roles' ) && ! empty( $userdata->roles ) && ! array_intersect( $userdata->roles, $shop_manager_editable_roles ) ) { $caps[] = 'do_not_allow'; } } } break; } return $caps; } add_filter( 'map_meta_cap', 'wc_modify_map_meta_cap', 10, 4 ); /** * Get customer download permissions from the database. * * @param int $customer_id Customer/User ID. * @return array */ function wc_get_customer_download_permissions( $customer_id ) { $data_store = WC_Data_Store::load( 'customer-download' ); return apply_filters( 'woocommerce_permission_list', $data_store->get_downloads_for_customer( $customer_id ), $customer_id ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment } /** * Get customer available downloads. * * @param int $customer_id Customer/User ID. * @return array */ function wc_get_customer_available_downloads( $customer_id ) { $downloads = array(); $_product = null; $order = null; $file_number = 0; // Get results from valid orders only. $results = wc_get_customer_download_permissions( $customer_id ); if ( $results ) { foreach ( $results as $result ) { $order_id = intval( $result->order_id ); if ( ! $order || $order->get_id() !== $order_id ) { // New order. $order = wc_get_order( $order_id ); $_product = null; } // Make sure the order exists for this download. if ( ! $order ) { continue; } // Check if downloads are permitted. if ( ! $order->is_download_permitted() ) { continue; } $product_id = intval( $result->product_id ); if ( ! $_product || $_product->get_id() !== $product_id ) { // New product. $file_number = 0; $_product = wc_get_product( $product_id ); } // Check product exists and has the file. if ( ! $_product || ! $_product->exists() || ! $_product->has_file( $result->download_id ) ) { continue; } $download_file = $_product->get_file( $result->download_id ); // If the downloadable file has been disabled (it may be located in an untrusted location) then do not return it. if ( ! $download_file->get_enabled() ) { continue; } // Download name will be 'Product Name' for products with a single downloadable file, and 'Product Name - File X' for products with multiple files. // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment $download_name = apply_filters( 'woocommerce_downloadable_product_name', $download_file['name'], $_product, $result->download_id, $file_number ); $downloads[] = array( 'download_url' => add_query_arg( array( 'download_file' => $product_id, 'order' => $result->order_key, 'email' => rawurlencode( $result->user_email ), 'key' => $result->download_id, ), home_url( '/' ) ), 'download_id' => $result->download_id, 'product_id' => $_product->get_id(), 'product_name' => $_product->get_name(), 'product_url' => $_product->is_visible() ? $_product->get_permalink() : '', // Since 3.3.0. 'download_name' => $download_name, 'order_id' => $order->get_id(), 'order_key' => $order->get_order_key(), 'downloads_remaining' => $result->downloads_remaining, 'access_expires' => $result->access_expires, 'file' => array( 'name' => $download_file->get_name(), 'file' => $download_file->get_file(), ), ); ++$file_number; } } // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment return apply_filters( 'woocommerce_customer_available_downloads', $downloads, $customer_id ); } /** * Get total spent by customer. * * @param int $user_id User ID. * @return string */ function wc_get_customer_total_spent( $user_id ) { $customer = new WC_Customer( $user_id ); return $customer->get_total_spent(); } /** * Get total orders by customer. * * @param int $user_id User ID. * @return int */ function wc_get_customer_order_count( $user_id ) { $customer = new WC_Customer( $user_id ); return $customer->get_order_count(); } /** * Reset _customer_user on orders when a user is deleted. * * @param int $user_id User ID. */ function wc_reset_order_customer_id_on_deleted_user( $user_id ) { global $wpdb; if ( OrderUtil::custom_orders_table_usage_is_enabled() ) { $order_table_ds = wc_get_container()->get( OrdersTableDataStore::class ); $order_table = $order_table_ds::get_orders_table_name(); $wpdb->update( $order_table, array( 'customer_id' => 0, 'date_updated_gmt' => current_time( 'mysql', true ), ), array( 'customer_id' => $user_id, ), array( '%d', '%s', ), array( '%d', ) ); } if ( ! OrderUtil::custom_orders_table_usage_is_enabled() || OrderUtil::is_custom_order_tables_in_sync() ) { $wpdb->update( $wpdb->postmeta, array( 'meta_value' => 0, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value ), array( 'meta_key' => '_customer_user', //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key 'meta_value' => $user_id, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value ) ); } } add_action( 'deleted_user', 'wc_reset_order_customer_id_on_deleted_user' ); /** * Get review verification status. * * @param int $comment_id Comment ID. * @return bool */ function wc_review_is_from_verified_owner( $comment_id ) { $verified = get_comment_meta( $comment_id, 'verified', true ); return '' === $verified ? WC_Comments::add_comment_purchase_verification( $comment_id ) : (bool) $verified; } /** * Disable author archives for customers. * * @since 2.5.0 */ function wc_disable_author_archives_for_customers() { global $author; if ( is_author() ) { $user = get_user_by( 'id', $author ); if ( user_can( $user, 'customer' ) && ! user_can( $user, 'edit_posts' ) ) { wp_safe_redirect( wc_get_page_permalink( 'shop' ) ); exit; } } } add_action( 'template_redirect', 'wc_disable_author_archives_for_customers' ); /** * Hooks into the `profile_update` hook to set the user last updated timestamp. * * @since 2.6.0 * @param int $user_id The user that was updated. * @param array $old The profile fields pre-change. */ function wc_update_profile_last_update_time( $user_id, $old ) { wc_set_user_last_update_time( $user_id ); } add_action( 'profile_update', 'wc_update_profile_last_update_time', 10, 2 ); /** * Hooks into the update user meta function to set the user last updated timestamp. * * @since 2.6.0 * @param int $meta_id ID of the meta object that was changed. * @param int $user_id The user that was updated. * @param string $meta_key Name of the meta key that was changed. * @param mixed $_meta_value Value of the meta that was changed. */ function wc_meta_update_last_update_time( $meta_id, $user_id, $meta_key, $_meta_value ) { $keys_to_track = apply_filters( 'woocommerce_user_last_update_fields', array( 'first_name', 'last_name' ) ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment $update_time = in_array( $meta_key, $keys_to_track, true ) ? true : false; $update_time = 'billing_' === substr( $meta_key, 0, 8 ) ? true : $update_time; $update_time = 'shipping_' === substr( $meta_key, 0, 9 ) ? true : $update_time; if ( $update_time ) { wc_set_user_last_update_time( $user_id ); } } add_action( 'update_user_meta', 'wc_meta_update_last_update_time', 10, 4 ); /** * Sets a user's "last update" time to the current timestamp. * * @since 2.6.0 * @param int $user_id The user to set a timestamp for. */ function wc_set_user_last_update_time( $user_id ) { update_user_meta( $user_id, 'last_update', gmdate( 'U' ) ); } /** * Get customer saved payment methods list. * * @since 2.6.0 * @param int $customer_id Customer ID. * @return array */ function wc_get_customer_saved_methods_list( $customer_id ) { return apply_filters( 'woocommerce_saved_payment_methods_list', array(), $customer_id ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment } /** * Get info about customer's last order. * * @since 2.6.0 * @param int $customer_id Customer ID. * @return WC_Order|bool Order object if successful or false. */ function wc_get_customer_last_order( $customer_id ) { $customer = new WC_Customer( $customer_id ); return $customer->get_last_order(); } /** * When a user is deleted in WordPress, delete corresponding WooCommerce data. * * @param int $user_id User ID being deleted. */ function wc_delete_user_data( $user_id ) { global $wpdb; // Clean up sessions. $wpdb->delete( $wpdb->prefix . 'woocommerce_sessions', array( 'session_key' => $user_id, ) ); // Revoke API keys. $wpdb->delete( $wpdb->prefix . 'woocommerce_api_keys', array( 'user_id' => $user_id, ) ); // Clean up payment tokens. $payment_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id ); foreach ( $payment_tokens as $payment_token ) { $payment_token->delete(); } } add_action( 'delete_user', 'wc_delete_user_data' ); /** * Store user agents. Used for tracker. * * @since 3.0.0 * @param string $user_login User login. * @param int|object $user User. */ function wc_maybe_store_user_agent( $user_login, $user ) { if ( 'yes' === get_option( 'woocommerce_allow_tracking', 'no' ) && user_can( $user, 'manage_woocommerce' ) ) { $admin_user_agents = array_filter( (array) get_option( 'woocommerce_tracker_ua', array() ) ); $admin_user_agents[] = wc_get_user_agent(); update_option( 'woocommerce_tracker_ua', array_unique( $admin_user_agents ), false ); } } add_action( 'wp_login', 'wc_maybe_store_user_agent', 10, 2 ); /** * Update logic triggered on login. * * @since 3.4.0 * @param string $user_login User login. * @param object $user User. */ function wc_user_logged_in( $user_login, $user ) { wc_update_user_last_active( $user->ID ); update_user_meta( $user->ID, '_woocommerce_load_saved_cart_after_login', 1 ); } add_action( 'wp_login', 'wc_user_logged_in', 10, 2 ); /** * Update when the user was last active. * * @since 3.4.0 */ function wc_current_user_is_active() { if ( ! is_user_logged_in() ) { return; } wc_update_user_last_active( get_current_user_id() ); } add_action( 'wp', 'wc_current_user_is_active', 10 ); /** * Set the user last active timestamp to now. * * @since 3.4.0 * @param int $user_id User ID to mark active. */ function wc_update_user_last_active( $user_id ) { if ( ! $user_id ) { return; } update_user_meta( $user_id, 'wc_last_active', (string) strtotime( gmdate( 'Y-m-d', time() ) ) ); } /** * Translate WC roles using the woocommerce textdomain. * * @since 3.7.0 * @param string $translation Translated text. * @param string $text Text to translate. * @param string $context Context information for the translators. * @param string $domain Text domain. Unique identifier for retrieving translated strings. * @return string */ function wc_translate_user_roles( $translation, $text, $context, $domain ) { // translate_user_role() only accepts a second parameter starting in WP 5.2. if ( version_compare( get_bloginfo( 'version' ), '5.2', '<' ) ) { return $translation; } if ( 'User role' === $context && 'default' === $domain && in_array( $text, array( 'Shop manager', 'Customer' ), true ) ) { return translate_user_role( $text, 'woocommerce' ); } return $translation; } add_filter( 'gettext_with_context', 'wc_translate_user_roles', 10, 4 ); "Wagering Company ᐉ On The Web Sports Betting 1xbet - Ravian Technologies

Exclusive OFF Exclusive OFF - We are also offering one month free customer support after completing the project

AI Powered, Well Reputed and Trusted Company for Your Successful Business

“Wagering Company ᐉ On The Web Sports Betting 1xbet

Pre-match Bets Online Sports Activities Betting ᐉ “1xbet” ᐉ 1xbet Com

The 1xBet login process for Bangladeshi players is designed to be user-friendly, protected, and accessible coming from any device. Whether you choose to log in by means of email, phone, or even social media, the platform ensures some sort of seamless experience. Added features like French language support, BDT transactions, and also a devoted mobile app make logging in to 1xBet easy for customers in Bangladesh.

The key to being a successful gambler is analyzing typically the markets and probabilities offered by gambling companies. Many bettors base their method on an examination of “odds movement”, making sense, while in the long term, your own success rate can reach 75-80%. Firstly, locate the committed ‘Sign Up’ button at the top right corner regarding the screen.

Forgot Password Problem

“1xbet is a top rated online betting program offering a secure and legal experience. With a variety of alternatives for sports gambling, live betting, and casino games, customers can enjoy a different selection of alternatives. Thanks to typically the success of its promotional offerings, 1xbet became a generating force behind their global expansion. The company was one of the first to create some sort of mobile wagering iphone app that impressed customers, who could at this point register make bets just a few minutes from their own smartphone. It may well seem commonplace today, but it has been considered almost technology fiction ten decades ago. By 2025, the company acquired reached global enterprise status, and these days it is one regarding the most well-liked online betting systems worldwide 1xbet apk.

  • You can certainly accessibility all the choices and features involving the woking platform during the particular registration process.
  • You also can register for an online gambling account by offering your phone range and country.
  • Both versions are user friendly and intuitive and offer the same subscription procedures and reward codes as the browser version.
  • Once you click upon the login key available on the particular homepage of typically the 1xBet sportsbook platform, you can be taken to the next webpage.
  • You can in addition find news in current free wagers for various matches on Google.

It is necessary to consider this information critically since financial dealings occur on the website, and users often have a great deal of real money on their balance. We recommend selecting the currency found in your own location for comfort. While various repayment methods are offered, the device works greatest with charge cards. You can decide on a variety of banks through around the planet for withdrawals.

Bet Partners

Enter your cell phone number and security password or email in addition to password, whichever choice you choose. Ensure that the details a person enter are proper as well as the same because those you applied at the period of registration. Otherwise, you might face problems when visiting in to your own 1xBet account.

You can also register regarding an online sports betting account by delivering your phone amount and country. Ensure the phone range is valid plus actively used within your selected nation. After submitting your current details, a verification code will end up being sent to your own phone via TEXT MESSAGE. Enter the computer code in the specified field in typically the menu to start the sign-up method. It is crucial just to request a couple of verification codes or even submit multiple cell phone numbers during sign-up, because doing so may result in additional identity verification.

Live Casino

With this offer, you’ll convey more chances in order to win and restore any lost funds without risking your current own money. Keep an eye out for similar promotions upon official social multimedia pages, like Instagram. You can in addition find news about current free bets for various matches on Google. You can use your own messenger or interpersonal media accounts to set up a good account on onexbet. By logging in with your Telegram, Twitter, Facebook, or perhaps other charges, a number of your data could be used to bypass certain periods in the registration method.

  • Ensure how the details a person enter are appropriate as well as the same since those you utilized at the moment of registration.
  • In addition, you should produce a secure get access and password in the required format.
  • With us, you can also place a great online bet around the winner of every single game, on frustrations and total ratings in individual units, for the number associated with break points, plus much more.
  • If you can access the support (which is recommended), you can select from over 35 different languages.
  • 1xBet Betting Company holds a Bet Slip Battle every month, giving players typically the opportunity to obtain” “yet another bonus.

If you wish to maintain betting, there will be much to acquire from exploring our own options. 1xBet, staying a popular website in the terme conseillé industry, has robust customer support. You could always contact all of them when you face any issue related to your 1xBet accounts. The customer support crew, which is always there to respond to your queries, may assist you inside solving them. There will vary methods regarding communicating with customer service so that you can solve any difficulty and get an answer to your own” “inquiries very quickly.

Games

To access all the characteristics of the 1xBet sports betting consideration, you have to register the account around the sportsbook platform using the 1xBet register. However, some simple steps include registering your account within the 1xBet program. Using the ‘one-click’ registration method is the fastest method to access 1xbet com services, which includes sports betting.

  • It is important to take this information critically since financial dealings occur on typically the website, and users often have significant amounts of real money on their balance.
  • You meet the criteria for this provide despite a minimal deposit, which can be excellent considering the platform’s high odds.
  • You can pick a selection of banks from around the entire world for withdrawals.
  • So, a number of bonuses are accessible for quick, cheeky wagers and those who prepare to extend their very own stay here.
  • Also, if you face virtually any hassle during accessing your 1xBet bank account page Bangladesh, the customer service crew is always right now there to help you out.

With us, you can also place the online bet around the winner of each and every game, on frustrations and total results in individual models, on the number of break points, in addition to much more. With these multiple alternatives, 1xBet makes this easier for Bangladeshi users to sign in quickly without difficulties, whether they’re using a desktop or mobile phone device. If you have difficulties logging in to 1xbet due to site blocking by authorities, don’t get worried. This website is using a security services to protect itself from online problems. There are various actions that can trigger this stop including submitting the certain word or even phrase, a SQL command or malformed data. All materials on this site are available beneath license Creative Commons Attribution 4. 0 International.”

Complete Login Process

Once you visit the gambling platform’s official home page, you will find the registration switch marked beside typically the login button. When it comes in order to betting on sports, football is by far the many popular option today, as there’s a reason it’s referred to as most valuable game. Our betting business offers highly” “aggressive odds on sports at all occasions with a wide array of bet types offered. Whether you choose a Windows PERSONAL COMPUTER or even a mobile gadget, developing a 1xbet account is quick and even convenient.

  • In addition to its on the internet presence, 1xbet is famous for its engagement inside the sports world.
  • Enter your phone number, confirmation code, currency, or perhaps other required details that you are usually asked to enter.
  • There is a forgot password choice present on the particular homepage of the particular website.

The executives in the 1xBet sportsbook platform may possibly take down the website if they plan to remove bugs. In this type of case, they might defeat their site for maintenance, and the particular users might confront problems in working in. Thus, an individual can try right after some time and even login into your betting account again. The login procedure in the 1xBet athletics” “gambling platform is quite simple and. It does not issue be it the 1xBet login mobile or even via desktop; the outcome may be the identical.

Bet Registration

Both techniques are basic and need a similar information, regardless of your gadget. You may easily accessibility all the choices and features associated with the platform during the particular registration process. In addition, it is advisable to generate a secure login and password in the required format. If you suspect someone has gained use of your account, make contact with 1xbet support immediately to freeze the particular account and totally reset the password.

  • With typically the 1xBet mobile program, you can basically sign in to your current account in secs.
  • In this sort of case, ensure that will the wifi or perhaps the internet a person are using will be running perfectly.
  • You can easily make and access your current 1xbet account about most operating systems.
  • Thus, you can try right after some time and even login into your current betting account once more.
  • The key to be able to as being a successful gambler is analyzing the particular markets and chances offered by betting companies.

This company have been offering on-line sports wagers and gambling options due to the fact 2007. You may reliably earn money through their services, which provides reasonably competitive coefficients across an array of games and activities. Their steadily developing user base will be a good signal of the legitimacy and recognition of their own service. There is definitely a bit regarding a difference between the 1xBet login cellular application as well as the site version.

“registration

1xbet. com is a global on the web betting platform that will originated as the physical bookmaker. The company has turned into a groundbreaking online betting shop, enticing many consumers with unique promo offers. Catering to a diverse viewers, it provides well-known online services around various regions this kind of as Asia, European countries, Africa, Latin America, and beyond.

  • The mirror site is identical to be able to the original 1xbet, and customers can log in to their account without having going through typically the registration process once more.
  • You can easily reliably earn cash through their services, which provides aggressive coefficients across a variety of games and occasions.
  • Furthermore, it continuously sponsors major suits and maintains” “a working advertising campaign around the world.
  • This website is using securities support to protect by itself from online assaults.
  • We highly suggest setting up your account security immediately to prevent potential breaches.

There is a forgot password alternative present on the homepage of typically the website. On selecting the option, you will receive a security password reset link which often you can make use of to reset your current password. Once the password is reset, you may use them to log in to your account again. So, all sorts of bonuses are offered for quick, cheeky wagers and those who program to extend their very own stay here. Importantly, 1x features the particular world’s most popular slot game Aviator Game.

💎what Makes 1xbet Stand Out By Other Online Bookies?

However, it does not really mean there is usually no solution for that problems arising within the platform. To help make things easier, there are solutions to just about all the problems in the 1xBet sportsbook platform. The internet site is for educational purposes only and does not inspire sports betting or online casino betting. Once the facts are came into correctly, you may click the Logon button to sign in to your bank account and enjoy typically the website’s features. For hardcore tennis followers, we offer a huge selection associated with markets which is not only restricted to outrights, handicaps, quantités” “or sets score.

  • If you experience difficulties logging into 1xbet due to site blocking simply by authorities, don’t get worried.
  • When you deposit any amount of money for your requirements on, the platform will dual it and present a person a 100% budgetary bonus.
  • To access typically the complete range of features and companies, you need to create some sort of fully-fledged account in 1x bet.
  • For hardcore tennis fans, we offer a new huge selection of markets which is not only limited to outrights, handicaps, quantités” “or sets score.
  • Added features like Bengali language support, BDT transactions, along with a devoted mobile app make logging directly into 1xBet easy for users in Bangladesh.

The mirror web site is identical in order to the original 1xbet, and customers can log in in order to their account with out going through the registration process once again. The only variation is the link, which changes regularly as the recognized site is regularly blocked in several regions. We up-date the 1xbet sign in link daily, making sure you can gain access to the site whenever. However, if an individual cannot do and so, consider utilizing a VPN alternatively solution. A network problem is usually very common and users might at times lose their network connection while accessing their 1xBet sportsbook account.

Bet Login Bd

1xbet is also reputed for its numerous reward offers, such as a generous delightful bonus for fresh users and repeated one-time events such as betting on typically the outcomes of certain awards. Bonus unique codes are also a regular feature, which could further boost your current betting wallet. This online betting system has been graded as one involving the top providers in the planet by many reliable surveys, and it’s easy to notice why. With above 50 betting possibilities that cover lots of sports and wagering, 1xbet provides” “an array of content to go well with different tastes.

  • The customers are bound in order to forget their security password if they try to be able to log in to their website.
  • It is important just to request several verification codes or submit multiple phone numbers during sign-up, as doing so might result in extra identity verification.
  • Once the network network is properly renewed, you can attempt the 1xBet app login to efficiently log in for your betting account.
  • However, if you cannot do thus, consider utilizing a VPN as a substitute solution.
  • We upgrade the 1xbet sign in link daily, ensuring you can entry the site whenever.

The ease of logging in through the mobile phone application is much simpler than the web site version. With typically the 1xBet mobile app, you can basically log in to your account in mere seconds. But for the particular website version, an individual will require much more time to journal in to your account. One of the almost all famous platforms throughout the betting market, 1xBet gambling web-site, has attracted” “consumers for a lengthy time. You would miss out on the opportunities by sports betting, live betting, aviator, esports, and many even more, if you don’t register yourself around the sportsbook site.

Difference Via Login Together With 1xbet App

However, you must realize how to perform a 1xBet login down load to access the different areas of typically the bookmaker site. With extraordinary promotions, which include the 25% Cashback Bonus, 250% Hyper Bonus, x2 Wednesday Promotion, and many more offers. The platform is accessible in popular operating systems, with a individual 1xbet app designed for Apple and Android devices, as nicely as various LAPTOP OR COMPUTER versions. Each variation offers similar advantages, and you could make use of the same login details across almost all of them.

  • The company has turned into a landmark online betting store, enticing many users with unique promo offers.
  • This online betting system has been graded as one associated with the top companies in the planet by many credible surveys, and it’s easy to notice why.
  • Thanks to the particular success of it is promotional offerings, 1xbet became a driving force behind it is global expansion.
  • If you decide to be able to download the 1xBet” “mobile app, you may access your bank account not only through your computer but likewise from the phone.
  • Enter the program code in the designated field in typically the menu to trigger the sign-up method.

Also, in case you face virtually any hassle during accessing your 1xBet accounts page Bangladesh, the customer service group is always generally there to help a person out. The techniques of communication of 1xBet, which are current online, are. Once done, click in the register switch to create your own account within the 1xBet bookmaker platform. Because incorrect information could lead you to be able to trouble and you may well face issues during 1xBet join.

Where May You Setup A Great Account On 1xbet?

By incorporating their own understanding with reliable statistics, customers can turn their predictions straight into money. They can easily weigh up the probability of 1 result or another, make their predictions, that a bet slip. What’s more, the particular 1xBet website gives customers the possibility to produce a successful combination and share their very own bet slip with their friends. 1xBet Betting Company retains a Bet Go Battle every calendar month, giving players typically the opportunity to acquire” “one more bonus.

Both versions are user friendly and intuitive and provide the same subscription procedures and bonus codes as the particular browser version. To access your 1xbet account from your desktop computer, click the sign in button in the official site’s top right corner. Since 1xBet is some sort of professional sportsbook program, it is really common to enable them to deal with login problems.

Mobile Login For On-the-go Betting

When you deposit any amount of cash for your requirements on, typically the platform will double it and provide an individual a 100% monetary bonus. You qualify for this present despite having a nominal deposit, which is superb considering the platform’s high odds. You can easily produce and access the 1xbet account about most operating systems. If you prefer not to use the internet browser, you could access the platform’s mobile type, which can be available for iPhone and Android devices. After going into your personal details, you can entry your account to select your preferred dialect and interest type, such as sports, casinos, or esports. We highly advise setting up your account security immediately to stop potential breaches.

The official 1xbet loyalty software rewards players together with points for every bet they succeed on the platform. You can actually earn extra loyalty take into account add to be able to your betting stability, which can become used to spot bets instead regarding actual money. The service is obtainable in many places” “globally, except those wherever it is restricted. If you could access the services (which is recommended), you can pick from over thirty different languages.

💰how Can You Generate Money With 1xbet? Predictions On Sports Activities Events

After completing these methods, you can access a huge functional site, from sports betting to watching are living broadcasts of the favourite matches. In improvement to its online presence, 1xbet is famous for its participation inside the sports entire world. It is typically the official sponsor involving FC Barcelona and the Italian Conjunto A football league. Furthermore, it regularly sponsors major suits and maintains” “the advertising campaign throughout the world.

  • After submitting your details, a confirmation code will end up being sent to your current phone via SMS.
  • There are different methods associated with communicating with customer service so that a person can solve any difficulty and get the answer to your” “concerns very quickly.
  • With over 50 betting opportunities that cover numerous sports and gambling, 1xbet provides” “an array of content to go well with different tastes.
  • Our web site can help assist you through the easy registration and login process on 1xbet. com.
  • The company was one of the initial to create a new mobile wagering iphone app that impressed customers, who could at this point register and place bets just a few minutes from their smartphone.

Provide your current location in addition to preferred currency during the registration process. To access typically the complete range associated with features and providers, you should create a new fully-fledged account in 1x bet. Every customer enjoys generating predictions on fits played by way of a favourite team.

Register Via Your Current Phone

Click upon the registration button to begin along with the registration procedure for the terme conseillé site. Enter your own phone number, verification code, currency, or even other required details that you are usually asked to. Don’t forget to work with our promo signal AVIATORCOM to improve your Aviator game chances.

Sometimes, you may face problems visiting into the 1xBet gambling account employing the application. Your mobile application may possibly not be up to date for the latest variation, and you may well face issues. Once you click upon the login key available on typically the homepage of the particular 1xBet sportsbook platform, you will be taken in order to the next web page.

Scroll to Top
Scroll to Top
small_c_popup.png

Let's have a chat

Get A Quote