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

Ext Direct Bundle Laravel Package

anilton.junior/ext-direct-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:
    composer require ghua/ext-direct-bundle
    
  2. Register Bundle: Add new Ext\DirectBundle\ExtDirectBundle() to AppKernel.php under $bundles.
  3. Routing: Include in app/config/routing.yml:
    ext_direct:
        resource: "@ExtDirectBundle/Resources/config/routing.yml"
    
  4. Configuration: Create app/config/extdirect_routing.yml with basic routes:
    getCustomers:
        defaults: { _controller: AcmeDemoBundle:Demo:getCustomers, params: true }
        reader: { root: root }
    
  5. Template Integration: Add the JS API script to your template:
    <script type="text/javascript" src="{{ url('ExtDirectBundle_api') }}"></script>
    
  6. ExtJS Provider Setup:
    Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
    

First Use Case: Fetching Data

Create a controller action returning raw data:

// src/Acme/DemoBundle/Controller/DemoController.php
public function getCustomersAction()
{
    $data = $this->getDoctrine()
        ->getRepository('AcmeDemoBundle:Customer')
        ->findAll();

    return $data;
}

Define an ExtJS model:

Ext.define('ACME.model.Customer', {
    extend: 'Ext.data.Model',
    fields: ['id', 'name', 'email'],
    proxy: {
        type: 'direct',
        api: {
            read: Actions.AcmeDemo_Demo.getCustomers
        }
    }
});

Implementation Patterns

Routing Configuration

YAML-Based Routing

Define routes in extdirect_routing.yml:

getCountries:
    defaults: { _controller: AcmeDemoBundle:Demo:getCountries }
    reader: { root: 'data', successProperty: 'success' }

updateCustomer:
    defaults: { _controller: AcmeDemoBundle:Demo:updateCustomer, params: true, form: true }
    writer: { root: 'result' }

Annotation-Based Routing

Use annotations in controllers:

use Ext\DirectBundle\Annotation\Route;
use Ext\DirectBundle\Annotation\Reader;
use Ext\DirectBundle\Annotation\Writer;

/**
 * @Route(name="acmeTest", isWithParams=true)
 * @Reader(root="data", successProperty="success")
 * @Writer(root="result")
 */
public function testAction($_data) { ... }

Data Handling Patterns

Simple Data Fetching

// Controller
public function getRolesAction()
{
    return $this->getDoctrine()
        ->getRepository('AcmeDemoBundle:Role')
        ->findAll();
}

ExtJS Model:

Ext.define('ACME.store.Role', {
    extend: 'Ext.data.Store',
    model: 'ACME.model.Role',
    proxy: {
        type: 'direct',
        api: {
            read: Actions.AcmeDemo_Demo.getRoles
        }
    }
});

Paginated Data with KnpPaginator

// Controller
public function getCustomersAction($page = 1, $limit = 10)
{
    $query = $this->getDoctrine()
        ->getRepository('AcmeDemoBundle:Customer')
        ->createQueryBuilder('c')
        ->getQuery()
        ->setHydrationMode(\Doctrine\ORM\Query::HYDRATE_ARRAY);

    $paginator = $this->get('knp_paginator')->paginate($query, $page, $limit);

    return $this->get('ext_direct')
        ->createResponse(new \Ext\DirectBundle\Response\KnpPaginator(), $paginator);
}

Form Handling

Form Submission

// Controller
public function createCustomerAction($_data)
{
    $customer = new Customer();
    $form = $this->createForm(CustomerType::class, $customer);
    $form->bind($_data);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($customer);
        $em->flush();
        return $this->get('ext_direct')->createResponse()->setSuccess(true);
    }

    return $this->get('ext_direct')
        ->createResponse(new \Ext\DirectBundle\Response\FormError(), $form);
}

ExtJS Form:

