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

Before After Bundle Laravel Package

expertcoder/before-after-bundle

A Symfony 2/3 bundle that runs code before every action in a controller. Implement ExecuteBeforeInterface on your controller and put logic in executeBefore() to execute automatically before any action method is invoked.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: this is a Symfony 2/3 bundle, not a Laravel package. It is archived, has 2 stars, 0 dependents, and readme-level maturity. Do not introduce it into a new Laravel or modern Symfony application. Use it only if you are maintaining a legacy Symfony 2/3 codebase that already uses it, or if you need to understand its very small behavior.

Minimal setup in a Symfony 2/3 app:

composer require expertcoder/before-after-bundle

Register the bundle in AppKernel.php:

public function registerBundles()
{
    $bundles = [
        // ...
        new ExpertCoder\BeforeAfterBundle\ExpertCoderBeforeAfterBundle(),
    ];
}

Then implement ExecuteBeforeInterface on the controller whose actions need pre-action logic:

use ExpertCoder\BeforeAfterBundle\Other\ExecuteBeforeInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class AdminController extends Controller implements ExecuteBeforeInterface
{
    public function executeBefore(FilterControllerEvent $event)
    {
        // Runs before every action in this controller.
    }

    public function dashboardAction()
    {
        // ...
    }
}

Where to look first: read Other/ExecuteBeforeInterface.php and the bundle’s kernel.controller event listener/service definition. The README is short; the listener is the actual behavior. Confirm exactly which controller callables it supports before relying on it.

First practical use case: resolve and attach tenant/user context once for every action in an admin controller:

public function executeBefore(FilterControllerEvent $event)
{
    $request = $event->getRequest();
    $request->attributes->set('tenant', $this->tenantResolver->resolve($request));
}

For a Laravel developer, the closest mental model is controller middleware or a base-controller callAction() hook. The important difference: this package only runs a method before the action. It cannot return a response or short-circuit the request by itself.

Implementation Patterns

Per-controller cross-cutting concern. Implement the interface directly on a controller when the same logic applies to every action in that controller: tenant resolution, audit logging, feature-flag checks, setting shared request attributes, or recording metrics.

public function executeBefore(FilterControllerEvent $event)
{
    $request = $event->getRequest();

    $this->logger->info('controller.before', [
        'route' => $request->attributes->get('_route'),
        'controller' => $request->attributes->get('_controller'),
    ]);
}

Base controller hook. If many controllers need similar behavior, put the interface implementation in an abstract base controller and delegate to an overridable method.

abstract class BaseController extends Controller implements ExecuteBeforeInterface
{
    public function executeBefore(FilterControllerEvent $event)
    {
        $this->beforeAction($event);
    }

    protected function beforeAction(FilterControllerEvent $event)
    {
        // Default no-op; child controllers override.
    }
}

Use this sparingly. A base controller that runs logic for every action can become hidden global behavior.

Attach data to the request for the action. Because executeBefore() receives the FilterControllerEvent, it can mutate request attributes that the action reads later:

public function executeBefore(FilterControllerEvent $event)
{
    $event->getRequest()->attributes->set(
        'account',
        $this->accountLocator->forRequest($event->getRequest())
    );
}

Use constructor injection where possible. In Symfony 2/3 controllers that extend Controller, $this->get('service') works, but constructor injection is clearer and testable. The interface gives you only the event, so dependencies must come from the controller.

Guard non-main requests. kernel.controller fires for subrequests as well. If the before logic must run only for the main request, guard it:

public function executeBefore(FilterControllerEvent $event)
{
    if (!$event->isMasterRequest()) {
        return;
    }

    // Main-request-only logic.
}

Use request attributes for ordering-sensitive data. If another kernel.controller listener must run before your bundle’s listener, register your own listener with a higher priority. If it must run after, use a lower priority. The bundle exposes no documented priority configuration.

Testing pattern. Test through the Symfony HTTP kernel rather than unit-testing executeBefore() in isolation. Assert the side effect: request attribute set, log written, service called, or exception thrown. In Laravel terms, this is a feature test against a route.

Gotchas and Tips

No after-action support exists. Despite the package name, the README explicitly lists executeAfter as TODO. If you need post-action behavior, use a kernel.response listener, a controller try/finally, or a Symfony event subscriber. Do not assume this package provides both sides.

It cannot short-circuit the action with a response. FilterControllerEvent does not let you set a response. If you need “deny and return 403” or “redirect to login,” throw an exception handled by Symfony’s exception/security listeners, or implement the check in kernel.request or Symfony security instead. Do not put authorization here if the only intended outcome is a response.

It is controller-level, not route-level. The logic runs before every action on the controller. If only one or two routes need it, split the controller or use a dedicated event subscriber with route checks. A broad controller hook is easy to forget months later.

Controller callable support may be narrow. The listener likely targets normal array callables such as [ControllerObject, 'action']. If you use closures, invokable controllers, or unusual controller resolvers, verify the listener behavior in the bundle source before depending on it.

Modern Symfony incompatibility. FilterControllerEvent is a Symfony 2/3-era API. Symfony 4.3+ deprecated it, and later versions removed it. This bundle is not a forward-compatible solution. If you are on modern Symfony, write a small kernel.controller subscriber using ControllerEvent instead.

Archived and effectively unsupported. There is no community around it: 2 stars, 0 dependents, archived, README-only maturity. Treat it as legacy code. If you must keep it, vendor or pin the dependency, add your own tests around the behavior, and document why it exists.

No configuration or extension points. There is no bundle config, no priority setting, and no strategy pattern. The only extension point is implementing ExecuteBeforeInterface. If you need more control, override the bundle service definition or write your own listener. Forking a 20-line listener is often cheaper than maintaining this dependency.

Watch subrequests and forwards. Because the listener runs on kernel.controller, subrequests and forwarded controllers can trigger executeBefore() again. Guard with isMasterRequest() in Symfony 2/3, or be sure repeated execution is safe.

Avoid heavy work. This runs on every action in the controller. Keep it to cheap, cached lookups. Do not perform uncached database writes, remote calls, or expensive permission calculations in executeBefore() unless you have measured and accepted the cost.

Laravel developers should not port this directly. Laravel middleware is the correct comparison, and it can short-circuit with a response. If you are porting the concept to Laravel, use middleware for cross-cutting concerns or a base controller’s callAction() hook. Do not install this bundle into a Laravel app expecting Symfony kernel events to work.

When in doubt, replace it. For a legacy Symfony 2/3 app, a small custom kernel.controller listener gives you the same behavior with explicit priority, testability, modern type hints, and no archived dependency. Use this bundle only when the cost of removing it is higher than the value it provides.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin