Weave 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

Godfather Laravel Package

pugx/godfather

PUGX Godfather is a lightweight PHP library that generates stub classes implementing any interface at runtime, so you can quickly create test doubles and fake dependencies without boilerplate or a full mocking framework. Ideal for unit testing legacy code.

Deep Wiki
Context7

Getting Started

pugx/godfather is a small strategy-pattern registry: implementations are registered under aliases, and callers resolve the implementation they need at runtime instead of writing switch/if chains. It is a 2014-era Symfony2/PHP library, so treat it as legacy and do a short compatibility spike before adopting it.

Minimal steps:

  1. Install it, pinning a version compatible with your PHP runtime:
    composer require pugx/godfather
    
  2. In Symfony2, register the bundle in app/AppKernel.php:
    new PUGX\GodfatherBundle\PUGXGodfatherBundle(),
    
  3. Look first at:
    • README.md for the exact registry API and tag name
    • Godfather.php / the core registry class for get() vs getStrategy() and default-strategy behavior
    • the dependency-injection compiler pass for the service tag name and supported attributes
    • Resources/config/*.xml for the service ID you will inject
  4. If using it standalone, instantiate the registry directly:
    use PUGX\Godfather\Godfather;
    
    $godfather = new Godfather();
    $godfather->addStrategy('flat_rate', new FlatRateStrategy());
    $godfather->addStrategy('carrier', new CarrierStrategy());
    
    $strategy = $godfather->get('flat_rate');
    
    Confirm the exact method names in the package source; older releases vary between get(), getStrategy(), and similar variants.

First use case: replace a shipping-cost or payment-method switch with a strategy interface. Define the contract, create one class per algorithm, tag each service with an alias, inject the registry into the service that chooses the algorithm, and resolve by alias.

interface ShippingCostStrategy
{
    public function calculate(Order $order): int;
}

final class FlatRateStrategy implements ShippingCostStrategy
{
    public function calculate(Order $order): int
    {
        return 500;
    }
}
services:
    app.shipping.flat_rate:
        class: App\Shipping\FlatRateStrategy
        tags:
            - { name: godfather.strategy, alias: flat_rate }

    app.shipping.carrier:
        class: App\Shipping\CarrierStrategy
        tags:
            - { name: godfather.strategy, alias: carrier }
final class ShippingCostCalculator
{
    public function __construct(private Godfather $godfather)
    {
    }

    public function quote(Order $order): int
    {
        $strategy = $this->godfather->get($order->getShippingMethod());

        return $strategy->calculate($order);
    }
}

Verify the tag name in the compiler pass before wiring production services; it may be godfather.strategy, pugx.godfather.strategy, or a bundle-specific variant.

Implementation Patterns

Use one registry per decision family. A shipping registry should not contain payment strategies. If the package supports only a single global registry, either keep aliases namespaced (shipping.flat_rate, payment.stripe) or wrap the registry in your own small application-level factory.

Define a narrow interface per strategy family. The registry returns object or a shared interface; the caller should type-check or assert the expected interface when resolving from a broad registry. Day-to-day code should look like this:

$strategy = $this->godfather->get('shipping.flat_rate');

if (!$strategy instanceof ShippingCostStrategy) {
    throw new \RuntimeException('Invalid shipping strategy');
}

Keep aliases as application contracts. Prefer constants or a dedicated enum-like class over raw strings scattered through templates, forms, and services:

final class ShippingStrategies
{
    public const FLAT_RATE = 'flat_rate';
    public const CARRIER = 'carrier';
}

Pass context objects rather than long argument lists. Strategy methods age better when they accept a request/context object:

interface TaxStrategy
{
    public function calculate(TaxContext $context): TaxResult;
}

Use the registry at the application boundary, not deep in domain entities. Good integration points are controllers, command handlers, form handlers, and application services. Bad integration points are entities, value objects, and low-level domain services that should not know about the DI container.

Workflow for adding a strategy:

  1. Add a class implementing the strategy interface.
  2. Register it with a unique alias in YAML/XML or via the package's supported attribute.
  3. Add or update a test for the new implementation.
  4. Add the alias to the application-level allowed list or form choices.
  5. Clear the Symfony container cache.

Testing pattern: unit-test each strategy in isolation; test the consumer with a stub registry or a real registry populated manually in standalone mode. Add one integration test that boots the Symfony container and resolves every configured alias to catch tag/compiler-pass mistakes.

If the package supports annotation-based registration, use it only if your team already uses annotations heavily. Explicit service tags are easier to grep and review in legacy Symfony2 projects.

Gotchas and Tips

This package is effectively abandoned: last release was 2014. Expect PHP 5.x/Symfony2 assumptions. On PHP 8 or Symfony 5/6, it may fail because of reserved words, container API changes, public/private service defaults, or removed bundle conventions. For new code, prefer Symfony’s native tagged services with !tagged_iterator or a ServiceLocator; use Godfather only when maintaining an existing legacy application.

The service tag name and tag attributes are the most common integration failure. Confirm the exact tag in the package’s compiler pass and inspect the compiled container when a strategy is missing:

php app/console debug:container --tag=godfather.strategy
php app/console cache:clear

In modern Symfony the command is bin/console, but this package predates that layout.

Alias collisions are dangerous. If two services are tagged with the same alias, behavior depends on compiler-pass ordering and may silently overwrite one another. Validate aliases at compile time in your own compiler pass, or at minimum add a container smoke test that resolves every alias.

Unknown aliases often surface as a generic exception from the registry. Wrap resolution at the application boundary and throw a domain-specific exception with the requested alias and the list of known aliases. This is much easier to debug than a bare “strategy not found” from deep in a service.

Avoid turning the registry into a service locator. Injecting Godfather into every class and calling get() from anywhere hides dependencies. Prefer injecting a small application-specific selector that owns the registry and exposes only the operations your application needs.

Watch service visibility and lazy loading. Old Symfony2 code generally assumed public services, while newer Symfony versions default to private services and may remove tagged services that are not referenced. If strategies have heavy constructor dependencies, consider lazy services or keep construction cheap.

Clear the cache after changing tags, aliases, or compiler passes. Symfony compiles the tagged-service map into the cached container, so stale cache is a frequent cause of “my new strategy is not there.”

Use the package’s extension points sparingly. A custom compiler pass can validate aliases, enforce interface implementation, normalize alias names, and inject a default strategy. A decorator around the registry can add logging, metrics, or fallback behavior without modifying the package.

Document the pattern locally. The name “Godfather” does not communicate “strategy registry” to new developers; add a short README section showing the interface, tag format, alias list, and one example call site.

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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style