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

Jsonform Laravel Package

effiana/jsonform

Serialize Symfony Forms into JSON Schema for documentation, validation, and client-side form generation. Map form field types to transformers via a resolver, then transform a Form into a JSON schema usable with tools like json-editor or liform-react.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require effiana/jsonform
    

    Add to composer.json if not auto-loaded:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Effiana\\JsonForm\\": "vendor/effiana/jsonform/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case Convert a Symfony FormBuilder to JSON Schema:

    use Effiana\JsonForm\JsonForm;
    use Symfony\Component\Form\FormBuilderInterface;
    
    $form = $this->createFormBuilder()
        ->add('name', TextType::class)
        ->add('email', EmailType::class)
        ->getForm();
    
    $jsonSchema = (new JsonForm())->transform($form);
    
  3. Where to Look First

    • Core Class: JsonForm (main transformer).
    • Type Mappings: TypeMapper (handles Symfony field types → JSON Schema).
    • Tests: Tests for edge cases (e.g., nested forms, custom types).

Implementation Patterns

Workflow: Form → JSON Schema → Frontend

  1. Define Symfony Form

    $form = $this->createFormBuilder()
        ->add('user', EntityType::class, [
            'class' => User::class,
            'property' => 'name',
            'label' => 'Select User',
        ])
        ->add('active', ChoiceType::class, [
            'choices' => [true => 'Yes', false => 'No'],
        ])
        ->getForm();
    
  2. Transform to JSON Schema

    $schema = (new JsonForm())->transform($form);
    // Outputs:
    // {
    //   "type": "object",
    //   "properties": {
    //     "user": { "type": "string" },
    //     "active": { "type": "boolean" }
    //   }
    // }
    
  3. Extend for Custom Types Override TypeMapper for unsupported fields (e.g., DateTimeType):

    $mapper = new TypeMapper();
    $mapper->addType('datetime', function() {
        return ['type' => 'string', 'format' => 'date-time'];
    });
    $jsonForm = new JsonForm($mapper);
    
  4. Integration with API Platform Use in a SerializerContextBuilder to dynamically generate schemas:

    $contextBuilder->getContext()->addExtraAttributes([
        'json_schema' => $jsonForm->transform($form),
    ]);
    

Common Patterns

  • Nested Forms: Automatically handles CollectionType/FormType:

    ->add('tags', CollectionType::class, [
        'entry_type' => TextType::class,
        'allow_add' => true,
    ])
    

    Outputs an array schema with items and additionalItems.

  • Validation Rules: Map Symfony constraints to JSON Schema keywords:

    ->add('age', IntegerType::class, [
        'constraints' => [new Assert\GreaterThan(18)],
    ])
    

    Outputs:

    { "type": "integer", "minimum": 19 }
    
  • Dynamic Forms: Regenerate schema on-the-fly in controllers:

    public function edit(Request $request, FormInterface $form) {
        $schema = (new JsonForm())->transform($form);
        return response()->json(['schema' => $schema]);
    }
    

Gotchas and Tips

Pitfalls

  1. Outdated Symfony Support

    • Last updated for Symfony 4.4. Test thoroughly with newer versions (e.g., Assert\* constraints may break).
    • Fix: Extend TypeMapper or patch the library (MIT license allows modifications).
  2. Missing Type Mappings

    • Not all Symfony types are supported (e.g., FileType, JsonType).
    • Workaround: Register custom mappings in TypeMapper:
      $mapper->addType('json', function() {
          return ['type' => 'object'];
      });
      
  3. Nested Form Quirks

    • CollectionType with prototype may not serialize correctly.
    • Debug: Use var_dump($jsonForm->getSchema()) to inspect intermediate steps.
  4. Constraint Conflicts

    • Multiple constraints (e.g., Length + NotBlank) may generate conflicting schemas.
    • Tip: Prioritize constraints by order in the array or override in TypeMapper.

Debugging Tips

  • Enable Verbose Output:
    $jsonForm = new JsonForm();
    $jsonForm->setDebug(true); // Logs unsupported types
    
  • Inspect Raw Schema:
    $schema = $jsonForm->transform($form);
    file_put_contents('schema.json', json_encode($schema, JSON_PRETTY_PRINT));
    
  • Test Edge Cases:
    • Empty forms.
    • Forms with circular references (e.g., self-referential EntityType).

Extension Points

  1. Custom Schema Generators Extend JsonForm to add metadata:

    class CustomJsonForm extends JsonForm {
        public function transform(FormInterface $form) {
            $schema = parent::transform($form);
            $schema['$metadata'] = ['source' => 'api'];
            return $schema;
        }
    }
    
  2. Frontend Integration

    • Use with libraries like:
    • Example payload:
      {
        "schema": { /* JSON Schema */ },
        "uiSchema": { /* Custom UI hints */ }
      }
      
  3. Performance

    • Cache schemas for static forms:
      $cache = new \Symfony\Component\Cache\SimpleFileCache();
      $schema = $cache->get('form_schema', function() use ($form) {
          return (new JsonForm())->transform($form);
      });
      
  4. Testing

    • Mock FormInterface for unit tests:
      $form = $this->createMock(FormInterface::class);
      $form->method('getConfig')->willReturn(new FormConfig());
      
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor