From cfe50bcf0e3cfa4c840dd1e9ad0181fe66debb50 Mon Sep 17 00:00:00 2001 From: Alex Killing Date: Tue, 30 Jul 2024 16:51:22 +0200 Subject: [PATCH 01/61] 41826: On saving a table, the content of some cells is duplicated --- Services/COPage/PC/Blog/class.ilPCBlog.php | 4 +--- Services/COPage/PC/Plugged/class.ilPCPlugged.php | 12 ++++++------ .../PC/Table/class.TableCommandActionHandler.php | 1 - Services/COPage/PC/Table/class.ilPCDataTable.php | 8 ++------ Services/COPage/PC/Table/class.ilPCTable.php | 8 ++------ Services/COPage/PC/Table/class.ilPCTableData.php | 8 ++------ 6 files changed, 13 insertions(+), 28 deletions(-) diff --git a/Services/COPage/PC/Blog/class.ilPCBlog.php b/Services/COPage/PC/Blog/class.ilPCBlog.php index dedac6941107..6bcdeea9c235 100644 --- a/Services/COPage/PC/Blog/class.ilPCBlog.php +++ b/Services/COPage/PC/Blog/class.ilPCBlog.php @@ -59,9 +59,7 @@ public function setData( // remove all children first $children = $this->getChildNode()->childNodes; if ($children) { - foreach ($children as $child) { - $this->getChildNode()->removeChild($child); - } + $this->dom_util->deleteAllChilds($this->getChildNode()); } if (count($a_posting_ids)) { diff --git a/Services/COPage/PC/Plugged/class.ilPCPlugged.php b/Services/COPage/PC/Plugged/class.ilPCPlugged.php index 12013df4b3d6..0333866ffc70 100755 --- a/Services/COPage/PC/Plugged/class.ilPCPlugged.php +++ b/Services/COPage/PC/Plugged/class.ilPCPlugged.php @@ -162,6 +162,7 @@ public static function handleCopiedPluggedContent( DOMDocument $a_domdoc ): void { global $DIC; + $dom_util = $DIC->copage()->internal()->domain()->domUtil(); $component_repository = $DIC['component.repository']; $component_factory = $DIC['component.factory']; @@ -187,9 +188,7 @@ public static function handleCopiedPluggedContent( // and allow it to modify the saved parameters $plugin_obj->onClone($properties, $plugin_version); - foreach ($node->childNodes as $child) { - $node->removeChild($child); - } + $dom_util->deleteAllChilds($node); foreach ($properties as $name => $value) { $child = new DOMElement( 'PluggedProperty', @@ -208,6 +207,9 @@ public static function handleCopiedPluggedContent( public static function afterRepositoryCopy(ilPageObject $page, array $mapping, int $source_ref_id): void { global $DIC; + + $dom_util = $DIC->copage()->internal()->domain()->domUtil(); + $ilPluginAdmin = $DIC['ilPluginAdmin']; /** @var ilComponentFactory $component_factory */ @@ -238,9 +240,7 @@ public static function afterRepositoryCopy(ilPageObject $page, array $mapping, i // and allow it to modify the saved parameters $plugin_obj->afterRepositoryCopy($properties, $mapping, $source_ref_id, $plugin_version); - foreach ($node->childNodes as $child) { - $node->removeChild($child); - } + $dom_util->deleteAllChilds($node); foreach ($properties as $name => $value) { $child = new DOMElement( 'PluggedProperty', diff --git a/Services/COPage/PC/Table/class.TableCommandActionHandler.php b/Services/COPage/PC/Table/class.TableCommandActionHandler.php index ec2b94a6e108..626e73f3c9ae 100644 --- a/Services/COPage/PC/Table/class.TableCommandActionHandler.php +++ b/Services/COPage/PC/Table/class.TableCommandActionHandler.php @@ -223,7 +223,6 @@ protected function updateData( $updated = (!is_null($text)); $text = $text["text"]; } - if ($updated) { $text = \ilPCParagraph::_input2xml( $text, diff --git a/Services/COPage/PC/Table/class.ilPCDataTable.php b/Services/COPage/PC/Table/class.ilPCDataTable.php index f33150f46de4..9d4080d8825e 100755 --- a/Services/COPage/PC/Table/class.ilPCDataTable.php +++ b/Services/COPage/PC/Table/class.ilPCDataTable.php @@ -50,9 +50,7 @@ public function create( public function makeEmptyCell(DomNode $td_node): void { // delete children of paragraph node - foreach ($td_node->childNodes as $child) { - $td_node->removeChild($child); - } + $this->dom_util->deleteAllChilds($td_node); // create page content and paragraph node here. $pc_node = $this->getNewPageContentNode(); @@ -86,9 +84,7 @@ public function setData(array $a_data) // remove all childs if (empty($error) && !is_null($par_node)) { // delete children of paragraph node - foreach ($par_node->childNodes as $child) { - $par_node->removeChild($child); - } + $this->dom_util->deleteAllChilds($par_node); // copy new content children in paragraph node $nodes = $this->dom_util->path( diff --git a/Services/COPage/PC/Table/class.ilPCTable.php b/Services/COPage/PC/Table/class.ilPCTable.php index 1f1ed0d7faa4..e5eacfb6fdbc 100755 --- a/Services/COPage/PC/Table/class.ilPCTable.php +++ b/Services/COPage/PC/Table/class.ilPCTable.php @@ -109,9 +109,7 @@ public function getCellNode(int $i, int $j, bool $create_if_not_exists = false): if (!is_null($td_node)) { // delete children of paragraph node - foreach ($td_node->childNodes as $child) { - $td_node->removeChild($child); - } + $this->dom_util->deleteAllChilds($td_node); // create page content and paragraph node here. $pc_node = $this->getNewPageContentNode(); @@ -409,9 +407,7 @@ public function fixHideAndSpans(): void public function makeEmptyCell(DomNode $td_node): void { // delete children of paragraph node - foreach ($td_node->childNodes as $child) { - $td_node->removeChild($child); - } + $this->dom_util->deleteAllChilds($td_node); } /** diff --git a/Services/COPage/PC/Table/class.ilPCTableData.php b/Services/COPage/PC/Table/class.ilPCTableData.php index e2558f060092..d48119252aa7 100755 --- a/Services/COPage/PC/Table/class.ilPCTableData.php +++ b/Services/COPage/PC/Table/class.ilPCTableData.php @@ -85,9 +85,7 @@ public function deleteRowContent( if ($td->hasAttribute("PCID")) { $td->removeAttribute("PCID"); } - foreach ($td->childNodes as $c) { - $td->removeChild($c); - } + $this->dom_util->deleteAllChilds($td); } } @@ -97,9 +95,7 @@ public function deleteRowContent( public function deleteTDContent( DOMNode $a_td_node ): void { - foreach ($a_td_node->childNodes as $child) { - $a_td_node->removeChild($child); - } + $this->dom_util->deleteAllChilds($a_td_node); } public function deleteRow(): void From 908de7aacb0a6d1c1152e65065cb59620fc71c20 Mon Sep 17 00:00:00 2001 From: Alexander Killing Date: Wed, 31 Jul 2024 08:28:02 +0200 Subject: [PATCH 02/61] added br on questions and multilinguality --- Modules/LearningModule/README.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Modules/LearningModule/README.md b/Modules/LearningModule/README.md index f5e21573dabd..6c5d6d29f6cd 100644 --- a/Modules/LearningModule/README.md +++ b/Modules/LearningModule/README.md @@ -1,21 +1,26 @@ # Learning Modules -## Business Rules - -### Copy Process +## Copy Process - When pages, chapters or learning modules are copied, the media objects are re-used. This means that all instances will refer to the same shared object. This prevents large media files from to filling up disk space quickly. - Questions will be not shared when pages are copied. Every page copy will get separate copies of a question. -### Reading Time +## Reading Time - The estimated reading time is language independent and always derived from the master language. (https://docu.ilias.de/goto_docu_wiki_wpage_6586_1357.html) -### Auto-Linked Glossaries +## Auto-Linked Glossaries - If glossaries are linked to a learning module, internal links to found terms in the glossary will be created during text editing automatically when text is saved. This can be triggered for the whole content, when linking the glossary to the learning module. Once the links are created they are part of the content like manual created links. Removing a glossary from the auto-link list will not delete the links to the glossary terms in the content. -### Print View +## Print View - Print view selection uses a modal, see https://docu.ilias.de/goto_docu_wiki_wpage_5907_1357.html -- The print view opens in a separate tab, see https://mantis.ilias.de/view.php?id=20653 \ No newline at end of file +- The print view opens in a separate tab, see https://mantis.ilias.de/view.php?id=20653 + +## Multilinguality and Questions + +Avoid mixing these two concepts. The outcome will be most probably not what you desire. + +The learning module component re-uses question from the T&A component. These questions do not support multilinguality yet. This means that using questions on multi-lingual pages are always completely separated instances. The question on the german page "does not know" that it is a copy of the version on the english page. Additionally there is nothing like a language-dependent learning progress in ILIAS. So activating the learning progress based on questions or navigation restrictions will also not work as expected in a multi-lingual learning module. + From 493423c86267fc8c58baf28c0b5cf200cf9c79ce Mon Sep 17 00:00:00 2001 From: Ilja Lukin Date: Thu, 4 Jul 2024 14:10:27 +0200 Subject: [PATCH 03/61] Fix: Missing Radio Buttons in ECS Course Allocation https://mantis.ilias.de/view.php?id=41657 --- .../classes/Mapping/class.ilECSMappingSettingsGUI.php | 2 +- .../Mapping/class.ilECSNodeMappingLocalExplorer.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Services/WebServices/ECS/classes/Mapping/class.ilECSMappingSettingsGUI.php b/Services/WebServices/ECS/classes/Mapping/class.ilECSMappingSettingsGUI.php index 0ac40765932a..6ce1f7de6042 100644 --- a/Services/WebServices/ECS/classes/Mapping/class.ilECSMappingSettingsGUI.php +++ b/Services/WebServices/ECS/classes/Mapping/class.ilECSMappingSettingsGUI.php @@ -225,7 +225,7 @@ protected function cShowLocalExplorer(): \ilECSNodeMappingLocalExplorer $explorer->setPostVar('lnodes[]'); $lnodes = (array) $_REQUEST['lnodes']; - $checked_node = array_pop($lnodes); + $checked_node = (int) array_pop($lnodes); if ((int) $_REQUEST['lid']) { $checked_node = (int) $_REQUEST['lid']; } diff --git a/Services/WebServices/ECS/classes/Mapping/class.ilECSNodeMappingLocalExplorer.php b/Services/WebServices/ECS/classes/Mapping/class.ilECSNodeMappingLocalExplorer.php index 27ab61b6b0c3..1f3173176f1a 100644 --- a/Services/WebServices/ECS/classes/Mapping/class.ilECSNodeMappingLocalExplorer.php +++ b/Services/WebServices/ECS/classes/Mapping/class.ilECSNodeMappingLocalExplorer.php @@ -123,7 +123,7 @@ public function getPostVar(): string return $this->post_var; } - public function buildFormItem($a_node_id, int $a_type): string + public function buildFormItem($a_node_id, string $a_type): string { if (!array_key_exists($a_type, $this->form_items) || !$this->form_items[$a_type]) { return ''; @@ -134,13 +134,13 @@ public function buildFormItem($a_node_id, int $a_type): string return ilLegacyFormElementsUtil::formCheckbox( $this->isItemChecked($a_node_id), $this->post_var, - $a_node_id + (string) $a_node_id ); case self::SEL_TYPE_RADIO: return ilLegacyFormElementsUtil::formRadioButton( $this->isItemChecked($a_node_id), $this->post_var, - $a_node_id, + (string) $a_node_id, "document.getElementById('map').submit(); return false;" ); } @@ -201,7 +201,7 @@ public function formatObject(ilTemplate $tpl, $a_node_id, array $a_option, $a_ob $tpl->parseCurrentBlock(); } - if ($formItem = ($this->buildFormItem((int) $a_node_id, (int) $a_option['type']) !== '')) { + if (($formItem = $this->buildFormItem((int) $a_node_id, (string) $a_option['type'])) !== '') { $tpl->setCurrentBlock('check'); $tpl->setVariable('OBJ_CHECK', $formItem); $tpl->parseCurrentBlock(); @@ -285,7 +285,7 @@ public function formatHeader(ilTemplate $tpl, $a_obj_id, array $a_option): void $tpl->setVariable("TXT_ALT_IMG", $title); $tpl->parseCurrentBlock(); - if (($formItem = $this->buildFormItem((int) $a_obj_id, (int) $a_option['type'])) !== '') { + if (($formItem = $this->buildFormItem((int) $a_obj_id, (string) $a_option['type'])) !== '') { $tpl->setCurrentBlock('check'); $tpl->setVariable('OBJ_CHECK', $formItem); $tpl->parseCurrentBlock(); From f926b2b353b5ff1efa610bad74f4a365e00843ee Mon Sep 17 00:00:00 2001 From: mjansen Date: Wed, 5 Jun 2024 08:42:11 +0200 Subject: [PATCH 04/61] LDAP: Increase length of password fields See: https://mantis.ilias.de/view.php?id=31280 --- .../Setup/LDAPBindPasswordFieldMigration.php | 62 +++++++++++++++++ .../LDAP/classes/Setup/LDAPSetupAgent.php | 69 +++++++++++++++++++ .../LDAP/classes/class.ilLDAPSettingsGUI.php | 4 +- 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 Services/LDAP/classes/Setup/LDAPBindPasswordFieldMigration.php create mode 100644 Services/LDAP/classes/Setup/LDAPSetupAgent.php diff --git a/Services/LDAP/classes/Setup/LDAPBindPasswordFieldMigration.php b/Services/LDAP/classes/Setup/LDAPBindPasswordFieldMigration.php new file mode 100644 index 000000000000..ba6e9e73ae18 --- /dev/null +++ b/Services/LDAP/classes/Setup/LDAPBindPasswordFieldMigration.php @@ -0,0 +1,62 @@ +db = $db; + } + + public function step_1(): void + { + if ($this->db->tableColumnExists('ldap_server_settings', 'bind_pass')) { + $this->db->modifyTableColumn( + 'ldap_server_settings', + 'bind_pass', + [ + 'type' => 'text', + 'length' => 100, + 'notnull' => false, + 'default' => null + ] + ); + } + if ($this->db->tableColumnExists('ldap_server_settings', 'role_bind_pass')) { + $this->db->modifyTableColumn( + 'ldap_server_settings', + 'role_bind_pass', + [ + 'type' => 'text', + 'length' => 100, + 'notnull' => false, + 'default' => null + ] + ); + } + } +} diff --git a/Services/LDAP/classes/Setup/LDAPSetupAgent.php b/Services/LDAP/classes/Setup/LDAPSetupAgent.php new file mode 100644 index 000000000000..2c2c16f3497b --- /dev/null +++ b/Services/LDAP/classes/Setup/LDAPSetupAgent.php @@ -0,0 +1,69 @@ +lng->txt('ldap_server_bind_pass'), 'bind_pass'); $pass->setSkipSyntaxCheck(true); $pass->setSize(12); - $pass->setMaxLength(36); + $pass->setMaxLength(100); $user->addSubItem($pass); $binding->addOption($user); $this->form_gui->addItem($binding); @@ -1369,7 +1369,7 @@ public function roleMapping(): void $pass->setPostVar("role_bind_pass"); $pass->setValue($this->server->getRoleBindPassword()); $pass->setSize(12); - $pass->setMaxLength(36); + $pass->setMaxLength(100); $pass->setRetype(false); $binding->addCombinationItem("1", $pass, $this->lng->txt('ldap_role_bind_pass')); From cd815e9854157586e7126a0e9fd3215a3b2d880a Mon Sep 17 00:00:00 2001 From: Stephan Kergomard Date: Thu, 1 Aug 2024 14:49:39 +0200 Subject: [PATCH 05/61] RBAC: DIC Should Never Be Set To Array See (maybe): https://mantis.ilias.de/view.php?id=41574 --- ...ccessCustomRBACOperationAddedObjective.php | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/Services/AccessControl/classes/Setup/class.ilAccessCustomRBACOperationAddedObjective.php b/Services/AccessControl/classes/Setup/class.ilAccessCustomRBACOperationAddedObjective.php index 2d7f5e625471..6e7ddd10da1f 100644 --- a/Services/AccessControl/classes/Setup/class.ilAccessCustomRBACOperationAddedObjective.php +++ b/Services/AccessControl/classes/Setup/class.ilAccessCustomRBACOperationAddedObjective.php @@ -25,6 +25,8 @@ class ilAccessCustomRBACOperationAddedObjective implements Setup\Objective { + private const NO_DIC_FOUND = 'There is no $DIC.'; + protected string $id; protected string $title; protected string $class; @@ -125,7 +127,7 @@ public function achieve(Environment $environment): Environment $db->insert("rbac_ta", $values); } - $GLOBALS["DIC"] = $dic; + $this->resetDIC($dic); return $environment; } @@ -159,8 +161,7 @@ public function isApplicable(Environment $environment): bool } } - $GLOBALS["DIC"] = $dic; - + $this->resetDIC($dic); return count($this->types) && in_array($this->class, ['create', 'object', 'general']); } @@ -172,17 +173,26 @@ protected function initEnvironment(Setup\Environment $environment) // subcomponents of the various readers to run. This is a memento to the // fact, that dependency injection is something we want. Currently, every // component could just service locate the whole world via the global $DIC. - $DIC = []; - if (isset($GLOBALS["DIC"])) { - $DIC = $GLOBALS["DIC"]; + $DIC = self::NO_DIC_FOUND; + if (array_key_exists('DIC', $GLOBALS)) { + $DIC = $GLOBALS['DIC']; } - $GLOBALS["DIC"] = new DI\Container(); - $GLOBALS["DIC"]["ilDB"] = $db; + $GLOBALS['DIC'] = new DI\Container(); + $GLOBALS['DIC']['ilDB'] = $db; - if (!defined("ILIAS_ABSOLUTE_PATH")) { - define("ILIAS_ABSOLUTE_PATH", dirname(__FILE__, 5)); + if (!defined('ILIAS_ABSOLUTE_PATH')) { + define('ILIAS_ABSOLUTE_PATH', dirname(__FILE__, 5)); } return $DIC; } + + protected function resetDIC($dic): void + { + if ($dic !== self::NO_DIC_FOUND) { + $GLOBALS['DIC'] = $dic; + return; + } + unset($GLOBALS['DIC']); + } } From d44b60c0246c137a7fa668292bda0b33706889dc Mon Sep 17 00:00:00 2001 From: Stephan Kergomard Date: Fri, 2 Aug 2024 08:01:44 +0200 Subject: [PATCH 06/61] RBAC: Operation Allows Null in DB See: https://mantis.ilias.de/view.php?id=41835 --- Services/AccessControl/classes/class.ilRoleXmlExport.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Services/AccessControl/classes/class.ilRoleXmlExport.php b/Services/AccessControl/classes/class.ilRoleXmlExport.php index 33367be63e7f..86cda7eaecdb 100644 --- a/Services/AccessControl/classes/class.ilRoleXmlExport.php +++ b/Services/AccessControl/classes/class.ilRoleXmlExport.php @@ -120,7 +120,9 @@ private function writeRole(int $a_role_id, int $a_rolf): void $this->xmlStartTag('operations'); foreach ($this->rbacreview->getAllOperationsOfRole($a_role_id, $a_rolf) as $obj_group => $operations) { foreach ($operations as $ops_id) { - $this->xmlElement('operation', ['group' => $obj_group], trim($this->operations[$ops_id])); + if (isset($this->operations[$ops_id])) { + $this->xmlElement('operation', ['group' => $obj_group], trim($this->operations[$ops_id])); + } } } $this->xmlEndTag('operations'); From 22363180617510342e3715bebb2a53832d40faa1 Mon Sep 17 00:00:00 2001 From: Releasemanager Date: Tue, 30 Jul 2024 14:54:21 +0000 Subject: [PATCH 07/61] Update composer.lock and package-lock.json after release v9.3 --- composer.lock | 686 ++++++++++++++++++++++++++++---------------------- 1 file changed, 387 insertions(+), 299 deletions(-) diff --git a/composer.lock b/composer.lock index 929456e9005d..85b473791adb 100644 --- a/composer.lock +++ b/composer.lock @@ -64,16 +64,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.5.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "0c5ccfcfea312b5c5a190a21ac5cef93f74baf99" + "reference": "063d9aa8696582f5a41dffbbaf3c81024f0a604a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/0c5ccfcfea312b5c5a190a21ac5cef93f74baf99", - "reference": "0c5ccfcfea312b5c5a190a21ac5cef93f74baf99", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/063d9aa8696582f5a41dffbbaf3c81024f0a604a", + "reference": "063d9aa8696582f5a41dffbbaf3c81024f0a604a", "shasum": "" }, "require": { @@ -83,7 +83,7 @@ }, "require-dev": { "phpstan/phpstan": "^1.10", - "psr/log": "^1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", "symfony/phpunit-bridge": "^4.2 || ^5", "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, @@ -120,7 +120,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.5.0" + "source": "https://github.com/composer/ca-bundle/tree/1.5.1" }, "funding": [ { @@ -136,7 +136,7 @@ "type": "tidelift" } ], - "time": "2024-03-15T14:00:32+00:00" + "time": "2024-07-08T15:28:20+00:00" }, { "name": "composer/class-map-generator", @@ -396,30 +396,38 @@ }, { "name": "composer/pcre", - "version": "3.1.4", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "04229f163664973f68f38f6f73d917799168ef24" + "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/04229f163664973f68f38f6f73d917799168ef24", - "reference": "04229f163664973f68f38f6f73d917799168ef24", + "url": "https://api.github.com/repos/composer/pcre/zipball/ea4ab6f9580a4fd221e0418f2c357cdd39102a90", + "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, + "conflict": { + "phpstan/phpstan": "<1.11.8" + }, "require-dev": { - "phpstan/phpstan": "^1.3", + "phpstan/phpstan": "^1.11.8", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" + "phpunit/phpunit": "^8 || ^9" }, "type": "library", "extra": { "branch-alias": { "dev-main": "3.x-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] } }, "autoload": { @@ -447,7 +455,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.4" + "source": "https://github.com/composer/pcre/tree/3.2.0" }, "funding": [ { @@ -463,20 +471,20 @@ "type": "tidelift" } ], - "time": "2024-05-27T13:40:54+00:00" + "time": "2024-07-25T09:36:02+00:00" }, { "name": "composer/semver", - "version": "3.4.0", + "version": "3.4.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6", + "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6", "shasum": "" }, "require": { @@ -528,7 +536,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.0" + "source": "https://github.com/composer/semver/tree/3.4.2" }, "funding": [ { @@ -544,7 +552,7 @@ "type": "tidelift" } ], - "time": "2023-08-31T09:50:34+00:00" + "time": "2024-07-12T11:35:52+00:00" }, { "name": "composer/spdx-licenses", @@ -742,16 +750,16 @@ }, { "name": "dflydev/dot-access-data", - "version": "v3.0.2", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/dflydev/dflydev-dot-access-data.git", - "reference": "f41715465d65213d644d3141a6a93081be5d3549" + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549", - "reference": "f41715465d65213d644d3141a6a93081be5d3549", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", "shasum": "" }, "require": { @@ -811,9 +819,9 @@ ], "support": { "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", - "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2" + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" }, - "time": "2022-10-27T11:44:00+00:00" + "time": "2024-07-08T12:26:09+00:00" }, { "name": "dflydev/fig-cookies", @@ -1097,16 +1105,16 @@ }, { "name": "gettext/gettext", - "version": "v5.7.0", + "version": "v5.7.1", "source": { "type": "git", "url": "https://github.com/php-gettext/Gettext.git", - "reference": "8657e580747bb3baacccdcebe69cac094661e404" + "reference": "a9f89e0cc9d9a67b422632b594b5f1afb16eccfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/8657e580747bb3baacccdcebe69cac094661e404", - "reference": "8657e580747bb3baacccdcebe69cac094661e404", + "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/a9f89e0cc9d9a67b422632b594b5f1afb16eccfc", + "reference": "a9f89e0cc9d9a67b422632b594b5f1afb16eccfc", "shasum": "" }, "require": { @@ -1151,7 +1159,7 @@ "support": { "email": "oom@oscarotero.com", "issues": "https://github.com/php-gettext/Gettext/issues", - "source": "https://github.com/php-gettext/Gettext/tree/v5.7.0" + "source": "https://github.com/php-gettext/Gettext/tree/v5.7.1" }, "funding": [ { @@ -1167,7 +1175,7 @@ "type": "patreon" } ], - "time": "2022-07-27T19:54:55+00:00" + "time": "2024-07-24T22:05:18+00:00" }, { "name": "gettext/languages", @@ -1319,22 +1327,22 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.8.1", + "version": "7.9.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0.1", - "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -1345,9 +1353,9 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -1425,7 +1433,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + "source": "https://github.com/guzzle/guzzle/tree/7.9.2" }, "funding": [ { @@ -1441,20 +1449,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:35:24+00:00" + "time": "2024-07-24T11:22:20+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "url": "https://api.github.com/repos/guzzle/promises/zipball/6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", + "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", "shasum": "" }, "require": { @@ -1462,7 +1470,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "type": "library", "extra": { @@ -1508,7 +1516,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.2" + "source": "https://github.com/guzzle/promises/tree/2.0.3" }, "funding": [ { @@ -1524,20 +1532,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:19:20+00:00" + "time": "2024-07-18T10:29:17+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.6.2", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", "shasum": "" }, "require": { @@ -1552,8 +1560,8 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -1624,7 +1632,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.6.2" + "source": "https://github.com/guzzle/psr7/tree/2.7.0" }, "funding": [ { @@ -1640,7 +1648,7 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:05:35+00:00" + "time": "2024-07-18T11:15:46+00:00" }, { "name": "ifsnop/mysqldump-php", @@ -1883,20 +1891,20 @@ }, { "name": "justinrainbow/json-schema", - "version": "v5.2.13", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", @@ -1907,11 +1915,6 @@ "bin/validate-json" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, "autoload": { "psr-4": { "JsonSchema\\": "src/JsonSchema/" @@ -1947,22 +1950,22 @@ ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/v5.2.13" + "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.0" }, - "time": "2023-09-26T02:20:38+00:00" + "time": "2024-07-06T21:00:26+00:00" }, { "name": "league/commonmark", - "version": "2.4.2", + "version": "2.5.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf" + "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91c24291965bd6d7c46c46a12ba7492f83b1cadf", - "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/ac815920de0eff6de947eac0a6a94e5ed0fb147c", + "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c", "shasum": "" }, "require": { @@ -1975,8 +1978,8 @@ }, "require-dev": { "cebe/markdown": "^1.0", - "commonmark/cmark": "0.30.3", - "commonmark/commonmark.js": "0.30.0", + "commonmark/cmark": "0.31.0", + "commonmark/commonmark.js": "0.31.0", "composer/package-versions-deprecated": "^1.8", "embed/embed": "^4.4", "erusev/parsedown": "^1.0", @@ -1998,7 +2001,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "2.6-dev" } }, "autoload": { @@ -2055,7 +2058,7 @@ "type": "tidelift" } ], - "time": "2024-02-02T11:59:32+00:00" + "time": "2024-07-24T12:52:09+00:00" }, { "name": "league/config", @@ -2327,6 +2330,90 @@ ], "time": "2024-01-28T23:22:08+00:00" }, + { + "name": "league/uri-interfaces", + "version": "7.4.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "8d43ef5c841032c87e2de015972c06f3865ef718" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/8d43ef5c841032c87e2de015972c06f3865ef718", + "reference": "8d43ef5c841032c87e2de015972c06f3865ef718", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-factory": "^1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interfaces and classes for URI representation and interaction", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.4.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-03-23T07:42:40+00:00" + }, { "name": "maennchen/zipstream-php", "version": "3.1.0", @@ -3170,16 +3257,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.38", + "version": "3.0.39", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "b18b8788e51156c4dd97b7f220a31149a0052067" + "reference": "211ebc399c6e73c225a018435fe5ae209d1d1485" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/b18b8788e51156c4dd97b7f220a31149a0052067", - "reference": "b18b8788e51156c4dd97b7f220a31149a0052067", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/211ebc399c6e73c225a018435fe5ae209d1d1485", + "reference": "211ebc399c6e73c225a018435fe5ae209d1d1485", "shasum": "" }, "require": { @@ -3260,7 +3347,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.38" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.39" }, "funding": [ { @@ -3276,7 +3363,7 @@ "type": "tidelift" } ], - "time": "2024-06-17T10:11:32+00:00" + "time": "2024-06-24T06:27:33+00:00" }, { "name": "pimple/pimple", @@ -4166,16 +4253,16 @@ }, { "name": "sabre/event", - "version": "5.1.4", + "version": "5.1.6", "source": { "type": "git", "url": "https://github.com/sabre-io/event.git", - "reference": "d7da22897125d34d7eddf7977758191c06a74497" + "reference": "e0e1ccbff1965083de9a6530182b8b70819e1347" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/event/zipball/d7da22897125d34d7eddf7977758191c06a74497", - "reference": "d7da22897125d34d7eddf7977758191c06a74497", + "url": "https://api.github.com/repos/sabre-io/event/zipball/e0e1ccbff1965083de9a6530182b8b70819e1347", + "reference": "e0e1ccbff1965083de9a6530182b8b70819e1347", "shasum": "" }, "require": { @@ -4184,7 +4271,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.17.1", "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" }, "type": "library", "autoload": { @@ -4228,20 +4315,20 @@ "issues": "https://github.com/sabre-io/event/issues", "source": "https://github.com/fruux/sabre-event" }, - "time": "2021-11-04T06:51:17+00:00" + "time": "2024-07-26T05:09:47+00:00" }, { "name": "sabre/http", - "version": "5.1.10", + "version": "5.1.11", "source": { "type": "git", "url": "https://github.com/sabre-io/http.git", - "reference": "f9f3d1fba8916fa2f4ec25636c4fedc26cb94e02" + "reference": "abb019d9415d8c6c39c377e212ef34ad727b711f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/http/zipball/f9f3d1fba8916fa2f4ec25636c4fedc26cb94e02", - "reference": "f9f3d1fba8916fa2f4ec25636c4fedc26cb94e02", + "url": "https://api.github.com/repos/sabre-io/http/zipball/abb019d9415d8c6c39c377e212ef34ad727b711f", + "reference": "abb019d9415d8c6c39c377e212ef34ad727b711f", "shasum": "" }, "require": { @@ -4255,7 +4342,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.17.1", "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" }, "suggest": { "ext-curl": " to make http requests with the Client class" @@ -4291,7 +4378,7 @@ "issues": "https://github.com/sabre-io/http/issues", "source": "https://github.com/fruux/sabre-http" }, - "time": "2023-08-18T01:55:28+00:00" + "time": "2024-07-26T06:15:25+00:00" }, { "name": "sabre/uri", @@ -4355,16 +4442,16 @@ }, { "name": "sabre/vobject", - "version": "4.5.4", + "version": "4.5.5", "source": { "type": "git", "url": "https://github.com/sabre-io/vobject.git", - "reference": "a6d53a3e5bec85ed3dd78868b7de0f5b4e12f772" + "reference": "7148cf57d25aaba0a49f6656d37c35e8175b3087" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/vobject/zipball/a6d53a3e5bec85ed3dd78868b7de0f5b4e12f772", - "reference": "a6d53a3e5bec85ed3dd78868b7de0f5b4e12f772", + "url": "https://api.github.com/repos/sabre-io/vobject/zipball/7148cf57d25aaba0a49f6656d37c35e8175b3087", + "reference": "7148cf57d25aaba0a49f6656d37c35e8175b3087", "shasum": "" }, "require": { @@ -4455,20 +4542,20 @@ "issues": "https://github.com/sabre-io/vobject/issues", "source": "https://github.com/fruux/sabre-vobject" }, - "time": "2023-11-09T12:54:37+00:00" + "time": "2024-07-02T08:48:52+00:00" }, { "name": "sabre/xml", - "version": "2.2.7", + "version": "2.2.9", "source": { "type": "git", "url": "https://github.com/sabre-io/xml.git", - "reference": "f1d53d55976bbd4cf3e640dda6ebc31120c71a4e" + "reference": "88288712d45f694be3679a0db7dfb3770f08d4f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/f1d53d55976bbd4cf3e640dda6ebc31120c71a4e", - "reference": "f1d53d55976bbd4cf3e640dda6ebc31120c71a4e", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/88288712d45f694be3679a0db7dfb3770f08d4f0", + "reference": "88288712d45f694be3679a0db7dfb3770f08d4f0", "shasum": "" }, "require": { @@ -4482,7 +4569,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.17.1", "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" }, "type": "library", "autoload": { @@ -4524,27 +4611,27 @@ "issues": "https://github.com/sabre-io/xml/issues", "source": "https://github.com/fruux/sabre-xml" }, - "time": "2024-04-18T10:15:43+00:00" + "time": "2024-07-26T12:32:40+00:00" }, { "name": "seld/jsonlint", - "version": "1.10.2", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "9bb7db07b5d66d90f6ebf542f09fc67d800e5259" + "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9bb7db07b5d66d90f6ebf542f09fc67d800e5259", - "reference": "9bb7db07b5d66d90f6ebf542f09fc67d800e5259", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/1748aaf847fc731cfad7725aec413ee46f0cc3a2", + "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2", "shasum": "" }, "require": { "php": "^5.3 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.5", + "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" }, "bin": [ @@ -4576,7 +4663,7 @@ ], "support": { "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.10.2" + "source": "https://github.com/Seldaek/jsonlint/tree/1.11.0" }, "funding": [ { @@ -4588,7 +4675,7 @@ "type": "tidelift" } ], - "time": "2024-02-07T12:57:50+00:00" + "time": "2024-07-11T14:55:45+00:00" }, { "name": "seld/phar-utils", @@ -4701,16 +4788,16 @@ }, { "name": "simplesamlphp/assert", - "version": "v1.1.8", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/assert.git", - "reference": "0a5ffa660849db748872bbf017569b4365a39fac" + "reference": "bc80f10858179af2516b48643f3ec43ae7a36937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/assert/zipball/0a5ffa660849db748872bbf017569b4365a39fac", - "reference": "0a5ffa660849db748872bbf017569b4365a39fac", + "url": "https://api.github.com/repos/simplesamlphp/assert/zipball/bc80f10858179af2516b48643f3ec43ae7a36937", + "reference": "bc80f10858179af2516b48643f3ec43ae7a36937", "shasum": "" }, "require": { @@ -4718,11 +4805,12 @@ "ext-filter": "*", "ext-pcre": "*", "ext-spl": "*", + "league/uri-interfaces": "^7.4", "php": "^8.1", "webmozart/assert": "^1.11" }, "require-dev": { - "simplesamlphp/simplesamlphp-test-framework": "^1.5.5" + "simplesamlphp/simplesamlphp-test-framework": "^1.7" }, "type": "library", "extra": { @@ -4752,9 +4840,9 @@ "description": "A wrapper around webmozart/assert to make it useful beyond checking method arguments", "support": { "issues": "https://github.com/simplesamlphp/assert/issues", - "source": "https://github.com/simplesamlphp/assert/tree/v1.1.8" + "source": "https://github.com/simplesamlphp/assert/tree/v1.2.1" }, - "time": "2024-05-21T10:35:09+00:00" + "time": "2024-07-23T14:28:59+00:00" }, { "name": "simplesamlphp/composer-module-installer", @@ -5101,16 +5189,16 @@ }, { "name": "symfony/cache", - "version": "v5.4.40", + "version": "v5.4.42", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "89005bc368ca02ed0433c592e4d27670d0844a66" + "reference": "6f5f750692bd5a212e01a4f1945fd856bceef89e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/89005bc368ca02ed0433c592e4d27670d0844a66", - "reference": "89005bc368ca02ed0433c592e4d27670d0844a66", + "url": "https://api.github.com/repos/symfony/cache/zipball/6f5f750692bd5a212e01a4f1945fd856bceef89e", + "reference": "6f5f750692bd5a212e01a4f1945fd856bceef89e", "shasum": "" }, "require": { @@ -5178,7 +5266,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v5.4.40" + "source": "https://github.com/symfony/cache/tree/v5.4.42" }, "funding": [ { @@ -5194,7 +5282,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2024-07-10T06:02:18+00:00" }, { "name": "symfony/cache-contracts", @@ -5356,16 +5444,16 @@ }, { "name": "symfony/console", - "version": "v5.4.40", + "version": "v5.4.42", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "aa73115c0c24220b523625bfcfa655d7d73662dd" + "reference": "cef62396a0477e94fc52e87a17c6e5c32e226b7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/aa73115c0c24220b523625bfcfa655d7d73662dd", - "reference": "aa73115c0c24220b523625bfcfa655d7d73662dd", + "url": "https://api.github.com/repos/symfony/console/zipball/cef62396a0477e94fc52e87a17c6e5c32e226b7f", + "reference": "cef62396a0477e94fc52e87a17c6e5c32e226b7f", "shasum": "" }, "require": { @@ -5435,7 +5523,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.40" + "source": "https://github.com/symfony/console/tree/v5.4.42" }, "funding": [ { @@ -5451,20 +5539,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2024-07-26T12:21:55+00:00" }, { "name": "symfony/dependency-injection", - "version": "v5.4.40", + "version": "v5.4.42", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "408b33326496030c201b8051b003e9e8cdb2efc9" + "reference": "c8409889fdbf48b99271930ea0ebcf3ee5e1ceae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/408b33326496030c201b8051b003e9e8cdb2efc9", - "reference": "408b33326496030c201b8051b003e9e8cdb2efc9", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/c8409889fdbf48b99271930ea0ebcf3ee5e1ceae", + "reference": "c8409889fdbf48b99271930ea0ebcf3ee5e1ceae", "shasum": "" }, "require": { @@ -5524,7 +5612,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v5.4.40" + "source": "https://github.com/symfony/dependency-injection/tree/v5.4.42" }, "funding": [ { @@ -5540,7 +5628,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2024-07-25T13:57:40+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5841,16 +5929,16 @@ }, { "name": "symfony/filesystem", - "version": "v5.4.40", + "version": "v5.4.41", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "26dd9912df6940810ea00f8f53ad48d6a3424995" + "reference": "6d29dd9340b372fa603f04e6df4dd76bb808591e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/26dd9912df6940810ea00f8f53ad48d6a3424995", - "reference": "26dd9912df6940810ea00f8f53ad48d6a3424995", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/6d29dd9340b372fa603f04e6df4dd76bb808591e", + "reference": "6d29dd9340b372fa603f04e6df4dd76bb808591e", "shasum": "" }, "require": { @@ -5888,7 +5976,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.40" + "source": "https://github.com/symfony/filesystem/tree/v5.4.41" }, "funding": [ { @@ -5904,20 +5992,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2024-06-28T09:36:24+00:00" }, { "name": "symfony/finder", - "version": "v5.4.40", + "version": "v5.4.42", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "f51cff4687547641c7d8180d74932ab40b2205ce" + "reference": "0724c51fa067b198e36506d2864e09a52180998a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/f51cff4687547641c7d8180d74932ab40b2205ce", - "reference": "f51cff4687547641c7d8180d74932ab40b2205ce", + "url": "https://api.github.com/repos/symfony/finder/zipball/0724c51fa067b198e36506d2864e09a52180998a", + "reference": "0724c51fa067b198e36506d2864e09a52180998a", "shasum": "" }, "require": { @@ -5951,7 +6039,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.40" + "source": "https://github.com/symfony/finder/tree/v5.4.42" }, "funding": [ { @@ -5967,20 +6055,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2024-07-22T08:53:29+00:00" }, { "name": "symfony/framework-bundle", - "version": "v5.4.40", + "version": "v5.4.42", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "603090d8327e279bd233d5ce42a1ed89bc91612f" + "reference": "0a9f66cd53cb2578c9dff53645304ef313ecb63b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/603090d8327e279bd233d5ce42a1ed89bc91612f", - "reference": "603090d8327e279bd233d5ce42a1ed89bc91612f", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/0a9f66cd53cb2578c9dff53645304ef313ecb63b", + "reference": "0a9f66cd53cb2578c9dff53645304ef313ecb63b", "shasum": "" }, "require": { @@ -6101,7 +6189,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v5.4.40" + "source": "https://github.com/symfony/framework-bundle/tree/v5.4.42" }, "funding": [ { @@ -6117,20 +6205,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2024-07-09T20:57:15+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.4.40", + "version": "v5.4.42", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "cf4893ca4eca3fac4ae06da1590afdbbb4217847" + "reference": "9c375b2abef0b657aa0b7612b763df5c12a465ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cf4893ca4eca3fac4ae06da1590afdbbb4217847", - "reference": "cf4893ca4eca3fac4ae06da1590afdbbb4217847", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9c375b2abef0b657aa0b7612b763df5c12a465ab", + "reference": "9c375b2abef0b657aa0b7612b763df5c12a465ab", "shasum": "" }, "require": { @@ -6177,7 +6265,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.40" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.42" }, "funding": [ { @@ -6193,20 +6281,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2024-07-26T11:59:59+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.40", + "version": "v5.4.42", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "3ad03183c6985adc2eece16f239f8cfe1c4ccbe3" + "reference": "948db7caf761dacc8abb9a59465f0639c30cc6dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3ad03183c6985adc2eece16f239f8cfe1c4ccbe3", - "reference": "3ad03183c6985adc2eece16f239f8cfe1c4ccbe3", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/948db7caf761dacc8abb9a59465f0639c30cc6dd", + "reference": "948db7caf761dacc8abb9a59465f0639c30cc6dd", "shasum": "" }, "require": { @@ -6290,7 +6378,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.4.40" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.42" }, "funding": [ { @@ -6306,7 +6394,7 @@ "type": "tidelift" } ], - "time": "2024-06-02T15:53:08+00:00" + "time": "2024-07-26T14:46:22+00:00" }, { "name": "symfony/intl", @@ -6400,16 +6488,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "0424dff1c58f028c451efff2045f5d92410bd540" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", + "reference": "0424dff1c58f028c451efff2045f5d92410bd540", "shasum": "" }, "require": { @@ -6459,7 +6547,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" }, "funding": [ { @@ -6475,20 +6563,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a", + "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a", "shasum": "" }, "require": { @@ -6537,7 +6625,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0" }, "funding": [ { @@ -6553,20 +6641,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "07094a28851a49107f3ab4f9120ca2975a64b6e1" + "reference": "e76343c631b453088e2260ac41dfebe21954de81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/07094a28851a49107f3ab4f9120ca2975a64b6e1", - "reference": "07094a28851a49107f3ab4f9120ca2975a64b6e1", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/e76343c631b453088e2260ac41dfebe21954de81", + "reference": "e76343c631b453088e2260ac41dfebe21954de81", "shasum": "" }, "require": { @@ -6621,7 +6709,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.30.0" }, "funding": [ { @@ -6637,20 +6725,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:12:16+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb", + "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb", "shasum": "" }, "require": { @@ -6702,7 +6790,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0" }, "funding": [ { @@ -6718,20 +6806,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", "shasum": "" }, "require": { @@ -6782,7 +6870,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" }, "funding": [ { @@ -6798,20 +6886,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:30:46+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" + "reference": "ec444d3f3f6505bb28d11afa41e75faadebc10a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/ec444d3f3f6505bb28d11afa41e75faadebc10a1", + "reference": "ec444d3f3f6505bb28d11afa41e75faadebc10a1", "shasum": "" }, "require": { @@ -6858,7 +6946,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.30.0" }, "funding": [ { @@ -6874,20 +6962,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", "shasum": "" }, "require": { @@ -6938,7 +7026,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" }, "funding": [ { @@ -6954,20 +7042,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/3fb075789fb91f9ad9af537c4012d523085bd5af", + "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af", "shasum": "" }, "require": { @@ -7014,7 +7102,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.30.0" }, "funding": [ { @@ -7030,7 +7118,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:30:46+00:00" }, { "name": "symfony/process", @@ -7095,16 +7183,16 @@ }, { "name": "symfony/routing", - "version": "v5.4.40", + "version": "v5.4.42", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "6df1dd8b306649303267a760699cf04cf39b1f7b" + "reference": "f8dd6f80c96aeec9b13fc13757842342e05c4878" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/6df1dd8b306649303267a760699cf04cf39b1f7b", - "reference": "6df1dd8b306649303267a760699cf04cf39b1f7b", + "url": "https://api.github.com/repos/symfony/routing/zipball/f8dd6f80c96aeec9b13fc13757842342e05c4878", + "reference": "f8dd6f80c96aeec9b13fc13757842342e05c4878", "shasum": "" }, "require": { @@ -7165,7 +7253,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v5.4.40" + "source": "https://github.com/symfony/routing/tree/v5.4.42" }, "funding": [ { @@ -7181,7 +7269,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2024-07-09T20:57:15+00:00" }, { "name": "symfony/service-contracts", @@ -7268,16 +7356,16 @@ }, { "name": "symfony/string", - "version": "v6.4.8", + "version": "v6.4.10", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d" + "reference": "ccf9b30251719567bfd46494138327522b9a9446" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/a147c0f826c4a1f3afb763ab8e009e37c877a44d", - "reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d", + "url": "https://api.github.com/repos/symfony/string/zipball/ccf9b30251719567bfd46494138327522b9a9446", + "reference": "ccf9b30251719567bfd46494138327522b9a9446", "shasum": "" }, "require": { @@ -7334,7 +7422,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.8" + "source": "https://github.com/symfony/string/tree/v6.4.10" }, "funding": [ { @@ -7350,7 +7438,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:49:08+00:00" + "time": "2024-07-22T10:21:14+00:00" }, { "name": "symfony/translation-contracts", @@ -7432,16 +7520,16 @@ }, { "name": "symfony/twig-bridge", - "version": "v5.4.40", + "version": "v5.4.41", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "b982cfa2d15058d2642ca4cf7edab495d6dac707" + "reference": "d7b10dad12c49863c20c7f8e4cc74b9416eefbb9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/b982cfa2d15058d2642ca4cf7edab495d6dac707", - "reference": "b982cfa2d15058d2642ca4cf7edab495d6dac707", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/d7b10dad12c49863c20c7f8e4cc74b9416eefbb9", + "reference": "d7b10dad12c49863c20c7f8e4cc74b9416eefbb9", "shasum": "" }, "require": { @@ -7533,7 +7621,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v5.4.40" + "source": "https://github.com/symfony/twig-bridge/tree/v5.4.41" }, "funding": [ { @@ -7549,20 +7637,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2024-06-09T18:59:35+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.8", + "version": "v6.4.10", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "ad23ca4312395f0a8a8633c831ef4c4ee542ed25" + "reference": "a71cc3374f5fb9759da1961d28c452373b343dd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ad23ca4312395f0a8a8633c831ef4c4ee542ed25", - "reference": "ad23ca4312395f0a8a8633c831ef4c4ee542ed25", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a71cc3374f5fb9759da1961d28c452373b343dd4", + "reference": "a71cc3374f5fb9759da1961d28c452373b343dd4", "shasum": "" }, "require": { @@ -7618,7 +7706,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.8" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.10" }, "funding": [ { @@ -7634,7 +7722,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:49:08+00:00" + "time": "2024-07-26T12:30:32+00:00" }, { "name": "symfony/var-exporter", @@ -8037,16 +8125,16 @@ "packages-dev": [ { "name": "captainhook/captainhook", - "version": "5.23.0", + "version": "5.23.3", "source": { "type": "git", "url": "https://github.com/captainhookphp/captainhook.git", - "reference": "08d90e4d98db123ab58826be8e891d7d36c14f2a" + "reference": "c9deaefc098dde7f7093b44482b099195442e70d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/captainhookphp/captainhook/zipball/08d90e4d98db123ab58826be8e891d7d36c14f2a", - "reference": "08d90e4d98db123ab58826be8e891d7d36c14f2a", + "url": "https://api.github.com/repos/captainhookphp/captainhook/zipball/c9deaefc098dde7f7093b44482b099195442e70d", + "reference": "c9deaefc098dde7f7093b44482b099195442e70d", "shasum": "" }, "require": { @@ -8109,7 +8197,7 @@ ], "support": { "issues": "https://github.com/captainhookphp/captainhook/issues", - "source": "https://github.com/captainhookphp/captainhook/tree/5.23.0" + "source": "https://github.com/captainhookphp/captainhook/tree/5.23.3" }, "funding": [ { @@ -8117,7 +8205,7 @@ "type": "github" } ], - "time": "2024-04-12T10:39:21+00:00" + "time": "2024-07-07T19:12:59+00:00" }, { "name": "captainhook/plugin-composer", @@ -8474,16 +8562,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.59.3", + "version": "v3.60.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "30ba9ecc2b0e5205e578fe29973c15653d9bfd29" + "reference": "e595e4e070d17c5d42ed8c4206f630fcc5f401a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/30ba9ecc2b0e5205e578fe29973c15653d9bfd29", - "reference": "30ba9ecc2b0e5205e578fe29973c15653d9bfd29", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/e595e4e070d17c5d42ed8c4206f630fcc5f401a4", + "reference": "e595e4e070d17c5d42ed8c4206f630fcc5f401a4", "shasum": "" }, "require": { @@ -8565,7 +8653,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.59.3" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.60.0" }, "funding": [ { @@ -8573,7 +8661,7 @@ "type": "github" } ], - "time": "2024-06-16T14:17:03+00:00" + "time": "2024-07-25T09:26:51+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -8822,16 +8910,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.0.2", + "version": "v5.1.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", "shasum": "" }, "require": { @@ -8842,7 +8930,7 @@ }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" @@ -8874,9 +8962,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" }, - "time": "2024-03-05T20:51:40+00:00" + "time": "2024-07-01T20:03:41+00:00" }, { "name": "phar-io/manifest", @@ -8998,16 +9086,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.5", + "version": "1.11.8", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "490f0ae1c92b082f154681d7849aee776a7c1443" + "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/490f0ae1c92b082f154681d7849aee776a7c1443", - "reference": "490f0ae1c92b082f154681d7849aee776a7c1443", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", + "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", "shasum": "" }, "require": { @@ -9052,7 +9140,7 @@ "type": "github" } ], - "time": "2024-06-17T15:10:54+00:00" + "time": "2024-07-24T07:01:22+00:00" }, { "name": "phpunit/php-code-coverage", @@ -9375,45 +9463,45 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.19", + "version": "9.6.20", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8" + "reference": "49d7820565836236411f5dc002d16dd689cde42f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1a54a473501ef4cdeaae4e06891674114d79db8", - "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/49d7820565836236411f5dc002d16dd689cde42f", + "reference": "49d7820565836236411f5dc002d16dd689cde42f", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1 || ^2", + "doctrine/instantiator": "^1.5.0 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", + "myclabs/deep-copy": "^1.12.0", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.28", - "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-code-coverage": "^9.2.31", + "phpunit/php-file-iterator": "^3.0.6", "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", + "phpunit/php-text-template": "^2.0.4", + "phpunit/php-timer": "^5.0.3", + "sebastian/cli-parser": "^1.0.2", + "sebastian/code-unit": "^1.0.8", "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.5", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.2", + "sebastian/diff": "^4.0.6", + "sebastian/environment": "^5.1.5", + "sebastian/exporter": "^4.0.6", + "sebastian/global-state": "^5.0.7", + "sebastian/object-enumerator": "^4.0.4", + "sebastian/resource-operations": "^3.0.4", + "sebastian/type": "^3.2.1", "sebastian/version": "^3.0.2" }, "suggest": { @@ -9458,7 +9546,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.19" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.20" }, "funding": [ { @@ -9474,7 +9562,7 @@ "type": "tidelift" } ], - "time": "2024-04-05T04:35:58+00:00" + "time": "2024-07-10T11:45:39+00:00" }, { "name": "react/cache", @@ -9777,31 +9865,31 @@ }, { "name": "react/socket", - "version": "v1.15.0", + "version": "v1.16.0", "source": { "type": "git", "url": "https://github.com/reactphp/socket.git", - "reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038" + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/socket/zipball/216d3aec0b87f04a40ca04f481e6af01bdd1d038", - "reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", "shasum": "" }, "require": { "evenement/evenement": "^3.0 || ^2.0 || ^1.0", "php": ">=5.3.0", - "react/dns": "^1.11", + "react/dns": "^1.13", "react/event-loop": "^1.2", - "react/promise": "^3 || ^2.6 || ^1.2.1", - "react/stream": "^1.2" + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" }, "require-dev": { "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", - "react/async": "^4 || ^3 || ^2", + "react/async": "^4.3 || ^3.3 || ^2", "react/promise-stream": "^1.4", - "react/promise-timer": "^1.10" + "react/promise-timer": "^1.11" }, "type": "library", "autoload": { @@ -9845,7 +9933,7 @@ ], "support": { "issues": "https://github.com/reactphp/socket/issues", - "source": "https://github.com/reactphp/socket/tree/v1.15.0" + "source": "https://github.com/reactphp/socket/tree/v1.16.0" }, "funding": [ { @@ -9853,7 +9941,7 @@ "type": "open_collective" } ], - "time": "2023-12-15T11:02:10+00:00" + "time": "2024-07-26T10:38:09+00:00" }, { "name": "react/stream", From 08a7be545d523d7f51ce6783b92d48d1ef7071b2 Mon Sep 17 00:00:00 2001 From: Alex Killing Date: Fri, 2 Aug 2024 13:43:11 +0200 Subject: [PATCH 08/61] 41841: Editing the Portfilio pages leads to an error --- .../Portfolio/PrintView/class.PortfolioPrintViewProviderGUI.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/Portfolio/PrintView/class.PortfolioPrintViewProviderGUI.php b/Modules/Portfolio/PrintView/class.PortfolioPrintViewProviderGUI.php index 072b83296952..5f45845fa7b5 100644 --- a/Modules/Portfolio/PrintView/class.PortfolioPrintViewProviderGUI.php +++ b/Modules/Portfolio/PrintView/class.PortfolioPrintViewProviderGUI.php @@ -27,6 +27,7 @@ */ class PortfolioPrintViewProviderGUI extends Export\AbstractPrintViewProvider { + protected bool $include_declaration = false; protected StandardGUIRequest $port_request; protected \ilLanguage $lng; protected \ilObjPortfolio $portfolio; From 776e226783d436dea313d56e406250adf679a363 Mon Sep 17 00:00:00 2001 From: Alex Killing Date: Fri, 2 Aug 2024 13:54:27 +0200 Subject: [PATCH 09/61] 41825: Import failure for portfolios --- Modules/Portfolio/Export/class.ilPortfolioImporter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Portfolio/Export/class.ilPortfolioImporter.php b/Modules/Portfolio/Export/class.ilPortfolioImporter.php index edc28115adc6..659a84e47675 100644 --- a/Modules/Portfolio/Export/class.ilPortfolioImporter.php +++ b/Modules/Portfolio/Export/class.ilPortfolioImporter.php @@ -52,7 +52,7 @@ public function finalProcessing( ): void { $prttpg_map = $a_mapping->getMappingsOfEntity("Services/COPage", "pg"); foreach ($prttpg_map as $prttpg_id) { - $prttpg_id = substr($prttpg_id, 5); + $prttpg_id = (int) substr($prttpg_id, 5); $prtt_id = ilPortfolioTemplatePage::findPortfolioForPage($prttpg_id); ilPortfolioTemplatePage::_writeParentId("prtt", $prttpg_id, $prtt_id); } From 02c1a4ea881990438d76ae8b0941f569a77a40ed Mon Sep 17 00:00:00 2001 From: Alex Killing Date: Fri, 2 Aug 2024 14:30:08 +0200 Subject: [PATCH 10/61] added br on heading formattings in page overview --- Modules/Wiki/README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Modules/Wiki/README.md b/Modules/Wiki/README.md index 1f2144400113..231d1fbe4efa 100644 --- a/Modules/Wiki/README.md +++ b/Modules/Wiki/README.md @@ -1,13 +1,15 @@ # Wiki -## Business Rules - -### Print View +## Print View - The print process uses a modal to select the printed pages, see https://docu.ilias.de/goto_docu_wiki_wpage_6995_1357.html - The print view opens in a separate tab, see https://mantis.ilias.de/view.php?id=20653 -### Notifications +## Notifications - Notifications can be activated for the whole wiki or for single wiki pages. -- After a notification for a page change has been sent, ILIAS does not sent additional notifications for the same page for the next 3 hours (standard waiting time in notification service). \ No newline at end of file +- After a notification for a page change has been sent, ILIAS does not sent additional notifications for the same page for the next 3 hours (standard waiting time in notification service). + +## Page Overview + +- The overview block on top, container all headings, will render all formattings included in the headings to enable things like sub and sup or latex code. \ No newline at end of file From 82e909bd5a4d2be3bb641ff458afed2261d3e2e7 Mon Sep 17 00:00:00 2001 From: Alex Killing Date: Fri, 2 Aug 2024 15:42:47 +0200 Subject: [PATCH 11/61] 37390: Data not saved when adding internal links --- .../components/paragraph/actions/paragraph-action-types.js | 2 +- .../paragraph/actions/paragraph-editor-action-factory.js | 4 ++++ .../Editor/js/src/components/paragraph/ui/paragraph-ui.js | 6 ++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Services/COPage/Editor/js/src/components/paragraph/actions/paragraph-action-types.js b/Services/COPage/Editor/js/src/components/paragraph/actions/paragraph-action-types.js index 06a32e444f24..5f405f262beb 100644 --- a/Services/COPage/Editor/js/src/components/paragraph/actions/paragraph-action-types.js +++ b/Services/COPage/Editor/js/src/components/paragraph/actions/paragraph-action-types.js @@ -49,6 +49,7 @@ const ACTIONS = { LINK_INTERNAL: 'link.internal', LINK_EXTERNAL: 'link.external', LINK_USER: 'link.user', + LINK_ADDED: 'link.added', SAVE_RETURN: 'save.return', AUTO_SAVE: 'save.auto', AUTO_INSERT_POST: 'post.insert.auto', @@ -56,6 +57,5 @@ const ACTIONS = { SPLIT_PARAGRAPH: 'par.split', MERGE_PREVIOUS: 'merge.previous', SECTION_CLASS: 'sec.class', // section format - }; export default ACTIONS; diff --git a/Services/COPage/Editor/js/src/components/paragraph/actions/paragraph-editor-action-factory.js b/Services/COPage/Editor/js/src/components/paragraph/actions/paragraph-editor-action-factory.js index f8d261c00d42..8e2715f90d96 100644 --- a/Services/COPage/Editor/js/src/components/paragraph/actions/paragraph-editor-action-factory.js +++ b/Services/COPage/Editor/js/src/components/paragraph/actions/paragraph-editor-action-factory.js @@ -174,6 +174,10 @@ export default class ParagraphEditorActionFactory { return this.editorActionFactory.action(this.COMPONENT, ACTIONS.LINK_USER); } + linkAdded() { + return this.editorActionFactory.action(this.COMPONENT, ACTIONS.LINK_ADDED); + } + /** * @returns {EditorAction} */ diff --git a/Services/COPage/Editor/js/src/components/paragraph/ui/paragraph-ui.js b/Services/COPage/Editor/js/src/components/paragraph/ui/paragraph-ui.js index 2fd191dc19b5..66ea4a6a4f64 100644 --- a/Services/COPage/Editor/js/src/components/paragraph/ui/paragraph-ui.js +++ b/Services/COPage/Editor/js/src/components/paragraph/ui/paragraph-ui.js @@ -294,7 +294,10 @@ export default class ParagraphUI { } addIntLink(b, e, content) { + const dispatch = this.dispatcher; + const action = this.actionFactory; this.addBBCode(b, e, false, content); + dispatch.dispatch(action.paragraph().editor().linkAdded()); } cmdIntLink() { @@ -424,6 +427,9 @@ export default class ParagraphUI { const t = this; il.Wiki.Edit.openLinkDialog(url, this.getSelection(), (stag) => { t.addBBCode(stag, '', true); + const dispatch = t.dispatcher; + const action = t.actionFactory; + dispatch.dispatch(action.paragraph().editor().linkAdded()); }); } From 0cb2ee12aa6d90662cd76f79a55b7ffe548cb131 Mon Sep 17 00:00:00 2001 From: mjansen Date: Wed, 3 Apr 2024 16:37:05 +0200 Subject: [PATCH 12/61] WAC/Init: Provide a possible fix for Mantis 39817 See: https://mantis.ilias.de/view.php?id=39817 --- .../CmiXapi/classes/XapiProxy/DataService.php | 19 ++++--- .../Init/classes/class.ilInitialisation.php | 56 ++++++++++++------- .../classes/class.ilWebAccessChecker.php | 7 +-- 3 files changed, 50 insertions(+), 32 deletions(-) diff --git a/Modules/CmiXapi/classes/XapiProxy/DataService.php b/Modules/CmiXapi/classes/XapiProxy/DataService.php index 8306c6c4f865..2008d05966c1 100755 --- a/Modules/CmiXapi/classes/XapiProxy/DataService.php +++ b/Modules/CmiXapi/classes/XapiProxy/DataService.php @@ -1,7 +1,5 @@ getLogger('auth') ); @@ -1341,7 +1358,8 @@ protected static function initUser(): void self::initGlobal( "ilUser", new ilObjUser(ANONYMOUS_USER_ID), - "./Services/User/classes/class.ilObjUser.php" + "./Services/User/classes/class.ilObjUser.php", + true ); $ilias->account = $ilUser; diff --git a/Services/WebAccessChecker/classes/class.ilWebAccessChecker.php b/Services/WebAccessChecker/classes/class.ilWebAccessChecker.php index 3c8c9b3b2233..7e630b73f9b0 100644 --- a/Services/WebAccessChecker/classes/class.ilWebAccessChecker.php +++ b/Services/WebAccessChecker/classes/class.ilWebAccessChecker.php @@ -1,4 +1,5 @@ init(); $ilAuthSession->regenerateId(); $ilAuthSession->setUserId(ANONYMOUS_USER_ID); $ilAuthSession->setAuthenticated(false, ANONYMOUS_USER_ID); From 06e6bd9bb2301b5ce66a3258b7444362805739f1 Mon Sep 17 00:00:00 2001 From: mjansen Date: Fri, 14 Jun 2024 11:39:38 +0200 Subject: [PATCH 13/61] LDAP: Handle internal PHP errors in `ilLDAPQuery` See: https://mantis.ilias.de/view.php?id=38111 --- Services/LDAP/classes/class.ilLDAPQuery.php | 91 +++++++++++++++----- Services/LDAP/classes/class.ilLDAPResult.php | 44 ++++------ 2 files changed, 84 insertions(+), 51 deletions(-) diff --git a/Services/LDAP/classes/class.ilLDAPQuery.php b/Services/LDAP/classes/class.ilLDAPQuery.php index 056e7d9b2e8d..31e09b58d95d 100644 --- a/Services/LDAP/classes/class.ilLDAPQuery.php +++ b/Services/LDAP/classes/class.ilLDAPQuery.php @@ -43,10 +43,9 @@ class ilLDAPQuery private array $users = []; /** - * LDAP Handle - * @var resource + * @var false|resource|\LDAP\Connection */ - private $lh; + private $lh = false; /** * @throws ilLDAPQueryException @@ -541,29 +540,77 @@ private function readUserData(string $a_name, bool $a_check_dn = false, bool $a_ * IL_SCOPE_SUB => ldap_search * IL_SCOPE_ONE => ldap_list * @param array|null $controls LDAP Control to be passed on the the ldap functions - * @return resource|null + * @return null|false|resource|list<\LDAP\Result>|\LDAP\Result */ - private function queryByScope(int $a_scope, string $a_base_dn, string $a_filter, array $a_attributes, array $controls = null) - { + private function queryByScope( + int $a_scope, + string $a_base_dn, + string $a_filter, + array $a_attributes, + array $controls = null + ) { $a_filter = $a_filter ?: "(objectclass=*)"; - switch ($a_scope) { - case ilLDAPServer::LDAP_SCOPE_SUB: - $res = ldap_search($this->lh, $a_base_dn, $a_filter, $a_attributes, 0, 0, 0, LDAP_DEREF_NEVER, $controls); - break; + set_error_handler(static function (int $severity, string $message, string $file, int $line): void { + throw new ErrorException($message, $severity, $severity, $file, $line); + }); - case ilLDAPServer::LDAP_SCOPE_ONE: - $res = ldap_list($this->lh, $a_base_dn, $a_filter, $a_attributes, 0, 0, 0, LDAP_DEREF_NEVER, $controls); - break; - - case ilLDAPServer::LDAP_SCOPE_BASE: - $res = ldap_read($this->lh, $a_base_dn, $a_filter, $a_attributes, 0, 0, 0, LDAP_DEREF_NEVER, $controls); - break; + $result = null; // We should ensure the similar behaviour of using the @ operator in PHP < 8.x - default: - throw new ilLDAPUndefinedScopeException( - "Undefined LDAP Search Scope: " . $a_scope - ); + try { + switch ($a_scope) { + case ilLDAPServer::LDAP_SCOPE_SUB: + $result = ldap_search( + $this->lh, + $a_base_dn, + $a_filter, + $a_attributes, + 0, + 0, + 0, + LDAP_DEREF_NEVER, + $controls + ); + break; + + case ilLDAPServer::LDAP_SCOPE_ONE: + $result = ldap_list( + $this->lh, + $a_base_dn, + $a_filter, + $a_attributes, + 0, + 0, + 0, + LDAP_DEREF_NEVER, + $controls + ); + break; + + case ilLDAPServer::LDAP_SCOPE_BASE: + $result = ldap_read( + $this->lh, + $a_base_dn, + $a_filter, + $a_attributes, + 0, + 0, + 0, + LDAP_DEREF_NEVER, + $controls + ); + break; + + default: + throw new ilLDAPUndefinedScopeException( + "Undefined LDAP Search Scope: " . $a_scope + ); + } + } catch (ErrorException $e) { + $this->logger->warning($e->getMessage()); + $this->logger->warning($e->getTraceAsString()); + } finally { + restore_error_handler(); } $error = ldap_errno($this->lh); @@ -573,7 +620,7 @@ private function queryByScope(int $a_scope, string $a_base_dn, string $a_filter, $this->logger->warning('Filter: ' . $a_filter); } - return $res ?? null; + return $result; } /** diff --git a/Services/LDAP/classes/class.ilLDAPResult.php b/Services/LDAP/classes/class.ilLDAPResult.php index c335bcf6f9cb..4e4a92fb67da 100644 --- a/Services/LDAP/classes/class.ilLDAPResult.php +++ b/Services/LDAP/classes/class.ilLDAPResult.php @@ -26,53 +26,42 @@ class ilLDAPResult { /** - * @var resource + * @var resource|\Ldap\Connection */ private $handle; /** - * @var resource + * @var null|resource|list<\Ldap\Result>|\Ldap\Result */ - private $result; + private $result = null; private array $rows = []; private ?array $last_row; /** - * ilLDAPPagedResult constructor. - * @param resource $a_ldap_handle from ldap_connect() - * @param resource $a_result from ldap_search() + * @param resource|\Ldap\Connection $a_ldap_handle from ldap_connect() + * @param null|false|resource|list<\Ldap\Result>|\Ldap\Result $a_result from ldap_search(), ldap_list() or ldap_read() */ public function __construct($a_ldap_handle, $a_result = null) { $this->handle = $a_ldap_handle; - if ($a_result !== null) { + if ($a_result !== null && $a_result !== false) { $this->result = $a_result; } } /** * Total count of resulted rows - * @return int */ public function numRows(): int { - return is_array($this->rows) ? count($this->rows) : 0; + return count($this->rows); } /** * Resource from ldap_search() - * @return resource - */ - public function getResult() - { - return $this->result; - } - - /** - * Resource from ldap_search() - * @param resource $result + * @param false|resource|list<\Ldap\Result>|\Ldap\Result $result */ public function setResult($result): void { @@ -93,7 +82,7 @@ public function get(): array */ public function getRows(): array { - return is_array($this->rows) ? $this->rows : []; + return $this->rows; } /** @@ -102,8 +91,10 @@ public function getRows(): array */ public function run(): self { - $entries = ldap_get_entries($this->handle, $this->result); - $this->addEntriesToRows($entries); + if ($this->result) { + $entries = ldap_get_entries($this->handle, $this->result); + $this->addEntriesToRows($entries); + } return $this; } @@ -118,8 +109,7 @@ private function addEntriesToRows(array $entries): void return; } - - for ($row_counter = 0; $row_counter < $num;$row_counter++) { + for ($row_counter = 0; $row_counter < $num; $row_counter++) { $data = $this->toSimpleArray($entries[$row_counter]); $this->rows[] = $data; $this->last_row = $data; @@ -129,10 +119,9 @@ private function addEntriesToRows(array $entries): void /** * Transforms results from ldap_get_entries() to a simple format */ - private function toSimpleArray(array $entry): array { - $data = array(); + $data = []; foreach ($entry as $key => $value) { if (is_int($key)) { continue; @@ -159,9 +148,6 @@ private function toSimpleArray(array $entry): array return $data; } - /** - * Destructor - */ public function __destruct() { if ($this->result) { From 7a75657d2fc9d1f0881f640b4f678e4478297a1c Mon Sep 17 00:00:00 2001 From: Fabian Helfer Date: Fri, 2 Aug 2024 13:38:51 +0200 Subject: [PATCH 14/61] Sprachvariable sort_by_posts --- lang/ilias_de.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index b3f37dcae4e5..2ab4d1010752 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -10089,7 +10089,7 @@ forum#:#selected_threads_closed#:#Das Thema wurde geschlossen. forum#:#selected_threads_reopened#:#Das Thema wurde wiedereröffnet. forum#:#sort_by_date#:#Nach Datum sortieren forum#:#sort_by_date_desc#:#Das Thema wird in flacher Ansicht präsentiert. Die Beiträge werden in der zeitlichen Reihenfolge der Erstellung gezeigt. -forum#:#sort_by_posts#:#Nach Beiträge sortieren +forum#:#sort_by_posts#:#Nach Beiträgen sortieren forum#:#sort_by_posts_desc#:#Das Thema wird in einer Baumansicht präsentiert. Antworten auf Beiträge werden in der Reihenfolge gezeigt, in der sie sich aufeinander beziehen. forum#:#sorting#:#Sortierung forum#:#sticky#:#'Top-Thema' From b15a21e99d524c729b59308cf80d2746d398f1fc Mon Sep 17 00:00:00 2001 From: fneumann Date: Wed, 24 Jul 2024 10:50:57 +0200 Subject: [PATCH 15/61] Registration: Fix Unable to access Registration Codes Mantis: https://mantis.ilias.de/view.php?id=41640 --- .../Registration/classes/class.ilRegistrationCodesTableGUI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Services/Registration/classes/class.ilRegistrationCodesTableGUI.php b/Services/Registration/classes/class.ilRegistrationCodesTableGUI.php index 42fc44bca9ae..a2ed15503bb3 100644 --- a/Services/Registration/classes/class.ilRegistrationCodesTableGUI.php +++ b/Services/Registration/classes/class.ilRegistrationCodesTableGUI.php @@ -135,7 +135,7 @@ private function getItems(): void } if ($code["role"]) { - $result[$k]["role"] = $this->role_map[$code["role"]]; + $result[$k]["role"] = $this->role_map[$code["role"]] ?? $this->lng->txt('deleted'); } else { $result[$k]["role"] = ""; } From e32779b97b51d75cb77d70afa5ff9c3714d8285e Mon Sep 17 00:00:00 2001 From: Marvin Beym Date: Thu, 18 Jul 2024 11:22:28 +0200 Subject: [PATCH 16/61] Move ilias_copa_5_4.xsd file to correct folder and adapt to current Schema style --- xml/SchemaValidation/ilias_copa_5_4.xsd | 27 +++++++++++++++++++++++ xml/ilias_copa_5_4.xsd | 29 ------------------------- 2 files changed, 27 insertions(+), 29 deletions(-) create mode 100644 xml/SchemaValidation/ilias_copa_5_4.xsd delete mode 100644 xml/ilias_copa_5_4.xsd diff --git a/xml/SchemaValidation/ilias_copa_5_4.xsd b/xml/SchemaValidation/ilias_copa_5_4.xsd new file mode 100644 index 000000000000..d111259a1bce --- /dev/null +++ b/xml/SchemaValidation/ilias_copa_5_4.xsd @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xml/ilias_copa_5_4.xsd b/xml/ilias_copa_5_4.xsd deleted file mode 100644 index 092507af0f26..000000000000 --- a/xml/ilias_copa_5_4.xsd +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 573b6fcfe87585e856a4cb392a4429209ea4b5d0 Mon Sep 17 00:00:00 2001 From: Marvin Beym Date: Thu, 18 Jul 2024 11:22:44 +0200 Subject: [PATCH 17/61] Check for style-id set for older imported contentpage --- Modules/ContentPage/classes/class.ilContentPageDataSet.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/ContentPage/classes/class.ilContentPageDataSet.php b/Modules/ContentPage/classes/class.ilContentPageDataSet.php index e343a73c962e..ec5147f894d1 100644 --- a/Modules/ContentPage/classes/class.ilContentPageDataSet.php +++ b/Modules/ContentPage/classes/class.ilContentPageDataSet.php @@ -132,6 +132,10 @@ public function importRecord( self::$style_map[(int) $a_rec['Style']][] = $newObject->getId(); } + if ($a_rec['style-id'] ?? false) { + self::$style_map[(int) $a_rec['style-id']][] = $newObject->getId(); + } + ilContainer::_writeContainerSetting( $newObject->getId(), ilObjectServiceSettingsGUI::INFO_TAB_VISIBILITY, From b0a3c5e73b08b13c83fde0366c601fd2cf5d3057 Mon Sep 17 00:00:00 2001 From: Marvin Beym Date: Thu, 18 Jul 2024 11:49:30 +0200 Subject: [PATCH 18/61] Fiy code style --- Modules/ContentPage/classes/class.ilContentPageDataSet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/ContentPage/classes/class.ilContentPageDataSet.php b/Modules/ContentPage/classes/class.ilContentPageDataSet.php index ec5147f894d1..c573b6697763 100644 --- a/Modules/ContentPage/classes/class.ilContentPageDataSet.php +++ b/Modules/ContentPage/classes/class.ilContentPageDataSet.php @@ -175,7 +175,7 @@ public function getXmlRecord( return $a_set; } - + return parent::getXmlRecord($a_entity, $a_version, $a_set); } } From 28b5701d80f4d147de9cb0feb6fe902fedd9f7d8 Mon Sep 17 00:00:00 2001 From: Vincenzo Padula Date: Mon, 5 Aug 2024 09:44:20 +0200 Subject: [PATCH 19/61] Fix skin path in html exports (#7836) (cherry picked from commit 17ce70f79b82d5734829a08fc2b940f0635f9873) --- .../Style/System/classes/class.ilSystemStyleHTMLExport.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Services/Style/System/classes/class.ilSystemStyleHTMLExport.php b/Services/Style/System/classes/class.ilSystemStyleHTMLExport.php index 7baeab2977d1..6948adc5448c 100644 --- a/Services/Style/System/classes/class.ilSystemStyleHTMLExport.php +++ b/Services/Style/System/classes/class.ilSystemStyleHTMLExport.php @@ -74,10 +74,14 @@ public function addImage(string $a_file, string $a_exp_file_name = ''): void public function export(): void { + $location_stylesheet = ilUtil::getStyleSheetLocation('filesystem'); + + // Fix skin path + $this->style_dir = dirname($this->style_dir, 2) . DIRECTORY_SEPARATOR . dirname($location_stylesheet); + $this->createDirectories(); // export system style sheet - $location_stylesheet = ilUtil::getStyleSheetLocation('filesystem'); $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator(dirname($location_stylesheet), FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST From 9243651431bb85fa504a63e856075ea96249964f Mon Sep 17 00:00:00 2001 From: Luka Stocker <67695434+lukastocker@users.noreply.github.com> Date: Mon, 5 Aug 2024 10:53:33 +0200 Subject: [PATCH 20/61] UI: disable displaying divider label in sub-menu lists if placed in main-menu. (#41666) (#7848) https://mantis.ilias.de/view.php?id=41666 --- .../UI-framework/Divider/_ui-component_divider.scss | 2 +- .../UI-framework/Menu/_ui-component_drilldown.scss | 3 ++- templates/default/delos.css | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/templates/default/070-components/UI-framework/Divider/_ui-component_divider.scss b/templates/default/070-components/UI-framework/Divider/_ui-component_divider.scss index 34beb574447a..af5f7ed09b12 100644 --- a/templates/default/070-components/UI-framework/Divider/_ui-component_divider.scss +++ b/templates/default/070-components/UI-framework/Divider/_ui-component_divider.scss @@ -8,7 +8,7 @@ $il-divider-bg: $il-main-bg; $il-divider-color: $il-text-color; $il-divider-color: $il-text-color; -h4.il-divider { +.engaged ~ ul > li > h4.il-divider { padding: $il-padding-small-vertical $il-padding-small-horizontal; margin-bottom: 0px; background-color: $il-divider-bg; diff --git a/templates/default/070-components/UI-framework/Menu/_ui-component_drilldown.scss b/templates/default/070-components/UI-framework/Menu/_ui-component_drilldown.scss index 6d9f4d6698f4..6b70ad9fd048 100644 --- a/templates/default/070-components/UI-framework/Menu/_ui-component_drilldown.scss +++ b/templates/default/070-components/UI-framework/Menu/_ui-component_drilldown.scss @@ -68,7 +68,8 @@ $il-drilldown-left-indent: l.$il-padding-large-horizontal + s-symbol.$il-icon-si li > .menulevel, li > .btn-bulky, li > .link-bulky, - li > hr { + li > hr, + li > h4.il-divider { display: none; } .engaged ~ ul > li > .menulevel, diff --git a/templates/default/delos.css b/templates/default/delos.css index 5c1f8519c7bc..893fd033c644 100644 --- a/templates/default/delos.css +++ b/templates/default/delos.css @@ -3838,7 +3838,7 @@ button .minimize, button .close { display: flex; } -h4.il-divider { +.engaged ~ ul > li > h4.il-divider { padding: 3px 6px; margin-bottom: 0px; background-color: white; @@ -6547,7 +6547,8 @@ footer { .il-drilldown li > .menulevel, .il-drilldown li > .btn-bulky, .il-drilldown li > .link-bulky, -.il-drilldown li > hr { +.il-drilldown li > hr, +.il-drilldown li > h4.il-divider { display: none; } .il-drilldown .engaged ~ ul > li > .menulevel, From 0c7321ce95c715fb68916f0f30a49e7030852b19 Mon Sep 17 00:00:00 2001 From: Luka Stocker <67695434+lukastocker@users.noreply.github.com> Date: Mon, 5 Aug 2024 10:54:33 +0200 Subject: [PATCH 21/61] UI: set min-width to max-content for dropdowns. (#39053) (#7850) * UI: set min-width to max-content for dropdowns. (#39053) https://mantis.ilias.de/view.php?id=39053 * MEM & PRG: remove actions dropdown label from members table. (#39053) https://mantis.ilias.de/view.php?id=39053 --- .../classes/class.ilStudyProgrammeMembersTableGUI.php | 2 +- .../Membership/classes/class.ilParticipantTableGUI.php | 7 +++---- .../UI-framework/Dropdown/_ui-component_dropdown.scss | 1 + templates/default/delos.css | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Modules/StudyProgramme/classes/class.ilStudyProgrammeMembersTableGUI.php b/Modules/StudyProgramme/classes/class.ilStudyProgrammeMembersTableGUI.php index 51bd5033ea3d..9b8f367ff0be 100644 --- a/Modules/StudyProgramme/classes/class.ilStudyProgrammeMembersTableGUI.php +++ b/Modules/StudyProgramme/classes/class.ilStudyProgrammeMembersTableGUI.php @@ -303,7 +303,7 @@ protected function buildActionDropDown( $l[] = $this->ui_factory->button()->shy($this->lng->txt("prg_$action"), $target); } return $this->ui_renderer->render( - $this->ui_factory->dropdown()->standard($l)->withLabel($this->lng->txt('actions')) + $this->ui_factory->dropdown()->standard($l) ); } diff --git a/Services/Membership/classes/class.ilParticipantTableGUI.php b/Services/Membership/classes/class.ilParticipantTableGUI.php index 6aef4c911053..8c1aeed73407 100644 --- a/Services/Membership/classes/class.ilParticipantTableGUI.php +++ b/Services/Membership/classes/class.ilParticipantTableGUI.php @@ -1,7 +1,5 @@ uiFactory->dropdown()->standard($dropDownItems) - ->withLabel($this->lng->txt('actions')); + $dropDown = $this->uiFactory->dropdown()->standard($dropDownItems); $this->tpl->setVariable('ACTION_USER', $this->renderer->render($dropDown)); } } diff --git a/templates/default/070-components/UI-framework/Dropdown/_ui-component_dropdown.scss b/templates/default/070-components/UI-framework/Dropdown/_ui-component_dropdown.scss index ce0556ae6d3c..50ce59e2245c 100644 --- a/templates/default/070-components/UI-framework/Dropdown/_ui-component_dropdown.scss +++ b/templates/default/070-components/UI-framework/Dropdown/_ui-component_dropdown.scss @@ -63,6 +63,7 @@ $cursor-disabled: not-allowed !default; .dropdown { position: relative; display: inline-block; // so dropdown can be in one line with a button + min-width: max-content; } // The dropdown menu (ul) diff --git a/templates/default/delos.css b/templates/default/delos.css index 893fd033c644..3f9c4b6f5856 100644 --- a/templates/default/delos.css +++ b/templates/default/delos.css @@ -386,6 +386,7 @@ .dropdown { position: relative; display: inline-block; + min-width: max-content; } .dropdown-menu { From 8eac224488720f086696ff57c9a8c3b0096fbb3c Mon Sep 17 00:00:00 2001 From: iszmais Date: Thu, 25 Jul 2024 18:00:22 +0200 Subject: [PATCH 22/61] Prevent calling of undefined constants --- Modules/File/classes/class.ilObjFileStakeholder.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/File/classes/class.ilObjFileStakeholder.php b/Modules/File/classes/class.ilObjFileStakeholder.php index d0f6593162a0..7db2fde73b27 100644 --- a/Modules/File/classes/class.ilObjFileStakeholder.php +++ b/Modules/File/classes/class.ilObjFileStakeholder.php @@ -1,4 +1,5 @@ current_user = (int) ($DIC->isDependencyAvailable('user') ? $DIC->user()->getId() : ANONYMOUS_USER_ID); + $this->current_user = (int) ($DIC->isDependencyAvailable('user') ? $DIC->user()->getId() : 13); } /** From eca55172dc6a53f2980fe30b0a818730909145b2 Mon Sep 17 00:00:00 2001 From: iszmais <45942348+iszmais@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:15:50 +0200 Subject: [PATCH 23/61] catch old permalinks (#7890) --- .../classes/class.ilObjDataCollectionGUI.php | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Modules/DataCollection/classes/class.ilObjDataCollectionGUI.php b/Modules/DataCollection/classes/class.ilObjDataCollectionGUI.php index 375de51ab105..0d8c834174aa 100644 --- a/Modules/DataCollection/classes/class.ilObjDataCollectionGUI.php +++ b/Modules/DataCollection/classes/class.ilObjDataCollectionGUI.php @@ -350,21 +350,30 @@ public static function _goto(string $a_target): void $access = $DIC->access(); $tpl = $DIC->ui()->mainTemplate(); + $params = explode("_", $a_target); + //41821: Handles old permanent links. This is deprecated and removed for ILIAS 10 + if (count($params) > 1) { + $goto_string = explode('/', $DIC->http()->request()->getRequestTarget()); + if(str_contains(end($goto_string), 'dcl_')) { + $view = new ilDclTableView((int) $params[1]); + $params = [$params[0], $view->getTableId(), $params[1] ?? null, $params[2] ?? null]; + } + } $values = [self::GET_REF_ID, self::GET_TABLE_ID, self::GET_VIEW_ID, self::GET_RECORD_ID]; - $values = array_combine($values, array_pad(explode("_", $a_target), count($values), null)); + $values = array_combine($values, array_pad($params, count($values), null)); $ref_id = (int) $values[self::GET_REF_ID]; //load record list if ($access->checkAccess('read', "", $ref_id)) { $ilCtrl->setParameterByClass(ilRepositoryGUI::class, self::GET_REF_ID, $ref_id); - if ($values['table_id'] !== null) { - $ilCtrl->setParameterByClass(ilObjDataCollectionGUI::class, self::GET_TABLE_ID, $values['table_id']); - if ($values['tableview_id'] !== null) { - $ilCtrl->setParameterByClass(ilObjDataCollectionGUI::class, self::GET_VIEW_ID, $values['tableview_id']); + if ($values[self::GET_TABLE_ID] !== null) { + $ilCtrl->setParameterByClass(ilObjDataCollectionGUI::class, self::GET_TABLE_ID, $values[self::GET_TABLE_ID]); + if ($values[self::GET_VIEW_ID] !== null) { + $ilCtrl->setParameterByClass(ilObjDataCollectionGUI::class, self::GET_VIEW_ID, $values[self::GET_VIEW_ID]); } - if ($values['record_id'] !== null) { - $ilCtrl->setParameterByClass(ilDclDetailedViewGUI::class, self::GET_RECORD_ID, $values['record_id']); + if ($values[self::GET_RECORD_ID] !== null) { + $ilCtrl->setParameterByClass(ilDclDetailedViewGUI::class, self::GET_RECORD_ID, $values[self::GET_RECORD_ID]); $ilCtrl->redirectByClass([ilRepositoryGUI::class, self::class, ilDclDetailedViewGUI::class], "renderRecord"); } } From f68d9c9030099f0ae523da9857ec7386de3ed6ca Mon Sep 17 00:00:00 2001 From: mjansen Date: Mon, 5 Aug 2024 13:56:24 +0200 Subject: [PATCH 24/61] Chatroom: Fix blank page on installation status page See: https://mantis.ilias.de/view.php?id=41839 --- ...ss.ilChatroomMetricsCollectedObjective.php | 113 +++++++++--------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/Modules/Chatroom/classes/Setup/class.ilChatroomMetricsCollectedObjective.php b/Modules/Chatroom/classes/Setup/class.ilChatroomMetricsCollectedObjective.php index 6b4398e8b9fa..bd08849f5ce6 100644 --- a/Modules/Chatroom/classes/Setup/class.ilChatroomMetricsCollectedObjective.php +++ b/Modules/Chatroom/classes/Setup/class.ilChatroomMetricsCollectedObjective.php @@ -28,7 +28,7 @@ protected function getTentativePreconditions(Setup\Environment $environment): ar return [ new ilIniFilesLoadedObjective(), new ilDatabaseInitializedObjective(), - new ilFileSystemComponentDataDirectoryCreatedObjective("chatroom") + new ilFileSystemComponentDataDirectoryCreatedObjective('chatroom') ]; } @@ -40,10 +40,10 @@ protected function collectFrom(Setup\Environment $environment, Setup\Metrics\Sto // sub components of the various readers to run. This is a memento to the // fact, that dependency injection is something we want. Currently, every // component could just service locate the whole world via the global $DIC. - $DIC = $GLOBALS["DIC"]; - $GLOBALS["DIC"] = new DI\Container(); - $GLOBALS["DIC"]["ilDB"] = $db; - $GLOBALS["DIC"]["ilBench"] = null; + $DIC = $GLOBALS['DIC']; + $GLOBALS['DIC'] = new DI\Container(); + $GLOBALS['DIC']['ilDB'] = $db; + $GLOBALS['DIC']['ilBench'] = null; $chatAdministrations = ilObject::_getObjectsByType('chta'); $chatAdministration = current($chatAdministrations); @@ -53,123 +53,123 @@ protected function collectFrom(Setup\Environment $environment, Setup\Metrics\Sto if (count($settings) > 0) { $storage->storeConfigText( - "address", - $settings['address'] ?? "", - "IP-Address/FQN of Chat Server." + 'address', + $settings['address'] ?? '', + 'IP-Address/FQN of Chat Server.' ); $storage->storeConfigText( - "port", - (string) ($settings['port'] ?? ""), - "Port of the chat server." + 'port', + (string) ($settings['port'] ?? ''), + 'Port of the chat server.' ); $storage->storeConfigText( - "sub_directory", - $settings['sub_directory'] ?? "", - "http(s)://[IP/Domain]/[SUB_DIRECTORY]" + 'sub_directory', + $settings['sub_directory'] ?? '', + 'http(s)://[IP/Domain]/[SUB_DIRECTORY]' ); $storage->storeConfigText( - "protocol", - $settings['protocol'] ?? "", - "Protocol used for connection (http/https)." + 'protocol', + $settings['protocol'] ?? '', + 'Protocol used for connection (http/https).' ); - if ($settings['protocol'] === 'https') { + if (isset($settings['protocol']) && $settings['protocol'] === 'https') { $cert = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_TEXT, - $settings['cert'] ?? "" + $settings['cert'] ?? '' ); $key = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_TEXT, - $settings['key'] ?? "" + $settings['key'] ?? '' ); $dhparam = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_TEXT, - $settings['dhparam'] ?? "" + $settings['dhparam'] ?? '' ); $https = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_COLLECTION, [ - "cert" => $cert, - "key" => $key, - "dhparam" => $dhparam, + 'cert' => $cert, + 'key' => $key, + 'dhparam' => $dhparam, ], - "Holds parameters for https." + 'Holds parameters for https.' ); - $storage->store("https", $https); + $storage->store('https', $https); } $storage->storeConfigText( - "log", + 'log', (string) ($settings['log'] ?? ''), "Absolute server path to the chat server's log file." ); $storage->storeConfigText( - "log_level", - $settings['log_level'] ?? "", - "Possible values are emerg, alert, crit error, warning, notice, info, debug, silly." + 'log_level', + $settings['log_level'] ?? '', + 'Possible values are emerg, alert, crit error, warning, notice, info, debug, silly.' ); $storage->storeConfigText( - "error_log", - $settings['error_log'] ?? "", + 'error_log', + $settings['error_log'] ?? '', "Absolute server path to the chat server's error log file." ); - if ($settings['ilias_proxy']) { + if (isset($settings['ilias_proxy']) && $settings['ilias_proxy']) { $ilias_url = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_TEXT, - $settings['ilias_url'] ?? "" + $settings['ilias_url'] ?? '' ); $ilias_proxy = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_COLLECTION, [ - "ilias_url" => $ilias_url + 'ilias_url' => $ilias_url ], - "Holds proxy url if ILIAS proxy is enabled." + 'Holds proxy url if ILIAS proxy is enabled.' ); - $storage->store("ilias_proxy", $ilias_proxy); + $storage->store('ilias_proxy', $ilias_proxy); } else { $storage->storeConfigBool( - "ilias_proxy", + 'ilias_proxy', false, - "Holds proxy url if ILIAS proxy is enabled." + 'Holds proxy url if ILIAS proxy is enabled.' ); } - if ($settings['client_proxy']) { + if (isset($settings['client_proxy']) && $settings['client_proxy']) { $client_url = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_TEXT, - $settings['client_url'] ?? "" + $settings['client_url'] ?? '' ); $client_proxy = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_COLLECTION, [ - "client_url" => $client_url + 'client_url' => $client_url ], - "Holds proxy url if client proxy is enabled." + 'Holds proxy url if client proxy is enabled.' ); - $storage->store("client_proxy", $client_proxy); + $storage->store('client_proxy', $client_proxy); } else { $storage->storeConfigBool( - "client_proxy", + 'client_proxy', false, - "Holds proxy url if client proxy is enabled." + 'Holds proxy url if client proxy is enabled.' ); } - if ($settings['deletion_mode']) { + if (isset($settings['deletion_mode']) && $settings['deletion_mode']) { $deletion_unit = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_TEXT, - $settings['deletion_unit'] ?? "" + $settings['deletion_unit'] ?? '' ); $deletion_value = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, @@ -179,22 +179,25 @@ protected function collectFrom(Setup\Environment $environment, Setup\Metrics\Sto $deletion_time = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_TEXT, - $settings['deletion_time'] ?? "" + $settings['deletion_time'] ?? '' ); $deletion_mode = new Setup\Metrics\Metric( Setup\Metrics\Metric::STABILITY_CONFIG, Setup\Metrics\Metric::TYPE_COLLECTION, [ - "deletion_unit" => $deletion_unit, - "deletion_value" => $deletion_value, - "deletion_time" => $deletion_time, + 'deletion_unit' => $deletion_unit, + 'deletion_value' => $deletion_value, + 'deletion_time' => $deletion_time, ], - "Holds information about deletion process." + 'Holds information about deletion process.' + ); + $storage->store( + 'deletion_mode', + $deletion_mode ); - $storage->store("deletion_mode", $deletion_mode); } } - $GLOBALS["DIC"] = $DIC; + $GLOBALS['DIC'] = $DIC; } } From 813d8978ec6029305a2d40b4a44ea8faa891f3eb Mon Sep 17 00:00:00 2001 From: Fabian Schmid Date: Mon, 5 Aug 2024 15:12:23 +0200 Subject: [PATCH 25/61] [IMPR] better handling of fallback delivery --- src/FileDelivery/Delivery/BaseDelivery.php | 3 ++- src/FileDelivery/Delivery/StreamDelivery.php | 10 +++++----- src/FileDelivery/Init.php | 15 ++++++++++++--- src/FileDelivery/Services.php | 1 + .../Setup/DeliveryMethodObjective.php | 9 ++++++++- src/ResourceStorage/Consumer/Consumers.php | 2 +- 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/FileDelivery/Delivery/BaseDelivery.php b/src/FileDelivery/Delivery/BaseDelivery.php index 27ac3dc1f5f1..f3b695128280 100644 --- a/src/FileDelivery/Delivery/BaseDelivery.php +++ b/src/FileDelivery/Delivery/BaseDelivery.php @@ -36,7 +36,8 @@ abstract class BaseDelivery public function __construct( protected \ILIAS\HTTP\Services $http, - protected ResponseBuilder $response_builder + protected ResponseBuilder $response_builder, + protected ResponseBuilder $fallback_response_builder, ) { if (is_readable(self::MIME_TYPE_MAP)) { $map = include self::MIME_TYPE_MAP; diff --git a/src/FileDelivery/Delivery/StreamDelivery.php b/src/FileDelivery/Delivery/StreamDelivery.php index 69e8a1df3d8a..eaa3b1e7fc0a 100644 --- a/src/FileDelivery/Delivery/StreamDelivery.php +++ b/src/FileDelivery/Delivery/StreamDelivery.php @@ -26,7 +26,6 @@ use ILIAS\Filesystem\Stream\FileStream; use ILIAS\FileDelivery\Token\Signer\Payload\FilePayload; use ILIAS\Filesystem\Stream\Streams; -use ILIAS\FileDelivery\Delivery\ResponseBuilder\PHPResponseBuilder; use ILIAS\FileDelivery\Token\Signer\Payload\ShortFilePayload; use ILIAS\Filesystem\Stream\ZIPStream; @@ -40,9 +39,10 @@ final class StreamDelivery extends BaseDelivery public function __construct( private DataSigner $data_signer, \ILIAS\HTTP\Services $http, - ResponseBuilder $response_builder + ResponseBuilder $response_builder, + ResponseBuilder $fallback_response_builder, ) { - parent::__construct($http, $response_builder); + parent::__construct($http, $response_builder, $fallback_response_builder); } /** @@ -100,7 +100,7 @@ public function deliver( $disposition ); if ($stream instanceof ZIPStream) { - $this->response_builder = new PHPResponseBuilder(); + $this->response_builder = $this->fallback_response_builder; } $r = $this->response_builder->buildForStream( @@ -173,7 +173,7 @@ public function deliverFromToken(string $token): never } // we must use PHPResponseBuilder here, because the streams inside zips cant be delivered using XSendFile or others - $this->response_builder = new PHPResponseBuilder(); + $this->response_builder = $this->fallback_response_builder; $mime_type = $this->determineMimeType($file_inside_zip_uri); $r = $this->setGeneralHeaders( diff --git a/src/FileDelivery/Init.php b/src/FileDelivery/Init.php index 57f9b539d6bb..d5c937f45a54 100644 --- a/src/FileDelivery/Init.php +++ b/src/FileDelivery/Init.php @@ -30,6 +30,7 @@ use ILIAS\FileDelivery\Delivery\ResponseBuilder\ResponseBuilder; use ILIAS\FileDelivery\Setup\DeliveryMethodObjective; use ILIAS\FileDelivery\Delivery\LegacyDelivery; +use ILIAS\FileDelivery\Delivery\ResponseBuilder\XAccelResponseBuilder; /** * @author Fabian Schmid @@ -39,9 +40,11 @@ class Init public static function init(Container $c): void { $c['file_delivery.response_builder'] = static function (): ResponseBuilder { - $settings = (require DeliveryMethodObjective::ARTIFACT) ?? []; + $settings = (@include DeliveryMethodObjective::ARTIFACT) ?? []; switch ($settings[DeliveryMethodObjective::SETTINGS] ?? null) { + case DeliveryMethodObjective::XACCEL: + return new XAccelResponseBuilder(); case DeliveryMethodObjective::XSENDFILE: return new XSendFileResponseBuilder(); case DeliveryMethodObjective::PHP: @@ -50,6 +53,10 @@ public static function init(Container $c): void } }; + $c['file_delivery.fallback_response_builder'] = static function (): ResponseBuilder { + return new PHPResponseBuilder(); + }; + $c['file_delivery.data_signer'] = static function (): DataSigner { $keys = array_map(static function (string $key): SecretKey { return new SecretKey($key); @@ -75,7 +82,8 @@ public static function init(Container $c): void return new \ILIAS\FileDelivery\Delivery\StreamDelivery( $c['file_delivery.data_signer'], $c['http'], - $c['file_delivery.response_builder'] + $c['file_delivery.response_builder'], + $c['file_delivery.fallback_response_builder'] ); }; @@ -88,7 +96,8 @@ public static function init(Container $c): void return new LegacyDelivery( $c['http'], - $c['file_delivery.response_builder'] + $c['file_delivery.response_builder'], + $c['file_delivery.fallback_response_builder'] ); }; diff --git a/src/FileDelivery/Services.php b/src/FileDelivery/Services.php index c5a5e91c2e6b..996197ed583b 100644 --- a/src/FileDelivery/Services.php +++ b/src/FileDelivery/Services.php @@ -58,6 +58,7 @@ public function buildTokenURL( int $valid_for_at_least_hours ): URI { // a new DateTimeImmutable which is set to the end of now + $valid_for_at_least_hours hours + $valid_for_at_least_hours++; $until = new \DateTimeImmutable( (new \DateTimeImmutable("now +$valid_for_at_least_hours hours"))->format('Y-m-d H:00') ); diff --git a/src/FileDelivery/Setup/DeliveryMethodObjective.php b/src/FileDelivery/Setup/DeliveryMethodObjective.php index 1e20e780fb87..093d133d7252 100644 --- a/src/FileDelivery/Setup/DeliveryMethodObjective.php +++ b/src/FileDelivery/Setup/DeliveryMethodObjective.php @@ -31,6 +31,7 @@ class DeliveryMethodObjective extends BuildArtifactObjective public const ARTIFACT = './src/FileDelivery/artifacts/delivery_method.php'; public const SETTINGS = 'delivery_method'; public const XSENDFILE = 'xsendfile'; + public const XACCEL = 'xaccel'; public const PHP = 'php'; public function getArtifactPath(): string @@ -60,7 +61,7 @@ private function isModXSendFileLoaded(): bool try { $command_exists = shell_exec("which apache2ctl"); - if ($command_exists === null) { + if ($command_exists === null || empty($command_exists)) { return false; } @@ -75,4 +76,10 @@ private function isModXSendFileLoaded(): bool } return false; } + + public function isApplicable(Setup\Environment $environment): bool + { + return !file_exists(self::ARTIFACT); + } + } diff --git a/src/ResourceStorage/Consumer/Consumers.php b/src/ResourceStorage/Consumer/Consumers.php index 18c63f35a189..7c42adc9cad9 100644 --- a/src/ResourceStorage/Consumer/Consumers.php +++ b/src/ResourceStorage/Consumer/Consumers.php @@ -38,7 +38,7 @@ class Consumers private ConsumerFactory $consumer_factory; private ResourceBuilder $resource_builder; private CollectionBuilder $collection_builder; - private ?SrcBuilder $src_builder = null; + private SrcBuilder $src_builder; /** * Consumers constructor. From 8a9f6220447b2e0ce5cea7577e60bb43bef0372e Mon Sep 17 00:00:00 2001 From: mjansen Date: Mon, 5 Aug 2024 15:22:27 +0200 Subject: [PATCH 26/61] Forum: Fix default ordering See: https://mantis.ilias.de/view.php?id=41725 --- Modules/Forum/classes/GUI/ThreadSortation.php | 60 +++++++ Modules/Forum/classes/class.ilObjForumGUI.php | 148 +++++++----------- 2 files changed, 114 insertions(+), 94 deletions(-) create mode 100644 Modules/Forum/classes/GUI/ThreadSortation.php diff --git a/Modules/Forum/classes/GUI/ThreadSortation.php b/Modules/Forum/classes/GUI/ThreadSortation.php new file mode 100644 index 000000000000..634fec8683e5 --- /dev/null +++ b/Modules/Forum/classes/GUI/ThreadSortation.php @@ -0,0 +1,60 @@ + 'forums_thread_sorting_asc', + self::SUBJECT_DESC => 'forums_thread_sorting_dsc', + self::LAST_POST_ASC => 'forums_last_posting_asc', + self::LAST_POST_DESC => 'forums_last_posting_dsc', + self::RATING_ASC => 'forums_rating_asc', + self::RATING_DESC => 'forums_rating_dsc', + }; + } + + public function field(): string + { + return match($this) { + self::SUBJECT_ASC, self::SUBJECT_DESC => 'thr_subject', + self::LAST_POST_ASC, self::LAST_POST_DESC => 'lp_date', + self::RATING_ASC, self::RATING_DESC => 'rating', + }; + } + + public function direction(): string + { + return match($this) { + self::SUBJECT_ASC, self::LAST_POST_ASC, self::RATING_ASC => 'asc', + self::SUBJECT_DESC, self::LAST_POST_DESC, self::RATING_DESC => 'desc', + }; + } +} diff --git a/Modules/Forum/classes/class.ilObjForumGUI.php b/Modules/Forum/classes/class.ilObjForumGUI.php index 0b79a6bb0f23..9df150db421d 100755 --- a/Modules/Forum/classes/class.ilObjForumGUI.php +++ b/Modules/Forum/classes/class.ilObjForumGUI.php @@ -23,22 +23,15 @@ use ILIAS\UI\Component\Button\Shy; use ILIAS\UI\Component\Dropdown\Standard; use ILIAS\UI\Component\Item\Item; -use ILIAS\UI\Component\Symbol\Avatar\Avatar; -use ILIAS\UI\Component\Modal\Interruptive; use ILIAS\UI\Component\Modal\RoundTrip; -use ILIAS\Data\Order; use ILIAS\UI\Component\Input\ViewControl\Sortation; /** - * Class ilObjForumGUI - * @author Stefan Meyer - * @author Nadia Matuschek * @ilCtrl_Calls ilObjForumGUI: ilPermissionGUI, ilForumExportGUI, ilInfoScreenGUI * @ilCtrl_Calls ilObjForumGUI: ilColumnGUI, ilPublicUserProfileGUI, ilForumModeratorsGUI, ilRepositoryObjectSearchGUI * @ilCtrl_Calls ilObjForumGUI: ilObjectCopyGUI, ilExportGUI, ilCommonActionDispatcherGUI, ilRatingGUI * @ilCtrl_Calls ilObjForumGUI: ilForumSettingsGUI, ilContainerNewsSettingsGUI, ilLearningProgressGUI, ilForumPageGUI * @ilCtrl_Calls ilObjForumGUI: ilObjectContentStyleSettingsGUI - * @ingroup ModulesForum */ class ilObjForumGUI extends ilObjectGUI implements ilDesktopItemHandling, ilForumObjectConstants, ilCtrlSecurityInterface { @@ -63,7 +56,7 @@ class ilObjForumGUI extends ilObjectGUI implements ilDesktopItemHandling, ilForu private bool $is_moderator; private ?ilPropertyFormGUI $replyEditForm = null; private bool $hideToolbar = false; - private $httpRequest; + private \Psr\Http\Message\ServerRequestInterface $httpRequest; private \ILIAS\HTTP\Services $http; private Factory $uiFactory; private Renderer $uiRenderer; @@ -85,7 +78,6 @@ class ilObjForumGUI extends ilObjectGUI implements ilDesktopItemHandling, ilForu protected \ILIAS\Style\Content\Object\ObjectFacade $content_style_domain; protected \ILIAS\Style\Content\GUIService $content_style_gui; private array $modal_collection = []; - protected int $thread_sortation = 1; public function __construct($data, int $id = 0, bool $call_by_reference = true, bool $prepare_output = true) { @@ -700,9 +692,6 @@ public function showThreadsObject(): void $this->getCenterColumnHTML(); } - /** - * @throws ilCtrlException - */ public function getContent(): string { if (!$this->access->checkAccess('read', '', $this->object->getRefId())) { @@ -785,10 +774,7 @@ public function getContent(): string return ''; } - /** - * @throws ilCtrlException - */ - protected function renderThreadOverview(ilForumThreadObjectTableGUI $tbl, ilForum $frm, ForumDto $frm_object): void + private function renderThreadOverview(ilForumThreadObjectTableGUI $tbl, ilForum $frm, ForumDto $frm_object): void { $data_objects = $tbl->setMapper($frm)->fetchDataAnReturnObject(); @@ -837,7 +823,6 @@ protected function renderThreadOverview(ilForumThreadObjectTableGUI $tbl, ilForu $normal_threads = $this->factory->item()->group('', $thread_group); } - $url = $this->http->request()->getRequestTarget(); $current_page = 0; if ($this->http->wrapper()->query()->has(ilForumProperties::PAGE_NAME_THREAD_OVERVIEW)) { @@ -847,12 +832,14 @@ protected function renderThreadOverview(ilForumThreadObjectTableGUI $tbl, ilForu ); } - $view_control = $this->getSortationViewControl(); - $view_control[] = $this->factory->viewControl()->pagination() - ->withTargetURL($url, ilForumProperties::PAGE_NAME_THREAD_OVERVIEW) - ->withTotalEntries($frm_object->getTopNumThreads()) - ->withPageSize(ilForumProperties::PAGE_SIZE_THREAD_OVERVIEW) - ->withCurrentPage($current_page); + $view_controls[] = $this->getSortationViewControl(); + $view_controls[] = $this->factory + ->viewControl() + ->pagination() + ->withTargetURL($url, ilForumProperties::PAGE_NAME_THREAD_OVERVIEW) + ->withTotalEntries($frm_object->getTopNumThreads()) + ->withPageSize(ilForumProperties::PAGE_SIZE_THREAD_OVERVIEW) + ->withCurrentPage($current_page); if ($found_threads === false) { $vc_container = $this->factory->panel()->listing()->standard( @@ -863,7 +850,7 @@ protected function renderThreadOverview(ilForumThreadObjectTableGUI $tbl, ilForu $vc_container = $this->factory->panel()->listing()->standard( $this->lng->txt('thread_overview'), [$top_threads, $normal_threads] - )->withViewControls($view_control); + )->withViewControls($view_controls); } $default_html = $this->renderer->render($vc_container); @@ -882,28 +869,33 @@ protected function renderThreadOverview(ilForumThreadObjectTableGUI $tbl, ilForu $this->tpl->setContent($forwarder->forward() . $default_html . $modals); } - - protected function getThreadSortation(): int + + private function getRequestedThreadSortation(): ?int { - if ($this->http->wrapper()->query()->has('thread_sortation')) { - $this->thread_sortation = $this->http->wrapper()->query()->retrieve('thread_sortation', $this->refinery->kindlyTo()->int()); - } - return $this->thread_sortation; + return $this->http->wrapper()->query()->retrieve( + 'thread_sortation', + $this->refinery->byTrying([ + $this->refinery->kindlyTo()->int(), + $this->refinery->always(null) + ]) + ); } - protected function getThreadOffset(): int + private function getRequestedThreadOffset(): int { - $offset = 0; - if ($this->http->wrapper()->query()->has('page')) { - $offset = $this->http->wrapper()->query()->retrieve('page', $this->refinery->kindlyTo()->int()); - } - return $offset; + return $this->http->wrapper()->query()->retrieve( + 'page', + $this->refinery->byTrying([ + $this->refinery->kindlyTo()->int(), + $this->refinery->always(0) + ]) + ); } - protected function initializeThreadOffsetAndLimit(ilForumThreadObjectTableGUI $tbl): void + private function initializeThreadOffsetAndLimit(ilForumThreadObjectTableGUI $tbl): void { $limit = ilForumProperties::PAGE_SIZE_THREAD_OVERVIEW; - $offset = $this->getThreadOffset() * $limit; + $offset = $this->getRequestedThreadOffset() * $limit; $tbl->setOffset($offset); $tbl->setLimit($limit); @@ -911,68 +903,40 @@ protected function initializeThreadOffsetAndLimit(ilForumThreadObjectTableGUI $t protected function initializeThreadSortation(ilForumThreadObjectTableGUI $tbl): void { - $sortation_value = $this->getThreadSortation(); - $sortation_options = [ - 1 => ['direction' => 'asc', 'field' => 'thr_subject'], - 2 => ['direction' => 'desc', 'field' => 'thr_subject'], - 3 => ['direction' => 'asc', 'field' => 'lp_date'], - 4 => ['direction' => 'desc', 'field' => 'lp_date'], - 5 => ['direction' => 'asc', 'field' => 'rating'], - 6 => ['direction' => 'desc', 'field' => 'rating'], - ]; - if (array_key_exists($sortation_value, $sortation_options)) { - $tbl->setOrderDirection($sortation_options[$sortation_value]['direction']); - $tbl->setOrderField($sortation_options[$sortation_value]['field']); - } else { - $tbl->setOrderDirection($sortation_options[1]['direction']); - $tbl->setOrderField($sortation_options[1]['field']); + $sortation = ThreadSortation::tryFrom( + $this->getRequestedThreadSortation() ?? ThreadSortation::DEFAULT_SORTATION->value + ); + if ($sortation === null) { + $sortation = ThreadSortation::DEFAULT_SORTATION; } + $tbl->setOrderDirection($sortation->direction()); + $tbl->setOrderField($sortation->field()); } - /** - * @return array - * @throws ilCtrlException - */ - protected function getSortationViewControl(): array - { - $view_controls = []; - $sortation = [ - 1 => 'forums_thread_sorting_asc', - 2 => 'forums_thread_sorting_dsc', - 3 => 'forums_last_posting_asc', - 4 => 'forums_last_posting_dsc', - 5 => 'forums_rating_asc', - 6 => 'forums_rating_dsc' - ]; - - $offset = $this->getThreadOffset(); + private function getSortationViewControl(): \ILIAS\UI\Component\ViewControl\Sortation + { + $offset = $this->getRequestedThreadOffset(); if ($offset > 0) { $this->ctrl->setParameter($this, 'page', $offset); } + $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId()); $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId()); - $base_url = $this->ctrl->getLinkTarget( - $this, - 'showThreads', - '' - ); - $translationKeys = []; - foreach ($sortation as $sortingConstantKey => $languageKey) { - $this->ctrl->setParameter($this, 'thread_sortation', $sortingConstantKey); + $base_url = $this->ctrl->getLinkTarget($this, 'showThreads'); - $url = $this->ctrl->getLinkTarget( - $this, - 'showThreads', - '' - ); - $translationKeys[$url] = $this->lng->txt($languageKey); + $translationKeys = []; + foreach (ThreadSortation::cases() as $sortation) { + $this->ctrl->setParameter($this, 'thread_sortation', $sortation->value); + $url = $this->ctrl->getLinkTarget($this, 'showThreads'); - $this->ctrl->clearParameters($this); + $translationKeys[$url] = $this->lng->txt($sortation->languageId()); } - $view_controls[] = $this->factory->viewControl()->sortation( - $translationKeys - )->withTargetURL($base_url, 'thread_sortation'); - return $view_controls; + $this->ctrl->clearParameters($this); + + return $this->factory + ->viewControl() + ->sortation($translationKeys) + ->withTargetURL($base_url, 'thread_sortation'); } /** @@ -1000,7 +964,6 @@ private function retrieveThreadIds(): array /** * @return array - * @throws ilCtrlException */ protected function getThreadProperties(ilForumTopic $forum_topic): array { @@ -1059,10 +1022,7 @@ protected function getLinkActionForThread(int $ref_id, string $title, string $cm return $f->button()->shy($title, $url); } - /** - * @throws ilCtrlException - */ - protected function getActionsForThreadOverview(int $ref_id, ilForumTopic $forum_topic): Standard + private function getActionsForThreadOverview(int $ref_id, ilForumTopic $forum_topic): Standard { $f = $this->uiFactory; From d238f335dc8026220cb1689f14534474bc11929a Mon Sep 17 00:00:00 2001 From: mjansen Date: Mon, 5 Aug 2024 15:35:29 +0200 Subject: [PATCH 27/61] Forum: Fix code style --- Modules/Forum/classes/class.ilForumPost.php | 2 +- Modules/Forum/classes/class.ilForumPostDraft.php | 2 +- Modules/Forum/classes/class.ilForumXMLParser.php | 2 +- Modules/Forum/classes/class.ilObjForumGUI.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/Forum/classes/class.ilForumPost.php b/Modules/Forum/classes/class.ilForumPost.php index cf148530be16..01990f17e182 100644 --- a/Modules/Forum/classes/class.ilForumPost.php +++ b/Modules/Forum/classes/class.ilForumPost.php @@ -619,7 +619,7 @@ public function assignData(array $row): void $this->setDisplayUserId((int) $row['pos_display_user_id']); $this->setPosAuthorId((int) $row['pos_author_id']); $this->setIsAuthorModerator((bool) $row['is_author_moderator']); - $this->setRCID((string)($row['rcid'] ?? self::NO_RCID)); + $this->setRCID((string) ($row['rcid'] ?? self::NO_RCID)); } /** diff --git a/Modules/Forum/classes/class.ilForumPostDraft.php b/Modules/Forum/classes/class.ilForumPostDraft.php index 15d4c0d7b13d..d4c8b7fe51a5 100644 --- a/Modules/Forum/classes/class.ilForumPostDraft.php +++ b/Modules/Forum/classes/class.ilForumPostDraft.php @@ -79,7 +79,7 @@ protected static function populateWithDatabaseRecord(ilForumPostDraft $draft, ar $draft->setPostUserAlias((string) $row['post_user_alias']); $draft->setNotificationStatus((bool) $row['notify']); $draft->setPostNotificationStatus((bool) $row['post_notify']); - $draft->setRCID((string)($row['rcid'])); + $draft->setRCID((string) ($row['rcid'])); } public function getRCID(): string diff --git a/Modules/Forum/classes/class.ilForumXMLParser.php b/Modules/Forum/classes/class.ilForumXMLParser.php index 5f671d947977..acc0df02e8f5 100644 --- a/Modules/Forum/classes/class.ilForumXMLParser.php +++ b/Modules/Forum/classes/class.ilForumXMLParser.php @@ -599,7 +599,7 @@ public function handlerEndTag(XMLParser $a_xml_parser, string $a_name): void $import_path = $this->contentArray['content']; if ($import_path !== '') { $import_path = $this->getImportDirectory() . '/' . $import_path; - $filedata->importPath($import_path, (int)$this->lastHandledPostId); + $filedata->importPath($import_path, (int) $this->lastHandledPostId); } break; } diff --git a/Modules/Forum/classes/class.ilObjForumGUI.php b/Modules/Forum/classes/class.ilObjForumGUI.php index 9df150db421d..5b7a65ba5fa2 100755 --- a/Modules/Forum/classes/class.ilObjForumGUI.php +++ b/Modules/Forum/classes/class.ilObjForumGUI.php @@ -869,7 +869,7 @@ private function renderThreadOverview(ilForumThreadObjectTableGUI $tbl, ilForum $this->tpl->setContent($forwarder->forward() . $default_html . $modals); } - + private function getRequestedThreadSortation(): ?int { return $this->http->wrapper()->query()->retrieve( From 568ca4119e5a7b11037384deb623c5e92282781f Mon Sep 17 00:00:00 2001 From: Fabian Schmid Date: Mon, 5 Aug 2024 16:16:57 +0200 Subject: [PATCH 28/61] [FIX] 0041850: Unknown Adapter: migrate stops running --- ...class.ilGlobalCacheAllFlushedObjective.php | 11 ++-- ...ilGlobalCacheMetricsCollectedObjective.php | 64 ++++++++++--------- .../class.ilGlobalCacheSettingsAdapter.php | 43 ++++++++----- .../Init/classes/class.ilInitialisation.php | 2 +- src/Cache/Adaptor/Factory.php | 6 +- src/Cache/Services.php | 4 +- 6 files changed, 73 insertions(+), 57 deletions(-) diff --git a/Services/GlobalCache/classes/Setup/class.ilGlobalCacheAllFlushedObjective.php b/Services/GlobalCache/classes/Setup/class.ilGlobalCacheAllFlushedObjective.php index f93276297d43..eb46abf5dd06 100644 --- a/Services/GlobalCache/classes/Setup/class.ilGlobalCacheAllFlushedObjective.php +++ b/Services/GlobalCache/classes/Setup/class.ilGlobalCacheAllFlushedObjective.php @@ -17,6 +17,7 @@ *********************************************************************/ declare(strict_types=1); +use ILIAS\Setup\Environment; use ILIAS\Setup; use ILIAS\Cache\Services; @@ -42,21 +43,21 @@ public function isNotable(): bool return true; } - public function getPreconditions(Setup\Environment $environment): array + public function getPreconditions(Environment $environment): array { return [ new ilIniFilesLoadedObjective(), ]; } - public function achieve(Setup\Environment $environment): Setup\Environment + public function achieve(Environment $environment): Environment { - $client_ini = $environment->getResource(Setup\Environment::RESOURCE_CLIENT_INI); + $client_ini = $environment->getResource(Environment::RESOURCE_CLIENT_INI); if ($client_ini === null) { throw new UnexpectedValueException("Client ini not found"); } $this->cache_settings_adapter->readFromIniFile($client_ini); - $services = new Services($this->cache_settings_adapter->toConfig()); + $services = new Services($this->cache_settings_adapter->getConfig()); $services->flushAdapter(); return $environment; @@ -65,7 +66,7 @@ public function achieve(Setup\Environment $environment): Setup\Environment /** * @inheritDoc */ - public function isApplicable(Setup\Environment $environment): bool + public function isApplicable(Environment $environment): bool { return true; } diff --git a/Services/GlobalCache/classes/Setup/class.ilGlobalCacheMetricsCollectedObjective.php b/Services/GlobalCache/classes/Setup/class.ilGlobalCacheMetricsCollectedObjective.php index efa6da86cb34..63f2c5806175 100644 --- a/Services/GlobalCache/classes/Setup/class.ilGlobalCacheMetricsCollectedObjective.php +++ b/Services/GlobalCache/classes/Setup/class.ilGlobalCacheMetricsCollectedObjective.php @@ -16,12 +16,16 @@ * *********************************************************************/ +use ILIAS\Setup\Metrics\CollectedObjective; +use ILIAS\Setup\Environment; +use ILIAS\Setup\Metrics\Storage; +use ILIAS\Cache\Config; +use ILIAS\Setup\Metrics\Metric; use ILIAS\Setup; -use ILIAS\DI; -class ilGlobalCacheMetricsCollectedObjective extends Setup\Metrics\CollectedObjective +class ilGlobalCacheMetricsCollectedObjective extends CollectedObjective { - protected function getTentativePreconditions(Setup\Environment $environment): array + protected function getTentativePreconditions(Environment $environment): array { return [ new ilIniFilesLoadedObjective(), @@ -29,16 +33,16 @@ protected function getTentativePreconditions(Setup\Environment $environment): ar ]; } - protected function collectFrom(Setup\Environment $environment, Setup\Metrics\Storage $storage): void + protected function collectFrom(Environment $environment, Storage $storage): void { - $db = $environment->getResource(Setup\Environment::RESOURCE_DATABASE); - $client_ini = $environment->getResource(Setup\Environment::RESOURCE_CLIENT_INI); + $db = $environment->getResource(Environment::RESOURCE_DATABASE); + $client_ini = $environment->getResource(Environment::RESOURCE_CLIENT_INI); if (!$client_ini) { return; } - $config = (new ilGlobalCacheSettingsAdapter($client_ini, $db))->toConfig(); + $config = (new ilGlobalCacheSettingsAdapter($client_ini, $db))->getConfig(); $service = $config->getAdaptorName(); $storage->storeConfigText( @@ -53,30 +57,30 @@ protected function collectFrom(Setup\Environment $environment, Setup\Metrics\Sto $servers = $config->getNodes(); if ( - $service === ILIAS\Cache\Config::MEMCACHED && - count($servers) > 0 + $service === Config::MEMCACHED && + $servers !== [] ) { $server_collection = []; foreach ($servers as $server) { - $host = new Setup\Metrics\Metric( - Setup\Metrics\Metric::STABILITY_CONFIG, - Setup\Metrics\Metric::TYPE_TEXT, + $host = new Metric( + Metric::STABILITY_CONFIG, + Metric::TYPE_TEXT, $server->getHost() ); - $port = new Setup\Metrics\Metric( - Setup\Metrics\Metric::STABILITY_CONFIG, - Setup\Metrics\Metric::TYPE_GAUGE, + $port = new Metric( + Metric::STABILITY_CONFIG, + Metric::TYPE_GAUGE, $server->getPort() ); - $weight = new Setup\Metrics\Metric( - Setup\Metrics\Metric::STABILITY_CONFIG, - Setup\Metrics\Metric::TYPE_GAUGE, + $weight = new Metric( + Metric::STABILITY_CONFIG, + Metric::TYPE_GAUGE, $server->getWeight() ); - $server_collection[] = new Setup\Metrics\Metric( - Setup\Metrics\Metric::STABILITY_CONFIG, - Setup\Metrics\Metric::TYPE_COLLECTION, + $server_collection[] = new Metric( + Metric::STABILITY_CONFIG, + Metric::TYPE_COLLECTION, [ "host" => $host, "port" => $port, @@ -86,9 +90,9 @@ protected function collectFrom(Setup\Environment $environment, Setup\Metrics\Sto ); } - $nodes = new Setup\Metrics\Metric( - Setup\Metrics\Metric::STABILITY_CONFIG, - Setup\Metrics\Metric::TYPE_COLLECTION, + $nodes = new Metric( + Metric::STABILITY_CONFIG, + Metric::TYPE_COLLECTION, $server_collection, "Collection of configured memcached nodes." ); @@ -97,15 +101,15 @@ protected function collectFrom(Setup\Environment $environment, Setup\Metrics\Sto $component_activation = []; foreach (ilGlobalCache::getAvailableComponents() as $component) { - $component_activation[$component] = new Setup\Metrics\Metric( - Setup\Metrics\Metric::STABILITY_CONFIG, - Setup\Metrics\Metric::TYPE_BOOL, + $component_activation[$component] = new Metric( + Metric::STABILITY_CONFIG, + Metric::TYPE_BOOL, $config->isComponentActivated($component) ); } - $component_activation = new Setup\Metrics\Metric( - Setup\Metrics\Metric::STABILITY_CONFIG, - Setup\Metrics\Metric::TYPE_COLLECTION, + $component_activation = new Metric( + Metric::STABILITY_CONFIG, + Metric::TYPE_COLLECTION, $component_activation, "Which components are activated to use caching?" ); diff --git a/Services/GlobalCache/classes/class.ilGlobalCacheSettingsAdapter.php b/Services/GlobalCache/classes/class.ilGlobalCacheSettingsAdapter.php index 62baf8f1d80e..626286d8bb16 100644 --- a/Services/GlobalCache/classes/class.ilGlobalCacheSettingsAdapter.php +++ b/Services/GlobalCache/classes/class.ilGlobalCacheSettingsAdapter.php @@ -25,10 +25,10 @@ */ class ilGlobalCacheSettingsAdapter implements Setup\Config { - private ?ilIniFile $client_ini; - private ?ilDBInterface $db; - - private Config $config; + /** + * @readonly + */ + private ?Config $config = null; private bool $active = true; private string $service = Config::PHPSTATIC; private array $components = []; @@ -38,36 +38,47 @@ class ilGlobalCacheSettingsAdapter implements Setup\Config private array $nodes = []; public function __construct( - ?ilIniFile $client_ini = null, - ?ilDBInterface $db = null + private readonly ?ilIniFile $client_ini = null, + private readonly ?ilDBInterface $db = null ) { - $this->db = $db; - $this->client_ini = $client_ini; - if ($client_ini !== null) { - $this->readFromIniFile($client_ini); + if ($this->client_ini !== null) { + $this->readFromIniFile($this->client_ini); } $this->config = $this->toConfig(); } + public function getConfig(): Config + { + return $this->config ?? $this->toConfig(); + } + public function toConfig(): Config { - $config = new Config( + return new Config( $this->service, $this->active, $this->components, $this->getNodesRepository() ); - return $config; } public function readFromIniFile(ilIniFile $client_ini): bool { $this->active = (bool) $client_ini->readVariable('cache', 'activate_global_cache'); - $this->service = $client_ini->readVariable('cache', 'global_cache_service_type'); + $service_type = $client_ini->readVariable('cache', 'global_cache_service_type'); + if(is_numeric($service_type)) { + $service_type = match ((int) $service_type) { + 0 => Config::PHPSTATIC, + 2 => Config::MEMCACHED, + 3 => Config::APCU, + default => Config::PHPSTATIC, + }; + } + $this->service = (string) $service_type; $read_group = $client_ini->readGroup('cache_activated_components'); $this->components = array_unique( - array_map(function (string $component): string { + array_map(static function (string $component): string { if ($component === 'all') { return '*'; } @@ -127,12 +138,12 @@ public function addMemcachedNode(Node $node): void $this->nodes[] = $node; } - public function getMemcachedNodes() + public function getMemcachedNodes(): array { return $this->nodes; } - public function resetActivatedComponents() + public function resetActivatedComponents(): void { $this->components = []; } diff --git a/Services/Init/classes/class.ilInitialisation.php b/Services/Init/classes/class.ilInitialisation.php index 29dbdde6a0a6..52300dcf93b0 100644 --- a/Services/Init/classes/class.ilInitialisation.php +++ b/Services/Init/classes/class.ilInitialisation.php @@ -619,7 +619,7 @@ protected static function initGlobalCache(): void $DIC->database(), ); $DIC['global_cache'] = new \ILIAS\Cache\Services( - $legacy_settings->toConfig() + $legacy_settings->getConfig() ); } diff --git a/src/Cache/Adaptor/Factory.php b/src/Cache/Adaptor/Factory.php index b7887bba5eb3..5c8741dfede5 100644 --- a/src/Cache/Adaptor/Factory.php +++ b/src/Cache/Adaptor/Factory.php @@ -29,14 +29,14 @@ class Factory { public function getSpecific(string $adaptor, Config $config): Adaptor { - $adaptor = match ($adaptor) { + $adaptor_implementation = match ($adaptor) { Config::APCU => new APCu($config), Config::PHPSTATIC => new PHPStatic($config), Config::MEMCACHED => new Memcached($config), - default => throw new \InvalidArgumentException('Unknown Adapter'), + default => new PHPStatic($config), }; - return $adaptor->isAvailable() ? $adaptor : new PHPStatic($config); + return $adaptor_implementation->isAvailable() ? $adaptor_implementation : new PHPStatic($config); } public function getWithConfig(Config $config): Adaptor diff --git a/src/Cache/Services.php b/src/Cache/Services.php index 0647dd10404f..20882246a17b 100644 --- a/src/Cache/Services.php +++ b/src/Cache/Services.php @@ -69,9 +69,9 @@ private function new(Request $for_container): Container } if ( - !in_array($for_container->getContainerKey(), $this->config->getActivatedContainerKeys(), true) + $for_container->isForced() === false && !in_array(Config::ALL, $this->config->getActivatedContainerKeys(), true) - && $for_container->isForced() === false + && !in_array($for_container->getContainerKey(), $this->config->getActivatedContainerKeys(), true) ) { return new VoidContainer($for_container); } From 0e09ca579707276dc08159ff1cbcd959afe77cb6 Mon Sep 17 00:00:00 2001 From: mjansen Date: Tue, 27 Jun 2023 13:02:13 +0200 Subject: [PATCH 29/61] Registration: Prevent multiple assignments for same domain See: https://mantis.ilias.de/view.php?id=29273 --- .../class.ilRegistrationSettingsGUI.php | 59 +++++++++++++++---- lang/ilias_de.lang | 2 + lang/ilias_en.lang | 2 + 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/Services/Registration/classes/class.ilRegistrationSettingsGUI.php b/Services/Registration/classes/class.ilRegistrationSettingsGUI.php index 9cd3636fdb6b..23340d522e36 100644 --- a/Services/Registration/classes/class.ilRegistrationSettingsGUI.php +++ b/Services/Registration/classes/class.ilRegistrationSettingsGUI.php @@ -537,30 +537,67 @@ public function saveAssignment(): bool $this->checkAccess('write'); $this->initRoleAssignments(); $form = $this->initEmailAssignmentForm(); - if (!$form->checkInput()) { - $form->setValuesByPost(); + $is_valid = $form->checkInput(); + $form->setValuesByPost(); + if (!$is_valid) { $this->editEmailAssignments($form); return false; } - $this->assignments_obj->deleteAll(); - $counter = 0; + $assignments_by_domain = []; + $problems_domains_by_field_id = []; foreach ($this->rbacreview->getGlobalRoles() as $role_id) { if ($role_id === ANONYMOUS_ROLE_ID) { continue; } - $domain_input = $form->getInput("domain_$role_id"); + $role_assigned_input = $form->getInput("role_assigned_$role_id"); - if (!empty($role_assigned_input)) { - foreach ($domain_input as $domain) { - if (!empty($domain)) { - $this->assignments_obj->setDomain($counter, $domain); - $this->assignments_obj->setRole($counter, $role_id); - $counter++; + if (!$role_assigned_input) { + continue; + } + + $domain_input = $form->getInput("domain_$role_id"); + foreach ($domain_input as $domain) { + if (!is_string($domain) || $domain === '') { + continue; + } + + if (isset($assignments_by_domain[$domain])) { + if (!isset($problems_domains_by_field_id["role_assigned_$role_id"])) { + $problems_domains_by_field_id["role_assigned_$role_id"] = []; } + + $problems_domains_by_field_id["domain_$role_id"][$domain] = $domain; + continue; } + + $assignments_by_domain[$domain] = $role_id; } } + + if ($problems_domains_by_field_id !== []) { + foreach ($problems_domains_by_field_id as $field_id => $domains) { + $domain_string = implode(', ', $domains); + $alert = sprintf($this->lng->txt('reg_domain_already_assigned_p'), $domain_string); + if (count($domains) === 1) { + $alert = sprintf($this->lng->txt('reg_domain_already_assigned_s'), $domain_string); + } + $form->getItemByPostVar($field_id)->setAlert($alert); + } + + $this->tpl->setOnScreenMessage('failure', $this->lng->txt('form_input_not_valid')); + $this->editEmailAssignments($form); + return false; + } + + $this->assignments_obj->deleteAll(); + + $counter = 0; + foreach ($assignments_by_domain as $domain => $role_id) { + $this->assignments_obj->setDomain($counter, $domain); + $this->assignments_obj->setRole($counter, $role_id); + $counter++; + } $default_role = $form->getInput("default_role"); $this->assignments_obj->setDefaultRole((int) $default_role); $this->assignments_obj->save(); diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 2ab4d1010752..3308eae8ce0d 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -14655,6 +14655,8 @@ registration#:#reg_direct#:#Direkte Anmeldung registration#:#reg_direct_info#:#Wenn eingeschaltet, werden alle neu angemeldeten Benutzer automatisch freigeschaltet. registration#:#reg_disabled#:#Keine Registrierung möglich registration#:#reg_domain#:#Domäne (z.B. '@your_domain.de') +registration#:#reg_domain_already_assigned_p#:#Die Domänen '%s' wurdem bereits für die Zuweisung einer anderen Rolle gewählt. +registration#:#reg_domain_already_assigned_s#:#Die Domäne '%s' wurde bereits für die Zuweisung einer anderen Rolle gewählt. registration#:#reg_email#:#Automatische Rollenzuweisung registration#:#reg_email_domains#:#Die folgenden E-Mail-Adressdomains sind gültig: %s registration#:#reg_email_domains_code#:#Bei Verwendung eines Codes sind beliebige E-Mail-Adressen möglich. diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 42cd54672eee..84225c9323ee 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -14655,6 +14655,8 @@ registration#:#reg_direct#:#Direct Registration registration#:#reg_direct_info#:#New user registration requests are automatically approved. registration#:#reg_disabled#:#No Registration Possible registration#:#reg_domain#:#Domain +registration#:#reg_domain_already_assigned_p#:#The domains '%s' were already entered for another role. +registration#:#reg_domain_already_assigned_s#:#The domain '%s' was already entered for another role. registration#:#reg_email#:#Automatic Role Assignment registration#:#reg_email_domains#:#The following e-mail address domains are valid: %s registration#:#reg_email_domains_code#:#With a registration code any E-Mail-Address is valid. From 9ea4926074cdc67055743f9a392e8ffe7f1ac09f Mon Sep 17 00:00:00 2001 From: Fabian Wolf Date: Tue, 6 Aug 2024 09:33:12 +0200 Subject: [PATCH 30/61] Add withMaxPaginationButtons to thread overview pagination --- Modules/Forum/classes/class.ilObjForumGUI.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/Forum/classes/class.ilObjForumGUI.php b/Modules/Forum/classes/class.ilObjForumGUI.php index 5b7a65ba5fa2..c54f14f8185c 100755 --- a/Modules/Forum/classes/class.ilObjForumGUI.php +++ b/Modules/Forum/classes/class.ilObjForumGUI.php @@ -839,6 +839,7 @@ private function renderThreadOverview(ilForumThreadObjectTableGUI $tbl, ilForum ->withTargetURL($url, ilForumProperties::PAGE_NAME_THREAD_OVERVIEW) ->withTotalEntries($frm_object->getTopNumThreads()) ->withPageSize(ilForumProperties::PAGE_SIZE_THREAD_OVERVIEW) + ->withMaxPaginationButtons(5) ->withCurrentPage($current_page); if ($found_threads === false) { From 65d948fc44b76c32599b4c617fa3600a4410bc81 Mon Sep 17 00:00:00 2001 From: catenglaender <59924129+catenglaender@users.noreply.github.com> Date: Tue, 6 Aug 2024 10:40:50 +0200 Subject: [PATCH 31/61] 9/Learning-Sequence push footer down 41463 (#7806) --- Modules/LearningSequence/templates/default/tpl.kioskpage.html | 2 +- .../UI-framework/MainControls/_ui-component_mode_info.scss | 2 +- templates/default/delos.css | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/LearningSequence/templates/default/tpl.kioskpage.html b/Modules/LearningSequence/templates/default/tpl.kioskpage.html index 92fc800f96d9..b6acc4314309 100644 --- a/Modules/LearningSequence/templates/default/tpl.kioskpage.html +++ b/Modules/LearningSequence/templates/default/tpl.kioskpage.html @@ -1,4 +1,4 @@ -
+
diff --git a/templates/default/070-components/UI-framework/MainControls/_ui-component_mode_info.scss b/templates/default/070-components/UI-framework/MainControls/_ui-component_mode_info.scss index bc9958186c36..29d55e404261 100644 --- a/templates/default/070-components/UI-framework/MainControls/_ui-component_mode_info.scss +++ b/templates/default/070-components/UI-framework/MainControls/_ui-component_mode_info.scss @@ -15,7 +15,7 @@ $il-mode-info-shadow: $il-shadow--large; .c-mode-info { display: flex; - position: absolute; + position: fixed; z-index: $il-mode-info-zindex; width: 100%; align-items: start; diff --git a/templates/default/delos.css b/templates/default/delos.css index 3f9c4b6f5856..299a82bac809 100644 --- a/templates/default/delos.css +++ b/templates/default/delos.css @@ -6269,7 +6269,7 @@ footer { */ .c-mode-info { display: flex; - position: absolute; + position: fixed; z-index: 1010; width: 100%; align-items: start; From 1dd2b7578a74cc90fb1c2c112f07e41a42841f9c Mon Sep 17 00:00:00 2001 From: Alexander Killing Date: Tue, 6 Aug 2024 12:40:22 +0200 Subject: [PATCH 32/61] fixed template setting --- .../Types/GUI/classes/class.ilExAssTypePortfolioGUI.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Modules/Exercise/Assignment/Types/GUI/classes/class.ilExAssTypePortfolioGUI.php b/Modules/Exercise/Assignment/Types/GUI/classes/class.ilExAssTypePortfolioGUI.php index 6bdfb9bea6a3..413519756d93 100644 --- a/Modules/Exercise/Assignment/Types/GUI/classes/class.ilExAssTypePortfolioGUI.php +++ b/Modules/Exercise/Assignment/Types/GUI/classes/class.ilExAssTypePortfolioGUI.php @@ -49,8 +49,8 @@ public function addEditFormCustomProperties(ilPropertyFormGUI $form): void $rd_template = new ilRadioGroupInputGUI($lng->txt("exc_template"), "template"); $rd_template->setRequired(true); - $radio_no_template = new ilRadioOption($lng->txt("exc_without_template"), 0, $lng->txt("exc_without_template_info", "without_template_info")); - $radio_with_template = new ilRadioOption($lng->txt("exc_with_template"), 1, $lng->txt("exc_with_template_info", "with_template_info")); + $radio_no_template = new ilRadioOption($lng->txt("exc_without_template"), "0", $lng->txt("exc_without_template_info", "without_template_info")); + $radio_with_template = new ilRadioOption($lng->txt("exc_with_template"), "1", $lng->txt("exc_with_template_info", "with_template_info")); $repo = new ilRepositorySelector2InputGUI($lng->txt("exc_portfolio_template"), "template_id"); $repo->setRequired(true); @@ -81,9 +81,10 @@ public function getFormValuesArray(ilExAssignment $ass) { $values = []; + $values["template"] = "0"; if ($ass->getPortfolioTemplateId() > 0) { $values["template_id"] = $ass->getPortfolioTemplateId(); - $values["template"] = 1; + $values["template"] = "1"; } return $values; From 4d97785e5c8754b2e57f413500fdfdd1ef54cf69 Mon Sep 17 00:00:00 2001 From: iszmais <45942348+iszmais@users.noreply.github.com> Date: Tue, 6 Aug 2024 15:56:57 +0200 Subject: [PATCH 33/61] Excape json of filter correct (#7899) --- .../classes/class.ilDataCollectionDataSet.php | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/Modules/DataCollection/classes/class.ilDataCollectionDataSet.php b/Modules/DataCollection/classes/class.ilDataCollectionDataSet.php index b3cc32df07ba..504cd720ce9a 100644 --- a/Modules/DataCollection/classes/class.ilDataCollectionDataSet.php +++ b/Modules/DataCollection/classes/class.ilDataCollectionDataSet.php @@ -111,15 +111,13 @@ public function importRecord( string $a_schema_version ): void { foreach ($a_rec as $key => &$value) { - $decode = json_decode($value, true); - if (is_array($decode)) { - $value = htmlspecialchars(json_encode($decode, JSON_HEX_APOS | JSON_HEX_QUOT), ENT_SUBSTITUTE, 'utf-8'); + $array = json_decode($value, true); + if ($key === 'title' || $key === 'description') { + $value = strip_tags($value, ilObjectGUI::ALLOWED_TAGS_IN_TITLE_AND_DESCRIPTION); + } elseif (is_array($array)) { + $value = json_encode($this->escapeArray($array)); } else { - if ($key === 'title' || $key === 'description') { - $value = strip_tags($value, ilObjectGUI::ALLOWED_TAGS_IN_TITLE_AND_DESCRIPTION); - } else { - $value = htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8'); - } + $value = htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8'); } } switch ($a_entity) { @@ -485,6 +483,26 @@ public function importRecord( } } + protected function escapeArray(array $array): array + { + $new = []; + foreach ($array as $key => $value) { + $newkey = $key; + if (is_string($key)) { + $newkey = htmlspecialchars($key, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8'); + } + $newvalue = $value; + if (is_string($value)) { + $newvalue = htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8'); + } + if (is_array($value)) { + $newvalue = $this->escapeArray($value); + } + $new[$newkey] = $newvalue; + } + return $new; + } + /** * Called before finishing import. Fix references inside DataCollections * @param ilImportMapping $a_mapping From 5f20e7f9f4b44fb72649be6c0f55d6a39b32cf32 Mon Sep 17 00:00:00 2001 From: iszmais <45942348+iszmais@users.noreply.github.com> Date: Tue, 6 Aug 2024 18:13:00 +0200 Subject: [PATCH 34/61] Refactor cast properties on image upload field (#7903) --- .../Mob/class.ilDclMobRecordFieldModel.php | 80 ++++++++----------- 1 file changed, 32 insertions(+), 48 deletions(-) diff --git a/Modules/DataCollection/classes/Fields/Mob/class.ilDclMobRecordFieldModel.php b/Modules/DataCollection/classes/Fields/Mob/class.ilDclMobRecordFieldModel.php index eff5316e950f..921c1ffd3470 100644 --- a/Modules/DataCollection/classes/Fields/Mob/class.ilDclMobRecordFieldModel.php +++ b/Modules/DataCollection/classes/Fields/Mob/class.ilDclMobRecordFieldModel.php @@ -33,14 +33,11 @@ public function __construct(ilDclBaseRecordModel $record, ilDclBaseFieldModel $f /** * @param array|int $value - * @return array|string * @throws ilException - * @throws ilFileUtilsException - * @throws ilMediaObjectsException */ public function parseValue($value) { - if ($value === -1) { //marked for deletion. + if ($value === -1) { return null; } @@ -50,11 +47,7 @@ public function parseValue($value) $is_confirmed = $this->http->wrapper()->post()->has('save_confirmed'); $has_save_confirmation = ($this->getRecord()->getTable()->getSaveConfirmation() && !$has_record_id); - if (is_array($media) - && isset($media['tmp_name']) - && $media['tmp_name'] !== "" - && (!$has_save_confirmation || $is_confirmed) - ) { + if (($media['tmp_name'] ?? '') !== '' && (!$has_save_confirmation || $is_confirmed)) { $mob = new ilObjMediaObject(); $mob->setTitle($media['name']); $mob->create(); @@ -64,10 +57,10 @@ public function parseValue($value) } $media_item = new ilMediaItem(); $mob->addMediaItem($media_item); - $media_item->setPurpose("Standard"); + $media_item->setPurpose('Standard'); $file_name = ilFileUtils::getASCIIFilename($media['name']); - $file_name = str_replace(" ", "_", $file_name); - $target_file_path = $mob_dir . "/" . $file_name; + $file_name = str_replace(' ', '_', $file_name); + $target_file_path = $mob_dir . '/' . $file_name; $location = $file_name; if ($has_save_confirmation) { @@ -79,15 +72,15 @@ public function parseValue($value) $move_file = ilDclPropertyFormGUI::getTempFilename( $ilfilehash, 'field_' . $this->getField()->getId(), - $media["name"], - $media["type"] + $media['name'], + $media['type'] ); } else { - if (false === $this->upload->hasBeenProcessed()) { + if (!$this->upload->hasBeenProcessed()) { $this->upload->process(); } - if (false === $this->upload->hasUploads()) { + if (!$this->upload->hasUploads()) { throw new ilException($this->lng->txt('upload_error_file_not_found')); } $move_file = $media['tmp_name']; @@ -96,36 +89,28 @@ public function parseValue($value) ilFileUtils::rename($move_file, $target_file_path); ilFileUtils::renameExecutables($mob_dir); - // Check image/video $format = ilObjMediaObject::getMimeType($target_file_path); - if ($format == 'image/jpeg') { + if ($format === 'image/jpeg') { list($width, $height, $type, $attr) = getimagesize($target_file_path); - $field = $this->getField(); - $new_width = $field->getProperty(ilDclBaseFieldModel::PROP_WIDTH); - $new_height = $field->getProperty(ilDclBaseFieldModel::PROP_HEIGHT); - if ($new_width || $new_height) { - //only resize if it is bigger, not if it is smaller + $new_width = (int) $this->getField()->getProperty(ilDclBaseFieldModel::PROP_WIDTH); + $new_height = (int) $this->getField()->getProperty(ilDclBaseFieldModel::PROP_HEIGHT); + if ($new_width > 0 || $new_height > 0) { if ($new_height < $height && $new_width < $width) { - //resize proportional - if (!$new_height || !$new_width) { - $format = ilObjMediaObject::getMimeType($target_file_path); - $wh - = ilObjMediaObject::_determineWidthHeight( - $format, - "File", - $target_file_path, - "", - true, - false, - $field->getProperty(ilDclBaseFieldModel::PROP_WIDTH), - (int) $field->getProperty(ilDclBaseFieldModel::PROP_HEIGHT) - ); - } else { - $wh['width'] = (int) $field->getProperty(ilDclBaseFieldModel::PROP_WIDTH); - $wh['height'] = (int) $field->getProperty(ilDclBaseFieldModel::PROP_HEIGHT); + $wh['width'] = $new_width; + $wh['height'] = $new_height; + if ($new_height === 0 || $new_width === 0) { + $wh = ilObjMediaObject::_determineWidthHeight( + $format, + 'File', + $target_file_path, + '', + true, + false, + $new_width, + $new_height + ); } - $location = ilObjMediaObject::_resizeImage($target_file_path, $wh['width'], $wh['height']); } } @@ -133,19 +118,19 @@ public function parseValue($value) ilObjMediaObject::_saveUsage( $mob->getId(), - "dcl:html", + 'dcl:html', $this->getRecord()->getTable()->getCollectionObject()->getId() ); $media_item->setFormat($format); $media_item->setLocation($location); - $media_item->setLocationType("LocalFile"); + $media_item->setLocationType('LocalFile'); if (ilFFmpeg::enabled() && ilFFmpeg::supportsImageExtraction($format)) { - $med = $mob->getMediaItem("Standard"); - $mob_file = ilObjMediaObject::_getDirectory($mob->getId()) . "/" . $med->getLocation(); + $med = $mob->getMediaItem('Standard'); + $mob_file = ilObjMediaObject::_getDirectory($mob->getId()) . '/' . $med->getLocation(); $a_target_dir = ilObjMediaObject::_getDirectory($mob->getId()); try { - ilFFmpeg::extractImage($mob_file, "mob_vpreview.png", $a_target_dir); + ilFFmpeg::extractImage($mob_file, 'mob_vpreview.png', $a_target_dir); } catch (Exception $e) { $this->main_tpl->setOnScreenMessage('failure', $e->getMessage(), true); } @@ -153,9 +138,8 @@ public function parseValue($value) $mob->update(); $return = $mob->getId(); - // handover for save-confirmation } else { - if (is_array($media) && isset($media['tmp_name']) && $media['tmp_name'] != '') { + if (($media['tmp_name'] ?? '') !== '') { $return = $media; } else { $return = $this->getValue(); From 7ce8e4b94d030c95ee91504a08c544aea90c13db Mon Sep 17 00:00:00 2001 From: Tim Schmitz Date: Wed, 7 Aug 2024 09:37:53 +0200 Subject: [PATCH 35/61] MetaData: add missing step to enabling lom doc --- Services/MetaData/docs/enabling_lom.md | 32 ++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/Services/MetaData/docs/enabling_lom.md b/Services/MetaData/docs/enabling_lom.md index 28944a377f9e..91eb0012c770 100644 --- a/Services/MetaData/docs/enabling_lom.md +++ b/Services/MetaData/docs/enabling_lom.md @@ -29,12 +29,36 @@ them in your component, and set the ID-triple in `ilMD` as described ### LOM Editor -In order to show the 'Metadata' tab with the LOM editor, you have to -add the `ilObjectMetadataGUI` to your control flow, and it will take +To give users of your object access to the LOM editor, add a 'Metadata' +tab in your GUI class with the link given by `ilObjectMetadataGUI::getTab` +as follows: + +```` +if ($ilAccess->checkAccess("write", "", $this->object->getRefId())) { + $mdgui = new ilObjectMetaDataGUI($this->object); + $mdtab = $mdgui->getTab(); + if ($mdtab) { + $this->tabs_gui->addTab( + "meta_data", + $this->lng->txt("meta_data"), + $mdtab + ); + } +} +```` + +Add `ilObjectMetadataGUI` to your control flow, and it will take care of the rest: have your object's main GUI forward commands to `ilObjectMetadataGUI`, and activate the tab with ID `'meta_data'` -when it does. In addition, add your object's type to the array in -`ilObjectMetadataGUI::isLOMAvailable`. +when it does. If required, permissions should be checked before +forwarding (and before showing the tab). For most objects, editing +of LOM should be restricted to users with 'write' permission. + +Lastly, add your object's type to the array in +`ilObjectMetadataGUI::isLOMAvailable`. Otherwise the 'Metadata' tab +will not actually lead to the LOM editor. Be aware that this step +is required even if your object already has a 'Metadata' tab, e.g. +because it supports Custom Metadata. If your object is a repository object, you can just pass the object itself to the constructor of `ilObjectMetadataGUI`, and it will extract From 871af690b883a1228259fa5ddf8c4bec4714eedc Mon Sep 17 00:00:00 2001 From: Alex Killing Date: Wed, 7 Aug 2024 09:50:50 +0200 Subject: [PATCH 36/61] 41861: Type Error in class ilInternalLink --- Modules/Exercise/Submission/class.ilExSubmission.php | 2 -- Services/Link/classes/class.ilInternalLink.php | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Modules/Exercise/Submission/class.ilExSubmission.php b/Modules/Exercise/Submission/class.ilExSubmission.php index 37d94378be54..b920078a18e2 100644 --- a/Modules/Exercise/Submission/class.ilExSubmission.php +++ b/Modules/Exercise/Submission/class.ilExSubmission.php @@ -308,7 +308,6 @@ public function uploadFile( bool $unzip = false ): bool { $ilDB = $this->db; - if (!$this->canAddFile()) { return false; } @@ -366,7 +365,6 @@ public function addFileUpload( if (!$this->canAddFile()) { return false; } - if ($this->ass_type->isSubmissionAssignedToTeam()) { $team_id = $this->getTeam()->getId(); $user_id = 0; diff --git a/Services/Link/classes/class.ilInternalLink.php b/Services/Link/classes/class.ilInternalLink.php index 393c01965122..4b5cc54fd321 100755 --- a/Services/Link/classes/class.ilInternalLink.php +++ b/Services/Link/classes/class.ilInternalLink.php @@ -272,13 +272,13 @@ public static function _exists( switch ($a_type) { case "PageObject": case "StructureObject": - return ilLMObject::_exists($a_target); + return ilLMObject::_exists((int) $a_target); case "GlossaryItem": - return ilGlossaryTerm::_exists($a_target); + return ilGlossaryTerm::_exists((int) $a_target); case "MediaObject": - return ilObjMediaObject::_exists($a_target); + return ilObjMediaObject::_exists((int) $a_target); case "WikiPage": return ilWikiPage::_exists("wiki", (int) $a_target); From e9ad53d23eac528b09dbf8353221d34c458fa1d0 Mon Sep 17 00:00:00 2001 From: Tim Schmitz Date: Wed, 7 Aug 2024 14:23:07 +0200 Subject: [PATCH 37/61] Group: fix updating group title and description for some groups (41866) --- Modules/Group/classes/class.ilObjGroupGUI.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Modules/Group/classes/class.ilObjGroupGUI.php b/Modules/Group/classes/class.ilObjGroupGUI.php index ec52b58bfc5f..ed0c3ddca57a 100755 --- a/Modules/Group/classes/class.ilObjGroupGUI.php +++ b/Modules/Group/classes/class.ilObjGroupGUI.php @@ -665,6 +665,9 @@ public function updateObject(): void break; } + // update object settings + $this->object->update(); + // title icon visibility $obj_service->commonSettings()->legacyForm($form, $this->object)->saveTitleIconVisibility(); @@ -680,10 +683,6 @@ public function updateObject(): void // list presentation $this->saveListPresentation($form); - // update object settings - $this->object->update(); - - ilObjectServiceSettingsGUI::updateServiceSettingsForm( $this->object->getId(), $form, From c55c9d6513e4a69ab6cade5387c65925109437b9 Mon Sep 17 00:00:00 2001 From: mjansen Date: Wed, 7 Aug 2024 16:56:58 +0200 Subject: [PATCH 38/61] Forum: Fix default sorting of threads See: https://mantis.ilias.de/view.php?id=41870 --- Modules/Forum/classes/GUI/ThreadSortation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Forum/classes/GUI/ThreadSortation.php b/Modules/Forum/classes/GUI/ThreadSortation.php index 634fec8683e5..41f8061b7933 100644 --- a/Modules/Forum/classes/GUI/ThreadSortation.php +++ b/Modules/Forum/classes/GUI/ThreadSortation.php @@ -20,7 +20,7 @@ enum ThreadSortation: int { - public const DEFAULT_SORTATION = self::SUBJECT_ASC; + public const DEFAULT_SORTATION = self::LAST_POST_DESC; case SUBJECT_ASC = 1; case SUBJECT_DESC = 2; From 401dd644f3e4f703d6014dbbb7e5c8aed22d64ef Mon Sep 17 00:00:00 2001 From: Alexander Killing Date: Wed, 7 Aug 2024 19:06:42 +0200 Subject: [PATCH 39/61] 41838: New Item Menu fixed to single column with custom grouping --- .../Administration/class.ilObjRepositorySettings.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/Services/Repository/Administration/class.ilObjRepositorySettings.php b/Services/Repository/Administration/class.ilObjRepositorySettings.php index f92a3779a08c..2cf866f6bec5 100644 --- a/Services/Repository/Administration/class.ilObjRepositorySettings.php +++ b/Services/Repository/Administration/class.ilObjRepositorySettings.php @@ -140,9 +140,6 @@ public static function getNewItemGroups(): array $set = $ilDB->query("SELECT * FROM il_new_item_grp ORDER BY pos"); while ($row = $ilDB->fetchAssoc($set)) { - if ($row['titles'] === null) { - continue; - } if ((int) $row["type"] === self::NEW_ITEM_GROUP_TYPE_GROUP) { $row["titles"] = unserialize($row["titles"], ["allowed_classes" => false]); From 7fdd25d42edda25f51f839d979f4e1e49b98010f Mon Sep 17 00:00:00 2001 From: Alexander Killing Date: Wed, 7 Aug 2024 19:13:32 +0200 Subject: [PATCH 40/61] 41838: New Item Menu fixed to single column with custom grouping --- .../Administration/class.ilObjRepositorySettingsGUI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Services/Repository/Administration/class.ilObjRepositorySettingsGUI.php b/Services/Repository/Administration/class.ilObjRepositorySettingsGUI.php index 4522e3007ad6..2ffd59c7abc1 100644 --- a/Services/Repository/Administration/class.ilObjRepositorySettingsGUI.php +++ b/Services/Repository/Administration/class.ilObjRepositorySettingsGUI.php @@ -838,7 +838,7 @@ protected function saveNewItemGroupOrder(): void $grp_pos_map = []; foreach (ilObjRepositorySettings::getNewItemGroups() as $item) { - $grp_pos_map[$item["id"]] = str_pad($item["pos"], 4, "0", STR_PAD_LEFT); + $grp_pos_map[$item["id"]] = str_pad((string) $item["pos"], 4, "0", STR_PAD_LEFT); } // update order of assigned objects From 9455a695c45204a6286886f544ad4af13b074401 Mon Sep 17 00:00:00 2001 From: Alexander Killing Date: Wed, 7 Aug 2024 19:59:48 +0200 Subject: [PATCH 41/61] 41797: Missing Method ilLMPresentationGUI->getObject() in ilLMNavigationRendererGUI:315 --- .../Presentation/class.ilLMNavigationRendererGUI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/LearningModule/Presentation/class.ilLMNavigationRendererGUI.php b/Modules/LearningModule/Presentation/class.ilLMNavigationRendererGUI.php index c93bd858a282..8a6163183e26 100644 --- a/Modules/LearningModule/Presentation/class.ilLMNavigationRendererGUI.php +++ b/Modules/LearningModule/Presentation/class.ilLMNavigationRendererGUI.php @@ -312,7 +312,7 @@ protected function addDropdown() ); if ($this->user->getId() === ANONYMOUS_USER_ID && - $this->parent_gui->getObject()->getPublicAccessMode() === "selected") { + $this->lm->getPublicAccessMode() === "selected") { if (!ilLMObject::_isPagePublic($node["obj_id"])) { $disabled = true; $text .= " (" . $this->lng->txt("cont_no_access") . ")"; From ffe08b8c707345a00935d91bc7f8a69868d89103 Mon Sep 17 00:00:00 2001 From: mjansen Date: Thu, 8 Aug 2024 08:33:32 +0200 Subject: [PATCH 42/61] Mail: Return sanitized filename when moving into attachment stage (cherry picked from commit 2b684c9317c3523161a16bf80107771b583f9fb9) --- Services/Mail/README.md | 20 +++++----- .../Mail/classes/class.ilFileDataMail.php | 40 ++++++++++++++----- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Services/Mail/README.md b/Services/Mail/README.md index caeeaf252f69..f61d11f67dcb 100644 --- a/Services/Mail/README.md +++ b/Services/Mail/README.md @@ -324,15 +324,17 @@ This can be done as described in the following examples: ```php $attachment = new \ilFileDataMail($senderUserId); -$attachment->storeAsAttachment( - 'appointment.ics', $someIcalString +$attachment_filename = $attachment->storeAsAttachment( + 'appointment.ics', + $some_ical_string ); $attachment->copyAttachmentFile( - '/temp/hello.jpg', 'HelloWorld.jpg' + '/temp/hello.jpg', + 'HelloWorld.jpg' ); -$mail = new \ilMail($senderUserId); +$mail = new \ilMail($sender_usr_id); $mail->enqueue( $to, $cc, @@ -340,14 +342,14 @@ $mail->enqueue( $subject, $message, [ - 'appointment.ics', + $attachment_filename, 'HelloWorld.jpg' - ], - array("system") + ] ); -// or $attachment->unlinkFiles(['/temp/hello.jpg']); -$attachment->unlinkFile('/temp/hello.jpg'); +// or $attachment->unlinkFiles(['HelloWorld.jpg', $attachment_filename]); +$attachment->unlinkFile('HelloWorld.jpg'); +$attachment->unlinkFile($attachment_filename); ``` As outlined above attachments have to be removed diff --git a/Services/Mail/classes/class.ilFileDataMail.php b/Services/Mail/classes/class.ilFileDataMail.php index 38417fbb31e0..5db5d7f66d37 100755 --- a/Services/Mail/classes/class.ilFileDataMail.php +++ b/Services/Mail/classes/class.ilFileDataMail.php @@ -217,10 +217,15 @@ private function getUnsentFiles(): array return $files; } - public function storeAsAttachment(string $a_filename, string $a_content) + public function storeAsAttachment(string $a_filename, string $a_content): string { if (strlen($a_content) >= $this->getUploadLimit()) { - return 1; + throw new DomainException( + sprintf( + 'Mail upload limit reached for user with id %s', + $this->user_id + ) + ); } $name = ilFileUtils::_sanitizeFilemame($a_filename); @@ -230,32 +235,45 @@ public function storeAsAttachment(string $a_filename, string $a_content) $fp = fopen($abs_path, 'wb+'); if (!is_resource($fp)) { - return false; + throw new RuntimeException( + sprintf( + 'Could not read file: %s', + $abs_path + ) + ); } if (fwrite($fp, $a_content) === false) { fclose($fp); - return false; + throw new RuntimeException( + sprintf( + 'Could not write file: %s', + $abs_path + ) + ); } fclose($fp); - return true; + + return $name; } /** * @param array{name:string, tmp_name:string} $file */ - public function storeUploadedFile(array $file): void + public function storeUploadedFile(array $file): string { - $file['name'] = ilFileUtils::_sanitizeFilemame($file['name']); + $sanitized_filename = ilFileUtils::_sanitizeFilemame($file['name']); - $this->rotateFiles($this->getMailPath() . '/' . $this->user_id . '_' . $file['name']); + $this->rotateFiles($this->getMailPath() . '/' . $this->user_id . '_' . $sanitized_filename); ilFileUtils::moveUploadedFile( $file['tmp_name'], - $file['name'], - $this->getMailPath() . '/' . $this->user_id . '_' . $file['name'] + $sanitized_filename, + $this->getMailPath() . '/' . $this->user_id . '_' . $sanitized_filename ); + + return $sanitized_filename; } /** @@ -268,7 +286,7 @@ public function copyAttachmentFile(string $a_abs_path, string $a_new_name): bool return true; } - public function rotateFiles(string $a_path): bool + private function rotateFiles(string $a_path): bool { if (is_file($a_path)) { $this->rotateFiles($a_path . ".old"); From 729c795a84bea9d2757ef75dc9bf9c2f775d57b7 Mon Sep 17 00:00:00 2001 From: mjansen Date: Wed, 7 Aug 2024 09:37:45 +0200 Subject: [PATCH 43/61] Registration: Fix translation in `MessageBox > Failure` after failed confirmation See: https://mantis.ilias.de/view.php?id=41704 --- Services/Init/classes/class.ilStartUpGUI.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Services/Init/classes/class.ilStartUpGUI.php b/Services/Init/classes/class.ilStartUpGUI.php index 62f1ed73f030..9b3ae992d372 100755 --- a/Services/Init/classes/class.ilStartUpGUI.php +++ b/Services/Init/classes/class.ilStartUpGUI.php @@ -1505,6 +1505,8 @@ public static function _checkGoto(string $a_target) private function confirmRegistration(): void { + $this->lng->loadLanguageModule('registration'); + ilUtil::setCookie('iltest', 'cookie', false); $regitration_hash = trim($this->http->wrapper()->query()->retrieve( 'rh', From 725d7332144dccd298433c2c58a3d08a84402092 Mon Sep 17 00:00:00 2001 From: Thomas Hufschmidt Date: Thu, 8 Aug 2024 11:32:34 +0200 Subject: [PATCH 44/61] 41874: Cron.php does not work when account has IP restriction. (cherry picked from commit e3daaafa9cf903bdde45e5bc4fdcd5720d983a38) --- .../classes/Frontend/class.ilAuthFrontendCLI.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php b/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php index fac51fe93b0c..2e44967c8440 100644 --- a/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php +++ b/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php @@ -26,4 +26,12 @@ */ class ilAuthFrontendCLI extends ilAuthFrontend implements ilAuthFrontendInterface { + /** + * This overwrites ilAuthFrontend::checkIp used in ilAuthFrontend::authenticate + * since CLI does not set $_SERVER['REMOTE_ADDR']! + */ + protected function checkIp(ilObjUser $user): bool + { + return true; + } } From bc7f759b7cbb90133410bcf9701e7e4ebc79741d Mon Sep 17 00:00:00 2001 From: mjansen Date: Thu, 8 Aug 2024 13:00:47 +0200 Subject: [PATCH 45/61] Auth: Fix code style (cherry picked from commit 070351655517213cc801a6837c5e1efc3266325b) --- .../Frontend/class.ilAuthFrontendCLI.php | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php b/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php index 2e44967c8440..ef041be8317d 100644 --- a/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php +++ b/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php @@ -1,7 +1,5 @@ - * - */ +declare(strict_types=1); + class ilAuthFrontendCLI extends ilAuthFrontend implements ilAuthFrontendInterface { - /** - * This overwrites ilAuthFrontend::checkIp used in ilAuthFrontend::authenticate - * since CLI does not set $_SERVER['REMOTE_ADDR']! - */ - protected function checkIp(ilObjUser $user): bool - { - return true; - } + /** + * This overwrites ilAuthFrontend::checkIp used in ilAuthFrontend::authenticate + * since CLI does not set $_SERVER['REMOTE_ADDR']! + */ + protected function checkIp(ilObjUser $user): bool + { + return true; + } } From 40660ee53bd840699da94350889caad6d7d0868b Mon Sep 17 00:00:00 2001 From: iszmais Date: Thu, 8 Aug 2024 15:17:38 +0200 Subject: [PATCH 46/61] fix default command target for sahs --- Services/Object/classes/class.ilObjectListGUI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Services/Object/classes/class.ilObjectListGUI.php b/Services/Object/classes/class.ilObjectListGUI.php index ab1ad7023418..cdf4c67a9d41 100644 --- a/Services/Object/classes/class.ilObjectListGUI.php +++ b/Services/Object/classes/class.ilObjectListGUI.php @@ -3163,7 +3163,7 @@ public function getAsListItem( if ($def_command['link'] ?? false) { list($def_command['link'], $def_command['frame']) = $this->modifySAHSlaunch($def_command['link'], $def_command['frame']); - $new_viewport = !in_array($this->getDefaultCommand()['frame'], ['', '_top', '_self', '_parent'], true); // Cannot use $def_command['frame']. $this->default_command has been edited. + $new_viewport = !in_array($def_command['frame'], ['', '_top', '_self', '_parent'], true); $link = $this->ui->factory() ->link() ->standard($this->getTitle(), $def_command['link']) From ab8fa816298462cdfbdc7d23add2d0130d6e2cef Mon Sep 17 00:00:00 2001 From: Pascal Seeland Date: Thu, 8 Aug 2024 21:27:44 +0200 Subject: [PATCH 47/61] Fix 0041709: Permission tab on remote courses throws error --- .../ECS/classes/class.ilRemoteObjectBaseGUI.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Services/WebServices/ECS/classes/class.ilRemoteObjectBaseGUI.php b/Services/WebServices/ECS/classes/class.ilRemoteObjectBaseGUI.php index 3c19ab8a5d3f..79a9c36f4ad7 100644 --- a/Services/WebServices/ECS/classes/class.ilRemoteObjectBaseGUI.php +++ b/Services/WebServices/ECS/classes/class.ilRemoteObjectBaseGUI.php @@ -18,12 +18,14 @@ declare(strict_types=1); /** -* @author Stefan Meyer -*/ + * @author Stefan Meyer + */ abstract class ilRemoteObjectBaseGUI extends ilObject2GUI { private ilLogger $logger; + public const TAB_ID_PERMISSIONS = "id_permissions"; + public function __construct($a_id = 0, $a_id_type = self::REPOSITORY_NODE_ID, $a_parent_node_id = 0) { global $DIC; @@ -115,9 +117,13 @@ protected function setTabs(): void $this->ctrl->getLinkTarget($this, "edit") ); } - - // will add permissions if needed - parent::setTabs(); + if ($this->checkPermissionBool("edit_permission")) { + $this->tabs_gui->addTab( + self::TAB_ID_PERMISSIONS, + $this->lng->txt("perm_settings"), + $this->ctrl->getLinkTargetByClass("ilpermissiongui", "perm") + ); + } } /** From 9777e946b179b0034d060867238b995c3df50388 Mon Sep 17 00:00:00 2001 From: Matthias Kunkel Date: Fri, 9 Aug 2024 11:04:50 +0200 Subject: [PATCH 48/61] Fixed Mantis #41705: Male mail... All users referred to as 'he' in contact request mails. --- lang/ilias_en.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 84225c9323ee..948678c0b875 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -2667,8 +2667,8 @@ buddysystem#:#buddy_notification_contact_request_ignore#:#Ignore Request buddysystem#:#buddy_notification_contact_request_ignore_osd#:#Ignore Request buddysystem#:#buddy_notification_contact_request_link#:#Approve Request buddysystem#:#buddy_notification_contact_request_link_osd#:#Approve Request -buddysystem#:#buddy_notification_contact_request_long#:#[SALUTATION][BR][BR]"[REQUESTING_USER]" wants to add you to his friends list.[BR][BR]Personal Profile Link: [PERSONAL_PROFILE_LINK][BR][BR][APPROVE_REQUEST_TXT] [APPROVE_REQUEST][BR][IGNORE_REQUEST_TXT] [IGNORE_REQUEST] -buddysystem#:#buddy_notification_contact_request_short#:#The user "[REQUESTING_USER]" wants to add you to his friends list. +buddysystem#:#buddy_notification_contact_request_long#:#[SALUTATION][BR][BR]"[REQUESTING_USER]" wants to add you to their friends list.[BR][BR]Personal Profile Link: [PERSONAL_PROFILE_LINK][BR][BR][APPROVE_REQUEST_TXT] [APPROVE_REQUEST][BR][IGNORE_REQUEST_TXT] [IGNORE_REQUEST] +buddysystem#:#buddy_notification_contact_request_short#:#The user "[REQUESTING_USER]" wants to add you to their friends list. buddysystem#:#buddy_relation_requested#:#A request has been sent to the user. buddysystem#:#buddy_request_approved#:#You successfully approved the contact. buddysystem#:#buddy_request_ignored#:#You ignored the user. From 4a3bccc22bac449796dfca318fb3d37496c7884e Mon Sep 17 00:00:00 2001 From: Alex Killing Date: Fri, 9 Aug 2024 11:47:01 +0200 Subject: [PATCH 49/61] fixed 41886: Fehler in Matrixfrage neutrale Antwort --- .../Categories/class.ilCategoryWizardInputGUI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/SurveyQuestionPool/Categories/class.ilCategoryWizardInputGUI.php b/Modules/SurveyQuestionPool/Categories/class.ilCategoryWizardInputGUI.php index 53421e347466..f852c19249cd 100644 --- a/Modules/SurveyQuestionPool/Categories/class.ilCategoryWizardInputGUI.php +++ b/Modules/SurveyQuestionPool/Categories/class.ilCategoryWizardInputGUI.php @@ -195,7 +195,7 @@ public function checkInput(): bool if (count($foundvalues) > 0) { // check answers - if (is_array($foundvalues['answer'])) { + if (is_array($foundvalues['answer'] ?? false)) { foreach ($foundvalues['answer'] as $idx => $answervalue) { if (((strlen($answervalue ?? "")) == 0) && ($this->getRequired() && (!isset($foundvalues['other'][$idx])))) { $this->setAlert($lng->txt("msg_input_is_required")); From 4b38e84d8d01b0911b04fc07c00a25778be2e523 Mon Sep 17 00:00:00 2001 From: Guido Vollbach Date: Fri, 9 Aug 2024 13:02:01 +0200 Subject: [PATCH 50/61] Fix bug #41891 (#7921) --- Modules/Forum/classes/class.ilObjForumGUI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Forum/classes/class.ilObjForumGUI.php b/Modules/Forum/classes/class.ilObjForumGUI.php index c54f14f8185c..47ebee046f2b 100755 --- a/Modules/Forum/classes/class.ilObjForumGUI.php +++ b/Modules/Forum/classes/class.ilObjForumGUI.php @@ -1029,7 +1029,7 @@ private function getActionsForThreadOverview(int $ref_id, ilForumTopic $forum_to $actions = $f->dropdown()->standard([]); - if (ilForum::_isModerator($ref_id, $this->user->getId())) { + if ($this->is_moderator) { $open_close = $this->getOpenCloseActionForThread($forum_topic, $ref_id); $stick_or_no_stick = $this->getStickyActionForThread($forum_topic, $ref_id); $edit_title_modal = $this->getEditTitleModal($forum_topic); From 6fe29f876a13411d1d54bae4b430abee06e70f83 Mon Sep 17 00:00:00 2001 From: mjansen Date: Fri, 9 Aug 2024 14:53:18 +0200 Subject: [PATCH 51/61] Mail: Cleanup old files from attachment stage (for anonymous user) (cherry picked from commit 04f9348242bfa637632707e28d8e45682c8f67ec) --- Services/Mail/classes/class.ilMail.php | 10 +++ .../class.ilMailAttachmentStageCleanup.php | 71 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 Services/Mail/classes/class.ilMailAttachmentStageCleanup.php diff --git a/Services/Mail/classes/class.ilMail.php b/Services/Mail/classes/class.ilMail.php index a103b492124d..1584f62b1bbd 100755 --- a/Services/Mail/classes/class.ilMail.php +++ b/Services/Mail/classes/class.ilMail.php @@ -1136,6 +1136,16 @@ public function sendMail( $this->deleteMails([$internalMessageId]); } + if ($this->isSystemMail()) { + $random = new ilRandom(); + if ($random->int(0, 50) === 2) { + (new ilMailAttachmentStageCleanup( + $this->logger, + $this->mfile + ))->run(); + } + } + return array_values($errors); } diff --git a/Services/Mail/classes/class.ilMailAttachmentStageCleanup.php b/Services/Mail/classes/class.ilMailAttachmentStageCleanup.php new file mode 100644 index 000000000000..80a11eb7645e --- /dev/null +++ b/Services/Mail/classes/class.ilMailAttachmentStageCleanup.php @@ -0,0 +1,71 @@ +logger = $logger; + $this->mail_file_manager = $mail_file_manager; + } + + public function run(): void + { + $right_interval = (new DateTimeImmutable(self::OLD_FILE_MTIME_EXPRESSION))->format('U'); + + $iter = new CallbackFilterIterator( + new RegexIterator( + new DirectoryIterator($this->mail_file_manager->getMailPath()), + '/^' . $this->mail_file_manager->user_id . '_/' + ), + function (SplFileInfo $file) use ($right_interval): bool { + if (!$file->isFile()) { + return false; + } + + return (int) $file->getMTime() < (int) $right_interval; + } + ); + + $filesystem = \ILIAS\Filesystem\Util\LegacyPathHelper::deriveFilesystemFrom( + $this->mail_file_manager->getMailPath() + ); + + foreach ($iter as $file) { + /** @var SplFileInfo $file */ + if (strpos($file->getFilename(), $this->mail_file_manager->user_id . '_') === 0) { + try { + $relative_path = 'mail/' . $file->getFilename(); + if ($filesystem->has($relative_path)) { + $filesystem->delete($relative_path); + $this->logger->info('Deleting file from attachment stage: ' . $file->getPath()); + } + } catch (Exception $e) { + $this->logger->error('Error deleting file from attachment stage: ' . $file->getPath()); + } + } + } + } +} From 30e85eb90c7c34faac4745e3bb9bcbcc45db3888 Mon Sep 17 00:00:00 2001 From: mjansen Date: Fri, 9 Aug 2024 14:59:52 +0200 Subject: [PATCH 52/61] Mail: Cleanup old files from attachment stage (for anonymous user) --- Services/Mail/classes/class.ilMail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Services/Mail/classes/class.ilMail.php b/Services/Mail/classes/class.ilMail.php index 1584f62b1bbd..6699654a6000 100755 --- a/Services/Mail/classes/class.ilMail.php +++ b/Services/Mail/classes/class.ilMail.php @@ -1141,7 +1141,7 @@ public function sendMail( if ($random->int(0, 50) === 2) { (new ilMailAttachmentStageCleanup( $this->logger, - $this->mfile + $this->mail_file_data ))->run(); } } From 31d8f8ddd21952495a1bb77d78dba8210e62fb1d Mon Sep 17 00:00:00 2001 From: mjansen Date: Fri, 9 Aug 2024 15:10:34 +0200 Subject: [PATCH 53/61] Mail: Cleanup old files from attachment stage (for anonymous user) (cherry picked from commit fb37aef98c639e5cc9a6ac3e8c5279f1430032d2) --- Services/Mail/classes/class.ilMailAttachmentStageCleanup.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Services/Mail/classes/class.ilMailAttachmentStageCleanup.php b/Services/Mail/classes/class.ilMailAttachmentStageCleanup.php index 80a11eb7645e..0762ef2ff299 100644 --- a/Services/Mail/classes/class.ilMailAttachmentStageCleanup.php +++ b/Services/Mail/classes/class.ilMailAttachmentStageCleanup.php @@ -60,10 +60,10 @@ function (SplFileInfo $file) use ($right_interval): bool { $relative_path = 'mail/' . $file->getFilename(); if ($filesystem->has($relative_path)) { $filesystem->delete($relative_path); - $this->logger->info('Deleting file from attachment stage: ' . $file->getPath()); + $this->logger->info('Deleting file from attachment stage: ' . $file->getPathname()); } } catch (Exception $e) { - $this->logger->error('Error deleting file from attachment stage: ' . $file->getPath()); + $this->logger->error('Error deleting file from attachment stage: ' . $file->getPathname()); } } } From f5b410fc3ba4429900303a4faec3c98e4ccd3a50 Mon Sep 17 00:00:00 2001 From: Stefan Meyer Date: Mon, 12 Aug 2024 09:20:33 +0200 Subject: [PATCH 54/61] Merge pull request #7919 from mjansenDatabay/hotfix/8/cal-noti-unique-mail-attachments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calendar/Mail: Use (more or less) unique filenames for "ics" mail att… --- .../classes/class.ilCalendarMailNotification.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Services/Calendar/classes/class.ilCalendarMailNotification.php b/Services/Calendar/classes/class.ilCalendarMailNotification.php index add740271f6f..59ec724b8caa 100644 --- a/Services/Calendar/classes/class.ilCalendarMailNotification.php +++ b/Services/Calendar/classes/class.ilCalendarMailNotification.php @@ -381,17 +381,15 @@ protected function addAttachment(): void $export->setAppointments([(int) $this->getAppointmentId()]); $export->export(); + $ics_filename = 'appointment_' . (new DateTimeImmutable('now'))->format('Ymd_His_u') . '.ics'; + $attachment = new ilFileDataMail($this->getSender()); - $attachment->storeAsAttachment( - 'appointment.ics', + $effective_ics_filename = $attachment->storeAsAttachment( + $ics_filename, $export->getExportString() ); - $this->setAttachments( - array( - 'appointment.ics' - ) - ); + $this->setAttachments([$effective_ics_filename]); } protected function deleteAttachments(): void From b3786a5bf23d7ae61f95ae3093c780d38e61a5cf Mon Sep 17 00:00:00 2001 From: Stefan Meyer Date: Mon, 12 Aug 2024 10:50:24 +0200 Subject: [PATCH 55/61] Merge pull request #7895 from chlulei/8_import_ical_exclusions implements import of iCal exclusions --- .../Calendar/classes/iCal/class.ilICalParser.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Services/Calendar/classes/iCal/class.ilICalParser.php b/Services/Calendar/classes/iCal/class.ilICalParser.php index 2c48b30047e8..d8a7ed200c61 100644 --- a/Services/Calendar/classes/iCal/class.ilICalParser.php +++ b/Services/Calendar/classes/iCal/class.ilICalParser.php @@ -1,7 +1,5 @@ @@ -393,6 +392,17 @@ protected function writeEvent(): void } $entry->save(); + // Search exclusions + // Only possible after entry is saved, otherwise the id is not available + foreach ($this->getContainer()->getItemsByName('EXDATE', false) as $item) { + if (is_a($item, 'ilICalProperty')) { + $rec_exclusion = new ilCalendarRecurrenceExclusion(); + $rec_exclusion->setEntryId($entry->getEntryId()); + $rec_exclusion->setDate(new ilDate($item->getValue(), IL_CAL_DATE)); + $rec_exclusion->save(); + } + } + $ass = new ilCalendarCategoryAssignments($entry->getEntryId()); $ass->addAssignment($this->category->getCategoryID()); From a5746b31ddeb3526e3fa15959eef0bf9ed1c40f3 Mon Sep 17 00:00:00 2001 From: "christof.buch" Date: Wed, 7 Aug 2024 16:27:54 +0200 Subject: [PATCH 56/61] PRG: fix salutation in email (#418668) * https://mantis.ilias.de/view.php?id=41868 --- Modules/StudyProgramme/classes/Mail/class.ilPRGMail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/StudyProgramme/classes/Mail/class.ilPRGMail.php b/Modules/StudyProgramme/classes/Mail/class.ilPRGMail.php index 22d5886a1b20..0f0d3f5e5872 100644 --- a/Modules/StudyProgramme/classes/Mail/class.ilPRGMail.php +++ b/Modules/StudyProgramme/classes/Mail/class.ilPRGMail.php @@ -73,7 +73,7 @@ protected function sendMail( string $body_template ): bool { $user_info = $assignment->getUserInformation(); - $gender = $user_info->getGender() ?? 'n'; + $gender = $user_info->getGender() ?: 'anonymous'; $name = implode(' ', [$user_info->getFirstname(), $user_info->getLastname()]); $login = $user_info->getLogin(); $prg_link = \ilLink::_getStaticLink(ilObjStudyProgramme::getRefIdFor($assignment->getRootId()), 'prg'); From 9c947f6947846ce28c87ca2772c7390441c425d2 Mon Sep 17 00:00:00 2001 From: Tim Schmitz Date: Mon, 12 Aug 2024 11:58:50 +0200 Subject: [PATCH 57/61] Group: display wait list default correctly (41862) --- Modules/Group/classes/class.ilObjGroupGUI.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/Group/classes/class.ilObjGroupGUI.php b/Modules/Group/classes/class.ilObjGroupGUI.php index ed0c3ddca57a..0b0b2cb36d5c 100755 --- a/Modules/Group/classes/class.ilObjGroupGUI.php +++ b/Modules/Group/classes/class.ilObjGroupGUI.php @@ -1606,6 +1606,8 @@ public function initForm(string $a_mode = 'edit', bool $a_omit_form_action = fal $wait->setValue('2'); } elseif ($this->object->isWaitingListEnabled()) { $wait->setValue('1'); + } else { + $wait->setValue('0'); } $lim->addSubItem($wait); From 693eb8b457e4e02d3d8b1ba6a8252fef7763019a Mon Sep 17 00:00:00 2001 From: Tim Schmitz Date: Mon, 12 Aug 2024 12:22:43 +0200 Subject: [PATCH 58/61] MetaData: fix copyright table layout --- .../MetaData/templates/default/tpl.show_copyright_row.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Services/MetaData/templates/default/tpl.show_copyright_row.html b/Services/MetaData/templates/default/tpl.show_copyright_row.html index 18ffe18bd2ec..75eee39e1b00 100644 --- a/Services/MetaData/templates/default/tpl.show_copyright_row.html +++ b/Services/MetaData/templates/default/tpl.show_copyright_row.html @@ -4,11 +4,11 @@ + - - + {VAL_TITLE} From f0398656baa0d8b590e421575884a7d96a13c1bc Mon Sep 17 00:00:00 2001 From: Fabian Wolf Date: Mon, 12 Aug 2024 15:48:25 +0200 Subject: [PATCH 59/61] #41875 fix array access --- Services/Tree/classes/class.ilMaterializedPathTree.php | 2 +- Services/Tree/classes/class.ilNestedSetTree.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Services/Tree/classes/class.ilMaterializedPathTree.php b/Services/Tree/classes/class.ilMaterializedPathTree.php index a0ee268187f6..e3c00f63fe0f 100644 --- a/Services/Tree/classes/class.ilMaterializedPathTree.php +++ b/Services/Tree/classes/class.ilMaterializedPathTree.php @@ -583,7 +583,7 @@ public function getSubtreeInfo(int $a_endnode_id): array */ public function validateParentRelations(): array { - $query = 'select child from ' . $this->getTree()->getTreeTable() . ' child where not exists ' . + $query = 'select ' . $this->getTree()->getTreePk() .', child from ' . $this->getTree()->getTreeTable() . ' child where not exists ' . '( ' . 'select child from ' . $this->getTree()->getTreeTable() . ' parent where child.parent = parent.child and ' . '(child.path BETWEEN parent.path AND CONCAT(parent.path,' . $this->db->quote('Z', 'text') . ') )' . ')' . diff --git a/Services/Tree/classes/class.ilNestedSetTree.php b/Services/Tree/classes/class.ilNestedSetTree.php index 5d40b8f1c966..c9b42161834c 100644 --- a/Services/Tree/classes/class.ilNestedSetTree.php +++ b/Services/Tree/classes/class.ilNestedSetTree.php @@ -955,7 +955,7 @@ public function getSubtreeInfo(int $a_endnode_id): array */ public function validateParentRelations(): array { - $query = 'select child from ' . $this->getTree()->getTreeTable() . ' child where not exists ' . + $query = 'select ' . $this->getTree()->getTreePk() .', child from ' . $this->getTree()->getTreeTable() . ' child where not exists ' . '( ' . 'select child from ' . $this->getTree()->getTreeTable() . ' parent where child.parent = parent.child and (parent.lft < child.lft) and (parent.rgt > child.rgt) ' . ')' . From 6d3d76f23045fd737998ec3bb61b19d3c62ab47b Mon Sep 17 00:00:00 2001 From: Tim Schmitz Date: Mon, 12 Aug 2024 15:52:46 +0200 Subject: [PATCH 60/61] MetaData: small changes to pre-installed copyright licences (41301, 41898) --- .../Setup/class.ilMDCopyrightMigration.php | 12 ++ .../Setup/class.ilMDCopyrightUpdateSteps.php | 104 +++++++++++++++++- Services/MetaData/docs/copyrights.md | 20 ++-- 3 files changed, 124 insertions(+), 12 deletions(-) diff --git a/Services/MetaData/classes/Setup/class.ilMDCopyrightMigration.php b/Services/MetaData/classes/Setup/class.ilMDCopyrightMigration.php index 57e150e93796..ad6f59894124 100644 --- a/Services/MetaData/classes/Setup/class.ilMDCopyrightMigration.php +++ b/Services/MetaData/classes/Setup/class.ilMDCopyrightMigration.php @@ -110,6 +110,7 @@ protected function extractFields(string $copyright): array } $image_link = $this->translatePreInstalledLinksToSVG($image_link); + $full_name = $this->cleanupPreInstalledPublicDomainFullName($full_name); return [ 'full_name' => [\ilDBConstants::T_TEXT, $full_name], @@ -143,4 +144,15 @@ protected function translatePreInstalledLinksToSVG(string $image_link): string } return $image_link; } + + /** + * see https://mantis.ilias.de/view.php?id=41301 + */ + protected function cleanupPreInstalledPublicDomainFullName(string $full_name): string + { + if ($full_name === 'This work has all rights reserved by the owner.') { + return 'All rights reserved'; + } + return $full_name; + } } diff --git a/Services/MetaData/classes/Setup/class.ilMDCopyrightUpdateSteps.php b/Services/MetaData/classes/Setup/class.ilMDCopyrightUpdateSteps.php index 732b771855f2..5cadc8b15e45 100644 --- a/Services/MetaData/classes/Setup/class.ilMDCopyrightUpdateSteps.php +++ b/Services/MetaData/classes/Setup/class.ilMDCopyrightUpdateSteps.php @@ -164,8 +164,6 @@ public function step_8(): void $old_image_link = "https://licensebuttons.net/p/zero/1.0/88x31.png"; $new_image_link = "https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg"; - $next_id = $this->db->nextId('il_md_cpr_selections'); - $res = $this->db->query( 'SELECT entry_id FROM il_md_cpr_selections WHERE title = ' . $this->db->quote($title, ilDBConstants::T_TEXT) . ' AND full_name = ' . @@ -180,4 +178,106 @@ public function step_8(): void ); } } + + /** + * Change title, description and full name of 'All rights reserved', + * see https://mantis.ilias.de/view.php?id=41301 + */ + public function step_9(): void + { + $title = "All rights reserved"; + $old_full_name = "This work has all rights reserved by the owner."; + $new_full_name = "All rights reserved"; + $new_description = "The copyright holder reserves, or holds for their own use, all the rights provided by copyright law."; + + $res = $this->db->query( + 'SELECT entry_id FROM il_md_cpr_selections WHERE title = ' . + $this->db->quote($title, ilDBConstants::T_TEXT) . ' AND full_name = ' . + $this->db->quote($old_full_name, ilDBConstants::T_TEXT) . + " AND COALESCE(link, '') = '' AND COALESCE(description, '') = ''" + ); + if (($row = $this->db->fetchAssoc($res)) && isset($row['entry_id'])) { + $this->db->update( + 'il_md_cpr_selections', + [ + 'full_name' => [\ilDBConstants::T_TEXT, $new_full_name], + 'description' => [\ilDBConstants::T_TEXT, $new_description] + ], + ['entry_id' => [\ilDBConstants::T_INTEGER, $row['entry_id']]] + ); + } + } + + /** + * Change title, description and full name of 'Public Domain', + * see https://mantis.ilias.de/view.php?id=41301 + */ + public function step_10(): void + { + $title = "Public Domain"; + $link = "http://creativecommons.org/publicdomain/zero/1.0/"; + $old_full_name = "This work is free of known copyright restrictions."; + $new_full_name = "Public Domain"; + $new_description = "Creative work to which no exclusive intellectual property rights apply."; + + $res = $this->db->query( + 'SELECT entry_id FROM il_md_cpr_selections WHERE title = ' . + $this->db->quote($title, ilDBConstants::T_TEXT) . ' AND full_name = ' . + $this->db->quote($old_full_name, ilDBConstants::T_TEXT) . ' AND link = ' . + $this->db->quote($link, ilDBConstants::T_TEXT) . + " AND COALESCE(description, '') = ''" + ); + if (($row = $this->db->fetchAssoc($res)) && isset($row['entry_id'])) { + $this->db->update( + 'il_md_cpr_selections', + [ + 'full_name' => [\ilDBConstants::T_TEXT, $new_full_name], + 'description' => [\ilDBConstants::T_TEXT, $new_description] + ], + ['entry_id' => [\ilDBConstants::T_INTEGER, $row['entry_id']]] + ); + } + } + + /** + * Change title of CC licences, see https://mantis.ilias.de/view.php?id=41898 + */ + public function step_11(): void + { + $old_titles_by_link = [ + 'http://creativecommons.org/licenses/by-nc-nd/4.0/' => 'Attribution Non-commercial No Derivatives (by-nc-nd)', + 'http://creativecommons.org/licenses/by-nc-sa/4.0/' => 'Attribution Non-commercial Share Alike (by-nc-sa)', + 'http://creativecommons.org/licenses/by-nc/4.0/' => 'Attribution Non-commercial (by-nc)', + 'http://creativecommons.org/licenses/by-nd/4.0/' => 'Attribution No Derivatives (by-nd)', + 'http://creativecommons.org/licenses/by-sa/4.0/' => 'Attribution Share Alike (by-sa)', + 'http://creativecommons.org/licenses/by/4.0/' => 'Attribution (by)' + ]; + $new_titles_by_link = [ + 'http://creativecommons.org/licenses/by-nc-nd/4.0/' => 'Attribution Non-commercial No Derivatives (BY-NC-ND) 4.0', + 'http://creativecommons.org/licenses/by-nc-sa/4.0/' => 'Attribution Non-commercial Share Alike (BY-NC-SA) 4.0', + 'http://creativecommons.org/licenses/by-nc/4.0/' => 'Attribution Non-commercial (BY-NC) 4.0', + 'http://creativecommons.org/licenses/by-nd/4.0/' => 'Attribution No Derivatives (BY-ND) 4.0', + 'http://creativecommons.org/licenses/by-sa/4.0/' => 'Attribution Share Alike (BY-SA) 4.0', + 'http://creativecommons.org/licenses/by/4.0/' => 'Attribution (BY) 4.0' + ]; + + foreach ($old_titles_by_link as $link => $old_title) { + $res = $this->db->query( + 'SELECT entry_id FROM il_md_cpr_selections WHERE title = ' . + $this->db->quote($old_title, ilDBConstants::T_TEXT) . ' AND link = ' . + $this->db->quote($link, ilDBConstants::T_TEXT) + ); + if ( + ($row = $this->db->fetchAssoc($res)) && + isset($row['entry_id']) && + isset($new_titles_by_link[$link]) + ) { + $this->db->update( + 'il_md_cpr_selections', + ['title' => [\ilDBConstants::T_TEXT, $new_titles_by_link[$link]]], + ['entry_id' => [\ilDBConstants::T_INTEGER, $row['entry_id']]] + ); + } + } + } } diff --git a/Services/MetaData/docs/copyrights.md b/Services/MetaData/docs/copyrights.md index 538c7c6ff6e0..d5f20f1468d2 100644 --- a/Services/MetaData/docs/copyrights.md +++ b/Services/MetaData/docs/copyrights.md @@ -13,16 +13,16 @@ version of the CC licenses. These can however be added manually. ## Pre-Installed Licenses -| Title | Full Name | URL | Image URL | -|------------------------------------------------------|------------------------------------------------------------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------| -| All rights reserved | This work has all rights reserved by the owner. | - | - | -| Attribution Non-commercial No Derivatives (by-nc-nd) | Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License | http://creativecommons.org/licenses/by-nc-nd/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-nd.svg | -| Attribution Non-commercial Share Alike (by-nc-sa) | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License | http://creativecommons.org/licenses/by-nc-sa/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg | -| Attribution Non-commercial (by-nc) | Creative Commons Attribution-NonCommercial 4.0 International License | http://creativecommons.org/licenses/by-nc/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc.svg | -| Attribution No Derivatives (by-nd) | Creative Commons Attribution-NoDerivatives 4.0 International License | http://creativecommons.org/licenses/by-nd/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nd.svg | -| Attribution Share Alike (by-sa) | Creative Commons Attribution-ShareAlike 4.0 International License | http://creativecommons.org/licenses/by-sa/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg | -| Attribution (by) | Creative Commons Attribution 4.0 International License | http://creativecommons.org/licenses/by/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg | -| Public Domain | This work is free of known copyright restrictions. | http://creativecommons.org/publicdomain/zero/1.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg | +| Title | Description | Full Name | URL | Image URL | +|----------------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------| +| All rights reserved | The copyright holder reserves, or holds for their own use, all the rights provided by copyright law. | All rights reserved | - | - | +| Attribution Non-commercial No Derivatives (BY-NC-ND) 4.0 | Creative Commons License | Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License | http://creativecommons.org/licenses/by-nc-nd/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-nd.svg | +| Attribution Non-commercial Share Alike (BY-NC-SA) 4.0 | Creative Commons License | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License | http://creativecommons.org/licenses/by-nc-sa/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg | +| Attribution Non-commercial (BY-NC) 4.0 | Creative Commons License | Creative Commons Attribution-NonCommercial 4.0 International License | http://creativecommons.org/licenses/by-nc/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc.svg | +| Attribution No Derivatives (BY-ND) 4.0 | Creative Commons License | Creative Commons Attribution-NoDerivatives 4.0 International License | http://creativecommons.org/licenses/by-nd/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nd.svg | +| Attribution Share Alike (BY-SA) 4.0 | Creative Commons License | Creative Commons Attribution-ShareAlike 4.0 International License | http://creativecommons.org/licenses/by-sa/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg | +| Attribution (BY) 4.0 | Creative Commons License | Creative Commons Attribution 4.0 International License | http://creativecommons.org/licenses/by/4.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg | +| Public Domain | Creative work to which no exclusive intellectual property rights apply. | Public Domain | http://creativecommons.org/publicdomain/zero/1.0/ | https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg | ## Default License From e06bbb7a1d36739bc97760caf3ce4e6e06f89aa9 Mon Sep 17 00:00:00 2001 From: Fabian Wolf Date: Mon, 12 Aug 2024 16:01:11 +0200 Subject: [PATCH 61/61] Fix typo in 'ilMaterializedPathTree::createFromParentRelation' call --- Services/Tree/classes/SystemCheck/class.ilSCTreeTasksGUI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Services/Tree/classes/SystemCheck/class.ilSCTreeTasksGUI.php b/Services/Tree/classes/SystemCheck/class.ilSCTreeTasksGUI.php index 5695ebac668d..07b800c7ab99 100644 --- a/Services/Tree/classes/SystemCheck/class.ilSCTreeTasksGUI.php +++ b/Services/Tree/classes/SystemCheck/class.ilSCTreeTasksGUI.php @@ -229,7 +229,7 @@ protected function repairStructure(): void $tasks = new ilSCTreeTasks($this->getTask()); if ($this->tree->getTreeImplementation() instanceof ilMaterializedPathTree) { - ilMaterializedPathTree::createFromParentReleation($this->db); + ilMaterializedPathTree::createFromParentRelation($this->db); } elseif ($this->tree->getTreeImplementation() instanceof ilNestedSetTree) { $this->tree->renumber(ROOT_FOLDER_ID); }