<?php
/**
* Form submission handler.
*
* @package TonItaliaRegistration
*/
defined( 'ABSPATH' ) || exit;
/**
* Class TON_Reg_Registration_Handler
*/
class TON_Reg_Registration_Handler {
/**
* Register hooks.
*/
public static function register() {
add_action( 'admin_post_nopriv_ton_reg_submit', array( __CLASS__, 'handle' ) );
add_action( 'admin_post_ton_reg_submit', array( __CLASS__, 'handle' ) );
}
/**
* Handle POST.
*/
public static function handle() {
$redirect = wp_get_referer() ? wp_get_referer() : home_url( '/' );
if ( ! isset( $_POST['ton_reg_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['ton_reg_nonce'] ) ), TON_Reg_Captcha::NONCE_ACTION ) ) {
self::redirect_error( $redirect, __( 'Sessione non valida.', 'ton-italia-registration' ) );
}
if ( ! TON_Reg_Captcha::check_rate_limit() ) {
self::redirect_error( $redirect, __( 'Troppi tentativi. Riprova più tardi.', 'ton-italia-registration' ) );
}
$captcha = TON_Reg_Captcha::validate( $_POST );
if ( is_wp_error( $captcha ) ) {
self::redirect_error( $redirect, $captcha->get_error_message() );
}
$data = self::sanitize_post( $_POST );
$valid = self::validate( $data );
if ( is_wp_error( $valid ) ) {
self::redirect_error( $redirect, $valid->get_error_message() );
}
$existing = TON_Reg_Database::find_active_by_email_or_cf( $data['email'], $data['codice_fiscale'] );
if ( $existing ) {
self::redirect_error( $redirect, __( 'Esiste già una richiesta attiva con questa email o codice fiscale.', 'ton-italia-registration' ) );
}
$user_id = TON_Reg_User_Manager::create_subscriber( $data );
if ( is_wp_error( $user_id ) ) {
self::redirect_error( $redirect, $user_id->get_error_message() );
}
$now = current_time( 'mysql', true );
$privacy = (string) get_option( 'ton_reg_privacy_version', '1' );
$row = array(
'user_id' => $user_id,
'cognome' => $data['cognome'],
'nome' => $data['nome'],
'luogo_nascita' => $data['luogo_nascita'],
'provincia_nascita' => $data['provincia_nascita'],
'data_nascita' => $data['data_nascita'],
'codice_fiscale' => $data['codice_fiscale'],
'comune_residenza' => $data['comune_residenza'],
'provincia_residenza' => $data['provincia_residenza'],
'indirizzo' => $data['indirizzo'],
'numero_civico' => $data['numero_civico'],
'cap' => $data['cap'],
'telefono' => $data['telefono'],
'email' => $data['email'],
'luogo_dichiarazione' => $data['luogo_dichiarazione'],
'data_dichiarazione' => $data['data_dichiarazione'],
'bonifico_effettuato' => $data['bonifico_effettuato'],
'consenso_statuto' => 1,
'consenso_privacy' => 1,
'consenso_newsletter' => $data['consenso_newsletter'],
'registration_ip' => TON_Reg_Captcha::get_client_ip(),
'user_agent' => self::user_agent(),
'privacy_text_version' => $privacy,
'consent_statuto_at' => $now,
'consent_privacy_at' => $now,
'status' => 'pending',
);
$reg_id = TON_Reg_Database::insert( $row );
if ( ! $reg_id ) {
wp_delete_user( $user_id );
self::redirect_error( $redirect, __( 'Errore nel salvataggio. Riprova.', 'ton-italia-registration' ) );
}
update_user_meta( $user_id, 'ton_reg_registration_id', $reg_id );
$data['registration_id'] = $reg_id;
TON_Reg_User_Manager::sync_user_meta( $user_id, $data );
$registration = TON_Reg_Database::get( $reg_id );
TON_Reg_Documents::ensure_member_folder( $registration );
TON_Reg_Mailer::send_admin_notification( $registration, $user_id );
TON_Reg_Mailer::send_user_confirmation( $registration, $user_id );
$success_url = add_query_arg(
array(
'ton_reg' => 'success',
),
$redirect
);
wp_safe_redirect( $success_url );
exit;
}
/**
* @param array<string,mixed> $post Raw POST.
* @return array<string,mixed>
*/
private static function sanitize_post( $post ) {
$cf = isset( $post['codice_fiscale'] ) ? strtoupper( preg_replace( '/\s+/', '', sanitize_text_field( wp_unslash( $post['codice_fiscale'] ) ) ) ) : '';
return array(
'cognome' => sanitize_text_field( wp_unslash( $post['cognome'] ?? '' ) ),
'nome' => sanitize_text_field( wp_unslash( $post['nome'] ?? '' ) ),
'luogo_nascita' => sanitize_text_field( wp_unslash( $post['luogo_nascita'] ?? '' ) ),
'provincia_nascita' => strtoupper( sanitize_text_field( wp_unslash( $post['provincia_nascita'] ?? '' ) ) ),
'data_nascita' => self::parse_date_input( sanitize_text_field( wp_unslash( $post['data_nascita'] ?? '' ) ) ),
'codice_fiscale' => $cf,
'comune_residenza' => sanitize_text_field( wp_unslash( $post['comune_residenza'] ?? '' ) ),
'provincia_residenza' => strtoupper( sanitize_text_field( wp_unslash( $post['provincia_residenza'] ?? '' ) ) ),
'indirizzo' => sanitize_text_field( wp_unslash( $post['indirizzo'] ?? '' ) ),
'numero_civico' => sanitize_text_field( wp_unslash( $post['numero_civico'] ?? '' ) ),
'cap' => sanitize_text_field( wp_unslash( $post['cap'] ?? '' ) ),
'telefono' => sanitize_text_field( wp_unslash( $post['telefono'] ?? '' ) ),
'email' => sanitize_email( wp_unslash( $post['email'] ?? '' ) ),
'luogo_dichiarazione' => sanitize_text_field( wp_unslash( $post['luogo_dichiarazione'] ?? '' ) ),
'data_dichiarazione' => self::parse_date_input( sanitize_text_field( wp_unslash( $post['data_dichiarazione'] ?? '' ) ) ),
'bonifico_effettuato' => ! empty( $post['bonifico_effettuato'] ) ? 1 : 0,
'consenso_statuto' => ! empty( $post['accettazione_statuto'] ) ? 1 : 0,
'consenso_privacy' => ! empty( $post['consenso_privacy'] ) ? 1 : 0,
'consenso_newsletter' => ! empty( $post['consenso_newsletter'] ) ? 1 : 0,
);
}
/**
* @param array<string,mixed> $data Data.
* @return true|WP_Error
*/
private static function validate( $data ) {
$required = array(
'cognome' => __( 'Cognome', 'ton-italia-registration' ),
'nome' => __( 'Nome', 'ton-italia-registration' ),
'luogo_nascita' => __( 'Luogo di nascita', 'ton-italia-registration' ),
'provincia_nascita' => __( 'Provincia di nascita', 'ton-italia-registration' ),
'data_nascita' => __( 'Data di nascita', 'ton-italia-registration' ),
'codice_fiscale' => __( 'Codice fiscale', 'ton-italia-registration' ),
'comune_residenza' => __( 'Comune di residenza', 'ton-italia-registration' ),
'provincia_residenza' => __( 'Provincia di residenza', 'ton-italia-registration' ),
'indirizzo' => __( 'Indirizzo', 'ton-italia-registration' ),
'numero_civico' => __( 'Numero civico', 'ton-italia-registration' ),
'cap' => __( 'CAP', 'ton-italia-registration' ),
'telefono' => __( 'Telefono', 'ton-italia-registration' ),
'email' => __( 'Email', 'ton-italia-registration' ),
'luogo_dichiarazione' => __( 'Luogo dichiarazione', 'ton-italia-registration' ),
'data_dichiarazione' => __( 'Data dichiarazione', 'ton-italia-registration' ),
);
foreach ( $required as $key => $label ) {
if ( empty( $data[ $key ] ) ) {
return new WP_Error( 'required', sprintf( __( 'Il campo %s è obbligatorio.', 'ton-italia-registration' ), $label ) );
}
}
if ( ! is_email( $data['email'] ) ) {
return new WP_Error( 'email', __( 'Email non valida.', 'ton-italia-registration' ) );
}
if ( ! TON_Reg_User_Manager::validate_codice_fiscale( $data['codice_fiscale'] ) ) {
return new WP_Error( 'cf', __( 'Codice fiscale non valido.', 'ton-italia-registration' ) );
}
if ( ! preg_match( '/^\d{5}$/', $data['cap'] ) ) {
return new WP_Error( 'cap', __( 'CAP non valido.', 'ton-italia-registration' ) );
}
if ( ! preg_match( '/^[A-Z]{2}$/', $data['provincia_nascita'] ) || ! preg_match( '/^[A-Z]{2}$/', $data['provincia_residenza'] ) ) {
return new WP_Error( 'prov', __( 'Provincia non valida (2 lettere).', 'ton-italia-registration' ) );
}
if ( ! self::is_valid_date( $data['data_nascita'] ) || ! self::is_valid_date( $data['data_dichiarazione'] ) ) {
return new WP_Error( 'date', __( 'Data non valida. Usa il formato gg-mm-aaaa.', 'ton-italia-registration' ) );
}
if ( empty( $data['consenso_statuto'] ) ) {
return new WP_Error( 'statuto', __( 'Devi accettare la dichiarazione sullo statuto.', 'ton-italia-registration' ) );
}
if ( empty( $data['consenso_privacy'] ) ) {
return new WP_Error( 'privacy', __( 'Devi accettare l\'informativa privacy.', 'ton-italia-registration' ) );
}
if ( '1' === get_option( 'ton_reg_newsletter_required', '0' ) && empty( $data['consenso_newsletter'] ) ) {
return new WP_Error( 'newsletter', __( 'Devi accettare il consenso newsletter.', 'ton-italia-registration' ) );
}
return true;
}
/**
* Parse gg-mm-aaaa (or already normalized aaaa-mm-gg) to DB format Y-m-d.
*
* @param string $value User input.
* @return string Empty if invalid.
*/
private static function parse_date_input( $value ) {
$value = trim( $value );
if ( preg_match( '/^(\d{2})-(\d{2})-(\d{4})$/', $value, $m ) ) {
$day = (int) $m[1];
$month = (int) $m[2];
$year = (int) $m[3];
if ( checkdate( $month, $day, $year ) ) {
return sprintf( '%04d-%02d-%02d', $year, $month, $day );
}
return '';
}
if ( preg_match( '/^\d{4}-\d{2}-\d{2}$/', $value ) ) {
$parts = array_map( 'intval', explode( '-', $value ) );
if ( checkdate( $parts[1], $parts[2], $parts[0] ) ) {
return $value;
}
}
return '';
}
/**
* @param string $date Date Y-m-d.
* @return bool
*/
private static function is_valid_date( $date ) {
if ( ! preg_match( '/^\d{4}-\d{2}-\d{2}$/', $date ) ) {
return false;
}
$parts = array_map( 'intval', explode( '-', $date ) );
return checkdate( $parts[1], $parts[2], $parts[0] );
}
/**
* @return string
*/
private static function user_agent() {
if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
return '';
}
return substr( sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ), 0, 255 );
}
/**
* @param string $url URL.
* @param string $message Message.
*/
private static function redirect_error( $url, $message ) {
$url = add_query_arg(
array(
'ton_reg' => 'error',
'ton_msg' => rawurlencode( $message ),
),
$url
);
wp_safe_redirect( $url );
exit;
}
}