Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Liform Laravel Package

dariotilgner/liform

Serialize Symfony Forms into JSON Schema for documentation, validation, and client-side form generation. Works with generators like liform-react or json-editor, and powers LiformBundle. Use as a standalone library to keep backend and frontend forms in sync.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require dariotilgner/liform
    

    Add to composer.json if not auto-loaded:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "DarioTilgner\\Liform\\": "vendor/dariotilgner/liform/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case Convert a Symfony Form to JSON Schema in a Laravel controller:

    use DarioTilgner\Liform\Liform;
    use Symfony\Component\Form\FormInterface;
    
    public function getSchema(FormInterface $form)
    {
        $liform = new Liform();
        $schema = $liform->transform($form);
        return response()->json($schema);
    }
    
  3. Key Files

    • src/Liform.php: Core transformer class.
    • src/Type/: Type-specific schema generators (e.g., TextType.php).

Implementation Patterns

Workflow: Form-to-Schema Pipeline

  1. Define Symfony Form

    $builder = $this->createFormBuilder($data);
    $builder->add('name', TextType::class);
    $builder->add('email', EmailType::class);
    $form = $builder->getForm();
    
  2. Transform to JSON Schema

    $liform = new Liform();
    $schema = $liform->transform($form);
    // $schema = [
    //     "type": "object",
    //     "properties": {
    //         "name": {"type": "string"},
    //         "email": {"type": "string", "format": "email"}
    //     }
    // ]
    
  3. Integrate with API Responses

    return response()->json([
        'schema' => $schema,
        'form_data' => $form->getData()
    ]);
    

Common Patterns

  • Dynamic Forms: Use FormFactory to generate forms dynamically and transform them on-the-fly.
  • Validation Rules: Map Symfony constraints (e.g., @Assert\Length) to JSON Schema keywords (minLength, maxLength).
    $builder->add('bio', TextType::class, [
        'constraints' => [new Length(['min' => 10])]
    ]);
    
  • Nested Forms: Handle CollectionType or FormType for nested objects/arrays.
    $builder->add('addresses', CollectionType::class, [
        'entry_type' => AddressType::class,
        'allow_add' => true
    ]);
    

Integration Tips

  • Laravel Validation: Use the generated schema to validate incoming requests with validator()->make($data, $schema).
  • Frontend Frameworks: Pass the schema to Vue/React forms (e.g., vee-validate or formik) for dynamic rendering.
  • Documentation: Auto-generate OpenAPI specs by combining schemas with route definitions.

Gotchas and Tips

Pitfalls

  1. Unsupported Types

    • Not all Symfony types are mapped. Check src/Type/ for coverage.
    • Workaround: Extend Liform or create custom type handlers (see below).
  2. Constraint Mismaps

    • Some constraints (e.g., @Assert\Callback) won’t translate to JSON Schema.
    • Tip: Log unsupported constraints with:
      $liform->setLogger(new \Monolog\Logger('liform'));
      
  3. Circular References

    • Nested forms with mutual references (e.g., UserProfile) may cause infinite loops.
    • Fix: Use $liform->setMaxDepth(5) to limit recursion.
  4. Default Values

    • Symfony’s data option may not always map to JSON Schema’s default.
    • Tip: Explicitly set defaults in the form builder:
      $builder->add('status', ChoiceType::class, [
          'choices' => ['active', 'inactive'],
          'default' => 'active'
      ]);
      

Debugging

  • Enable Verbose Output:
    $liform->setDebug(true); // Logs unsupported types/constraints
    
  • Inspect Intermediate Steps:
    $transformer = $liform->getTransformer();
    $transformer->setDebug(true);
    

Extension Points

  1. Custom Type Handlers Create a new type class (e.g., CustomType.php) extending AbstractType:

    namespace App\Liform\Type;
    use DarioTilgner\Liform\Type\AbstractType;
    
    class CustomType extends AbstractType {
        public function getSchema() {
            return ['type' => 'string', 'custom' => true];
        }
    }
    

    Register it in Liform:

    $liform->addType('custom', CustomType::class);
    
  2. Override Default Behavior Replace the default Transformer:

    $liform->setTransformer(new \App\CustomTransformer());
    
  3. Post-Processing Modify the schema after transformation:

    $schema = $liform->transform($form);
    $schema['additionalProperties'] = false; // Enforce strict schema
    

Configuration Quirks

  • Schema Version: Defaults to draft-07. Override with:
    $liform->setSchemaVersion('draft-06');
    
  • Array Handling: By default, CollectionType maps to array. Force object for keyed collections:
    $builder->add('items', CollectionType::class, [
        'entry_type' => ItemType::class,
        'by_reference' => false,
        'allow_add' => true
    ]);
    $liform->setArrayAsObject(true);
    

Performance

  • Cache Transformed Schemas: Store schemas in Laravel’s cache for repeated forms:
    $cacheKey = 'form_schema_'.$form->getName();
    $schema = Cache::remember($cacheKey, 60, function() use ($form) {
        return $liform->transform($form);
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope