Newer
Older
tonitalia-pluginsoci / includes / class-registration-form.php
<?php
/**
 * Registration form shortcode.
 *
 * @package TonItaliaRegistration
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class TON_Reg_Registration_Form
 */
class TON_Reg_Registration_Form {

	/**
	 * Register hooks.
	 */
	public static function register() {
		add_shortcode( 'ton_registration_form', array( __CLASS__, 'render_shortcode' ) );
		add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_assets' ) );
	}

	/**
	 * Enqueue form assets.
	 */
	public static function enqueue_assets() {
		if ( ! self::page_has_shortcode() ) {
			return;
		}
		wp_enqueue_style(
			'ton-reg-form',
			TON_REG_PLUGIN_URL . 'assets/css/form.css',
			array(),
			TON_REG_VERSION
		);
		wp_enqueue_script(
			'ton-reg-form',
			TON_REG_PLUGIN_URL . 'assets/js/form.js',
			array(),
			TON_REG_VERSION,
			true
		);

		wp_localize_script(
			'ton-reg-form',
			'tonRegForm',
			array(
				'msgRequired'   => __( 'Compila questo campo.', 'ton-italia-registration' ),
				'msgEmail'      => __( 'Inserisci un indirizzo email valido.', 'ton-italia-registration' ),
				'msgCf'         => __( 'Codice fiscale non valido (16 caratteri).', 'ton-italia-registration' ),
				'msgCap'        => __( 'Il CAP deve essere di 5 cifre.', 'ton-italia-registration' ),
				'msgProvincia'  => __( 'Inserisci la sigla provincia (2 lettere).', 'ton-italia-registration' ),
				'msgDate'       => __( 'Inserisci la data nel formato gg-mm-aaaa.', 'ton-italia-registration' ),
				'msgCheckbox'   => __( 'Devi selezionare questa casella per continuare.', 'ton-italia-registration' ),
				'msgCaptcha'    => __( 'Inserisci la risposta alla verifica anti-spam.', 'ton-italia-registration' ),
			)
		);
	}

	/**
	 * @return bool
	 */
	private static function page_has_shortcode() {
		global $post;
		return $post instanceof WP_Post && has_shortcode( $post->post_content, 'ton_registration_form' );
	}

	/**
	 * @param array<string,string> $atts Attributes.
	 * @return string
	 */
	public static function render_shortcode( $atts ) {
		$atts = shortcode_atts(
			array( 'class' => '' ),
			$atts,
			'ton_registration_form'
		);

		if ( isset( $_GET['ton_reg'] ) && 'success' === $_GET['ton_reg'] ) {
			return self::render_message( 'success' );
		}

		$token     = TON_Reg_Captcha::create_token();
		$challenge = TON_Reg_Captcha::generate_challenge( $token );

		ob_start();
		self::render_form( $atts['class'], $token, $challenge );
		return ob_get_clean();
	}

	/**
	 * @param string $type success|error.
	 * @return string
	 */
	private static function render_message( $type ) {
		if ( 'success' === $type ) {
			$html = get_option( 'ton_reg_success_message', '' );
			return '<div class="ton-reg-form ton-reg-form--success">' . wp_kses_post( $html ) . '</div>';
		}
		$msg = isset( $_GET['ton_msg'] ) ? sanitize_text_field( wp_unslash( rawurldecode( $_GET['ton_msg'] ) ) ) : '';
		return '<div class="ton-reg-form ton-reg-form--error"><p>' . esc_html( $msg ) . '</p></div>';
	}

