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

Manager Laravel Package

graham-campbell/manager

Laravel Manager provides reusable manager functionality for Laravel apps. It helps you build driver-based services with a consistent API for creating, caching, and resolving implementations. Supports PHP 7.4–8.5 and Laravel 8–13.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require graham-campbell/manager:^5.3
    

    No service provider registration is required—just use the abstract class directly.

  2. First Use Case: Create a manager for a custom service (e.g., PaymentManager):

    use GrahamCampbell\Manager\AbstractManager;
    
    class PaymentManager extends AbstractManager
    {
        protected function createConnection(array $config)
        {
            return new PaymentService($config);
        }
    
        protected function getConfigName(): string
        {
            return 'payments';
        }
    }
    
  3. Configuration: Define configs in config/payments.php:

    return [
        'default' => 'stripe',
        'stripe' => [
            'api_key' => env('STRIPE_KEY'),
        ],
        'paypal' => [
            'client_id' => env('PAYPAL_ID'),
        ],
    ];
    
  4. Usage:

    $manager = new PaymentManager;
    $stripe = $manager->connection('stripe'); // Resolves Stripe instance
    $stripe->charge(100); // Direct method call via __call
    

Implementation Patterns

Core Workflows

  1. Connection Resolution:

    • Default Connection:
      $manager->connection(); // Uses 'default' from config
      
    • Named Connection:
      $manager->connection('paypal'); // Explicit driver
      
    • Dynamic Extension:
      $manager->extend('square', fn() => new SquareService([]));
      $square = $manager->connection('square');
      
  2. Connection Lifecycle:

    • Reconnect: Force a fresh instance.
      $manager->reconnect('stripe');
      
    • Disconnect: Remove from pool.
      $manager->disconnect('paypal');
      
    • Config Access:
      $config = $manager->getConnectionConfig('stripe');
      
  3. Method Delegation: Use __call to chain methods:

    $manager->charge(100); // Delegates to $manager->connection()->charge(100)
    

Integration Tips

  1. Laravel Service Providers: Bind the manager to the container for dependency injection:

    $this->app->singleton(PaymentManager::class, fn($app) => new PaymentManager);
    
  2. Configuration Caching: Use Laravel’s config() helper or cache configs to avoid repeated file reads:

    $config = config('payments.stripe');
    
  3. Testing: Mock connections in tests:

    $manager->extend('test', fn() => Mockery::mock(PaymentService::class));
    
  4. Multi-Tenancy: Override getConfigName() dynamically:

    class TenantAwareManager extends AbstractManager
    {
        protected function getConfigName(): string
        {
            return 'payments.tenant_' . auth()->id();
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Connection Pooling:

    • Connections are singleton-like by default. Use reconnect() to force a new instance if stateful.
    • Fix: Override createConnection() to manage state (e.g., increment a counter).
  2. Config Name Mismatch:

    • getConfigName() must match the config file key (e.g., 'payments'config/payments.php).
    • Fix: Use getNamedConfig() for dynamic config paths:
      $manager->getNamedConfig('custom.path');
      
  3. Extension Overrides:

    • Extensions (extend()) replace existing connections. Use disconnect() first if needed:
      $manager->disconnect('stripe');
      $manager->extend('stripe', fn() => new UpdatedStripeService([]));
      
  4. PHP 8+ Type Safety:

    • Ensure createConnection() returns the correct type (e.g., PaymentService).
    • Tip: Use return new self($config); in abstract classes for consistency.

Debugging

  1. Connection Not Found:

    • Verify the config key exists and the connection name matches.
    • Check for typos in getConfigName().
  2. Method Not Found:

    • Ensure the connection class implements the method or use __call in the manager:
      public function __call($method, $params)
      {
          return $this->connection()->$method(...$params);
      }
      
  3. Config Loading Issues:

    • Use php artisan config:clear to reset cached configs.
    • Tip: Add a boot() method to your service provider to merge configs dynamically:
      $this->mergeConfigFrom(__DIR__.'/config.php', 'payments');
      

Extension Points

  1. Custom Connection Factories:

    • Override createConnection() to add logic (e.g., logging, validation):
      protected function createConnection(array $config)
      {
          $this->log("Creating connection for: " . $config['driver']);
          return new PaymentService($config);
      }
      
  2. Dynamic Config Resolution:

    • Use getNamedConfig() to load configs from arbitrary paths:
      $manager->getNamedConfig('services.' . $serviceName);
      
  3. Connection Events:

    • Trigger events on connect/disconnect:
      $manager->extend('stripe', fn() => event(new Connecting('stripe')));
      
  4. Fluent Interface:

    • Chain methods for readability:
      $manager->connection('stripe')->setApiKey('new_key')->saveConfig();
      
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport