selcukmart/form-generator

Modern PHP Form Generator with Chain Pattern - Supports Symfony, Laravel, Twig, and Smarty

Installs: 7

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 1

Open Issues: 0

pkg:composer/selcukmart/form-generator


README

PHP Version License Version Tests

Modern PHP Form Generator

A production-ready form builder library offering nested forms, type system, cross-field validation, dynamic form modification, advanced error handling, internationalization, and automatic CSRF protection.

Version 3.0.0 - Production Ready

FormGenerator V3.0.0 is a comprehensive form building library with an intuitive fluent API.

Key Features

Enterprise-Grade Form Builder

  • Comprehensive form building capabilities
  • Fluent chain pattern API
  • Framework-agnostic design (standalone or integrate with Symfony/Laravel)
  • 500+ comprehensive unit tests

🌍 Internationalization (NEW in v3.0.0)

  • Multi-language form labels and messages
  • Built-in translator with PHP and YAML loaders
  • Parameter interpolation ({{ param }} syntax)
  • Locale fallback chains

πŸ”’ Automatic CSRF Protection (NEW in v3.0.0)

  • Session-based token management
  • Automatic token generation and validation
  • Configurable token lifetime (default: 2 hours)
  • Zero configuration required

πŸ“– Read Full V3 Documentation β†’

Quick Start - Simple Contact Form with i18n & CSRF

use FormGenerator\V2\Builder\FormBuilder;
use FormGenerator\V2\Translation\FormTranslator;
use FormGenerator\V2\Translation\Loader\PhpLoader;

// Setup translator (optional)
$translator = new FormTranslator('en_US');
$translator->addLoader('php', new PhpLoader());
$translator->loadTranslationFile(__DIR__ . '/translations/forms.en_US.php', 'en_US', 'php');

FormBuilder::setTranslator($translator);

// Build form with CSRF protection (automatic!)
$form = FormBuilder::create('contact_form')
    ->setAction('/contact/send')
    ->setMethod('POST')
    ->setCsrfTokenId('contact_form') // Automatic CSRF protection

    ->addText('name', 'form.label.name') // Translated automatically
        ->required()
        ->minLength(3)
        ->add()

    ->addEmail('email', 'form.label.email')
        ->required()
        ->add()

    ->addTextarea('message', 'form.label.message')
        ->required()
        ->minLength(20)
        ->add()

    ->addSubmit('send', 'form.button.send')
    ->build();

// Render with automatic CSRF token
echo $form;

Nested Forms with Cross-Field Validation

use FormGenerator\V2\Builder\FormBuilder;
use FormGenerator\V2\Form\Form;
use FormGenerator\V2\Validation\Constraints\Callback;

// Create address sub-form
$addressForm = new Form('address');
$addressForm->add('street', FormBuilder::text('street', 'Street'));
$addressForm->add('city', FormBuilder::text('city', 'City'));
$addressForm->add('zipcode', FormBuilder::text('zipcode', 'ZIP Code'));

// Create user form with nested address
$form = FormBuilder::create('user_registration')
    ->setCsrfTokenId('register')

    ->addText('username', 'Username')
        ->required()
        ->minLength(3)
        ->add()

    ->addPassword('password', 'Password')
        ->required()
        ->minLength(8)
        ->add()

    ->addPassword('password_confirm', 'Confirm Password')
        ->required()
        ->add()

    ->add('address', $addressForm) // Nested form!

    ->build();

// Add cross-field validation
$form->addConstraint(new Callback(function($data, $context) {
    if ($data['password'] !== $data['password_confirm']) {
        $context->buildViolation('Passwords do not match')
                ->atPath('password_confirm')
                ->addViolation();
    }
}));

// Validate and handle errors
$form->submit($_POST);
if ($form->isValid()) {
    // Process data
} else {
    $errors = $form->getErrorList(deep: true);
}

Dynamic Form Modification with Events

use FormGenerator\V2\Builder\FormBuilder;
use FormGenerator\V2\Event\FormEvents;

$form = FormBuilder::create('product_form')
    ->setCsrfTokenId('product')

    ->addSelect('product_type', 'Product Type')
        ->options([
            'physical' => 'Physical Product',
            'digital' => 'Digital Product',
        ])
        ->add()

    ->build();

// Add fields dynamically based on product type
$form->addEventListener(FormEvents::PRE_SET_DATA, function($event) {
    $data = $event->getData();
    $form = $event->getForm();

    if ($data['product_type'] === 'physical') {
        // Add shipping fields
        $form->add('weight', FormBuilder::number('weight', 'Weight (kg)'));
        $form->add('dimensions', FormBuilder::text('dimensions', 'Dimensions'));
    } else {
        // Add download fields
        $form->add('file_size', FormBuilder::text('file_size', 'File Size'));
        $form->add('download_limit', FormBuilder::number('download_limit', 'Downloads'));
    }
});

πŸ“Š Complete Feature Set

