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

Oro Platform Advanced Form Bundle Laravel Package

clickandmortar/oro-platform-advanced-form-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require clickandmortar/oro-platform-advanced-form-bundle
    php bin/console cache:clear
    

    Verify compatibility with your OroPlatform version (e.g., 4.2.* for OroPlatform 4.2.*).

  2. First Use Case: Create a custom form type by extending CmAdvancedFormBundle\Form\Type\AbstractAdvancedFormType and register it in your bundle’s Resources/config/services.yml:

    services:
        app.form.type.my_custom_form:
            class: App\Form\Type\MyCustomFormType
            tags:
                - { name: form.type, alias: my_custom_form }
    
  3. Key Files to Review:

    • src/Form/Type/AbstractAdvancedFormType.php (base class for custom form types).
    • src/DependencyInjection/Configuration.php (bundle configuration).
    • docs/demo.gif (visual reference for expected behavior).

Implementation Patterns

Common Workflows

  1. Extending Form Types: Override buildForm() and configureOptions() in your custom form type to add fields, validation, or logic:

    namespace App\Form\Type;
    
    use CmAdvancedFormBundle\Form\Type\AbstractAdvancedFormType;
    
    class MyCustomFormType extends AbstractAdvancedFormType {
        public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder
                ->add('field1', TextType::class)
                ->add('field2', ChoiceType::class, [
                    'choices' => ['Option 1', 'Option 2'],
                ]);
        }
    }
    
  2. Dynamic Field Loading: Use AbstractAdvancedFormType’s loadFieldDefinitions() to dynamically add fields based on runtime logic (e.g., entity metadata):

    protected function loadFieldDefinitions(FieldDefinitionCollection $collection) {
        $collection->add('dynamic_field', new FieldDefinition('text', TextType::class));
    }
    
  3. Integration with OroCRM Entities: Attach forms to entity types via YAML (e.g., config/oro_entity_extend.yml):

    oro_entity:
        entity_definitions:
            my_entity:
                form_types:
                    default: app.form.type.my_custom_form
    
  4. Submitting and Handling Forms: Use Symfony’s form handling workflow with Oro’s entity managers:

    $form = $this->createForm(MyCustomFormType::class, $entity);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $em->persist($entity);
        $em->flush();
    }
    
  5. Theming: Override Twig templates in templates/form/ or extend the base template (@CmAdvancedForm/form.html.twig).


Gotchas and Tips

Pitfalls

  1. Version Mismatch:

    • The bundle only supports OroPlatform 3.1.* and 4.2.*. Mixing versions (e.g., OroCRM 4.1.* with this bundle) may break dependencies.
    • Fix: Pin OroPlatform to a compatible version in composer.json:
      "require": {
          "oro/platform": "4.2.*"
      }
      
  2. Caching Issues:

    • After adding custom form types, clear all caches:
      php bin/console cache:clear --env=prod --no-debug
      
    • Debug Tip: Use --env=dev during development to avoid cache-related headaches.
  3. Form Type Registration:

    • Forgetting to tag the service with form.type will make the form type invisible to Symfony’s form factory.
    • Fix: Ensure your services.yml includes:
      tags:
          - { name: form.type, alias: your_form_alias }
      
  4. Entity Form Overrides:

    • Overriding Oro’s default entity forms may conflict with platform updates. Use event listeners (oro_entity.form.build) for safer extensions:
      // src/EventListener/FormListener.php
      public function onBuildForm(FormEvent $event) {
          $form = $event->getForm();
          $form->add('custom_field', TextType::class);
      }
      
      Register the listener in services.yml:
      tags:
          - { name: kernel.event_listener, event: oro_entity.form.build, method: onBuildForm }
      
  5. Dynamic Fields and Hydration:

    • Fields added via loadFieldDefinitions() won’t auto-hydrate from entity data unless you implement setDefaultOptions():
      public function setDefaultOptions(OptionsResolver $resolver) {
          $resolver->setDefaults([
              'data_class' => MyEntity::class,
              'csrf_protection' => true,
          ]);
      }
      

Tips

  1. Debugging Form Data: Dump form data in a controller to verify field binding:

    $data = $form->getData();
    dump($data); // Check if dynamic fields are populated.
    
  2. Reusing Field Definitions: Create a base form type for shared fields (e.g., BaseEntityFormType) and extend it for specific entities to avoid duplication.

  3. Performance:

    • Lazy-load field definitions in loadFieldDefinitions() if the form has many dynamic fields:
      protected function loadFieldDefinitions(FieldDefinitionCollection $collection) {
          if ($this->shouldLoadFields()) {
              $collection->add('heavy_field', new FieldDefinition('text', TextType::class));
          }
      }
      
  4. Testing: Use Oro’s EntityTestCase to test form submissions:

    public function testFormSubmission() {
        $formData = ['field1' => 'value'];
        $form = $this->factory->create(MyCustomFormType::class, null, ['csrf_protection' => false]);
        $form->submit($formData);
        $this->assertTrue($form->isValid());
    }
    
  5. Extending the Bundle:

    • Override the bundle’s templates by copying vendor/clickandmortar/oro-platform-advanced-form-bundle/Resources/views/ to templates/CmAdvancedForm/.
    • Extend AbstractAdvancedFormType to add global form behaviors (e.g., auto-save logic).
  6. OroCRM-Specific:

    • For CRM entities, use Oro’s entity_alias in form options to avoid hydration issues:
      $builder->add('entity_field', EntityType::class, [
          'class' => 'OroCRM:Account',
          'property' => 'entity_alias',
      ]);
      

```markdown
## Extension Points
1. **Custom Field Types**:
   Extend `CmAdvancedFormBundle\Form\Type\Field\AbstractFieldType` to create reusable field components.

2. **Form Events**:
   Listen to `cm_advanced_form.build` and `cm_advanced_form.submit` events for cross-cutting concerns:
   ```yaml
   tags:
       - { name: kernel.event_listener, event: cm_advanced_form.build, method: onFormBuild }
  1. Data Transformers: Implement DataTransformerInterface for custom field data mapping (e.g., converting arrays to JSON).

  2. Validation Groups: Dynamically set validation groups in configureOptions():

    $resolver->setDefaults([
        'validation_groups' => function (FormInterface $form) {
            return ['Default', 'custom_group'];
        },
    ]);
    
  3. Asset Integration: Load JavaScript/CSS for dynamic forms via buildView():

    public function buildView(FormView $view, FormInterface $form, array $options) {
        $view->vars['cm_advanced_form_assets'] = $this->assetHelper->getAssets();
    }
    
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.
facebook/capi-param-builder-php
babelqueue/symfony
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