Allow login by email, CPF or CNPJ Woocommerce

1

I need to make a filter where it is allowed to login with the CPF or CNPJ in addition to those already allowed by Woocommerce, which is the email or user, in the My Account page. In short, I need to be able to log in with email, user, cpf or cnpj

I've read that the filter that can do this is add_filter( 'authenticate', 'my_custom_authenticate', 10, 3 ); but I do not know how to do it.

I'm using the WooCommerce Extra Checkout Fields for Brazil plugin to add the fields.

    
asked by anonymous 24.10.2016 / 15:35

3 answers

3

I do not know exactly how this plugin stores the data, but the code to log in to work with them is going to be something like this.

add_filter( 'authenticate', 'ptstackoverflow_auth_com_cpf_ou_cpnj', 99, 3 );

function ptstackoverflow_auth_com_cpf_ou_cpnj( $user, $username, $password ) {
    global $wpdb;

    // Se o primeiro parametro não é null, o usuário já está autenticado
    if ( $user ) {
        return $user;
    }

     // Passo 1: procurar no banco um usuário que tenha aquele CPF ou CNPJ 
     // ( que está na variável $username ).
     // exemplo, supondo que as meta_keys sejam "cpf" e "cnpj":
     $user_row = $wpdb->get_results( 
        $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}usermeta 
                         WHERE ( meta_key = 'cpf' AND meta_value = '%s') 
                         OR ( meta_key = 'cnpj' AND meta_value = '%s' )",
                        $username, $username ) );

    // Passo 2: Se encontrou, pega o objeto desse usuário,
    // confere a senha
     if ( ! empty( $user_row ) ) {
        $user = get_user_by( 'ID', $user_row[0]->ID );
        // Passo 3: Se a senha confere você retorna o objeto do usuário (WP_User)
        if ( wp_check_password( $password, $user->user_pass, $user_row[0]->ID ) ) {
            return $user;
        }       
     }

     /** 
     * Se não encontrou ou se a senha não confere, retorne um objeto WP_Error 
     * com a mensagem que deve aparecer 
     */
    return new WP_Error( '', 'mensagem de erro', $username );
}

This is just an example , it needs to be modified to work for you.

    
25.10.2016 / 16:00
1

Thanks for the help! I was able to authenticate, but only for one type (CPF or CNPJ), I would check for both. I believe it's time to make $ wpdb-prepare, but according to my research, I can not do two SELECT's at the same time. Here's how my code checks by only CPF:

add_filter('authenticate', 'login_cpf_cnpj', 10, 3);
function login_cpf_cnpj($user, $username, $password){
   if ($username == '' || $password == '') return;

   global $wpdb;
   if ($user) {
     return $user;
   }
    $user_row = $wpdb->get_results(
    $wpdb->prepare( "SELECT user_id FROM {$wpdb->prefix}usermeta 
                     WHERE ( meta_key = 'billing_cpf' AND meta_value = '%s') 
                     OR ( meta_key = 'billing_cnpj' AND meta_value = '%s' )",
        $username, $username ) );

   if (!empty($user_row)) {
     $user = get_user_by('ID', $user_row[0]->user_id);
     if ($user && wp_check_password($password, $user->user_pass, $user_row[0]->user_id)) {
        return $user;
     } else { ?>
          <script>
              alert('Senha Inválida!');
              window.location = "<?php get_permalink(); ?>";
          </script>
        <?php
     }
  }
  return $user;
}

UPDATE: As Ricardo replied, I changed my code to search 2 fields.

    
26.10.2016 / 20:46
1

Look for you to make it choose between cpf and cnpj you can put a condition to check the number of digits if it is greater than 12 do the cnpj test if you do not do cpf.

    
27.12.2016 / 11:39