From 86a30a53238794f9f9703ce7aac296e9d312e382 Mon Sep 17 00:00:00 2001 From: Thibeau Fuhrer Date: Tue, 29 Oct 2024 15:49:08 +0100 Subject: [PATCH 1/2] [FIX] flaky ILIAS\LegalDocuments\Setup\ConsumerObjective artifact objective. --- components/ILIAS/DataProtection/classes/Consumer.php | 2 +- components/ILIAS/TermsOfService/classes/Consumer.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/ILIAS/DataProtection/classes/Consumer.php b/components/ILIAS/DataProtection/classes/Consumer.php index e50662a80e11..7324e5155233 100755 --- a/components/ILIAS/DataProtection/classes/Consumer.php +++ b/components/ILIAS/DataProtection/classes/Consumer.php @@ -46,7 +46,7 @@ final class Consumer implements ConsumerInterface public function __construct(?Container $container = null) { - $this->container = $container ?? $GLOBALS['DIC']; + $this->container = $container ?? $GLOBALS['DIC'] ?? new Container(); } public function id(): string diff --git a/components/ILIAS/TermsOfService/classes/Consumer.php b/components/ILIAS/TermsOfService/classes/Consumer.php index ac631e508633..e7f050a327ed 100755 --- a/components/ILIAS/TermsOfService/classes/Consumer.php +++ b/components/ILIAS/TermsOfService/classes/Consumer.php @@ -40,7 +40,7 @@ class Consumer implements ConsumerInterface public function __construct(?Container $container = null) { - $this->container = $container ?? $GLOBALS['DIC']; + $this->container = $container ?? $GLOBALS['DIC'] ?? new Container(); } public function id(): string From a59b171ff4ddf1b58669078a14a84e07224d1803 Mon Sep 17 00:00:00 2001 From: Thibeau Fuhrer Date: Tue, 29 Oct 2024 15:49:22 +0100 Subject: [PATCH 2/2] [FEATURE] implement UI initialisation using bootstrap mechanism. --- .../ILIAS/Authentication/Authentication.php | 26 + .../ILIAS/FileServices/FileServices.php | 5 + ...ileServicesLegacyInitialisationAdapter.php | 44 ++ components/ILIAS/Help/Help.php | 3 + components/ILIAS/Init/Init.php | 55 +++ .../Init/classes/class.ilInitialisation.php | 43 +- .../Init/resources/dependency_resolution.php | 22 + components/ILIAS/Init/resources/error.php | 3 +- components/ILIAS/Init/resources/ilias.php | 4 +- components/ILIAS/Init/resources/index.php | 8 +- components/ILIAS/Init/resources/login.php | 9 +- components/ILIAS/Init/resources/logout.php | 9 +- components/ILIAS/Init/resources/pwassist.php | 9 +- components/ILIAS/Init/resources/register.php | 9 +- .../ILIAS/Init/src/AllModernComponents.php | 172 +++++++ .../ILIAS/Init/tests/InitUIFrameworkTest.php | 90 ---- components/ILIAS/Language/Language.php | 6 + components/ILIAS/Language/src/Language.php | 6 + .../LanguageLegacyInitialisationAdapter.php | 52 ++ components/ILIAS/Refinery/src/Factory.php | 18 +- .../Logical/Constraint/LogicalOrTest.php | 7 + .../Constraint/PasswordContraintsTest.php | 7 + components/ILIAS/Refinery/tests/TestCase.php | 6 + .../Setup/resources/dependency_resolution.php | 20 +- components/ILIAS/StaticURL/resources/goto.php | 5 +- components/ILIAS/Style/Style.php | 3 + .../ScoreReporting/SettingsScoringGUITest.php | 10 +- .../tests/ilTestQuestionNavigationGUITest.php | 7 +- components/ILIAS/UI/UI.php | 451 ++++++++++++++++++ components/ILIAS/UI/docs/ROADMAP.md | 13 + .../Input/Field/GlobalUploadLimit.php | 29 ++ .../Component/Input/Field/PhpUploadLimit.php | 29 ++ .../ILIAS/UI/src/Component/Table/Data.php | 1 - .../ILIAS/UI/src/Component/Table/Storage.php | 25 + .../Component/Input/UploadLimitResolver.php | 24 +- .../Progress/DefaultAsyncRefreshInterval.php | 33 ++ .../UI/src/Implementation/DefaultRenderer.php | 3 + .../UI/src/Implementation/Render/Template.php | 7 - .../Render/ilJavaScriptBinding.php | 10 +- .../Render/ilResourceRegistry.php | 9 +- .../Render/ilTemplateWrapper.php | 18 +- .../Render/ilTemplateWrapperFactory.php | 9 +- components/ILIAS/UI/tests/Base.php | 5 +- .../Input/UploadLimitResolverTest.php | 21 +- .../ILIAS/UI/tests/Examples/ExamplesTest.php | 1 + .../tests}/InitUIFramework.php | 63 ++- .../UI/tests/Renderer/DefaultRendererTest.php | 15 +- components/ILIAS/UI/tests/UITestHelper.php | 36 +- .../ILIAS/UI/tests/UITestHelperTest.php | 57 --- components/ILIAS/UICore/UICore.php | 9 +- .../interface.ilGlobalTemplateInterface.php | 267 +---------- .../ILIAS/UICore/src/GlobalTemplate.php | 290 +++++++++++ ...balTemplateLegacyInitialisationAdapter.php | 253 ++++++++++ composer.json | 1 + 54 files changed, 1746 insertions(+), 591 deletions(-) create mode 100644 components/ILIAS/FileServices/src/FileServicesLegacyInitialisationAdapter.php create mode 100644 components/ILIAS/Init/resources/dependency_resolution.php create mode 100644 components/ILIAS/Init/src/AllModernComponents.php delete mode 100755 components/ILIAS/Init/tests/InitUIFrameworkTest.php create mode 100644 components/ILIAS/Language/src/LanguageLegacyInitialisationAdapter.php create mode 100644 components/ILIAS/UI/src/Component/Input/Field/GlobalUploadLimit.php create mode 100644 components/ILIAS/UI/src/Component/Input/Field/PhpUploadLimit.php create mode 100644 components/ILIAS/UI/src/Component/Table/Storage.php create mode 100644 components/ILIAS/UI/src/Implementation/Component/Progress/DefaultAsyncRefreshInterval.php rename components/ILIAS/{Init/classes/Dependencies => UI/tests}/InitUIFramework.php (90%) delete mode 100755 components/ILIAS/UI/tests/UITestHelperTest.php create mode 100644 components/ILIAS/UICore/src/GlobalTemplate.php create mode 100644 components/ILIAS/UICore/src/GlobalTemplateLegacyInitialisationAdapter.php diff --git a/components/ILIAS/Authentication/Authentication.php b/components/ILIAS/Authentication/Authentication.php index 07a4cbc71717..5afe2e7a6074 100644 --- a/components/ILIAS/Authentication/Authentication.php +++ b/components/ILIAS/Authentication/Authentication.php @@ -32,6 +32,32 @@ public function init( array | \ArrayAccess &$pull, array | \ArrayAccess &$internal, ): void { + // currently this is will be a session storage because we cannot store + // data on the client, see https://mantis.ilias.de/view.php?id=38503. + // @todo: this should be implemented by some proper key-value storage (or service). + $implement[UI\Component\Table\Storage::class] = static fn() => + new class () implements UI\Component\Table\Storage { + public function offsetExists(mixed $offset): bool + { + return \ilSession::has($offset); + } + public function offsetGet(mixed $offset): mixed + { + return \ilSession::get($offset); + } + public function offsetSet(mixed $offset, mixed $value): void + { + if (!is_string($offset)) { + throw new \InvalidArgumentException('Offset needs to be of type string.'); + } + \ilSession::set($offset, $value); + } + public function offsetUnset(mixed $offset): void + { + \ilSession::clear($offset); + } + }; + $contribute[\ILIAS\Setup\Agent::class] = static fn() => new \ilAuthenticationSetupAgent( $pull[\ILIAS\Refinery\Factory::class] diff --git a/components/ILIAS/FileServices/FileServices.php b/components/ILIAS/FileServices/FileServices.php index f638b6601bef..22a4881fb6c2 100644 --- a/components/ILIAS/FileServices/FileServices.php +++ b/components/ILIAS/FileServices/FileServices.php @@ -32,6 +32,11 @@ public function init( array | \ArrayAccess &$pull, array | \ArrayAccess &$internal, ): void { + $implement[UI\Component\Input\Field\PhpUploadLimit::class] = static fn() => + new FileServices\FileServicesLegacyInitialisationAdapter(); + $implement[UI\Component\Input\Field\GlobalUploadLimit::class] = static fn() => + new FileServices\FileServicesLegacyInitialisationAdapter(); + $contribute[\ILIAS\Setup\Agent::class] = static fn() => new \ilFileServicesSetupAgent( $pull[\ILIAS\Refinery\Factory::class] diff --git a/components/ILIAS/FileServices/src/FileServicesLegacyInitialisationAdapter.php b/components/ILIAS/FileServices/src/FileServicesLegacyInitialisationAdapter.php new file mode 100644 index 000000000000..817976b12292 --- /dev/null +++ b/components/ILIAS/FileServices/src/FileServicesLegacyInitialisationAdapter.php @@ -0,0 +1,44 @@ + + */ +class FileServicesLegacyInitialisationAdapter implements PhpUploadLimit, GlobalUploadLimit +{ + public function getPhpUploadLimitInBytes(): int + { + return (int) \ilFileUtils::getPhpUploadSizeLimitInBytes(); + } + + public function getGlobalUploadLimitInBytes(): ?int + { + global $DIC; + if ($DIC->offsetExists('upload_policy_resolver')) { + /** @var $DIC array{upload_policy_resolver: \UploadPolicyResolver} */ + return $DIC['upload_policy_resolver']->getUserUploadSizeLimitInBytes(); + } + return null; + } +} diff --git a/components/ILIAS/Help/Help.php b/components/ILIAS/Help/Help.php index 9be0ab1cf44c..977d21dabfdd 100644 --- a/components/ILIAS/Help/Help.php +++ b/components/ILIAS/Help/Help.php @@ -32,6 +32,9 @@ public function init( array | \ArrayAccess &$pull, array | \ArrayAccess &$internal, ): void { + $implement[UI\HelpTextRetriever::class] = static fn() => + new \ilHelpUITextRetriever(); + $contribute[\ILIAS\Setup\Agent::class] = static fn() => new \ILIAS\Help\Setup\Agent( $pull[\ILIAS\Refinery\Factory::class] diff --git a/components/ILIAS/Init/Init.php b/components/ILIAS/Init/Init.php index 7ccd822e9194..1d527e01e9e3 100644 --- a/components/ILIAS/Init/Init.php +++ b/components/ILIAS/Init/Init.php @@ -58,5 +58,60 @@ public function init( $contribute[Component\Resource\PublicAsset::class] = fn() => new Component\Resource\OfComponent($this, ".htaccess", "."); + + $contribute[Component\EntryPoint::class] = static fn() => + new Init\AllModernComponents( + $pull[\ILIAS\Refinery\Factory::class], + $pull[\ILIAS\Data\Factory::class], + $use[\ILIAS\UI\Factory::class], + $use[\ILIAS\UI\Renderer::class], + $pull[\ILIAS\UI\Implementation\Component\Counter\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Button\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Listing\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Image\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Panel\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Modal\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Dropzone\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Popover\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Divider\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Link\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Dropdown\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Item\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\ViewControl\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Chart\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Input\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Table\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\MessageBox\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Card\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Layout\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\MainControls\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Tree\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Menu\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Symbol\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Toast\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Legacy\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Launcher\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Entity\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Panel\Listing\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Modal\InterruptiveItem\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Chart\ProgressMeter\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Chart\Bar\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Input\ViewControl\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Input\Container\ViewControl\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Table\Column\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Table\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\MainControls\Slate\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Symbol\Icon\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Symbol\Glyph\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Symbol\Avatar\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Input\Container\Form\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Input\Container\Filter\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Input\Field\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Prompt\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Prompt\State\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Progress\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Progress\State\Factory::class], + $pull[\ILIAS\UI\Implementation\Component\Progress\State\Bar\Factory::class], + ); } } diff --git a/components/ILIAS/Init/classes/class.ilInitialisation.php b/components/ILIAS/Init/classes/class.ilInitialisation.php index dfdc9eed2df4..094a42cfe9db 100755 --- a/components/ILIAS/Init/classes/class.ilInitialisation.php +++ b/components/ILIAS/Init/classes/class.ilInitialisation.php @@ -39,12 +39,6 @@ $GLOBALS['ilGlobalStartTime'] = microtime(); } -global $DIC; -if (null === $DIC) { - // Don't remove this, intellisense autocompletion does not work in PhpStorm without a top level assignment - $DIC = new Container(); -} - /** * ILIAS Initialisation Utility Class * perform basic setup: init database handler, load configuration file, @@ -414,7 +408,7 @@ protected static function buildHTTPPath(): bool $ilias_http_path = preg_replace('/goto.php$/', '', $ilias_http_path); $ilias_http_path = preg_replace('/go\/.*$/', '', $ilias_http_path); - $f = new \ILIAS\Data\Factory(); + $f = $GLOBALS["DIC"][\ILIAS\Data\Factory::class]; $uri = $f->uri(ilFileUtils::removeTrailingPathSeparators($ilias_http_path)); $base_URI = $uri->getBaseURI(); @@ -432,7 +426,7 @@ protected static function determineClient(): void return; } global $DIC; - $df = new \ILIAS\Data\Factory(); + $df = $DIC[\ILIAS\Data\Factory::class]; // check whether ini file object exists if (!$DIC->isDependencyAvailable('iliasIni')) { @@ -782,7 +776,7 @@ protected static function initCron(\ILIAS\DI\Container $c): void $c->database(), $c->settings(), $c->logger()->cron(), - (new \ILIAS\Data\Factory())->clock() + $c[\ILIAS\Data\Factory::class]->clock(), ); }; } @@ -1074,9 +1068,6 @@ protected static function initLanguage(bool $a_use_user_language = true): void $DIC->offsetUnset('lng'); } self::initGlobal('lng', ilLanguage::getGlobalInstance()); - //re-init refinery with the user's language - unset($DIC['refinery']); - self::initRefinery($DIC); } else { self::initGlobal('lng', ilLanguage::getFallbackInstance()); } @@ -1200,7 +1191,6 @@ public static function initILIAS(): void return; } - $GLOBALS["DIC"] = new Container(); $GLOBALS["DIC"]["ilLoggerFactory"] = function ($c) { return ilLoggerFactory::getInstance(); }; @@ -1284,7 +1274,7 @@ protected static function initCore(): void // breaks CAS: must be included after CAS context isset in AuthUtils self::requireCommonIncludes(); - $GLOBALS["DIC"]["ilias.version"] = (new ILIAS\Data\Factory())->version(ILIAS_VERSION_NUMERIC); + $GLOBALS["DIC"]["ilias.version"] = $GLOBALS["DIC"][\ILIAS\Data\Factory::class]->version(ILIAS_VERSION_NUMERIC); // error handler self::initGlobal( @@ -1401,8 +1391,6 @@ protected static function initClient(): void self::setSessionCookieParams(); self::setClientIdCookie(); - self::initRefinery($DIC); - (new InitCtrlService())->init($DIC); // Init GlobalScreen @@ -1547,13 +1535,11 @@ private static function initGlobalScreen(\ILIAS\DI\Container $c): void } /** - * init the ILIAS UI framework. + * @deprecated this mechanism will be removed as part of the component revision and + * the refactoring to the new bootstrap mechanism. */ - public static function initUIFramework(\ILIAS\DI\Container $c): void + public static function applyPluginManipulationsToUiFramework(\ILIAS\DI\Container $c): void { - $init_ui = new InitUIFramework(); - $init_ui->init($c); - $component_repository = $c["component.repository"]; $component_factory = $c["component.factory"]; foreach ($component_repository->getPlugins() as $pl) { @@ -1571,19 +1557,6 @@ public static function initUIFramework(\ILIAS\DI\Container $c): void } } - /** - * @param \ILIAS\DI\Container $container - */ - protected static function initRefinery(\ILIAS\DI\Container $container): void - { - $container['refinery'] = function ($container) { - $dataFactory = new \ILIAS\Data\Factory(); - $language = $container['lng']; - - return new \ILIAS\Refinery\Factory($dataFactory, $language); - }; - } - /** * @param Container $container */ @@ -1628,7 +1601,7 @@ protected static function initHTML(): void self::initUploadPolicies($DIC); } - self::initUIFramework($GLOBALS["DIC"]); + self::applyPluginManipulationsToUiFramework($GLOBALS["DIC"]); $tpl = new ilGlobalPageTemplate($DIC->globalScreen(), $DIC->ui(), $DIC->http()); self::initGlobal("tpl", $tpl); diff --git a/components/ILIAS/Init/resources/dependency_resolution.php b/components/ILIAS/Init/resources/dependency_resolution.php new file mode 100644 index 000000000000..b85a2ca7c6cc --- /dev/null +++ b/components/ILIAS/Init/resources/dependency_resolution.php @@ -0,0 +1,22 @@ + [ + \ILIAS\Language\Language::class => \ILIAS\Language\LanguageLegacyInitialisationAdapter::class, + ], +]; diff --git a/components/ILIAS/Init/resources/error.php b/components/ILIAS/Init/resources/error.php index b463d8acebbc..9e40bc9afa1e 100644 --- a/components/ILIAS/Init/resources/error.php +++ b/components/ILIAS/Init/resources/error.php @@ -20,7 +20,8 @@ try { require_once '../vendor/composer/vendor/autoload.php'; - ilInitialisation::initILIAS(); + require_once __DIR__ . '/../artifacts/bootstrap_default.php'; + entry_point('ILIAS Legacy Initialisation Adapter'); $DIC->globalScreen()->tool()->context()->claim()->external(); $local_tpl = new ilGlobalTemplate("tpl.main.html", true, true); $local_tpl->addBlockFile("CONTENT", "content", "tpl.error.html"); diff --git a/components/ILIAS/Init/resources/ilias.php b/components/ILIAS/Init/resources/ilias.php index 214e0678d91d..57728c052ecd 100644 --- a/components/ILIAS/Init/resources/ilias.php +++ b/components/ILIAS/Init/resources/ilias.php @@ -23,8 +23,8 @@ } require_once '../vendor/composer/vendor/autoload.php'; - -ilInitialisation::initILIAS(); +require_once __DIR__ . '/../artifacts/bootstrap_default.php'; +entry_point('ILIAS Legacy Initialisation Adapter'); /** @var $DIC \ILIAS\DI\Container */ global $DIC; diff --git a/components/ILIAS/Init/resources/index.php b/components/ILIAS/Init/resources/index.php index db0a1cd39b41..1d77439ea7c2 100644 --- a/components/ILIAS/Init/resources/index.php +++ b/components/ILIAS/Init/resources/index.php @@ -44,7 +44,9 @@ } // END WebDAV: Block WebDAV Requests from Microsoft WebDAV MiniRedir client. -ilInitialisation::initILIAS(); +require_once __DIR__ . '/../artifacts/bootstrap_default.php'; +entry_point('ILIAS Legacy Initialisation Adapter'); -$ilCtrl->callBaseClass(ilStartUpGUI::class); -$ilBench->save(); +global $DIC; +$DIC->ctrl()->callBaseClass(ilStartUpGUI::class); +$DIC['ilBench']->save(); diff --git a/components/ILIAS/Init/resources/login.php b/components/ILIAS/Init/resources/login.php index 9ab7401f6d2c..6580e8c60ee3 100644 --- a/components/ILIAS/Init/resources/login.php +++ b/components/ILIAS/Init/resources/login.php @@ -23,10 +23,11 @@ } require_once '../vendor/composer/vendor/autoload.php'; +require_once __DIR__ . '/../artifacts/bootstrap_default.php'; +entry_point('ILIAS Legacy Initialisation Adapter'); -ilInitialisation::initILIAS(); - +global $DIC; ilStartUpGUI::setForcedCommand('showLoginPageOrStartupPage'); -$ilCtrl->callBaseClass(ilStartUpGUI::class); -$ilBench->save(); +$DIC->ctrl()->callBaseClass(ilStartUpGUI::class); +$DIC['ilBench']->save(); exit(); diff --git a/components/ILIAS/Init/resources/logout.php b/components/ILIAS/Init/resources/logout.php index 2cdf26f2c64c..f6f70f150415 100644 --- a/components/ILIAS/Init/resources/logout.php +++ b/components/ILIAS/Init/resources/logout.php @@ -23,10 +23,11 @@ } require_once '../vendor/composer/vendor/autoload.php'; +require_once __DIR__ . '/../artifacts/bootstrap_default.php'; +entry_point('ILIAS Legacy Initialisation Adapter'); -ilInitialisation::initILIAS(); - +global $DIC; ilStartUpGUI::setForcedCommand('doLogout'); -$ilCtrl->callBaseClass(ilStartUpGUI::class); -$ilBench->save(); +$DIC->ctrl()->callBaseClass(ilStartUpGUI::class); +$DIC['ilBench']->save(); exit(); diff --git a/components/ILIAS/Init/resources/pwassist.php b/components/ILIAS/Init/resources/pwassist.php index c74a46afc276..41928aa57c3a 100644 --- a/components/ILIAS/Init/resources/pwassist.php +++ b/components/ILIAS/Init/resources/pwassist.php @@ -23,10 +23,11 @@ } require_once '../vendor/composer/vendor/autoload.php'; +require_once __DIR__ . '/../artifacts/bootstrap_default.php'; +entry_point('ILIAS Legacy Initialisation Adapter'); -ilInitialisation::initILIAS(); - +global $DIC; ilStartUpGUI::setForcedCommand('jumpToPasswordAssistance'); -$ilCtrl->callBaseClass(ilStartUpGUI::class); -$ilBench->save(); +$DIC->ctrl()->callBaseClass(ilStartUpGUI::class); +$DIC['ilBench']->save(); exit(); diff --git a/components/ILIAS/Init/resources/register.php b/components/ILIAS/Init/resources/register.php index 3ec9505b99ac..2014d022e743 100644 --- a/components/ILIAS/Init/resources/register.php +++ b/components/ILIAS/Init/resources/register.php @@ -23,10 +23,11 @@ } require_once '../vendor/composer/vendor/autoload.php'; +require_once __DIR__ . '/../artifacts/bootstrap_default.php'; +entry_point('ILIAS Legacy Initialisation Adapter'); -ilInitialisation::initILIAS(); - +global $DIC; ilStartUpGUI::setForcedCommand('jumpToRegistration'); -$ilCtrl->callBaseClass(ilStartUpGUI::class); -$ilBench->save(); +$DIC->ctrl()->callBaseClass(ilStartUpGUI::class); +$DIC['ilBench']->save(); exit(); diff --git a/components/ILIAS/Init/src/AllModernComponents.php b/components/ILIAS/Init/src/AllModernComponents.php new file mode 100644 index 000000000000..c58b53a3bcde --- /dev/null +++ b/components/ILIAS/Init/src/AllModernComponents.php @@ -0,0 +1,172 @@ + + */ +class AllModernComponents implements \ILIAS\Component\EntryPoint +{ + public function __construct( + protected \ILIAS\Refinery\Factory $refinery_factory, + protected \ILIAS\Data\Factory $data_factory, + protected \ILIAS\UI\Factory $ui_factory, + protected \ILIAS\UI\Renderer $ui_renderer, + protected \ILIAS\UI\Component\Counter\Factory $ui_factory_counter, + protected \ILIAS\UI\Component\Button\Factory $ui_factory_button, + protected \ILIAS\UI\Component\Listing\Factory $ui_factory_listing, + protected \ILIAS\UI\Component\Image\Factory $ui_factory_image, + protected \ILIAS\UI\Component\Panel\Factory $ui_factory_panel, + protected \ILIAS\UI\Component\Modal\Factory $ui_factory_modal, + protected \ILIAS\UI\Component\Dropzone\Factory $ui_factory_dropzone, + protected \ILIAS\UI\Component\Popover\Factory $ui_factory_popover, + protected \ILIAS\UI\Component\Divider\Factory $ui_factory_divider, + protected \ILIAS\UI\Component\Link\Factory $ui_factory_link, + protected \ILIAS\UI\Component\Dropdown\Factory $ui_factory_dropdown, + protected \ILIAS\UI\Component\Item\Factory $ui_factory_item, + protected \ILIAS\UI\Component\Viewcontrol\Factory $ui_factory_viewcontrol, + protected \ILIAS\UI\Component\Chart\Factory $ui_factory_chart, + protected \ILIAS\UI\Component\Input\Factory $ui_factory_input, + protected \ILIAS\UI\Component\Table\Factory $ui_factory_table, + protected \ILIAS\UI\Component\MessageBox\Factory $ui_factory_messagebox, + protected \ILIAS\UI\Component\Card\Factory $ui_factory_card, + protected \ILIAS\UI\Component\Layout\Factory $ui_factory_layout, + protected \ILIAS\UI\Component\Maincontrols\Factory $ui_factory_maincontrols, + protected \ILIAS\UI\Component\Tree\Factory $ui_factory_tree, + protected \ILIAS\UI\Component\Menu\Factory $ui_factory_menu, + protected \ILIAS\UI\Component\Symbol\Factory $ui_factory_symbol, + protected \ILIAS\UI\Component\Toast\Factory $ui_factory_toast, + protected \ILIAS\UI\Component\Legacy\Factory $ui_factory_legacy, + protected \ILIAS\UI\Component\Launcher\Factory $ui_factory_launcher, + protected \ILIAS\UI\Component\Entity\Factory $ui_factory_entity, + protected \ILIAS\UI\Component\Panel\Listing\Factory $ui_factory_panel_listing, + protected \ILIAS\UI\Component\Modal\InterruptiveItem\Factory $ui_factory_interruptive_item, + protected \ILIAS\UI\Component\Chart\ProgressMeter\Factory $ui_factory_progressmeter, + protected \ILIAS\UI\Component\Chart\Bar\Factory $ui_factory_bar, + protected \ILIAS\UI\Component\Input\Viewcontrol\Factory $ui_factory_input_viewcontrol, + protected \ILIAS\UI\Component\Input\Container\ViewControl\Factory $ui_factory_input_container_viewcontrol, + protected \ILIAS\UI\Component\Table\Column\Factory $ui_factory_table_column, + protected \ILIAS\UI\Component\Table\Factory $ui_factory_table_action, + protected \ILIAS\UI\Component\Maincontrols\Slate\Factory $ui_factory_maincontrols_slate, + protected \ILIAS\UI\Component\Symbol\icon\Factory $ui_factory_symbol_icon, + protected \ILIAS\UI\Component\Symbol\Glyph\Factory $ui_factory_symbol_glyph, + protected \ILIAS\UI\Component\Symbol\avatar\Factory $ui_factory_symbol_avatar, + protected \ILIAS\UI\Component\Input\Container\Form\Factory $ui_factory_input_container_form, + protected \ILIAS\UI\Component\Input\Container\Filter\Factory $ui_factory_input_container_filter, + protected \ILIAS\UI\Component\Input\Field\Factory $ui_factory_input_field, + protected \ILIAS\UI\Component\Prompt\Factory $ui_prompt_factory, + protected \ILIAS\UI\Component\Prompt\State\Factory $ui_prompt_state_factory, + protected \ILIAS\UI\Component\Progress\Factory $ui_progress_factory, + protected \ILIAS\UI\Component\Progress\State\Factory $ui_progress_state_factory, + protected \ILIAS\UI\Component\Progress\State\Bar\Factory $ui_progress_state_bar_factory, + ) { + } + + /** + * Populates already bootstrapped components in the legacy service locator $DIC. + * Components which are not contained in the service locator are populated using their + * fully qualified namespace. E.g. to zse the data factory, access it the service like + * $DIC[\ILIAS\Refinery\Factory::class]; + * Components which have been populated in the past at some point, should be populated + * using their legacy offset, since it cannot be service-located by legacy components + * otherwise. + */ + protected function populateComponentsInLegacyEnvironment(\Pimple\Container $DIC): void + { + $DIC[\ILIAS\Data\Factory::class] = fn() => $this->data_factory; + + $DIC['refinery'] = fn() => $this->refinery_factory; + $DIC['ui.factory.counter'] = fn() => $this->ui_factory_counter; + $DIC['ui.factory.button'] = fn() => $this->ui_factory_button; + $DIC['ui.factory.listing'] = fn() => $this->ui_factory_listing; + $DIC['ui.factory.image'] = fn() => $this->ui_factory_image; + $DIC['ui.factory.panel'] = fn() => $this->ui_factory_panel; + $DIC['ui.factory.modal'] = fn() => $this->ui_factory_modal; + $DIC['ui.factory.progress'] = fn() => $this->ui_progress_factory; + $DIC['ui.factory.progress.state'] = fn() => $this->ui_progress_state_factory; + $DIC['ui.factory.progress.state.bar'] = fn() => $this->ui_progress_state_bar_factory; + $DIC['ui.factory.dropzone'] = fn() => $this->ui_factory_dropzone; + $DIC['ui.factory.popover'] = fn() => $this->ui_factory_popover; + $DIC['ui.factory.divider'] = fn() => $this->ui_factory_divider; + $DIC['ui.factory.link'] = fn() => $this->ui_factory_link; + $DIC['ui.factory.dropdown'] = fn() => $this->ui_factory_dropdown; + $DIC['ui.factory.item'] = fn() => $this->ui_factory_item; + $DIC['ui.factory.viewcontrol'] = fn() => $this->ui_factory_viewcontrol; + $DIC['ui.factory.chart'] = fn() => $this->ui_factory_chart; + $DIC['ui.factory.input'] = fn() => $this->ui_factory_input; + $DIC['ui.factory.table'] = fn() => $this->ui_factory_table; + $DIC['ui.factory.messagebox'] = fn() => $this->ui_factory_messagebox; + $DIC['ui.factory.card'] = fn() => $this->ui_factory_card; + $DIC['ui.factory.layout'] = fn() => $this->ui_factory_layout; + $DIC['ui.factory.maincontrols'] = fn() => $this->ui_factory_maincontrols; + $DIC['ui.factory.tree'] = fn() => $this->ui_factory_tree; + $DIC['ui.factory.menu'] = fn() => $this->ui_factory_menu; + $DIC['ui.factory.symbol'] = fn() => $this->ui_factory_symbol; + $DIC['ui.factory.toast'] = fn() => $this->ui_factory_toast; + $DIC['ui.factory.legacy'] = fn() => $this->ui_factory_legacy; + $DIC['ui.factory.launcher'] = fn() => $this->ui_factory_launcher; + $DIC['ui.factory.entity'] = fn() => $this->ui_factory_entity; + $DIC['ui.factory.prompt'] = fn() => $this->ui_prompt_factory; + $DIC['ui.factory.prompt.state'] = fn() => $this->ui_prompt_state_factory; + $DIC['ui.factory.panel.listing'] = fn() => $this->ui_factory_panel_listing; + $DIC['ui.factory.interruptive_item'] = fn() => $this->ui_factory_interruptive_item; + $DIC['ui.factory.progressmeter'] = fn() => $this->ui_factory_progressmeter; + $DIC['ui.factory.bar'] = fn() => $this->ui_factory_bar; + $DIC['ui.factory.input.viewcontrol'] = fn() => $this->ui_factory_input_viewcontrol; + $DIC['ui.factory.input.container.viewcontrol'] = fn() => $this->ui_factory_input_container_viewcontrol; + $DIC['ui.factory.table.column'] = fn() => $this->ui_factory_table_column; + $DIC['ui.factory.table.action'] = fn() => $this->ui_factory_table_action; + $DIC['ui.factory.maincontrols.slate'] = fn() => $this->ui_factory_maincontrols_slate; + $DIC['ui.factory.symbol.icon'] = fn() => $this->ui_factory_symbol_icon; + $DIC['ui.factory.symbol.glyph'] = fn() => $this->ui_factory_symbol_glyph; + $DIC['ui.factory.symbol.avatar'] = fn() => $this->ui_factory_symbol_avatar; + $DIC['ui.factory.input.container.form'] = fn() => $this->ui_factory_input_container_form; + $DIC['ui.factory.input.container.filter'] = fn() => $this->ui_factory_input_container_filter; + $DIC['ui.factory.input.field'] = fn() => $this->ui_factory_input_field; + $DIC['ui.factory'] = fn() => $this->ui_factory; + $DIC['ui.renderer'] = fn() => $this->ui_renderer; + } + + public function getName(): string + { + return 'ILIAS Legacy Initialisation Adapter'; + } + + public function enter(): int + { + global $DIC; + + $DIC = new \ILIAS\DI\Container(); + $GLOBALS['DIC'] = $DIC; + + $this->populateComponentsInLegacyEnvironment($DIC); + + \ilInitialisation::initILIAS(); + + return 0; + } +} diff --git a/components/ILIAS/Init/tests/InitUIFrameworkTest.php b/components/ILIAS/Init/tests/InitUIFrameworkTest.php deleted file mode 100755 index 9415e3245c7f..000000000000 --- a/components/ILIAS/Init/tests/InitUIFrameworkTest.php +++ /dev/null @@ -1,90 +0,0 @@ -dic = new \ILIAS\DI\Container(); - - $this->dic["lng"] = $this->createMock("\ilLanguage"); - $this->dic["tpl"] = $this->createMock("\ilGlobalTemplateInterface"); - $this->dic["refinery"] = $this->createMock("\ILIAS\Refinery\Factory"); - $this->dic["help.text_retriever"] = $this->createMock("ILIAS\UI\Help\TextRetriever\Echoing"); - } - - public function testUIFrameworkInitialization(): void - { - $this->assertInstanceOf("\ILIAS\DI\UIServices", $this->dic->ui()); - $this->assertFalse(isset($this->dic['ui.factory'])); - $this->assertFalse(isset($this->dic['ui.renderer'])); - (new \InitUIFramework())->init($this->dic); - $this->assertTrue(isset($this->dic['ui.factory'])); - $this->assertTrue(isset($this->dic['ui.renderer'])); - $this->assertInstanceOf("\ILIAS\UI\Factory", $this->dic->ui()->factory()); - $this->assertInstanceOf("\ILIAS\UI\Renderer", $this->dic->ui()->renderer()); - } - - /** - * This checks only by example that the factory is loaded and ready to work. - * A complete check of the factory is performed in the Test cases of tests/UI - */ - public function testByExampleThatFactoryIsLoaded(): void - { - (new \InitUIFramework())->init($this->dic); - - $this->assertInstanceOf( - "ILIAS\UI\Implementation\Component\Divider\Vertical", - $this->dic->ui()->factory()->divider()->vertical() - ); - } - - /** - * This checks only by example that the renderer is all up and ready to work. - * A complete set of the rendering tests is performed in the Test cases of tests/UI - * Note that some additional dependencies are needed for this to run. - */ - public function testByExampleThatRendererIsReadyToWork(): void - { - (new \InitUIFramework())->init($this->dic); - $this->dic["tpl"]->expects($this->atLeastOnce())->method("addJavaScript"); - - //Note, this dep is not properly injected ilTemplate, therefore we need to hit on the global. - global $DIC; - $initial_state = $DIC; - $DIC = new \ILIAS\DI\Container(); - $DIC["component.factory"] = $this->createMock(ilComponentFactory::class); - - $example_componanent = $this->dic->ui()->factory()->divider()->vertical(); - $example_out = $this->dic->ui()->renderer()->render($example_componanent); - $this->assertIsString($example_out); - $DIC = $initial_state; - } -} diff --git a/components/ILIAS/Language/Language.php b/components/ILIAS/Language/Language.php index da7461fdb281..b847464c4347 100644 --- a/components/ILIAS/Language/Language.php +++ b/components/ILIAS/Language/Language.php @@ -37,6 +37,9 @@ public function init( $implement[\ILIAS\Language\Language::class] = static fn() => $internal[\ilSetupLanguage::class]; + $implement[\ILIAS\Language\Language::class] = static fn() => + $internal[\ilLanguage::class]; + $contribute[\ILIAS\Setup\Agent::class] = static fn() => new \ilLanguageSetupAgent( $pull[\ILIAS\Refinery\Factory::class], @@ -45,5 +48,8 @@ public function init( $internal[\ilSetupLanguage::class] = static fn() => new \ilSetupLanguage("en"); + + $internal[\ilLanguage::class] = static fn() => + new Language\LanguageLegacyInitialisationAdapter(); } } diff --git a/components/ILIAS/Language/src/Language.php b/components/ILIAS/Language/src/Language.php index 046bd526c6ce..e492958f4626 100644 --- a/components/ILIAS/Language/src/Language.php +++ b/components/ILIAS/Language/src/Language.php @@ -24,5 +24,11 @@ interface Language { public function txt(string $a_topic, string $a_default_lang_fallback_mod = ""): string; + public function loadLanguageModule(string $a_module): void; + + public function getLangKey(): string; + + /** @param $key string|string[] */ + public function toJS($key): void; } diff --git a/components/ILIAS/Language/src/LanguageLegacyInitialisationAdapter.php b/components/ILIAS/Language/src/LanguageLegacyInitialisationAdapter.php new file mode 100644 index 000000000000..f46595f76d40 --- /dev/null +++ b/components/ILIAS/Language/src/LanguageLegacyInitialisationAdapter.php @@ -0,0 +1,52 @@ + + */ +class LanguageLegacyInitialisationAdapter implements Language +{ + public function txt(string $a_topic, string $a_default_lang_fallback_mod = ""): string + { + return $this->getLegacyLanguageInstance()->txt($a_topic, $a_default_lang_fallback_mod); + } + + public function loadLanguageModule(string $a_module): void + { + $this->getLegacyLanguageInstance()->loadLanguageModule($a_module); + } + + public function getLangKey(): string + { + return $this->getLegacyLanguageInstance()->getLangKey(); + } + + public function toJS($key): void + { + $this->getLegacyLanguageInstance()->toJS($key); + } + + protected function getLegacyLanguageInstance(): Language + { + global $DIC; + return $DIC->language(); + } +} diff --git a/components/ILIAS/Refinery/src/Factory.php b/components/ILIAS/Refinery/src/Factory.php index af6e4e22fad9..5c99a3b73606 100755 --- a/components/ILIAS/Refinery/src/Factory.php +++ b/components/ILIAS/Refinery/src/Factory.php @@ -31,8 +31,6 @@ public function __construct(\ILIAS\Data\Factory $dataFactory, \ILIAS\Language\La { $this->dataFactory = $dataFactory; $this->language = $language; - - $this->language->loadLanguageModule('validation'); } /** @@ -41,6 +39,7 @@ public function __construct(\ILIAS\Data\Factory $dataFactory, \ILIAS\Language\La */ public function to(): To\Group { + $this->loadLanguageModules(); return new To\Group($this->dataFactory, $this->language); } @@ -74,6 +73,7 @@ public function in(): In\Group */ public function int(): Integer\Group { + $this->loadLanguageModules(); return new Integer\Group($this->dataFactory, $this->language, $this->in()); } @@ -82,6 +82,7 @@ public function int(): Integer\Group */ public function string(): String\Group { + $this->loadLanguageModules(); return new String\Group($this->dataFactory, $this->language); } @@ -90,6 +91,7 @@ public function string(): String\Group */ public function custom(): Custom\Group { + $this->language->loadLanguageModule('validation'); return new Custom\Group($this->dataFactory, $this->language); } @@ -98,6 +100,7 @@ public function custom(): Custom\Group */ public function container(): Container\Group { + $this->loadLanguageModules(); return new Container\Group($this->dataFactory); } @@ -106,6 +109,7 @@ public function container(): Container\Group */ public function password(): Password\Group { + $this->loadLanguageModules(); return new Password\Group($this->dataFactory, $this->language); } @@ -114,6 +118,7 @@ public function password(): Password\Group */ public function logical(): Logical\Group { + $this->loadLanguageModules(); return new Logical\Group($this->dataFactory, $this->language); } @@ -122,6 +127,7 @@ public function logical(): Logical\Group */ public function null(): Constraint { + $this->loadLanguageModules(); return new IsNull($this->dataFactory, $this->language); } @@ -130,6 +136,7 @@ public function null(): Constraint */ public function numeric(): Numeric\Group { + $this->loadLanguageModules(); return new Numeric\Group($this->dataFactory, $this->language); } @@ -160,6 +167,7 @@ public function encode(): Encode\Group */ public function byTrying(array $transformations): ByTrying { + $this->loadLanguageModules(); return new ByTrying($transformations, $this->dataFactory, $this->language); } @@ -180,6 +188,12 @@ public function always($value): Transformation public function executable(): Transformation { + $this->loadLanguageModules(); return new IsExecutableTransformation($this->language); } + + protected function loadLanguageModules(): void + { + $this->language->loadLanguageModule('validation'); + } } diff --git a/components/ILIAS/Refinery/tests/Logical/Constraint/LogicalOrTest.php b/components/ILIAS/Refinery/tests/Logical/Constraint/LogicalOrTest.php index 1e877c412228..49fa15cdae21 100755 --- a/components/ILIAS/Refinery/tests/Logical/Constraint/LogicalOrTest.php +++ b/components/ILIAS/Refinery/tests/Logical/Constraint/LogicalOrTest.php @@ -127,6 +127,13 @@ public function txt(string $a_topic, string $a_default_lang_fallback_mod = ""): public function loadLanguageModule(string $a_module): void { } + public function getLangKey(): string + { + return ''; + } + public function toJS($key): void + { + } }; $data_factory = new DataFactory(); diff --git a/components/ILIAS/Refinery/tests/Password/Constraint/PasswordContraintsTest.php b/components/ILIAS/Refinery/tests/Password/Constraint/PasswordContraintsTest.php index 059bd3eb0520..b26fb9f4603a 100755 --- a/components/ILIAS/Refinery/tests/Password/Constraint/PasswordContraintsTest.php +++ b/components/ILIAS/Refinery/tests/Password/Constraint/PasswordContraintsTest.php @@ -38,6 +38,13 @@ public function txt(string $a_topic, string $a_default_lang_fallback_mod = ""): public function loadLanguageModule(string $a_module): void { } + public function getLangKey(): string + { + return ''; + } + public function toJS($key): void + { + } }; $d = new \ILIAS\Data\Factory(); $refinery = new \ILIAS\Refinery\Factory($d, $lng); diff --git a/components/ILIAS/Refinery/tests/TestCase.php b/components/ILIAS/Refinery/tests/TestCase.php index a5c9d32ee5e9..06c980972d7d 100755 --- a/components/ILIAS/Refinery/tests/TestCase.php +++ b/components/ILIAS/Refinery/tests/TestCase.php @@ -29,6 +29,7 @@ class ilLanguageMock implements Language /** @var string[] */ public array $requested = []; public string $lang_module = 'common'; + public string $lang_key = 'en'; public function __construct() { @@ -47,6 +48,11 @@ public function toJS($a_lang_key, ilGlobalTemplateInterface $a_tpl = null): void public function loadLanguageModule(string $a_module): void { } + + public function getLangKey(): string + { + return $this->lang_key; + } } abstract class TestCase extends PHPUnitTestCase diff --git a/components/ILIAS/Setup/resources/dependency_resolution.php b/components/ILIAS/Setup/resources/dependency_resolution.php index cef810dc97a8..e6a83658ed99 100644 --- a/components/ILIAS/Setup/resources/dependency_resolution.php +++ b/components/ILIAS/Setup/resources/dependency_resolution.php @@ -1,5 +1,20 @@ [ - "\\ILIAS\\Language\\Language" => "ilSetupLanguage" + \ILIAS\Language\Language::class => \ilSetupLanguage::class ], - "\\ILIAS\\Refinery" => [ - "\\ILIAS\Language\Language" => "myLanguage" - ] ]; diff --git a/components/ILIAS/StaticURL/resources/goto.php b/components/ILIAS/StaticURL/resources/goto.php index a29cd7dbb9d6..77b4de8679c6 100644 --- a/components/ILIAS/StaticURL/resources/goto.php +++ b/components/ILIAS/StaticURL/resources/goto.php @@ -21,7 +21,8 @@ use ILIAS\StaticURL\Services; require_once("../vendor/composer/vendor/autoload.php"); -ilInitialisation::initILIAS(); +require_once __DIR__ . '/../artifacts/bootstrap_default.php'; +entry_point('ILIAS Legacy Initialisation Adapter'); global $DIC; @@ -29,4 +30,4 @@ $static_url = $DIC['static_url']; $static_url->handler()->performRedirect( $static_url->builder()->getBaseURI() -); \ No newline at end of file +); diff --git a/components/ILIAS/Style/Style.php b/components/ILIAS/Style/Style.php index 795c6ac817c3..e2f0cef439b9 100644 --- a/components/ILIAS/Style/Style.php +++ b/components/ILIAS/Style/Style.php @@ -32,6 +32,9 @@ public function init( array | \ArrayAccess &$pull, array | \ArrayAccess &$internal, ): void { + $implement[UI\Implementation\Render\ImagePathResolver::class] = static fn() => + new \ilImagePathResolver(); + $contribute[\ILIAS\Setup\Agent::class] = static fn() => new \ilStyleSetupAgent( $pull[\ILIAS\Refinery\Factory::class] diff --git a/components/ILIAS/Test/tests/Settings/ScoreReporting/SettingsScoringGUITest.php b/components/ILIAS/Test/tests/Settings/ScoreReporting/SettingsScoringGUITest.php index 61f6005de574..8b259bee933c 100755 --- a/components/ILIAS/Test/tests/Settings/ScoreReporting/SettingsScoringGUITest.php +++ b/components/ILIAS/Test/tests/Settings/ScoreReporting/SettingsScoringGUITest.php @@ -27,16 +27,16 @@ */ class SettingsScoringGUITest extends ilTestBaseTestCase { + use UITestHelper; + protected function getUIComponents(): array { - $test_helper = new UITestHelper(); - return [ - $test_helper->factory(), - $test_helper->renderer(), + $this->factory(), + $this->renderer(), $this->createMock(ServerRequestInterface::class), $this->getMockBuilder(\ILIAS\Refinery\Factory::class)->disableOriginalConstructor()->getMock(), - $test_helper->mainTemplate(), + $this->mainTemplate(), $this->createMock(ilTabsGUI::class) ]; } diff --git a/components/ILIAS/Test/tests/ilTestQuestionNavigationGUITest.php b/components/ILIAS/Test/tests/ilTestQuestionNavigationGUITest.php index c70e53cbdaba..dbf0c174cd93 100755 --- a/components/ILIAS/Test/tests/ilTestQuestionNavigationGUITest.php +++ b/components/ILIAS/Test/tests/ilTestQuestionNavigationGUITest.php @@ -24,15 +24,16 @@ */ class ilTestQuestionNavigationGUITest extends ilTestBaseTestCase { + use UITestHelper; + private ilTestQuestionNavigationGUI $testObj; protected function setUp(): void { parent::setUp(); - $test_helper = new UITestHelper(); - $ui_factory = $test_helper->factory(); - $ui_renderer = $test_helper->renderer(); + $ui_factory = $this->factory(); + $ui_renderer = $this->renderer(); $this->testObj = new ilTestQuestionNavigationGUI( $this->createMock(ilLanguage::class), diff --git a/components/ILIAS/UI/UI.php b/components/ILIAS/UI/UI.php index dfe29b391ff3..146344e22a61 100644 --- a/components/ILIAS/UI/UI.php +++ b/components/ILIAS/UI/UI.php @@ -32,6 +32,457 @@ public function init( array | \ArrayAccess &$pull, array | \ArrayAccess &$internal, ): void { + $define[] = UI\Factory::class; + $define[] = UI\Renderer::class; + $define[] = UI\HelpTextRetriever::class; + $define[] = UI\Component\Table\Storage::class; + $define[] = UI\Component\Progress\AsyncRefreshInterval::class; + $define[] = UI\Component\Input\Field\PhpUploadLimit::class; + $define[] = UI\Component\Input\Field\GlobalUploadLimit::class; + $define[] = UI\Implementation\Render\ImagePathResolver::class; + + $implement[UI\Factory::class] = static fn() => + $internal[UI\Implementation\Factory::class]; + $implement[UI\Renderer::class] = static fn() => + $internal[UI\Implementation\DefaultRenderer::class]; + $implement[UI\Component\Progress\AsyncRefreshInterval::class] = static fn() => + $internal[UI\Implementation\Component\Progress\DefaultAsyncRefreshInterval::class]; + + // ================================================================================= + // ATTENTION: these factories are only populated inside $provide in order to + // keep plugin renderer- and factory-exchanges possible. These factories will + // only be internal again, once this functionality is improved for ILIAS 11. + $provide[UI\Implementation\Component\Counter\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Counter\Factory::class]; + $provide[UI\Implementation\Component\Button\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Button\Factory::class]; + $provide[UI\Implementation\Component\Listing\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Listing\Factory::class]; + $provide[UI\Implementation\Component\Image\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Image\Factory::class]; + $provide[UI\Implementation\Component\Panel\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Panel\Factory::class]; + $provide[UI\Implementation\Component\Modal\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Modal\Factory::class]; + $provide[UI\Implementation\Component\Progress\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Progress\Factory::class]; + $provide[UI\Implementation\Component\Progress\State\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Progress\State\Factory::class]; + $provide[UI\Implementation\Component\Progress\State\Bar\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Progress\State\Bar\Factory::class]; + $provide[UI\Implementation\Component\Dropzone\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Dropzone\Factory::class]; + $provide[UI\Implementation\Component\Popover\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Popover\Factory::class]; + $provide[UI\Implementation\Component\Divider\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Divider\Factory::class]; + $provide[UI\Implementation\Component\Link\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Link\Factory::class]; + $provide[UI\Implementation\Component\Dropdown\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Dropdown\Factory::class]; + $provide[UI\Implementation\Component\Item\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Item\Factory::class]; + $provide[UI\Implementation\Component\ViewControl\Factory::class] = static fn() => + $internal[UI\Implementation\Component\ViewControl\Factory::class]; + $provide[UI\Implementation\Component\Chart\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Chart\Factory::class]; + $provide[UI\Implementation\Component\Input\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Input\Factory::class]; + $provide[UI\Implementation\Component\Table\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Table\Factory::class]; + $provide[UI\Implementation\Component\MessageBox\Factory::class] = static fn() => + $internal[UI\Implementation\Component\MessageBox\Factory::class]; + $provide[UI\Implementation\Component\Card\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Card\Factory::class]; + $provide[UI\Implementation\Component\Layout\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Layout\Factory::class]; + $provide[UI\Implementation\Component\MainControls\Factory::class] = static fn() => + $internal[UI\Implementation\Component\MainControls\Factory::class]; + $provide[UI\Implementation\Component\Tree\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Tree\Factory::class]; + $provide[UI\Implementation\Component\Menu\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Menu\Factory::class]; + $provide[UI\Implementation\Component\Symbol\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Symbol\Factory::class]; + $provide[UI\Implementation\Component\Toast\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Toast\Factory::class]; + $provide[UI\Implementation\Component\Legacy\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Legacy\Factory::class]; + $provide[UI\Implementation\Component\Launcher\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Launcher\Factory::class]; + $provide[UI\Implementation\Component\Entity\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Entity\Factory::class]; + $provide[UI\Implementation\Component\Panel\Listing\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Panel\Listing\Factory::class]; + $provide[UI\Implementation\Component\Modal\InterruptiveItem\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Modal\InterruptiveItem\Factory::class]; + $provide[UI\Implementation\Component\Chart\ProgressMeter\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Chart\ProgressMeter\Factory::class]; + $provide[UI\Implementation\Component\Chart\Bar\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Chart\Bar\Factory::class]; + $provide[UI\Implementation\Component\Input\ViewControl\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Input\ViewControl\Factory::class]; + $provide[UI\Implementation\Component\Input\Container\ViewControl\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Input\Container\ViewControl\Factory::class]; + $provide[UI\Implementation\Component\Table\Column\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Table\Column\Factory::class]; + $provide[UI\Implementation\Component\Table\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Table\Factory::class]; + $provide[UI\Implementation\Component\MainControls\Slate\Factory::class] = static fn() => + $internal[UI\Implementation\Component\MainControls\Slate\Factory::class]; + $provide[UI\Implementation\Component\Symbol\Icon\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Symbol\Icon\Factory::class]; + $provide[UI\Implementation\Component\Symbol\Glyph\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Symbol\Glyph\Factory::class]; + $provide[UI\Implementation\Component\Symbol\Avatar\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Symbol\Avatar\Factory::class]; + $provide[UI\Implementation\Component\Input\Container\Form\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Input\Container\Form\Factory::class]; + $provide[UI\Implementation\Component\Input\Container\Filter\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Input\Container\Filter\Factory::class]; + $provide[UI\Implementation\Component\Input\Field\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Input\Field\Factory::class]; + $provide[UI\Implementation\Component\Prompt\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Prompt\Factory::class]; + $provide[UI\Implementation\Component\Prompt\State\Factory::class] = static fn() => + $internal[UI\Implementation\Component\Prompt\State\Factory::class]; + // ================================================================================= + + $internal[UI\Implementation\Factory::class] = static fn() => + new UI\Implementation\Factory( + $internal[UI\Implementation\Component\Counter\Factory::class], + $internal[UI\Implementation\Component\Button\Factory::class], + $internal[UI\Implementation\Component\Listing\Factory::class], + $internal[UI\Implementation\Component\Image\Factory::class], + $internal[UI\Implementation\Component\Panel\Factory::class], + $internal[UI\Implementation\Component\Modal\Factory::class], + $internal[UI\Implementation\Component\Progress\Factory::class], + $internal[UI\Implementation\Component\Dropzone\Factory::class], + $internal[UI\Implementation\Component\Popover\Factory::class], + $internal[UI\Implementation\Component\Divider\Factory::class], + $internal[UI\Implementation\Component\Link\Factory::class], + $internal[UI\Implementation\Component\Dropdown\Factory::class], + $internal[UI\Implementation\Component\Item\Factory::class], + $internal[UI\Implementation\Component\ViewControl\Factory::class], + $internal[UI\Implementation\Component\Chart\Factory::class], + $internal[UI\Implementation\Component\Input\Factory::class], + $internal[UI\Implementation\Component\Table\Factory::class], + $internal[UI\Implementation\Component\MessageBox\Factory::class], + $internal[UI\Implementation\Component\Card\Factory::class], + $internal[UI\Implementation\Component\Layout\Factory::class], + $internal[UI\Implementation\Component\MainControls\Factory::class], + $internal[UI\Implementation\Component\Tree\Factory::class], + $internal[UI\Implementation\Component\Menu\Factory::class], + $internal[UI\Implementation\Component\Symbol\Factory::class], + $internal[UI\Implementation\Component\Toast\Factory::class], + $internal[UI\Implementation\Component\Legacy\Factory::class], + $internal[UI\Implementation\Component\Launcher\Factory::class], + $internal[UI\Implementation\Component\Entity\Factory::class], + $internal[UI\Implementation\Component\Prompt\Factory::class], + ); + + $internal[UI\Implementation\Component\Counter\Factory::class] = static fn() => + new UI\Implementation\Component\Counter\Factory(); + + $internal[UI\Implementation\Component\Button\Factory::class] = static fn() => + new UI\Implementation\Component\Button\Factory(); + + $internal[UI\Implementation\Component\Listing\Factory::class] = static fn() => + new UI\Implementation\Component\Listing\Factory(); + + $internal[UI\Implementation\Component\Image\Factory::class] = static fn() => + new UI\Implementation\Component\Image\Factory(); + + $internal[UI\Implementation\Component\Panel\Factory::class] = static fn() => + new UI\Implementation\Component\Panel\Factory( + $internal[UI\Implementation\Component\Panel\Listing\Factory::class], + ); + $internal[UI\Implementation\Component\Panel\Listing\Factory::class] = static fn() => + new UI\Implementation\Component\Panel\Listing\Factory(); + + $internal[UI\Implementation\Component\Modal\Factory::class] = static fn() => + new UI\Implementation\Component\Modal\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $internal[UI\Implementation\Component\Modal\InterruptiveItem\Factory::class], + $internal[UI\Implementation\Component\Input\Field\Factory::class], + ); + $internal[UI\Implementation\Component\SignalGeneratorInterface::class] = static fn() => + new UI\Implementation\Component\SignalGenerator(); + $internal[UI\Implementation\Component\Modal\InterruptiveItem\Factory::class] = static fn() => + new UI\Implementation\Component\Modal\InterruptiveItem\Factory(); + + $internal[UI\Implementation\Component\Progress\Factory::class] = static fn() => + new UI\Implementation\Component\Progress\Factory( + $use[UI\Component\Progress\AsyncRefreshInterval::class], + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $internal[UI\Implementation\Component\Progress\State\Factory::class], + ); + $internal[UI\Implementation\Component\Progress\State\Factory::class] = static fn() => + new UI\Implementation\Component\Progress\State\Factory( + $internal[UI\Implementation\Component\Progress\State\Bar\Factory::class], + ); + $internal[UI\Implementation\Component\Progress\State\Bar\Factory::class] = static fn() => + new UI\Implementation\Component\Progress\State\Bar\Factory(); + $internal[UI\Implementation\Component\Progress\DefaultAsyncRefreshInterval::class] = static fn() => + new UI\Implementation\Component\Progress\DefaultAsyncRefreshInterval(); + + $internal[UI\Implementation\Component\Dropzone\Factory::class] = static fn() => + new UI\Implementation\Component\Dropzone\Factory( + $internal[UI\Implementation\Component\Dropzone\File\Factory::class], + ); + $internal[UI\Implementation\Component\Dropzone\File\Factory::class] = static fn() => + new UI\Implementation\Component\Dropzone\File\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $internal[UI\Implementation\Component\Input\Field\Factory::class], + ); + + $internal[UI\Implementation\Component\Popover\Factory::class] = static fn() => + new UI\Implementation\Component\Popover\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + ); + + $internal[UI\Implementation\Component\Divider\Factory::class] = static fn() => + new UI\Implementation\Component\Divider\Factory(); + + $internal[UI\Implementation\Component\Link\Factory::class] = static fn() => + new UI\Implementation\Component\Link\Factory(); + + $internal[UI\Implementation\Component\Dropdown\Factory::class] = static fn() => + new UI\Implementation\Component\Dropdown\Factory(); + + $internal[UI\Implementation\Component\Item\Factory::class] = static fn() => + new UI\Implementation\Component\Item\Factory(); + + $internal[UI\Implementation\Component\ViewControl\Factory::class] = static fn() => + new UI\Implementation\Component\ViewControl\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + ); + + $internal[UI\Implementation\Component\Chart\Factory::class] = static fn() => + new UI\Implementation\Component\Chart\Factory( + $internal[UI\Implementation\Component\Chart\ProgressMeter\Factory::class], + $internal[UI\Implementation\Component\Chart\Bar\Factory::class], + ); + $internal[UI\Implementation\Component\Chart\ProgressMeter\Factory::class] = static fn() => + new UI\Implementation\Component\Chart\ProgressMeter\Factory(); + $internal[UI\Implementation\Component\Chart\Bar\Factory::class] = static fn() => + new UI\Implementation\Component\Chart\Bar\Factory(); + + $internal[UI\Implementation\Component\Input\Factory::class] = static fn() => + new UI\Implementation\Component\Input\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $internal[UI\Implementation\Component\Input\Field\Factory::class], + $internal[UI\Implementation\Component\Input\Container\Factory::class], + $internal[UI\Implementation\Component\Input\ViewControl\Factory::class], + ); + $internal[UI\Implementation\Component\Input\Field\Factory::class] = static fn() => + new UI\Implementation\Component\Input\Field\Factory( + $internal[UI\Implementation\Component\Input\UploadLimitResolver::class], + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $pull[Data\Factory::class], + $pull[Refinery\Factory::class], + $use[Language\Language::class] + ); + $internal[UI\Implementation\Component\Input\UploadLimitResolver::class] = static fn() => + new UI\Implementation\Component\Input\UploadLimitResolver( + $use[UI\Component\Input\Field\PhpUploadLimit::class], + $use[UI\Component\Input\Field\GlobalUploadLimit::class], + ); + $internal[UI\Implementation\Component\Input\Container\Factory::class] = static fn() => + new UI\Implementation\Component\Input\Container\Factory( + $internal[UI\Implementation\Component\Input\Container\Form\Factory::class], + $internal[UI\Implementation\Component\Input\Container\Filter\Factory::class], + $internal[UI\Implementation\Component\Input\Container\ViewControl\Factory::class], + ); + $internal[UI\Implementation\Component\Input\Container\Form\Factory::class] = static fn() => + new UI\Implementation\Component\Input\Container\Form\Factory( + $internal[UI\Implementation\Component\Input\Field\Factory::class], + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + ); + $internal[UI\Implementation\Component\Input\Container\Filter\Factory::class] = static fn() => + new UI\Implementation\Component\Input\Container\Filter\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $internal[UI\Implementation\Component\Input\Field\Factory::class], + ); + $internal[UI\Implementation\Component\Input\Container\ViewControl\Factory::class] = static fn() => + new UI\Implementation\Component\Input\Container\ViewControl\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $internal[UI\Implementation\Component\Input\ViewControl\Factory::class], + ); + $internal[UI\Implementation\Component\Input\ViewControl\Factory::class] = static fn() => + new UI\Implementation\Component\Input\ViewControl\Factory( + $internal[UI\Implementation\Component\Input\Field\Factory::class], + $pull[Data\Factory::class], + $pull[Refinery\Factory::class], + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $use[Language\Language::class], + ); + + $internal[UI\Implementation\Component\Table\Factory::class] = static fn() => + new UI\Implementation\Component\Table\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $internal[UI\Implementation\Component\Input\ViewControl\Factory::class], + $internal[UI\Implementation\Component\Input\Container\ViewControl\Factory::class], + $pull[Data\Factory::class], + $internal[UI\Implementation\Component\Table\Column\Factory::class], + $internal[UI\Implementation\Component\Table\Action\Factory::class], + $use[UI\Component\Table\Storage::class], + $internal[UI\Implementation\Component\Table\DataRowBuilder::class], + $internal[UI\Implementation\Component\Table\OrderingRowBuilder::class], + ); + $internal[UI\Implementation\Component\Table\Column\Factory::class] = static fn() => + new UI\Implementation\Component\Table\Column\Factory( + $use[\ILIAS\Language\Language::class], + ); + $internal[UI\Implementation\Component\Table\Action\Factory::class] = static fn() => + new UI\Implementation\Component\Table\Action\Factory(); + $internal[UI\Implementation\Component\Table\DataRowBuilder::class] = static fn() => + new UI\Implementation\Component\Table\DataRowBuilder(); + $internal[UI\Implementation\Component\Table\OrderingRowBuilder::class] = static fn() => + new UI\Implementation\Component\Table\OrderingRowBuilder(); + + $internal[UI\Implementation\Component\MessageBox\Factory::class] = static fn() => + new UI\Implementation\Component\MessageBox\Factory(); + + $internal[UI\Implementation\Component\Card\Factory::class] = static fn() => + new UI\Implementation\Component\Card\Factory(); + + $internal[UI\Implementation\Component\Layout\Factory::class] = static fn() => + new UI\Implementation\Component\Layout\Factory(); + + $internal[UI\Implementation\Component\MainControls\Factory::class] = static fn() => + new UI\Implementation\Component\MainControls\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $internal[UI\Implementation\Component\MainControls\Slate\Factory::class], + ); + $internal[UI\Implementation\Component\MainControls\Slate\Factory::class] = static fn() => + new UI\Implementation\Component\MainControls\Slate\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + $internal[UI\Implementation\Component\Counter\Factory::class], + $internal[UI\Implementation\Component\Symbol\Factory::class], + ); + + $internal[UI\Implementation\Component\Tree\Factory::class] = static fn() => + new UI\Implementation\Component\Tree\Factory(); + + $internal[UI\Implementation\Component\Menu\Factory::class] = static fn() => + new UI\Implementation\Component\Menu\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + ); + + $internal[UI\Implementation\Component\Symbol\Factory::class] = static fn() => + new UI\Implementation\Component\Symbol\Factory( + $internal[UI\Implementation\Component\Symbol\Icon\Factory::class], + $internal[UI\Implementation\Component\Symbol\Glyph\Factory::class], + $internal[UI\Implementation\Component\Symbol\Avatar\Factory::class], + ); + $internal[UI\Implementation\Component\Symbol\Icon\Factory::class] = static fn() => + new UI\Implementation\Component\Symbol\Icon\Factory(); + $internal[UI\Implementation\Component\Symbol\Glyph\Factory::class] = static fn() => + new UI\Implementation\Component\Symbol\Glyph\Factory(); + $internal[UI\Implementation\Component\Symbol\Avatar\Factory::class] = static fn() => + new UI\Implementation\Component\Symbol\Avatar\Factory(); + + $internal[UI\Implementation\Component\Toast\Factory::class] = static fn() => + new UI\Implementation\Component\Toast\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + ); + + $internal[UI\Implementation\Component\Legacy\Factory::class] = static fn() => + new UI\Implementation\Component\Legacy\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + ); + + $internal[UI\Implementation\Component\Launcher\Factory::class] = static fn() => + new UI\Implementation\Component\Launcher\Factory( + $internal[UI\Implementation\Component\Modal\Factory::class], + ); + + $internal[UI\Implementation\Component\Entity\Factory::class] = static fn() => + new UI\Implementation\Component\Entity\Factory(); + + $internal[UI\Implementation\Component\Prompt\Factory::class] = static fn() => + new UI\Implementation\Component\Prompt\Factory( + $internal[UI\Implementation\Component\SignalGeneratorInterface::class], + ); + $internal[UI\Implementation\Component\Prompt\State\Factory::class] = static fn() => + new UI\Implementation\Component\Prompt\State\Factory(); + + $internal[UI\Implementation\DefaultRenderer::class] = static fn() => + new UI\Implementation\DefaultRenderer( + $internal[UI\Implementation\Render\Loader::class], + $internal[UI\Implementation\Render\JavaScriptBinding::class], + $use[Language\Language::class], + ); + $internal[UI\Implementation\Render\Loader::class] = static fn() => + new UI\Implementation\Render\LoaderCachingWrapper( + new UI\Implementation\Render\LoaderResourceRegistryWrapper( + $internal[UI\Implementation\Render\ResourceRegistry::class], + new UI\Implementation\Render\FSLoader( + new UI\Implementation\Render\DefaultRendererFactory( + $use[UI\Factory::class], + $internal[UI\Implementation\Render\TemplateFactory::class], + $use[Language\Language::class], + $internal[UI\Implementation\Render\JavaScriptBinding::class], + $use[UI\Implementation\Render\ImagePathResolver::class], + $pull[Data\Factory::class], + $use[UI\HelpTextRetriever::class], + $internal[UI\Implementation\Component\Input\UploadLimitResolver::class], + ), + new UI\Implementation\Component\Symbol\Glyph\GlyphRendererFactory( + $use[UI\Factory::class], + $internal[UI\Implementation\Render\TemplateFactory::class], + $use[Language\Language::class], + $internal[UI\Implementation\Render\JavaScriptBinding::class], + $use[UI\Implementation\Render\ImagePathResolver::class], + $pull[Data\Factory::class], + $use[UI\HelpTextRetriever::class], + $internal[UI\Implementation\Component\Input\UploadLimitResolver::class], + ), + new UI\Implementation\Component\Input\Field\FieldRendererFactory( + $use[UI\Factory::class], + $internal[UI\Implementation\Render\TemplateFactory::class], + $use[Language\Language::class], + $internal[UI\Implementation\Render\JavaScriptBinding::class], + $use[UI\Implementation\Render\ImagePathResolver::class], + $pull[Data\Factory::class], + $use[UI\HelpTextRetriever::class], + $internal[UI\Implementation\Component\Input\UploadLimitResolver::class], + ), + new UI\Implementation\Component\MessageBox\MessageBoxRendererFactory( + $use[UI\Factory::class], + $internal[UI\Implementation\Render\TemplateFactory::class], + $use[Language\Language::class], + $internal[UI\Implementation\Render\JavaScriptBinding::class], + $use[UI\Implementation\Render\ImagePathResolver::class], + $pull[Data\Factory::class], + $use[UI\HelpTextRetriever::class], + $internal[UI\Implementation\Component\Input\UploadLimitResolver::class], + ), + new UI\Implementation\Component\Input\Container\Form\FormRendererFactory( + $use[UI\Factory::class], + $internal[UI\Implementation\Render\TemplateFactory::class], + $use[Language\Language::class], + $internal[UI\Implementation\Render\JavaScriptBinding::class], + $use[UI\Implementation\Render\ImagePathResolver::class], + $pull[Data\Factory::class], + $use[UI\HelpTextRetriever::class], + $internal[UI\Implementation\Component\Input\UploadLimitResolver::class], + ) + ) + ) + ); + $internal[UI\Implementation\Render\JavaScriptBinding::class] = static fn() => + new UI\Implementation\Render\ilJavaScriptBinding( + $use[UICore\GlobalTemplate::class], + ); + $internal[UI\Implementation\Render\ResourceRegistry::class] = static fn() => + new UI\Implementation\Render\ilResourceRegistry( + $use[UICore\GlobalTemplate::class], + ); + $internal[UI\Implementation\Render\TemplateFactory::class] = static fn() => + new UI\Implementation\Render\ilTemplateWrapperFactory(); + $contribute[Component\Resource\PublicAsset::class] = fn() => new Component\Resource\ComponentJS($this, "js/Button/button.js"); $contribute[Component\Resource\PublicAsset::class] = fn() => diff --git a/components/ILIAS/UI/docs/ROADMAP.md b/components/ILIAS/UI/docs/ROADMAP.md index a62bff2f85b4..a9deebf4a9c0 100755 --- a/components/ILIAS/UI/docs/ROADMAP.md +++ b/components/ILIAS/UI/docs/ROADMAP.md @@ -480,6 +480,19 @@ functions in form of arguments. While at it, all other dependencies such as the injected this way too, ultimately getting rid of all the `$DIC` usages. To achieve this, we need to adjust every example function signature, as well as the Kitchensink where the examples are built. +### Remove `LegacyInitialisation` class from unit tests (advanced, ~3d) + +As part of the component revision we have migrated the UI framework to the new bootstrap mechanism. +This resulted in the removal of the `InitUIFramework` class inside the Init component, which was +responsible for a full initialisation of the UI framework. Some unit tests however, mostly for example and +T&A rendering tests, still rely on this. + +The problem is that we cannot properly inject the our components into unit tests using the bootstrap +mechanism. This means, we either need a way to combine these two worlds, like we did with the "bridge" to the +legacy initialisation of the Init component (see https://github.com/ILIAS-eLearning/ILIAS/pull/7969), +or refactor our unit tests in a way where no fully initialised UI framework is required. For the time being +we have moved a copy of the `InitUIFramework` into our `tests/` directory, so unit tests still pass. + ## Ideas and Food for Thought * Create a mechanism to wire less-files to delos.less that is more automatic than diff --git a/components/ILIAS/UI/src/Component/Input/Field/GlobalUploadLimit.php b/components/ILIAS/UI/src/Component/Input/Field/GlobalUploadLimit.php new file mode 100644 index 000000000000..79648ab7124d --- /dev/null +++ b/components/ILIAS/UI/src/Component/Input/Field/GlobalUploadLimit.php @@ -0,0 +1,29 @@ + + */ +interface GlobalUploadLimit +{ + /** + * Returns a global upload limit in bytes, may exceed the @see PhpUploadLimit + */ + public function getGlobalUploadLimitInBytes(): ?int; +} diff --git a/components/ILIAS/UI/src/Component/Input/Field/PhpUploadLimit.php b/components/ILIAS/UI/src/Component/Input/Field/PhpUploadLimit.php new file mode 100644 index 000000000000..56b16fb7e26e --- /dev/null +++ b/components/ILIAS/UI/src/Component/Input/Field/PhpUploadLimit.php @@ -0,0 +1,29 @@ + + */ +interface PhpUploadLimit +{ + /** + * Returns the smaller php-ini option of 'post_max_size' and 'upload_max_filesize' in bytes. + */ + public function getPhpUploadLimitInBytes(): int; +} diff --git a/components/ILIAS/UI/src/Component/Table/Data.php b/components/ILIAS/UI/src/Component/Table/Data.php index 46c5221b6336..8e95d409de7f 100755 --- a/components/ILIAS/UI/src/Component/Table/Data.php +++ b/components/ILIAS/UI/src/Component/Table/Data.php @@ -20,7 +20,6 @@ namespace ILIAS\UI\Component\Table; -use ILIAS\UI\Component\Input\ViewControl\ViewControl; use Psr\Http\Message\ServerRequestInterface; use ILIAS\Data\Order; use ILIAS\Data\Range; diff --git a/components/ILIAS/UI/src/Component/Table/Storage.php b/components/ILIAS/UI/src/Component/Table/Storage.php new file mode 100644 index 000000000000..c06dbde283ce --- /dev/null +++ b/components/ILIAS/UI/src/Component/Table/Storage.php @@ -0,0 +1,25 @@ + + */ +interface Storage extends \ArrayAccess +{ +} diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/UploadLimitResolver.php b/components/ILIAS/UI/src/Implementation/Component/Input/UploadLimitResolver.php index fe62ac9c977a..45481c63187f 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Input/UploadLimitResolver.php +++ b/components/ILIAS/UI/src/Implementation/Component/Input/UploadLimitResolver.php @@ -20,6 +20,8 @@ namespace ILIAS\UI\Implementation\Component\Input; use ILIAS\UI\Component\Input\Field\UploadHandler; +use ILIAS\UI\Component\Input\Field\PhpUploadLimit; +use ILIAS\UI\Component\Input\Field\GlobalUploadLimit; /** * This class will bee used by @see FileUpload to resolve upload-limits. @@ -39,13 +41,9 @@ */ class UploadLimitResolver { - /** - * @param int $php_upload_limit_in_bytes smaller php-ini option of 'post_max_size' and 'upload_max_filesize' - * @param int|null $custom_global_upload_limit_in_bytes custom upload limit (may exceed $php_upload_limit_in_bytes) - */ public function __construct( - protected int $php_upload_limit_in_bytes, - protected ?int $custom_global_upload_limit_in_bytes = null + protected PhpUploadLimit $php_upload_limit, + protected GlobalUploadLimit $global_upload_limit ) { } @@ -57,18 +55,20 @@ public function getBestPossibleUploadLimitInBytes( return $local_limit_in_bytes; } - if (null !== $this->custom_global_upload_limit_in_bytes && - $this->canUploadLimitBeUsed($upload_handler, $this->custom_global_upload_limit_in_bytes) + $global_upload_limit_in_bytes = $this->global_upload_limit->getGlobalUploadLimitInBytes(); + + if (null !== $global_upload_limit_in_bytes && + $this->canUploadLimitBeUsed($upload_handler, $global_upload_limit_in_bytes) ) { - return $this->custom_global_upload_limit_in_bytes; + return $global_upload_limit_in_bytes; } - return $this->php_upload_limit_in_bytes; + return $this->getPhpUploadLimitInBytes(); } public function getPhpUploadLimitInBytes(): int { - return $this->php_upload_limit_in_bytes; + return $this->php_upload_limit->getPhpUploadLimitInBytes(); } protected function canUploadLimitBeUsed(UploadHandler $upload_handler, ?int $limit_in_bytes): bool @@ -77,6 +77,6 @@ protected function canUploadLimitBeUsed(UploadHandler $upload_handler, ?int $lim return true; } - return $limit_in_bytes <= $this->php_upload_limit_in_bytes; + return $limit_in_bytes <= $this->getPhpUploadLimitInBytes(); } } diff --git a/components/ILIAS/UI/src/Implementation/Component/Progress/DefaultAsyncRefreshInterval.php b/components/ILIAS/UI/src/Implementation/Component/Progress/DefaultAsyncRefreshInterval.php new file mode 100644 index 000000000000..8e1168e03902 --- /dev/null +++ b/components/ILIAS/UI/src/Implementation/Component/Progress/DefaultAsyncRefreshInterval.php @@ -0,0 +1,33 @@ + + */ +class DefaultAsyncRefreshInterval implements AsyncRefreshInterval +{ + public function getRefreshIntervalInMs(): int + { + return 1_000; + } +} diff --git a/components/ILIAS/UI/src/Implementation/DefaultRenderer.php b/components/ILIAS/UI/src/Implementation/DefaultRenderer.php index a6be82241999..d1b5ae9e9bf6 100755 --- a/components/ILIAS/UI/src/Implementation/DefaultRenderer.php +++ b/components/ILIAS/UI/src/Implementation/DefaultRenderer.php @@ -40,6 +40,7 @@ class DefaultRenderer implements Renderer public function __construct( private Render\Loader $component_renderer_loader, private JavaScriptBinding $java_script_binding, + private \ILIAS\Language\Language $language, ) { } @@ -48,6 +49,8 @@ public function __construct( */ public function render($component, ?Renderer $root = null) { + $this->language->loadLanguageModule('ui'); + $root = $root ?? $this; if (is_array($component)) { diff --git a/components/ILIAS/UI/src/Implementation/Render/Template.php b/components/ILIAS/UI/src/Implementation/Render/Template.php index 749adade598a..4512bec84216 100755 --- a/components/ILIAS/UI/src/Implementation/Render/Template.php +++ b/components/ILIAS/UI/src/Implementation/Render/Template.php @@ -52,11 +52,4 @@ public function setVariable(string $name, $value): void; * Get the rendered template or a specific block. */ public function get(string $block = null): string; - - /** - * Add some javascript to be executed on_load of the rendered page. - * TODO: This seems to be no rendering, but a javascript concern. We should - * revise this when introducing patterns for javascript. - */ - public function addOnLoadCode(string $code): void; } diff --git a/components/ILIAS/UI/src/Implementation/Render/ilJavaScriptBinding.php b/components/ILIAS/UI/src/Implementation/Render/ilJavaScriptBinding.php index 1d4fe6c73017..b8f43f553090 100755 --- a/components/ILIAS/UI/src/Implementation/Render/ilJavaScriptBinding.php +++ b/components/ILIAS/UI/src/Implementation/Render/ilJavaScriptBinding.php @@ -20,8 +20,6 @@ namespace ILIAS\UI\Implementation\Render; -use ilGlobalTemplateInterface; - /** * Wraps global ilTemplate to provide JavaScriptBinding. */ @@ -29,16 +27,14 @@ class ilJavaScriptBinding implements JavaScriptBinding { public const PREFIX = "il_ui_fw_"; - private ilGlobalTemplateInterface $global_tpl; - /** * Cache for all registered JS code */ protected array $code = array(); - public function __construct(ilGlobalTemplateInterface $global_tpl) - { - $this->global_tpl = $global_tpl; + public function __construct( + private \ILIAS\UICore\GlobalTemplate $global_tpl, + ) { } /** diff --git a/components/ILIAS/UI/src/Implementation/Render/ilResourceRegistry.php b/components/ILIAS/UI/src/Implementation/Render/ilResourceRegistry.php index 432933c21842..f3d198a66fa1 100755 --- a/components/ILIAS/UI/src/Implementation/Render/ilResourceRegistry.php +++ b/components/ILIAS/UI/src/Implementation/Render/ilResourceRegistry.php @@ -20,7 +20,6 @@ namespace ILIAS\UI\Implementation\Render; -use ilGlobalTemplateInterface; use InvalidArgumentException; /** @@ -29,11 +28,9 @@ */ class ilResourceRegistry implements ResourceRegistry { - protected ilGlobalTemplateInterface $il_template; - - public function __construct(ilGlobalTemplateInterface $il_template) - { - $this->il_template = $il_template; + public function __construct( + protected \ILIAS\UICore\GlobalTemplate $il_template, + ) { } /** diff --git a/components/ILIAS/UI/src/Implementation/Render/ilTemplateWrapper.php b/components/ILIAS/UI/src/Implementation/Render/ilTemplateWrapper.php index 3e28a36379a2..73005b5454ae 100755 --- a/components/ILIAS/UI/src/Implementation/Render/ilTemplateWrapper.php +++ b/components/ILIAS/UI/src/Implementation/Render/ilTemplateWrapper.php @@ -28,13 +28,9 @@ */ class ilTemplateWrapper implements Template { - protected ilGlobalTemplateInterface $global_tpl; - private ilTemplate $tpl; - - final public function __construct(ilGlobalTemplateInterface $global_tpl, ilTemplate $tpl) - { - $this->global_tpl = $global_tpl; - $this->tpl = $tpl; + final public function __construct( + private ilTemplate $tpl, + ) { } /** @@ -79,12 +75,4 @@ public function get(string $block = null): string } return $this->tpl->get($block); } - - /** - * @inheritdocs - */ - public function addOnLoadCode(string $code): void - { - $this->global_tpl->addOnLoadCode($code); - } } diff --git a/components/ILIAS/UI/src/Implementation/Render/ilTemplateWrapperFactory.php b/components/ILIAS/UI/src/Implementation/Render/ilTemplateWrapperFactory.php index b1da81272cc9..00170040f92c 100755 --- a/components/ILIAS/UI/src/Implementation/Render/ilTemplateWrapperFactory.php +++ b/components/ILIAS/UI/src/Implementation/Render/ilTemplateWrapperFactory.php @@ -28,19 +28,12 @@ */ class ilTemplateWrapperFactory implements TemplateFactory { - protected ilGlobalTemplateInterface $global_tpl; - - public function __construct(ilGlobalTemplateInterface $global_tpl) - { - $this->global_tpl = $global_tpl; - } - /** * @inheritdocs */ public function getTemplate(string $path, bool $purge_unfilled_vars, bool $purge_unused_blocks): Template { $tpl = new ilTemplate($path, $purge_unfilled_vars, $purge_unused_blocks); - return new ilTemplateWrapper($this->global_tpl, $tpl); + return new ilTemplateWrapper($tpl); } } diff --git a/components/ILIAS/UI/tests/Base.php b/components/ILIAS/UI/tests/Base.php index 72cd090f4997..e2a04591abeb 100755 --- a/components/ILIAS/UI/tests/Base.php +++ b/components/ILIAS/UI/tests/Base.php @@ -230,6 +230,7 @@ class TestDefaultRenderer extends DefaultRenderer public function __construct( Render\Loader $component_renderer_loader, JavaScriptBinding $java_script_binding, + \ILIAS\Language\Language $language, array $with_stub_renderings = [], protected array $with_additional_contexts = [], ) { @@ -239,7 +240,7 @@ public function __construct( array_walk($this->with_additional_contexts, fn(Component $c) => $this->pushContext($c)); - parent::__construct($component_renderer_loader, $java_script_binding); + parent::__construct($component_renderer_loader, $java_script_binding, $language); } public function _getRendererFor(IComponent $component): Render\ComponentRenderer @@ -467,7 +468,7 @@ public function getDefaultRenderer( ) ) ); - return new TestDefaultRenderer($component_renderer_loader, $js_binding, $with_stub_renderings, $with_additional_contexts); + return new TestDefaultRenderer($component_renderer_loader, $js_binding, $lng, $with_stub_renderings, $with_additional_contexts); } public function getDecoratedRenderer(Renderer $default) diff --git a/components/ILIAS/UI/tests/Component/Input/UploadLimitResolverTest.php b/components/ILIAS/UI/tests/Component/Input/UploadLimitResolverTest.php index 621150ce062a..69a040b55dcb 100755 --- a/components/ILIAS/UI/tests/Component/Input/UploadLimitResolverTest.php +++ b/components/ILIAS/UI/tests/Component/Input/UploadLimitResolverTest.php @@ -22,6 +22,8 @@ use PHPUnit\Framework\TestCase; use ILIAS\UI\Component\Input\Field\UploadHandler; use ILIAS\UI\Implementation\Component\Input\UploadLimitResolver; +use ILIAS\UI\Component\Input\Field\PhpUploadLimit; +use ILIAS\UI\Component\Input\Field\GlobalUploadLimit; /** * @author Thibeau Fuhrer @@ -115,7 +117,10 @@ public function testUploadLimitResolution( bool $upload_handler_supports_chunks, int $expected_result, ): void { - $resolver = new UploadLimitResolver($php_ini_value, $custom_global_value); + $resolver = new UploadLimitResolver( + $this->getPhpUploadLimitMock($php_ini_value), + $this->getGlobalUploadLimitMock($custom_global_value) + ); if ($upload_handler_supports_chunks) { $upload_handler = $this->upload_handler_with_chunks; @@ -127,4 +132,18 @@ public function testUploadLimitResolution( $this->assertEquals($expected_result, $actual_value); } + + protected function getPhpUploadLimitMock(int $upload_limit): PhpUploadLimit + { + $mock = $this->createMock(PhpUploadLimit::class); + $mock->method('getPhpUploadLimitInBytes')->willReturn($upload_limit); + return $mock; + } + + protected function getGlobalUploadLimitMock(?int $upload_limit): GlobalUploadLimit + { + $mock = $this->createMock(GlobalUploadLimit::class); + $mock->method('getGlobalUploadLimitInBytes')->willReturn($upload_limit); + return $mock; + } } diff --git a/components/ILIAS/UI/tests/Examples/ExamplesTest.php b/components/ILIAS/UI/tests/Examples/ExamplesTest.php index bf56f7693838..315a0a97c3fd 100755 --- a/components/ILIAS/UI/tests/Examples/ExamplesTest.php +++ b/components/ILIAS/UI/tests/Examples/ExamplesTest.php @@ -74,6 +74,7 @@ protected function setUpMockDependencies(): void new ILIAS\Data\Factory(), $this->getLanguage() ); + (new InitUIFramework())->init($this->dic); $this->dic["ui.template_factory"] = $this->getTemplateFactory(); diff --git a/components/ILIAS/Init/classes/Dependencies/InitUIFramework.php b/components/ILIAS/UI/tests/InitUIFramework.php similarity index 90% rename from components/ILIAS/Init/classes/Dependencies/InitUIFramework.php rename to components/ILIAS/UI/tests/InitUIFramework.php index b7e4b73a8b44..f632e7a16864 100755 --- a/components/ILIAS/Init/classes/Dependencies/InitUIFramework.php +++ b/components/ILIAS/UI/tests/InitUIFramework.php @@ -16,17 +16,21 @@ * *********************************************************************/ -use ILIAS\Data\Factory; +declare(strict_types=1); /** - * Responsible for loading the UI Framework into the dependency injection container of ILIAS + * This is more or less a copy of the removed InitUIFramework file inside the Init component. + * We keep it here since some unit tests depend on a fully initialised UI framework, which + * is populated in the global DIC using the old offsets. + * + * @deprecated don't use this. we should try to find a better way to perform rendering + * tests that rely on a fully initialised UI framework. */ class InitUIFramework { public function init(\ILIAS\DI\Container $c): void { $c["ui.factory"] = function ($c) { - $c["lng"]->loadLanguageModule("ui"); return new ILIAS\UI\Implementation\Factory( $c["ui.factory.counter"], $c["ui.factory.button"], @@ -61,10 +65,18 @@ public function init(\ILIAS\DI\Container $c): void }; $c["ui.upload_limit_resolver"] = function ($c) { return new \ILIAS\UI\Implementation\Component\Input\UploadLimitResolver( - (int) \ilFileUtils::getPhpUploadSizeLimitInBytes(), - ($c->offsetExists('upload_policy_resolver')) ? - $c['upload_policy_resolver']->getUserUploadSizeLimitInBytes() : - null + new class() implements ILIAS\UI\Component\Input\Field\PhpUploadLimit { + public function getPhpUploadLimitInBytes(): int + { + return 0; + } + }, + new class() implements ILIAS\UI\Component\Input\Field\GlobalUploadLimit { + public function getGlobalUploadLimitInBytes(): ?int + { + return null; + } + }, ); }; $c["ui.data_factory"] = function ($c) { @@ -98,23 +110,23 @@ public function init(\ILIAS\DI\Container $c): void $c["ui.factory.input.field"], ); }; - $c["ui.factory.progress.refresh_interval"] = static fn(\ILIAS\DI\Container $c) => - new class () implements \ILIAS\UI\Component\Progress\AsyncRefreshInterval { - public function getRefreshIntervalInMs(): int - { - return 1_000; - } - }; - $c["ui.factory.progress"] = static fn(\ILIAS\DI\Container $c) => - new \ILIAS\UI\Implementation\Component\Progress\Factory( - $c["ui.factory.progress.refresh_interval"], - $c["ui.signal_generator"], - $c["ui.factory.progress.state"], - ); - $c["ui.factory.progress.state"] = static fn(\ILIAS\DI\Container $c) => - new \ILIAS\UI\Implementation\Component\Progress\State\Factory( - new \ILIAS\UI\Implementation\Component\Progress\State\Bar\Factory(), - ); + $c["ui.factory.progress.refresh_interval"] = static fn (\ILIAS\DI\Container $c) => + new class() implements \ILIAS\UI\Component\Progress\AsyncRefreshInterval { + public function getRefreshIntervalInMs(): int + { + return 1_000; + } + }; + $c["ui.factory.progress"] = static fn (\ILIAS\DI\Container $c) => + new \ILIAS\UI\Implementation\Component\Progress\Factory( + $c["ui.factory.progress.refresh_interval"], + $c["ui.signal_generator"], + $c["ui.factory.progress.state"], + ); + $c["ui.factory.progress.state"] = static fn (\ILIAS\DI\Container $c) => + new \ILIAS\UI\Implementation\Component\Progress\State\Factory( + new \ILIAS\UI\Implementation\Component\Progress\State\Bar\Factory(), + ); $c["ui.factory.dropzone"] = function ($c) { return new ILIAS\UI\Implementation\Component\Dropzone\Factory($c["ui.factory.dropzone.file"]); }; @@ -283,6 +295,7 @@ public function getRefreshIntervalInMs(): int return new ILIAS\UI\Implementation\DefaultRenderer( $c["ui.component_renderer_loader"], $c["ui.javascript_binding"], + $c["lng"], ); }; $c["ui.component_renderer_loader"] = function ($c) { @@ -383,7 +396,7 @@ public function getRefreshIntervalInMs(): int // currently this is will be a session storage because we cannot store // data on the client, see https://mantis.ilias.de/view.php?id=38503. $c["ui.storage"] = function ($c): ArrayAccess { - return new class () implements ArrayAccess { + return new class() implements ArrayAccess { public function offsetExists(mixed $offset): bool { return ilSession::has($offset); diff --git a/components/ILIAS/UI/tests/Renderer/DefaultRendererTest.php b/components/ILIAS/UI/tests/Renderer/DefaultRendererTest.php index c3371decbae1..3f22c44c6050 100755 --- a/components/ILIAS/UI/tests/Renderer/DefaultRendererTest.php +++ b/components/ILIAS/UI/tests/Renderer/DefaultRendererTest.php @@ -98,12 +98,21 @@ static function (TestComponent $component, DefaultRenderer $renderer) use ( } ); - $renderer = new class ($component_renderer) extends DefaultRenderer { + $renderer = new class ( + $this->createMock(Render\Loader::class), + $this->createMock(JavaScriptBinding::class), + $this->createMock(\ILIAS\Language\Language::class), + $component_renderer, + ) extends DefaultRenderer { public array $context_history = []; public function __construct( + Render\Loader $component_renderer_loader, + JavaScriptBinding $java_script_binding, + \ILIAS\Language\Language $language, protected ComponentRenderer $component_renderer ) { + parent::__construct($component_renderer_loader, $java_script_binding, $language); } protected function getRendererFor(Component $component): ComponentRenderer @@ -211,7 +220,7 @@ public function testPassesSelfAsRootIfNoRootExist($render_type) $loader = $this->createMock(Loader::class); $loader->method('getRendererFor')->willReturn($this->component_renderer); - $renderer = new TestDefaultRenderer($loader, $this->getJavaScriptBinding()); + $renderer = new TestDefaultRenderer($loader, $this->getJavaScriptBinding(), $this->getLanguage()); $this->component_renderer->expects($this->once()) ->method("render") @@ -232,7 +241,7 @@ public function testPassesOtherOnAsRoot($render_type) $loader = $this->createMock(Loader::class); $loader->method('getRendererFor')->willReturn($this->component_renderer); - $renderer = new TestDefaultRenderer($loader, $this->getJavaScriptBinding()); + $renderer = new TestDefaultRenderer($loader, $this->getJavaScriptBinding(), $this->getLanguage()); $this->component_renderer->expects($this->once()) ->method("render") diff --git a/components/ILIAS/UI/tests/UITestHelper.php b/components/ILIAS/UI/tests/UITestHelper.php index 7470fd4b991c..9e4dac0c4368 100755 --- a/components/ILIAS/UI/tests/UITestHelper.php +++ b/components/ILIAS/UI/tests/UITestHelper.php @@ -32,51 +32,53 @@ * factory and renderer into some classes to be unit tested. * See UITestHelperTest for an example of how this can be used. */ -class UITestHelper +trait UITestHelper { - protected Container $dic; + protected Container $dic_with_ui; public function init(Container $dic = null): Container { if ($dic) { - $this->dic = $dic; + $this->dic_with_ui = $dic; } else { - $this->dic = new Container(); + $this->dic_with_ui = new Container(); } $tpl_fac = new ilIndependentTemplateFactory(); - $this->dic["tpl"] = $tpl_fac->getTemplate("tpl.main.html", false, false); - $this->dic["lng"] = new LanguageMock(); + $this->dic_with_ui["tpl"] = $tpl_fac->getTemplate("tpl.main.html", false, false); + $this->dic_with_ui["lng"] = new LanguageMock(); $data_factory = new DataFactory(); - $this->dic["refinery"] = new RefinaryFactory($data_factory, $this->dic["lng"]); - (new InitUIFramework())->init($this->dic); - $this->dic["ui.template_factory"] = new ilIndependentTemplateFactory(); - $this->dic["help.text_retriever"] = new ILIAS\UI\Help\TextRetriever\Echoing(); + $this->dic_with_ui["refinery"] = new RefinaryFactory($data_factory, $this->dic_with_ui["lng"]); - return $this->dic; + (new InitUIFramework())->init($this->dic_with_ui); + + $this->dic_with_ui["ui.template_factory"] = new ilIndependentTemplateFactory(); + $this->dic_with_ui["help.text_retriever"] = new ILIAS\UI\Help\TextRetriever\Echoing(); + + return $this->dic_with_ui; } public function factory(): Factory { - if (!isset($this->dic)) { + if (!isset($this->dic_with_ui)) { $this->init(); } - return $this->dic->ui()->factory(); + return $this->dic_with_ui->ui()->factory(); } public function renderer(): Renderer { - if (!isset($this->dic)) { + if (!isset($this->dic_with_ui)) { $this->init(); } - return $this->dic->ui()->renderer(); + return $this->dic_with_ui->ui()->renderer(); } public function mainTemplate(): ilGlobalTemplateInterface { - if (!isset($this->dic)) { + if (!isset($this->dic_with_ui)) { $this->init(); } - return $this->dic->ui()->mainTemplate(); + return $this->dic_with_ui->ui()->mainTemplate(); } } diff --git a/components/ILIAS/UI/tests/UITestHelperTest.php b/components/ILIAS/UI/tests/UITestHelperTest.php deleted file mode 100755 index 88f5d9fe4477..000000000000 --- a/components/ILIAS/UI/tests/UITestHelperTest.php +++ /dev/null @@ -1,57 +0,0 @@ -assertInstanceOf("UITestHelper", new UITestHelper()); - } - - public function testGetFactory(): void - { - $this->assertInstanceOf(Factory::class, (new UITestHelper())->factory()); - } - - public function testGetRenderer(): void - { - $this->assertInstanceOf(Renderer::class, (new UITestHelper())->renderer()); - } - - public function testGetMainTemplate(): void - { - $this->assertInstanceOf(ilIndependentGlobalTemplate::class, (new UITestHelper())->mainTemplate()); - } - - public function testRenderExample(): void - { - $helper = new UITestHelper(); - $c = $helper->factory()->legacy("hello world"); - $this->assertEquals("hello world", $helper->renderer()->render($c)); - } -} diff --git a/components/ILIAS/UICore/UICore.php b/components/ILIAS/UICore/UICore.php index 510ac2e92e0a..d47e6927fd73 100644 --- a/components/ILIAS/UICore/UICore.php +++ b/components/ILIAS/UICore/UICore.php @@ -32,10 +32,13 @@ public function init( array | \ArrayAccess &$pull, array | \ArrayAccess &$internal, ): void { + $define[] = UICore\GlobalTemplate::class; + + $implement[UICore\GlobalTemplate::class] = static fn() => + new UICore\GlobalTemplateLegacyInitialisationAdapter(); + $contribute[\ILIAS\Setup\Agent::class] = fn() => - new \ilUICoreSetupAgent( - $pull[\ILIAS\Refinery\Factory::class] - ); + new \ilUICoreSetupAgent(); /* This library was missing after discussing dependencies for ILIAS 10 $contribute[Component\Resource\PublicAsset::class] = static fn() => diff --git a/components/ILIAS/UICore/interfaces/interface.ilGlobalTemplateInterface.php b/components/ILIAS/UICore/interfaces/interface.ilGlobalTemplateInterface.php index 023cff900ae3..155eaf4f8ef0 100755 --- a/components/ILIAS/UICore/interfaces/interface.ilGlobalTemplateInterface.php +++ b/components/ILIAS/UICore/interfaces/interface.ilGlobalTemplateInterface.php @@ -16,274 +16,13 @@ * *********************************************************************/ +use ILIAS\UICore\GlobalTemplate; + /** * @author Stefan Kesseler * @author Sascha Hofmann * @author Thibeau Fuhrer */ -interface ilGlobalTemplateInterface +interface ilGlobalTemplateInterface extends GlobalTemplate { - public const MESSAGE_TYPE_FAILURE = 'failure'; - public const MESSAGE_TYPE_SUCCESS = "success"; - public const MESSAGE_TYPE_QUESTION = "question"; - public const MESSAGE_TYPE_INFO = "info"; - - /** - * @var array available types for messages. - */ - public const MESSAGE_TYPES = [ - self::MESSAGE_TYPE_FAILURE, - self::MESSAGE_TYPE_INFO, - self::MESSAGE_TYPE_SUCCESS, - self::MESSAGE_TYPE_QUESTION, - ]; - - /** - * @var string default block for several operations. - */ - public const DEFAULT_BLOCK = 'DEFAULT'; - - /** - * Make the template hide the footer. - */ - public function hideFooter(): void; - - /** - * Set a message to be displayed to the user. Please use instead of ilUtil::sendInfo(), - * ilUtil::sendSuccess() and ilUtil::sendFailure(). - */ - public function setOnScreenMessage(string $type, string $a_txt, bool $a_keep = false): void; - - /** - * Add a javascript file that should be included in the header. - */ - public function addJavaScript(string $a_js_file, bool $a_add_version_parameter = true, int $a_batch = 2): void; - - /** - * Add on load code - */ - public function addOnLoadCode(string $a_code, int $a_batch = 2): void; - - /** - * Get js onload code for ajax calls - */ - public function getOnLoadCodeForAsynch(): string; - - /** - * Reset javascript files - */ - public function resetJavascript(): void; - - /** - * Probably adds javascript files. - */ - public function fillJavaScriptFiles(bool $a_force = false): void; - - /** - * Add a css file that should be included in the header. - */ - public function addCss(string $a_css_file, string $media = "screen"): void; - - /** - * Add a css file that should be included in the header. - */ - public function addInlineCss(string $a_css, string $media = "screen"): void; - - /** - * Sets the body-tags class. - */ - public function setBodyClass(string $a_class = ""): void; - - /** - * This loads the standard template "tpl.adm_content.html" and - * "tpl.statusline.html" the CONTENT and STATUSLINE placeholders - * if they are not already loaded. - */ - public function loadStandardTemplate(): void; - - /** - * Sets title in standard template. - * Will override the header_page_title. - */ - public function setTitle(string $a_title, bool $hidden = false): void; - - /** - * Sets description below title in standard template. - */ - public function setDescription(string $a_descr): void; - - /** - * set title icon - */ - public function setTitleIcon(string $a_icon_path, string $a_icon_desc = ""): void; - - /** - * Set alert properties - * @param array $alerts - */ - public function setAlertProperties(array $alerts): void; - - /** - * Clear header - */ - public function clearHeader(): void; - - /** - * Set header action menu - */ - public function setHeaderActionMenu(string $a_header): void; - - /** - * Sets the title of the page (for browser window). - */ - public function setHeaderPageTitle(string $a_title): void; - - /** - * Insert locator. - */ - public function setLocator(): void; - - /** - * sets tabs in standard template - */ - public function setTabs(string $a_tabs_html): void; - - /** - * sets subtabs in standard template - */ - public function setSubTabs(string $a_tabs_html): void; - - /** - * Sets content for standard template. - */ - public function setContent(string $a_html): void; - - /** - * Sets content of left column. - */ - public function setLeftContent(string $a_html): void; - - /** - * Sets content of left navigation column. - */ - public function setLeftNavContent(string $a_content): void; - - /** - * Sets content of right column. - */ - public function setRightContent(string $a_html): void; - - /** - * Sets the pages form action. - */ - public function setPageFormAction(string $a_action): void; - - /** - * Set target parameter for login (public sector). - * This is used by the main menu - */ - public function setLoginTargetPar(string $a_val): void; - - /** - * Renders the page with specific elements enabled. - */ - public function getSpecial( - string $part = self::DEFAULT_BLOCK, - bool $add_error_mess = false, - bool $handle_referer = false, - bool $add_ilias_footer = false, - bool $add_standard_elements = false, - bool $a_main_menu = true, - bool $a_tabs = true - ): string; - - /** - * @param bool $has_tabs if template variable {TABS} should be filled with content of ilTabs - * @param bool $skip_main_menu if the main menu should be rendered. - */ - public function printToStdout( - string $part = self::DEFAULT_BLOCK, - bool $has_tabs = true, - bool $skip_main_menu = false - ): void; - - /** - * Use this method to get the finally rendered page as string - */ - public function printToString(): string; - - /** - * Sets a tree or flat icon. - * @param string $a_mode ("tree" | "flat") - */ - public function setTreeFlatIcon(string $a_link, string $a_mode): void; - - /** - * Add admin panel commands as toolbar - * @param bool $is_bottom_panel if the panel should be rendered at the bottom of the page as well. - * @param bool $has_arrow if the panel should be rendered with an arrow icon. - */ - public function addAdminPanelToolbar( - ilToolbarGUI $toolbar, - bool $is_bottom_panel = true, - bool $has_arrow = false - ): void; - - /** - * Generates and sets a permanent ilias link. - */ - public function setPermanentLink( - string $a_type, - ?int $a_id, - string $a_append = "", - string $a_target = "", - string $a_title = "" - ): void; - - /** - * Reset all header properties: title, icon, description, alerts, action menu - */ - public function resetHeaderBlock(bool $a_reset_header_action = true): void; - - /** - * Enables the file upload into this object by dropping a file. - */ - public function setFileUploadRefId(int $a_ref_id): void; - - /** - * Renders the given block and returns the html string. - */ - public function get(string $part = self::DEFAULT_BLOCK): string; - - /** - * Sets the given variable to the given value. - * @param mixed $value - */ - public function setVariable(string $variable, $value = ''): void; - - /** - * Sets the template to the given block. - */ - public function setCurrentBlock(string $part = self::DEFAULT_BLOCK): bool; - - /** - * Parses the given block. - */ - public function parseCurrentBlock(string $block_name = self::DEFAULT_BLOCK): bool; - - /** - * overwrites ITX::touchBlock. - */ - public function touchBlock(string $block): bool; - - /** - * overwrites ITX::addBlockFile - */ - public function addBlockFile(string $var, string $block, string $template_name, string $in_module = null): bool; - - /** - * check if block exists in actual template - * @param string $block_name - */ - public function blockExists(string $block_name): bool; } diff --git a/components/ILIAS/UICore/src/GlobalTemplate.php b/components/ILIAS/UICore/src/GlobalTemplate.php new file mode 100644 index 000000000000..7285a1a619bd --- /dev/null +++ b/components/ILIAS/UICore/src/GlobalTemplate.php @@ -0,0 +1,290 @@ + + */ +interface GlobalTemplate +{ + public const MESSAGE_TYPE_FAILURE = 'failure'; + public const MESSAGE_TYPE_SUCCESS = "success"; + public const MESSAGE_TYPE_QUESTION = "question"; + public const MESSAGE_TYPE_INFO = "info"; + + /** + * @var array available types for messages. + */ + public const MESSAGE_TYPES = [ + self::MESSAGE_TYPE_FAILURE, + self::MESSAGE_TYPE_INFO, + self::MESSAGE_TYPE_SUCCESS, + self::MESSAGE_TYPE_QUESTION, + ]; + + /** + * @var string default block for several operations. + */ + public const DEFAULT_BLOCK = 'DEFAULT'; + + /** + * Make the template hide the footer. + */ + public function hideFooter(): void; + + /** + * Set a message to be displayed to the user. Please use instead of ilUtil::sendInfo(), + * ilUtil::sendSuccess() and ilUtil::sendFailure(). + */ + public function setOnScreenMessage(string $type, string $a_txt, bool $a_keep = false): void; + + /** + * Add a javascript file that should be included in the header. + */ + public function addJavaScript(string $a_js_file, bool $a_add_version_parameter = true, int $a_batch = 2): void; + + /** + * Add on load code + */ + public function addOnLoadCode(string $a_code, int $a_batch = 2): void; + + /** + * Get js onload code for ajax calls + */ + public function getOnLoadCodeForAsynch(): string; + + /** + * Reset javascript files + */ + public function resetJavascript(): void; + + /** + * Probably adds javascript files. + */ + public function fillJavaScriptFiles(bool $a_force = false): void; + + /** + * Add a css file that should be included in the header. + */ + public function addCss(string $a_css_file, string $media = "screen"): void; + + /** + * Add a css file that should be included in the header. + */ + public function addInlineCss(string $a_css, string $media = "screen"): void; + + /** + * Sets the body-tags class. + */ + public function setBodyClass(string $a_class = ""): void; + + /** + * This loads the standard template "tpl.adm_content.html" and + * "tpl.statusline.html" the CONTENT and STATUSLINE placeholders + * if they are not already loaded. + */ + public function loadStandardTemplate(): void; + + /** + * Sets title in standard template. + * Will override the header_page_title. + */ + public function setTitle(string $a_title, bool $hidden = false): void; + + /** + * Sets description below title in standard template. + */ + public function setDescription(string $a_descr): void; + + /** + * set title icon + */ + public function setTitleIcon(string $a_icon_path, string $a_icon_desc = ""): void; + + /** + * Set alert properties + * @param array $alerts + */ + public function setAlertProperties(array $alerts): void; + + /** + * Clear header + */ + public function clearHeader(): void; + + /** + * Set header action menu + */ + public function setHeaderActionMenu(string $a_header): void; + + /** + * Sets the title of the page (for browser window). + */ + public function setHeaderPageTitle(string $a_title): void; + + /** + * Insert locator. + */ + public function setLocator(): void; + + /** + * sets tabs in standard template + */ + public function setTabs(string $a_tabs_html): void; + + /** + * sets subtabs in standard template + */ + public function setSubTabs(string $a_tabs_html): void; + + /** + * Sets content for standard template. + */ + public function setContent(string $a_html): void; + + /** + * Sets content of left column. + */ + public function setLeftContent(string $a_html): void; + + /** + * Sets content of left navigation column. + */ + public function setLeftNavContent(string $a_content): void; + + /** + * Sets content of right column. + */ + public function setRightContent(string $a_html): void; + + /** + * Sets the pages form action. + */ + public function setPageFormAction(string $a_action): void; + + /** + * Set target parameter for login (public sector). + * This is used by the main menu + */ + public function setLoginTargetPar(string $a_val): void; + + /** + * Renders the page with specific elements enabled. + */ + public function getSpecial( + string $part = self::DEFAULT_BLOCK, + bool $add_error_mess = false, + bool $handle_referer = false, + bool $add_ilias_footer = false, + bool $add_standard_elements = false, + bool $a_main_menu = true, + bool $a_tabs = true + ): string; + + /** + * @param bool $has_tabs if template variable {TABS} should be filled with content of ilTabs + * @param bool $skip_main_menu if the main menu should be rendered. + */ + public function printToStdout( + string $part = self::DEFAULT_BLOCK, + bool $has_tabs = true, + bool $skip_main_menu = false + ): void; + + /** + * Use this method to get the finally rendered page as string + */ + public function printToString(): string; + + /** + * Sets a tree or flat icon. + * @param string $a_mode ("tree" | "flat") + */ + public function setTreeFlatIcon(string $a_link, string $a_mode): void; + + /** + * Add admin panel commands as toolbar + * @param bool $is_bottom_panel if the panel should be rendered at the bottom of the page as well. + * @param bool $has_arrow if the panel should be rendered with an arrow icon. + */ + public function addAdminPanelToolbar( + \ilToolbarGUI $toolbar, + bool $is_bottom_panel = true, + bool $has_arrow = false + ): void; + + /** + * Generates and sets a permanent ilias link. + */ + public function setPermanentLink( + string $a_type, + ?int $a_id, + string $a_append = "", + string $a_target = "", + string $a_title = "" + ): void; + + /** + * Reset all header properties: title, icon, description, alerts, action menu + */ + public function resetHeaderBlock(bool $a_reset_header_action = true): void; + + /** + * Enables the file upload into this object by dropping a file. + */ + public function setFileUploadRefId(int $a_ref_id): void; + + /** + * Renders the given block and returns the html string. + */ + public function get(string $part = self::DEFAULT_BLOCK): string; + + /** + * Sets the given variable to the given value. + * @param mixed $value + */ + public function setVariable(string $variable, $value = ''): void; + + /** + * Sets the template to the given block. + */ + public function setCurrentBlock(string $part = self::DEFAULT_BLOCK): bool; + + /** + * Parses the given block. + */ + public function parseCurrentBlock(string $block_name = self::DEFAULT_BLOCK): bool; + + /** + * overwrites ITX::touchBlock. + */ + public function touchBlock(string $block): bool; + + /** + * overwrites ITX::addBlockFile + */ + public function addBlockFile(string $var, string $block, string $template_name, string $in_module = null): bool; + + /** + * check if block exists in actual template + * @param string $block_name + */ + public function blockExists(string $block_name): bool; +} diff --git a/components/ILIAS/UICore/src/GlobalTemplateLegacyInitialisationAdapter.php b/components/ILIAS/UICore/src/GlobalTemplateLegacyInitialisationAdapter.php new file mode 100644 index 000000000000..1c386b3ba050 --- /dev/null +++ b/components/ILIAS/UICore/src/GlobalTemplateLegacyInitialisationAdapter.php @@ -0,0 +1,253 @@ +getLegacyGlobalTemplateInstance()->hideFooter(); + } + + public function setOnScreenMessage(string $type, string $a_txt, bool $a_keep = false): void + { + $this->getLegacyGlobalTemplateInstance()->setOnScreenMessage($type, $a_txt, $a_keep); + } + + public function addJavaScript(string $a_js_file, bool $a_add_version_parameter = true, int $a_batch = 2): void + { + $this->getLegacyGlobalTemplateInstance()->addJavaScript($a_js_file, $a_add_version_parameter, $a_batch); + } + + public function addOnLoadCode(string $a_code, int $a_batch = 2): void + { + $this->getLegacyGlobalTemplateInstance()->addOnLoadCode($a_code, $a_batch); + } + + public function getOnLoadCodeForAsynch(): string + { + return $this->getLegacyGlobalTemplateInstance()->getOnLoadCodeForAsynch(); + } + + public function resetJavascript(): void + { + $this->getLegacyGlobalTemplateInstance()->resetJavascript(); + } + + public function fillJavaScriptFiles(bool $a_force = false): void + { + $this->getLegacyGlobalTemplateInstance()->fillJavaScriptFiles($a_force); + } + + public function addCss(string $a_css_file, string $media = "screen"): void + { + $this->getLegacyGlobalTemplateInstance()->addCss($a_css_file, $media); + } + + public function addInlineCss(string $a_css, string $media = "screen"): void + { + $this->getLegacyGlobalTemplateInstance()->addInlineCss($a_css, $media); + } + + public function setBodyClass(string $a_class = ""): void + { + $this->getLegacyGlobalTemplateInstance()->setBodyClass($a_class); + } + + public function loadStandardTemplate(): void + { + $this->getLegacyGlobalTemplateInstance()->loadStandardTemplate(); + } + + public function setTitle(string $a_title, bool $hidden = false): void + { + $this->getLegacyGlobalTemplateInstance()->setTitle($a_title, $hidden); + } + + public function setDescription(string $a_descr): void + { + $this->getLegacyGlobalTemplateInstance()->setDescription($a_descr); + } + + public function setTitleIcon(string $a_icon_path, string $a_icon_desc = ""): void + { + $this->getLegacyGlobalTemplateInstance()->setTitleIcon($a_icon_path, $a_icon_desc); + } + + public function setAlertProperties(array $alerts): void + { + $this->getLegacyGlobalTemplateInstance()->setAlertProperties($alerts); + } + + public function clearHeader(): void + { + $this->getLegacyGlobalTemplateInstance()->clearHeader(); + } + + public function setHeaderActionMenu(string $a_header): void + { + $this->getLegacyGlobalTemplateInstance()->setHeaderActionMenu($a_header); + } + + public function setHeaderPageTitle(string $a_title): void + { + $this->getLegacyGlobalTemplateInstance()->setHeaderPageTitle($a_title); + } + + public function setLocator(): void + { + $this->getLegacyGlobalTemplateInstance()->setLocator(); + } + + public function setTabs(string $a_tabs_html): void + { + $this->getLegacyGlobalTemplateInstance()->setTabs($a_tabs_html); + } + + public function setSubTabs(string $a_tabs_html): void + { + $this->getLegacyGlobalTemplateInstance()->setSubTabs($a_tabs_html); + } + + public function setContent(string $a_html): void + { + $this->getLegacyGlobalTemplateInstance()->setContent($a_html); + } + + public function setLeftContent(string $a_html): void + { + $this->getLegacyGlobalTemplateInstance()->setLeftContent($a_html); + } + + public function setLeftNavContent(string $a_content): void + { + $this->getLegacyGlobalTemplateInstance()->setLeftNavContent($a_content); + } + + public function setRightContent(string $a_html): void + { + $this->getLegacyGlobalTemplateInstance()->setRightContent($a_html); + } + + public function setPageFormAction(string $a_action): void + { + $this->getLegacyGlobalTemplateInstance()->setPageFormAction($a_action); + } + + public function setLoginTargetPar(string $a_val): void + { + $this->getLegacyGlobalTemplateInstance()->setLoginTargetPar($a_val); + } + + public function getSpecial( + string $part = self::DEFAULT_BLOCK, + bool $add_error_mess = false, + bool $handle_referer = false, + bool $add_ilias_footer = false, + bool $add_standard_elements = false, + bool $a_main_menu = true, + bool $a_tabs = true + ): string { + return $this->getLegacyGlobalTemplateInstance()->getSpecial( + $part, + $add_error_mess, + $handle_referer, + $add_ilias_footer, + $add_standard_elements, + $a_main_menu, + $a_tabs + ); + } + + public function printToStdout( + string $part = self::DEFAULT_BLOCK, + bool $has_tabs = true, + bool $skip_main_menu = false + ): void { + $this->getLegacyGlobalTemplateInstance()->printToStdout($part, $has_tabs, $skip_main_menu); + } + + public function printToString(): string + { + return $this->getLegacyGlobalTemplateInstance()->printToString(); + } + + public function setTreeFlatIcon(string $a_link, string $a_mode): void + { + $this->getLegacyGlobalTemplateInstance()->setTreeFlatIcon($a_link, $a_mode); + } + + public function addAdminPanelToolbar( + ilToolbarGUI $toolbar, + bool $is_bottom_panel = true, + bool $has_arrow = false + ): void { + $this->getLegacyGlobalTemplateInstance()->addAdminPanelToolbar($toolbar, $is_bottom_panel, $has_arrow); + } + + public function setPermanentLink( + string $a_type, + ?int $a_id, + string $a_append = "", + string $a_target = "", + string $a_title = "" + ): void { + $this->getLegacyGlobalTemplateInstance()->setPermanentLink($a_type, $a_id, $a_append, $a_target, $a_title); + } + + public function resetHeaderBlock(bool $a_reset_header_action = true): void + { + $this->getLegacyGlobalTemplateInstance()->resetHeaderBlock($a_reset_header_action); + } + + public function setFileUploadRefId(int $a_ref_id): void + { + $this->getLegacyGlobalTemplateInstance()->setFileUploadRefId($a_ref_id); + } + + public function get(string $part = self::DEFAULT_BLOCK): string + { + return $this->getLegacyGlobalTemplateInstance()->get($part); + } + + public function setVariable(string $variable, $value = ''): void + { + $this->getLegacyGlobalTemplateInstance()->setVariable($variable, $value); + } + + public function setCurrentBlock(string $part = self::DEFAULT_BLOCK): bool + { + return $this->getLegacyGlobalTemplateInstance()->setCurrentBlock($part); + } + + public function parseCurrentBlock(string $block_name = self::DEFAULT_BLOCK): bool + { + return $this->getLegacyGlobalTemplateInstance()->parseCurrentBlock($block_name); + } + + public function touchBlock(string $block): bool + { + return $this->getLegacyGlobalTemplateInstance()->touchBlock($block); + } + + public function addBlockFile(string $var, string $block, string $template_name, string $in_module = null): bool + { + return $this->getLegacyGlobalTemplateInstance()->addBlockFile($var, $block, $template_name, $in_module); + } + + public function blockExists(string $block_name): bool + { + return $this->getLegacyGlobalTemplateInstance()->blockExists($block_name); + } + + protected function getLegacyGlobalTemplateInstance(): GlobalTemplate + { + global $DIC; + return $DIC->ui()->mainTemplate(); + } +} diff --git a/composer.json b/composer.json index 9112ed48c968..7d5d753fb49f 100755 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "scripts": { "post-autoload-dump": [ "@php cli/build_bootstrap.php components/ILIAS/Setup/resources/dependency_resolution.php setup", + "@php cli/build_bootstrap.php components/ILIAS/Init/resources/dependency_resolution.php default", "@php cli/setup.php build --yes" ], "pre-install-cmd": [