Ext.define('ACME.view.CustomerForm', {
    extend: 'Ext.form.Panel',
    api: {
        submit: Actions.AcmeDemo_Demo.createCustomer
    },
    items: [
        { xtype: 'textfield', name: 'name', fieldLabel: 'Name' }
    ]
});

Event-Driven Data Transformation

// Event Subscriber
class CompactCustomerRolesSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [\Ext\DirectBundle\Event\DirectEvents::POST_QUERY_EXECUTE => 'transformData'];
    }

    public function transformData(\Ext\DirectBundle\Event\ResponseEvent $event)
    {
        $data = $event->getData();
        // Transform data here
        $event->setData($transformedData);
    }
}

Gotchas and Tips

Common Pitfalls

  1. Parameter Binding:

    • Ensure method parameters in controllers match the keys sent from ExtJS. Use params: true in routing for dynamic parameters.
    • Example: If ExtJS sends {page: 1, limit: 10}, the controller must define getCustomersAction($page, $limit).
  2. Hydration Mode:

    • For KnpPaginator, always set HYDRATE_ARRAY in Doctrine queries to avoid hydration issues:
      $query->setHydrationMode(\Doctrine\ORM\Query::HYDRATE_ARRAY);
      
  3. Form Data Binding:

    • Use array_intersect_key($_data, $form->all()) to filter out unsupported fields before binding:
      $_data = array_intersect_key($_data, $form->all());
      
  4. CORS Issues:

    • If using ExtJS in a separate domain, configure CORS headers in Symfony:
      # config/packages/nelmio_cors.yaml
      nelmio_cors:
          defaults:
              allow_origin: ["*"]
              allow_methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
              allow_headers: ["Content-Type", "Authorization"]
              expose_headers: ["Link"]
      
  5. Annotation Loading:

    • Ensure annotations are autoloaded. Add this to composer.json:
      "autoload": {
          "psr-4": {
              "": "src/"
          },
          "classmap": ["app/AppKernel.php", "app/AppCache.php"]
      }
      

Debugging Tips

  1. Check ExtJS Console:

    • Open browser dev tools (F12) to inspect ExtDirect requests/responses. Look for errors in the "Network" tab under ExtDirect.
  2. Symfony Profiler:

    • Enable the profiler to debug controller actions and routing:
      // app/config/config_dev.yml
      framework:
          profiler: { only_exceptions: false }
      
  3. Logging DirectBundle Events:

    • Log events for debugging:
      // In an event subscriber
      public function transformData(ResponseEvent $event)
      {
          $this->logger->debug('Event data:', ['data' => $event->getData()]);
          // ...
      }
      
  4. Validate Routing:

    • Clear cache and check routes:
      php bin/console cache:clear
      php bin/console debug:router | grep ext_direct
      

Extension Points

  1. Custom Response Classes:

    • Extend \Ext\DirectBundle\Response\Response to add custom logic:
      class CustomResponse extends \Ext\DirectBundle\Response\Response
      {
          public function setCustomData($data)
          {
              $this->data['custom'] = $data;
              return $this;
          }
      }
      
  2. Event Subscribers:

    • Subscribe to events like PRE_QUERY_EXECUTE or POST_QUERY_EXECUTE to modify data:
      // src/Acme/DemoBundle/EventListener/CustomSubscriber.php
      class CustomSubscriber implements EventSubscriberInterface
      {
          public static function getSubscribedEvents()
          {
              return [
                  \Ext\DirectBundle\Event\DirectEvents::PRE_QUERY_EXECUTE => 'preExecute',
                  \Ext\DirectBundle\Event\DirectEvents::POST_QUERY_EXECUTE => 'postExecute'
              ];
          }
      }
      
  3. Override Templates:

    • Customize error templates by overriding the default in config.yml:
      ext_direct:
          error_template: "@AcmeDemo/extdirect/error_template.html.twig"
      
  4. Batch Processing:

    • Handle batch updates ($_list) by iterating
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware