Aleš Sýkora / October 29, 2024 / 0 comments

Fluent Forms: ARES Czech Company ID Validator

Post summary: I have created a Czech Company ID (IČO) validatior via ARES for Fluent Forms.

I am not responsible for the code usage. If you need help, comment this post.

<?php

/**
 * Plugin Name: Great-tit.com - Fluent Forms ARES Validator
 * Description: Czech Business Registry (ARES) Validation for WordPress Forms
 * Version: 1.0
 * Author: Aleš Sýkora
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Plugin Configuration
 * 
 * COMPANY_ID - Your company's identification number to be excluded from validation
 * FIELD_ID - Name of the form field for company ID input
 * FIELD_NAME - Name of the form field for company name display
 * MESSAGE_* - User-facing messages (kept in Czech for end users)
 * COLOR_* - Color scheme for different states
 */
define('ARES_VALIDATOR_CONFIG', [
    // Company identification
    'COMPANY_ID' => '00000000',

    // Form field names
    'FIELD_ID' => 'spolecnost_ico',      // Company ID field
    'FIELD_NAME' => 'spolecnost',        // Company name field

    // User messages (in Czech)
    'MESSAGE_YOUR_COMPANY' => 'VAŠE FIRMA',
    'MESSAGE_VERIFYING' => 'Ověřuji...',
    'MESSAGE_FOUND' => 'Název společnosti nalezen',
    'MESSAGE_YOUR_ID' => 'Toto IČO nelze použít - jedná se o IČO vaší firmy',
    'MESSAGE_VERIFY_ERROR' => 'Chyba při ověření IČO',
    'MESSAGE_API_ERROR' => 'Došlo k chybě při ověřování',
    'MESSAGE_SHORT_ID' => 'IČO musí mít 8 číslic',
    'MESSAGE_LONG_ID' => 'IČO nesmí být delší než 8 číslic',

    // Status colors
    'COLOR_INFO' => '#666',
    'COLOR_SUCCESS' => '#0f9d58',
    'COLOR_ERROR' => '#dc3232'
]);

/**
 * Adds the necessary JavaScript to the frontend
 * Initializes ARES validation functionality
 */
function add_ares_validator_script()
{
    $config = ARES_VALIDATOR_CONFIG;

    $script = "
    /* Pass PHP config to JavaScript */
    const ARES_CONFIG = " . json_encode($config) . ";
    
    document.addEventListener('DOMContentLoaded', function() {
        console.log('ARES Validator: Initialization');
        
        /* Get form field elements */
        const companyIdInput = document.querySelector('input[name=\"' + ARES_CONFIG.FIELD_ID + '\"]');
        const companyNameInput = document.querySelector('input[name=\"' + ARES_CONFIG.FIELD_NAME + '\"]');
        
        /* Validate field existence */
        if (!companyIdInput || !companyNameInput) {
            console.log('ARES Validator: Required fields not found');
            return;
        }
        
        /* Create message display element */
        const messageDisplay = document.createElement('div');
        messageDisplay.style.display = 'none';
        messageDisplay.className = 'ff-el-help-message';
        companyIdInput.closest('.ff-el-input--content').appendChild(messageDisplay);
        
        let validationTimer;
        
        /* Handle input changes */
        companyIdInput.addEventListener('input', function(e) {
            const companyId = this.value.trim();
            console.log('ARES Validator: Entered ID:', companyId);
            
            /* Clear previous timeout */
            if (validationTimer) {
                clearTimeout(validationTimer);
            }
            
            /* Validate ID length */
            if (companyId.length > 0) {
                messageDisplay.style.display = 'inline';
                if (companyId.length < 8) {
                    messageDisplay.textContent = ARES_CONFIG.MESSAGE_SHORT_ID + ' (' + companyId.length + '/8)';
                    messageDisplay.style.color = ARES_CONFIG.COLOR_INFO;
                    companyNameInput.value = '';
                } else if (companyId.length > 8) {
                    messageDisplay.textContent = ARES_CONFIG.MESSAGE_LONG_ID;
                    messageDisplay.style.color = ARES_CONFIG.COLOR_ERROR;
                    companyNameInput.value = '';
                    return;
                }
            } else {
                messageDisplay.style.display = 'none';
                companyNameInput.value = '';
                return;
            }
            
            /* Process valid company ID */
            if (companyId.length === 8) {
                console.log('ARES Validator: Starting verification');
                
                validationTimer = setTimeout(() => {
                    messageDisplay.textContent = ARES_CONFIG.MESSAGE_VERIFYING;
                    messageDisplay.style.color = ARES_CONFIG.COLOR_INFO;
                    
                    const formData = new FormData();
                    formData.append('action', 'verify_company_id');
                    formData.append('ico', companyId);
                    
                    /* Make API request */
                    fetch(ajaxurl, {
                        method: 'POST',
                        body: formData
                    })
                    .then(response => response.json())
                    .then(data => {
                        console.log('ARES Validator: Server response:', data);
                        
                        if (data.success) {
                            if (data.data.message === 'Vaše IČO') {
                                /* Handle own company ID */
                                messageDisplay.textContent = ARES_CONFIG.MESSAGE_YOUR_ID;
                                messageDisplay.style.color = ARES_CONFIG.COLOR_ERROR;
                                companyNameInput.value = '';
                            } else if (data.data.company_name) {
                                /* Handle found company */
                                companyNameInput.value = data.data.company_name;
                                messageDisplay.textContent = ARES_CONFIG.MESSAGE_FOUND;
                                messageDisplay.style.color = ARES_CONFIG.COLOR_SUCCESS;
                            }
                        } else {
                            /* Handle error response */
                            messageDisplay.textContent = data.data?.message || ARES_CONFIG.MESSAGE_VERIFY_ERROR;
                            messageDisplay.style.color = ARES_CONFIG.COLOR_ERROR;
                            companyNameInput.value = '';
                        }
                    })
                    .catch(error => {
                        /* Handle API error */
                        console.error('ARES Validator: API Error:', error);
                        messageDisplay.textContent = ARES_CONFIG.MESSAGE_API_ERROR;
                        messageDisplay.style.color = ARES_CONFIG.COLOR_ERROR;
                        companyNameInput.value = '';
                    });
                }, 300);
            }
        });
        
        /* Prevent entering more than 8 digits */
        companyIdInput.addEventListener('keydown', function(e) {
            const companyId = this.value.trim();
            if (companyId.length >= 8 && 
                !e.key.match(/Backspace|Delete|ArrowLeft|ArrowRight|Tab/) && 
                !e.ctrlKey && !e.metaKey) {
                e.preventDefault();
            }
        });
        
        console.log('ARES Validator: Initialization complete');
    });
    ";

    wp_register_script('ares-validator', '', [], '', true);
    wp_enqueue_script('ares-validator');
    wp_add_inline_script('ares-validator', 'var ajaxurl = "' . admin_url('admin-ajax.php') . '";');
    wp_add_inline_script('ares-validator', $script);
}
add_action('wp_enqueue_scripts', 'add_ares_validator_script');