	/**
	 * @param string               $extra_class Extra CSS class.
	 * @param string               $token       Form token.
	 * @param array<string,mixed>  $challenge   Captcha challenge.
	 */
	private static function render_form( $extra_class, $token, $challenge ) {
		$payment = self::replace_payment_placeholders( get_option( 'ton_reg_payment_instructions', '' ) );
		$class   = 'ton-reg-form' . ( $extra_class ? ' ' . esc_attr( $extra_class ) : '' );

		if ( isset( $_GET['ton_reg'] ) && 'error' === $_GET['ton_reg'] ) {
			echo self::render_message( 'error' );
		}
		?>
		<form class="<?php echo esc_attr( $class ); ?>" method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
			<input type="hidden" name="action" value="ton_reg_submit" />
			<?php wp_nonce_field( TON_Reg_Captcha::NONCE_ACTION, 'ton_reg_nonce' ); ?>
			<input type="hidden" name="<?php echo esc_attr( TON_Reg_Captcha::FIELD_TOKEN ); ?>" value="<?php echo esc_attr( $token ); ?>" />

			<p class="ton-reg-form__intro"><?php esc_html_e( 'Domanda di ammissione a socio e contestuale tesseramento', 'ton-italia-registration' ); ?></p>

			<fieldset class="ton-reg-form__fieldset ton-reg-form__payment">
				<legend><?php esc_html_e( 'Quota associativa', 'ton-italia-registration' ); ?></legend>
				<div class="ton-reg-form__richtext"><?php echo wp_kses_post( $payment ); ?></div>
				<label class="ton-reg-form__checkbox">
					<input type="checkbox" name="bonifico_effettuato" value="1" />
					<span><?php esc_html_e( 'Ho effettuato il bonifico (o provvederò a breve)', 'ton-italia-registration' ); ?></span>
				</label>
			</fieldset>

			<fieldset class="ton-reg-form__fieldset">
				<legend><?php esc_html_e( 'Dati anagrafici', 'ton-italia-registration' ); ?></legend>
				<div class="ton-reg-form__grid">
					<?php self::field_text( 'cognome', __( 'Cognome', 'ton-italia-registration' ), true ); ?>
					<?php self::field_text( 'nome', __( 'Nome', 'ton-italia-registration' ), true ); ?>
					<?php self::field_text( 'luogo_nascita', __( 'Nato/a a', 'ton-italia-registration' ), true ); ?>
					<?php self::field_text( 'provincia_nascita', __( 'Prov.', 'ton-italia-registration' ), true, '2', 'text', '', '[A-Z]{2}' ); ?>
					<?php self::field_text( 'data_nascita', __( 'Data di nascita', 'ton-italia-registration' ), true, '10', 'text', '', '[0-9]{2}-[0-9]{2}-[0-9]{4}' ); ?>
					<?php self::field_text( 'codice_fiscale', __( 'Codice fiscale', 'ton-italia-registration' ), true, '16', 'text', '', '[A-Za-z]{6}[0-9]{2}[A-Za-z][0-9]{2}[A-Za-z][0-9]{3}[A-Za-z]' ); ?>
					<?php self::field_text( 'comune_residenza', __( 'Residente in', 'ton-italia-registration' ), true ); ?>
					<?php self::field_text( 'provincia_residenza', __( 'Prov.', 'ton-italia-registration' ), true, '2', 'text', '', '[A-Z]{2}' ); ?>
					<?php self::field_text( 'indirizzo', __( 'Via/Piazza', 'ton-italia-registration' ), true ); ?>
					<?php self::field_text( 'numero_civico', __( 'n.', 'ton-italia-registration' ), true, '10' ); ?>
					<?php self::field_text( 'cap', __( 'CAP', 'ton-italia-registration' ), true, '5', 'text', '', '[0-9]{5}' ); ?>
					<?php self::field_text( 'telefono', __( 'Telefono / Cellulare', 'ton-italia-registration' ), true, '', 'tel' ); ?>
					<?php self::field_text( 'email', __( 'Email', 'ton-italia-registration' ), true, '', 'email' ); ?>
				</div>
			</fieldset>

			<fieldset class="ton-reg-form__fieldset">
				<legend><?php esc_html_e( 'Dichiarazione', 'ton-italia-registration' ); ?></legend>
				<p class="ton-reg-form__declaration"><?php echo esc_html( get_option( 'ton_reg_statuto_declaration', '' ) ); ?></p>
				<div class="ton-reg-form__grid ton-reg-form__grid--narrow">
					<?php self::field_text( 'luogo_dichiarazione', __( 'Luogo', 'ton-italia-registration' ), true ); ?>
					<?php self::field_text( 'data_dichiarazione', __( 'Data', 'ton-italia-registration' ), true, '10', 'text', '', '[0-9]{2}-[0-9]{2}-[0-9]{4}' ); ?>
				</div>
				<label class="ton-reg-form__checkbox ton-reg-form__checkbox--required">
					<input type="checkbox" name="accettazione_statuto" value="1" required />
					<span><?php esc_html_e( 'Dichiaro di aver letto e accettato quanto sopra (sostitutivo della firma).', 'ton-italia-registration' ); ?></span>
				</label>
				<p class="ton-reg-form__minor"><?php echo esc_html( get_option( 'ton_reg_minor_notice', '' ) ); ?></p>
			</fieldset>

			<fieldset class="ton-reg-form__fieldset">
				<legend><?php esc_html_e( 'Privacy', 'ton-italia-registration' ); ?></legend>
				<div class="ton-reg-form__richtext"><?php echo wp_kses_post( get_option( 'ton_reg_privacy_notice', '' ) ); ?></div>
				<label class="ton-reg-form__checkbox ton-reg-form__checkbox--required">
					<input type="checkbox" name="consenso_privacy" value="1" required />
					<span><?php esc_html_e( 'Acconsento al trattamento dei dati personali come da informativa (sostitutivo della firma per consenso).', 'ton-italia-registration' ); ?></span>
				</label>
				<label class="ton-reg-form__checkbox<?php echo '1' === get_option( 'ton_reg_newsletter_required', '0' ) ? ' ton-reg-form__checkbox--required' : ''; ?>">
					<input type="checkbox" name="consenso_newsletter" value="1" <?php echo '1' === get_option( 'ton_reg_newsletter_required', '0' ) ? 'required' : ''; ?> />
					<span><?php echo esc_html( get_option( 'ton_reg_newsletter_label', '' ) ); ?></span>
				</label>
			</fieldset>

			<?php if ( TON_Reg_Captcha::is_enabled() ) : ?>
			<fieldset class="ton-reg-form__fieldset ton-reg-form__captcha">
				<legend><?php esc_html_e( 'Verifica anti-spam', 'ton-italia-registration' ); ?></legend>
				<label class="ton-reg-form__honeypot" aria-hidden="true">
					<?php esc_html_e( 'Lascia vuoto questo campo', 'ton-italia-registration' ); ?>
					<input type="text" name="<?php echo esc_attr( TON_Reg_Captcha::FIELD_HONEYPOT ); ?>" value="" tabindex="-1" autocomplete="off" />
				</label>
				<p class="ton-reg-form__field">
					<label for="ton_reg_captcha_answer"><?php echo esc_html( $challenge['question'] ); ?> <span class="required">*</span></label>
					<input type="number" id="ton_reg_captcha_answer" class="ton-reg-form__input" name="<?php echo esc_attr( TON_Reg_Captcha::FIELD_MATH ); ?>" required inputmode="numeric" placeholder="<?php esc_attr_e( 'Inserisci il risultato', 'ton-italia-registration' ); ?>" />
				</p>
			</fieldset>
			<?php endif; ?>

			<p class="ton-reg-form__submit">
				<button type="submit" class="ton-reg-form__button"><?php esc_html_e( 'Invia domanda di iscrizione', 'ton-italia-registration' ); ?></button>
			</p>
		</form>
		<?php
	}

