<?php
/*
Plugin Name: CPF Login WooCommerce
Description: Permite login e cadastro usando CPF no WooCommerce, integrado com o plugin WooCommerce Extra Checkout Fields for Brazil.
Version: 1.6
Author: Juan Pablo
*/
// Bloqueia acesso direto
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WC_CPF_Login' ) ) :
class WC_CPF_Login {
public function __construct() {
// Campos de cadastro
add_action( 'woocommerce_register_form_start', [ $this, 'add_cpf_field' ] );
add_action( 'woocommerce_register_form', [ $this, 'add_cpf_field' ] );
// Validação do CPF no registro
add_action( 'woocommerce_register_post', [ $this, 'validate_cpf_field' ], 10, 3 );
// Salvando CPF no user meta
add_action( 'woocommerce_created_customer', [ $this, 'save_cpf_user_meta' ] );
// Login via CPF
add_filter( 'authenticate', [ $this, 'login_with_cpf' ], 30, 3 );
// Ajusta prioridade do campo CPF
add_filter( 'woocommerce_form_field_args', [ $this, 'reorder_cpf_field' ], 10, 3 );
// Enfileira JS para máscara CPF
add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
}
/**
* Adiciona o campo CPF no formulário de cadastro.
*/
public function add_cpf_field() {
woocommerce_form_field( 'billing_cpf', [
'type' => 'text',
'label' => __( 'CPF', 'woocommerce' ),
'required' => true,
'class' => [ 'form-row-wide' ],
'input_class' => [ 'cpf-mask' ],
'priority' => 5,
'maxlength' => 14,
], isset( $_POST['billing_cpf'] ) ? sanitize_text_field( wp_unslash( $_POST['billing_cpf'] ) ) : '' );
}
/**
* Valida o campo CPF.
*/
public function validate_cpf_field( $username, $email, $validation_errors ) {
if ( empty( $_POST['billing_cpf'] ) ) {
$validation_errors->add( 'billing_cpf_error', __( 'Por favor, insira seu CPF.', 'woocommerce' ) );
return;
}
$cpf = preg_replace( '/[^0-9]/', '', sanitize_text_field( $_POST['billing_cpf'] ) );
if ( ! $this->validate_cpf( $cpf ) ) {
$validation_errors->add( 'billing_cpf_invalid', __( 'CPF inválido.', 'woocommerce' ) );
return;
}
// Confere se já existe o CPF cadastrado
$existing_users = get_users( [
'meta_key' => 'billing_cpf',
'meta_value' => $cpf,
'number' => 1,
'fields' => 'ID',
] );
if ( ! empty( $existing_users ) ) {
$validation_errors->add( 'billing_cpf_exists', __( 'Este CPF já está cadastrado.', 'woocommerce' ) );
return;
}
}
/**
* Salva o CPF como user meta.
*/
public function save_cpf_user_meta( $customer_id ) {
if ( isset( $_POST['billing_cpf'] ) ) {
$cpf = preg_replace( '/[^0-9]/', '', sanitize_text_field( $_POST['billing_cpf'] ) );
update_user_meta( $customer_id, 'billing_cpf', $cpf );
update_user_meta( $customer_id, 'cpf', $cpf ); // Compatível com alguns plugins
// Opcional: força o user_login a ser o CPF
// CUIDADO: isso pode causar problemas se o usuário quiser mudar o login depois.
wp_update_user( [
'ID' => $customer_id,
'user_login' => $cpf,
] );
}
}
/**
* Permite autenticação via CPF.
*/
function login_with_cpf( $user, $username, $password ) {
if ( is_a( $user, 'WP_User' ) || empty( $username ) || empty( $password ) ) {
return $user;
}
global $wpdb;
// Limpa tudo que não for número
$cpf_clean = preg_replace( '/[^0-9]/', '', $username );
if ( strlen( $cpf_clean ) !== 11 ) {
return $user; // Não tenta se não for CPF válido
}
// Função para mascarar CPF: 12345678901 -> 123.456.789-01
function mask_cpf($cpf) {
return substr($cpf, 0, 3) . '.' . substr($cpf, 3, 3) . '.' . substr($cpf, 6, 3) . '-' . substr($cpf, 9, 2);
}
$cpf_masked = mask_cpf($cpf_clean);
// Consulta direta no banco para meta_key 'billing_cpf' com valor exato igual ao CPF limpo ou CPF mascarado
$user_id = $wpdb->get_var( $wpdb->prepare(
"SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = 'billing_cpf' AND (meta_value = %s OR meta_value = %s) LIMIT 1",
$cpf_clean,
$cpf_masked
));
if ( ! $user_id ) {
return $user; // Não encontrou usuário
}
$user_obj = get_userdata( $user_id );
if ( ! $user_obj ) {
return $user; // Usuário não existe
}
// Verifica senha
if ( wp_check_password( $password, $user_obj->user_pass, $user_obj->ID ) ) {
return $user_obj;
} else {
return new WP_Error( 'incorrect_password', __( 'Senha incorreta.', 'woocommerce' ) );
}
}
/**
* Ajusta a prioridade do campo CPF.
*/
public function reorder_cpf_field( $args, $key, $value ) {
if ( 'billing_cpf' === $key ) {
$args['priority'] = 5;
}
return $args;
}
/**
* Valida CPF conforme regras oficiais.
*/
private function validate_cpf( $cpf ) {
if ( strlen( $cpf ) != 11 || preg_match( '/(\d)\1{10}/', $cpf ) ) {
return false;
}
for ( $t = 9; $t < 11; $t++ ) {
$d = 0;
for ( $c = 0; $c < $t; $c++ ) {
$d += $cpf[$c] * ( ( $t + 1 ) - $c );
}
$d = ( ( 10 * $d ) % 11 ) % 10;
if ( $cpf[$t] != $d ) {
return false;
}
}
return true;
}
/**
* Enfileira JS para a máscara de CPF.
*/
public function enqueue_scripts() {
wp_enqueue_script( 'jquery-mask', 'https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js', [ 'jquery' ], null, true );
wp_add_inline_script( 'jquery-mask', "
jQuery(function($){
$('.cpf-mask').mask('000.000.000-00');
});
" );
}
}
new WC_CPF_Login();
endif;