*/ private array $factories = []; /** @var array */ private array $instances = []; public function set(string $id, callable $factory): void { $this->factories[$id] = $factory; unset($this->instances[$id]); } /** @return mixed */ public function get(string $id) { if (!array_key_exists($id, $this->instances)) { if (!isset($this->factories[$id])) { throw new \LogicException(esc_html("No service registered for {$id}")); } $this->instances[$id] = ($this->factories[$id])($this); } return $this->instances[$id]; } public static function build(): self { $c = new self(); $c->set(Settings::class, static fn () => new Settings()); $c->set(Database\Db::class, static function () { global $wpdb; return new Database\Db($wpdb); }); $c->set(Jobs\JobRepository::class, static fn (Container $c) => new Jobs\JobRepository($c->get(Database\Db::class))); $c->set(Jobs\Lock::class, static fn (Container $c) => new Jobs\Lock($c->get(Database\Db::class))); $c->set(Database\RowReader::class, static fn (Container $c) => new Database\RowReader($c->get(Database\Db::class))); $c->set(Database\TableCopier::class, static fn (Container $c) => new Database\TableCopier($c->get(Database\Db::class), $c->get(Database\RowReader::class))); $c->set(Jobs\Planner::class, static function (Container $c) { $planner = new Jobs\Planner(); $planner->register('export', static fn (Jobs\Job $job) => Jobs\Plans::export($c, $job)); $planner->register('find_replace', static fn (Jobs\Job $job) => Jobs\Plans::find_replace($c, $job)); $planner->register('restore', static fn (Jobs\Job $job) => Jobs\Plans::restore($c, $job)); $planner->register('backup', static fn (Jobs\Job $job) => Jobs\Plans::backup($c, $job)); $planner->register('backup_restore', static fn (Jobs\Job $job) => Jobs\Plans::backup_restore($c, $job)); $planner->register('pull', static fn (Jobs\Job $job) => Jobs\Plans::pull($c, $job)); $planner->register('push', static fn (Jobs\Job $job) => Jobs\Plans::push($c, $job)); $planner->register('import', static fn (Jobs\Job $job) => Jobs\Plans::import($c, $job)); return $planner; }); $c->set(Database\Swap::class, static fn (Container $c) => new Database\Swap($c->get(Database\Db::class))); $c->set(Files\PointArchive::class, static fn (Container $c) => new Files\PointArchive($c->get(Jobs\JobRepository::class), $c->get(Jobs\Lock::class))); $c->set(Database\RestorePoints::class, static fn (Container $c) => new Database\RestorePoints( $c->get(Jobs\JobRepository::class), $c->get(Database\Swap::class), $c->get(Database\Db::class) )); $c->set(Database\SiteSwap::class, static fn (Container $c) => new Database\SiteSwap( $c->get(Database\Db::class), $c->get(Database\Swap::class), $c->get(Database\RestorePoints::class), $c->get(Settings::class) )); $c->set(Jobs\Runner::class, static fn (Container $c) => new Jobs\Runner( $c->get(Jobs\JobRepository::class), $c->get(Jobs\Planner::class), $c->get(Jobs\Lock::class), $c->get(Database\Db::class) )); $c->set(Security\KeyRepository::class, static fn (Container $c) => new Security\KeyRepository($c->get(Database\Db::class))); $c->set(Security\ReplayGuard::class, static fn (Container $c) => new Security\ReplayGuard($c->get(Database\Db::class))); $c->set(Remote\ConnectionRepository::class, static fn (Container $c) => new Remote\ConnectionRepository($c->get(Database\Db::class))); $c->set(Import\ImportUploads::class, static fn () => new Import\ImportUploads()); $c->set(Backups\BackupRepository::class, static fn (Container $c) => new Backups\BackupRepository($c->get(Database\Db::class))); $c->set(Backups\BackupService::class, static fn (Container $c) => new Backups\BackupService( $c->get(Backups\BackupRepository::class), $c->get(Settings::class), $c->get(Jobs\JobRepository::class) )); $c->set(Jobs\JobService::class, static fn (Container $c) => new Jobs\JobService( $c->get(Jobs\JobRepository::class), $c->get(Jobs\Runner::class), $c->get(Jobs\Lock::class), $c->get(Database\Db::class), $c->get(Settings::class), $c->get(Database\RestorePoints::class), $c->get(Backups\BackupService::class), $c->get(Remote\ConnectionRepository::class), $c->get(Remote\Client::class), $c->get(Import\ImportUploads::class) )); $c->set(Remote\Client::class, static fn (Container $c) => new Remote\Client($c->get(Remote\ConnectionRepository::class))); $c->set(Remote\Operations::class, static fn (Container $c) => new Remote\Operations( $c->get(Database\Db::class), $c->get(Jobs\JobRepository::class), $c->get(Database\TableCopier::class), $c->get(Settings::class), $c->get(Database\SiteSwap::class), $c->get(Security\KeyRepository::class), $c->get(Jobs\Runner::class) )); $c->set(Remote\Server::class, static fn (Container $c) => new Remote\Server( $c->get(Security\KeyRepository::class), $c->get(Security\ReplayGuard::class), $c->get(Jobs\JobRepository::class), $c->get(Remote\Operations::class), $c->get(Jobs\Lock::class) )); $c->set(Remote\Endpoint::class, static fn (Container $c) => new Remote\Endpoint($c->get(Remote\Server::class))); $c->set(Cli\Driver::class, static fn (Container $c) => new Cli\Driver($c->get(Jobs\Runner::class), $c->get(Jobs\JobRepository::class), $c->get(Settings::class))); $c->set(Multisite\MergePreview::class, static fn (Container $c) => new Multisite\MergePreview($c->get(Database\Db::class), $c->get(Remote\Client::class))); $c->set(Remote\ConnectionService::class, static fn (Container $c) => new Remote\ConnectionService($c->get(Remote\ConnectionRepository::class), $c->get(Remote\Client::class))); $c->set(Rest\AccessController::class, static fn (Container $c) => new Rest\AccessController($c->get(Security\KeyRepository::class), $c->get(Remote\ConnectionRepository::class), $c->get(Remote\ConnectionService::class), $c->get(Multisite\MergePreview::class))); $c->set(Rest\JobsController::class, static fn (Container $c) => new Rest\JobsController($c->get(Jobs\JobService::class), $c->get(Jobs\JobRepository::class))); $c->set(Rest\SettingsController::class, static fn (Container $c) => new Rest\SettingsController($c->get(Settings::class))); $c->set(Rest\FilesController::class, static fn (Container $c) => new Rest\FilesController($c->get(Jobs\JobService::class), $c->get(Jobs\JobRepository::class), $c->get(Database\RestorePoints::class))); $c->set(Rest\SiteController::class, static fn (Container $c) => new Rest\SiteController($c->get(Database\Db::class), $c->get(Jobs\JobRepository::class), $c->get(Settings::class), $c->get(Backups\BackupRepository::class))); $c->set(Rest\BackupsController::class, static fn (Container $c) => new Rest\BackupsController($c->get(Backups\BackupService::class), $c->get(Backups\BackupRepository::class), $c->get(Jobs\JobService::class))); $c->set(Profiles\ProfileRepository::class, static fn (Container $c) => new Profiles\ProfileRepository($c->get(Database\Db::class), $c->get(Remote\ConnectionRepository::class))); $c->set(Notify\NotificationSettings::class, static fn () => new Notify\NotificationSettings()); $c->set(Notify\Notifier::class, static fn (Container $c) => new Notify\Notifier($c->get(Notify\NotificationSettings::class), $c->get(Jobs\JobRepository::class))); $c->set(Rest\ProfilesController::class, static fn (Container $c) => new Rest\ProfilesController($c->get(Profiles\ProfileRepository::class))); $c->set(Rest\NotificationsController::class, static fn (Container $c) => new Rest\NotificationsController($c->get(Notify\NotificationSettings::class), $c->get(Notify\Notifier::class))); $c->set(Rest\ImportsController::class, static fn (Container $c) => new Rest\ImportsController($c->get(Import\ImportUploads::class))); $c->set(Rest\RestApi::class, static fn (Container $c) => new Rest\RestApi([ $c->get(Rest\JobsController::class), $c->get(Rest\SettingsController::class), $c->get(Rest\FilesController::class), $c->get(Rest\SiteController::class), $c->get(Rest\BackupsController::class), $c->get(Rest\AccessController::class), $c->get(Rest\ImportsController::class), $c->get(Rest\ProfilesController::class), $c->get(Rest\NotificationsController::class), ])); $c->set(Admin\Assets::class, static fn () => new Admin\Assets()); $c->set(Admin\Menu::class, static fn (Container $c) => new Admin\Menu($c->get(Admin\Assets::class))); return $c; } }