	/**
	 * @param string $name        Field name.
	 * @param string $label       Label.
	 * @param bool   $required    Required.
	 * @param string $maxlength   Max length.
	 * @param string $type        Input type.
	 * @param string $placeholder Placeholder override.
	 * @param string $pattern     HTML pattern.
	 */
	private static function field_text( $name, $label, $required = false, $maxlength = '', $type = 'text', $placeholder = '', $pattern = '' ) {
		$id          = 'ton_reg_' . $name;
		$holders     = self::placeholders();
		$placeholder = '' !== $placeholder ? $placeholder : ( $holders[ $name ] ?? '' );
		?>
		<p class="ton-reg-form__field" data-field="<?php echo esc_attr( $name ); ?>">
			<label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( $label ); ?><?php if ( $required ) : ?> <span class="required">*</span><?php endif; ?></label>
			<input
				class="ton-reg-form__input"
				type="<?php echo esc_attr( $type ); ?>"
				id="<?php echo esc_attr( $id ); ?>"
				name="<?php echo esc_attr( $name ); ?>"
				value="<?php echo esc_attr( self::old( $name ) ); ?>"
				<?php echo $required ? 'required' : ''; ?>
				<?php echo $maxlength ? 'maxlength="' . esc_attr( $maxlength ) . '"' : ''; ?>
				<?php echo $placeholder ? 'placeholder="' . esc_attr( $placeholder ) . '"' : ''; ?>
				<?php echo $pattern ? 'pattern="' . esc_attr( $pattern ) . '"' : ''; ?>
				<?php echo 'email' === $type ? 'autocomplete="email"' : ''; ?>
			/>
			<span class="ton-reg-form__error" role="alert" hidden></span>
		</p>
		<?php
	}

