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; } } 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 @@ 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, @@ -171,7 +175,7 @@ public function getXmlRecord( return $a_set; } - + return parent::getXmlRecord($a_entity, $a_version, $a_set); } } 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(); 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 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"); } } 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; 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/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); } /** diff --git a/Modules/Forum/classes/GUI/ThreadSortation.php b/Modules/Forum/classes/GUI/ThreadSortation.php new file mode 100644 index 000000000000..41f8061b7933 --- /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.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 0b79a6bb0f23..47ebee046f2b 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,15 @@ 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) + ->withMaxPaginationButtons(5) + ->withCurrentPage($current_page); if ($found_threads === false) { $vc_container = $this->factory->panel()->listing()->standard( @@ -863,7 +851,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); @@ -883,27 +871,32 @@ 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 +904,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 +965,6 @@ private function retrieveThreadIds(): array /** * @return array - * @throws ilCtrlException */ protected function getThreadProperties(ilForumTopic $forum_topic): array { @@ -1059,16 +1023,13 @@ 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; $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); diff --git a/Modules/Group/classes/class.ilObjGroupGUI.php b/Modules/Group/classes/class.ilObjGroupGUI.php index ec52b58bfc5f..0b0b2cb36d5c 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, @@ -1607,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); 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") . ")"; 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. + 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/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); } 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; 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'); 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/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")); 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 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']); + } } 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'); diff --git a/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php b/Services/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php index fac51fe93b0c..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; + } } 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()); }); } 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 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 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()); 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 79df76a2b6a1..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() ); } @@ -1027,24 +1027,27 @@ protected static function initLanguage(bool $a_use_user_language = true): void protected static function initAccessHandling(): void { self::initGlobal( - "rbacreview", - "ilRbacReview", - "./Services/AccessControl/classes/class.ilRbacReview.php" + 'rbacreview', + 'ilRbacReview', + './Services/AccessControl/classes/class.ilRbacReview.php', + true ); $rbacsystem = ilRbacSystem::getInstance(); - self::initGlobal("rbacsystem", $rbacsystem); + self::initGlobal('rbacsystem', $rbacsystem, null, true); self::initGlobal( - "rbacadmin", - "ilRbacAdmin", - "./Services/AccessControl/classes/class.ilRbacAdmin.php" + 'rbacadmin', + 'ilRbacAdmin', + './Services/AccessControl/classes/class.ilRbacAdmin.php', + true ); self::initGlobal( - "ilAccess", - "ilAccess", - "./Services/AccessControl/classes/class.ilAccess.php" + 'ilAccess', + 'ilAccess', + './Services/AccessControl/classes/class.ilAccess.php', + true ); } @@ -1061,18 +1064,28 @@ protected static function initLog(): void } /** - * Initialize global instance - * @param string $a_name - * @param string|object $a_class - * @param ?string $a_source_file + * @param object|string $a_class */ - protected static function initGlobal($a_name, $a_class, $a_source_file = null): void - { + protected static function initGlobal( + string $a_name, + $a_class, + ?string $a_source_file = null, + ?bool $destroy_existing = false + ): void { global $DIC; + if ($destroy_existing) { + if (isset($GLOBALS[$a_name])) { + unset($GLOBALS[$a_name]); + } + if (isset($DIC[$a_name])) { + unset($DIC[$a_name]); + } + } + $GLOBALS[$a_name] = is_object($a_class) ? $a_class : new $a_class(); - $DIC[$a_name] = function ($c) use ($a_name) { + $DIC[$a_name] = static function (Container $c) use ($a_name) { return $GLOBALS[$a_name]; }; } @@ -1173,7 +1186,11 @@ public static function initILIAS(): void */ protected static function initSession(): void { - $GLOBALS["DIC"]["ilAuthSession"] = function ($c) { + if (isset($GLOBALS['DIC']['ilAuthSession'])) { + unset($GLOBALS['DIC']['ilAuthSession']); + } + + $GLOBALS['DIC']['ilAuthSession'] = static function (Container $c): ilAuthSession { $auth_session = ilAuthSession::getInstance( $c['ilLoggerFactory']->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/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', 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 @@ + 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) { diff --git a/Services/LDAP/classes/class.ilLDAPSettingsGUI.php b/Services/LDAP/classes/class.ilLDAPSettingsGUI.php index 8d407015ae2a..d95ee9785f60 100644 --- a/Services/LDAP/classes/class.ilLDAPSettingsGUI.php +++ b/Services/LDAP/classes/class.ilLDAPSettingsGUI.php @@ -805,7 +805,7 @@ private function initForm(): void $pass = new ilPasswordInputGUI($this->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')); 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); 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"); diff --git a/Services/Mail/classes/class.ilMail.php b/Services/Mail/classes/class.ilMail.php index a103b492124d..6699654a6000 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->mail_file_data + ))->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..0762ef2ff299 --- /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->getPathname()); + } + } catch (Exception $e) { + $this->logger->error('Error deleting file from attachment stage: ' . $file->getPathname()); + } + } + } + } +} 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/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 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 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} 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']) 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"] = ""; } 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/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]); 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 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 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); } 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) ' . ')' . 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); 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(); 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") + ); + } } /** 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", diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index b3f37dcae4e5..3308eae8ce0d 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' @@ -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..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. @@ -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. 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); } 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. 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/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/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/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..299a82bac809 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 { @@ -3838,7 +3839,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; @@ -6268,7 +6269,7 @@ footer { */ .c-mode-info { display: flex; - position: absolute; + position: fixed; z-index: 1010; width: 100%; align-items: start; @@ -6547,7 +6548,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, 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