/**
 * Handle AJAX requests for company verification
 */
add_action('wp_ajax_verify_company_id', 'handle_company_verification');
add_action('wp_ajax_nopriv_verify_company_id', 'handle_company_verification');

function handle_company_verification()
{
    $config = ARES_VALIDATOR_CONFIG;

    if (!isset($_POST['ico'])) {
        wp_send_json_error(['message' => 'IČO nebylo zasláno']);
        return;
    }

    $company_id = sanitize_text_field($_POST['ico']);

    // Check if it's our company ID
    if ($company_id === $config['COMPANY_ID']) {
        wp_send_json_success(['message' => 'Vaše IČO']);
        return;
    }

    // Validate ID length
    if (strlen($company_id) !== 8) {
        wp_send_json_error(['message' => $config['MESSAGE_SHORT_ID']]);
        return;
    }

    // Validate ID format
    if (!preg_match('/^[0-9]{8}$/', $company_id)) {
        wp_send_json_error(['message' => 'IČO může obsahovat pouze číslice']);
        return;
    }

    $company_name = verify_company_in_ares($company_id);

    if ($company_name) {
        wp_send_json_success(['company_name' => $company_name]);
    } else {
        wp_send_json_error(['message' => 'Společnost nenalezena']);
    }

    wp_die();
}

/**
 * Verify company ID in ARES registry
 * 
 * @param string $company_id Company identification number
 * @return string|false Company name if found, false otherwise
 */
function verify_company_in_ares($company_id)
{
    $url = 'https://ares.gov.cz/ekonomicke-subjekty-v-be/rest/ekonomicke-subjekty-res/' . $company_id;

    $response = wp_remote_get($url, [
        'headers' => [
            'Accept' => 'application/json'
        ],
        'timeout' => 15
    ]);

    if (is_wp_error($response)) {
        return false;
    }

    $body = wp_remote_retrieve_body($response);
    $data = json_decode($body, true);

    if (json_last_error() !== JSON_ERROR_NONE) {
        return false;
    }

    if (!isset($data['zaznamy'][0]['ico']) || $data['zaznamy'][0]['ico'] !== $company_id) {
        return false;
    }

    return $data['zaznamy'][0]['obchodniJmeno'];
}

Fuel my passion for writing with a beer🍺

Your support not only makes me drunk but also greatly motivates me to continue creating content that helps. Cheers to more discoveries and shared success. 🍻

0 comments

Share Your Thoughts