v3.0.0 - Internationalization & CSRF (Current)

  • 🌍 Multi-language support with built-in translator
  • πŸ”’ Automatic CSRF protection
  • πŸ“ Multiple translation loaders (PHP, YAML)
  • πŸ”„ Parameter interpolation in messages

v2.9.0 - Advanced Error Handling

  • ⚠️ Three error levels (ERROR, WARNING, INFO)
  • 🎯 Error bubbling from nested forms
  • πŸ“‹ Rich error metadata
  • πŸ” Error filtering and grouping

v2.8.0 - Dynamic Form Modification

  • 🎭 Event-driven form building
  • πŸ”„ Modify forms based on data
  • βž• Add/remove fields dynamically
  • 🎬 Full event lifecycle

v2.7.0 - Cross-Field Validation

  • βœ… Field relationship validation
  • 🎯 Validation groups
  • πŸ“ Custom callback constraints
  • πŸ”§ Execution context

v2.5.0 - Type System

  • πŸ—οΈ Custom field types
  • 🎨 Type inheritance
  • πŸ”Œ Type extensions
  • βš™οΈ Options resolver

v2.4.0 - Nested Forms

  • 🌳 Unlimited nesting
  • πŸ” Form collections
  • πŸ‘¨β€πŸ‘©β€πŸ‘§ Parent-child relationships
  • πŸ—ΊοΈ Data mapping

Earlier Features

  • πŸ”„ Data transformation (v2.3.1)
  • 🎯 Event-driven dependencies (v2.3.0)
  • βœ… Laravel-style validation (v2.1.0)
  • 🎨 Bootstrap 5 & Tailwind themes
  • πŸ” CSRF, XSS protection
  • πŸš€ Symfony & Laravel integration

πŸ“¦ Installation

composer require selcukmart/form-generator

πŸ§ͺ Testing

500+ Comprehensive Unit Tests

# Run all tests
vendor/bin/phpunit

# Run specific test suite
vendor/bin/phpunit tests/V2/Type/          # Type system tests
vendor/bin/phpunit tests/V2/Validation/    # Validation tests
vendor/bin/phpunit tests/V2/Event/         # Event system tests
vendor/bin/phpunit tests/V2/Error/         # Error handling tests
vendor/bin/phpunit tests/V2/Translation/   # i18n tests
vendor/bin/phpunit tests/V2/Security/      # CSRF tests

# With coverage
vendor/bin/phpunit --coverage-html coverage/

Test Coverage:

  • βœ… 400+ unit tests
  • βœ… 100+ integration tests
  • βœ… Full API coverage
  • βœ… Edge case handling
  • βœ… Real-world scenarios

πŸ”„ Migration from Symfony Forms

Before (Symfony Form Component)

$form = $this->createFormBuilder()
    ->add('username', TextType::class, [
        'required' => true,
        'constraints' => [new Length(['min' => 3])]
    ])
    ->add('email', EmailType::class)
    ->getForm();

After (FormGenerator)

$form = FormBuilder::create('user_form')
    ->addText('username')->required()->minLength(3)->add()
    ->addEmail('email')->required()->add()
    ->build();

Advantages:

  • 🎯 Chain pattern is more readable
  • πŸš€ No need for type classes
  • πŸ”§ Less boilerplate code
  • πŸ’‘ Better IDE autocomplete
  • 🎨 Cleaner syntax

See SYMFONY_ALTERNATIVE_ROADMAP.md for complete migration guide.

πŸ“š Complete Documentation

Core Documentation

Examples by Version

🌍 v3.0.0 - Internationalization & CSRF (NEW!)

⚠️ v2.9.0 - Error Handling

🎭 v2.8.0 - Dynamic Forms

βœ… v2.7.0 - Cross-Field Validation

πŸ—οΈ v2.5.0 - Type System

🌳 v2.4.0 - Nested Forms

Earlier Features

🀝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Areas for contribution:

  • Additional field types
  • More translation loaders
  • Framework integrations
  • Theme development
  • Documentation improvements

πŸ“ Version History

  • v3.0.0 (2025) - i18n & Auto CSRF - Current ⭐
  • v2.9.0 (2025) - Advanced Error Handling & Bubbling
  • v2.8.0 (2025) - Dynamic Form Modification
  • v2.7.0 (2024) - Cross-Field Validation & Groups
  • v2.5.0 (2024) - Type System & Extensions
  • v2.4.0 (2024) - Nested Forms & Collections
  • v2.3.1 (2024) - Data Transformation
  • v2.3.0 (2024) - Event-Driven Dependencies
  • v2.1.0 (2024) - Laravel-Style Validation
  • v2.0.0 (2024) - Complete rewrite with chain pattern

See CHANGELOG.md for details.

πŸ“„ License

MIT License - see LICENSE for details.

πŸ‘¨β€πŸ’» Author

selcukmart

🌟 Star History

If this project helped you, please give it a ⭐ on GitHub!

Made with ❀️ using modern PHP 8.1+

Production-ready β€’ Secure by Default β€’ Internationalized β€’ Framework-agnostic