Skip to content

Commit 81c6f74

Browse files
authored
feat: enhance DDLess debug mode with conditional stream wrapper regis… (#6)
…tration and prevent double bootstrap
2 parents d0d0ce6 + 016bedd commit 81c6f74

1 file changed

Lines changed: 31 additions & 9 deletions

File tree

src/frameworks/cakephp/http_request.php

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,18 @@ function () use ($projectRoot, $ddlessDirectory, &$__ddless_cake_error) {
532532
// CLI mode (DDLess direct request): manual bootstrap, capture response, snapshot.
533533
// ═══════════════════════════════════════════════════════════════════════════════
534534

535+
$breakpoints = ddless_read_breakpoints($ddlessDirectory);
536+
$executionStartedAt = microtime(true);
537+
538+
// Register stream wrapper BEFORE autoload — same order as proxy mode.
539+
// The wrapper must be active when Composer's autoloader is set up so that
540+
// all subsequent include/require calls go through it.
541+
if (getenv('DDLESS_DEBUG_MODE') === 'true') {
542+
if (function_exists('ddless_register_stream_wrapper')) {
543+
ddless_register_stream_wrapper();
544+
}
545+
}
546+
535547
require_once $projectRoot . '/vendor/autoload.php';
536548

537549
$bootstrapFile = $projectRoot . '/config/bootstrap.php';
@@ -544,8 +556,6 @@ function () use ($projectRoot, $ddlessDirectory, &$__ddless_cake_error) {
544556
exit(1);
545557
}
546558

547-
$breakpoints = ddless_read_breakpoints($ddlessDirectory);
548-
$executionStartedAt = microtime(true);
549559
$logDir = defined('LOGS') ? LOGS : $projectRoot . DIRECTORY_SEPARATOR . 'logs';
550560

551561
$phpWrapperReplaced = false;
@@ -559,12 +569,10 @@ function () use ($projectRoot, $ddlessDirectory, &$__ddless_cake_error) {
559569
}
560570
}
561571

562-
if (getenv('DDLESS_DEBUG_MODE') === 'true') {
563-
$debugModule = dirname(__DIR__, 2) . '/debug.php';
564-
if (file_exists($debugModule)) {
565-
require_once $debugModule;
566-
if (function_exists('ddless_register_stream_wrapper')) {
567-
ddless_register_stream_wrapper();
572+
if (getenv('DDLESS_DEBUG_MODE') === 'true' && !empty($GLOBALS['__DDLESS_INSTRUMENTED_CODE__'])) {
573+
foreach (array_keys($GLOBALS['__DDLESS_INSTRUMENTED_CODE__']) as $instrumentedPath) {
574+
if (is_file($instrumentedPath) && str_ends_with($instrumentedPath, '.php')) {
575+
include_once $instrumentedPath;
568576
}
569577
}
570578
}
@@ -576,6 +584,21 @@ function () use ($projectRoot, $ddlessDirectory, &$__ddless_cake_error) {
576584
$app->bootstrap();
577585
$app->pluginBootstrap();
578586

587+
// Server::run() always calls bootstrap() internally, which would re-load
588+
// plugins (DebugKit) and crash. This subclass guards against double bootstrap.
589+
$server = new class($app) extends \Cake\Http\Server {
590+
private bool $__bootstrapped = false;
591+
protected function bootstrap(): void {
592+
if ($this->__bootstrapped) return;
593+
parent::bootstrap();
594+
$this->__bootstrapped = true;
595+
}
596+
public function skipBootstrap(): void {
597+
$this->__bootstrapped = true;
598+
}
599+
};
600+
$server->skipBootstrap();
601+
579602
$request = \Cake\Http\ServerRequestFactory::fromGlobals();
580603

581604
if (!empty($_FILES) && class_exists('Laminas\Diactoros\UploadedFile')) {
@@ -612,7 +635,6 @@ function () use ($projectRoot, $ddlessDirectory, &$__ddless_cake_error) {
612635
}
613636
}
614637

615-
$server = new \Cake\Http\Server($app);
616638
$response = $server->run($request);
617639

618640
$statusCode = $response->getStatusCode();

0 commit comments

Comments
 (0)