From 7e149a8289c84dee53108c50599ffa53da1150a3 Mon Sep 17 00:00:00 2001 From: Fabian Helfer Date: Thu, 8 Jan 2026 12:00:42 +0100 Subject: [PATCH 1/3] [Feature] NamedSetup Objective Start BackgroundTaskWorker --- .../Setup/BackgoundWorkerObjective.php | 200 ++++++++++++++++++ .../class.ilBackgroundTasksSetupAgent.php | 11 + 2 files changed, 211 insertions(+) create mode 100644 components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php diff --git a/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php b/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php new file mode 100644 index 000000000000..8001235f83d7 --- /dev/null +++ b/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php @@ -0,0 +1,200 @@ +getResource(Environment::RESOURCE_ADMIN_INTERACTION); + $settings_factory = $environment->getResource(Environment::RESOURCE_SETTINGS_FACTORY); + $ini = $environment->getResource(Environment::RESOURCE_ILIAS_INI); + + if ($io instanceof IOWrapper) { + $this->io = $io; + } + + $settings = $settings_factory->settingsFor('common'); + + try { + $internal_path = $settings->get('soap_internal_wsdl_path'); + if ($internal_path) { + $uri = (new \ILIAS\Data\URI($internal_path)); + parse_str($uri->getQuery() ?? '', $query); + $uri = (string) (isset($query['wsdl']) ? + $uri : + $uri->withQuery(http_build_query(array_merge($query, ['wsdl' => ''])))); + } elseif (trim($settings->get('soap_wsdl_path', '')) !== '') { + $uri = $settings->get('soap_wsdl_path', ''); + } else { + $uri = ilUtil::_getHttpPath() . '/public/soap/server.php?wsdl'; + } + $this->inform('Trying to call webserver by using WSDL: ' . $uri); + $soap_client = new SoapClient($uri, ['exceptions' => true, 'trace' => true, 'connection_timeout' => 10]); + $this->inform('SOAP client initialized'); + + $client_id = defined('CLIENT_ID') ? CLIENT_ID : $environment->getResource(Environment::RESOURCE_CLIENT_ID); + if ($client_id === null) { + throw new RuntimeException('CLIENT_ID is not defined.'); + } + + $url = $ini->readVariable('server', 'http_path'); + $session_url = rtrim($url, '/') . '/goto.php'; + $curl = $this->getCurlConnection($settings, $session_url); + $result = $curl->exec(); + $header_array = $curl->getResponseHeaderArray(); + $session_id = null; + if (isset($header_array['set-cookie'])) { + $set_cookie = $header_array['set-cookie']; + $cookies = is_array($set_cookie) ? $set_cookie : [$set_cookie]; + foreach ($cookies as $cookie) { + if (preg_match('/PHPSESSID=([^;]+)/i', $cookie, $matches)) { + $session_id = $matches[1]; + break; + } + } + } + + if ($session_id === null) { + throw new RuntimeException('Could not extract session ID from server response.'); + } + + if (!$result) { + throw new RuntimeException('Could not retrieve session ID from server.'); + } + + $this->inform('Obtained session ID: ' . substr($session_id, 0, 40)); + $session_string = $session_id ? ($session_id . '::' . $client_id) : ('::' . $client_id); + $this->inform('Calling startBackgroundTaskWorker with session: ' . ($session_id ? substr($session_id, 0, 40) : 'empty') . ', client: ' . $client_id); + + $result = $soap_client->__call('startBackgroundTaskWorker', [ + $session_string, + ]); + if ($result) { + $this->inform('Calling webserver successful.'); + } else { + throw new RuntimeException('Calling webserver failed.'); + } + } catch (Throwable $t) { + $this->error($t->getMessage()); + $this->error('Calling webserver failed'); + $this->error('Stack trace: ' . $t->getTraceAsString()); + } + + return $environment; + } + + private function inform(string $text, bool $force = false): void + { + if ($this->io === null || (!$force && !$this->io->isVerbose())) { + return; + } + + $this->io->inform($text); + } + + private function error(string $text): void + { + if ($this->io === null) { + return; + } + + $this->io->error($text); + } + + /** + * @throws ilCurlConnectionException + */ + private function getCurlConnection(ilSetting $settings, string $url): ilCurlConnection + { + $curl = new ilCurlConnection( + $url, + new ilProxySettings($settings) + ); + $curl->init(); + $curl->setOpt(CURLOPT_SSL_VERIFYPEER, 0); + $curl->setOpt(CURLOPT_SSL_VERIFYHOST, 0); + $curl->setOpt(CURLOPT_RETURNTRANSFER, 1); + $curl->setOpt(CURLOPT_FOLLOWLOCATION, 1); + $curl->setOpt(CURLOPT_MAXREDIRS, 1); + + return $curl; + } +} diff --git a/components/ILIAS/BackgroundTasks_/classes/Setup/class.ilBackgroundTasksSetupAgent.php b/components/ILIAS/BackgroundTasks_/classes/Setup/class.ilBackgroundTasksSetupAgent.php index 2953229e2615..f4983d0443c4 100755 --- a/components/ILIAS/BackgroundTasks_/classes/Setup/class.ilBackgroundTasksSetupAgent.php +++ b/components/ILIAS/BackgroundTasks_/classes/Setup/class.ilBackgroundTasksSetupAgent.php @@ -20,6 +20,7 @@ use ILIAS\Refinery; use ILIAS\Data; use ILIAS\UI; +use ILIAS\BackgroundTask\Setup\BackgoundWorkerObjective; class ilBackgroundTasksSetupAgent implements Setup\Agent { @@ -94,6 +95,16 @@ public function getStatusObjective(Setup\Metrics\Storage $storage): Setup\Object ); } + public function getNamedObjectives(?Setup\Config $config = null): array + { + return [ + 'startBackgroundWorker' => new Setup\ObjectiveConstructor( + 'Start Worker', + static fn(): Setup\Objective => new BackgoundWorkerObjective() + ) + ]; + } + /** * @inheritDoc */ From 3efee9cd6750d6e7a50e103ccf0cb01fcd5907bb Mon Sep 17 00:00:00 2001 From: Fabian Helfer Date: Thu, 8 Jan 2026 14:37:20 +0100 Subject: [PATCH 2/3] [Feature] NamedSetup Objective Start BackgroundTaskWorker Review Part I --- .../BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php | 2 +- .../classes/Setup/class.ilBackgroundTasksSetupAgent.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php b/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php index 8001235f83d7..8710ec03aed8 100644 --- a/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php +++ b/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php @@ -18,7 +18,7 @@ declare(strict_types=1); -namespace ILIAS\BackgroundTask\Setup; +namespace ILIAS\BackgroundTasks\Setup; use ilUtil; use ilSetting; diff --git a/components/ILIAS/BackgroundTasks_/classes/Setup/class.ilBackgroundTasksSetupAgent.php b/components/ILIAS/BackgroundTasks_/classes/Setup/class.ilBackgroundTasksSetupAgent.php index f4983d0443c4..e0fb869c25f7 100755 --- a/components/ILIAS/BackgroundTasks_/classes/Setup/class.ilBackgroundTasksSetupAgent.php +++ b/components/ILIAS/BackgroundTasks_/classes/Setup/class.ilBackgroundTasksSetupAgent.php @@ -20,7 +20,7 @@ use ILIAS\Refinery; use ILIAS\Data; use ILIAS\UI; -use ILIAS\BackgroundTask\Setup\BackgoundWorkerObjective; +use ILIAS\BackgroundTasks\Setup\BackgoundWorkerObjective; class ilBackgroundTasksSetupAgent implements Setup\Agent { From ffb6f7502f825151188bebc48e5f4dac20ba2af0 Mon Sep 17 00:00:00 2001 From: Fabian Helfer Date: Fri, 9 Jan 2026 10:45:27 +0100 Subject: [PATCH 3/3] [Feature] NamedSetup Objective Start BackgroundTaskWorker Part II --- .../classes/Setup/BackgoundWorkerObjective.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php b/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php index 8710ec03aed8..7fb67bc56d18 100644 --- a/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php +++ b/components/ILIAS/BackgroundTasks_/classes/Setup/BackgoundWorkerObjective.php @@ -37,6 +37,7 @@ use ilSettingsFactoryExistsObjective; use ILIAS\Setup\Objective\ClientIdReadObjective; use ILIAS\Setup\Objective\AdminConfirmedObjective; +use ilBackgroundTasksSetupConfig; class BackgoundWorkerObjective extends AdminConfirmedObjective { @@ -80,6 +81,20 @@ public function getPreconditions(Environment $environment): array ]; } + /** + * @inheritDoc + */ + public function isApplicable(Environment $environment): bool + { + $ini = $environment->getResource(Environment::RESOURCE_ILIAS_INI); + + if (!$ini->groupExists('background_tasks')) { + return false; + } + + return $ini->readVariable('background_tasks', 'concurrency') === ilBackgroundTasksSetupConfig::TYPE_ASYNCHRONOUS; + } + public function achieve(Environment $environment): Environment { $environment = parent::achieve($environment);