Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions src/Server/WireAwareContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,53 @@
namespace Elabx\ProcessWireMcp\Server;

use ProcessWire\ProcessWire;
use Elabx\ProcessWireMcp\Bootstrap\ProcessWireBootstrap;
use Elabx\ProcessWireMcp\Tool\ProcessWireMcpTool;
use Elabx\ProcessWireMcp\Resource\ProcessWireMcpResource;
use Psr\Container\ContainerInterface;

/**
* PSR-11 container that resolves tool/resource classes with ProcessWire injected
* PSR-11 container that resolves tool/resource classes with ProcessWire injected.
*
* Re-bootstraps ProcessWire on every tool/resource call so each request sees
* current DB state (new fields, templates, pages added by migrations, etc.),
* following PHP's share-nothing principle.
*/
class WireAwareContainer implements ContainerInterface
{
private ProcessWire $wire;
private string $pwPath;
private array $instances = [];

public function __construct(ProcessWire $wire)
{
$this->wire = $wire;
$this->pwPath = rtrim($wire->wire('config')->paths->root, '/');
}

public function get(string $id): mixed
{
// Re-bootstrap ProcessWire so each call sees current DB state
$this->wire = ProcessWireBootstrap::boot($this->pwPath);

if (!isset($this->instances[$id])) {
if (!class_exists($id)) {
throw new class("Class not found: {$id}") extends \Exception implements \Psr\Container\NotFoundExceptionInterface {};
}

$instance = new $id();

// Inject ProcessWire if it's one of our base classes
if ($instance instanceof ProcessWireMcpTool) {
$instance->setWire($this->wire);
} elseif ($instance instanceof ProcessWireMcpResource) {
$instance->setWire($this->wire);
}

$this->instances[$id] = $instance;
}

return $this->instances[$id];
// Always inject the fresh ProcessWire instance
$instance = $this->instances[$id];
if ($instance instanceof ProcessWireMcpTool) {
$instance->setWire($this->wire);
} elseif ($instance instanceof ProcessWireMcpResource) {
$instance->setWire($this->wire);
}

return $instance;
}

public function has(string $id): bool
Expand Down
Loading