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

Elissa Bundle Laravel Package

carthage/elissa-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation: Run composer require carthage-software/elissa-bundle and enable the bundle in config/bundles.php.
  2. First Use Case: Inject PSR-7 factories into a service to create HTTP messages:
    use Psr\Http\Message\RequestFactoryInterface;
    
    public function __construct(private RequestFactoryInterface $requestFactory) {}
    
  3. Auto-Tagged Handlers: Create a PSR-15 handler (e.g., app/src/Handler/MyHandler.php) and tag it as a controller in Symfony’s DI container:
    # config/services.yaml
    services:
        App\Handler\MyHandler:
            tags: ['controller']
    

Key Entry Points

  • PSR-7 Factories: Available as autowired services (e.g., StreamFactoryInterface, ResponseFactoryInterface).
  • Middleware Integration: Register middleware via Symfony’s kernel.middleware config or as services tagged kernel.middleware.
  • PSR-15 Handlers: Define handlers as services tagged controller and use them like Symfony controllers.

Implementation Patterns

1. PSR-7 Factories in Services

  • Pattern: Inject factories into services to create HTTP messages dynamically.
  • Example:
    public function createRequest(string $method, string $uri): ServerRequestInterface {
        $request = $this->requestFactory->createServerRequest($method, $uri);
        return $request->withHeader('X-Custom', 'Value');
    }
    
  • Use Case: Useful for testing, API clients, or background jobs requiring HTTP messages.

2. PSR-15 Handlers as Controllers

  • Pattern: Replace Symfony controllers with PSR-15 handlers for cleaner separation.
  • Example:
    // src/Handler/MyHandler.php
    use Psr\Http\Message\ResponseInterface;
    use Psr\Http\Message\ServerRequestInterface;
    use Psr\Http\Server\RequestHandlerInterface;
    
    final class MyHandler implements RequestHandlerInterface {
        public function handle(ServerRequestInterface $request): ResponseInterface {
            return new ResponseFactory()->createResponse(200)
                ->withBody($this->streamFactory->createStream('Hello, PSR-15!'));
        }
    }
    
  • Routing: Route to handlers via Symfony’s router (e.g., any: /api/hello App\Handler\MyHandler).

3. Middleware Stack Integration

  • Pattern: Leverage Symfony’s middleware stack for PSR-15 middleware.
  • Example:
    # config/packages/framework.yaml
    framework:
        http_client:
            middleware:
                - CarthageSoftware\ElissaBundle\Middleware\MyMiddleware
    
  • Third-Party Middleware: Use middleware from other PSR-15-compliant packages (e.g., brick/varnish).

4. Stream Handling

  • Pattern: Use StreamFactoryInterface to create streams from strings, files, or resources.
  • Example:
    $stream = $this->streamFactory->createStream('{"key": "value"}');
    $response = $this->responseFactory->createResponse(200)->withBody($stream);
    

5. Uploaded Files

  • Pattern: Process uploaded files via UploadedFileFactoryInterface.
  • Example:
    $uploadedFile = $this->uploadedFileFactory->createUploadedFile(
        $_FILES['file']['tmp_name'],
        $_FILES['file']['name'],
        $_FILES['file']['type'],
        $_FILES['file']['size'],
        $_FILES['file']['error']
    );
    

Gotchas and Tips

Pitfalls

  1. Middleware Order Matters:

    • Middleware registered via kernel.middleware runs before Symfony’s built-in middleware. Use framework.http_client.middleware for HTTP client middleware or framework.middleware for global middleware.
    • Fix: Explicitly order middleware in config/packages/framework.yaml:
      framework:
          middleware: [MyMiddleware, AnotherMiddleware]
      
  2. PSR-15 Handlers vs. Symfony Controllers:

    • PSR-15 handlers do not automatically resolve Symfony’s Request or Response objects. Use PSR-7 factories instead.
    • Fix: Inject ServerRequestFactoryInterface and ResponseFactoryInterface into handlers.
  3. Stream Detachment:

    • Detach streams when no longer needed to free memory:
      $stream->detach(); // Call this when done with the stream.
      
    • Gotcha: Forgetting to detach can cause memory leaks in long-running processes.
  4. UploadedFile Limitations:

    • UploadedFileFactoryInterface works with $_FILES data. For custom uploads (e.g., from S3), create a Psr\Http\Message\UploadedFileInterface manually or use a library like league/glide.
  5. Caching Factories:

    • PSR-7 factories are stateless but may be cached by Symfony’s DI container. Avoid recreating factories manually.

Debugging Tips

  1. Middleware Debugging:

    • Use Symfony’s debug:router and debug:container commands to verify middleware tags and services.
    • Example:
      php bin/console debug:container CarthageSoftware\ElissaBundle\Middleware\MyMiddleware
      
  2. Handler Resolution:

    • Ensure PSR-15 handlers are tagged controller and are autowired. Use:
      php bin/console debug:container --tag=controller
      
  3. Stream Issues:

    • Check for detached streams or invalid resources causing RuntimeExceptions. Use StreamInterface::isWritable() to verify stream state.

Extension Points

  1. Custom Factories:

    • Override default factories by binding custom implementations in config/services.yaml:
      services:
          Psr\Http\Message\StreamFactoryInterface: '@App\Factory\CustomStreamFactory'
      
  2. Middleware Decorators:

    • Decorate middleware to add cross-cutting concerns (e.g., logging):
      use Psr\Http\Server\MiddlewareInterface;
      use Psr\Http\Server\RequestHandlerInterface;
      
      final class LoggingMiddleware implements MiddlewareInterface {
          public function __construct(private MiddlewareInterface $decorated) {}
      
          public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
              // Log request
              return $this->decorated->process($request, $handler);
          }
      }
      
    • Register the decorator in services.yaml:
      services:
          App\Middleware\LoggingMiddleware:
              decorates: 'some.middleware'
              arguments: ['@.inner']
      
  3. Event Listeners:

    • Listen to kernel.request and kernel.response events to inspect/modify PSR-7 messages:
      use Symfony\Component\HttpKernel\Event\RequestEvent;
      use Symfony\Component\HttpKernel\KernelEvents;
      
      $eventDispatcher->addListener(KernelEvents::REQUEST, function (RequestEvent $event) {
          $request = $event->getRequest();
          if ($request instanceof ServerRequestInterface) {
              // Modify PSR-7 request
          }
      });
      
  4. Testing:

    • Use Nyholm\Psr7\Factory\Psr17Factory for testing PSR-7 objects:
      use Nyholm\Psr7\Factory\Psr17Factory;
      
      $factory = new Psr17Factory();
      $request = $factory->createServerRequest('GET', '/test');
      
    • Mock factories in tests:
      $this->mockBuilder()
          ->disableOriginalCloneMethods()
          ->getMockBuilder(StreamFactoryInterface::class)
          ->addMethods(['createStream'])
          ->getMock();
      
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