	/**
	 * @return array<string, string>
	 */
	private static function placeholders() {
		return array(
			'cognome'              => __( 'Inserisci il cognome', 'ton-italia-registration' ),
			'nome'                 => __( 'Inserisci il nome', 'ton-italia-registration' ),
			'luogo_nascita'        => __( 'Comune o stato di nascita', 'ton-italia-registration' ),
			'provincia_nascita'    => __( 'Sigla provincia, es. VR', 'ton-italia-registration' ),
			'data_nascita'         => __( 'gg-mm-aaaa', 'ton-italia-registration' ),
			'codice_fiscale'       => __( '16 caratteri alfanumerici', 'ton-italia-registration' ),
			'comune_residenza'     => __( 'Comune di residenza', 'ton-italia-registration' ),
			'provincia_residenza'  => __( 'Sigla provincia, es. MI', 'ton-italia-registration' ),
			'indirizzo'            => __( 'Via o piazza', 'ton-italia-registration' ),
			'numero_civico'        => __( 'Numero civico', 'ton-italia-registration' ),
			'cap'                  => __( '5 cifre', 'ton-italia-registration' ),
			'telefono'             => __( 'Telefono o cellulare', 'ton-italia-registration' ),
			'email'                => __( 'nome@esempio.it', 'ton-italia-registration' ),
			'luogo_dichiarazione'  => __( 'Comune della dichiarazione', 'ton-italia-registration' ),
			'data_dichiarazione'   => __( 'gg-mm-aaaa', 'ton-italia-registration' ),
		);
	}

	/**
	 * @param string $key Field key.
	 * @return string
	 */
	private static function old( $key ) {
		// No session storage for security; empty on fresh load.
		return '';
	}

	/**
	 * @param string $html HTML template.
	 * @return string
	 */
	private static function replace_payment_placeholders( $html ) {
		return strtr(
			$html,
			array(
				'{quota}'        => esc_html( get_option( 'ton_reg_membership_fee', '10,00' ) ),
				'{anno}'         => esc_html( get_option( 'ton_reg_social_year', '2026' ) ),
				'{beneficiario}' => esc_html( get_option( 'ton_reg_beneficiary', '' ) ),
				'{iban}'         => esc_html( get_option( 'ton_reg_iban', '' ) ),
				'{nome}'         => '',
				'{cognome}'      => '',
			)
		);
	}
}