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

Doctrine Readonly Middleware Laravel Package

dnwk/doctrine-readonly-middleware

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require dnwk/doctrine-readonly-middleware
    

    Ensure your Laravel app uses Doctrine DBAL (e.g., via doctrine/dbal or laravel-doctrine/orm).

  2. First Use Case: Enable readonly mode in a controller/middleware:

    use DnwK\DoctrineReadonlyMiddleware\ReadonlyMiddleware;
    
    public function __construct() {
        ReadonlyMiddleware::enable(); // Activates readonly mode for the request
    }
    
    • Test by querying a read-only replica (e.g., in staging) to verify behavior.
  3. Where to Look First:

    • Source Code (minimal, ~50 lines).
    • Check ReadonlyMiddleware::enable() and disable() methods for core logic.

Implementation Patterns

Workflows

  1. Request-Scoped Activation: Enable readonly mode in middleware or controllers for specific routes:

    // app/Http/Middleware/ReadonlyMiddleware.php
    public function handle($request, Closure $next) {
        ReadonlyMiddleware::enable();
        return $next($request);
    }
    

    Register in app/Http/Kernel.php:

    protected $middlewareGroups = [
        'web' => [
            // ...
            \App\Http\Middleware\ReadonlyMiddleware::class,
        ],
    ];
    
  2. Conditional Activation: Toggle based on environment or user roles:

    if (app()->environment('staging') || auth()->user()->isAdmin()) {
        ReadonlyMiddleware::enable();
    }
    
  3. Doctrine Query Integration: Use with Doctrine repositories/entities:

    $entityManager->getRepository(User::class)->find(1); // Readonly enforced
    

Integration Tips

  • Laravel Eloquent: If using both Eloquent and Doctrine, ensure the middleware targets Doctrine’s connection (e.g., doctrine in config/database.php).
  • Testing: Simulate read-only scenarios in PHPUnit:
    $this->app->make(ReadonlyMiddleware::class)->enable();
    $this->assertTrue(ReadonlyMiddleware::isEnabled());
    
  • Fallback Logic: Wrap write operations in checks:
    if (!ReadonlyMiddleware::isEnabled()) {
        $entityManager->persist($entity);
        $entityManager->flush();
    }
    

Gotchas and Tips

Pitfalls

  1. Connection Targeting:

    • The middleware assumes Doctrine’s default connection. Fix: Explicitly set the connection name:
      ReadonlyMiddleware::enable('doctrine_replica');
      
    • Debug Tip: Check Doctrine\DBAL\Connection events for errors (e.g., preExecuteStatement).
  2. Transaction Conflicts:

    • Readonly mode may fail if transactions are active. Workaround: Disable transactions or use READ UNCOMMITTED isolation.
  3. Caching Quirks:

    • Doctrine’s second-level cache may bypass readonly checks. Solution: Clear cache or disable it during readonly mode:
      $entityManager->getConfiguration()->setQueryCacheImpl(null);
      
  4. Laravel Caching:

    • If using Laravel’s cache with Doctrine, ensure cache drivers (e.g., Redis) are read-only compliant.

Debugging

  • Enable Logging:
    ReadonlyMiddleware::setDebug(true); // Logs connection attempts
    
  • Check Middleware State:
    var_dump(ReadonlyMiddleware::isEnabled()); // Verify activation
    
  • Doctrine Events: Listen for connection.connecting to inspect connection parameters:
    $eventManager->addEventListener(
        ConnectionEvents::CONNECTING,
        function (ConnectEventArgs $args) {
            var_dump($args->getConnection()->getWrappedConnection()->getReadOnly());
        }
    );
    

Extension Points

  1. Custom Readonly Logic: Override the middleware’s getReadonlyConnection() method to implement custom connection logic (e.g., load balancing).

  2. Environment-Based Activation: Extend the package to auto-enable in specific environments:

    // app/Providers/AppServiceProvider.php
    public function boot() {
        if (app()->environment('production')) {
            ReadonlyMiddleware::enable();
        }
    }
    
  3. Fallback to Write Connection: Implement a fallback mechanism for critical writes:

    try {
        ReadonlyMiddleware::enable();
        $result = $entityManager->createQuery(...)->getResult();
    } catch (ReadonlyException $e) {
        ReadonlyMiddleware::disable();
        // Retry with write connection
    }
    
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
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