quantum-php / quantum-php/framework

Refactor debugbar into an event-driven optional integration and remove hardcoded framework coupling

Open
#539 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

debugbar hooks
Dominant language
PHP
Stars
36
Forks
22
PR merge metrics
No merged PRs in 30d

Description

Summary

Refactor debugbar so it becomes a true optional integration built on top of the Event/lifecycle system.

This should remove hardcoded debugger integration from core boot/runtime flow and move framework-owned integration onto lifecycle and package event boundaries, while handling recursion and logger coupling carefully.

Why

Debugbar is currently coupled to the framework at multiple levels.

Hardcoded core integration exists through:

  • InitDebuggerStage in the web boot pipeline

Framework-owned runtime integration also exists in places such as:

  • WebAppTrait pushing hook/debug metadata into the debugger store

In addition, there are direct debugger dependencies in framework packages such as:

  • View
  • logger message reporting through MessageAdapter
  • mailer-related reporting

If the goal is to make debugbar truly optional and lifecycle-driven, then only moving boot initialization to hooks is not enough.

At the same time, this refactor must be careful about two real risks:

  • debugger listeners will themselves participate in the event system they observe, which can create self-reference and recursion problems if not handled carefully
  • MessageAdapter is the default logger adapter in debug mode, so blindly converting logger/debugger integration into events can create circular reporting paths

Goal

Make debugbar a true optional event-driven integration by:

  • removing hardcoded core debugger wiring
  • moving framework-owned debugbar integration onto lifecycle and event subscriptions
  • avoiding recursive or circular integration paths

Scope

This ticket should focus on framework integration boundaries and optional integration registration.

It should:

  • remove hardcoded debugbar boot/runtime wiring from core
  • use external optional-integration listener registration for debugbar
  • move framework-owned debugbar integration onto lifecycle hooks
  • invert direct debugger dependencies where that boundary is safe and justified
  • explicitly avoid recursion-prone or circular event/reporting paths

It should not force a broad event rewrite where the dependency boundary is not yet safe.

Proposed Direction

Remove hardcoded core integration

Remove InitDebuggerStage from the web boot pipeline.

Core should only define and dispatch lifecycle/event boundaries. Core should not call debugbar() directly for framework integration.

Register debugbar listeners externally

Debugbar should subscribe through the external Event/lifecycle listener registration mechanism rather than through hardcoded core wiring.

Move framework-owned integration to listeners

Framework-owned debugbar integration should move to lifecycle-driven listeners, including areas such as:

  • debugger store initialization
  • framework lifecycle/debug metadata collection
  • other runtime/route/response integration owned by framework flow
Invert package dependencies only where safe

Direct debugger dependencies should be reduced where event emission is the better architectural boundary, but this should be done selectively.

Candidate areas include:

  • view/render-related debug data
  • mailer-related debug data
Treat logger/debugger coupling as a special case

MessageAdapter is the debug-mode default logger adapter today.

That means logger/debugger integration must be handled carefully to avoid circular paths such as:

  • package emits log event
  • debugbar listener consumes it
  • listener logs again
  • event loop repeats

For that reason, logger/debugger integration should either:

  • remain direct in this refactor, or
  • be changed only with an explicitly recursion-safe design
Enforce non-recursive debugger listeners

Debugger listeners should not rely on event-producing logging/reporting APIs while handling debugger-related events.

They should write directly to debugger storage/rendering concerns instead of routing back through logger/event producers.

Example Direction

Core lifecycle dispatch
event()->dispatch(LoadModulesStage::BEFORE, [
    'context' => $context,
]);
Debugbar subscribes externally
event()->listen(LoadModulesStage::BEFORE, function (array $payload): void {
    $debugger = debugbar();

    if ($debugger->isEnabled()) {
        $debugger->initStore();
    }
});
Mailer emits an event
event()->dispatch('mailer.warning', [
    'message' => $message,
    'transport' => 'smtp',
]);
Debugbar listens and writes directly to its store
event()->listen('mailer.warning', function (array $payload): void {
    $debugger = debugbar();

    if ($debugger->isEnabled()) {
        $debugger->addToStoreCell(Debugger::MAILS, 'warning', $payload['message']);
    }
});

Acceptance Criteria

  • InitDebuggerStage is removed from hardcoded core integration
  • debugbar lifecycle listeners are registered externally rather than inside core boot/runtime flow
  • framework-owned debugbar integration is moved onto lifecycle/event listeners
  • recursion-prone debugger listener behavior is explicitly avoided
  • logger/debugger integration is either left direct or changed only through a justified recursion-safe design
  • debugbar remains optional and is not hardcoded as a core framework concern
  • tests are updated as needed

Notes

Relevant code:

  • src/App/Stages/InitDebuggerStage.php
  • src/App/Traits/WebAppTrait.php
  • src/View/View.php
  • src/Logger/Adapters/MessageAdapter.php
  • src/Logger/Factories/LoggerFactory.php
  • src/Mailer/Traits/MailerTrait.php
  • src/Mailer/Adapters/SmtpAdapter.php
  • src/Debugger/Debugger.php
  • src/Debugger/Helpers/debugger.php

Depends on:

  • #536
  • #537
  • #538

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the listed integration points: src/App/Stages/InitDebuggerStage.php, src/App/Traits/WebAppTrait.php, src/View/View.php, the logger files, and the mailer files, then review dependencies #536–#538. Trace existing debugger and event flows before changing anything; done means core no longer hardcodes debugbar, optional listeners cover justified boundaries, recursion is avoided, and relevant tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend, tooling
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.