From 83d19eb62d9b26754e65092b909f55467080de6a Mon Sep 17 00:00:00 2001 From: Lukas Zehnder Date: Tue, 15 Oct 2024 09:52:22 +0200 Subject: [PATCH 01/75] [FEATURE] Bibliographic: replaced old entry ilTable2GUI implementation with new ui components --- .../Entry/class.ilBiblEntryTableGUI.php | 313 ++++++++++++------ ...class.ilBiblFieldFilterPresentationGUI.php | 29 +- .../classes/class.ilObjBibliographicGUI.php | 5 +- lang/ilias_de.lang | 21 +- lang/ilias_en.lang | 9 +- 5 files changed, 252 insertions(+), 125 deletions(-) diff --git a/components/ILIAS/Bibliographic/classes/Entry/class.ilBiblEntryTableGUI.php b/components/ILIAS/Bibliographic/classes/Entry/class.ilBiblEntryTableGUI.php index b61d95778a05..598b07ea486c 100755 --- a/components/ILIAS/Bibliographic/classes/Entry/class.ilBiblEntryTableGUI.php +++ b/components/ILIAS/Bibliographic/classes/Entry/class.ilBiblEntryTableGUI.php @@ -1,5 +1,14 @@ - * @author Fabian Schmid - * - * @deprecated REFACTOR - */ -class ilBiblEntryTableGUI extends ilTable2GUI + +class ilBiblEntryTableGUI { - /** - * @var \ilBiblFieldFilterInterface[] - */ + public const P_PAGE = 'page'; + public const P_SORTATION = 'sortation'; + public const SORTATION_BY_TITLE_ASC = 1; + public const SORTATION_BY_TITLE_DESC = 2; + public const SORTATION_BY_AUTHOR_ASC = 3; + public const SORTATION_BY_AUTHOR_DESC = 4; + public const SORTATION_BY_YEAR_ASC = 5; + public const SORTATION_BY_YEAR_DESC = 6; + + + private HttpServices $http; + private ilLanguage $lng; + private UIFactory $ui_factory; + private Renderer $ui_renderer; + private ilCtrlInterface $ctrl; + private Factory $refinery; + private int $current_page = 0; + private int $entries_per_page = 10; + private ilUIService $ui_service; + private ?StandardFilter $filter; + private PresentationTable $table; + + /** @var ilBiblFieldFilterInterface[] */ protected array $filter_objects = array(); - protected array $applied_filter = array(); - /** - * ilBiblEntryTableGUI constructor. - */ - public function __construct(protected ilObjBibliographicGUI $a_parent_obj, protected ilBiblFactoryFacade $facade, protected \ILIAS\DI\UIServices $ui) + public function __construct(protected ilObjBibliographicGUI $a_parent_obj, protected ilBiblFactoryFacade $facade, protected UIServices $ui) { - $this->setId('tbl_bibl_overview_' . $facade->iliasRefId()); - $this->setPrefix('tbl_bibl_overview_' . $facade->iliasRefId()); - $this->setFormName('tbl_bibl_overview_' . $facade->iliasRefId()); - parent::__construct($a_parent_obj, ilObjBibliographicGUI::CMD_VIEW); - - //Number of records - $this->setEnableNumInfo(true); - $this->setShowRowsSelector(true); - - $this->setEnableHeader(false); - $this->setFormAction($this->ctrl->getFormAction($a_parent_obj)); - $this->setRowTemplate('tpl.bibliographic_record_table_row.html', 'components/ILIAS/Bibliographic'); - // enable sorting by alphabet -- therefore an unvisible column 'content' is added to the table, and the array-key 'content' is also delivered in setData - $this->addColumn($this->lng->txt('a'), 'content', 'auto'); - $this->initFilter(); - $this->setOrderField('content'); - $this->setExternalSorting(true); - $this->initData(); - $this->setDefaultOrderField('content'); + global $DIC; + $this->ctrl = $DIC->ctrl(); + $this->http = $DIC->http(); + $this->lng = $DIC->language(); + $this->ui_factory = $DIC->ui()->factory(); + $this->ui_renderer = $DIC->ui()->renderer(); + $this->ui_service = $DIC->uiService(); + $this->refinery = $DIC->refinery(); + $this->ctrl->saveParameterByClass(ilObjBibliographicGUI::class, self::P_PAGE); + $this->ctrl->saveParameterByClass(ilObjBibliographicGUI::class, self::P_SORTATION); + + $this->filter = $this->buildFilter(); + $this->table = $this->buildTable(); } + public function getRenderedTableAndExistingFilters(): string + { + if ($this->filter !== null) { + $components[] = $this->filter; + } + $components[] = $this->table; + return $this->ui_renderer->render($components); + } - public function initFilter(): void + protected function buildFilter(): ?StandardFilter { - $available_field_ids_for_object = array_map(function (ilBiblField $field) { + $filter_objects = $this->facade->filterFactory()->getAllForObjectId($this->facade->iliasObjId()); + if (empty($filter_objects)) { + return null; + } + + $available_field_ids_for_object = array_map(static function (ilBiblField $field) { return $field->getId(); }, $this->facade->fieldFactory()->getAvailableFieldsForObjId($this->facade->iliasObjId())); - foreach ($this->facade->filterFactory()->getAllForObjectId($this->facade->iliasObjId()) as $item) { - if (in_array($item->getFieldId(), $available_field_ids_for_object)) { - $filter_presentation = new ilBiblFieldFilterPresentationGUI($item, $this->facade); - $field = $filter_presentation->getFilterItem(); - $this->addAndReadFilterItem($field); - $this->filter_objects[$field->getPostVar()] = $item; + $filter_inputs = []; + $filter_active_states = []; + foreach ($filter_objects as $filter_object) { + if (in_array($filter_object->getFieldId(), $available_field_ids_for_object, true)) { + $filter_presentation = new ilBiblFieldFilterPresentationGUI($filter_object, $this->facade); + $field = $this->facade->fieldFactory()->findById($filter_object->getFieldId()); + $post_var = $field->getIdentifier(); + $filter_input = $filter_presentation->getFilterInput(); + $filter_inputs[$post_var] = $filter_input; + $filter_active_states[] = true; + $this->filter_objects[$post_var] = $filter_object; } } - } + return $this->ui_service->filter()->standard( + 'bibl_entry_filter', + $this->ctrl->getLinkTargetByClass( + ilObjBibliographicGUI::class, + ilObjBibliographicGUI::CMD_SHOW_CONTENT, + "", + true + ), + $filter_inputs, + $filter_active_states, + true, + true + ); + } - /** - * @param $field - */ - protected function addAndReadFilterItem(ilTableFilterItem $field): void + protected function buildTable(): PresentationTable { - $this->addFilterItem($field); - $field->readFromSession(); - if ($field instanceof ilCheckboxInputGUI) { - $this->applied_filter[$field->getPostVar()] = $field->getChecked(); - ; - } else { - $this->applied_filter[$field->getPostVar()] = $field->getValue(); + $records = $this->getData(); + $sorted_records = $this->getSortedRecords($records); + $this->current_page = $this->determinePage(); + $records_current_page = $this->getRecordsOfCurrentPage($sorted_records); + $view_controls = []; + $sortations = []; + foreach (array_keys($this->getSortationsMapping()) as $sort_id) { + $sortations[$sort_id] = $this->lng->txt('sorting_' . $sort_id); } - } - + $view_controls[] = $this->ui_factory->viewControl()->sortation($sortations) + ->withTargetURL( + $this->ctrl->getLinkTargetByClass(ilObjBibliographicGUI::class, ilObjBibliographicGUI::CMD_SHOW_CONTENT), + self::P_SORTATION + )->withLabel($this->lng->txt('sorting_' . $this->determineSortation())); + $view_controls[] = $this->ui_factory->viewControl()->pagination() + ->withTargetURL($this->http->request()->getRequestTarget(), self::P_PAGE) + ->withTotalEntries(count($records)) + ->withPageSize($this->entries_per_page) + ->withCurrentPage($this->current_page); + return $this->ui_factory->table()->presentation( + "", + $view_controls, + function ( + PresentationRow $row, + array $record, + UIFactory $ui_factory + ): PresentationRow { + // Create row with fields and actions + $author = $record['author'] ?? ''; + $title = $record['title'] ?? ''; + $year = $record['year'] ?? ''; + unset($record['author'], $record['title']); + $translated_record = $this->getRecordWithTranslatedKeys($record); - public function fillRow(array $a_set): void - { - /** @var ilBiblEntryTablePresentationGUI $presentation_gui */ - $presentation_gui = $a_set['overview_gui']; - $this->tpl->setVariable( - 'SINGLE_ENTRY', - $presentation_gui->getHtml() - ); - //Detail-Link - $this->ctrl->setParameter($this->parent_obj, ilObjBibliographicGUI::P_ENTRY_ID, $a_set['entry_id']); - $this->tpl->setVariable('DETAIL_LINK', $this->ctrl->getLinkTarget($this->parent_obj, 'showDetails')); - // generate/render links to libraries - $libraries = $this->facade->libraryFactory()->getAll(); - $arr_library_link = array(); - foreach ($libraries as $library) { - if ($library->getShowInList()) { - $presentation = new ilBiblLibraryPresentationGUI($library, $this->facade); - $arr_library_link[] = $presentation->getButton($this->facade, $presentation_gui->getEntry()); + return $row + ->withHeadline($title) + ->withSubheadline($author) + ->withImportantFields([$year]) + ->withContent( $ui_factory->listing()->descriptive($translated_record)); } - } - if ($arr_library_link !== []) { - $this->tpl->setVariable('LIBRARY_LINK', implode('
', $arr_library_link)); - } + )->withData($records_current_page); } - protected function initData(): void + protected function getData(): array { $query = new ilBiblTableQueryInfo(); - /** - * @var $filter \ilBiblFieldFilterInterface - */ - foreach ($this->applied_filter as $field_name => $field_value) { - if (!$field_value || (is_array($field_value) && count($field_value) == 0)) { + + $filter_data = ($this->filter !== null) ? ($this->ui_service->filter()->getData($this->filter) ?? []) : []; + foreach ($filter_data as $field_name => $field_value) { + if (empty($field_value) || (is_array($field_value) && count($field_value) === 0)) { continue; } $filter = $this->filter_objects[$field_name]; @@ -141,7 +187,7 @@ protected function initData(): void $filter_info->setOperator("="); break; case ilBiblFieldFilterInterface::FILTER_TYPE_TEXT_INPUT: - $filter_info->setFieldValue("%{$field_value}%"); + $filter_info->setFieldValue("%$field_value%"); $filter_info->setOperator("LIKE"); break; } @@ -149,24 +195,91 @@ protected function initData(): void $query->addFilter($filter_info); } - $entries = []; + $bibl_data = []; $object_id = $this->facade->iliasObjId(); - foreach ( - $this->facade->entryFactory() - ->filterEntryIdsForTableAsArray($object_id, $query) as $entry - ) { + $entries = $this->facade->entryFactory()->filterEntryIdsForTableAsArray($object_id, $query); + + foreach ($entries as $entry) { /** @var $bibl_entry ilBiblEntry */ $bibl_entry = $this->facade->entryFactory()->findByIdAndTypeString($entry['entry_id'], $entry['entry_type']); - $overview_gui = new ilBiblEntryTablePresentationGUI($bibl_entry, $this->facade); - $entry['content'] = strip_tags($overview_gui->getHtml()); - $entry['overview_gui'] = $overview_gui; - $entries[] = $entry; + $entry_attributes = $this->facade->attributeFactory()->getAttributesForEntry($bibl_entry); + $sorted_attributes = $this->facade->attributeFactory()->sortAttributes($entry_attributes); + $entry_data = []; + foreach ($sorted_attributes as $sorted_attribute) { + $entry_data[$sorted_attribute->getName()] = $sorted_attribute->getValue(); + } + if(!array_key_exists('author', $entry_data)) { + $entry_data['author'] = ''; + } + if(!array_key_exists('title', $entry_data)) { + $entry_data['title'] = ''; + } + if(!array_key_exists('year', $entry_data)) { + $entry_data['year'] = ''; + } + $bibl_data[] = $entry_data; } - usort($entries, function ($a, $b) { - return strcmp($a['content'], $b['content']); - }); + return $bibl_data; + } + + protected function getSortedRecords(array $records): array + { + $sortation = $this->determineSortation(); + $sortation_mapping = $this->getSortationsMapping(); + $sortation_string = $sortation_mapping[$sortation]; + $sortation_parts = explode(' ', $sortation_string); + $sortation_field = array_column($records, $sortation_parts[0]); + $sortation_direction = ($sortation_parts[1] === 'ASC') ? SORT_ASC : SORT_DESC; + array_multisort($sortation_field, $sortation_direction, $records); + return $records; + } + + + protected function getRecordsOfCurrentPage(array $records): array + { + $offset = array_search($this->current_page * $this->entries_per_page, array_keys($records), true); + $length = $this->entries_per_page; + return array_slice($records, $offset, $length); + } + - $this->setData($entries); + protected function getRecordWithTranslatedKeys(array $record): array + { + $translated_record = []; + foreach ($record as $key => $value) { + /** @var ilBiblField $field */ + $field = ilBiblField::where(['identifier' => $key])->first(); + $translated_key = $this->facade->translationFactory()->translate($field); + $translated_record[$translated_key] = $value; + } + return $translated_record; + } + + + private function determinePage(): int + { + return $this->http->wrapper()->query()->has(self::P_PAGE) + ? $this->http->wrapper()->query()->retrieve(self::P_PAGE, $this->refinery->kindlyTo()->int()) + : 0; + } + + private function determineSortation(): int + { + return $this->http->wrapper()->query()->has(self::P_SORTATION) + ? $this->http->wrapper()->query()->retrieve(self::P_SORTATION, $this->refinery->kindlyTo()->int()) + : array_keys($this->getSortationsMapping())[0] ?? self::SORTATION_BY_TITLE_ASC; + } + + public function getSortationsMapping(): array + { + return [ + self::SORTATION_BY_TITLE_ASC => 'title ASC', + self::SORTATION_BY_TITLE_DESC => 'title DESC', + self::SORTATION_BY_AUTHOR_ASC => 'author ASC', + self::SORTATION_BY_AUTHOR_DESC => 'author DESC', + self::SORTATION_BY_YEAR_ASC => 'year ASC', + self::SORTATION_BY_YEAR_DESC => 'year DESC' + ]; } } diff --git a/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterPresentationGUI.php b/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterPresentationGUI.php index bb3a51248695..7298c8041f5c 100755 --- a/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterPresentationGUI.php +++ b/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterPresentationGUI.php @@ -16,6 +16,10 @@ * *********************************************************************/ +use ILIAS\UI\Component\Input\Field\MultiSelect; +use ILIAS\UI\Component\Input\Field\Select; +use ILIAS\UI\Component\Input\Field\Text; + /** * Class ilBiblFieldFilterPresentationGUI * @@ -24,14 +28,14 @@ class ilBiblFieldFilterPresentationGUI { use \ILIAS\components\OrgUnit\ARHelper\DIC; - protected \ilBiblFactoryFacadeInterface $facade; - protected \ilBiblFieldFilterInterface $filter; + protected ilBiblFactoryFacadeInterface $facade; + protected ilBiblFieldFilterInterface $filter; /** * ilBiblFieldFilterPresentationGUI constructor. */ - public function __construct(\ilBiblFieldFilterInterface $filter, ilBiblFactoryFacadeInterface $facade) + public function __construct(ilBiblFieldFilterInterface $filter, ilBiblFactoryFacadeInterface $facade) { $this->facade = $facade; $this->filter = $filter; @@ -39,7 +43,7 @@ public function __construct(\ilBiblFieldFilterInterface $filter, ilBiblFactoryFa } - public function getFilterItem(): \ilTableFilterItem + public function getFilterInput(): MultiSelect|Select|Text { $field = $this->facade->fieldFactory()->findById($this->getFilter()->getFieldId()); $translated = $this->facade->translationFactory()->translate($field); @@ -51,34 +55,31 @@ public function getFilterItem(): \ilTableFilterItem switch ($ilBiblFieldFilter->getFilterType()) { case ilBiblFieldFilterInterface::FILTER_TYPE_TEXT_INPUT: - $filter = new ilTextInputGUI($translated, $field->getIdentifier()); + $filter_input = $this->ui()->factory()->input()->field()->text($translated); break; case ilBiblFieldFilterInterface::FILTER_TYPE_SELECT_INPUT: - $filter = new ilSelectInputGUI($translated, $field->getIdentifier()); - $options[null] = $this->lng()->txt("please_select"); - $options += $f->getPossibleValuesForFieldAndObject($field, $obj_id); - $filter->setOptions($options); + $options = $f->getPossibleValuesForFieldAndObject($field, $obj_id); + $filter_input = $this->ui()->factory()->input()->field()->select($translated, $options); break; case ilBiblFieldFilterInterface::FILTER_TYPE_MULTI_SELECT_INPUT: - $filter = new ilMultiSelectInputGUI($translated, $field->getIdentifier()); $options = $f->getPossibleValuesForFieldAndObject($field, $obj_id); - $filter->setOptions($options); + $filter_input = $this->ui()->factory()->input()->field()->multiSelect($translated, $options); break; default: throw new LogicException('no filter type used'); } - return $filter; + return $filter_input; } - public function getFilter(): \ilBiblFieldFilterInterface + public function getFilter(): ilBiblFieldFilterInterface { return $this->filter; } - public function setFilter(\ilBiblFieldFilterInterface $filter): void + public function setFilter(ilBiblFieldFilterInterface $filter): void { $this->filter = $filter; } diff --git a/components/ILIAS/Bibliographic/classes/class.ilObjBibliographicGUI.php b/components/ILIAS/Bibliographic/classes/class.ilObjBibliographicGUI.php index c2ccd75dbece..94e8425e221d 100755 --- a/components/ILIAS/Bibliographic/classes/class.ilObjBibliographicGUI.php +++ b/components/ILIAS/Bibliographic/classes/class.ilObjBibliographicGUI.php @@ -710,9 +710,8 @@ public function showContent(): void ); $this->toolbar->addComponent($btn_overwrite_bibliographic_file); - $table = new ilBiblEntryTableGUI($this, $this->facade, $this->ui()); - $html = $table->getHTML(); - $DIC->ui()->mainTemplate()->setContent($html); + $table_gui = new ilBiblEntryTableGUI($this, $this->facade, $this->ui()); + $DIC->ui()->mainTemplate()->setContent($table_gui->getRenderedTableAndExistingFilters()); //Permanent Link $DIC->ui()->mainTemplate()->setPermanentLink("bibl", $this->object->getRefId()); diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 0590b61aaa8f..28017e47ee1e 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -2308,7 +2308,7 @@ bibl#:#Type#:#Typ bibl#:#add_filter#:#Felder hinzufügen bibl#:#bib_default_abstract#:#Abstract bibl#:#bib_default_address#:#Adresse -bibl#:#bib_default_author#:#Autor +bibl#:#bib_default_author#:#Autor:in bibl#:#bib_default_cite#:#Bib Cite bibl#:#bib_default_edition#:#Auflage bibl#:#bib_default_howpublished#:#Publikations-Typ @@ -2320,7 +2320,7 @@ bibl#:#bib_default_note#:#Notiz bibl#:#bib_default_number#:#Nummer bibl#:#bib_default_organization#:#Organisation bibl#:#bib_default_pages#:#Seiten -bibl#:#bib_default_publisher#:#Verleger +bibl#:#bib_default_publisher#:#Verleger:in bibl#:#bib_default_series#:#Serie bibl#:#bib_default_title#:#Titel bibl#:#bib_default_type#:#Typ @@ -2350,6 +2350,7 @@ bibl#:#bibtex#:#Bibtex bibl#:#changes_saved#:#Die Änderungen wurden gespeichert. bibl#:#custom#:#Benutzerdefiniert bibl#:#detail_view#:#Detailansicht +bibl#:#detailed_information#:#Detaillierte Informationen bibl#:#download_original_file#:#Original-Datei herunterladen bibl#:#field#:#Feld bibl#:#fields#:#Felder @@ -2373,8 +2374,8 @@ bibl#:#override_entries#:#Einträge überschreiben bibl#:#replace_bibliography_file#:#Literaturliste ersetzen bibl#:#replace_bibliography_file_info#:#Die aktuelle Literaturlisten-Datei wird durch die neue Datei ersetzt. Alle vorhandenen Einträge der aktuellen Datei werden dabei gelöscht. bibl#:#ris#:#Ris -bibl#:#ris_default_a2#:#Zweiter Autor -bibl#:#ris_default_au#:#Autor +bibl#:#ris_default_a2#:#Zweite:r Autor:in +bibl#:#ris_default_au#:#Autor:in bibl#:#ris_default_cy#:#Herausgabeort bibl#:#ris_default_ep#:#letzte Seite bibl#:#ris_default_id#:#Referenz-ID @@ -2385,7 +2386,7 @@ bibl#:#ris_default_m1#:#Nummer bibl#:#ris_default_m3#:#Misc. 3 bibl#:#ris_default_n1#:#Notizen bibl#:#ris_default_n2#:#Abstract -bibl#:#ris_default_pb#:#Herausgeber +bibl#:#ris_default_pb#:#Herausgeber:in bibl#:#ris_default_py#:#Erscheinungsjahr bibl#:#ris_default_sn#:#ISSN/ISBN/ASIN bibl#:#ris_default_t1#:#Haupttitel @@ -2397,6 +2398,12 @@ bibl#:#ris_default_u2#:#Benutzerdefiniert bibl#:#ris_default_ur#:#URL bibl#:#ris_default_vl#:#Volume bibl#:#ris_default_y1#:#Jahr +bibl#:#sorting_1#:#Titel (aufsteigend) +bibl#:#sorting_2#:#Titel (absteigend) +bibl#:#sorting_3#:#Autor:in (aufsteigend) +bibl#:#sorting_4#:#Autor:in (absteigend) +bibl#:#sorting_5#:#Jahr (aufsteigend) +bibl#:#sorting_6#:#Jahr (absteigend) bibl#:#standard#:#Standard bibl#:#translate#:#Übersetzen bkm#:#bkm_fold_created#:#Bookmark-Ordner wurde angelegt. @@ -8527,7 +8534,7 @@ dcl#:#dcl_add_perm_desc#:#Es können Einträge in dieser Tabelle erstellt werden dcl#:#dcl_additional_info_desc#:#Der Inhalt wird oberhalb der Tabelle angezeigt. dcl#:#dcl_all_entries#:#Alle Einträge dcl#:#dcl_any#:#Alle -dcl#:#dcl_asc#:#Aufsteigend ↑ +dcl#:#dcl_asc#:#Aufsteigend ↑ dcl#:#dcl_boolean#:#Checkbox dcl#:#dcl_boolean_desc#:#Kontrollkästchen, das abgehakt werden kann dcl#:#dcl_cant_delete_last_table#:#Die Tabelle selbst kann nicht gelöscht werden, da sie die einzige Tabelle dieser Datensammlung ist. Es wurden aber Inhalt und Struktur der Tabelle erfolgreich gelöscht. @@ -17678,4 +17685,4 @@ wsp#:#wsp_type_ltiv#:#Zertifikat: LTI-Konsument wsp#:#wsp_type_scov#:#Zertifikat: SCORM wsp#:#wsp_type_tstv#:#Zertifikat: Test wsp#:#wsp_type_webr#:#Weblink -wsp#:#wsp_type_wfld#:#Ordner \ No newline at end of file +wsp#:#wsp_type_wfld#:#Ordner diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 8ab32d367ca4..500bd3469826 100755 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -2350,6 +2350,7 @@ bibl#:#bibtex#:#Bibtex bibl#:#changes_saved#:#Changes were saved. bibl#:#custom#:#Custom bibl#:#detail_view#:#Detail View +bibl#:#detailed_information#:#Detailed Information bibl#:#download_original_file#:#Download Original File bibl#:#field#:#Field bibl#:#fields#:#Fields @@ -2397,6 +2398,12 @@ bibl#:#ris_default_u2#:#User Defined bibl#:#ris_default_ur#:#URL bibl#:#ris_default_vl#:#Volume bibl#:#ris_default_y1#:#Year +bibl#:#sorting_1#:#By Title (Ascending) +bibl#:#sorting_2#:#By Title (Descending) +bibl#:#sorting_3#:#By Author (Ascending) +bibl#:#sorting_4#:#By Author (Descending) +bibl#:#sorting_5#:#By Year (Ascending) +bibl#:#sorting_6#:#By Year (Descending) bibl#:#standard#:#Standard bibl#:#translate#:#Translate bkm#:#bkm_fold_created#:#Bookmark folder has been created. @@ -17658,4 +17665,4 @@ wsp#:#wsp_type_ltiv#:#Certificate: LTI Consumer wsp#:#wsp_type_scov#:#Certificate: SCORM wsp#:#wsp_type_tstv#:#Certificate: Test wsp#:#wsp_type_webr#:#Weblink -wsp#:#wsp_type_wfld#:#Folder \ No newline at end of file +wsp#:#wsp_type_wfld#:#Folder From 203a6c6d7f214b4ce14192173fbd26e4c3a1a55f Mon Sep 17 00:00:00 2001 From: Lukas Zehnder Date: Tue, 22 Oct 2024 09:31:33 +0200 Subject: [PATCH 02/75] [FIX] Bibliographic: Fixed issues with filter creation and editing --- .../class.ilBiblFieldFilterFormGUI.php | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterFormGUI.php b/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterFormGUI.php index de087499aab3..5024d90984e5 100755 --- a/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterFormGUI.php +++ b/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterFormGUI.php @@ -39,10 +39,7 @@ public function __construct(ilBiblFieldFilterGUI $parent_gui, ilBiblFieldFilterI $this->facade = $facade; $this->filter = $field_filter; $this->parent_gui = $parent_gui; - $q = $this->http()->wrapper()->query(); - $this->filter_id = $q->has(ilBiblFieldFilterGUI::FILTER_ID) - ? $q->retrieve(ilBiblFieldFilterGUI::FILTER_ID, $this->dic()->refinery()->kindlyTo()->int()) - : null; + $this->filter_id = $this->filter->getId(); $this->lng()->loadLanguageModule('bibl'); $this->ctrl()->saveParameterByClass(ilBiblFieldFilterGUI::class, ilBiblFieldFilterGUI::FILTER_ID); @@ -57,24 +54,24 @@ public function initForm(): void $this->setTarget('_top'); $available_fields_for_object = $this->facade->fieldFactory()->getAvailableFieldsForObjId($this->facade->iliasObjId()); - if (null !== $this->filter_id) { + if (null !== $this->filter_id && $this->filter_id > 0) { $edited_filter = $this->facade->filterFactory()->findById($this->filter_id); } + $existing_fields_of_object = $this->facade->filterFactory()->getAllForObjectId($this->facade->iliasObjId()); + $existing_field_ids = []; + foreach ($existing_fields_of_object as $existing_field) { + $existing_field_ids[] = $existing_field->getFieldId(); + } //show only the fields as options which don't have already a filter $options = []; foreach ($available_fields_for_object as $available_field) { - if (empty($this->facade->filterFactory()->findByFieldId($available_field->getId())) - || (!empty($edited_filter) - && $edited_filter->getFieldId() == $available_field->getId()) - ) { - if (!empty($edited_filter) - && $edited_filter->getFieldId() == $available_field->getId() - ) { - array_unshift($options, $available_field); - continue; - } + if (isset($edited_filter) && $edited_filter->getFieldId() === $available_field->getId()) { + array_unshift($options, $available_field); + continue; + } + if(!in_array($available_field->getId(), $existing_field_ids, false)) { $options[] = $available_field; } } From 988b6ea87160dc94e6898fe703ae26f0cad96339 Mon Sep 17 00:00:00 2001 From: Lukas Zehnder Date: Tue, 22 Oct 2024 11:13:50 +0200 Subject: [PATCH 03/75] [FIX] Bibliographic: fixed bug with request filter retrieval which caused editing to update the wrong filter --- .../classes/FieldFilter/class.ilBiblFieldFilterGUI.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterGUI.php b/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterGUI.php index d091b9b9cb06..af39bffbd268 100755 --- a/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterGUI.php +++ b/components/ILIAS/Bibliographic/classes/FieldFilter/class.ilBiblFieldFilterGUI.php @@ -246,7 +246,10 @@ private function getFieldFilterFromRequest(): \ilBiblFieldFilterInterface $token = $table->getIdToken()->getName(); if (isset($this->http->request()->getQueryParams()[$token])) { $field_id = $this->http->request()->getQueryParams()[$token] ?? null; - return $this->facade->filterFactory()->findById($field_id[0] ?? 0); + if (is_array($field_id)) { + $field_id = $field_id[0]; + } + return $this->facade->filterFactory()->findById($field_id ?? 0); } $field = $this->http->request()->getQueryParams()[self::FILTER_ID]; From fcf44d630e2b463799ea27cfbf7b6e2d243efd5f Mon Sep 17 00:00:00 2001 From: Lukas Zehnder Date: Tue, 22 Oct 2024 15:07:50 +0200 Subject: [PATCH 04/75] [FEATURE] Bibliographic: replaced old library ilTable2GUI implementation with new ui components --- .../Library/class.ilBiblLibraryFormGUI.php | 4 +- .../Admin/Library/class.ilBiblLibraryGUI.php | 79 +++---- .../Library/class.ilBiblLibraryTableGUI.php | 213 ++++++++++++++---- 3 files changed, 202 insertions(+), 94 deletions(-) diff --git a/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryFormGUI.php b/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryFormGUI.php index f5c748a16f70..a075b89bd1aa 100755 --- a/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryFormGUI.php +++ b/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryFormGUI.php @@ -26,7 +26,7 @@ class ilBiblLibraryFormGUI extends ilPropertyFormGUI { use \ILIAS\components\OrgUnit\ARHelper\DIC; - protected \ilBiblLibraryInterface $object; + protected ilBiblLibraryInterface $object; /** @@ -35,7 +35,7 @@ class ilBiblLibraryFormGUI extends ilPropertyFormGUI public function __construct(ilBiblLibraryInterface $library) { $this->object = $library; - $this->ctrl()->saveParameterByClass(ilBiblLibraryGUI::class, ilBiblLibraryGUI::F_LIB_ID); + $this->ctrl()->setParameterByClass(ilBiblLibraryGUI::class, ilBiblLibraryGUI::F_LIB_ID, $library->getId()); $this->initForm(); if ($this->object->getId()) { diff --git a/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryGUI.php b/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryGUI.php index 9e96c96f842f..634a99031fce 100755 --- a/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryGUI.php +++ b/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryGUI.php @@ -25,6 +25,7 @@ class ilBiblLibraryGUI { use \ILIAS\components\OrgUnit\ARHelper\DIC; public const F_LIB_ID = 'lib_id'; + public const F_LIB_IDS = 'lib_ids'; public const CMD_DELETE = 'delete'; public const CMD_EDIT = 'edit'; public const CMD_INDEX = 'index'; @@ -79,32 +80,13 @@ public function index(): bool } - $a_table = $this->initTable(); - $this->tpl()->setContent($a_table->getHTML()); + $table_gui = new ilBiblLibraryTableGUI($this->facade); + $this->tpl()->setContent($table_gui->getRenderedTable()); return true; } - protected function initTable(): \ilBiblLibraryTableGUI - { - $table = new ilBiblLibraryTableGUI($this, $this->checkPermissionBoolAndReturn('write')); - $settings = $this->facade->libraryFactory()->getAll(); - $result = array(); - foreach ($settings as $set) { - $result[] = array( - "id" => $set->getId(), - "name" => $set->getName(), - "url" => $set->getUrl(), - "img" => $set->getImg(), - ); - } - $table->setData($result); - - return $table; - } - - /** * add library */ @@ -122,8 +104,10 @@ public function add(): void public function delete(): void { $this->checkPermissionAndFail('write'); - $ilBibliographicSetting = $this->getInstanceFromRequest(); - $ilBibliographicSetting->delete(); + $ilBibliographicSettings = $this->getInstancesFromRequest(); + foreach ($ilBibliographicSettings as $ilBibliographicSetting) { + $ilBibliographicSetting->delete(); + } $this->ctrl()->redirect($this, self::CMD_INDEX); } @@ -143,7 +127,7 @@ public function cancel(): void public function update(): void { $this->checkPermissionAndFail('write'); - $ilBibliographicSetting = $this->getInstanceFromRequest(); + $ilBibliographicSetting = $this->getInstancesFromRequest()[0]; $form = new ilBiblLibraryFormGUI($ilBibliographicSetting); $form->setValuesByPost(); if ($form->saveObject()) { @@ -176,34 +160,37 @@ public function create(): void public function edit(): void { $this->checkPermissionAndFail('write'); - $this->ctrl()->saveParameter($this, self::F_LIB_ID); - $ilBibliographicSetting = $this->getInstanceFromRequest(); + $ilBibliographicSetting = $this->getInstancesFromRequest()[0]; $form = new ilBiblLibraryFormGUI($ilBibliographicSetting); $this->tpl()->setContent($form->getHTML()); } - private function getInstanceFromRequest(): \ilBiblLibraryInterface + /** + * return ilBiblLibraryInterface[] + */ + private function getInstancesFromRequest(): array { - // check Query - if ($this->wrapper->query()->has(self::F_LIB_ID)) { - return $this->facade->libraryFactory() - ->findById( - $this->wrapper->query()->retrieve( - self::F_LIB_ID, - $this->refinery->kindlyTo()->int() - ) - ); + $lib_ids = null; + $to_int = $this->refinery->kindlyTo()->int(); + $to_int_array = $this->refinery->kindlyTo()->listOf($to_int); + if ($this->wrapper->query()->has(self::F_LIB_IDS)) { + $lib_ids = $this->wrapper->query()->retrieve(self::F_LIB_IDS, $to_int_array); + } elseif ($this->wrapper->query()->has(self::F_LIB_ID)) { + $lib_ids[] = $this->wrapper->query()->retrieve(self::F_LIB_ID, $to_int); + } elseif ($this->wrapper->post()->has(self::F_LIB_IDS)) { + $lib_ids = $this->wrapper->post()->retrieve(self::F_LIB_IDS, $to_int_array); + } elseif ($this->wrapper->post()->has(self::F_LIB_ID)) { + $lib_ids[] = $this->wrapper->post()->retrieve(self::F_LIB_ID, $to_int); } - // check post - if ($this->wrapper->post()->has(self::F_LIB_ID)) { - return $this->facade->libraryFactory() - ->findById( - $this->wrapper->post()->retrieve( - self::F_LIB_ID, - $this->refinery->kindlyTo()->int() - ) - ); + + if ($lib_ids === null) { + throw new ilException('library not found'); + } + + $instances = []; + foreach ($lib_ids as $lib_id) { + $instances[] = $this->facade->libraryFactory()->findById($lib_id); } - throw new ilException('library not found'); + return $instances; } } diff --git a/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryTableGUI.php b/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryTableGUI.php index b99420cf1051..e8ca7ad9b82c 100755 --- a/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryTableGUI.php +++ b/components/ILIAS/Bibliographic/classes/Admin/Library/class.ilBiblLibraryTableGUI.php @@ -1,4 +1,17 @@ - * @author Martin Studer - * @author Fabian Schmid - */ -class ilBiblLibraryTableGUI extends ilTable2GUI + +class ilBiblLibraryTableGUI implements DataRetrieval { - use \ILIAS\components\OrgUnit\ARHelper\DIC; + private ilAccessHandler $access; + private ilCtrlInterface $ctrl; + private DataFactory $data_factory; + private HttpRequest $http_request; + private ilLanguage $lng; + private UIFactory $ui_factory; + private UIRenderer $ui_renderer; + + private DataTable $table; + + public function __construct(private readonly ilBiblAdminLibraryFacadeInterface $facade) + { + global $DIC; + + $this->access = $DIC->access(); + $this->ctrl = $DIC->ctrl(); + $this->data_factory = new DataFactory(); + $this->http_request = $DIC->http()->request(); + $this->lng = $DIC->language(); + $this->ui_factory = $DIC->ui()->factory(); + $this->ui_renderer = $DIC->ui()->renderer(); + + $this->table = $this->buildTable(); + } + + + public function getRenderedTable(): string + { + return $this->ui_renderer->render([$this->table]); + } + + + private function buildTable(): DataTable + { + return $this->ui_factory->table()->data( + $this->lng->txt('bibl_settings_libraries'), + $this->getColumns(), + $this + )->withActions( + $this->getActions() + )->withRange( + new Range(0, 10) + )->withOrder( + new Order('bibl_library_name', Order::ASC) + )->withRequest($this->http_request); + } - /** - * ilObjBibliographicAdminTableGUI constructor. - */ - public function __construct(ilBiblLibraryGUI $parent_gui) + private function getColumns(): array { - parent::__construct($parent_gui); - $this->setTitle($this->lng()->txt('bibl_settings_libraries')); - $this->setId('bibl_libraries_tbl'); - $this->initColumns(); - $this->setEnableNumInfo(false); - $this->setFormAction($this->ctrl()->getFormAction($parent_gui)); - $this->setRowTemplate('tpl.bibl_settings_lib_list_row.html', 'components/ILIAS/Bibliographic'); + return [ + 'bibl_library_name' => $this->ui_factory->table()->column()->text($this->lng->txt('bibl_library_name')), + 'bibl_library_url' => $this->ui_factory->table()->column()->text($this->lng->txt('bibl_library_url')), + 'bibl_library_img' => $this->ui_factory->table()->column()->text($this->lng->txt('bibl_library_img')) + ]; } - public function fillRow(array $a_set): void + private function getActions(): array { - $this->tpl->setVariable('VAL_LIBRARY_NAME', $a_set['name']); - $this->tpl->setVariable('VAL_LIBRARY_URL', $a_set['url']); - $this->tpl->setVariable('VAL_LIBRARY_IMG', $a_set['img']); - - if ($this->checkPermissionBoolAndReturn('write')) { - $this->ctrl()->setParameter($this->parent_obj, ilBiblLibraryGUI::F_LIB_ID, $a_set['id']); - // build edit action entry - $action_entries['edit'] = $this->ui()->factory()->button()->shy( - $this->lng->txt(ilBiblLibraryGUI::CMD_EDIT), - $this->ctrl()->getLinkTarget($this->parent_obj, ilBiblLibraryGUI::CMD_EDIT) + $namespace = ['lib']; + + $actions = []; + if ($this->access->checkAccess('write', '', $this->http_request->getQueryParams()['ref_id'])) { + $uri_edit = $this->data_factory->uri( + ILIAS_HTTP_PATH . '/' . $this->ctrl->getLinkTargetByClass( + ilBiblLibraryGUI::class, + ilBiblLibraryGUI::CMD_EDIT + ) + ); + /** + * @var URLBuilder $url_builder_edit + * @var URLBuilderToken $action_parameter_token_edit + * @var URLBuilderToken $row_id_token_edit + */ + [$url_builder_edit, $action_parameter_token_edit, $row_id_token_edit] = ( + new URLBuilder($uri_edit) + )->acquireParameters( + $namespace, + 'action', + 'ids' ); - // build delete action entry - $action_entries['delete'] = $this->ui()->factory()->button()->shy( - $this->lng->txt(ilBiblLibraryGUI::CMD_DELETE), - $this->ctrl()->getLinkTarget($this->parent_obj, ilBiblLibraryGUI::CMD_DELETE) + + $uri_delete = $this->data_factory->uri( + ILIAS_HTTP_PATH . '/' . $this->ctrl->getLinkTargetByClass( + ilBiblLibraryGUI::class, + ilBiblLibraryGUI::CMD_DELETE + ) ); - // build actions dropdown - $actions = $this->ui()->factory()->dropdown()->standard($action_entries)->withLabel($this->lng->txt("actions")); - $rendered_actions = $this->ui()->renderer()->render($actions); + /** + * @var URLBuilder $url_builder_delete + * @var URLBuilderToken $action_parameter_token_delete + * @var URLBuilderToken $row_id_token_delete + */ + [$url_builder_delete, $action_parameter_token_delete, $row_id_token_delete] = ( + new URLBuilder($uri_delete) + )->acquireParameters( + $namespace, + 'action', + 'ids' + ); + + $actions = [ + 'edit' => $this->ui_factory->table()->action()->single( + $this->lng->txt('edit'), + $url_builder_edit->withParameter($action_parameter_token_edit, 'edit'), + $row_id_token_edit + ), + 'delete' => $this->ui_factory->table()->action()->standard( + $this->lng->txt('delete'), + $url_builder_delete->withParameter($action_parameter_token_delete, 'delete'), + $row_id_token_delete + ) + ]; + } + + return $actions; + } + - $this->tpl->setVariable('VAL_ACTIONS', $rendered_actions); - } else { - $this->tpl->setVariable('VAL_ACTIONS', " "); + public function getRows( + DataRowBuilder $row_builder, + array $visible_column_ids, + Range $range, + Order $order, + ?array $filter_data, + ?array $additional_parameters + ): Generator { + $records = $this->getRecords($range, $order); + foreach ($records as $record) { + $row_id = (string) $record['bibl_library_id']; + yield $row_builder->buildDataRow($row_id, $record); } } - protected function initColumns(): void + public function getTotalRowCount(?array $filter_data, ?array $additional_parameters): ?int { - $this->addColumn($this->lng()->txt('bibl_library_name'), '', '30%'); - $this->addColumn($this->lng()->txt('bibl_library_url'), '30%'); - $this->addColumn($this->lng()->txt('bibl_library_img'), '', '30%'); - $this->addColumn($this->lng()->txt('actions'), '', '8%'); + return count($this->getRecords()); + } + + + private function getRecords(Range $range = null, Order $order = null): array + { + $records = []; + $libraries = $this->facade->libraryFactory()->getAll(); + foreach ($libraries as $library) { + $records[] = [ + "bibl_library_id" => $library->getId(), + "bibl_library_name" => $library->getName(), + "bibl_library_url" => $library->getUrl(), + "bibl_library_img" => $library->getImg(), + ]; + } + + if ($order) { + [$order_field, $order_direction] = $order->join([], fn($ret, $key, $value) => [$key, $value]); + usort($records, static fn($a, $b) => $a[$order_field] <=> $b[$order_field]); + if ($order_direction === 'DESC') { + $records = array_reverse($records); + } + } + if ($range) { + $records = array_slice($records, $range->getStart(), $range->getLength()); + } + + return $records; } } From ed75129607cba161eeedbbc78803512d806150b9 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Fri, 18 Oct 2024 13:06:51 +0200 Subject: [PATCH 05/75] Export: adds tests and adjusts code to allow for tests --- .../I/Repository/Element/HandlerInterface.php | 12 +- .../I/Repository/Key/HandlerInterface.php | 13 +- .../Stakeholder/HandlerInterface.php | 2 + .../I/Repository/Values/HandlerInterface.php | 13 +- .../Wrapper/IRSS/HandlerInterface.php | 6 +- ...{class.ilCollection.php => Collection.php} | 2 +- .../{class.ilFactory.php => Factory.php} | 6 +- .../{class.ilHandler.php => Handler.php} | 2 +- .../classes/ExportHandler/Info/Factory.php | 2 +- .../classes/ExportHandler/Manager/Handler.php | 2 +- .../Repository/Element/Handler.php | 24 ++ .../ExportHandler/Repository/Handler.php | 6 +- .../ExportHandler/Repository/Key/Handler.php | 24 ++ .../Repository/Stakeholder/Handler.php | 4 +- .../Repository/Values/Handler.php | 24 ++ .../Repository/Wrapper/IRSS/Handler.php | 14 +- .../Export/classes/class.ilExportGUI.php | 2 +- .../Repository/Element/CollectionTest.php | 115 +++++++++ .../Repository/Element/HandlerTest.php | 19 +- .../ExportHandler/Repository/Handler.php | 229 ++++++++++++++++++ .../Repository/Key/CollectionTest.php | 12 +- .../Repository/Key/HandlerTest.php | 71 ++++++ .../Repository/Key/ilHandlerTest.php | 61 ----- .../Repository/Stakeholder/HandlerTest.php | 41 ++++ .../Repository/Values/HandlerTest.php | 59 +++++ .../Table/RowId/CollectionTest.php | 15 +- .../ExportHandler/Table/RowId/HandlerTest.php | 12 +- .../ExportHandler/Target/HandlerTest.php | 10 +- ...er.php => class.ilILIASObjectExporter.php} | 0 29 files changed, 679 insertions(+), 123 deletions(-) rename components/ILIAS/Export/classes/ExportHandler/Info/Export/{class.ilCollection.php => Collection.php} (96%) rename components/ILIAS/Export/classes/ExportHandler/Info/Export/{class.ilFactory.php => Factory.php} (92%) rename components/ILIAS/Export/classes/ExportHandler/Info/Export/{class.ilHandler.php => Handler.php} (99%) create mode 100644 components/ILIAS/Export/tests/ExportHandler/Repository/Element/CollectionTest.php create mode 100644 components/ILIAS/Export/tests/ExportHandler/Repository/Handler.php create mode 100644 components/ILIAS/Export/tests/ExportHandler/Repository/Key/HandlerTest.php delete mode 100644 components/ILIAS/Export/tests/ExportHandler/Repository/Key/ilHandlerTest.php create mode 100644 components/ILIAS/Export/tests/ExportHandler/Repository/Stakeholder/HandlerTest.php create mode 100644 components/ILIAS/Export/tests/ExportHandler/Repository/Values/HandlerTest.php rename components/ILIAS/ILIASObject/classes/{class.ilObjectExporter.php => class.ilILIASObjectExporter.php} (100%) diff --git a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Element/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Element/HandlerInterface.php index 3cde49e2d5c3..cd8e64647925 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Element/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Element/HandlerInterface.php @@ -29,9 +29,13 @@ interface HandlerInterface { public const ELEMENT_TYPE = 'xml'; - public function withKey(ilExportHandlerRepositoryKeyInterface $key): HandlerInterface; + public function withKey( + ilExportHandlerRepositoryKeyInterface $key + ): HandlerInterface; - public function withValues(ilExportHandlerRepositoryValuesInterface $values): HandlerInterface; + public function withValues( + ilExportHandlerRepositoryValuesInterface $values + ): HandlerInterface; public function getKey(): ilExportHandlerRepositoryKeyInterface; @@ -44,4 +48,8 @@ public function getIRSS(): ilExportHandlerRepositoryElementIRSSWrapperInterface; public function getFileType(): string; public function isStorable(): bool; + + public function equals( + HandlerInterface $other_element + ): bool; } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Key/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Key/HandlerInterface.php index 673f4ee01176..afd177dfee7d 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Key/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Key/HandlerInterface.php @@ -21,15 +21,20 @@ namespace ILIAS\Export\ExportHandler\I\Repository\Key; use ILIAS\Data\ObjectId; +use ILIAS\Export\ExportHandler\I\Repository\Key\HandlerInterface as ilExportHandlerRepositoryKeyInterface; interface HandlerInterface { public const EMPTY_RESOURCE_IDENTIFICATION = ""; public const EMPTY_OBJECT_ID = -1; - public function withObjectId(ObjectId $object_id): HandlerInterface; + public function withObjectId( + ObjectId $object_id + ): HandlerInterface; - public function withResourceIdSerialized(string $resource_identification_serialized): HandlerInterface; + public function withResourceIdSerialized( + string $resource_identification_serialized + ): HandlerInterface; public function getObjectId(): ObjectId; @@ -40,4 +45,8 @@ public function isCompleteKey(): bool; public function isObjectIdKey(): bool; public function isResourceIdKey(): bool; + + public function equals( + ilExportHandlerRepositoryKeyInterface $other_repository_key + ): bool; } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Stakeholder/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Stakeholder/HandlerInterface.php index df7b2de13ce8..8c095b9e5112 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Stakeholder/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Stakeholder/HandlerInterface.php @@ -24,6 +24,8 @@ interface HandlerInterface extends ResourceStakeholder { + public const DEFAULT_OWNER_ID = 6; + public function withOwnerId(int $owner_id): HandlerInterface; public function getOwnerId(): int; diff --git a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Values/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Values/HandlerInterface.php index e11a24ce2cd6..47fac80a0cc4 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Values/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Values/HandlerInterface.php @@ -21,16 +21,25 @@ namespace ILIAS\Export\ExportHandler\I\Repository\Values; use DateTimeImmutable; +use ILIAS\Export\ExportHandler\I\Repository\Values\HandlerInterface as ilExportHandlerRepositoryValuesInterface; interface HandlerInterface { - public function withOwnerId(int $owner_id): HandlerInterface; + public function withOwnerId( + int $owner_id + ): HandlerInterface; - public function withCreationDate(DateTimeImmutable $creation_date): HandlerInterface; + public function withCreationDate( + DateTimeImmutable $creation_date + ): HandlerInterface; public function getOwnerId(): int; public function getCreationDate(): DateTimeImmutable; public function isValid(): bool; + + public function equals( + ilExportHandlerRepositoryValuesInterface $other_repository_values + ): bool; } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Wrapper/IRSS/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Wrapper/IRSS/HandlerInterface.php index f391a32f41bf..8f0bea684f0d 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/Repository/Wrapper/IRSS/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/Repository/Wrapper/IRSS/HandlerInterface.php @@ -33,9 +33,11 @@ interface HandlerInterface public function createEmptyContainer( ilExportHandlerExportInfoInterface $info, ilExportHandlerRepositoryStakeholderInterface $stakeholder - ): ResourceIdentification; + ): string; - public function getCreationDate(ResourceIdentification $resource_id): DateTimeImmutable; + public function getCreationDate( + string $resource_identification_serialized + ): DateTimeImmutable; public function removeContainer( string $resource_identification_serialized, diff --git a/components/ILIAS/Export/classes/ExportHandler/Info/Export/class.ilCollection.php b/components/ILIAS/Export/classes/ExportHandler/Info/Export/Collection.php similarity index 96% rename from components/ILIAS/Export/classes/ExportHandler/Info/Export/class.ilCollection.php rename to components/ILIAS/Export/classes/ExportHandler/Info/Export/Collection.php index d6ec277498e6..cc8af724eea1 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Info/Export/class.ilCollection.php +++ b/components/ILIAS/Export/classes/ExportHandler/Info/Export/Collection.php @@ -23,7 +23,7 @@ use ILIAS\Export\ExportHandler\I\Info\Export\CollectionInterface as ilExportHandlerExportInfoCollectionInterface; use ILIAS\Export\ExportHandler\I\Info\Export\HandlerInterface as ilExportHandlerExportInfoInterface; -class collection implements ilExportHandlerExportInfoCollectionInterface +class Collection implements ilExportHandlerExportInfoCollectionInterface { protected array $elements; protected int $index; diff --git a/components/ILIAS/Export/classes/ExportHandler/Info/Export/class.ilFactory.php b/components/ILIAS/Export/classes/ExportHandler/Info/Export/Factory.php similarity index 92% rename from components/ILIAS/Export/classes/ExportHandler/Info/Export/class.ilFactory.php rename to components/ILIAS/Export/classes/ExportHandler/Info/Export/Factory.php index d2c42aeff6e5..21967aff6dfc 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Info/Export/class.ilFactory.php +++ b/components/ILIAS/Export/classes/ExportHandler/Info/Export/Factory.php @@ -26,12 +26,12 @@ use ILIAS\Export\ExportHandler\I\Info\Export\Container\FactoryInterface as ilExportHandlerContainerExportInfoFactoryInterface; use ILIAS\Export\ExportHandler\I\Info\Export\FactoryInterface as ilExportHandlerExportInfoFactory; use ILIAS\Export\ExportHandler\I\Info\Export\HandlerInterface as ilExportHandlerExportInfoInterface; -use ILIAS\Export\ExportHandler\Info\Export\collection as ilExportHandlerExportInfoCollection; +use ILIAS\Export\ExportHandler\Info\Export\Collection as ilExportHandlerExportInfoCollection; use ILIAS\Export\ExportHandler\Info\Export\Component\Factory as ilExportHandlerExportComponentInfoFactory; use ILIAS\Export\ExportHandler\Info\Export\Container\Factory as ilExportHandlerContainerExportInfoFactory; -use ILIAS\Export\ExportHandler\Info\Export\handler as ilExportHandlerExportInfo; +use ILIAS\Export\ExportHandler\Info\Export\Handler as ilExportHandlerExportInfo; -class factory implements ilExportHandlerExportInfoFactory +class Factory implements ilExportHandlerExportInfoFactory { protected ilExportHandlerFactoryInterface $export_handler; diff --git a/components/ILIAS/Export/classes/ExportHandler/Info/Export/class.ilHandler.php b/components/ILIAS/Export/classes/ExportHandler/Info/Export/Handler.php similarity index 99% rename from components/ILIAS/Export/classes/ExportHandler/Info/Export/class.ilHandler.php rename to components/ILIAS/Export/classes/ExportHandler/Info/Export/Handler.php index d448891226de..2305f5415732 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Info/Export/class.ilHandler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Info/Export/Handler.php @@ -30,7 +30,7 @@ use ILIAS\Export\ExportHandler\I\Repository\Element\HandlerInterface as ilExportHandlerRepositoryElementInterface; use ILIAS\Export\ExportHandler\I\Target\HandlerInterface as ilExportHandlerTargetInterface; -class handler implements ilExportHandlerExportInfoInterface +class Handler implements ilExportHandlerExportInfoInterface { protected ilExportHandlerFactoryInterface $export_handler; protected ilExportHandlerTargetInterface $export_target; diff --git a/components/ILIAS/Export/classes/ExportHandler/Info/Factory.php b/components/ILIAS/Export/classes/ExportHandler/Info/Factory.php index 18de3567fde4..d6566fcc8b75 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Info/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/Info/Factory.php @@ -24,7 +24,7 @@ use ILIAS\Export\ExportHandler\I\Info\Export\FactoryInterface as ilExportHandlerExportInfoFactoryInterface; use ILIAS\Export\ExportHandler\I\Info\FactoryInterface as ilExportHandlerInfoFactoryInterface; use ILIAS\Export\ExportHandler\I\Info\File\FactoryInterface as ilExportHandlerFileInfoFactoryInterface; -use ILIAS\Export\ExportHandler\Info\Export\factory as ilExportHandlerExportInfoFactory; +use ILIAS\Export\ExportHandler\Info\Export\Factory as ilExportHandlerExportInfoFactory; use ILIAS\Export\ExportHandler\Info\File\Factory as ilExportHandlerFileInfoFactory; use ILIAS\ResourceStorage\Services as ResourcesStorageService; diff --git a/components/ILIAS/Export/classes/ExportHandler/Manager/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Manager/Handler.php index dcedc4c5e2f2..d8597f4919f2 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Manager/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Manager/Handler.php @@ -33,7 +33,7 @@ use ILIAS\Export\ExportHandler\I\Manager\HandlerInterface as ilExportHandlerManagerInterface; use ILIAS\Export\ExportHandler\I\Repository\Element\HandlerInterface as ilExportHandlerRepositoryElementInterface; use ILIAS\Export\ExportHandler\I\Target\HandlerInterface as ilExportHandlerTargetInterface; -use ILIAS\Export\ExportHandler\Info\Export\handler as ilExportHandlerExportInfo; +use ILIAS\Export\ExportHandler\Info\Export\Handler as ilExportHandlerExportInfo; use ILIAS\Filesystem\Stream\Streams; use ilImportExportFactory; use ilObject; diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Element/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Element/Handler.php index 7711e2acba28..1dfdc942aac5 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Element/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Element/Handler.php @@ -91,4 +91,28 @@ public function isStorable(): bool $this->values->isValid() ); } + + public function equals( + ilExportHandlerRepositoryElementInterface $other_element + ): bool { + $key_equals = + ( + isset($this->key) and + isset($other_element->key) and + $this->key->equals($other_element->key) + ) || ( + !isset($this->key) and + !isset($other_element->key) + ); + $values_equals = + ( + isset($this->values) and + isset($other_element->values) and + $this->values->equals($other_element->values) + ) || ( + !isset($this->values) and + !isset($other_element->values) + ); + return $key_equals and $values_equals; + } } diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Handler.php index a4271f01fa91..cf209ff909d3 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Handler.php @@ -60,13 +60,13 @@ public function createElement( ilExportHandlerExportInfoInterface $info, ilExportHandlerRepositoryStakeholderInterface $stakeholder ): ilExportHandlerRepositoryElementInterface { - $resource_id = $this->irss_wrapper->createEmptyContainer($info, $stakeholder); + $resource_id_serialized = $this->irss_wrapper->createEmptyContainer($info, $stakeholder); $key = $this->key_factory->handler() ->withObjectId($object_id) - ->withResourceIdSerialized($resource_id->serialize()); + ->withResourceIdSerialized($resource_id_serialized); $values = $this->values_factory->handler() ->withOwnerId($stakeholder->getOwnerId()) - ->withCreationDate($this->irss_wrapper->getCreationDate($resource_id)); + ->withCreationDate($this->irss_wrapper->getCreationDate($resource_id_serialized)); $element = $this->element_factory->handler() ->withKey($key) ->withValues($values); diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Handler.php index a65421319ef0..fef94c2c2610 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Handler.php @@ -85,4 +85,28 @@ public function isResourceIdKey(): bool $this->resource_identification_serialized !== self::EMPTY_RESOURCE_IDENTIFICATION ); } + + public function equals( + ilExportHandlerRepositoryKeyInterface $other_repository_key + ): bool { + $object_id_equals = + ( + isset($this->object_id) and + isset($other_repository_key->object_id) and + $this->object_id->toInt() === $other_repository_key->object_id->toInt() + ) || ( + !isset($this->object_id) and + !isset($other_repository_key->object_id) + ); + $resource_id_equals = + ( + isset($this->resource_identification_serialized) and + isset($other_repository_key->resource_identification_serialized) and + $this->resource_identification_serialized === $other_repository_key->resource_identification_serialized + ) || ( + !isset($this->resource_identification_serialized) and + !isset($other_repository_key->resource_identification_serialized) + ); + return $resource_id_equals and $object_id_equals; + } } diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Stakeholder/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Stakeholder/Handler.php index 4d1084231162..825c2833337e 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Stakeholder/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Stakeholder/Handler.php @@ -27,9 +27,9 @@ class Handler extends AbstractResourceStakeholder implements ilExportHandlerRepo { protected int $owner_id; - public function __construct(int $usr_id = 6) + public function __construct(int $usr_id = null) { - $this->owner_id = $usr_id; + $this->owner_id = $usr_id ?? self::DEFAULT_OWNER_ID; } public function getId(): string diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Values/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Values/Handler.php index d84cbeae2d88..9b069f43ff14 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Values/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Values/Handler.php @@ -59,4 +59,28 @@ public function isValid(): bool isset($this->creation_date) ); } + + public function equals( + ilExportHandlerRepositoryValuesInterface $other_repository_values + ): bool { + $owner_id_equals = + ( + isset($this->owner_id) and + isset($other_repository_values->owner_id) and + $this->owner_id = $other_repository_values->owner_id + ) || ( + !isset($this->owner_id) and + !isset($other_repository_values->owner_id) + ); + $creation_date_equals = + ( + isset($this->creation_date) and + isset($other_repository_values->creation_date) and + $this->creation_date->getTimestamp() === $other_repository_values->creation_date->getTimestamp() + ) || ( + !isset($this->creation_date) and + !isset($other_repository_values->creation_date) + ); + return $owner_id_equals and $creation_date_equals; + } } diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/IRSS/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/IRSS/Handler.php index c73e8bcf28cd..6f73703da937 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/IRSS/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/IRSS/Handler.php @@ -49,7 +49,7 @@ public function __construct( public function createEmptyContainer( ilExportHandlerExportInfoInterface $info, ilExportHandlerRepositoryStakeholderInterface $stakeholder - ): ResourceIdentification { + ): string { $tmp_dir_info = new SplFileInfo(ilFileUtils::ilTempnam()); $this->filesystems->temp()->createDir($tmp_dir_info->getFilename()); $export_dir = $tmp_dir_info->getRealPath(); @@ -62,13 +62,15 @@ public function createEmptyContainer( $zip->addStream(Streams::ofString(self::TMP_FILE_CONTENT), self::TMP_FILE_PATH); $rid = $this->irss->manageContainer()->containerFromStream($zip->get(), $stakeholder); ilFileUtils::delDir($export_dir); - return $rid; + return $rid->serialize(); } - public function getCreationDate(ResourceIdentification $resource_id): DateTimeImmutable - { - return $this->irss->manageContainer()->getResource($resource_id)->getCurrentRevision()->getInformation() - ->getCreationDate(); + public function getCreationDate( + string $resource_identification_serialized + ): DateTimeImmutable { + $resource_identification = $this->irss->manageContainer()->find($resource_identification_serialized); + return $this->irss->manageContainer()->getResource($resource_identification)->getCurrentRevision() + ->getInformation()->getCreationDate(); } public function removeContainer( diff --git a/components/ILIAS/Export/classes/class.ilExportGUI.php b/components/ILIAS/Export/classes/class.ilExportGUI.php index 70712dcf9581..303ae90799bb 100755 --- a/components/ILIAS/Export/classes/class.ilExportGUI.php +++ b/components/ILIAS/Export/classes/class.ilExportGUI.php @@ -181,7 +181,7 @@ final protected function builtExportOptionCommand(ilExportHandlerConsumerExportO final protected function enableStandardXMLExport(): void { - # Exception for Test, TestQuestionPool, OrgUnit + # Exception for Test, TestQuestionPool if (in_array($this->obj->getType(), ["tst", "qpl"])) { return; } diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Element/CollectionTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Element/CollectionTest.php new file mode 100644 index 000000000000..a37b312f9da0 --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Element/CollectionTest.php @@ -0,0 +1,115 @@ +createMock(ilExportHandlerRepositoryValues::class); + $values_mock_01->method("getCreationDate")->willReturn($date_1); + $values_mock_02 = $this->createMock(ilExportHandlerRepositoryValues::class); + $values_mock_02->method("getCreationDate")->willReturn($date_2); + $values_mock_03 = $this->createMock(ilExportHandlerRepositoryValues::class); + $values_mock_03->method("getCreationDate")->willReturn($date_2); + $values_mock_04 = $this->createMock(ilExportHandlerRepositoryValues::class); + $values_mock_04->method("getCreationDate")->willReturn($date_3); + $element_mock_01 = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_mock_01->method('getValues')->willReturn($values_mock_01); + $element_mock_02 = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_mock_02->method('getValues')->willReturn($values_mock_02); + $element_mock_03 = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_mock_03->method('getValues')->willReturn($values_mock_03); + $element_mock_04 = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_mock_04->method('getValues')->willReturn($values_mock_04); + $element_mock_01->method("equals")->willReturnMap([ + [$element_mock_01, true], [$element_mock_02, false], + [$element_mock_03, false], [$element_mock_04, false] + ]); + $element_mock_02->method("equals")->willReturnMap([ + [$element_mock_01, false], [$element_mock_02, true], + [$element_mock_03, false], [$element_mock_04, false] + ]); + $element_mock_03->method("equals")->willReturnMap([ + [$element_mock_01, false], [$element_mock_02, false], + [$element_mock_03, true], [$element_mock_04, false] + ]); + $element_mock_04->method("equals")->willReturnMap([ + [$element_mock_01, false], [$element_mock_02, false], + [$element_mock_03, false], [$element_mock_04, true] + ]); + $collection_empty = new ilExportHandlerRepositoryElementCollection(); + $collection = $collection_empty + ->withElement($element_mock_01) + ->withElement($element_mock_02) + ->withElement($element_mock_03) + ->withElement($element_mock_04); + $collection->rewind(); + $collection_empty->rewind(); + self::assertTrue($element_mock_01->equals($element_mock_01)); + self::assertFalse($element_mock_01->equals($element_mock_02)); + self::assertFalse($element_mock_01->equals($element_mock_03)); + self::assertFalse($element_mock_01->equals($element_mock_04)); + self::assertTrue($collection->valid()); + self::assertFalse($collection_empty->valid()); + self::assertCount(4, $collection); + self::assertCount(0, $collection_empty); + $this->checkElements($collection, [ + $element_mock_01, + $element_mock_02, + $element_mock_03, + $element_mock_04 + ]); + self::assertObjectEquals($element_mock_04, $collection->newest()); + # Check if newest() call changed element order + $this->checkElements($collection, [ + $element_mock_01, + $element_mock_02, + $element_mock_03, + $element_mock_04 + ]); + } + + /** + * @param ilExportHandlerRepositoryElement[] $elements + */ + protected function checkElements( + ilExportHandlerRepositoryElementCollection $collection, + array $elements + ): void { + $i = 0; + foreach ($collection as $element) { + self::assertTrue($elements[$i++]->equals($element)); + } + } +} diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Element/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Element/HandlerTest.php index 73c21f536104..8d60be1c1bbe 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Element/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Element/HandlerTest.php @@ -23,7 +23,6 @@ use DateTimeImmutable; use ILIAS\Data\ObjectId; use PHPUnit\Framework\TestCase; - use ILIAS\Export\ExportHandler\Repository\Element\Handler as ilExportHandlerRepositoryElement; use ILIAS\Export\ExportHandler\Repository\Element\Wrapper\IRSSInfo\Factory as ilExportHandlerRepositoryElementIRSSInfoWrapperFactory; use ILIAS\Export\ExportHandler\Repository\Element\Wrapper\IRSSInfo\Handler as ilExportHandlerRepositoryElementIRSSInfoWrapper; @@ -71,14 +70,14 @@ public function testExportHandlerRepositoryElement(): void $element_not_storable_1 = $element_not_storable_0->withValues($value_mock); $element_not_storable_2 = $element_not_storable_0->withKey($key_mock); - $this->assertFalse($element_not_storable_0->isStorable()); - $this->assertFalse($element_not_storable_1->isStorable()); - $this->assertFalse($element_not_storable_2->isStorable()); - $this->assertEquals($irss_wrapper_factory_mock->handler(), $element->getIRSS()); - $this->assertEquals($irss_info_wrapper_factory_mock->handler(), $element->getIRSSInfo()); - $this->assertEquals($value_mock, $element->getValues()); - $this->assertEquals($key_mock, $element->getKey()); - $this->assertTrue($element->isStorable()); - $this->assertEquals("xml", $element->getFileType()); + self::assertFalse($element_not_storable_0->isStorable()); + self::assertFalse($element_not_storable_1->isStorable()); + self::assertFalse($element_not_storable_2->isStorable()); + self::assertEquals($irss_wrapper_mock, $element->getIRSS()); + self::assertEquals($irss_info_wrapper_mock, $element->getIRSSInfo()); + self::assertEquals($value_mock, $element->getValues()); + self::assertEquals($key_mock, $element->getKey()); + self::assertTrue($element->isStorable()); + self::assertEquals("xml", $element->getFileType()); } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Handler.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Handler.php new file mode 100644 index 000000000000..7d281261af8d --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Handler.php @@ -0,0 +1,229 @@ +createMock(ilExportHandlerRepositoryElementCollection::class); + + $stakeholder_mock = $this->createMock(ilExportHandlerRepositoryStakeholder::class); + $stakeholder_mock->method("getOwnerId")->willReturn($owner_id); + $stakeholder_mock->method("withOwnerId")->willThrowException(new Exception("owner id changed")); + + $this->repository_elements = []; + + $object_id_mock01 = $this->createMock(ObjectId::class); + $object_id_mock01->method("toInt")->willReturn(1); + $object_id_mock01->method("toReferenceIds")->willThrowException(new Exception("unexpected method call")); + + $key_complete_mock = $this->createMock(ilExportHandlerRepositoryKey::class); + $key_complete_mock->method("withObjectId")->with($object_id_mock01)->willReturn($key_complete_mock); + $key_complete_mock->method("withResourceIdSerialized")->with($resource_id_serialized)->willReturn($key_complete_mock); + $key_complete_mock->method("getObjectId")->willReturn($object_id_mock01); + $key_complete_mock->method("getResourceIdSerialized")->willReturn($resource_id_serialized); + + $key_obj_id_mock = $this->createMock(ilExportHandlerRepositoryKey::class); + $key_obj_id_mock->method("withObjectId")->with($object_id_mock01)->willReturn($key_obj_id_mock); + $key_obj_id_mock->method("withResourceIdSerialized")->with($resource_id_serialized)->willReturn($key_complete_mock); + $key_obj_id_mock->method("getObjectId")->willReturn($object_id_mock01); + $key_obj_id_mock->method("getResourceIdSerialized")->willThrowException(new Exception("resource id not set")); + + $key_res_id_mock = $this->createMock(ilExportHandlerRepositoryKey::class); + $key_res_id_mock->method("withObjectId")->with($object_id_mock01)->willReturn($key_complete_mock); + $key_res_id_mock->method("withResourceIdSerialized")->with($resource_id_serialized)->willReturn($key_res_id_mock); + $key_res_id_mock->method("getObjectId")->willThrowException(new Exception("obj id not set")); + $key_res_id_mock->method("getResourceIdSerialized")->willReturn($resource_id_serialized); + + $key_mock = $this->createMock(ilExportHandlerRepositoryKey::class); + $key_mock->method("withObjectId")->with($object_id_mock01)->willReturn($key_obj_id_mock); + $key_mock->method("withResourceIdSerialized")->with($resource_id_serialized)->willReturn($key_res_id_mock); + $key_mock->method("getObjectId")->willThrowException(new Exception("obj id not set")); + $key_mock->method("getResourceIdSerialized")->willThrowException(new Exception("resource id not set")); + + $key_collection_with_element_mock = $this->createMock(ilExportHandlerRepositoryKeyCollection::class); + $key_collection_with_element_mock->method("withElement")->willThrowException(new Exception("to many keys added to collection")); + $key_collection_with_element_mock->method("current")->willReturn($key_complete_mock); + $key_collection_with_element_mock->method("key")->willReturn(0, 1); + # next() does not return anything + # rewind() does not return anything + $key_collection_with_element_mock->method("valid")->willReturn(true, false); + $key_collection_with_element_mock->method("count")->willReturn(1); + + $key_collection_mock01 = $this->createMock(ilExportHandlerRepositoryKeyCollection::class); + $key_collection_mock01->method("withElement")->with($key_complete_mock)->willReturn($key_collection_with_element_mock); + $key_collection_mock01->method("withElement")->with($key_mock)->willThrowException(new Exception("key incomplete")); + $key_collection_mock01->method("withElement")->with($key_obj_id_mock)->willThrowException(new Exception("key incomplete")); + $key_collection_mock01->method("withElement")->with($key_res_id_mock)->willThrowException(new Exception("key incomplete")); + $key_collection_mock01->method("current")->willThrowException(new Exception("collection empty")); + $key_collection_mock01->method("key")->willReturn(0); + # next() does not return anything + # rewind() does not return anything + $key_collection_mock01->method("valid")->willReturn(false); + $key_collection_mock01->method("count")->willReturn(0); + + $key_factory_mock = $this->createMock(ilExportHandlerRepositoryKeyFactory::class); + $key_factory_mock->method("handler")->willReturn($key_mock); + $key_factory_mock->method("collection")->willReturn($key_collection_mock01); + + $export_info_mock = $this->createMock(ilExportHandlerExportInfo::class); + + $irss_wrapper_mock = $this->createMock(ilExportHandlerRepositoryIRSSWrapper::class); + $irss_wrapper_mock->method('createEmptyContainer')->with($export_info_mock, $stakeholder_mock)->willReturn($resource_id_serialized); + $irss_wrapper_mock->method("getCreationDate")->with($resource_id_serialized)->willReturn($creation_date); + + $value_mock = $this->createMock(ilExportHandlerRepositoryValues::class); + $value_mock->method("withOwnerId")->with($owner_id)->willReturn($value_mock); + $value_mock->method("withCreationDate")->with($creation_date)->willReturn($value_mock); + $value_mock->method("getOwnerId")->willReturn($owner_id); + $value_mock->method("getCreationDate")->willReturn($creation_date); + + $values_factory = $this->createMock(ilExportHandlerRepositoryValuesFactory::class); + $values_factory->method("handler")->willReturn($value_mock); + + $element_complete_mock = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_complete_mock->method("isStorable")->willReturn(true); + $element_complete_mock->method("withKey")->with($key_mock)->willReturn($element_complete_mock); + $element_complete_mock->method("withValues")->with($value_mock)->willReturn($element_complete_mock); + + $element_w_key_mock = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_w_key_mock->method("isStorable")->willReturn(false); + $element_w_key_mock->method("withKey")->with($key_mock)->willReturn($element_w_key_mock); + $element_w_key_mock->method("withValues")->with($value_mock)->willReturn($element_complete_mock); + + $element_w_values_mock = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_w_values_mock->method("isStorable")->willReturn(false); + $element_w_values_mock->method("withKey")->with($key_mock)->willReturn($element_complete_mock); + $element_w_values_mock->method("withValues")->with($value_mock)->willReturn($element_w_values_mock); + + $element_emtpy_mock = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_emtpy_mock->method("isStorable")->willReturn(false); + $element_emtpy_mock->method("withKey")->with($key_mock)->willReturn($element_w_key_mock); + $element_emtpy_mock->method("withValues")->with($value_mock)->willReturn($element_w_values_mock); + + $element_factory_mock = $this->createMock(ilExportHandlerRepositoryElementFactory::class); + $element_factory_mock->method("handler")->willReturn($element_emtpy_mock); + + $db_wrapper_mock = $this->createMock(ilExportHandlerRepositoryDBWrapper::class); + $db_wrapper_mock->method("getElements")->with($key_collection_mock01)->willReturnCallback(function ($x) { + return $this->mockDBWrapperGetElements($x); + }); + $db_wrapper_mock->method("deleteElements")->with($key_collection_mock01)->willReturnCallback(function ($x) { + $this->mockDBWrapperDeleteElements($x); + }); + $db_wrapper_mock->method("store")->with($element_complete_mock)->willReturnCallback(function ($x) { + $this->mockDBWrapperStore($x); + }); + + $export_repository = new ilExportHandlerRepository( + $key_factory_mock, + $values_factory, + $element_factory_mock, + $db_wrapper_mock, + $irss_wrapper_mock + ); + + $element = $export_repository->createElement( + $object_id_mock01, + $export_info_mock, + $stakeholder_mock + ); + + self::assertCount(1, $this->repository_elements); + + $export_repository->storeElement($element_complete_mock); + $export_repository->storeElement($element_emtpy_mock); + + self::assertCount(2, $this->repository_elements); + + $elements = $export_repository->getElements($key_collection_mock01); + + self::assertCount(2, $this->repository_elements); + + $export_repository->deleteElements($key_collection_mock01, $stakeholder_mock); + + self::assertCount(0, $this->repository_elements); + } + + protected function mockDBWrapperStore( + $x + ): void { + $this->repository_elements[] = $x; + } + + protected function mockDBWrapperGetElements( + $x + ): ilExportHandlerRepositoryElementCollection { + $key_collection_mock = func_get_args()[0]; + $element_collection_mock = $this->createMock(ilExportHandlerRepositoryElementCollection::class); + if (empty($this->repository_elements)) { + $element_collection_mock->method("newest")->willReturn(null); + $element_collection_mock->method("current")->willThrowException(new Exception("empty collection")); + $element_collection_mock->method("key")->willReturn(0); + # next() does not return anything + # rewind() does not return anything + $element_collection_mock->method("valid")->willReturn(false); + $element_collection_mock->method("count")->willReturn(0); + } + if (!empty($this->repository_elements)) { + $element_collection_mock->method("newest")->willReturn($this->repository_elements[0]); + $element_collection_mock->method("current")->willReturn(...$this->repository_elements); + $element_collection_mock->method("key")->willReturn(...array_keys($this->repository_elements)); + # next() does not return anything + # rewind() does not return anything + $element_collection_mock->method("valid")->willReturn(...array_map(function ($element) { return !is_null($element); }, array_merge($this->repository_elements, [null]))); + $element_collection_mock->method("count")->willReturn(count($this->repository_elements)); + } + return $element_collection_mock; + } + + protected function mockDBWrapperDeleteElements( + $x + ): void { + $this->repository_elements = []; + } +} diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Key/CollectionTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Key/CollectionTest.php index 9e6bea74b1e4..e15ac227a179 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Key/CollectionTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Key/CollectionTest.php @@ -49,15 +49,15 @@ public function testExportHandlerRepositoryKeyCollection(): void ->withElement($element_1) ->withElement($element_2) ->withElement($element_3); - $this->assertEquals(3, $collection_with_elements->count()); - $this->assertTrue($collection_with_elements->valid()); + self::assertEquals(3, $collection_with_elements->count()); + self::assertTrue($collection_with_elements->valid()); $index = 1; foreach ($collection_with_elements as $element) { - $this->assertEquals($index, $element->getObjectId()->toInt()); - $this->assertEquals('r' . $index, $element->getResourceIdSerialized()); + self::assertEquals($index, $element->getObjectId()->toInt()); + self::assertEquals('r' . $index, $element->getResourceIdSerialized()); $index++; } - $this->assertEquals(0, $empty_collection->count()); - $this->assertFalse($empty_collection->valid()); + self::assertEquals(0, $empty_collection->count()); + self::assertFalse($empty_collection->valid()); } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Key/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Key/HandlerTest.php new file mode 100644 index 000000000000..affe6a922fa2 --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Key/HandlerTest.php @@ -0,0 +1,71 @@ +createMock(ObjectId::class); + $object_id_mock->method('toInt')->willReturn(123); + $object_id_mock->method("toReferenceIds")->willThrowException(new Exception("toReferenceIds should not be called")); + $repository_key_empty = new ilExportHandlerRepositoryKey(); + $repository_key_with_resource_id = $repository_key_empty->withResourceIdSerialized($resource_identification); + $repository_key_with_object_id = $repository_key_empty->withObjectId($object_id_mock); + $repository_key_complete = $repository_key_empty->withResourceIdSerialized($resource_identification)->withObjectId($object_id_mock); + self::assertFalse($repository_key_empty->isObjectIdKey()); + self::assertFalse($repository_key_empty->isResourceIdKey()); + self::assertFalse($repository_key_empty->isCompleteKey()); + self::assertEquals(-1, $repository_key_empty->getObjectId()->toInt()); + self::assertEquals("", $repository_key_empty->getResourceIdSerialized()); + self::assertFalse($repository_key_with_resource_id->isObjectIdKey()); + self::assertTrue($repository_key_with_resource_id->isResourceIdKey()); + self::assertFalse($repository_key_with_resource_id->isCompleteKey()); + self::assertEquals(-1, $repository_key_with_resource_id->getObjectId()->toInt()); + self::assertEquals($resource_identification, $repository_key_with_resource_id->getResourceIdSerialized()); + self::assertTrue($repository_key_with_object_id->isObjectIdKey()); + self::assertFalse($repository_key_with_object_id->isResourceIdKey()); + self::assertFalse($repository_key_with_object_id->isCompleteKey()); + self::assertEquals($object_id_mock->toInt(), $repository_key_with_object_id->getObjectId()->toInt()); + self::assertEquals("", $repository_key_with_object_id->getResourceIdSerialized()); + self::assertFalse($repository_key_complete->isObjectIdKey()); + self::assertFalse($repository_key_complete->isResourceIdKey()); + self::assertTrue($repository_key_complete->isCompleteKey()); + self::assertEquals($object_id_mock->toInt(), $repository_key_complete->getObjectId()->toInt()); + self::assertEquals($resource_identification, $repository_key_complete->getResourceIdSerialized()); + self::assertTrue($repository_key_empty->equals($repository_key_empty)); + self::assertTrue($repository_key_with_resource_id->equals($repository_key_with_resource_id)); + self::assertTrue($repository_key_with_object_id->equals($repository_key_with_object_id)); + self::assertTrue($repository_key_complete->equals($repository_key_complete)); + self::assertFalse($repository_key_empty->equals($repository_key_with_resource_id)); + self::assertFalse($repository_key_empty->equals($repository_key_with_object_id)); + self::assertFalse($repository_key_empty->equals($repository_key_complete)); + self::assertFalse($repository_key_with_object_id->equals($repository_key_with_resource_id)); + self::assertFalse($repository_key_with_object_id->equals($repository_key_complete)); + self::assertFalse($repository_key_with_resource_id->equals($repository_key_complete)); + } +} diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Key/ilHandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Key/ilHandlerTest.php deleted file mode 100644 index fc14bf7c48fb..000000000000 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Key/ilHandlerTest.php +++ /dev/null @@ -1,61 +0,0 @@ -createMock(ObjectId::class); - $object_id_mock->method('toInt')->willReturn(123); - $object_id_mock->method("toReferenceIds")->willThrowException(new Exception("toReferenceIds should not be called")); - $repository_key_empty = new ilExportHandlerRepositoryKey(); - $repository_key_with_resource_id = $repository_key_empty->withResourceIdSerialized($resource_identification); - $repository_key_with_object_id = $repository_key_empty->withObjectId($object_id_mock); - $repository_key_complete = $repository_key_empty->withResourceIdSerialized($resource_identification)->withObjectId($object_id_mock); - $this->assertFalse($repository_key_empty->isObjectIdKey()); - $this->assertFalse($repository_key_empty->isResourceIdKey()); - $this->assertFalse($repository_key_empty->isCompleteKey()); - $this->assertEquals(-1, $repository_key_empty->getObjectId()->toInt()); - $this->assertEquals("", $repository_key_empty->getResourceIdSerialized()); - $this->assertFalse($repository_key_with_resource_id->isObjectIdKey()); - $this->assertTrue($repository_key_with_resource_id->isResourceIdKey()); - $this->assertFalse($repository_key_with_resource_id->isCompleteKey()); - $this->assertEquals(-1, $repository_key_with_resource_id->getObjectId()->toInt()); - $this->assertEquals($resource_identification, $repository_key_with_resource_id->getResourceIdSerialized()); - $this->assertTrue($repository_key_with_object_id->isObjectIdKey()); - $this->assertFalse($repository_key_with_object_id->isResourceIdKey()); - $this->assertFalse($repository_key_with_object_id->isCompleteKey()); - $this->assertEquals($object_id_mock->toInt(), $repository_key_with_object_id->getObjectId()->toInt()); - $this->assertEquals("", $repository_key_with_object_id->getResourceIdSerialized()); - $this->assertFalse($repository_key_complete->isObjectIdKey()); - $this->assertFalse($repository_key_complete->isResourceIdKey()); - $this->assertTrue($repository_key_complete->isCompleteKey()); - $this->assertEquals($object_id_mock->toInt(), $repository_key_complete->getObjectId()->toInt()); - $this->assertEquals($resource_identification, $repository_key_complete->getResourceIdSerialized()); - } -} diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Stakeholder/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Stakeholder/HandlerTest.php new file mode 100644 index 000000000000..0ebc4d261b7a --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Stakeholder/HandlerTest.php @@ -0,0 +1,41 @@ +withOwnerId(6); + $stakeholder03 = new ilExportHandlerRepositoryStakeholder(); + self::assertEquals(10, $stakeholder01->getOwnerId()); + self::assertEquals(6, $stakeholder02->getOwnerId()); + self::assertEquals(ilExportHandlerRepositoryStakeholderInterface::DEFAULT_OWNER_ID, $stakeholder03->getOwnerId()); + } +} diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Values/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Values/HandlerTest.php new file mode 100644 index 000000000000..19fe3b2cb602 --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Values/HandlerTest.php @@ -0,0 +1,59 @@ +withOwnerId($owner_id); + $values_with_datetime = $values + ->withCreationDate($datetime); + $values_complete = $values + ->withOwnerId($owner_id) + ->withCreationDate($datetime); + self::assertFalse($values->isValid()); + self::assertFalse($values_with_owner_id->isValid()); + self::assertFalse($values_with_datetime->isValid()); + self::assertTrue($values_complete->isValid()); + self::assertEquals($owner_id, $values_with_owner_id->getOwnerId()); + self::assertEquals($owner_id, $values_complete->getOwnerId()); + self::assertEquals($datetime, $values_with_datetime->getCreationDate()); + self::assertEquals($datetime, $values_complete->getCreationDate()); + self::assertTrue($values->equals($values)); + self::assertTrue($values_with_owner_id->equals($values_with_owner_id)); + self::assertTrue($values_with_datetime->equals($values_with_datetime)); + self::assertTrue($values_complete->equals($values_complete)); + self::assertFalse($values->equals($values_with_owner_id)); + self::assertFalse($values->equals($values_complete)); + self::assertFalse($values->equals($values_with_datetime)); + } +} diff --git a/components/ILIAS/Export/tests/ExportHandler/Table/RowId/CollectionTest.php b/components/ILIAS/Export/tests/ExportHandler/Table/RowId/CollectionTest.php index 514c0cf5e2a0..835749ada439 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Table/RowId/CollectionTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Table/RowId/CollectionTest.php @@ -36,7 +36,6 @@ public function testExportHandlerTableRowIdCollection(): void $table_row_id_mock_2->method('getFileIdentifier')->willReturn("2"); $table_row_id_mock_2->method('getExportOptionId')->willReturn("e"); $table_row_id_mock_2->method('getCompositId')->willReturn("e:2"); - ; $table_row_id_mock_3 = $this->createMock(ilExportHandlerTableRowId::class); $table_row_id_mock_3->method('getFileIdentifier')->willReturn("3"); $table_row_id_mock_3->method('getExportOptionId')->willReturn("e"); @@ -46,15 +45,15 @@ public function testExportHandlerTableRowIdCollection(): void ->withElement($table_row_id_mock_1) ->withElement($table_row_id_mock_2) ->withElement($table_row_id_mock_3); - $this->assertEquals(0, $empty_collection->count()); - $this->assertFalse($empty_collection->valid()); - $this->assertEquals(3, $collection_with_elements->count()); - $this->assertTrue($collection_with_elements->valid()); + self::assertEquals(0, $empty_collection->count()); + self::assertFalse($empty_collection->valid()); + self::assertEquals(3, $collection_with_elements->count()); + self::assertTrue($collection_with_elements->valid()); $index = 1; foreach ($collection_with_elements as $element) { - $this->assertEquals("" . $index, $element->getFileIdentifier()); - $this->assertEquals("e", $element->getExportOptionId()); - $this->assertEquals("e:" . $index, $element->getCompositId()); + self::assertEquals("" . $index, $element->getFileIdentifier()); + self::assertEquals("e", $element->getExportOptionId()); + self::assertEquals("e:" . $index, $element->getCompositId()); $index++; } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Table/RowId/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Table/RowId/HandlerTest.php index 39e2c1efc130..0428773ad823 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Table/RowId/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Table/RowId/HandlerTest.php @@ -35,11 +35,11 @@ public function testExportHandlerTableRowId(): void ->withFileIdentifier($file_identifier) ->withExportOptionId($export_option_id); $table_row_id_2 = $table_row_id->withCompositId($composit_id); - $this->assertEquals($file_identifier, $table_row_id_1->getFileIdentifier()); - $this->assertEquals($export_option_id, $table_row_id_1->getExportOptionId()); - $this->assertEquals($composit_id, $table_row_id_1->getCompositId()); - $this->assertEquals($file_identifier, $table_row_id_2->getFileIdentifier()); - $this->assertEquals($export_option_id, $table_row_id_2->getExportOptionId()); - $this->assertEquals($composit_id, $table_row_id_2->getCompositId()); + self::assertEquals($file_identifier, $table_row_id_1->getFileIdentifier()); + self::assertEquals($export_option_id, $table_row_id_1->getExportOptionId()); + self::assertEquals($composit_id, $table_row_id_1->getCompositId()); + self::assertEquals($file_identifier, $table_row_id_2->getFileIdentifier()); + self::assertEquals($export_option_id, $table_row_id_2->getExportOptionId()); + self::assertEquals($composit_id, $table_row_id_2->getCompositId()); } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Target/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Target/HandlerTest.php index 5a8c1a1c014c..3ccb2b41cd50 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Target/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Target/HandlerTest.php @@ -39,10 +39,10 @@ public function testExportHandlerTarget(): void ->withClassname($class_name) ->withTargetRelease($target_release) ->withObjectIds($object_ids); - $this->assertEquals($type, $target_1->getType()); - $this->assertEquals($component, $target_1->getComponent()); - $this->assertEquals($class_name, $target_1->getClassname()); - $this->assertEquals($target_release, $target_1->getTargetRelease()); - $this->assertEmpty(array_diff($object_ids, $target_1->getObjectIds())); + self::assertEquals($type, $target_1->getType()); + self::assertEquals($component, $target_1->getComponent()); + self::assertEquals($class_name, $target_1->getClassname()); + self::assertEquals($target_release, $target_1->getTargetRelease()); + self::assertEmpty(array_diff($object_ids, $target_1->getObjectIds())); } } diff --git a/components/ILIAS/ILIASObject/classes/class.ilObjectExporter.php b/components/ILIAS/ILIASObject/classes/class.ilILIASObjectExporter.php similarity index 100% rename from components/ILIAS/ILIASObject/classes/class.ilObjectExporter.php rename to components/ILIAS/ILIASObject/classes/class.ilILIASObjectExporter.php From cf5060a35c640149da8e06dc6304cfbf7eff141e Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Mon, 21 Oct 2024 12:46:21 +0200 Subject: [PATCH 06/75] Export: run php cs fixer --- .../ImportHandler/File/Validation/Set/ilCollectionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilCollectionTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilCollectionTest.php index 940edd5ee302..05517ec1c7d4 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilCollectionTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilCollectionTest.php @@ -39,7 +39,7 @@ public function testSetCollection(): void ->withElement($set3); $this->assertCount(3, $collection); - for($i = 0; $i < 3; $i++) { + for ($i = 0; $i < 3; $i++) { $sets[$i] = $collection->toArray()[$i]; } } From 10e3e10b42f162f4f6692be7eb8c3cbe25216a33 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Mon, 21 Oct 2024 13:06:18 +0200 Subject: [PATCH 07/75] Export: fix namespace of test classes --- .../tests/ExportHandler/PublicAccess/Link/HandlerTest.php | 8 ++++++++ .../ExportHandler/Repository/Element/CollectionTest.php | 2 +- .../ExportHandler/Repository/Element/HandlerTest.php | 2 +- .../Export/tests/ExportHandler/Repository/Handler.php | 2 +- .../ExportHandler/Repository/Stakeholder/HandlerTest.php | 2 +- .../tests/ExportHandler/Repository/Values/HandlerTest.php | 2 +- 6 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php diff --git a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php new file mode 100644 index 000000000000..2d6ad0e38ec5 --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php @@ -0,0 +1,8 @@ + Date: Mon, 21 Oct 2024 14:05:36 +0200 Subject: [PATCH 08/75] Export: add unit tests for link, adjusts code to allow for unit tests, optimize imports --- .../ExportOption/BasicLegacyHandler.php | 1 - .../Export/Component/HandlerInterface.php | 1 - .../I/PublicAccess/Link/FactoryInterface.php | 3 + .../I/PublicAccess/Link/HandlerInterface.php | 8 +++ .../Link/Wrapper/FactoryInterface.php | 28 ++++++++++ .../Wrapper/StaticURL/FactoryInterface.php | 28 ++++++++++ .../Wrapper/StaticURL/HandlerInterface.php | 38 +++++++++++++ .../Wrapper/IRSS/HandlerInterface.php | 1 - .../Info/Export/Component/Handler.php | 1 - .../PublicAccess/Link/Factory.php | 13 ++++- .../PublicAccess/Link/Handler.php | 22 ++++---- .../PublicAccess/Link/Wrapper/Factory.php | 49 +++++++++++++++++ .../Link/Wrapper/StaticURL/Factory.php | 47 ++++++++++++++++ .../Link/Wrapper/StaticURL/Handler.php | 55 +++++++++++++++++++ .../Repository/Wrapper/IRSS/Handler.php | 1 - .../PublicAccess/Link/HandlerTest.php | 51 +++++++++++++++-- 16 files changed, 327 insertions(+), 20 deletions(-) create mode 100644 components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/Wrapper/FactoryInterface.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/Wrapper/StaticURL/FactoryInterface.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/Wrapper/StaticURL/HandlerInterface.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/Factory.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/StaticURL/Factory.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/StaticURL/Handler.php diff --git a/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportOption/BasicLegacyHandler.php b/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportOption/BasicLegacyHandler.php index 668729b8e055..ef9b88c67ac8 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportOption/BasicLegacyHandler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportOption/BasicLegacyHandler.php @@ -22,7 +22,6 @@ use ilCtrl; use ilExport; -use ilExportFileInfo; use ilFileDelivery; use ilFileUtils; use ILIAS\Data\ObjectId; diff --git a/components/ILIAS/Export/classes/ExportHandler/I/Info/Export/Component/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/Info/Export/Component/HandlerInterface.php index 716d716da43f..bf2f6184a39e 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/Info/Export/Component/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/Info/Export/Component/HandlerInterface.php @@ -22,7 +22,6 @@ use ilExport; use ILIAS\Export\ExportHandler\I\Info\Export\Component\CollectionInterface as ilExportHandlerExportComponentInfoCollectionInterface; -use ILIAS\Export\ExportHandler\I\Repository\Element\HandlerInterface as ilExportHandlerRepositoryElementInterface; use ILIAS\Export\ExportHandler\I\Target\HandlerInterface as ilExportHandlerTargetInterface; use ilXmlExporter; diff --git a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/FactoryInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/FactoryInterface.php index d78cd153eebd..51a1efae5209 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/FactoryInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/FactoryInterface.php @@ -21,8 +21,11 @@ namespace ILIAS\Export\ExportHandler\I\PublicAccess\Link; use ILIAS\Export\ExportHandler\I\PublicAccess\Link\HandlerInterface as ilExportHandlerPublicAccessLinkInterface; +use ILIAS\Export\ExportHandler\I\PublicAccess\Link\Wrapper\FactoryInterface as ilExportHandlerPublicAccessLinkWrapperFactoryInterface; interface FactoryInterface { public function handler(): ilExportHandlerPublicAccessLinkInterface; + + public function wrapper(): ilExportHandlerPublicAccessLinkWrapperFactoryInterface; } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/HandlerInterface.php index 7d8f7695e016..ea82b0c2f1e7 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/HandlerInterface.php @@ -22,12 +22,20 @@ use ILIAS\Data\ReferenceId; use ILIAS\Data\URI; +use ILIAS\Export\ExportHandler\I\PublicAccess\Link\HandlerInterface as ilExportHandlerPublicAccessLinkHandlerInterface; +use ILIAS\Export\ExportHandler\I\PublicAccess\Link\Wrapper\StaticURL\HandlerInterface as ilExportHandlerPublicAccessLinkStaticURLWrapperInterface; interface HandlerInterface { public function withReferenceId(ReferenceId $referenceId): HandlerInterface; + public function withStaticURLWrapper( + ilExportHandlerPublicAccessLinkStaticURLWrapperInterface $static_url_wrapper + ): ilExportHandlerPublicAccessLinkHandlerInterface; + public function getReferenceId(): ReferenceId; + public function getStaticURLWrapper(): ilExportHandlerPublicAccessLinkStaticURLWrapperInterface; + public function getLink(): URI; } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/Wrapper/FactoryInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/Wrapper/FactoryInterface.php new file mode 100644 index 000000000000..ebccd60de0e6 --- /dev/null +++ b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Link/Wrapper/FactoryInterface.php @@ -0,0 +1,28 @@ +withStaticUrl($this->static_url); + return (new ilExportHandlerPublicAccessLink()) + ->withStaticURLWrapper($this->wrapper()->staticURL()->handler()); + } + + public function wrapper(): ilExportHandlerPublicAccessLinkWrapperFactoryInterface + { + return new ilExportHandlerPublicAccessLinkWrapperFactory( + $this->export_handler, + $this->static_url + ); } } diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Handler.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Handler.php index 04388a4a2adc..46260c9582f6 100644 --- a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Handler.php @@ -23,6 +23,7 @@ use ILIAS\Data\ReferenceId; use ILIAS\Data\URI; use ILIAS\Export\ExportHandler\I\PublicAccess\Link\HandlerInterface as ilExportHandlerPublicAccessLinkHandlerInterface; +use ILIAS\Export\ExportHandler\I\PublicAccess\Link\Wrapper\StaticURL\HandlerInterface as ilExportHandlerPublicAccessLinkStaticURLWrapperInterface; use ILIAS\Export\ExportHandler\StaticUrlHandler as ilExportHandlerStaticUrlHandler; use ILIAS\StaticURL\Context; use ILIAS\StaticURL\Handler\BaseHandler; @@ -30,21 +31,21 @@ use ILIAS\StaticURL\Request\Request; use ILIAS\StaticURL\Response\Factory; use ILIAS\StaticURL\Response\Response; -use ILIAS\StaticURL\Services as StaticUrl; class Handler extends BaseHandler implements ilExportHandlerPublicAccessLinkHandlerInterface, StaticURLHandler { - protected StaticURL $static_url; + protected ilExportHandlerPublicAccessLinkStaticURLWrapperInterface $static_url_wrapper; protected ReferenceId $reference_id; public function __construct() { } - public function withStaticUrl(StaticURL $static_url): ilExportHandlerPublicAccessLinkHandlerInterface - { + public function withStaticURLWrapper( + ilExportHandlerPublicAccessLinkStaticURLWrapperInterface $static_url_wrapper + ): ilExportHandlerPublicAccessLinkHandlerInterface { $clone = clone $this; - $clone->static_url = $static_url; + $clone->static_url_wrapper = $static_url_wrapper; return $clone; } @@ -60,13 +61,14 @@ public function getReferenceId(): ReferenceId return $this->reference_id; } + public function getStaticURLWrapper(): ilExportHandlerPublicAccessLinkStaticURLWrapperInterface + { + return $this->static_url_wrapper; + } + public function getLink(): URI { - return $this->static_url->builder()->build( - ilExportHandlerStaticUrlHandler::NAMESPACE, - $this->reference_id, - [ilExportHandlerStaticUrlHandler::DOWNLOAD] - ); + return $this->static_url_wrapper->buildDownloadURI($this->reference_id); } public function getNamespace(): string diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/Factory.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/Factory.php new file mode 100644 index 000000000000..57e098007763 --- /dev/null +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/Factory.php @@ -0,0 +1,49 @@ +export_handler = $export_handler; + $this->static_url = $static_url; + } + + public function staticURL(): ilExportHandlerPublicAccessLinkStaticURLWrapperFactoryInterface + { + return new ilExportHandlerPublicAccessLinkStaticURLWrapperFactory( + $this->export_handler, + $this->static_url + ); + } +} diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/StaticURL/Factory.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/StaticURL/Factory.php new file mode 100644 index 000000000000..a905795321a1 --- /dev/null +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/StaticURL/Factory.php @@ -0,0 +1,47 @@ +export_handler = $export_handler; + $this->static_url = $static_url; + } + + public function handler(): ilExportHandlerPublicAccessLinkStaticURLWrapperInterface + { + return (new ilExportHandlerPublicAccessLinkStaticURLWrapper()) + ->withStaticURL($this->static_url); + } +} diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/StaticURL/Handler.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/StaticURL/Handler.php new file mode 100644 index 000000000000..4ee14a1be97e --- /dev/null +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Link/Wrapper/StaticURL/Handler.php @@ -0,0 +1,55 @@ +static_url = $static_url; + return $clone; + } + + public function getStatucURL(): StaticUrl + { + return $this->static_url; + } + + public function buildDownloadURI( + ReferenceId $reference_id + ): URI { + return $this->static_url->builder()->build( + ilExportHandlerStaticUrlHandler::NAMESPACE, + $reference_id, + [ilExportHandlerStaticUrlHandler::DOWNLOAD] + ); + } +} diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/IRSS/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/IRSS/Handler.php index 6f73703da937..4db8cecb28b5 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/IRSS/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/IRSS/Handler.php @@ -29,7 +29,6 @@ use ILIAS\Filesystem\Stream\Streams; use ILIAS\Filesystem\Util\Archive\Zip; use ILIAS\Filesystem\Util\Archive\ZipOptions; -use ILIAS\ResourceStorage\Identification\ResourceIdentification; use ILIAS\ResourceStorage\Services as ResourcesStorageService; use SplFileInfo; diff --git a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php index 2d6ad0e38ec5..101a67d2b804 100644 --- a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php @@ -1,8 +1,51 @@ createMock(Uri::class); + $uri_mock->expects($this->once())->method("__toString")->willReturn($download_url); + $reference_id_mock = $this->createMock(ReferenceId::class); + $reference_id_mock->method("toInt")->willReturn($reference_id); + $reference_id_mock->method("toObjectId")->willThrowException(new Exception("unexpected conversion to object id")); + $static_url_wrapper_mock = $this->createMock(ilExportHandlerPublicAccessLinkStaticURLWrapper::class); + $static_url_wrapper_mock->method("withStaticURL")->willThrowException(new Exception("unexpected overwrite of static URL service object")); + $static_url_wrapper_mock->method("buildDownloadURI")->willReturn($uri_mock); + $link = new ilExportHandlerPublicAccessLink(); + $link = $link + ->withReferenceId($reference_id_mock) + ->withStaticURLWrapper($static_url_wrapper_mock); + self::assertEquals($download_url, $link->getLink()); + self::assertEquals($reference_id, $link->getReferenceId()->toInt()); + } +} From e9cad6a6621ef8438a4d2461294639c945d2c2b9 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Tue, 22 Oct 2024 12:35:55 +0200 Subject: [PATCH 09/75] Export: Adds tests, fixes wrong type write and xml formatting in export, adds code to allow for tests --- .../ExportOption/BasicLegacyHandler.php | 6 +- .../Consumer/ExportWriter/Handler.php | 2 +- .../Consumer/File/CollectionBuilder.php | 7 +- .../Export/classes/ExportHandler/Factory.php | 18 ++- .../ExportHandler/I/FactoryInterface.php | 3 + .../Repository/Element/HandlerInterface.php | 4 + .../Repository/Key/HandlerInterface.php | 4 + .../Repository/Values/HandlerInterface.php | 4 + .../Wrapper/DataFactory/FactoryInterface.php | 28 ++++ .../Wrapper/DataFactory/HandlerInterface.php | 28 ++++ .../I/Wrapper/FactoryInterface.php | 28 ++++ .../ExportHandler/Info/Export/Factory.php | 5 +- .../ExportHandler/Info/Export/Handler.php | 11 +- .../classes/ExportHandler/Info/Factory.php | 4 +- .../classes/ExportHandler/Manager/Factory.php | 9 +- .../classes/ExportHandler/Manager/Handler.php | 14 +- .../ExportHandler/Part/Component/Handler.php | 2 +- .../Repository/Element/Handler.php | 28 ++++ .../PublicAccess/Repository/Factory.php | 4 +- .../PublicAccess/Repository/Key/Factory.php | 13 +- .../PublicAccess/Repository/Key/Handler.php | 26 +++- .../Repository/Values/Handler.php | 28 ++++ .../Repository/Wrapper/DB/Factory.php | 3 +- .../Repository/Wrapper/DB/Handler.php | 11 +- .../ExportHandler/Repository/Key/Factory.php | 6 +- .../ExportHandler/Repository/Key/Handler.php | 10 +- .../Repository/Wrapper/DB/Factory.php | 3 +- .../Repository/Wrapper/DB/Handler.php | 9 +- .../classes/ExportHandler/Table/Factory.php | 9 +- .../classes/ExportHandler/Table/Handler.php | 10 +- .../Wrapper/DataFactory/Factory.php | 44 ++++++ .../Wrapper/DataFactory/Handler.php | 41 +++++ .../classes/ExportHandler/Wrapper/Factory.php | 44 ++++++ .../classes/class.ilExportExportOptionXML.php | 13 +- .../Export/classes/class.ilExportGUI.php | 11 +- .../classes/class.ilImportExportFactory.php | 2 +- .../PublicAccess/Link/HandlerTest.php | 26 ++-- .../Repository/Element/HandlerTest.php | 103 +++++++++++++ .../Repository/Key/Collection.php | 75 +++++++++ .../Repository/Key/HandlerTest.php | 54 +++++++ .../Repository/Values/HandlerTest.php | 54 +++++++ .../Repository/Element/CollectionTest.php | 92 +++++------ .../Repository/Element/HandlerTest.php | 75 ++++----- .../ExportHandler/Repository/Handler.php | 145 +++++++----------- .../Repository/Key/CollectionTest.php | 65 ++++---- .../Repository/Key/HandlerTest.php | 83 +++++----- .../Repository/Stakeholder/HandlerTest.php | 22 +-- .../Repository/Values/HandlerTest.php | 55 +++---- .../Table/RowId/CollectionTest.php | 45 +++--- .../ExportHandler/Table/RowId/HandlerTest.php | 29 ++-- .../ExportHandler/Target/HandlerTest.php | 29 ++-- .../File/Namespace/ilCollectionTest.php | 6 +- .../File/Namespace/ilHandlerTest.php | 2 +- .../File/Path/Comparison/ilHandlerTest.php | 1 - .../File/Path/Node/ilAnyNodeTest.php | 2 +- .../File/Path/Node/ilAttributeTest.php | 4 +- .../Path/Node/ilCloseRoundBrackedTest.php | 2 +- .../File/Path/Node/ilIndexTest.php | 2 +- .../File/Path/Node/ilOpenRoundBrackedTest.php | 2 +- .../File/Path/Node/ilSimpleTest.php | 2 +- .../ImportHandler/File/Path/ilHandlerTest.php | 2 +- .../File/Validation/Set/ilCollectionTest.php | 2 +- .../File/Validation/Set/ilHandlerTest.php | 4 +- .../Node/Info/Attribute/ilCollectionTest.php | 2 +- .../XML/Node/Info/Attribute/ilPairTest.php | 2 +- .../ImportHandler/File/ilHandlerTest.php | 4 +- .../Export/tests/ilExportOptionsTest.php | 2 +- 67 files changed, 1085 insertions(+), 400 deletions(-) create mode 100644 components/ILIAS/Export/classes/ExportHandler/I/Wrapper/DataFactory/FactoryInterface.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/I/Wrapper/DataFactory/HandlerInterface.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/I/Wrapper/FactoryInterface.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/Wrapper/DataFactory/Factory.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/Wrapper/DataFactory/Handler.php create mode 100644 components/ILIAS/Export/classes/ExportHandler/Wrapper/Factory.php create mode 100644 components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Element/HandlerTest.php create mode 100644 components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Key/Collection.php create mode 100644 components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Key/HandlerTest.php create mode 100644 components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Values/HandlerTest.php diff --git a/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportOption/BasicLegacyHandler.php b/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportOption/BasicLegacyHandler.php index ef9b88c67ac8..a484bb6c95d8 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportOption/BasicLegacyHandler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportOption/BasicLegacyHandler.php @@ -24,7 +24,7 @@ use ilExport; use ilFileDelivery; use ilFileUtils; -use ILIAS\Data\ObjectId; +use ILIAS\Data\Factory as ilDataFactory; use ILIAS\Data\ReferenceId; use ILIAS\DI\Container; use ILIAS\Export\ExportHandler\Consumer\ExportOption\BasicHandler as ilExportHandlerConsumerBasicExportOption; @@ -38,10 +38,12 @@ abstract class BasicLegacyHandler extends ilExportHandlerConsumerBasicExportOption { protected ilCtrl $ctrl; + protected ilDataFactory $data_factory; public function init(Container $DIC): void { $this->ctrl = $DIC->ctrl(); + $this->data_factory = new ilDataFactory(); } public function onDeleteFiles( @@ -136,7 +138,7 @@ public function getFiles( [$this->getExportType()], $context->exportObject()->getType() ); - $object_id = new ObjectId($context->exportObject()->getId()); + $object_id = $this->data_factory->objId($context->exportObject()->getId()); foreach ($file_infos as $file_name => $file_info) { $collection_builder = $collection_builder->withSPLFileInfo( new SplFileInfo($dir . DIRECTORY_SEPARATOR . $file_info["file"]), diff --git a/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportWriter/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportWriter/Handler.php index cefcf5253232..ee99f581cd58 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportWriter/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Consumer/ExportWriter/Handler.php @@ -45,7 +45,7 @@ public function __construct( } public function withObjectId( - objectId $objectId + ObjectId $objectId ): ilExportHandlerConsumerExportWriterInterface { $clone = clone $this; $clone->object_id = $objectId; diff --git a/components/ILIAS/Export/classes/ExportHandler/Consumer/File/CollectionBuilder.php b/components/ILIAS/Export/classes/ExportHandler/Consumer/File/CollectionBuilder.php index 62480b94df7b..b9084b0af11f 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Consumer/File/CollectionBuilder.php +++ b/components/ILIAS/Export/classes/ExportHandler/Consumer/File/CollectionBuilder.php @@ -65,8 +65,11 @@ public function withSPLFileInfo( return $clone; } - public function withResourceIdentifier(ResourceIdentification $resource_id, ObjectId $object_id, ilExportHandlerConsumerExportOptionInterface $export_option): ilExportHandlerConsumerFileCollectionBuilderInterface - { + public function withResourceIdentifier( + ResourceIdentification $resource_id, + ObjectId $object_id, + ilExportHandlerConsumerExportOptionInterface $export_option + ): ilExportHandlerConsumerFileCollectionBuilderInterface { $file_info = $this->file_info_factory->handler() ->withResourceId($resource_id) ->withType($export_option->getExportType()) diff --git a/components/ILIAS/Export/classes/ExportHandler/Factory.php b/components/ILIAS/Export/classes/ExportHandler/Factory.php index e8fc3724f83f..87e21e811509 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/Factory.php @@ -23,6 +23,7 @@ use ilAccessHandler; use ilCtrlInterface; use ilDBInterface; +use ILIAS\Data\Factory as ilDataFactory; use ILIAS\DI\UIServices as ilUIServices; use ILIAS\Export\ExportHandler\Consumer\Factory as ilExportHandlderConsumerFactory; use ILIAS\Export\ExportHandler\I\Consumer\FactoryInterface as ilExportHandlderConsumerFactoryInterface; @@ -34,6 +35,7 @@ use ILIAS\Export\ExportHandler\I\Repository\FactoryInterface as ilExportHandlerRepositoryFactoryInterface; use ILIAS\Export\ExportHandler\I\Table\FactoryInterface as ilExportHandlerTableFactoryInterface; use ILIAS\Export\ExportHandler\I\Target\FactoryInterface as ilExportHandlerTargetFactoryInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\FactoryInterface as ilExportHandlerWrapperFactoryInterface; use ILIAS\Export\ExportHandler\Info\Factory as ilExportHandlerInfoFactory; use ILIAS\Export\ExportHandler\Manager\Factory as ilExportHandlerManagerFactory; use ILIAS\Export\ExportHandler\Part\Factory as ilExportHandlerPartFactory; @@ -41,6 +43,7 @@ use ILIAS\Export\ExportHandler\Repository\Factory as ilExportHandlerRepositoryFactory; use ILIAS\Export\ExportHandler\Table\Factory as ilExportHandlerTableFactory; use ILIAS\Export\ExportHandler\Target\Factory as ilExportHandlerTargetFactory; +use ILIAS\Export\ExportHandler\Wrapper\Factory as ilExportHandlerWrapperFactory; use ILIAS\Filesystem\Filesystems; use ILIAS\HTTP\Services as ilHTTPServices; use ILIAS\Refinery\Factory as ilRefineryFactory; @@ -66,6 +69,7 @@ class Factory implements ilExportHandlerFactoryInterface protected ilTree $tree; protected ilObjectDefinition $obj_definition; protected ilAccessHandler $access; + protected ilDataFactory $data_factory; public function __construct() { @@ -83,6 +87,7 @@ public function __construct() $this->obj_definition = $DIC['objDefinition']; $this->tree = $DIC->repositoryTree(); $this->access = $DIC->access(); + $this->data_factory = new ilDataFactory(); } public function part(): ilExportHandlerPartFactoryInterface @@ -130,7 +135,8 @@ public function manager(): ilExportHandlerManagerFactoryInterface $this, $this->obj_definition, $this->tree, - $this->access + $this->access, + $this->wrapper()->dataFactory()->handler() ); } @@ -150,7 +156,15 @@ public function table(): ilExportHandlerTableFactoryInterface $this->refinery, $this->user, $this->lng, - $this->ctrl + $this->ctrl, + $this->data_factory + ); + } + + public function wrapper(): ilExportHandlerWrapperFactoryInterface + { + return new ilExportHandlerWrapperFactory( + $this->data_factory ); } } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/FactoryInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/FactoryInterface.php index da3a11c8f43d..75f61d15ebe2 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/FactoryInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/FactoryInterface.php @@ -28,6 +28,7 @@ use ILIAS\Export\ExportHandler\I\Repository\FactoryInterface as ilExportHandlerRepositoryFactoryInterface; use ILIAS\Export\ExportHandler\I\Table\FactoryInterface as ilExportHandlerTableFactoryInterface; use ILIAS\Export\ExportHandler\I\Target\FactoryInterface as ilExportHandlerTargetFactoryInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\FactoryInterface as ilExportHandlerWrapperFactoryInterface; interface FactoryInterface { @@ -46,4 +47,6 @@ public function manager(): ilExportHandlerManagerFactoryInterface; public function consumer(): ilExportHandlderConsumerFactoryInterface; public function table(): ilExportHandlerTableFactoryInterface; + + public function wrapper(): ilExportHandlerWrapperFactoryInterface; } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Element/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Element/HandlerInterface.php index 6021d081c795..aa75dc04593d 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Element/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Element/HandlerInterface.php @@ -38,4 +38,8 @@ public function getKey(): ilExportHandlerPublicAccessRepositoryKeyInterface; public function getValues(): ilExportHandlerPublicAccessRepositoryValuesInterface; public function isStorable(): bool; + + public function equals( + HandlerInterface $other + ): bool; } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Key/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Key/HandlerInterface.php index 09da5e67deda..241b94859e37 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Key/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Key/HandlerInterface.php @@ -33,4 +33,8 @@ public function withObjectId( public function getObjectId(): ObjectId; public function isValid(): bool; + + public function equals( + HandlerInterface $other + ): bool; } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Values/HandlerInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Values/HandlerInterface.php index b466a5de2d25..0a5f7661a349 100644 --- a/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Values/HandlerInterface.php +++ b/components/ILIAS/Export/classes/ExportHandler/I/PublicAccess/Repository/Values/HandlerInterface.php @@ -35,4 +35,8 @@ public function getIdentification(): string; public function getLastModified(): DateTimeImmutable; public function isValid(): bool; + + public function equals( + HandlerInterface $other + ): bool; } diff --git a/components/ILIAS/Export/classes/ExportHandler/I/Wrapper/DataFactory/FactoryInterface.php b/components/ILIAS/Export/classes/ExportHandler/I/Wrapper/DataFactory/FactoryInterface.php new file mode 100644 index 000000000000..1d0a358529f5 --- /dev/null +++ b/components/ILIAS/Export/classes/ExportHandler/I/Wrapper/DataFactory/FactoryInterface.php @@ -0,0 +1,28 @@ +export_handler); + return new ilExportHandlerExportInfo( + $this->export_handler, + $this->export_handler->wrapper()->dataFactory()->handler() + ); } public function collection(): ilExportHandlerExportInfoCollectionInterface diff --git a/components/ILIAS/Export/classes/ExportHandler/Info/Export/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Info/Export/Handler.php index 2305f5415732..c051e43f9a77 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Info/Export/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Info/Export/Handler.php @@ -29,6 +29,7 @@ use ILIAS\Export\ExportHandler\I\Info\Export\HandlerInterface as ilExportHandlerExportInfoInterface; use ILIAS\Export\ExportHandler\I\Repository\Element\HandlerInterface as ilExportHandlerRepositoryElementInterface; use ILIAS\Export\ExportHandler\I\Target\HandlerInterface as ilExportHandlerTargetInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\DataFactory\HandlerInterface as ilExportHandlerDataFactoryWrapperInterface; class Handler implements ilExportHandlerExportInfoInterface { @@ -37,16 +38,20 @@ class Handler implements ilExportHandlerExportInfoInterface protected ilExportHandlerExportComponentInfoCollectionInterface $component_export_infos; protected ilExportHandlerContainerExportInfoInterface $container_export_info; protected ilExportHandlerRepositoryElementInterface $element; + protected ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper; protected array $component_counts; protected bool $reuse_export; protected int $time_stamp; protected int $set_number; - public function __construct(ilExportHandlerFactoryInterface $export_handler) - { + public function __construct( + ilExportHandlerFactoryInterface $export_handler, + ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper + ) { $this->export_handler = $export_handler; $this->component_export_infos = $this->export_handler->info()->export()->component()->collection(); $this->component_counts = []; + $this->data_factory_wrapper = $data_factory_wrapper; } protected function getExportFilePathInContainer(string $export_folder_name, string $component, int $component_count): string @@ -164,7 +169,7 @@ public function getTimestamp(): int public function getTargetObjectId(): ObjectId { - return new ObjectId($this->export_target->getObjectIds()[0]); + return $this->data_factory_wrapper->objId($this->export_target->getObjectIds()[0]); } public function getComponentCount(ilExportHandlerExportComponentInfoInterface $component_info) diff --git a/components/ILIAS/Export/classes/ExportHandler/Info/Factory.php b/components/ILIAS/Export/classes/ExportHandler/Info/Factory.php index d6566fcc8b75..f527e8a3b8a1 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Info/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/Info/Factory.php @@ -43,7 +43,9 @@ public function __construct( public function export(): ilExportHandlerExportInfoFactoryInterface { - return new ilExportHandlerExportInfoFactory($this->export_handler); + return new ilExportHandlerExportInfoFactory( + $this->export_handler + ); } public function file(): ilExportHandlerFileInfoFactoryInterface diff --git a/components/ILIAS/Export/classes/ExportHandler/Manager/Factory.php b/components/ILIAS/Export/classes/ExportHandler/Manager/Factory.php index f31041f117d5..6d215f2ccc0d 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Manager/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/Manager/Factory.php @@ -24,6 +24,7 @@ use ILIAS\Export\ExportHandler\I\FactoryInterface as ilExportHandlerFactoryInterface; use ILIAS\Export\ExportHandler\I\Manager\FactoryInterface as ilExportHandlerManagerFactoryInterface; use ILIAS\Export\ExportHandler\I\Manager\HandlerInterface as ilExportHandlerManagerInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\DataFactory\HandlerInterface as ilExportHandlerDataFactoryWrapperInterface; use ILIAS\Export\ExportHandler\Manager\Handler as ilExportHandlerManager; use ilObjectDefinition; use ilTree; @@ -34,17 +35,20 @@ class Factory implements ilExportHandlerManagerFactoryInterface protected ilTree $tree; protected ilObjectDefinition $obj_definition; protected ilAccessHandler $access; + protected ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper; public function __construct( ilExportHandlerFactoryInterface $export_handler, ilObjectDefinition $obj_definition, ilTree $tree, - ilAccessHandler $access + ilAccessHandler $access, + ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper ) { $this->export_handler = $export_handler; $this->obj_definition = $obj_definition; $this->tree = $tree; $this->access = $access; + $this->data_factory_wrapper = $data_factory_wrapper; } public function handler(): ilExportHandlerManagerInterface @@ -53,7 +57,8 @@ public function handler(): ilExportHandlerManagerInterface $this->export_handler, $this->obj_definition, $this->tree, - $this->access + $this->access, + $this->data_factory_wrapper ); } } diff --git a/components/ILIAS/Export/classes/ExportHandler/Manager/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Manager/Handler.php index d8597f4919f2..951694b1f2a0 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Manager/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Manager/Handler.php @@ -33,6 +33,7 @@ use ILIAS\Export\ExportHandler\I\Manager\HandlerInterface as ilExportHandlerManagerInterface; use ILIAS\Export\ExportHandler\I\Repository\Element\HandlerInterface as ilExportHandlerRepositoryElementInterface; use ILIAS\Export\ExportHandler\I\Target\HandlerInterface as ilExportHandlerTargetInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\DataFactory\HandlerInterface as ilExportHandlerDataFactoryWrapperInterface; use ILIAS\Export\ExportHandler\Info\Export\Handler as ilExportHandlerExportInfo; use ILIAS\Filesystem\Stream\Streams; use ilImportExportFactory; @@ -47,17 +48,20 @@ class Handler implements ilExportHandlerManagerInterface protected ilTree $tree; protected ilObjectDefinition $obj_definition; protected ilAccessHandler $access; + protected ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper; public function __construct( ilExportHandlerFactoryInterface $export_handler, ilObjectDefinition $obj_definition, ilTree $tree, - ilAccessHandler $access + ilAccessHandler $access, + ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper ) { $this->export_handler = $export_handler; $this->obj_definition = $obj_definition; $this->tree = $tree; $this->access = $access; + $this->data_factory_wrapper = $data_factory_wrapper; } protected function getExportTarget( @@ -86,7 +90,7 @@ protected function writeToElement( $manifest = $this->export_handler->part()->manifest()->handler() ->withInfo($export_info); $element->getIRSS()->write( - Streams::ofString($manifest->getXML()), + Streams::ofString($manifest->getXML(false)), $path_in_container . DIRECTORY_SEPARATOR . $export_info->getExportFolderName() . DIRECTORY_SEPARATOR . "manifest.xml" ); foreach ($export_info->getComponentInfos() as $component_info) { @@ -94,7 +98,7 @@ protected function writeToElement( ->withExportInfo($export_info) ->withComponentInfo($component_info); $element->getIRSS()->write( - Streams::ofString($component->getXML()), + Streams::ofString($component->getXML(false)), $path_in_container . DIRECTORY_SEPARATOR . $component_info->getExportFilePathInContainer() ); } @@ -139,7 +143,7 @@ public function createContainerExport( $container = $this->export_handler->part()->container()->handler() ->withExportInfos($container_export_info->getExportInfos()->withElementAtHead($main_export_info)) ->withMainEntityExportInfo($main_export_info); - $main_element->getIRSS()->write(Streams::ofString($container->getXML()), "manifest.xml"); + $main_element->getIRSS()->write(Streams::ofString($container->getXML(false)), "manifest.xml"); return $main_element; } @@ -153,7 +157,7 @@ public function createExport( ilFileUtils::makeDirParents($export_info->getLegacyExportRunDir()); $stakeholder = $this->export_handler->repository()->stakeholder()->handler()->withOwnerId($user_id); - $object_id = new ObjectId($export_info->getTarget()->getObjectIds()[0]); + $object_id = $this->data_factory_wrapper->objId($export_info->getTarget()->getObjectIds()[0]); $element = $this->export_handler->repository()->handler()->createElement( $object_id, $export_info, diff --git a/components/ILIAS/Export/classes/ExportHandler/Part/Component/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Part/Component/Handler.php index 92e38b373df4..d19f2d348a13 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Part/Component/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Part/Component/Handler.php @@ -41,7 +41,7 @@ public function getXML(bool $formatted = true): string { $attribs = array("InstallationId" => $this->export_info->getInstallationId(), "InstallationUrl" => $this->export_info->getHTTPPath(), - "Entity" => $this->component_info->getTarget()->getComponent(), + "Entity" => $this->component_info->getTarget()->getType(), "SchemaVersion" => $this->component_info->getSchemaVersion(), /* "TargetRelease" => $a_target_release, */ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Element/Handler.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Element/Handler.php index ab28d95242bd..ccc50575e557 100644 --- a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Element/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Element/Handler.php @@ -62,4 +62,32 @@ public function isStorable(): bool ($this->getValues()->isValid() ?? false) ); } + + public function equals( + ilExportHandlerPublicAccessRepositoryElementInterface $other + ): bool { + $key_equals = + ( + ( + !isset($this->key) and + !isset($other->key) + ) or ( + isset($this->key) and + isset($other->key) and + $this->key->equals($other->key) + ) + ); + $values_equals = + ( + ( + !isset($this->values) and + !isset($other->values) + ) or ( + isset($this->values) and + isset($other->values) and + $this->values->equals($other->values) + ) + ); + return $key_equals and $values_equals; + } } diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Factory.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Factory.php index 34e2eba1380e..2d4c9ed68895 100644 --- a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Factory.php @@ -64,7 +64,9 @@ public function handler(): ilExportHandlerPublicAccessRepositoryInterface public function key(): ilExportHandlerPublicAccessRepositoryKeyFactoryInterface { - return new ilExportHandlerPublicAccessRepositoryKeyFactory(); + return new ilExportHandlerPublicAccessRepositoryKeyFactory( + $this->export_handler->wrapper()->dataFactory()->handler() + ); } public function values(): ilExportHandlerPublicAccessRepositoryValuesFactoryInterface diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Key/Factory.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Key/Factory.php index 0b54e5c20983..7ce221d23bd2 100644 --- a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Key/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Key/Factory.php @@ -23,14 +23,25 @@ use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Key\CollectionInterface as ilExportHandlerPublicAccessRepositoryKeyCollectionInterface; use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Key\FactoryInterface as ilExportHandlerPublicAccessRepositoryKeyFactoryInterface; use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Key\HandlerInterface as ilExportHandlerPublicAccessRepositoryKeyInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\DataFactory\HandlerInterface as ilExportHandlerDataFactoryWrapperInterface; use ILIAS\Export\ExportHandler\PublicAccess\Repository\Key\Collection as ilExportHandlerPublicAccessRepositoryKeyCollection; use ILIAS\Export\ExportHandler\PublicAccess\Repository\Key\Handler as ilExportHandlerPublicAccessRepositoryKey; class Factory implements ilExportHandlerPublicAccessRepositoryKeyFactoryInterface { + protected ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper; + + public function __construct( + ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper + ) { + $this->data_factory_wrapper = $data_factory_wrapper; + } + public function handler(): ilExportHandlerPublicAccessRepositoryKeyInterface { - return new ilExportHandlerPublicAccessRepositoryKey(); + return new ilExportHandlerPublicAccessRepositoryKey( + $this->data_factory_wrapper + ); } public function collection(): ilExportHandlerPublicAccessRepositoryKeyCollectionInterface diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Key/Handler.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Key/Handler.php index aff63d0f5cf6..e24e794f543e 100644 --- a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Key/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Key/Handler.php @@ -22,14 +22,18 @@ use ILIAS\Data\ObjectId; use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Key\HandlerInterface as ilExportHandlerPublicAccessRepositoryKeyInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\DataFactory\HandlerInterface as ilExportHandlerDataFactoryWrapperInterface; class Handler implements ilExportHandlerPublicAccessRepositoryKeyInterface { protected ObjectId $object_id; + protected ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper; - public function __construct() - { - $this->object_id = new ObjectId(self::EMPTY_OBJECT_ID); + public function __construct( + ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper + ) { + $this->data_factory_wrapper = $data_factory_wrapper; + $this->object_id = $this->data_factory_wrapper->objId(self::EMPTY_OBJECT_ID); } public function withObjectId( @@ -49,4 +53,20 @@ public function isValid(): bool { return $this->object_id->toInt() !== self::EMPTY_OBJECT_ID; } + + public function equals( + ilExportHandlerPublicAccessRepositoryKeyInterface $other + ): bool { + return + ( + ( + !isset($this->object_id) and + !isset($other->object_id) + ) or ( + isset($this->object_id) and + isset($other->object_id) and + $this->object_id->toInt() === $other->object_id->toInt() + ) + ); + } } diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Values/Handler.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Values/Handler.php index 58b4ba45c14d..4929b1de1bb9 100644 --- a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Values/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Values/Handler.php @@ -73,4 +73,32 @@ public function isValid(): bool isset($this->last_modified) ); } + + public function equals( + ilExportHandlerPublicAccessRepositoryValuesInterface $other + ): bool { + $identification_equals = + ( + ( + !isset($this->identification) and + !isset($other->identification) + ) or ( + isset($this->identification) and + isset($other->identification) and + $this->identification === $other->identification + ) + ); + $export_option_id_equals = + ( + ( + !isset($this->export_option_id) and + !isset($other->export_option_id) + ) or ( + isset($this->export_option_id) and + isset($other->export_option_id) and + $this->export_option_id === $other->export_option_id + ) + ); + return $identification_equals and $export_option_id_equals; + } } diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Wrapper/DB/Factory.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Wrapper/DB/Factory.php index 196fecee7d42..723427b1a889 100644 --- a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Wrapper/DB/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Wrapper/DB/Factory.php @@ -33,7 +33,7 @@ class Factory implements ilExportHandlerPublicAccessRepositoryDBWrapperFactoryIn public function __construct( ilExportHandlerFactoryInterface $export_handler, - ilDBInterface $db + ilDBInterface $db, ) { $this->export_handler = $export_handler; $this->db = $db; @@ -46,6 +46,7 @@ public function handler(): ilExportHandlerPublicAccessRepositoryDBWrapperInterfa $this->export_handler->publicAccess()->repository()->element(), $this->export_handler->publicAccess()->repository()->key(), $this->export_handler->publicAccess()->repository()->values(), + $this->export_handler->wrapper()->dataFactory()->handler() ); } } diff --git a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Wrapper/DB/Handler.php b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Wrapper/DB/Handler.php index 9776e627e2c3..a8c72839363f 100644 --- a/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Wrapper/DB/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/PublicAccess/Repository/Wrapper/DB/Handler.php @@ -22,7 +22,6 @@ use ilDBConstants; use ilDBInterface; -use ILIAS\Data\ObjectId; use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Element\CollectionInterface as ilExportHandlerPublicAccessRepositoryElementCollectionInterface; use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Element\FactoryInterface as ilExportHandlerPublicAccessRepositoryElementFactroyInterface; use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Element\HandlerInterface as ilExportHandlerPublicAccessRepositoryElementInterface; @@ -30,6 +29,7 @@ use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Key\FactoryInterface as ilExportHandlerPublicAccessRepositoryKeyFactoryInterface; use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Values\FactoryInterface as ilExportHandlerPublicAccessRepositoryValuesFactoryInterface; use ILIAS\Export\ExportHandler\I\PublicAccess\Repository\Wrapper\DB\HandlerInterface as ilExportHandlerPublicAccessRepositoryDBWrapperInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\DataFactory\HandlerInterface as ilExportHandlerDataFactoryWrapperInterface; class Handler implements ilExportHandlerPublicAccessRepositoryDBWrapperInterface { @@ -37,17 +37,20 @@ class Handler implements ilExportHandlerPublicAccessRepositoryDBWrapperInterface protected ilExportHandlerPublicAccessRepositoryKeyFactoryInterface $key_factory; protected ilExportHandlerPublicAccessRepositoryValuesFactoryInterface $values_factory; protected ilDBInterface $db; + protected ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper; public function __construct( ilDBInterface $db, ilExportHandlerPublicAccessRepositoryElementFactroyInterface $element_factory, ilExportHandlerPublicAccessRepositoryKeyFactoryInterface $key_factory, - ilExportHandlerPublicAccessRepositoryValuesFactoryInterface $values_factory + ilExportHandlerPublicAccessRepositoryValuesFactoryInterface $values_factory, + ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper ) { $this->db = $db; $this->element_factory = $element_factory; $this->key_factory = $key_factory; $this->values_factory = $values_factory; + $this->data_factory_wrapper = $data_factory_wrapper; } public function storeElement( @@ -65,7 +68,7 @@ public function getElements( } $res = $this->db->query($this->buildSelectQuery($keys)); while ($row = $res->fetchAssoc()) { - $object_id = new ObjectId((int) $row['object_id']); + $object_id = $this->data_factory_wrapper->objId((int) $row['object_id']); $key = $this->key_factory->handler() ->withObjectId($object_id); $values = $this->values_factory->handler() @@ -85,7 +88,7 @@ public function getAllElements(): ilExportHandlerPublicAccessRepositoryElementCo $collection = $this->element_factory->collection(); $res = $this->db->query($this->buildSelectAllQuery()); while ($row = $res->fetchAssoc()) { - $object_id = new ObjectId((int) $row['object_id']); + $object_id = $this->data_factory_wrapper->objId((int) $row['object_id']); $key = $this->key_factory->handler() ->withObjectId($object_id); $values = $this->values_factory->handler() diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Factory.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Factory.php index 011253a3cb58..865f78d2e2bc 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Factory.php @@ -32,14 +32,16 @@ class Factory implements ilExportHandlerRepositoryKeyFactoryInterface protected ilExportHandlerFactoryInterface $export_handler; public function __construct( - ilExportHandlerFactoryInterface $export_handler, + ilExportHandlerFactoryInterface $export_handler ) { $this->export_handler = $export_handler; } public function handler(): ilExportHandlerRepositoryKeyInterface { - return new ilExportHandlerRepositoryKey(); + return new ilExportHandlerRepositoryKey( + $this->export_handler->wrapper()->dataFactory()->handler() + ); } public function collection(): ilExportHandlerRepositoryKeyCollectionInterface diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Handler.php index fef94c2c2610..e6d356d3f05f 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Key/Handler.php @@ -22,15 +22,19 @@ use ILIAS\Data\ObjectId; use ILIAS\Export\ExportHandler\I\Repository\Key\HandlerInterface as ilExportHandlerRepositoryKeyInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\DataFactory\HandlerInterface as ilExportHandlerDataFactoryWrapperInterface; class Handler implements ilExportHandlerRepositoryKeyInterface { + protected ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper; protected ObjectId $object_id; protected string $resource_identification_serialized; - public function __construct() - { - $this->object_id = new ObjectId(self::EMPTY_OBJECT_ID); + public function __construct( + ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper + ) { + $this->data_factory_wrapper = $data_factory_wrapper; + $this->object_id = $this->data_factory_wrapper->objId(self::EMPTY_OBJECT_ID); $this->resource_identification_serialized = self::EMPTY_RESOURCE_IDENTIFICATION; } diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/DB/Factory.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/DB/Factory.php index 67f0299d2aed..4c807af9674a 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/DB/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/DB/Factory.php @@ -43,7 +43,8 @@ public function handler(): ilExportHandlerRepositoryDBWrapperInterface { return new ilExportHandlerRepositoryDBWrapper( $this->export_handler, - $this->db + $this->db, + $this->export_handler->wrapper()->dataFactory()->handler() ); } } diff --git a/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/DB/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/DB/Handler.php index cfdb2acecbe0..1ef5d1f91b67 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/DB/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Repository/Wrapper/DB/Handler.php @@ -23,12 +23,12 @@ use DateTimeImmutable; use ilDBConstants; use ilDBInterface; -use ILIAS\Data\ObjectId; use ILIAS\Export\ExportHandler\I\FactoryInterface as ilExportHandlerFactoryInterface; use ILIAS\Export\ExportHandler\I\Repository\Element\CollectionInterface as ilExportHandlerRepositoryElementCollectionInterface; use ILIAS\Export\ExportHandler\I\Repository\Element\HandlerInterface as ilExportHandlerRepositoryElementInterface; use ILIAS\Export\ExportHandler\I\Repository\Key\CollectionInterface as ilExportHandlerRepositoryKeyCollectionInterface; use ILIAS\Export\ExportHandler\I\Repository\Wrapper\DB\HandlerInterface as ilExportHandlerRepositoryDBWrapperInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\DataFactory\HandlerInterface as ilExportHandlerDataFactoryWrapperInterface; class Handler implements ilExportHandlerRepositoryDBWrapperInterface { @@ -36,13 +36,16 @@ class Handler implements ilExportHandlerRepositoryDBWrapperInterface protected ilDBInterface $db; protected ilExportHandlerFactoryInterface $export_handler; + protected ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper; public function __construct( ilExportHandlerFactoryInterface $export_handler, - ilDBInterface $db + ilDBInterface $db, + ilExportHandlerDataFactoryWrapperInterface $data_factory_wrapper ) { $this->export_handler = $export_handler; $this->db = $db; + $this->data_factory_wrapper = $data_factory_wrapper; } public function store( @@ -61,7 +64,7 @@ public function getElements( $res = $this->db->query($this->buildSelectQuery($keys)); while ($row = $res->fetchAssoc()) { $key = $this->export_handler->repository()->key()->handler() - ->withObjectId(new ObjectId((int) $row['object_id'])) + ->withObjectId($this->data_factory_wrapper->objId((int) $row['object_id'])) ->withResourceIdSerialized($row['rid']); $values = $this->export_handler->repository()->values()->handler() ->withCreationDate((new DateTimeImmutable($row['timestamp']))) diff --git a/components/ILIAS/Export/classes/ExportHandler/Table/Factory.php b/components/ILIAS/Export/classes/ExportHandler/Table/Factory.php index 7d1ee1aa38bd..693417095ead 100644 --- a/components/ILIAS/Export/classes/ExportHandler/Table/Factory.php +++ b/components/ILIAS/Export/classes/ExportHandler/Table/Factory.php @@ -21,6 +21,7 @@ namespace ILIAS\Export\ExportHandler\Table; use ilCtrl; +use ILIAS\Data\Factory as ilDataFactory; use ILIAS\DI\UIServices as ilUIServices; use ILIAS\Export\ExportHandler\I\FactoryInterface as ilExportHandlerFactoryInterface; use ILIAS\Export\ExportHandler\I\Table\DataRetrieval\HandlerInterface as ilExportHandlerTableDataRetrievalFactoryInterface; @@ -44,6 +45,7 @@ class Factory implements ilExportHandlerTableFactoryInterface protected ilObjUser $user; protected ilLanguage $lng; protected ilCtrl $ctrl; + protected ilDataFactory $data_factory; public function __construct( ilExportHandlerFactoryInterface $export_handler, @@ -52,7 +54,8 @@ public function __construct( ilRefineryFactory $refinery, ilObjUser $user, ilLanguage $lng, - ilCtrl $ctrl + ilCtrl $ctrl, + ilDataFactory $data_factory ) { $this->export_handler = $export_handler; $this->ui_services = $ui_services; @@ -61,6 +64,7 @@ public function __construct( $this->user = $user; $this->lng = $lng; $this->ctrl = $ctrl; + $this->data_factory = $data_factory; } public function handler(): ilExportHandlerTableInterface @@ -72,7 +76,8 @@ public function handler(): ilExportHandlerTableInterface $this->user, $this->lng, $this->ctrl, - $this->export_handler + $this->export_handler, + $this->data_factory ); } diff --git a/components/ILIAS/Export/classes/ExportHandler/Table/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Table/Handler.php index 0526e437485d..a5a40ad63168 100755 --- a/components/ILIAS/Export/classes/ExportHandler/Table/Handler.php +++ b/components/ILIAS/Export/classes/ExportHandler/Table/Handler.php @@ -23,7 +23,6 @@ use ilCalendarSettings; use ilCtrl; use ILIAS\Data\Factory as ilDataFactory; -use ILIAS\Data\ObjectId; use ILIAS\DI\UIServices as ilUIServices; use ILIAS\Export\ExportHandler\Factory as ilExportHandler; use ILIAS\Export\ExportHandler\I\Consumer\Context\HandlerInterface as ilExportHandlerConsumerContextInterface; @@ -77,7 +76,8 @@ public function __construct( ilObjUser $user, ilLanguage $lng, ilCtrl $ctrl, - ilExportHandler $export_handler + ilExportHandler $export_handler, + ilDataFactory $data_factory ) { $this->http_services = $http_services; $this->ui_services = $ui_services; @@ -87,7 +87,7 @@ public function __construct( $this->user = $user; $this->ctrl = $ctrl; $this->export_handler = $export_handler; - $this->data_factory = new ilDataFactory(); + $this->data_factory = $data_factory; } protected function getColumns(): array @@ -189,7 +189,7 @@ protected function getActions(): array */ protected function deleteItems(array $ids_sorted): void { - $object_id = new ObjectId($this->context->exportObject()->getId()); + $object_id = $this->data_factory->objId($this->context->exportObject()->getId()); foreach ($ids_sorted as $export_option_id => $file_identifiers) { $export_option = $this->export_options->getById($export_option_id); if ( @@ -215,7 +215,7 @@ protected function markAsPublicAccess(array $ids_sorted): void $pa_repository_element_factory = $this->export_handler->publicAccess()->repository()->element(); $pa_repository_key_factory = $this->export_handler->publicAccess()->repository()->key(); $pa_repository_values_factory = $this->export_handler->publicAccess()->repository()->values(); - $obj_id = new ObjectId($this->context->exportObject()->getId()); + $obj_id = $this->data_factory->objId($this->context->exportObject()->getId()); foreach ($ids_sorted as $export_option_id => $file_identifiers) { $export_option = $this->export_options->getById($export_option_id); $type_allowed = $export_option->isPublicAccessPossible(); diff --git a/components/ILIAS/Export/classes/ExportHandler/Wrapper/DataFactory/Factory.php b/components/ILIAS/Export/classes/ExportHandler/Wrapper/DataFactory/Factory.php new file mode 100644 index 000000000000..6b88d35114d0 --- /dev/null +++ b/components/ILIAS/Export/classes/ExportHandler/Wrapper/DataFactory/Factory.php @@ -0,0 +1,44 @@ +data_factory = $data_factory; + } + + public function handler(): ilExportHandlerDataFactoryWrapperInterface + { + return new ilExportHandlerDataFactoryWrapper( + $this->data_factory + ); + } +} diff --git a/components/ILIAS/Export/classes/ExportHandler/Wrapper/DataFactory/Handler.php b/components/ILIAS/Export/classes/ExportHandler/Wrapper/DataFactory/Handler.php new file mode 100644 index 000000000000..f36dbc36d73e --- /dev/null +++ b/components/ILIAS/Export/classes/ExportHandler/Wrapper/DataFactory/Handler.php @@ -0,0 +1,41 @@ +data_factory = $data_factory; + } + + public function objId(int $object_id): ObjectId + { + return $this->data_factory->objId($object_id); + } +} diff --git a/components/ILIAS/Export/classes/ExportHandler/Wrapper/Factory.php b/components/ILIAS/Export/classes/ExportHandler/Wrapper/Factory.php new file mode 100644 index 000000000000..d6c57171ae17 --- /dev/null +++ b/components/ILIAS/Export/classes/ExportHandler/Wrapper/Factory.php @@ -0,0 +1,44 @@ +data_factory = $data_factory; + } + + public function dataFactory(): ilExportHandlerDataFactoryWrapperFactoryInterface + { + return new ilExportHandlerDataFactoryWrapperFactory( + $this->data_factory + ); + } +} diff --git a/components/ILIAS/Export/classes/class.ilExportExportOptionXML.php b/components/ILIAS/Export/classes/class.ilExportExportOptionXML.php index 413c3c315234..f2c932a44643 100644 --- a/components/ILIAS/Export/classes/class.ilExportExportOptionXML.php +++ b/components/ILIAS/Export/classes/class.ilExportExportOptionXML.php @@ -19,6 +19,7 @@ declare(strict_types=1); use ILIAS\Data\ObjectId; +use ILIAS\Data\Factory as ilDataFactory; use ILIAS\Data\ReferenceId; use ILIAS\DI\Container; use ILIAS\Export\ExportHandler\I\Table\RowId\HandlerInterface as ilExportHandlerTableRowIdInterface; @@ -38,6 +39,7 @@ class ilExportExportOptionXML extends ilBasicExportOption protected ilLanguage $lng; protected ilCtrl $ctrl; protected ilObjUser $user; + protected ilDataFactory $data_factory; public function init(Container $DIC): void { @@ -45,6 +47,7 @@ public function init(Container $DIC): void $this->lng = $DIC->language(); $this->ctrl = $DIC->ctrl(); $this->user = $DIC->user(); + $this->data_factory = new ilDataFactory(); } public function getExportType(): string @@ -86,7 +89,7 @@ public function onDeleteFiles( ilExportHandlerConsumerContextInterface $context, ilExportHandlerConsumerFileIdentifierCollectionInterface $file_identifiers ): void { - $object_id = new ObjectId($context->exportObject()->getId()); + $object_id = $this->data_factory->objId($context->exportObject()->getId()); $keys = $this->export_handler->repository()->key()->collection(); foreach ($file_identifiers as $file_identifier) { $keys = $keys->withElement($this->export_handler->repository()->key()->handler() @@ -103,7 +106,7 @@ public function onDownloadFiles( ilExportHandlerConsumerContextInterface $context, ilExportHandlerConsumerFileIdentifierCollectionInterface $file_identifiers ): void { - $object_id = new ObjectId($context->exportObject()->getId()); + $object_id = $this->data_factory->objId($context->exportObject()->getId()); $keys = $this->export_handler->repository()->key()->collection(); foreach ($file_identifiers as $file_identifier) { $keys = $keys->withElement($this->export_handler->repository()->key()->handler() @@ -134,7 +137,7 @@ public function onDownloadWithLink( public function getFiles( ilExportHandlerConsumerContextInterface $context ): ilExportHandlerFileInfoCollectionInterface { - $object_id = new ObjectId($context->exportObject()->getId()); + $object_id = $this->data_factory->objId($context->exportObject()->getId()); return $this->buildElements($context, $object_id, [], true); } @@ -142,7 +145,7 @@ public function getFileSelection( ilExportHandlerConsumerContextInterface $context, ilExportHandlerConsumerFileIdentifierCollectionInterface $file_identifiers ): ilExportHandlerFileInfoCollectionInterface { - $object_id = new ObjectId($context->exportObject()->getId()); + $object_id = $this->data_factory->objId($context->exportObject()->getId()); return $this->buildElements($context, $object_id, $file_identifiers->toStringArray()); } @@ -164,7 +167,7 @@ protected function buildElements( } } $elements = $this->export_handler->repository()->handler()->getElements($keys); - $object_id = new ObjectId($context->exportObject()->getId()); + $object_id = $this->data_factory->objId($context->exportObject()->getId()); $collection_builder = $context->fileCollectionBuilder(); foreach ($elements as $element) { $collection_builder = $collection_builder->withResourceIdentifier( diff --git a/components/ILIAS/Export/classes/class.ilExportGUI.php b/components/ILIAS/Export/classes/class.ilExportGUI.php index 303ae90799bb..ac8aacfa31f3 100755 --- a/components/ILIAS/Export/classes/class.ilExportGUI.php +++ b/components/ILIAS/Export/classes/class.ilExportGUI.php @@ -19,6 +19,7 @@ declare(strict_types=1); use ILIAS\Data\ObjectId; +use ILIAS\Data\Factory as ilDataFactory; use ILIAS\DI\UIServices as ilUIServices; use ILIAS\Export\ExportHandler\I\Consumer\Context\HandlerInterface as ilExportHandlerConsumerContextInterface; use ILIAS\Export\ExportHandler\I\Consumer\ExportOption\CollectionInterface as ilExportHandlerConsumerExportOptionCollectionInterface; @@ -56,6 +57,7 @@ class ilExportGUI protected ilTree $tree; protected ilExportHandler $export_handler; protected ilExportHandlerConsumerContextInterface $context; + protected ilDataFactory $data_factory; protected object $parent_gui; public function __construct(object $a_parent_gui, ?ilObject $a_main_obj = null) @@ -79,6 +81,7 @@ public function __construct(object $a_parent_gui, ?ilObject $a_main_obj = null) $this->export_handler = new ilExportHandler(); $this->context = $this->export_handler->consumer()->context()->handler($this, $this->obj); $this->export_options = $this->export_handler->consumer()->exportOption()->collection(); + $this->data_factory = new ilDataFactory(); $this->initExportOptions(); $this->enableStandardXMLExport(); } @@ -194,7 +197,7 @@ final protected function initExportOptions(): void foreach ($export_options as $export_option) { if ( in_array($this->obj->getType(), $export_option->getSupportedRepositoryObjectTypes()) and - $export_option->isObjectSupported(new ObjectId($this->obj->getId())) + $export_option->isObjectSupported($this->data_factory->objId($this->obj->getId())) ) { $this->export_options = $this->export_options->withElement($export_option); } @@ -323,7 +326,7 @@ final protected function createXMLExport() $manager = $this->export_handler->manager()->handler(); if (count($ref_ids_all) === 1) { $export_info = $manager->getExportInfo( - new ObjectId($this->obj->getId()), + $this->data_factory->objId($this->obj->getId()), time() ); $element = $manager->createExport( @@ -338,12 +341,12 @@ final protected function createXMLExport() $object_id_collection_builder = $manager->getObjectIdCollectioBuilder(); foreach ($obj_ids_all as $obj_id) { $object_id_collection_builder = $object_id_collection_builder->addObjectId( - new ObjectId($obj_id), + $this->data_factory->objId($obj_id), in_array($obj_id, $obj_ids_export) ); } $container_export_info = $manager->getContainerExportInfo( - new ObjectId($obj_ids_all[0]), + $this->data_factory->objId($obj_ids_all[0]), $object_id_collection_builder->getCollection() ); $element = $manager->createContainerExport($this->il_user->getId(), $container_export_info); diff --git a/components/ILIAS/Export/classes/class.ilImportExportFactory.php b/components/ILIAS/Export/classes/class.ilImportExportFactory.php index 1c8c8e842e29..6cf3944811ae 100755 --- a/components/ILIAS/Export/classes/class.ilImportExportFactory.php +++ b/components/ILIAS/Export/classes/class.ilImportExportFactory.php @@ -95,7 +95,7 @@ public static function getImporterClass(string $a_component): string $parts = explode('/', $a_component); $component_type = $parts[0]; - $component = $parts[1]; + $component = $parts[2] ?? $parts[1]; $class = ''; if ($component_type == self::PLUGINS_DIR && $objDefinition->isPlugin($component)) { diff --git a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php index 101a67d2b804..955084a0be16 100644 --- a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Link/HandlerTest.php @@ -20,12 +20,12 @@ namespace ILIAS\Export\Test\ExportHandler\PublicAccess\Link; -use _PHPStan_9815bbba4\Nette\Neon\Exception; -use PHPUnit\Framework\TestCase; -use ILIAS\Export\ExportHandler\PublicAccess\Link\Handler as ilExportHandlerPublicAccessLink; -use ILIAS\Export\ExportHandler\PublicAccess\Link\Wrapper\StaticURL\Handler as ilExportHandlerPublicAccessLinkStaticURLWrapper; +use Exception; use ILIAS\Data\ReferenceId; use ILIAS\Data\URI; +use ILIAS\Export\ExportHandler\I\PublicAccess\Link\Wrapper\StaticURL\HandlerInterface as ilExportHandlerPublicAccessLinkStaticURLWrapperInterface; +use ILIAS\Export\ExportHandler\PublicAccess\Link\Handler as ilExportHandlerPublicAccessLink; +use PHPUnit\Framework\TestCase; class HandlerTest extends TestCase { @@ -38,14 +38,18 @@ public function testExportHandlerPublicAccessLink(): void $reference_id_mock = $this->createMock(ReferenceId::class); $reference_id_mock->method("toInt")->willReturn($reference_id); $reference_id_mock->method("toObjectId")->willThrowException(new Exception("unexpected conversion to object id")); - $static_url_wrapper_mock = $this->createMock(ilExportHandlerPublicAccessLinkStaticURLWrapper::class); + $static_url_wrapper_mock = $this->createMock(ilExportHandlerPublicAccessLinkStaticURLWrapperInterface::class); $static_url_wrapper_mock->method("withStaticURL")->willThrowException(new Exception("unexpected overwrite of static URL service object")); $static_url_wrapper_mock->method("buildDownloadURI")->willReturn($uri_mock); - $link = new ilExportHandlerPublicAccessLink(); - $link = $link - ->withReferenceId($reference_id_mock) - ->withStaticURLWrapper($static_url_wrapper_mock); - self::assertEquals($download_url, $link->getLink()); - self::assertEquals($reference_id, $link->getReferenceId()->toInt()); + try { + $link = new ilExportHandlerPublicAccessLink(); + $link = $link + ->withReferenceId($reference_id_mock) + ->withStaticURLWrapper($static_url_wrapper_mock); + self::assertEquals($download_url, $link->getLink()); + self::assertEquals($reference_id, $link->getReferenceId()->toInt()); + } catch (Exception $exception) { + $this->fail($exception->getMessage()); + } } } diff --git a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Element/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Element/HandlerTest.php new file mode 100644 index 000000000000..49cdf36e4932 --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Element/HandlerTest.php @@ -0,0 +1,103 @@ +createMock(ObjectId::class); + $object_id_mock_01->method("toInt")->willReturn(20); + $object_id_mock_01->method("toReferenceIds")->willThrowException(new Exception("unexpected reference id access")); + $values_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryValuesInteface::class); + $values_mock->method("isValid")->willReturn(true); + $values_mock->method("getIdentification")->willReturn("id"); + $values_mock->method("withIdentification")->willThrowException(new Exception("unexpected id overwrite")); + $values_mock->method("getExportOptionId")->willReturn("exp_id"); + $values_mock->method("withExportOptionId")->willThrowException(new Exception("unexpected exp id overwrite")); + $values_mock->method("getLastModified")->willThrowException(new Exception("unexpected last modified access")); + $values_not_storable_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryValuesInteface::class); + $values_not_storable_mock->method("isValid")->willReturn(false); + $values_not_storable_mock->method("getIdentification")->willThrowException(new Exception("unexpected id access")); + $values_not_storable_mock->method("withIdentification")->willThrowException(new Exception("unexpected id overwrite")); + $values_not_storable_mock->method("getExportOptionId")->willThrowException(new Exception("unexpected exp id access")); + $values_not_storable_mock->method("withExportOptionId")->willThrowException(new Exception("unexpected exp id overwrite")); + $values_not_storable_mock->method("getLastModified")->willThrowException(new Exception("unexpected last modified access")); + $values_mock->method("equals")->willReturnMap([ + [$values_mock, true], [$values_not_storable_mock, false] + ]); + $values_not_storable_mock->method("equals")->willReturnMap([ + [$values_mock, false], [$values_not_storable_mock, true] + ]); + $key_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyInterface::class); + $key_mock->method("isValid")->willReturn(true); + $key_mock->method("getObjectId")->willReturn($object_id_mock_01); + $key_mock->method("withObjectId")->willThrowException(new Exception("unexpected object id overwrite")); + $key_not_storable_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyInterface::class); + $key_not_storable_mock->method("isValid")->willReturn(false); + $key_not_storable_mock->method("getObjectId")->willThrowException(new Exception("unexpected object id access")); + $key_not_storable_mock->method("withObjectId")->willThrowException(new Exception("unexpected object id overwrite")); + $key_mock->method("equals")->willReturnMap([ + [$key_mock, true], [$key_not_storable_mock, false] + ]); + $key_not_storable_mock->method("equals")->willReturnMap([ + [$key_mock, false], [$key_not_storable_mock, true] + ]); + try { + $element = new ilExportHandlerPublicAccessRepositoryElement(); + $element_with_key = $element + ->withKey($key_mock); + $element_with_values = $element + ->withValues($values_mock); + $element_complete = $element + ->withKey($key_mock) + ->withValues($values_mock); + $element_not_storable_01 = $element + ->withKey($key_not_storable_mock) + ->withValues($values_mock); + $element_not_storable_02 = $element + ->withKey($key_mock) + ->withValues($values_not_storable_mock); + $element_not_storable_03 = $element + ->withKey($key_not_storable_mock) + ->withValues($values_not_storable_mock); + self::assertTrue($element_complete->isStorable()); + self::assertFalse($element_not_storable_01->isStorable()); + self::assertFalse($element_not_storable_02->isStorable()); + self::assertFalse($element_not_storable_03->isStorable()); + self::assertTrue($element->equals($element)); + self::assertTrue($element_with_key->equals($element_with_key)); + self::assertTrue($element_with_values->equals($element_with_values)); + self::assertTrue($element_complete->equals($element_complete)); + self::assertFalse($element_complete->equals($element)); + self::assertFalse($element_not_storable_01->equals($element)); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } + } +} diff --git a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Key/Collection.php b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Key/Collection.php new file mode 100644 index 000000000000..c7408b11b632 --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Key/Collection.php @@ -0,0 +1,75 @@ +createMock(ObjectId::class); + $object_id_mock_01->method("toInt")->willReturn(1); + $object_id_mock_01->method("toReferenceIds")->willThrowException(new Exception("unexpected access of reference ids")); + $object_id_mock_02 = $this->createMock(ObjectId::class); + $object_id_mock_02->method("toInt")->willReturn(2); + $object_id_mock_02->method("toReferenceIds")->willThrowException(new Exception("unexpected access of reference ids")); + $object_id_mock_03 = $this->createMock(ObjectId::class); + $object_id_mock_03->method("toInt")->willReturn(3); + $object_id_mock_03->method("toReferenceIds")->willThrowException(new Exception("unexpected access of reference ids")); + $key_mock_01 = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyInterface::class); + $key_mock_01->method("isValid")->willReturn(true); + $key_mock_01->method("getObjectId")->willReturn($object_id_mock_01); + $key_mock_01->method("withObjectId")->willThrowException(new Exception("unexpected overwrite of object id")); + $key_mock_02 = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyInterface::class); + $key_mock_02->method("isValid")->willReturn(true); + $key_mock_02->method("getObjectId")->willReturn($object_id_mock_02); + $key_mock_02->method("withObjectId")->willThrowException(new Exception("unexpected overwrite of object id")); + $key_mock_03 = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyInterface::class); + $key_mock_03->method("isValid")->willReturn(true); + $key_mock_03->method("getObjectId")->willReturn($object_id_mock_03); + $key_mock_03->method("withObjectId")->willThrowException(new Exception("unexpected overwrite of object id")); + try { + $empty_collection = new ilExportHandlerPublicAccessRepositoryKeyCollection(); + $full_collection = $empty_collection + ->withElement($key_mock_01) + ->withElement($key_mock_02) + ->withElement($key_mock_03); + self::assertCount(0, $empty_collection); + self::assertFalse($empty_collection->valid()); + self::assertCount(3, $full_collection); + $full_collection->rewind(); + for ($i = 0; $i < 3; $i++) { + self::assertEquals($i, $full_collection->key()); + self::assertEquals($object_id_mock_01->toInt(), $full_collection->current()->getObjectId()->toInt()); + self::assertTrue($full_collection->valid()); + $full_collection->next(); + } + self::assertFalse($full_collection->valid()); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } + } +} diff --git a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Key/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Key/HandlerTest.php new file mode 100644 index 000000000000..587742a9f1e5 --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Key/HandlerTest.php @@ -0,0 +1,54 @@ +createMock(ObjectId::class); + $object_id_mock->method("toInt")->willReturn($object_id); + $object_id_mock->method("toReferenceIds")->willThrowException(new Exception("unexpected access of reference ids")); + $object_id_invalid_mock = $this->createMock(ObjectId::class); + $object_id_invalid_mock->method('toInt')->willReturn(ilExportHandlerPublicAccessRepositoryKeyInterface::EMPTY_OBJECT_ID); + $object_id_invalid_mock->method("toReferenceIds")->willThrowException(new Exception("toReferenceIds should not be called")); + $df_factory_wrapper_mock = $this->createMock(ilExportHandlerDataFactoryWrapperInterface::class); + $df_factory_wrapper_mock->method('objId')->willReturn($object_id_invalid_mock); + try { + $key = new ilExportHandlerPublicAccessRepositoryKey($df_factory_wrapper_mock); + $key_with_object_id = $key + ->withObjectId($object_id_mock); + self::assertFalse($key->isValid()); + self::assertTrue($key_with_object_id->isValid()); + self::assertEquals($object_id, $key_with_object_id->getObjectId()->toInt()); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } + } +} diff --git a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Values/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Values/HandlerTest.php new file mode 100644 index 000000000000..e6709c66f282 --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/Values/HandlerTest.php @@ -0,0 +1,54 @@ +withIdentification($identification); + $repository_values_with_export_option = $repository_values + ->withExportOptionId($export_option); + $repository_values_complete = $repository_values + ->withExportOptionId($export_option) + ->withIdentification($identification); + self::assertFalse($repository_values->isValid()); + self::assertFalse($repository_values_with_identification->isValid()); + self::assertFalse($repository_values_with_export_option->isValid()); + self::assertTrue($repository_values_complete->isValid()); + self::assertEquals($identification, $repository_values_with_identification->getIdentification()); + self::assertEquals($identification, $repository_values_complete->getIdentification()); + self::assertEquals($export_option, $repository_values_complete->getExportOptionId()); + self::assertEquals($export_option, $repository_values_with_export_option->getExportOptionId()); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } + } +} diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Element/CollectionTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Element/CollectionTest.php index 58dc81a68205..ff41f6e268f8 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Element/CollectionTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Element/CollectionTest.php @@ -21,13 +21,11 @@ namespace ILIAS\Export\Test\ExportHandler\Repository\Element; use DateTimeImmutable; -use ILIAS\Data\ObjectId; -use PHPUnit\Framework\TestCase; -use ILIAS\Export\ExportHandler\Repository\Values\Handler as ilExportHandlerRepositoryValues; +use Exception; +use ILIAS\Export\ExportHandler\I\Repository\Element\HandlerInterface as ilExportHandlerRepositoryElementInterface; +use ILIAS\Export\ExportHandler\I\Repository\Values\HandlerInterface as ilExportHandlerRepositoryValuesInterface; use ILIAS\Export\ExportHandler\Repository\Element\Collection as ilExportHandlerRepositoryElementCollection; -use ILIAS\Export\ExportHandler\Repository\Element\Handler as ilExportHandlerRepositoryElement; - -use function Symfony\Component\String\b; +use PHPUnit\Framework\TestCase; class CollectionTest extends TestCase { @@ -36,21 +34,21 @@ public function testExportHandlerRepositoryElementCollection(): void $date_1 = new DateTimeImmutable('2020-01-01'); $date_2 = new DateTimeImmutable('2020-01-02'); $date_3 = new DateTimeImmutable('2020-01-03'); - $values_mock_01 = $this->createMock(ilExportHandlerRepositoryValues::class); + $values_mock_01 = $this->createMock(ilExportHandlerRepositoryValuesInterface::class); $values_mock_01->method("getCreationDate")->willReturn($date_1); - $values_mock_02 = $this->createMock(ilExportHandlerRepositoryValues::class); + $values_mock_02 = $this->createMock(ilExportHandlerRepositoryValuesInterface::class); $values_mock_02->method("getCreationDate")->willReturn($date_2); - $values_mock_03 = $this->createMock(ilExportHandlerRepositoryValues::class); + $values_mock_03 = $this->createMock(ilExportHandlerRepositoryValuesInterface::class); $values_mock_03->method("getCreationDate")->willReturn($date_2); - $values_mock_04 = $this->createMock(ilExportHandlerRepositoryValues::class); + $values_mock_04 = $this->createMock(ilExportHandlerRepositoryValuesInterface::class); $values_mock_04->method("getCreationDate")->willReturn($date_3); - $element_mock_01 = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_mock_01 = $this->createMock(ilExportHandlerRepositoryElementInterface::class); $element_mock_01->method('getValues')->willReturn($values_mock_01); - $element_mock_02 = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_mock_02 = $this->createMock(ilExportHandlerRepositoryElementInterface::class); $element_mock_02->method('getValues')->willReturn($values_mock_02); - $element_mock_03 = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_mock_03 = $this->createMock(ilExportHandlerRepositoryElementInterface::class); $element_mock_03->method('getValues')->willReturn($values_mock_03); - $element_mock_04 = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_mock_04 = $this->createMock(ilExportHandlerRepositoryElementInterface::class); $element_mock_04->method('getValues')->willReturn($values_mock_04); $element_mock_01->method("equals")->willReturnMap([ [$element_mock_01, true], [$element_mock_02, false], @@ -68,40 +66,44 @@ public function testExportHandlerRepositoryElementCollection(): void [$element_mock_01, false], [$element_mock_02, false], [$element_mock_03, false], [$element_mock_04, true] ]); - $collection_empty = new ilExportHandlerRepositoryElementCollection(); - $collection = $collection_empty - ->withElement($element_mock_01) - ->withElement($element_mock_02) - ->withElement($element_mock_03) - ->withElement($element_mock_04); - $collection->rewind(); - $collection_empty->rewind(); - self::assertTrue($element_mock_01->equals($element_mock_01)); - self::assertFalse($element_mock_01->equals($element_mock_02)); - self::assertFalse($element_mock_01->equals($element_mock_03)); - self::assertFalse($element_mock_01->equals($element_mock_04)); - self::assertTrue($collection->valid()); - self::assertFalse($collection_empty->valid()); - self::assertCount(4, $collection); - self::assertCount(0, $collection_empty); - $this->checkElements($collection, [ - $element_mock_01, - $element_mock_02, - $element_mock_03, - $element_mock_04 - ]); - self::assertObjectEquals($element_mock_04, $collection->newest()); - # Check if newest() call changed element order - $this->checkElements($collection, [ - $element_mock_01, - $element_mock_02, - $element_mock_03, - $element_mock_04 - ]); + try { + $collection_empty = new ilExportHandlerRepositoryElementCollection(); + $collection = $collection_empty + ->withElement($element_mock_01) + ->withElement($element_mock_02) + ->withElement($element_mock_03) + ->withElement($element_mock_04); + $collection->rewind(); + $collection_empty->rewind(); + self::assertTrue($element_mock_01->equals($element_mock_01)); + self::assertFalse($element_mock_01->equals($element_mock_02)); + self::assertFalse($element_mock_01->equals($element_mock_03)); + self::assertFalse($element_mock_01->equals($element_mock_04)); + self::assertTrue($collection->valid()); + self::assertFalse($collection_empty->valid()); + self::assertCount(4, $collection); + self::assertCount(0, $collection_empty); + $this->checkElements($collection, [ + $element_mock_01, + $element_mock_02, + $element_mock_03, + $element_mock_04 + ]); + self::assertObjectEquals($element_mock_04, $collection->newest()); + # Check if newest() call changed element order + $this->checkElements($collection, [ + $element_mock_01, + $element_mock_02, + $element_mock_03, + $element_mock_04 + ]); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } } /** - * @param ilExportHandlerRepositoryElement[] $elements + * @param ilExportHandlerRepositoryElementInterface[] $elements */ protected function checkElements( ilExportHandlerRepositoryElementCollection $collection, diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Element/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Element/HandlerTest.php index 2643cb069e7d..d42b88463b10 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Element/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Element/HandlerTest.php @@ -21,15 +21,16 @@ namespace ILIAS\Export\Test\ExportHandler\Repository\Element; use DateTimeImmutable; +use Exception; use ILIAS\Data\ObjectId; -use PHPUnit\Framework\TestCase; +use ILIAS\Export\ExportHandler\I\Repository\Element\Wrapper\IRSS\FactoryInterface as ilExportHandlerRepositoryElementIRSSWrapperFactoryInterface; +use ILIAS\Export\ExportHandler\I\Repository\Element\Wrapper\IRSS\HandlerInterface as ilExportHandlerRepositoryElementIRSSWrapperInterface; +use ILIAS\Export\ExportHandler\I\Repository\Element\Wrapper\IRSSInfo\FactoryInterface as ilExportHandlerRepositoryElementIRSSInfoWrapperFactoryInterface; +use ILIAS\Export\ExportHandler\I\Repository\Element\Wrapper\IRSSInfo\HandlerInterface as ilExportHandlerRepositoryElementIRSSInfoWrapperInterface; +use ILIAS\Export\ExportHandler\I\Repository\Key\HandlerInterface as ilExportHandlerRepositoryKeyInterface; +use ILIAS\Export\ExportHandler\I\Repository\Values\HandlerInterface as ilExportHandlerRepositoryValuesInterface; use ILIAS\Export\ExportHandler\Repository\Element\Handler as ilExportHandlerRepositoryElement; -use ILIAS\Export\ExportHandler\Repository\Element\Wrapper\IRSSInfo\Factory as ilExportHandlerRepositoryElementIRSSInfoWrapperFactory; -use ILIAS\Export\ExportHandler\Repository\Element\Wrapper\IRSSInfo\Handler as ilExportHandlerRepositoryElementIRSSInfoWrapper; -use ILIAS\Export\ExportHandler\Repository\Element\Wrapper\IRSS\Factory as ilExportHandlerRepositoryElementIRSSWrapperFactory; -use ILIAS\Export\ExportHandler\Repository\Element\Wrapper\IRSS\Handler as ilExportHandlerRepositoryElementIRSSWrapper; -use ILIAS\Export\ExportHandler\Repository\Key\Handler as ilExportHandlerRepositoryKey; -use ILIAS\Export\ExportHandler\Repository\Values\Handler as ilExportHandlerRepositoryValues; +use PHPUnit\Framework\TestCase; class HandlerTest extends TestCase { @@ -37,47 +38,49 @@ public function testExportHandlerRepositoryElement(): void { $resouce_id_serialized = "keykeykey"; $object_id_mock = $this->createMock(ObjectId::class); - $key_mock = $this->createMock(ilExportHandlerRepositoryKey::class); + $key_mock = $this->createMock(ilExportHandlerRepositoryKeyInterface::class); $key_mock->method("isCompleteKey")->willReturn(true); $key_mock->method("isObjectIdKey")->willReturn(false); $key_mock->method("isResourceIdKey")->willReturn(false); $key_mock->method("getResourceIdSerialized")->willReturn($resouce_id_serialized); $key_mock->method("getObjectId")->willReturn($object_id_mock); $date_time_mock = $this->createMock(DateTimeImmutable::class); - $value_mock = $this->createMock(ilExportHandlerRepositoryValues::class); + $value_mock = $this->createMock(ilExportHandlerRepositoryValuesInterface::class); $value_mock->method("isValid")->willReturn(true); $value_mock->method("getOwnerId")->willReturn(1); $value_mock->method("getCreationDate")->willReturn($date_time_mock); - $irss_wrapper_mock = $this->createMock(ilExportHandlerRepositoryElementIRSSWrapper::class); + $irss_wrapper_mock = $this->createMock(ilExportHandlerRepositoryElementIRSSWrapperInterface::class); $irss_wrapper_mock->method("withResourceIdSerialized")->with($resouce_id_serialized)->willReturn($irss_wrapper_mock); - $irss_wrapper_factory_mock = $this->createMock(ilExportHandlerRepositoryElementIRSSWrapperFactory::class); + $irss_wrapper_factory_mock = $this->createMock(ilExportHandlerRepositoryElementIRSSWrapperFactoryInterface::class); $irss_wrapper_factory_mock->method("handler")->willReturn($irss_wrapper_mock); - $irss_info_wrapper_mock = $this->createMock(ilExportHandlerRepositoryElementIRSSInfoWrapper::class); + $irss_info_wrapper_mock = $this->createMock(ilExportHandlerRepositoryElementIRSSInfoWrapperInterface::class); $irss_info_wrapper_mock->method("withResourceIdSerialized")->with($resouce_id_serialized)->willReturn($irss_info_wrapper_mock); - $irss_info_wrapper_factory_mock = $this->createMock(ilExportHandlerRepositoryElementIRSSInfoWrapperFactory::class); + $irss_info_wrapper_factory_mock = $this->createMock(ilExportHandlerRepositoryElementIRSSInfoWrapperFactoryInterface::class); $irss_info_wrapper_factory_mock->method("handler")->willReturn($irss_info_wrapper_mock); - - $element = (new ilExportHandlerRepositoryElement( - $irss_wrapper_factory_mock, - $irss_info_wrapper_factory_mock - )) - ->withKey($key_mock) - ->withValues($value_mock); - $element_not_storable_0 = new ilExportHandlerRepositoryElement( - $irss_wrapper_factory_mock, - $irss_info_wrapper_factory_mock - ); - $element_not_storable_1 = $element_not_storable_0->withValues($value_mock); - $element_not_storable_2 = $element_not_storable_0->withKey($key_mock); - - self::assertFalse($element_not_storable_0->isStorable()); - self::assertFalse($element_not_storable_1->isStorable()); - self::assertFalse($element_not_storable_2->isStorable()); - self::assertEquals($irss_wrapper_mock, $element->getIRSS()); - self::assertEquals($irss_info_wrapper_mock, $element->getIRSSInfo()); - self::assertEquals($value_mock, $element->getValues()); - self::assertEquals($key_mock, $element->getKey()); - self::assertTrue($element->isStorable()); - self::assertEquals("xml", $element->getFileType()); + try { + $element = (new ilExportHandlerRepositoryElement( + $irss_wrapper_factory_mock, + $irss_info_wrapper_factory_mock + )) + ->withKey($key_mock) + ->withValues($value_mock); + $element_not_storable_0 = new ilExportHandlerRepositoryElement( + $irss_wrapper_factory_mock, + $irss_info_wrapper_factory_mock + ); + $element_not_storable_1 = $element_not_storable_0->withValues($value_mock); + $element_not_storable_2 = $element_not_storable_0->withKey($key_mock); + self::assertFalse($element_not_storable_0->isStorable()); + self::assertFalse($element_not_storable_1->isStorable()); + self::assertFalse($element_not_storable_2->isStorable()); + self::assertEquals($irss_wrapper_mock, $element->getIRSS()); + self::assertEquals($irss_info_wrapper_mock, $element->getIRSSInfo()); + self::assertEquals($value_mock, $element->getValues()); + self::assertEquals($key_mock, $element->getKey()); + self::assertTrue($element->isStorable()); + self::assertEquals("xml", $element->getFileType()); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Handler.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Handler.php index d8237c1b6029..77eaa5df59ce 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Handler.php +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Handler.php @@ -23,21 +23,20 @@ use DateTimeImmutable; use Exception; use ILIAS\Data\ObjectId; -use PHPUnit\Framework\Constraint\Callback; -use PHPUnit\Framework\TestCase; +use ILIAS\Export\ExportHandler\I\Info\Export\HandlerInterface as ilExportHandlerExportInfoInterface; +use ILIAS\Export\ExportHandler\I\Repository\Element\CollectionInterface as ilExportHandlerRepositoryElementCollectionInterface; +use ILIAS\Export\ExportHandler\I\Repository\Element\FactoryInterface as ilExportHandlerRepositoryElementFactoryInterface; +use ILIAS\Export\ExportHandler\I\Repository\Element\HandlerInterface as ilExportHandlerRepositoryElementInterface; +use ILIAS\Export\ExportHandler\I\Repository\Key\CollectionInterface as ilExportHandlerRepositoryKeyCollectionInterface; +use ILIAS\Export\ExportHandler\I\Repository\Key\FactoryInterface as ilExportHandlerRepositoryKeyFactoryInterface; +use ILIAS\Export\ExportHandler\I\Repository\Key\HandlerInterface as ilExportHandlerRepositoryKeyInterface; +use ILIAS\Export\ExportHandler\I\Repository\Stakeholder\HandlerInterface as ilExportHandlerRepositoryStakeholderInterface; +use ILIAS\Export\ExportHandler\I\Repository\Values\FactoryInterface as ilExportHandlerRepositoryValuesFactoryInterface; +use ILIAS\Export\ExportHandler\I\Repository\Values\HandlerInterface as ilExportHandlerRepositoryValuesInterface; +use ILIAS\Export\ExportHandler\I\Repository\Wrapper\DB\HandlerInterface as ilExportHandlerRepositoryDBWrapperInterface; +use ILIAS\Export\ExportHandler\I\Repository\Wrapper\IRSS\HandlerInterface as ilExportHandlerRepositoryIRSSWrapperInterface; use ILIAS\Export\ExportHandler\Repository\Handler as ilExportHandlerRepository; -use ILIAS\Export\ExportHandler\Repository\Stakeholder\Handler as ilExportHandlerRepositoryStakeholder; -use ILIAS\Export\ExportHandler\Repository\Key\Factory as ilExportHandlerRepositoryKeyFactory; -use ILIAS\Export\ExportHandler\Repository\Key\Handler as ilExportHandlerRepositoryKey; -use ILIAS\Export\ExportHandler\Repository\Key\Collection as ilExportHandlerRepositoryKeyCollection; -use ILIAS\Export\ExportHandler\Repository\Values\Factory as ilExportHandlerRepositoryValuesFactory; -use ILIAS\Export\ExportHandler\Repository\Values\Handler as ilExportHandlerRepositoryValues; -use ILIAS\Export\ExportHandler\Repository\Element\Factory as ilExportHandlerRepositoryElementFactory; -use ILIAS\Export\ExportHandler\Repository\Element\Handler as ilExportHandlerRepositoryElement; -use ILIAS\Export\ExportHandler\Repository\Element\Collection as ilExportHandlerRepositoryElementCollection; -use ILIAS\Export\ExportHandler\Repository\Wrapper\DB\Handler as ilExportHandlerRepositoryDBWrapper; -use ILIAS\Export\ExportHandler\Repository\Wrapper\IRSS\Handler as ilExportHandlerRepositoryIRSSWrapper; -use ILIAS\Export\ExportHandler\Info\Export\Handler as ilExportHandlerExportInfo; +use PHPUnit\Framework\TestCase; class Handler extends TestCase { @@ -48,44 +47,35 @@ public function testExportHandlerRepository(): void $resource_id_serialized = "rid"; $owner_id = 6; $creation_date = new DateTimeImmutable(); - - $element_collection_mock01 = $this->createMock(ilExportHandlerRepositoryElementCollection::class); - - $stakeholder_mock = $this->createMock(ilExportHandlerRepositoryStakeholder::class); + $element_collection_mock01 = $this->createMock(ilExportHandlerRepositoryElementCollectionInterface::class); + $stakeholder_mock = $this->createMock(ilExportHandlerRepositoryStakeholderInterface::class); $stakeholder_mock->method("getOwnerId")->willReturn($owner_id); $stakeholder_mock->method("withOwnerId")->willThrowException(new Exception("owner id changed")); - $this->repository_elements = []; - $object_id_mock01 = $this->createMock(ObjectId::class); $object_id_mock01->method("toInt")->willReturn(1); $object_id_mock01->method("toReferenceIds")->willThrowException(new Exception("unexpected method call")); - - $key_complete_mock = $this->createMock(ilExportHandlerRepositoryKey::class); + $key_complete_mock = $this->createMock(ilExportHandlerRepositoryKeyInterface::class); $key_complete_mock->method("withObjectId")->with($object_id_mock01)->willReturn($key_complete_mock); $key_complete_mock->method("withResourceIdSerialized")->with($resource_id_serialized)->willReturn($key_complete_mock); $key_complete_mock->method("getObjectId")->willReturn($object_id_mock01); $key_complete_mock->method("getResourceIdSerialized")->willReturn($resource_id_serialized); - - $key_obj_id_mock = $this->createMock(ilExportHandlerRepositoryKey::class); + $key_obj_id_mock = $this->createMock(ilExportHandlerRepositoryKeyInterface::class); $key_obj_id_mock->method("withObjectId")->with($object_id_mock01)->willReturn($key_obj_id_mock); $key_obj_id_mock->method("withResourceIdSerialized")->with($resource_id_serialized)->willReturn($key_complete_mock); $key_obj_id_mock->method("getObjectId")->willReturn($object_id_mock01); $key_obj_id_mock->method("getResourceIdSerialized")->willThrowException(new Exception("resource id not set")); - - $key_res_id_mock = $this->createMock(ilExportHandlerRepositoryKey::class); + $key_res_id_mock = $this->createMock(ilExportHandlerRepositoryKeyInterface::class); $key_res_id_mock->method("withObjectId")->with($object_id_mock01)->willReturn($key_complete_mock); $key_res_id_mock->method("withResourceIdSerialized")->with($resource_id_serialized)->willReturn($key_res_id_mock); $key_res_id_mock->method("getObjectId")->willThrowException(new Exception("obj id not set")); $key_res_id_mock->method("getResourceIdSerialized")->willReturn($resource_id_serialized); - - $key_mock = $this->createMock(ilExportHandlerRepositoryKey::class); + $key_mock = $this->createMock(ilExportHandlerRepositoryKeyInterface::class); $key_mock->method("withObjectId")->with($object_id_mock01)->willReturn($key_obj_id_mock); $key_mock->method("withResourceIdSerialized")->with($resource_id_serialized)->willReturn($key_res_id_mock); $key_mock->method("getObjectId")->willThrowException(new Exception("obj id not set")); $key_mock->method("getResourceIdSerialized")->willThrowException(new Exception("resource id not set")); - - $key_collection_with_element_mock = $this->createMock(ilExportHandlerRepositoryKeyCollection::class); + $key_collection_with_element_mock = $this->createMock(ilExportHandlerRepositoryKeyCollectionInterface::class); $key_collection_with_element_mock->method("withElement")->willThrowException(new Exception("to many keys added to collection")); $key_collection_with_element_mock->method("current")->willReturn($key_complete_mock); $key_collection_with_element_mock->method("key")->willReturn(0, 1); @@ -93,8 +83,7 @@ public function testExportHandlerRepository(): void # rewind() does not return anything $key_collection_with_element_mock->method("valid")->willReturn(true, false); $key_collection_with_element_mock->method("count")->willReturn(1); - - $key_collection_mock01 = $this->createMock(ilExportHandlerRepositoryKeyCollection::class); + $key_collection_mock01 = $this->createMock(ilExportHandlerRepositoryKeyCollectionInterface::class); $key_collection_mock01->method("withElement")->with($key_complete_mock)->willReturn($key_collection_with_element_mock); $key_collection_mock01->method("withElement")->with($key_mock)->willThrowException(new Exception("key incomplete")); $key_collection_mock01->method("withElement")->with($key_obj_id_mock)->willThrowException(new Exception("key incomplete")); @@ -105,50 +94,39 @@ public function testExportHandlerRepository(): void # rewind() does not return anything $key_collection_mock01->method("valid")->willReturn(false); $key_collection_mock01->method("count")->willReturn(0); - - $key_factory_mock = $this->createMock(ilExportHandlerRepositoryKeyFactory::class); + $key_factory_mock = $this->createMock(ilExportHandlerRepositoryKeyFactoryInterface::class); $key_factory_mock->method("handler")->willReturn($key_mock); $key_factory_mock->method("collection")->willReturn($key_collection_mock01); - - $export_info_mock = $this->createMock(ilExportHandlerExportInfo::class); - - $irss_wrapper_mock = $this->createMock(ilExportHandlerRepositoryIRSSWrapper::class); + $export_info_mock = $this->createMock(ilExportHandlerExportInfoInterface::class); + $irss_wrapper_mock = $this->createMock(ilExportHandlerRepositoryIRSSWrapperInterface::class); $irss_wrapper_mock->method('createEmptyContainer')->with($export_info_mock, $stakeholder_mock)->willReturn($resource_id_serialized); $irss_wrapper_mock->method("getCreationDate")->with($resource_id_serialized)->willReturn($creation_date); - - $value_mock = $this->createMock(ilExportHandlerRepositoryValues::class); + $value_mock = $this->createMock(ilExportHandlerRepositoryValuesInterface::class); $value_mock->method("withOwnerId")->with($owner_id)->willReturn($value_mock); $value_mock->method("withCreationDate")->with($creation_date)->willReturn($value_mock); $value_mock->method("getOwnerId")->willReturn($owner_id); $value_mock->method("getCreationDate")->willReturn($creation_date); - - $values_factory = $this->createMock(ilExportHandlerRepositoryValuesFactory::class); - $values_factory->method("handler")->willReturn($value_mock); - - $element_complete_mock = $this->createMock(ilExportHandlerRepositoryElement::class); + $values_factory_mock = $this->createMock(ilExportHandlerRepositoryValuesFactoryInterface::class); + $values_factory_mock->method("handler")->willReturn($value_mock); + $element_complete_mock = $this->createMock(ilExportHandlerRepositoryElementInterface::class); $element_complete_mock->method("isStorable")->willReturn(true); $element_complete_mock->method("withKey")->with($key_mock)->willReturn($element_complete_mock); $element_complete_mock->method("withValues")->with($value_mock)->willReturn($element_complete_mock); - - $element_w_key_mock = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_w_key_mock = $this->createMock(ilExportHandlerRepositoryElementInterface::class); $element_w_key_mock->method("isStorable")->willReturn(false); $element_w_key_mock->method("withKey")->with($key_mock)->willReturn($element_w_key_mock); $element_w_key_mock->method("withValues")->with($value_mock)->willReturn($element_complete_mock); - - $element_w_values_mock = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_w_values_mock = $this->createMock(ilExportHandlerRepositoryElementInterface::class); $element_w_values_mock->method("isStorable")->willReturn(false); $element_w_values_mock->method("withKey")->with($key_mock)->willReturn($element_complete_mock); $element_w_values_mock->method("withValues")->with($value_mock)->willReturn($element_w_values_mock); - - $element_emtpy_mock = $this->createMock(ilExportHandlerRepositoryElement::class); + $element_emtpy_mock = $this->createMock(ilExportHandlerRepositoryElementInterface::class); $element_emtpy_mock->method("isStorable")->willReturn(false); $element_emtpy_mock->method("withKey")->with($key_mock)->willReturn($element_w_key_mock); $element_emtpy_mock->method("withValues")->with($value_mock)->willReturn($element_w_values_mock); - - $element_factory_mock = $this->createMock(ilExportHandlerRepositoryElementFactory::class); + $element_factory_mock = $this->createMock(ilExportHandlerRepositoryElementFactoryInterface::class); $element_factory_mock->method("handler")->willReturn($element_emtpy_mock); - - $db_wrapper_mock = $this->createMock(ilExportHandlerRepositoryDBWrapper::class); + $db_wrapper_mock = $this->createMock(ilExportHandlerRepositoryDBWrapperInterface::class); $db_wrapper_mock->method("getElements")->with($key_collection_mock01)->willReturnCallback(function ($x) { return $this->mockDBWrapperGetElements($x); }); @@ -158,35 +136,30 @@ public function testExportHandlerRepository(): void $db_wrapper_mock->method("store")->with($element_complete_mock)->willReturnCallback(function ($x) { $this->mockDBWrapperStore($x); }); - - $export_repository = new ilExportHandlerRepository( - $key_factory_mock, - $values_factory, - $element_factory_mock, - $db_wrapper_mock, - $irss_wrapper_mock - ); - - $element = $export_repository->createElement( - $object_id_mock01, - $export_info_mock, - $stakeholder_mock - ); - - self::assertCount(1, $this->repository_elements); - - $export_repository->storeElement($element_complete_mock); - $export_repository->storeElement($element_emtpy_mock); - - self::assertCount(2, $this->repository_elements); - - $elements = $export_repository->getElements($key_collection_mock01); - - self::assertCount(2, $this->repository_elements); - - $export_repository->deleteElements($key_collection_mock01, $stakeholder_mock); - - self::assertCount(0, $this->repository_elements); + try { + $export_repository = new ilExportHandlerRepository( + $key_factory_mock, + $values_factory_mock, + $element_factory_mock, + $db_wrapper_mock, + $irss_wrapper_mock + ); + $element = $export_repository->createElement( + $object_id_mock01, + $export_info_mock, + $stakeholder_mock + ); + self::assertCount(1, $this->repository_elements); + $export_repository->storeElement($element_complete_mock); + $export_repository->storeElement($element_emtpy_mock); + self::assertCount(2, $this->repository_elements); + $elements = $export_repository->getElements($key_collection_mock01); + self::assertCount(2, $this->repository_elements); + $export_repository->deleteElements($key_collection_mock01, $stakeholder_mock); + self::assertCount(0, $this->repository_elements); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } } protected function mockDBWrapperStore( @@ -197,9 +170,9 @@ protected function mockDBWrapperStore( protected function mockDBWrapperGetElements( $x - ): ilExportHandlerRepositoryElementCollection { + ): ilExportHandlerRepositoryElementCollectionInterface { $key_collection_mock = func_get_args()[0]; - $element_collection_mock = $this->createMock(ilExportHandlerRepositoryElementCollection::class); + $element_collection_mock = $this->createMock(ilExportHandlerRepositoryElementCollectionInterface::class); if (empty($this->repository_elements)) { $element_collection_mock->method("newest")->willReturn(null); $element_collection_mock->method("current")->willThrowException(new Exception("empty collection")); diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Key/CollectionTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Key/CollectionTest.php index e15ac227a179..72c7fa9534d3 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Key/CollectionTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Key/CollectionTest.php @@ -20,44 +20,49 @@ namespace ILIAS\Export\Test\ExportHandler\Repository\Key; +use Exception; use ILIAS\Data\ObjectId; -use PHPUnit\Framework\TestCase; -use ILIAS\Export\ExportHandler\Repository\Key\Handler as ilExportHandlerRepositoryKey; +use ILIAS\Export\ExportHandler\I\Repository\Key\HandlerInterface as ilExportHandlerRepositoryKeyInterface; use ILIAS\Export\ExportHandler\Repository\Key\Collection as ilExportHandlerRepositoryKeyCollection; +use PHPUnit\Framework\TestCase; class CollectionTest extends TestCase { public function testExportHandlerRepositoryKeyCollection(): void { - $object_id_1 = $this->createMock(ObjectId::class); - $object_id_1->method('toInt')->willReturn(1); - $object_id_2 = $this->createMock(ObjectId::class); - $object_id_2->method('toInt')->willReturn(2); - $object_id_3 = $this->createMock(ObjectId::class); - $object_id_3->method('toInt')->willReturn(3); - $element_1 = $this->createMock(ilExportHandlerRepositoryKey::class); - $element_1->method('getResourceIdSerialized')->willReturn('r1'); - $element_1->method('getObjectId')->willReturn($object_id_1); - $element_2 = $this->createMock(ilExportHandlerRepositoryKey::class); - $element_2->method('getResourceIdSerialized')->willReturn('r2'); - $element_2->method('getObjectId')->willReturn($object_id_2); - $element_3 = $this->createMock(ilExportHandlerRepositoryKey::class); - $element_3->method('getResourceIdSerialized')->willReturn('r3'); - $element_3->method('getObjectId')->willReturn($object_id_3); + $object_id_mock_01 = $this->createMock(ObjectId::class); + $object_id_mock_01->method('toInt')->willReturn(1); + $object_id_mock_02 = $this->createMock(ObjectId::class); + $object_id_mock_02->method('toInt')->willReturn(2); + $object_id_mock_03 = $this->createMock(ObjectId::class); + $object_id_mock_03->method('toInt')->willReturn(3); + $element_1_mock = $this->createMock(ilExportHandlerRepositoryKeyInterface::class); + $element_1_mock->method('getResourceIdSerialized')->willReturn('r1'); + $element_1_mock->method('getObjectId')->willReturn($object_id_mock_01); + $element_2_mock = $this->createMock(ilExportHandlerRepositoryKeyInterface::class); + $element_2_mock->method('getResourceIdSerialized')->willReturn('r2'); + $element_2_mock->method('getObjectId')->willReturn($object_id_mock_02); + $element_3_mock = $this->createMock(ilExportHandlerRepositoryKeyInterface::class); + $element_3_mock->method('getResourceIdSerialized')->willReturn('r3'); + $element_3_mock->method('getObjectId')->willReturn($object_id_mock_03); $empty_collection = new ilExportHandlerRepositoryKeyCollection(); - $collection_with_elements = $empty_collection - ->withElement($element_1) - ->withElement($element_2) - ->withElement($element_3); - self::assertEquals(3, $collection_with_elements->count()); - self::assertTrue($collection_with_elements->valid()); - $index = 1; - foreach ($collection_with_elements as $element) { - self::assertEquals($index, $element->getObjectId()->toInt()); - self::assertEquals('r' . $index, $element->getResourceIdSerialized()); - $index++; + try { + $collection_with_elements = $empty_collection + ->withElement($element_1_mock) + ->withElement($element_2_mock) + ->withElement($element_3_mock); + self::assertEquals(3, $collection_with_elements->count()); + self::assertTrue($collection_with_elements->valid()); + $index = 1; + foreach ($collection_with_elements as $element) { + self::assertEquals($index, $element->getObjectId()->toInt()); + self::assertEquals('r' . $index, $element->getResourceIdSerialized()); + $index++; + } + self::assertEquals(0, $empty_collection->count()); + self::assertFalse($empty_collection->valid()); + } catch (Exception $exception) { + self::fail($exception->getMessage()); } - self::assertEquals(0, $empty_collection->count()); - self::assertFalse($empty_collection->valid()); } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Key/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Key/HandlerTest.php index affe6a922fa2..8a9c48a34129 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Key/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Key/HandlerTest.php @@ -22,8 +22,10 @@ use Exception; use ILIAS\Data\ObjectId; -use PHPUnit\Framework\TestCase; +use ILIAS\Export\ExportHandler\I\Repository\Key\HandlerInterface as ilExportHandlerRepositoryKeyInterface; +use ILIAS\Export\ExportHandler\I\Wrapper\DataFactory\HandlerInterface as ilExportHandlerDataFactoryWrapperInterface; use ILIAS\Export\ExportHandler\Repository\Key\Handler as ilExportHandlerRepositoryKey; +use PHPUnit\Framework\TestCase; class HandlerTest extends TestCase { @@ -33,39 +35,50 @@ public function testExportHandlerRepositoryKey(): void $object_id_mock = $this->createMock(ObjectId::class); $object_id_mock->method('toInt')->willReturn(123); $object_id_mock->method("toReferenceIds")->willThrowException(new Exception("toReferenceIds should not be called")); - $repository_key_empty = new ilExportHandlerRepositoryKey(); - $repository_key_with_resource_id = $repository_key_empty->withResourceIdSerialized($resource_identification); - $repository_key_with_object_id = $repository_key_empty->withObjectId($object_id_mock); - $repository_key_complete = $repository_key_empty->withResourceIdSerialized($resource_identification)->withObjectId($object_id_mock); - self::assertFalse($repository_key_empty->isObjectIdKey()); - self::assertFalse($repository_key_empty->isResourceIdKey()); - self::assertFalse($repository_key_empty->isCompleteKey()); - self::assertEquals(-1, $repository_key_empty->getObjectId()->toInt()); - self::assertEquals("", $repository_key_empty->getResourceIdSerialized()); - self::assertFalse($repository_key_with_resource_id->isObjectIdKey()); - self::assertTrue($repository_key_with_resource_id->isResourceIdKey()); - self::assertFalse($repository_key_with_resource_id->isCompleteKey()); - self::assertEquals(-1, $repository_key_with_resource_id->getObjectId()->toInt()); - self::assertEquals($resource_identification, $repository_key_with_resource_id->getResourceIdSerialized()); - self::assertTrue($repository_key_with_object_id->isObjectIdKey()); - self::assertFalse($repository_key_with_object_id->isResourceIdKey()); - self::assertFalse($repository_key_with_object_id->isCompleteKey()); - self::assertEquals($object_id_mock->toInt(), $repository_key_with_object_id->getObjectId()->toInt()); - self::assertEquals("", $repository_key_with_object_id->getResourceIdSerialized()); - self::assertFalse($repository_key_complete->isObjectIdKey()); - self::assertFalse($repository_key_complete->isResourceIdKey()); - self::assertTrue($repository_key_complete->isCompleteKey()); - self::assertEquals($object_id_mock->toInt(), $repository_key_complete->getObjectId()->toInt()); - self::assertEquals($resource_identification, $repository_key_complete->getResourceIdSerialized()); - self::assertTrue($repository_key_empty->equals($repository_key_empty)); - self::assertTrue($repository_key_with_resource_id->equals($repository_key_with_resource_id)); - self::assertTrue($repository_key_with_object_id->equals($repository_key_with_object_id)); - self::assertTrue($repository_key_complete->equals($repository_key_complete)); - self::assertFalse($repository_key_empty->equals($repository_key_with_resource_id)); - self::assertFalse($repository_key_empty->equals($repository_key_with_object_id)); - self::assertFalse($repository_key_empty->equals($repository_key_complete)); - self::assertFalse($repository_key_with_object_id->equals($repository_key_with_resource_id)); - self::assertFalse($repository_key_with_object_id->equals($repository_key_complete)); - self::assertFalse($repository_key_with_resource_id->equals($repository_key_complete)); + $object_id_invalid_mock = $this->createMock(ObjectId::class); + $object_id_invalid_mock->method('toInt')->willReturn(ilExportHandlerRepositoryKeyInterface::EMPTY_OBJECT_ID); + $object_id_invalid_mock->method("toReferenceIds")->willThrowException(new Exception("toReferenceIds should not be called")); + $df_factory_wrapper_mock = $this->createMock(ilExportHandlerDataFactoryWrapperInterface::class); + $df_factory_wrapper_mock->method('objId')->willReturn($object_id_invalid_mock); + try { + $repository_key_empty = new ilExportHandlerRepositoryKey( + $df_factory_wrapper_mock + ); + $repository_key_with_resource_id = $repository_key_empty->withResourceIdSerialized($resource_identification); + $repository_key_with_object_id = $repository_key_empty->withObjectId($object_id_mock); + $repository_key_complete = $repository_key_empty->withResourceIdSerialized($resource_identification)->withObjectId($object_id_mock); + self::assertFalse($repository_key_empty->isObjectIdKey()); + self::assertFalse($repository_key_empty->isResourceIdKey()); + self::assertFalse($repository_key_empty->isCompleteKey()); + self::assertEquals(-1, $repository_key_empty->getObjectId()->toInt()); + self::assertEquals("", $repository_key_empty->getResourceIdSerialized()); + self::assertFalse($repository_key_with_resource_id->isObjectIdKey()); + self::assertTrue($repository_key_with_resource_id->isResourceIdKey()); + self::assertFalse($repository_key_with_resource_id->isCompleteKey()); + self::assertEquals(-1, $repository_key_with_resource_id->getObjectId()->toInt()); + self::assertEquals($resource_identification, $repository_key_with_resource_id->getResourceIdSerialized()); + self::assertTrue($repository_key_with_object_id->isObjectIdKey()); + self::assertFalse($repository_key_with_object_id->isResourceIdKey()); + self::assertFalse($repository_key_with_object_id->isCompleteKey()); + self::assertEquals($object_id_mock->toInt(), $repository_key_with_object_id->getObjectId()->toInt()); + self::assertEquals("", $repository_key_with_object_id->getResourceIdSerialized()); + self::assertFalse($repository_key_complete->isObjectIdKey()); + self::assertFalse($repository_key_complete->isResourceIdKey()); + self::assertTrue($repository_key_complete->isCompleteKey()); + self::assertEquals($object_id_mock->toInt(), $repository_key_complete->getObjectId()->toInt()); + self::assertEquals($resource_identification, $repository_key_complete->getResourceIdSerialized()); + self::assertTrue($repository_key_empty->equals($repository_key_empty)); + self::assertTrue($repository_key_with_resource_id->equals($repository_key_with_resource_id)); + self::assertTrue($repository_key_with_object_id->equals($repository_key_with_object_id)); + self::assertTrue($repository_key_complete->equals($repository_key_complete)); + self::assertFalse($repository_key_empty->equals($repository_key_with_resource_id)); + self::assertFalse($repository_key_empty->equals($repository_key_with_object_id)); + self::assertFalse($repository_key_empty->equals($repository_key_complete)); + self::assertFalse($repository_key_with_object_id->equals($repository_key_with_resource_id)); + self::assertFalse($repository_key_with_object_id->equals($repository_key_complete)); + self::assertFalse($repository_key_with_resource_id->equals($repository_key_complete)); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Stakeholder/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Stakeholder/HandlerTest.php index 91951174a906..f17c5406a465 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Stakeholder/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Stakeholder/HandlerTest.php @@ -20,22 +20,24 @@ namespace ILIAS\Export\Test\ExportHandler\Repository\Stakeholder; -use DateTimeImmutable; use Exception; -use ILIAS\Data\ObjectId; -use PHPUnit\Framework\TestCase; -use ILIAS\Export\ExportHandler\Repository\Stakeholder\Handler as ilExportHandlerRepositoryStakeholder; use ILIAS\Export\ExportHandler\I\Repository\Stakeholder\HandlerInterface as ilExportHandlerRepositoryStakeholderInterface; +use ILIAS\Export\ExportHandler\Repository\Stakeholder\Handler as ilExportHandlerRepositoryStakeholder; +use PHPUnit\Framework\TestCase; class HandlerTest extends TestCase { public function testExportHandlerRepositoryStakeholder(): void { - $stakeholder01 = new ilExportHandlerRepositoryStakeholder(10); - $stakeholder02 = $stakeholder01->withOwnerId(6); - $stakeholder03 = new ilExportHandlerRepositoryStakeholder(); - self::assertEquals(10, $stakeholder01->getOwnerId()); - self::assertEquals(6, $stakeholder02->getOwnerId()); - self::assertEquals(ilExportHandlerRepositoryStakeholderInterface::DEFAULT_OWNER_ID, $stakeholder03->getOwnerId()); + try { + $stakeholder01 = new ilExportHandlerRepositoryStakeholder(10); + $stakeholder02 = $stakeholder01->withOwnerId(6); + $stakeholder03 = new ilExportHandlerRepositoryStakeholder(); + self::assertEquals(10, $stakeholder01->getOwnerId()); + self::assertEquals(6, $stakeholder02->getOwnerId()); + self::assertEquals(ilExportHandlerRepositoryStakeholderInterface::DEFAULT_OWNER_ID, $stakeholder03->getOwnerId()); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Repository/Values/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Repository/Values/HandlerTest.php index 73dbca5f59b6..0ec9f84b081a 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Repository/Values/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Repository/Values/HandlerTest.php @@ -22,38 +22,41 @@ use DateTimeImmutable; use Exception; -use ILIAS\Data\ObjectId; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ExportHandler\Repository\Values\Handler as ilExportHandlerRepositoryValues; +use PHPUnit\Framework\TestCase; class HandlerTest extends TestCase { public function testExportHandlerRepositoryValues() { $owner_id = 10; - $datetime = new DateTimeImmutable(); - $values = new ilExportHandlerRepositoryValues(); - $values_with_owner_id = $values - ->withOwnerId($owner_id); - $values_with_datetime = $values - ->withCreationDate($datetime); - $values_complete = $values - ->withOwnerId($owner_id) - ->withCreationDate($datetime); - self::assertFalse($values->isValid()); - self::assertFalse($values_with_owner_id->isValid()); - self::assertFalse($values_with_datetime->isValid()); - self::assertTrue($values_complete->isValid()); - self::assertEquals($owner_id, $values_with_owner_id->getOwnerId()); - self::assertEquals($owner_id, $values_complete->getOwnerId()); - self::assertEquals($datetime, $values_with_datetime->getCreationDate()); - self::assertEquals($datetime, $values_complete->getCreationDate()); - self::assertTrue($values->equals($values)); - self::assertTrue($values_with_owner_id->equals($values_with_owner_id)); - self::assertTrue($values_with_datetime->equals($values_with_datetime)); - self::assertTrue($values_complete->equals($values_complete)); - self::assertFalse($values->equals($values_with_owner_id)); - self::assertFalse($values->equals($values_complete)); - self::assertFalse($values->equals($values_with_datetime)); + try { + $datetime = new DateTimeImmutable(); + $values = new ilExportHandlerRepositoryValues(); + $values_with_owner_id = $values + ->withOwnerId($owner_id); + $values_with_datetime = $values + ->withCreationDate($datetime); + $values_complete = $values + ->withOwnerId($owner_id) + ->withCreationDate($datetime); + self::assertFalse($values->isValid()); + self::assertFalse($values_with_owner_id->isValid()); + self::assertFalse($values_with_datetime->isValid()); + self::assertTrue($values_complete->isValid()); + self::assertEquals($owner_id, $values_with_owner_id->getOwnerId()); + self::assertEquals($owner_id, $values_complete->getOwnerId()); + self::assertEquals($datetime, $values_with_datetime->getCreationDate()); + self::assertEquals($datetime, $values_complete->getCreationDate()); + self::assertTrue($values->equals($values)); + self::assertTrue($values_with_owner_id->equals($values_with_owner_id)); + self::assertTrue($values_with_datetime->equals($values_with_datetime)); + self::assertTrue($values_complete->equals($values_complete)); + self::assertFalse($values->equals($values_with_owner_id)); + self::assertFalse($values->equals($values_complete)); + self::assertFalse($values->equals($values_with_datetime)); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Table/RowId/CollectionTest.php b/components/ILIAS/Export/tests/ExportHandler/Table/RowId/CollectionTest.php index 835749ada439..76fc2d8c8f3a 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Table/RowId/CollectionTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Table/RowId/CollectionTest.php @@ -20,41 +20,46 @@ namespace ILIAS\Export\Test\ExportHandler\Table\RowId; -use PHPUnit\Framework\TestCase; +use Exception; +use ILIAS\Export\ExportHandler\I\Table\RowId\HandlerInterface as ilExportHandlerTableRowIdInterface; use ILIAS\Export\ExportHandler\Table\RowId\Collection as ilExportHandlerTableRowIdCollection; -use ILIAS\Export\ExportHandler\Table\RowId\Handler as ilExportHandlerTableRowId; +use PHPUnit\Framework\TestCase; class CollectionTest extends TestCase { public function testExportHandlerTableRowIdCollection(): void { - $table_row_id_mock_1 = $this->createMock(ilExportHandlerTableRowId::class); + $table_row_id_mock_1 = $this->createMock(ilExportHandlerTableRowIdInterface::class); $table_row_id_mock_1->method('getFileIdentifier')->willReturn("1"); $table_row_id_mock_1->method('getExportOptionId')->willReturn("e"); $table_row_id_mock_1->method('getCompositId')->willReturn("e:1"); - $table_row_id_mock_2 = $this->createMock(ilExportHandlerTableRowId::class); + $table_row_id_mock_2 = $this->createMock(ilExportHandlerTableRowIdInterface::class); $table_row_id_mock_2->method('getFileIdentifier')->willReturn("2"); $table_row_id_mock_2->method('getExportOptionId')->willReturn("e"); $table_row_id_mock_2->method('getCompositId')->willReturn("e:2"); - $table_row_id_mock_3 = $this->createMock(ilExportHandlerTableRowId::class); + $table_row_id_mock_3 = $this->createMock(ilExportHandlerTableRowIdInterface::class); $table_row_id_mock_3->method('getFileIdentifier')->willReturn("3"); $table_row_id_mock_3->method('getExportOptionId')->willReturn("e"); $table_row_id_mock_3->method('getCompositId')->willReturn("e:3"); - $empty_collection = new ilExportHandlerTableRowIdCollection(); - $collection_with_elements = $empty_collection - ->withElement($table_row_id_mock_1) - ->withElement($table_row_id_mock_2) - ->withElement($table_row_id_mock_3); - self::assertEquals(0, $empty_collection->count()); - self::assertFalse($empty_collection->valid()); - self::assertEquals(3, $collection_with_elements->count()); - self::assertTrue($collection_with_elements->valid()); - $index = 1; - foreach ($collection_with_elements as $element) { - self::assertEquals("" . $index, $element->getFileIdentifier()); - self::assertEquals("e", $element->getExportOptionId()); - self::assertEquals("e:" . $index, $element->getCompositId()); - $index++; + try { + $empty_collection = new ilExportHandlerTableRowIdCollection(); + $collection_with_elements = $empty_collection + ->withElement($table_row_id_mock_1) + ->withElement($table_row_id_mock_2) + ->withElement($table_row_id_mock_3); + self::assertEquals(0, $empty_collection->count()); + self::assertFalse($empty_collection->valid()); + self::assertEquals(3, $collection_with_elements->count()); + self::assertTrue($collection_with_elements->valid()); + $index = 1; + foreach ($collection_with_elements as $element) { + self::assertEquals("" . $index, $element->getFileIdentifier()); + self::assertEquals("e", $element->getExportOptionId()); + self::assertEquals("e:" . $index, $element->getCompositId()); + $index++; + } + } catch (Exception $exception) { + self::fail($exception->getMessage()); } } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Table/RowId/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Table/RowId/HandlerTest.php index 0428773ad823..89f723b390c9 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Table/RowId/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Table/RowId/HandlerTest.php @@ -20,8 +20,9 @@ namespace ILIAS\Export\Test\ExportHandler\Table\RowId; -use PHPUnit\Framework\TestCase; +use Exception; use ILIAS\Export\ExportHandler\Table\RowId\Handler as ilExportHandlerTableRowId; +use PHPUnit\Framework\TestCase; class HandlerTest extends TestCase { @@ -30,16 +31,20 @@ public function testExportHandlerTableRowId(): void $file_identifier = "super_xml:something"; $export_option_id = "super_export_option"; $composit_id = $export_option_id . ':' . $file_identifier; - $table_row_id = new ilExportHandlerTableRowId(); - $table_row_id_1 = $table_row_id - ->withFileIdentifier($file_identifier) - ->withExportOptionId($export_option_id); - $table_row_id_2 = $table_row_id->withCompositId($composit_id); - self::assertEquals($file_identifier, $table_row_id_1->getFileIdentifier()); - self::assertEquals($export_option_id, $table_row_id_1->getExportOptionId()); - self::assertEquals($composit_id, $table_row_id_1->getCompositId()); - self::assertEquals($file_identifier, $table_row_id_2->getFileIdentifier()); - self::assertEquals($export_option_id, $table_row_id_2->getExportOptionId()); - self::assertEquals($composit_id, $table_row_id_2->getCompositId()); + try { + $table_row_id = new ilExportHandlerTableRowId(); + $table_row_id_1 = $table_row_id + ->withFileIdentifier($file_identifier) + ->withExportOptionId($export_option_id); + $table_row_id_2 = $table_row_id->withCompositId($composit_id); + self::assertEquals($file_identifier, $table_row_id_1->getFileIdentifier()); + self::assertEquals($export_option_id, $table_row_id_1->getExportOptionId()); + self::assertEquals($composit_id, $table_row_id_1->getCompositId()); + self::assertEquals($file_identifier, $table_row_id_2->getFileIdentifier()); + self::assertEquals($export_option_id, $table_row_id_2->getExportOptionId()); + self::assertEquals($composit_id, $table_row_id_2->getCompositId()); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } } } diff --git a/components/ILIAS/Export/tests/ExportHandler/Target/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/Target/HandlerTest.php index 3ccb2b41cd50..7239fca0bc0b 100644 --- a/components/ILIAS/Export/tests/ExportHandler/Target/HandlerTest.php +++ b/components/ILIAS/Export/tests/ExportHandler/Target/HandlerTest.php @@ -20,8 +20,9 @@ namespace ILIAS\Export\Test\ExportHandler\Target; -use PHPUnit\Framework\TestCase; +use Exception; use ILIAS\Export\ExportHandler\Target\Handler as ilExportHandlerTarget; +use PHPUnit\Framework\TestCase; class HandlerTest extends TestCase { @@ -33,16 +34,20 @@ public function testExportHandlerTarget(): void $class_name = "classclass"; $v = ['10', '0']; $target_release = "2000.20"; - $target_1 = (new ilExportHandlerTarget()) - ->withType($type) - ->withComponent($component) - ->withClassname($class_name) - ->withTargetRelease($target_release) - ->withObjectIds($object_ids); - self::assertEquals($type, $target_1->getType()); - self::assertEquals($component, $target_1->getComponent()); - self::assertEquals($class_name, $target_1->getClassname()); - self::assertEquals($target_release, $target_1->getTargetRelease()); - self::assertEmpty(array_diff($object_ids, $target_1->getObjectIds())); + try { + $target_1 = (new ilExportHandlerTarget()) + ->withType($type) + ->withComponent($component) + ->withClassname($class_name) + ->withTargetRelease($target_release) + ->withObjectIds($object_ids); + self::assertEquals($type, $target_1->getType()); + self::assertEquals($component, $target_1->getComponent()); + self::assertEquals($class_name, $target_1->getClassname()); + self::assertEquals($target_release, $target_1->getTargetRelease()); + self::assertEmpty(array_diff($object_ids, $target_1->getObjectIds())); + } catch (Exception $exception) { + self::fail($exception->getMessage()); + } } } diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Namespace/ilCollectionTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Namespace/ilCollectionTest.php index 5568c987ba79..b654ff097aff 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Namespace/ilCollectionTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Namespace/ilCollectionTest.php @@ -20,10 +20,10 @@ namespace Test\ImportHandler\File\Namespace; -use PHPUnit\Framework\TestCase; -use ILIAS\Export\ImportHandler\I\File\Namespace\ilCollectionInterface as ilFileNamespaceCollectionInterface; -use ILIAS\Export\ImportHandler\File\Namespace\ilHandler as ilFileNamespaceHandler; use ILIAS\Export\ImportHandler\File\Namespace\ilCollection as ilFileNamespaceCollection; +use ILIAS\Export\ImportHandler\File\Namespace\ilHandler as ilFileNamespaceHandler; +use ILIAS\Export\ImportHandler\I\File\Namespace\ilCollectionInterface as ilFileNamespaceCollectionInterface; +use PHPUnit\Framework\TestCase; class ilCollectionTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Namespace/ilHandlerTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Namespace/ilHandlerTest.php index d980c3cb072a..ea417671b053 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Namespace/ilHandlerTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Namespace/ilHandlerTest.php @@ -20,8 +20,8 @@ namespace Test\ImportHandler\File\Namespace; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\Namespace\ilHandler as ilFileNamespaceHandler; +use PHPUnit\Framework\TestCase; class ilHandlerTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Path/Comparison/ilHandlerTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Path/Comparison/ilHandlerTest.php index 0eae9b618bcb..273d2fb61056 100644 --- a/components/ILIAS/Export/tests/ImportHandler/File/Path/Comparison/ilHandlerTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Path/Comparison/ilHandlerTest.php @@ -21,7 +21,6 @@ namespace Test\ImportHandler\File\Path\Comparison; use ILIAS\Export\ImportHandler\File\Path\Comparison\ilHandler as ilFilePathComparison; -use ILIAS\Export\ImportHandler\File\Path\Comparison\Operator; use ILIAS\Export\ImportHandler\File\Path\Comparison\Operator as ilFilePathComparisonOperator; use PHPUnit\Framework\TestCase; diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilAnyNodeTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilAnyNodeTest.php index f71a23f92157..5b293d51af5e 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilAnyNodeTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilAnyNodeTest.php @@ -20,8 +20,8 @@ namespace Test\ImportHandler\File\Path\Node; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\Path\Node\ilAnyNode as ilAnyNodeFilePathNode; +use PHPUnit\Framework\TestCase; class ilAnyNodeTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilAttributeTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilAttributeTest.php index 390f046b7cb2..e6f422052b76 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilAttributeTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilAttributeTest.php @@ -20,9 +20,9 @@ namespace Test\ImportHandler\File\Path\Node; -use PHPUnit\Framework\TestCase; -use ILIAS\Export\ImportHandler\File\Path\Node\ilAttribute as ilAttributeFilePathNode; use ILIAS\Export\ImportHandler\File\Path\Comparison\ilHandler as ilFilePathComparisonHandler; +use ILIAS\Export\ImportHandler\File\Path\Node\ilAttribute as ilAttributeFilePathNode; +use PHPUnit\Framework\TestCase; class ilAttributeTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilCloseRoundBrackedTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilCloseRoundBrackedTest.php index 1f7490ddcb14..1880cdf409c1 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilCloseRoundBrackedTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilCloseRoundBrackedTest.php @@ -20,8 +20,8 @@ namespace Test\ImportHandler\File\Path\Node; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\Path\Node\ilCloseRoundBracked as ilCloseRoundBrackedFilePathNode; +use PHPUnit\Framework\TestCase; class ilCloseRoundBrackedTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilIndexTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilIndexTest.php index 3ab3c6dd99ba..8b2b620f8eb0 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilIndexTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilIndexTest.php @@ -21,8 +21,8 @@ namespace Test\ImportHandler\File\Path\Node; use ILIAS\Export\ImportHandler\File\Path\Comparison\ilHandler as ilFilePathComparisonHandler; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\Path\Node\ilIndex as ilIndexFilePathNode; +use PHPUnit\Framework\TestCase; class ilIndexTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilOpenRoundBrackedTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilOpenRoundBrackedTest.php index 10ebca94089a..f0fffaf84f7a 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilOpenRoundBrackedTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilOpenRoundBrackedTest.php @@ -20,8 +20,8 @@ namespace Test\ImportHandler\File\Path\Node; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\Path\Node\ilOpenRoundBracked as ilOpenRoundBrackedFilePathNode; +use PHPUnit\Framework\TestCase; class ilOpenRoundBrackedTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilSimpleTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilSimpleTest.php index 6c0691102867..51841b9b7461 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilSimpleTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Path/Node/ilSimpleTest.php @@ -20,8 +20,8 @@ namespace Test\ImportHandler\File\Path\Node; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\Path\Node\ilSimple as ilSimpleFilePathNode; +use PHPUnit\Framework\TestCase; class ilSimpleTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Path/ilHandlerTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Path/ilHandlerTest.php index 8eb3bedbc9ca..fd6c6295b02b 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Path/ilHandlerTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Path/ilHandlerTest.php @@ -20,9 +20,9 @@ namespace Test\ImportHandler\File\Path; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\Path\ilHandler as ilFilePathHandler; use ILIAS\Export\ImportHandler\File\Path\Node\ilSimple as ilSimpleFilePathNode; +use PHPUnit\Framework\TestCase; class ilHandlerTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilCollectionTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilCollectionTest.php index 05517ec1c7d4..d88a571bc1ed 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilCollectionTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilCollectionTest.php @@ -20,9 +20,9 @@ namespace Test\ImportHandler\File\Validation\Set; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\Validation\Set\ilCollection as ilFileValidationSetCollection; use ILIAS\Export\ImportHandler\File\Validation\Set\ilHandler as ilFileValidationSetHandler; +use PHPUnit\Framework\TestCase; class ilCollectionTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilHandlerTest.php b/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilHandlerTest.php index ee1c2020949e..17be76420a60 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilHandlerTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/Validation/Set/ilHandlerTest.php @@ -20,11 +20,11 @@ namespace Test\ImportHandler\File\Validation\Set; -use PHPUnit\Framework\TestCase; -use ILIAS\Export\ImportHandler\File\Validation\Set\ilHandler as ilFileValidationSetHandler; use ILIAS\Export\ImportHandler\File\Path\ilHandler as ilFilePathHandler; +use ILIAS\Export\ImportHandler\File\Validation\Set\ilHandler as ilFileValidationSetHandler; use ILIAS\Export\ImportHandler\File\XML\ilHandler as ilXMLFileHandler; use ILIAS\Export\ImportHandler\File\XSD\ilHandler as ilXSDFileHandler; +use PHPUnit\Framework\TestCase; class ilHandlerTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/XML/Node/Info/Attribute/ilCollectionTest.php b/components/ILIAS/Export/tests/ImportHandler/File/XML/Node/Info/Attribute/ilCollectionTest.php index f873fa9ad5d5..aff379819f7b 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/XML/Node/Info/Attribute/ilCollectionTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/XML/Node/Info/Attribute/ilCollectionTest.php @@ -20,10 +20,10 @@ namespace Test\ImportHandler\File\XML\Node\Info\Attribute; -use ilLogger; use ILIAS\Export\ImportHandler\File\XML\Node\Info\Attribute\ilCollection as ilXMLFileNodeInfoAttributeCollection; use ILIAS\Export\ImportHandler\File\XML\Node\Info\Attribute\ilPair as ilXMLFileNodeInfoAttributePair; use ILIAS\Export\ImportHandler\File\XML\Node\Info\DOM\ilHandler as ilXMLFileNodeInfoDOMNodeHandler; +use ilLogger; use PHPUnit\Framework\TestCase; class ilCollectionTest extends TestCase diff --git a/components/ILIAS/Export/tests/ImportHandler/File/XML/Node/Info/Attribute/ilPairTest.php b/components/ILIAS/Export/tests/ImportHandler/File/XML/Node/Info/Attribute/ilPairTest.php index 96a79dc58724..f5b136834a5b 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/XML/Node/Info/Attribute/ilPairTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/XML/Node/Info/Attribute/ilPairTest.php @@ -20,8 +20,8 @@ namespace Test\ImportHandler\File\XML\Node\Info\Attribute; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\XML\Node\Info\Attribute\ilPair as ilXMLFileNodeInfoAttributePair; +use PHPUnit\Framework\TestCase; class ilPairTest extends TestCase { diff --git a/components/ILIAS/Export/tests/ImportHandler/File/ilHandlerTest.php b/components/ILIAS/Export/tests/ImportHandler/File/ilHandlerTest.php index 091475f01191..83d51283933d 100755 --- a/components/ILIAS/Export/tests/ImportHandler/File/ilHandlerTest.php +++ b/components/ILIAS/Export/tests/ImportHandler/File/ilHandlerTest.php @@ -20,10 +20,10 @@ namespace Test\ImportHandler\File; -use PHPUnit\Framework\TestCase; use ILIAS\Export\ImportHandler\File\ilHandler as ilFileHandler; -use ILIAS\Export\ImportHandler\File\Namespace\ilFactory as ilFileNamespaceFactory; use ILIAS\Export\ImportHandler\File\Namespace\ilCollection as ilFileNamespaceCollection; +use ILIAS\Export\ImportHandler\File\Namespace\ilFactory as ilFileNamespaceFactory; +use PHPUnit\Framework\TestCase; use SplFileInfo; class ilHandlerTest extends TestCase diff --git a/components/ILIAS/Export/tests/ilExportOptionsTest.php b/components/ILIAS/Export/tests/ilExportOptionsTest.php index be000aba4b81..cc21d9adb0b2 100755 --- a/components/ILIAS/Export/tests/ilExportOptionsTest.php +++ b/components/ILIAS/Export/tests/ilExportOptionsTest.php @@ -2,8 +2,8 @@ declare(strict_types=1); -use PHPUnit\Framework\TestCase; use ILIAS\DI\Container; +use PHPUnit\Framework\TestCase; /** * Class ilExportOptionsTest From 3c7e58fc8973a27d66d39d0a3fab1e7572d7a525 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Tue, 22 Oct 2024 15:29:05 +0200 Subject: [PATCH 10/75] Export: adds test --- .../PublicAccess/Repository/HandlerTest.php | 274 ++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/HandlerTest.php diff --git a/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/HandlerTest.php b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/HandlerTest.php new file mode 100644 index 000000000000..e2eb7dde7db6 --- /dev/null +++ b/components/ILIAS/Export/tests/ExportHandler/PublicAccess/Repository/HandlerTest.php @@ -0,0 +1,274 @@ +repository_elements = []; + + $object_id_mock_01 = $this->createMock(ObjectId::class); + $object_id_mock_01->method("toInt")->willReturn(1); + $object_id_mock_01->method("toReferenceIds")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $object_id_mock_02 = $this->createMock(ObjectId::class); + $object_id_mock_02->method("toInt")->willReturn(2); + $object_id_mock_02->method("toReferenceIds")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $object_id_mock_03 = $this->createMock(ObjectId::class); + $object_id_mock_03->method("toInt")->willReturn(3); + $object_id_mock_03->method("toReferenceIds")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $key_mock_01 = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyInterface::class); + $key_mock_01->method("getObjectId")->willReturn($object_id_mock_01); + $key_mock_01->method("withObjectId")->willThrowException(new UnexpectedValueException("unexpected method call")); + $key_mock_01->method("equals")->willThrowException(new UnexpectedValueException("unexpected method call")); + $key_mock_01->method("isValid")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $key_mock_02 = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyInterface::class); + $key_mock_02->method("getObjectId")->willReturn($object_id_mock_02); + $key_mock_02->method("withObjectId")->willThrowException(new UnexpectedValueException("unexpected method call")); + $key_mock_02->method("equals")->willThrowException(new UnexpectedValueException("unexpected method call")); + $key_mock_02->method("isValid")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $key_mock_03 = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyInterface::class); + $key_mock_03->method("getObjectId")->willReturn($object_id_mock_03); + $key_mock_03->method("withObjectId")->willThrowException(new UnexpectedValueException("unexpected method call")); + $key_mock_03->method("equals")->willThrowException(new UnexpectedValueException("unexpected method call")); + $key_mock_03->method("isValid")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $element_mock_01 = $this->createMock(ilExportHandlerPublicAccessRepositoryElementInterface::class); + $element_mock_01->method("getValues")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_mock_01->method("getKey")->willReturn($key_mock_01); + $element_mock_01->method("withValues")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_mock_01->method("withKey")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_mock_01->method("isStorable")->willReturn(true); + $element_mock_01->method("equals")->with($element_mock_01)->willReturn(true); + + $element_mock_02 = $this->createMock(ilExportHandlerPublicAccessRepositoryElementInterface::class); + $element_mock_02->method("getValues")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_mock_02->method("getKey")->willReturn($key_mock_02); + $element_mock_02->method("withValues")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_mock_02->method("withKey")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_mock_02->method("isStorable")->willReturn(true); + $element_mock_02->method("equals")->with($element_mock_02)->willReturn(true); + + $element_not_storable_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryElementInterface::class); + $element_not_storable_mock->method("getValues")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_not_storable_mock->method("getKey")->willReturn($key_mock_03); + $element_not_storable_mock->method("withValues")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_not_storable_mock->method("withKey")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_not_storable_mock->method("isStorable")->willReturn(false); + $element_not_storable_mock->method("equals")->with($element_not_storable_mock)->willReturn(true); + + $key_collection_01_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyCollectionInterface::class); + # next, rewind are void + $key_collection_01_mock->method("key")->willReturn(0, 1); + $key_collection_01_mock->method("valid")->willReturn(true, false); + $key_collection_01_mock->method("count")->willReturn(1); + $key_collection_01_mock->method("current")->willReturn($key_mock_01); + $key_collection_01_mock->method("withElement")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $key_collection_02_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyCollectionInterface::class); + # next, rewind are void + $key_collection_02_mock->method("key")->willReturn(0, 1); + $key_collection_02_mock->method("valid")->willReturn(true, false); + $key_collection_02_mock->method("count")->willReturn(1); + $key_collection_02_mock->method("current")->willReturn($key_mock_02); + $key_collection_02_mock->method("withElement")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $key_collection_03_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyCollectionInterface::class); + # next, rewind are void + $key_collection_03_mock->method("key")->willReturn(0, 1); + $key_collection_03_mock->method("valid")->willReturn(true, false); + $key_collection_03_mock->method("count")->willReturn(1); + $key_collection_03_mock->method("current")->willReturn($key_mock_03); + $key_collection_03_mock->method("withElement")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $key_collection_all_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyCollectionInterface::class); + # next, rewind are void + $key_collection_all_mock->method("key")->willReturn(0, 1, 2); + $key_collection_all_mock->method("valid")->willReturn(true, true, false); + $key_collection_all_mock->method("count")->willReturn(2); + $key_collection_all_mock->method("current")->willReturn($key_mock_01, $key_mock_02); + $key_collection_all_mock->method("withElement")->willThrowException(new UnexpectedValueException("unexpected method call")); + + $key_collection_empty_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyCollectionInterface::class); + # next, rewind are void + $key_collection_empty_mock->method("key")->willReturn(0); + $key_collection_empty_mock->method("valid")->willReturn(false); + $key_collection_empty_mock->method("count")->willReturn(0); + $key_collection_empty_mock->method("current")->willThrowException(new UnexpectedValueException("tried to access element on empty collection")); + $key_collection_empty_mock->method("withElement")->willReturnMap([ + [$key_mock_01, $key_collection_01_mock], + [$key_mock_02, $key_collection_02_mock], + [$key_mock_03, $key_collection_03_mock], + ]); + + $key_factory_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryKeyFactoryInterface::class); + $key_factory_mock->method("handler")->willThrowException(new UnexpectedValueException("unexpected method call")); + $key_factory_mock->method("collection")->willReturn($key_collection_empty_mock); + + $db_wrapper_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryDBWrapperInterface::class); + $db_wrapper_mock->method("storeElement")->willReturnCallback(function ($x) { + $this->mockDBWrapperStore($x); + }); + ; + $db_wrapper_mock->method("getElements")->willReturnCallback(function ($x) { + return $this->mockDBWrapperGetElementsByKeyCollection($x); + }); + ; + $db_wrapper_mock->method("deleteElements")->willReturnCallback(function ($x) { + $this->mockDBWrapperRemoveByKeyCollection($x); + }); + ; + $db_wrapper_mock->method("buildDeleteQuery")->willThrowException(new UnexpectedValueException("unexpected method call")); + $db_wrapper_mock->method("buildSelectQuery")->willThrowException(new UnexpectedValueException("unexpected method call")); + $db_wrapper_mock->method("buildSelectAllQuery")->willThrowException(new UnexpectedValueException("unexpected method call")); + + try { + $repository = new ilExportHandlerPublicAccessRepository( + $db_wrapper_mock, + $key_factory_mock + ); + + self::assertFalse($repository->hasElement($key_mock_01)); + self::assertFalse($repository->hasElement($key_mock_02)); + self::assertFalse($repository->hasElement($key_mock_03)); + + $repository->storeElement($element_mock_01); + $repository->storeElement($element_mock_02); + $element_in_repository_01 = $repository->getElement($key_mock_01); + $element_in_repository_02 = $repository->getElement($key_mock_02); + + self::assertObjectEquals($element_in_repository_01, $element_mock_01); + self::assertObjectEquals($element_in_repository_02, $element_mock_02); + self::assertTrue($repository->hasElement($key_mock_01)); + self::assertTrue($repository->hasElement($key_mock_02)); + self::assertFalse($repository->hasElement($key_mock_03)); + + $repository->deleteElement($key_mock_01); + $element_in_repository_01 = $repository->getElement($key_mock_01); + $element_in_repository_02 = $repository->getElement($key_mock_02); + + self::assertNull($element_in_repository_01); + self::assertObjectEquals($element_in_repository_02, $element_mock_02); + self::assertFalse($repository->hasElement($key_mock_01)); + self::assertTrue($repository->hasElement($key_mock_02)); + self::assertFalse($repository->hasElement($key_mock_03)); + + $repository->storeElement($element_mock_01); + $element_in_repository_01 = $repository->getElement($key_mock_01); + $element_in_repository_02 = $repository->getElement($key_mock_02); + + self::assertObjectEquals($element_in_repository_01, $element_mock_01); + self::assertObjectEquals($element_in_repository_02, $element_mock_02); + self::assertTrue($repository->hasElement($key_mock_01)); + self::assertTrue($repository->hasElement($key_mock_02)); + self::assertFalse($repository->hasElement($key_mock_03)); + + $repository->deleteElements($key_collection_all_mock); + $element_in_repository_01 = $repository->getElement($key_mock_01); + $element_in_repository_02 = $repository->getElement($key_mock_02); + + self::assertNull($element_in_repository_01); + self::assertNull($element_in_repository_02); + self::assertFalse($repository->hasElement($key_mock_01)); + self::assertFalse($repository->hasElement($key_mock_02)); + self::assertFalse($repository->hasElement($key_mock_03)); + } catch (UnexpectedValueException $exception) { + self::fail($exception->getMessage()); + } + } + + protected function mockDBWrapperStore( + ilExportHandlerPublicAccessRepositoryElementInterface&MockObject $element_mock + ): void { + $this->repository_elements[] = $element_mock; + } + + protected function mockDBWrapperRemoveByKeyCollection( + ilExportHandlerPublicAccessRepositoryKeyCollectionInterface&MockObject $key_collection_mock + ): void { + $ids = []; + for ($i = 0; $i < count($key_collection_mock); $i++) { + $ids[] = $key_collection_mock->current()->getObjectId()->toInt(); + } + $new_repository_elements = []; + foreach ($this->repository_elements as $element_mock) { + if (!in_array($element_mock->getKey()->getObjectId()->toInt(), $ids)) { + $new_repository_elements[] = $element_mock; + } + } + $this->repository_elements = $new_repository_elements; + } + + protected function mockDBWrapperGetElementsByKeyCollection( + ilExportHandlerPublicAccessRepositoryKeyCollectionInterface&MockObject $key_collection_mock + ): ilExportHandlerPublicAccessRepositoryElementCollectionInterface&MockObject { + $elements = []; + for ($i = 0; $i < $key_collection_mock->count(); $i++) { + $current = $key_collection_mock->current(); + foreach ($this->repository_elements as $element_mock) { + if ($current->getObjectId()->toInt() === $element_mock->getKey()->getObjectId()->toInt()) { + $elements[] = $element_mock; + } + } + } + $element_collection_mock = $this->createMock(ilExportHandlerPublicAccessRepositoryElementCollectionInterface::class); + $element_collection_mock->method("withElement")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_collection_mock->method("key")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_collection_mock->method("next")->willThrowException(new UnexpectedValueException("unexpected method call")); + if (count($elements) === 0) { + $element_collection_mock->method("count")->willReturn(0); + $element_collection_mock->method("current")->willThrowException(new UnexpectedValueException("unexpected method call")); + $element_collection_mock->method("valid")->willReturn(false); + } + if (count($elements) > 0) { + $valid_return_values = array_fill(0, count($elements), true); + $valid_return_values[] = false; + $element_collection_mock->method("count")->willReturn(count($elements)); + $element_collection_mock->method("current")->willReturn(...$elements); + $element_collection_mock->method("valid")->willReturn(...$valid_return_values); + } + return $element_collection_mock; + } +} From 75e7e4769277003b204aa697128f39fb89b62450 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Tue, 22 Oct 2024 15:41:02 +0200 Subject: [PATCH 11/75] Export: undo unwanted changes --- ...class.ilILIASObjectExporter.php => class.ilObjectExporter.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename components/ILIAS/ILIASObject/classes/{class.ilILIASObjectExporter.php => class.ilObjectExporter.php} (100%) diff --git a/components/ILIAS/ILIASObject/classes/class.ilILIASObjectExporter.php b/components/ILIAS/ILIASObject/classes/class.ilObjectExporter.php similarity index 100% rename from components/ILIAS/ILIASObject/classes/class.ilILIASObjectExporter.php rename to components/ILIAS/ILIASObject/classes/class.ilObjectExporter.php From 440ef50b7c2b0e7b2bea5c133dfdda780c417099 Mon Sep 17 00:00:00 2001 From: Alex Killing Date: Tue, 22 Oct 2024 15:53:26 +0200 Subject: [PATCH 12/75] booking manager, feature: Extend Booking Tool Permission --- .../BookingManager/Access/AccessManager.php | 171 ++++++++++++++++++ .../class.ilBookingProcessWithScheduleGUI.php | 19 +- ...ass.ilBookingProcessWithoutScheduleGUI.php | 24 ++- .../Objects/class.ilBookingObjectGUI.php | 19 +- .../class.ilBookingObjectsTableGUI.php | 10 +- .../class.ilBookingParticipantGUI.php | 10 +- .../class.ilBookingPreferencesGUI.php | 6 +- .../class.ilBookingReservationsGUI.php | 31 ++-- .../class.ilBookingReservationsTableGUI.php | 112 ++++++------ .../Schedule/class.ilBookingScheduleGUI.php | 8 +- .../class.ilBookingSchedulesTableGUI.php | 7 +- .../Service/class.InternalDomainService.php | 9 + .../AccessRBACOperationClonedObjective.php | 87 +++++++++ .../classes/Setup/class.Agent.php | 45 ++++- .../classes/class.ilBookCronNotification.php | 32 ++-- lang/ilias_de.lang | 4 + lang/ilias_en.lang | 4 + 17 files changed, 460 insertions(+), 138 deletions(-) create mode 100644 components/ILIAS/BookingManager/Access/AccessManager.php create mode 100644 components/ILIAS/BookingManager/classes/Setup/AccessRBACOperationClonedObjective.php diff --git a/components/ILIAS/BookingManager/Access/AccessManager.php b/components/ILIAS/BookingManager/Access/AccessManager.php new file mode 100644 index 000000000000..f0918dce33f3 --- /dev/null +++ b/components/ILIAS/BookingManager/Access/AccessManager.php @@ -0,0 +1,171 @@ +domain = $domain; + $this->access = $access; + $this->tree = $this->domain->repositoryTree(); + } + + protected function getCurrentUserId(int $user_id): int + { + if ($user_id > 0) { + return $user_id; + } + return $this->domain->user()->getId(); + } + + public function canManageObjects( + int $ref_id, + int $current_user = 0 + ): bool { + $current_user = $this->getCurrentUserId($current_user); + return $this->access->checkAccessOfUser($current_user, "write", "", $ref_id); + } + + public function canManageSettings( + int $ref_id, + int $current_user = 0 + ): bool { + $current_user = $this->getCurrentUserId($current_user); + return $this->access->checkAccessOfUser($current_user, "write", "", $ref_id); + } + + public function canManageParticipants( + int $ref_id, + int $current_user = 0 + ): bool { + $current_user = $this->getCurrentUserId($current_user); + return $this->access->checkAccessOfUser($current_user, "write", "", $ref_id); + } + + public function filterManageableParticipants( + int $ref_id, + array $participant_ids + ): array { + return $this->access->filterUserIdsByRbacOrPositionOfCurrentUser( + 'render', + 'render', + $ref_id, + $participant_ids + ); + } + + public function canManageAllReservations( + int $ref_id, + int $current_user = 0 + ): bool { + $current_user = $this->getCurrentUserId($current_user); + return $this->access->checkAccessOfUser($current_user, "manage_all_reservations", "", $ref_id); + } + + public function canManageOwnReservations( + int $ref_id, + int $current_user = 0 + ): bool { + $current_user = $this->getCurrentUserId($current_user); + return $this->access->checkAccessOfUser($current_user, "manage_own_reservations", "", $ref_id) || + $this->access->checkAccessOfUser($current_user, "manage_all_reservations", "", $ref_id); + } + + public function canManageReservationForUser( + int $ref_id, + int $target_user, + int $current_user = 0 + ): bool { + $current_user = $this->getCurrentUserId($current_user); + if ($target_user === $current_user) { + return $this->access->checkAccessOfUser($current_user, "manage_own_reservations", "", $ref_id) || + $this->access->checkAccessOfUser($current_user, "manage_all_reservations", "", $ref_id); + } + return $this->access->checkAccessOfUser($current_user, "manage_all_reservations", "", $ref_id); + } + + public function canRetrieveNotificationsForOwnReservationsByObjId( + int $book_obj_id, + int $current_user = 0 + ): bool { + $current_user = $this->getCurrentUserId($current_user); + return $this->hasPermissionOnAnyReference("manage_own_reservations", $current_user, $book_obj_id); + } + + public function canRetrieveNotificationsForAllReservationsByObjId( + int $book_obj_id, + int $current_user = 0 + ): bool { + $current_user = $this->getCurrentUserId($current_user); + return $this->hasPermissionOnAnyReference("manage_all_reservations", $current_user, $book_obj_id); + } + + protected function hasPermissionOnAnyReference( + string $perm, + int $uid, + int $obj_id + ): bool { + $access = $this->access; + foreach (\ilObject::_getAllReferences($obj_id) as $ref_id) { + if ($access->checkAccessOfUser($uid, $perm, "", $ref_id)) { + return true; + } + } + return false; + } + + public function getParentGroupCourse(int $ref_id): ?array + { + $tree = $this->tree; + if (($par_ref_id = $tree->checkForParentType($ref_id, "grp")) > 0) { + return [ + "ref_id" => $par_ref_id, + "type" => "grp" + ]; + } + if (($par_ref_id = $tree->checkForParentType($ref_id, "crs")) > 0) { + return [ + "ref_id" => $par_ref_id, + "type" => "crs" + ]; + } + return null; + } + + public function canManageMembersOfParent(int $ref_id): bool + { + if (($parent = $this->getParentGroupCourse($ref_id)) !== null) { + return ($this->access->checkAccess("manage_members", "", (int) $parent["ref_id"])) ; + } + return false; + } +} diff --git a/components/ILIAS/BookingManager/BookingProcess/class.ilBookingProcessWithScheduleGUI.php b/components/ILIAS/BookingManager/BookingProcess/class.ilBookingProcessWithScheduleGUI.php index 5e8d1ccb440c..c31c4e294a8d 100755 --- a/components/ILIAS/BookingManager/BookingProcess/class.ilBookingProcessWithScheduleGUI.php +++ b/components/ILIAS/BookingManager/BookingProcess/class.ilBookingProcessWithScheduleGUI.php @@ -16,14 +16,13 @@ * *********************************************************************/ -use ILIAS\Filesystem\Stream\Streams; - /** * Booking process ui class * @author Alexander Killing */ class ilBookingProcessWithScheduleGUI implements \ILIAS\BookingManager\BookingProcess\BookingProcessGUI { + protected \ILIAS\BookingManager\Access\AccessManager $access; protected ilLogger $log; protected \ILIAS\BookingManager\BookingProcess\ObjectSelectionManager $object_selection; protected \ILIAS\BookingManager\Objects\ObjectsManager $object_manager; @@ -45,7 +44,6 @@ class ilBookingProcessWithScheduleGUI implements \ILIAS\BookingManager\BookingPr protected ilCtrl $ctrl; protected ilGlobalTemplateInterface $tpl; protected ilLanguage $lng; - protected ilAccessHandler $access; protected ilTabsGUI $tabs_gui; protected ilObjUser $user; protected int $book_obj_id; @@ -62,7 +60,6 @@ public function __construct( $this->ctrl = $DIC->ctrl(); $this->tpl = $DIC["tpl"]; $this->lng = $DIC->language(); - $this->access = $DIC->access(); $this->tabs_gui = $DIC->tabs(); $this->user = $DIC->user(); $this->http = $DIC->http(); @@ -105,6 +102,7 @@ public function __construct( $this->pool, $this ); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); } public function executeCommand(): void @@ -133,6 +131,11 @@ public function executeCommand(): void } } + protected function showNoPermission(): void + { + $this->tpl->setOnScreenMessage('failure', $this->lng->txt("no_permission"), true); + $this->back(); + } // // Step 0 / week view @@ -222,6 +225,10 @@ public function book(): void // ok $this->ctrl->setParameter($this, 'bkusr', $this->user_id_to_book); } + if (!$this->access->canManageReservationForUser($this->book_request->getRefId(), $this->user_id_to_book)) { + return; + } + $user_settings = ilCalendarUserSettings::_getInstanceByUserId($this->user->getId()); $week_gui = new \ILIAS\BookingManager\BookingProcess\WeekGUI( @@ -466,6 +473,10 @@ protected function getMissingAvailabilityMessage(array $missing): string protected function bookAvailableItems(?int $recurrence = null, ?ilDateTime $until = null): void { + if (!$this->access->canManageReservationForUser($this->pool->getRefId(), $this->user_id_to_book)) { + $this->showNoPermission(); + return; + } $this->log->debug("bookAvailableItems"); $obj_id = $this->book_request->getObjectId(); $from = $this->book_request->getSlotFrom(); diff --git a/components/ILIAS/BookingManager/BookingProcess/class.ilBookingProcessWithoutScheduleGUI.php b/components/ILIAS/BookingManager/BookingProcess/class.ilBookingProcessWithoutScheduleGUI.php index e617b6805dbf..86a063da75e4 100755 --- a/components/ILIAS/BookingManager/BookingProcess/class.ilBookingProcessWithoutScheduleGUI.php +++ b/components/ILIAS/BookingManager/BookingProcess/class.ilBookingProcessWithoutScheduleGUI.php @@ -16,14 +16,13 @@ * *********************************************************************/ -use ILIAS\Filesystem\Stream\Streams; - /** * Booking process ui class * @author Alexander Killing */ class ilBookingProcessWithoutScheduleGUI implements \ILIAS\BookingManager\BookingProcess\BookingProcessGUI { + protected \ILIAS\BookingManager\Access\AccessManager $access; protected \ILIAS\BookingManager\Reservations\ReservationManager $reservation; protected \ILIAS\BookingManager\BookingProcess\ProcessUtilGUI $util_gui; protected \ILIAS\BookingManager\InternalRepoService $repo; @@ -41,7 +40,6 @@ class ilBookingProcessWithoutScheduleGUI implements \ILIAS\BookingManager\Bookin protected ilCtrl $ctrl; protected ilGlobalTemplateInterface $tpl; protected ilLanguage $lng; - protected ilAccessHandler $access; protected ilTabsGUI $tabs_gui; protected ilObjUser $user; protected int $book_obj_id; @@ -57,7 +55,6 @@ public function __construct( $this->ctrl = $DIC->ctrl(); $this->tpl = $DIC["tpl"]; $this->lng = $DIC->language(); - $this->access = $DIC->access(); $this->tabs_gui = $DIC->tabs(); $this->user = $DIC->user(); $this->help = $DIC->bookingManager()->internal() @@ -101,6 +98,7 @@ public function __construct( $this->pool, $this ); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); } public function executeCommand(): void @@ -128,6 +126,12 @@ public function executeCommand(): void } } + protected function showNoPermission(): void + { + $this->tpl->setOnScreenMessage('failure', $this->lng->txt("no_permission"), true); + $this->back(); + } + // // Step 1 // @@ -156,6 +160,10 @@ public function book(): void // ok $this->ctrl->setParameter($this, 'bkusr', $this->user_id_to_book); } + if (!$this->access->canManageReservationForUser($this->book_request->getRefId(), $this->user_id_to_book)) { + return; + } + if ($this->pool->usesMessages()) { $this->showMessageForm(); } else { @@ -236,6 +244,10 @@ public function bookMultipleParticipants(): void //add user list as items. foreach ($participants as $id) { + if (!$this->access->canManageReservationForUser($this->pool->getRefId(), $id)) { + $this->showNoPermission(); + return; + } $name = ilObjUser::_lookupFullname($id); $conf->addItem("participants[]", $id, $name); } @@ -280,6 +292,10 @@ public function saveMultipleBookings(): void } $rsv_ids = array(); foreach ($participants as $id) { + if (!$this->access->canManageReservationForUser($this->pool->getRefId(), $id)) { + $this->showNoPermission(); + return; + } $this->user_id_to_book = $id; $rsv_ids[] = $this->process->bookSingle( $this->book_obj_id, diff --git a/components/ILIAS/BookingManager/Objects/class.ilBookingObjectGUI.php b/components/ILIAS/BookingManager/Objects/class.ilBookingObjectGUI.php index d18e64855b67..3883614819d6 100755 --- a/components/ILIAS/BookingManager/Objects/class.ilBookingObjectGUI.php +++ b/components/ILIAS/BookingManager/Objects/class.ilBookingObjectGUI.php @@ -27,11 +27,11 @@ class ilBookingObjectGUI protected ilBookBulkCreationGUI $bulk_creation_gui; protected ilObjBookingPool $pool; protected \ILIAS\BookingManager\InternalGUIService $gui; + protected \ILIAS\BookingManager\Access\AccessManager $access; protected \ILIAS\BookingManager\StandardGUIRequest $book_request; protected ilCtrl $ctrl; protected ilGlobalTemplateInterface $tpl; protected ilLanguage $lng; - protected ilAccessHandler $access; protected ilTabsGUI $tabs; protected ilBookingHelpAdapter $help; protected ilObjectDataCache $obj_data_cache; @@ -63,7 +63,7 @@ public function __construct( $this->ctrl = $DIC->ctrl(); $this->tpl = $DIC["tpl"]; $this->lng = $DIC->language(); - $this->access = $DIC->access(); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); $this->tabs = $DIC->tabs(); $this->help = $help; $this->obj_data_cache = $DIC["ilObjDataCache"]; @@ -232,11 +232,10 @@ public function render(): void $tpl = $this->tpl; $ilCtrl = $this->ctrl; $lng = $this->lng; - $ilAccess = $this->access; $bar = ""; - if ($this->isManagementActivated() && $ilAccess->checkAccess('write', '', $this->getPoolRefId())) { + if ($this->isManagementActivated() && $this->access->canManageObjects($this->getPoolRefId())) { $bar = new ilToolbarGUI(); $bar->addButton($lng->txt('book_add_object'), $ilCtrl->getLinkTarget($this, 'create')); @@ -283,7 +282,7 @@ public function resetFilter(): void */ public function create(ilPropertyFormGUI $a_form = null): void { - if (!$this->access->checkAccess('write', '', $this->ref_id)) { + if (!$this->access->canManageObjects($this->ref_id)) { return; } @@ -308,7 +307,7 @@ public function create(ilPropertyFormGUI $a_form = null): void */ public function edit(ilPropertyFormGUI $a_form = null): void { - if (!$this->access->checkAccess('write', '', $this->ref_id)) { + if (!$this->access->canManageObjects($this->ref_id)) { return; } @@ -437,7 +436,7 @@ public function initForm( public function save(): void { - if (!$this->access->checkAccess('write', '', $this->ref_id)) { + if (!$this->access->canManageObjects($this->ref_id)) { return; } @@ -496,7 +495,7 @@ public function save(): void public function update(): void { - if (!$this->access->checkAccess('write', '', $this->ref_id)) { + if (!$this->access->canManageObjects($this->ref_id)) { return; } @@ -553,7 +552,7 @@ public function update(): void public function confirmDelete(): void { - if (!$this->access->checkAccess('write', '', $this->ref_id)) { + if (!$this->access->canManageObjects($this->ref_id)) { return; } @@ -579,7 +578,7 @@ public function confirmDelete(): void public function delete(): void { - if (!$this->access->checkAccess('write', '', $this->ref_id)) { + if (!$this->access->canManageObjects($this->ref_id)) { return; } diff --git a/components/ILIAS/BookingManager/Objects/class.ilBookingObjectsTableGUI.php b/components/ILIAS/BookingManager/Objects/class.ilBookingObjectsTableGUI.php index 381b336b6b29..562788f29d9a 100755 --- a/components/ILIAS/BookingManager/Objects/class.ilBookingObjectsTableGUI.php +++ b/components/ILIAS/BookingManager/Objects/class.ilBookingObjectsTableGUI.php @@ -23,9 +23,9 @@ class ilBookingObjectsTableGUI extends ilTable2GUI { protected string $process_class; + protected \ILIAS\BookingManager\Access\AccessManager $access; protected \ILIAS\UI\Renderer $ui_renderer; protected \ILIAS\UI\Factory $ui_factory; - protected ilAccessHandler $access; protected ilObjUser $user; protected int $ref_id; protected int $pool_id; @@ -55,7 +55,7 @@ public function __construct( $this->ctrl = $DIC->ctrl(); $this->lng = $DIC->language(); - $this->access = $DIC->access(); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); $this->user = $DIC->user(); $ilCtrl = $DIC->ctrl(); $lng = $DIC->language(); @@ -69,9 +69,9 @@ public function __construct( $this->overall_limit = $a_pool_overall_limit; $this->active_management = $active_management; $this->may_edit = ($this->active_management && - $ilAccess->checkAccess('write', '', $this->ref_id)); + $this->access->canManageObjects($this->ref_id)); $this->may_assign = ($this->active_management && - $ilAccess->checkAccess('write', '', $this->ref_id)); + $this->access->canManageAllReservations($this->ref_id)); $this->advmd = ilObjBookingPool::getAdvancedMDFields($this->ref_id); @@ -292,7 +292,7 @@ protected function fillRow(array $a_set): void $ilUser = $this->user; $has_booking = false; - $booking_possible = true; + $booking_possible = $this->access->canManageOwnReservations($this->ref_id); $assign_possible = true; $has_reservations = false; diff --git a/components/ILIAS/BookingManager/Participants/class.ilBookingParticipantGUI.php b/components/ILIAS/BookingManager/Participants/class.ilBookingParticipantGUI.php index 1c5d489d95ce..f92364b42e15 100755 --- a/components/ILIAS/BookingManager/Participants/class.ilBookingParticipantGUI.php +++ b/components/ILIAS/BookingManager/Participants/class.ilBookingParticipantGUI.php @@ -26,13 +26,13 @@ class ilBookingParticipantGUI public const FILTER_ACTION_APPLY = 1; public const FILTER_ACTION_RESET = 2; public const PARTICIPANT_VIEW = 1; + protected \ILIAS\BookingManager\Access\AccessManager $access; protected \ILIAS\BookingManager\StandardGUIRequest $book_request; protected ilGlobalTemplateInterface $tpl; protected ilTabsGUI $tabs; protected ilCtrl $ctrl; protected ilLanguage $lng; - protected ilAccessHandler $access; protected ilToolbarGUI $toolbar; protected int $ref_id; protected int $pool_id; @@ -46,7 +46,7 @@ public function __construct( $this->tabs = $DIC->tabs(); $this->ctrl = $DIC->ctrl(); $this->lng = $DIC->language(); - $this->access = $DIC->access(); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); $this->toolbar = $DIC->toolbar(); $this->book_request = $DIC->bookingManager() ->internal() @@ -71,9 +71,7 @@ public function executeCommand(): void $rep_search = new ilRepositorySearchGUI(); $ref_id = $this->ref_id; $rep_search->addUserAccessFilterCallable(function ($a_user_id) { - return $this->access->filterUserIdsByRbacOrPositionOfCurrentUser( - 'render', - 'render', + return $this->access->filterManageableParticipants( $this->ref_id, $a_user_id ); @@ -97,7 +95,7 @@ public function executeCommand(): void */ public function render(): void { - if ($this->access->checkAccess('write', '', $this->ref_id)) { + if ($this->access->canManageParticipants($this->ref_id)) { ilRepositorySearchGUI::fillAutoCompleteToolbar( $this, $this->toolbar, diff --git a/components/ILIAS/BookingManager/Preferences/class.ilBookingPreferencesGUI.php b/components/ILIAS/BookingManager/Preferences/class.ilBookingPreferencesGUI.php index 9703f87f3805..7e40efd75c70 100755 --- a/components/ILIAS/BookingManager/Preferences/class.ilBookingPreferencesGUI.php +++ b/components/ILIAS/BookingManager/Preferences/class.ilBookingPreferencesGUI.php @@ -24,6 +24,7 @@ */ class ilBookingPreferencesGUI { + protected \ILIAS\BookingManager\Access\AccessManager $access; protected \ILIAS\BookingManager\InternalService $service; protected ilCtrl $ctrl; protected ilGlobalTemplateInterface $main_tpl; @@ -33,7 +34,6 @@ class ilBookingPreferencesGUI protected \Psr\Http\Message\ServerRequestInterface $request; protected ilObjUser $user; protected ilBookingPreferencesDBRepository $repo; - protected ilAccessHandler $access; public function __construct( ilObjBookingPool $pool @@ -49,7 +49,7 @@ public function __construct( $this->service = $DIC->bookingManager()->internal(); $this->pool = $pool; $this->repo = $this->service->repo()->preferences(); - $this->access = $DIC->access(); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); } public function executeCommand(): void @@ -246,7 +246,7 @@ protected function listBookingResults(): void } // all users - if ($this->access->checkAccess("write", "", $this->pool->getRefId())) { + if ($this->access->canManageAllReservations($this->pool->getRefId())) { $info_gui->addSection($lng->txt("book_all_users")); $preferences = $repo->getPreferences($this->pool->getId()); $preferences = $preferences->getPreferences(); diff --git a/components/ILIAS/BookingManager/Reservations/class.ilBookingReservationsGUI.php b/components/ILIAS/BookingManager/Reservations/class.ilBookingReservationsGUI.php index 737376aa9817..c4ed474fe0a2 100755 --- a/components/ILIAS/BookingManager/Reservations/class.ilBookingReservationsGUI.php +++ b/components/ILIAS/BookingManager/Reservations/class.ilBookingReservationsGUI.php @@ -23,6 +23,7 @@ class ilBookingReservationsGUI { protected \ILIAS\BookingManager\BookingProcess\ProcessUtilGUI $util_gui; + protected \ILIAS\BookingManager\Access\AccessManager $access; protected ilToolbarGUI $toolbar; protected \ILIAS\DI\UIServices $ui; protected \ILIAS\BookingManager\InternalService $service; @@ -33,7 +34,6 @@ class ilBookingReservationsGUI protected ilCtrl $ctrl; protected ilGlobalTemplateInterface $tpl; protected ilLanguage $lng; - protected ilAccessHandler $access; protected ilTabsGUI $tabs_gui; protected ilObjUser $user; protected ilObjBookingPool $pool; @@ -55,7 +55,7 @@ public function __construct( $this->ctrl = $DIC->ctrl(); $this->ref_id = $pool->getRefId(); $this->lng = $DIC->language(); - $this->access = $DIC->access(); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); $this->tabs_gui = $DIC->tabs(); $this->help = $help; $this->user = $DIC->user(); @@ -145,7 +145,7 @@ public function log(): void protected function getReservationsTable( ?string $reservation_id = null ): ilBookingReservationsTableGUI { - $show_all = ($this->checkPermissionBool('write') || $this->pool->hasPublicLog()); + $show_all = ($this->access->canManageAllReservations($this->ref_id) || $this->pool->hasPublicLog()); $filter = null; if ($this->book_obj_id > 0) { @@ -196,7 +196,7 @@ public function changeStatusObject(): void $this->log(); } - if ($this->checkPermissionBool('write')) { + if ($this->access->canManageAllReservations($this->ref_id)) { ilBookingReservation::changeStatus( $rsv_ids, $this->book_request->getStatus() @@ -223,11 +223,6 @@ public function resetLogFilter(): void $this->log(); } - protected function checkPermissionBool(string $a_perm): bool - { - return $this->access->checkAccess($a_perm, "", $this->ref_id); - } - // // Cancelation reservations // @@ -325,7 +320,7 @@ public function rsvConfirmCancel(): void foreach (ilBookingObject::getList($this->pool->getId()) as $item) { $valid_ids[$item["booking_object_id"]] = $item["title"]; } - if (array_key_exists($obj_id, $valid_ids) && $from > time() && ($this->checkPermissionBool("write") || (int) $user_id === $ilUser->getId())) { + if (array_key_exists($obj_id, $valid_ids) && $from > time() && ($this->access->canManageAllReservations($this->ref_id) || (int) $user_id === $ilUser->getId())) { $rsv_ids = ilBookingReservation::getCancelDetails($obj_id, $user_id, $from, $to); if (!count($rsv_ids)) { unset($ids[$idx]); @@ -524,9 +519,7 @@ public function rsvCancel(): void $res = new ilBookingReservation($id); // either write permission or own booking - $cancel_allowed_per_read = ($this->checkPermissionBool("read") && ($res->getUserId() === $ilUser->getId())); - $cancel_allowed_per_write = ($this->checkPermissionBool("write")); - if (!$cancel_allowed_per_read && !$cancel_allowed_per_write) { + if (!$this->access->canManageReservationForUser($this->ref_id, $res->getUserId())) { $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true); $this->ctrl->redirect($this, 'log'); } @@ -552,7 +545,7 @@ public function rsvCancel(): void public function rsvConfirmDelete(): void { global $DIC; - if (!$this->checkPermissionBool("write")) { + if (!$this->access->canManageAllReservations($this->ref_id)) { $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true); $this->ctrl->redirect($this, 'log'); } @@ -617,7 +610,7 @@ public function rsvDelete(): void foreach ($rsv_ids as $rsv_id) { $res = new ilBookingReservation($rsv_id); $obj = new ilBookingObject($res->getObjectId()); - if (!$this->checkPermissionBool("write") || $obj->getPoolId() !== $this->pool->getId()) { + if (!$this->access->canManageAllReservations($this->ref_id) || $obj->getPoolId() !== $this->pool->getId()) { $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true); $this->ctrl->redirect($this, 'log'); } @@ -638,7 +631,7 @@ public function rsvDelete(): void protected function showRerunPreferenceAssignment(): void { - if (!$this->checkPermissionBool('write')) { + if (!$this->access->canManageAllReservations($this->ref_id)) { return; } if ($this->pool->getScheduleType() === ilObjBookingPool::TYPE_NO_SCHEDULE_PREFERENCES) { @@ -654,7 +647,7 @@ protected function showRerunPreferenceAssignment(): void protected function confirmResetRun() { - if (!$this->checkPermissionBool('write')) { + if (!$this->access->canManageAllReservations($this->ref_id)) { return; } $this->tabs_gui->activateTab("log"); @@ -677,11 +670,11 @@ protected function confirmResetRun() protected function resetRun() { - if (!$this->checkPermissionBool('write')) { + if (!$this->access->canManageAllReservations($this->ref_id)) { return; } if ($this->pool->getScheduleType() === ilObjBookingPool::TYPE_NO_SCHEDULE_PREFERENCES - && $this->access->checkAccess("write", "", $this->pool->getRefId())) { + && $this->access->canManageAllReservations($this->pool->getRefId())) { $pref_manager = $this->service->domain()->preferences($this->pool); $repo = $this->service->repo()->preferences(); $pref_manager->resetRun(); diff --git a/components/ILIAS/BookingManager/Reservations/class.ilBookingReservationsTableGUI.php b/components/ILIAS/BookingManager/Reservations/class.ilBookingReservationsTableGUI.php index 13960ce158f9..4c7d871666b6 100755 --- a/components/ILIAS/BookingManager/Reservations/class.ilBookingReservationsTableGUI.php +++ b/components/ILIAS/BookingManager/Reservations/class.ilBookingReservationsTableGUI.php @@ -33,9 +33,9 @@ class ilBookingReservationsTableGUI extends ilTable2GUI protected ilObjBookingPool $pool; protected ScheduleManager $schedule_manager; protected ReservationDBRepository $reservation_repo; + protected \ILIAS\BookingManager\Access\AccessManager $access; protected ReservationTableSessionRepository $table_repo; protected ilObjUser $user; - protected ilAccessHandler $access; protected int $ref_id; protected array $filter; protected int $pool_id; @@ -71,15 +71,15 @@ public function __construct( $this->ctrl = $DIC->ctrl(); $this->lng = $DIC->language(); $this->user = $DIC->user(); - $this->access = $DIC->access(); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); $ilCtrl = $DIC->ctrl(); $lng = $DIC->language(); $ilUser = $DIC->user(); $this->tree = $DIC->repositoryTree(); $this->reservation_repo = $DIC->bookingManager() - ->internal() - ->repo() - ->reservation(); + ->internal() + ->repo() + ->reservation(); $this->schedule_manager = $DIC ->bookingManager() ->internal() @@ -94,9 +94,9 @@ public function __construct( $this->group_id = $a_group_id; $this->table_repo = $DIC->bookingManager() - ->internal() - ->repo() - ->reservationTable(); + ->internal() + ->repo() + ->reservationTable(); $this->advmd = ilObjBookingPool::getAdvancedMDFields($a_ref_id); @@ -149,8 +149,6 @@ public function __construct( } } - - $this->initFilter($a_filter_pre); if ($this->group_id) { $this->setLimit(9999); @@ -185,14 +183,15 @@ public function __construct( $this->setFilterCommand("applyLogFilter"); $this->setDisableFilterHiding(true); - if ($ilUser->getId() !== ANONYMOUS_USER_ID) { - $this->addMultiCommand('rsvConfirmCancel', $lng->txt('book_set_cancel')); - if ($this->access->checkAccess('write', '', $this->ref_id)) { + if ($this->access->canManageAllReservations($this->ref_id) || + $this->access->canManageOwnReservations($this->ref_id)) { + $this->addMultiCommand('rsvConfirmCancel', $lng->txt('book_set_cancel')); + } + if ($this->access->canManageAllReservations($this->ref_id)) { $this->addMultiCommand('redirectMailToBooker', $lng->txt('book_mail_to_booker')); $this->addMultiCommand('rsvConfirmDelete', $lng->txt('delete')); } - $this->setSelectAllCheckbox('mrsv'); } ilDatePresentation::setUseRelativeDates(false); } @@ -240,13 +239,12 @@ protected function getSelectableUserColumns(): array { $cols = []; // additional user fields - if (($parent = $this->getParentGroupCourse()) !== null) { - if ($this->access->checkAccess("manage_members", "", $parent["ref_id"])) { - $ef = ilExportFieldsInfo::_getInstanceByType($parent["type"]); - foreach ($ef->getSelectableFieldsInfo(ilObject::_lookupObjectId($parent["ref_id"])) as $k => $v) { - if ($k !== "login") { - $cols[$k] = $v; - } + if ($this->access->canManageMembersOfParent($this->ref_id)) { + $parent = $this->access->getParentGroupCourse($this->ref_id); + $ef = ilExportFieldsInfo::_getInstanceByType($parent["type"]); + foreach ($ef->getSelectableFieldsInfo(ilObject::_lookupObjectId($parent["ref_id"])) as $k => $v) { + if ($k !== "login") { + $cols[$k] = $v; } } } @@ -265,24 +263,6 @@ protected function getSelectedUserColumns(): array return $sel; } - protected function getParentGroupCourse(): ?array - { - $tree = $this->tree; - if (($par_ref_id = $tree->checkForParentType($this->ref_id, "grp")) > 0) { - return [ - "ref_id" => $par_ref_id, - "type" => "grp" - ]; - } - if (($par_ref_id = $tree->checkForParentType($this->ref_id, "crs")) > 0) { - return [ - "ref_id" => $par_ref_id, - "type" => "crs" - ]; - } - return null; - } - public function initFilter( array $a_filter_pre = null ): void { @@ -337,7 +317,12 @@ public function initFilter( )) ); } - $item = $this->addFilterItemByMetaType("fromto", ilTable2GUI::FILTER_DATE_RANGE, false, $this->lng->txt('book_fromto')); + $item = $this->addFilterItemByMetaType( + "fromto", + ilTable2GUI::FILTER_DATE_RANGE, + false, + $this->lng->txt('book_fromto') + ); $this->filter["fromto"] = $item->getDate(); // only needed for full log @@ -383,7 +368,8 @@ public function initFilter( // status $valid_status = array(-ilBookingReservation::STATUS_CANCELLED, - ilBookingReservation::STATUS_CANCELLED); + ilBookingReservation::STATUS_CANCELLED + ); if (!$this->has_schedule) { $options = array("" => $this->lng->txt('book_all')); } else { @@ -452,7 +438,10 @@ public function getCurrentFilter(): array $filter["from"] = $this->filter["fromto"]["from"]->get(IL_CAL_UNIX); } if ($this->filter["fromto"]["to"]) { - $day_end = new ilDateTime($this->filter["fromto"]["to"]->get(IL_CAL_DATE) . " 23:59:59", IL_CAL_DATETIME); + $day_end = new ilDateTime( + $this->filter["fromto"]["to"]->get(IL_CAL_DATE) . " 23:59:59", + IL_CAL_DATETIME + ); $filter["to"] = $day_end->get(IL_CAL_UNIX); } } @@ -559,7 +548,7 @@ public function getItems(array $filter): void // object specific user data fields of parent course or group if ($odf_ids) { - $parent = $this->getParentGroupCourse(); + $parent = $this->access->getParentGroupCourse($this->ref_id); $parent_obj_id = ilObject::_lookupObjectId($parent['ref_id']); $parent_obj_type = ilObject::_lookupType($parent_obj_id); @@ -637,8 +626,7 @@ protected function fillRow(array $a_set): void $this->tpl->setVariable("TXT_TITLE", $a_set["title"]); - $can_be_cancelled = (($ilAccess->checkAccess('write', '', $this->ref_id) || - $a_set['user_id'] == $ilUser->getId()) && + $can_be_cancelled = ($this->access->canManageReservationForUser($this->ref_id, $a_set['user_id']) && $a_set["can_be_cancelled"]); if ($can_be_cancelled) { @@ -656,12 +644,18 @@ protected function fillRow(array $a_set): void $this->tpl->setVariable("TXT_CURRENT_USER", $uname); if ($this->has_schedule) { - $this->tpl->setVariable("VALUE_DATE", ilDatePresentation::formatDate(new ilDate($a_set["date"], IL_CAL_DATE))); + $this->tpl->setVariable( + "VALUE_DATE", + ilDatePresentation::formatDate(new ilDate($a_set["date"], IL_CAL_DATE)) + ); if (in_array("week", $selected, true)) { $this->tpl->setVariable("VALUE_WEEK", $a_set["week"]); } if (in_array("weekday", $selected, true)) { - $this->tpl->setVariable("VALUE_WEEKDAY", ilCalendarUtil::_numericDayToString((int) $a_set["weekday"], false)); + $this->tpl->setVariable( + "VALUE_WEEKDAY", + ilCalendarUtil::_numericDayToString((int) $a_set["weekday"], false) + ); } $this->tpl->setVariable("VALUE_SLOT", $a_set["slot"]); $this->tpl->setVariable("VALUE_COUNTER", $a_set["counter"]); @@ -735,8 +729,7 @@ protected function fillRow(array $a_set): void $ilCtrl->setParameter($this->parent_obj, 'reservation_id', ""); } - - if ($ilAccess->checkAccess('write', '', $this->ref_id)) { + if ($this->access->canManageAllReservations($this->ref_id)) { $ilCtrl->setParameter($this->parent_obj, 'reservation_id', $a_set['booking_reservation_id']); $dd_items[] = $f->button()->shy( $lng->txt('book_mail_to_booker'), @@ -755,11 +748,11 @@ protected function fillRow(array $a_set): void $this->lng->txt("book_message"), $this->lng->txt("close") ) - ->legacy(nl2br($a_set["message"])) - ->getTriggerButtonComponents( - $this->lng->txt("book_show_message"), - true - ); + ->legacy(nl2br($a_set["message"])) + ->getTriggerButtonComponents( + $this->lng->txt("book_show_message"), + true + ); $dd_items[] = $c["button"]; $render_items[] = $c["modal"]; } @@ -821,7 +814,6 @@ protected function fillHeaderExcel( $a_excel->setCell($a_row, ++$col, $this->lng->txt("book_message")); } - foreach ($this->getAdditionalExportCols() as $txt) { $a_excel->setCell($a_row, ++$col, $txt); } @@ -844,7 +836,10 @@ protected function fillRowExcel( $a_excel->setCell($a_row, ++$col, $a_set["counter"]); } else { $status = ""; - if (in_array($a_set['status'], array(ilBookingReservation::STATUS_CANCELLED, ilBookingReservation::STATUS_IN_USE))) { + if (in_array( + $a_set['status'], + array(ilBookingReservation::STATUS_CANCELLED, ilBookingReservation::STATUS_IN_USE) + )) { $status = $this->lng->txt('book_reservation_status_' . $a_set['status']); } $a_excel->setCell($a_row, ++$col, $status); @@ -907,7 +902,10 @@ protected function fillRowCSV( $a_csv->addColumn($a_set["counter"]); } else { $status = ""; - if (in_array($a_set['status'], array(ilBookingReservation::STATUS_CANCELLED, ilBookingReservation::STATUS_IN_USE))) { + if (in_array( + $a_set['status'], + array(ilBookingReservation::STATUS_CANCELLED, ilBookingReservation::STATUS_IN_USE) + )) { $status = $this->lng->txt('book_reservation_status_' . $a_set['status']); } $a_csv->addColumn($status); diff --git a/components/ILIAS/BookingManager/Schedule/class.ilBookingScheduleGUI.php b/components/ILIAS/BookingManager/Schedule/class.ilBookingScheduleGUI.php index 42ddc2486f8b..4dab27040902 100755 --- a/components/ILIAS/BookingManager/Schedule/class.ilBookingScheduleGUI.php +++ b/components/ILIAS/BookingManager/Schedule/class.ilBookingScheduleGUI.php @@ -24,12 +24,12 @@ */ class ilBookingScheduleGUI { + protected \ILIAS\BookingManager\Access\AccessManager $access; protected \ILIAS\BookingManager\StandardGUIRequest $book_request; protected ilGlobalTemplateInterface $tpl; protected ilTabsGUI $tabs; protected ilCtrl $ctrl; protected ilLanguage $lng; - protected ilAccessHandler $access; protected ilHelpGUI $help; protected ilObjectDataCache $obj_data_cache; protected int $schedule_id; @@ -44,7 +44,7 @@ public function __construct( $this->tabs = $DIC->tabs(); $this->ctrl = $DIC->ctrl(); $this->lng = $DIC->language(); - $this->access = $DIC->access(); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); $this->help = $DIC["ilHelp"]; $this->obj_data_cache = $DIC["ilObjDataCache"]; $this->ref_id = $a_parent_obj->getRefId(); @@ -78,12 +78,10 @@ public function render(): void $tpl = $this->tpl; $lng = $this->lng; $ilCtrl = $this->ctrl; - $ilAccess = $this->access; - $table = new ilBookingSchedulesTableGUI($this, 'render', $this->ref_id); $bar = ""; - if ($ilAccess->checkAccess('write', '', $this->ref_id)) { + if ($this->access->canManageSettings($this->ref_id)) { // if we have schedules but no objects - show info if (count($table->getData())) { if (!count(ilBookingObject::getList(ilObject::_lookupObjId($this->ref_id)))) { diff --git a/components/ILIAS/BookingManager/Schedule/class.ilBookingSchedulesTableGUI.php b/components/ILIAS/BookingManager/Schedule/class.ilBookingSchedulesTableGUI.php index beb0ba5a56a4..c4e914241c69 100755 --- a/components/ILIAS/BookingManager/Schedule/class.ilBookingSchedulesTableGUI.php +++ b/components/ILIAS/BookingManager/Schedule/class.ilBookingSchedulesTableGUI.php @@ -24,7 +24,7 @@ class ilBookingSchedulesTableGUI extends ilTable2GUI { protected \ILIAS\BookingManager\InternalGUIService $gui; protected \ILIAS\BookingManager\InternalDomainService $domain; - protected ilAccessHandler $access; + protected \ILIAS\BookingManager\Access\AccessManager $access; protected ilObjectDataCache $obj_data_cache; protected int $ref_id; @@ -37,7 +37,7 @@ public function __construct( $this->ctrl = $DIC->ctrl(); $this->lng = $DIC->language(); - $this->access = $DIC->access(); + $this->access = $DIC->bookingManager()->internal()->domain()->access(); $this->obj_data_cache = $DIC["ilObjDataCache"]; $ilCtrl = $DIC->ctrl(); $ilObjDataCache = $DIC["ilObjDataCache"]; @@ -81,7 +81,6 @@ public function getItems(int $a_pool_id): void protected function fillRow(array $a_set): void { $lng = $this->lng; - $ilAccess = $this->access; $ilCtrl = $this->ctrl; $ui_factory = $this->gui->ui()->factory(); $ui_renderer = $this->gui->ui()->renderer(); @@ -98,7 +97,7 @@ protected function fillRow(array $a_set): void $actions = []; - if ($ilAccess->checkAccess('write', '', $this->ref_id)) { + if ($this->access->canManageSettings($this->ref_id)) { $actions[] = $ui_factory->link()->standard( $lng->txt('edit'), $ilCtrl->getLinkTarget($this->parent_obj, 'edit') diff --git a/components/ILIAS/BookingManager/Service/class.InternalDomainService.php b/components/ILIAS/BookingManager/Service/class.InternalDomainService.php index 401348f8ee5f..448e9b0fc915 100755 --- a/components/ILIAS/BookingManager/Service/class.InternalDomainService.php +++ b/components/ILIAS/BookingManager/Service/class.InternalDomainService.php @@ -134,4 +134,13 @@ public function bookingSettings(): SettingsManager $this ); } + + public function access(): Access\AccessManager + { + return new Access\AccessManager( + $this, + $this->DIC->access() + ); + } + } diff --git a/components/ILIAS/BookingManager/classes/Setup/AccessRBACOperationClonedObjective.php b/components/ILIAS/BookingManager/classes/Setup/AccessRBACOperationClonedObjective.php new file mode 100644 index 000000000000..ba6f70a6934c --- /dev/null +++ b/components/ILIAS/BookingManager/classes/Setup/AccessRBACOperationClonedObjective.php @@ -0,0 +1,87 @@ +src_ops = $src_ops; + $this->dest_ops = $dest_ops; + } + + public function getHash(): string + { + return hash("sha256", self::class . $this->type . ":" . $this->src_ops . ":" . $this->dest_ops); + } + + public function getLabel(): string + { + return "Clone rbac operation from $this->src_ops to $this->dest_ops"; + } + + public function achieve(Environment $environment): Environment + { + $db = $environment->getResource(Environment::RESOURCE_DATABASE); + $this->src_id = \ilRbacReview::_getCustomRBACOperationId($this->src_ops, $db); + $this->dest_id = \ilRbacReview::_getCustomRBACOperationId($this->dest_ops, $db); + ; + $env = parent::achieve($environment); + $db->insert("settings", [ + "module" => ["text", $this->type], + "keyword" => ["text", $this->getSettingsKeyword()], + "value" => ["text", "1"] + ]); + + return $env; + } + + protected function getSettingsKeyword(): string + { + return "copied_perm_" . $this->src_ops . "_" . $this->dest_ops; + } + + public function isApplicable(Environment $environment): bool + { + $db = $environment->getResource(Environment::RESOURCE_DATABASE); + + $set = $db->queryF( + "SELECT value FROM settings " . + " WHERE module = %s AND keyword = %s", + ["text", "text"], + [$this->type, $this->getSettingsKeyword()] + ); + if ($rec = $db->fetchAssoc($set)) { + if ($rec["value"] === "1") { + return false; + } + } + return true; + } + +} diff --git a/components/ILIAS/BookingManager/classes/Setup/class.Agent.php b/components/ILIAS/BookingManager/classes/Setup/class.Agent.php index b405ccde70d9..766bbfa840c2 100755 --- a/components/ILIAS/BookingManager/classes/Setup/class.Agent.php +++ b/components/ILIAS/BookingManager/classes/Setup/class.Agent.php @@ -29,6 +29,49 @@ class Agent extends Setup\Agent\NullAgent { public function getUpdateObjective(Setup\Config $config = null): Setup\Objective { - return new \ilDatabaseUpdateStepsExecutedObjective(new ilBookingManagerDBUpdateSteps()); + return new Setup\ObjectiveCollection( + "Updates of Modules/BookingManager", + false, + ...$this->getObjectives() + ); } + + protected function getObjectives(): array + { + $objectives = []; + + $objectives[] = new \ilAccessCustomRBACOperationAddedObjective( + "manage_own_reservations", + "Manage Own Reservations", + "object", + 3110, + ["book"] + ); + + $objectives[] = new \ilAccessCustomRBACOperationAddedObjective( + "manage_all_reservations", + "Manage All Reservations", + "object", + 3850, + ["book"] + ); + + $objectives[] = new AccessRBACOperationClonedObjective( + "book", + "read", + "manage_own_reservations" + ); + + $objectives[] = new AccessRBACOperationClonedObjective( + "book", + "write", + "manage_all_reservations" + ); + + // db update steps + $objectives[] = new \ilDatabaseUpdateStepsExecutedObjective(new ilBookingManagerDBUpdateSteps()); + + return $objectives; + } + } diff --git a/components/ILIAS/BookingManager/classes/class.ilBookCronNotification.php b/components/ILIAS/BookingManager/classes/class.ilBookCronNotification.php index 147e087f91b6..cb8f479f8e2e 100755 --- a/components/ILIAS/BookingManager/classes/class.ilBookCronNotification.php +++ b/components/ILIAS/BookingManager/classes/class.ilBookCronNotification.php @@ -26,7 +26,6 @@ class ilBookCronNotification extends ilCronJob { protected \ILIAS\BookingManager\InternalRepoService $repo; protected ilLanguage $lng; - protected ilAccessHandler $access; protected ilLogger $book_log; public function __construct() @@ -34,9 +33,6 @@ public function __construct() global $DIC; $this->lng = $DIC->language(); - if (isset($DIC["ilAccess"])) { - $this->access = $DIC->access(); - } $this->book_log = ilLoggerFactory::getLogger("book"); $this->repo = $DIC->bookingManager() @@ -103,6 +99,10 @@ public function run(): ilCronJobResult protected function sendNotifications(): int { + global $DIC; + + $access = $DIC->bookingManager()->internal()->domain()->access(); + $log = $this->book_log; $log->debug("start"); @@ -162,7 +162,10 @@ protected function sendNotifications(): int // users $log->debug("check notification of user id: " . $r["user_id"]); if (in_array($r["user_id"], $user_ids)) { - if ($this->checkAccess("read", $r["user_id"], $p["booking_pool_id"])) { + if ($access->canRetrieveNotificationsForOwnReservationsByObjId( + (int) $p["booking_pool_id"], + (int) $r["user_id"] + )) { $log->debug("got read"); $notifications[$r["user_id"]]["personal"][$r["pool_id"]][] = $r; } @@ -172,7 +175,10 @@ protected function sendNotifications(): int foreach ($user_ids as $uid) { $log->debug("check write for user id: " . $uid . ", pool: " . $p["booking_pool_id"]); - if ($this->checkAccess("write", $uid, $p["booking_pool_id"])) { + if ($access->canRetrieveNotificationsForAllReservationsByObjId( + (int) $p["booking_pool_id"], + (int) $r["user_id"] + )) { $log->debug("got write"); $notifications[$uid]["admin"][$r["pool_id"]][] = $r; } @@ -236,18 +242,4 @@ protected function sendMails( } - // check access on obj id - protected function checkAccess( - string $perm, - int $uid, - int $obj_id - ): bool { - $access = $this->access; - foreach (ilObject::_getAllReferences($obj_id) as $ref_id) { - if ($access->checkAccessOfUser($uid, $perm, "", $ref_id)) { - return true; - } - } - return false; - } } diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 28017e47ee1e..bc815f7aba99 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -13877,6 +13877,8 @@ rbac#:#blog_write#:#Blog bearbeiten rbac#:#book_copy#:#Buchungspool kopieren rbac#:#book_delete#:#Buchungspool löschen oder verschieben rbac#:#book_edit_permission#:#Rechteeinstellungen für Buchungspool ändern +rbac#:#book_manage_all_reservations#:#Benutzer kann alle Reservierungen verwalten +rbac#:#book_manage_own_reservations#:#Benutzer kann die eigenen Reservierungen verwalten rbac#:#book_read#:#Buchungen in Buchungspool durchführen rbac#:#book_visible#:#Buchungspool ist sichtbar rbac#:#book_write#:#Buchungsobjekte anlegen und Einstellungen des Buchungspools bearbeiten @@ -14214,9 +14216,11 @@ rbac#:#mail_smtp_mail#:#Benutzer darf E-Mails per SMTP an externe Adressen sende rbac#:#mail_to_global_roles#:#Globale Mails rbac#:#mail_visible#:#Mail-Administration ist sichtbar rbac#:#mail_write#:#Einstellungen im Mail-Administration bearbeiten +rbac#:#manage_all_reservations#:#Alle Reservierungen verwalten rbac#:#manage_comp#:#Kompetenzen bearbeiten rbac#:#manage_comp_temp#:#Kompetenzvorlagen bearbeiten rbac#:#manage_materials#:#Materialien verwalten +rbac#:#manage_own_reservations#:#Eigene Reservierungen verwalten rbac#:#manage_profiles#:#Kompetenzprofile bearbeiten rbac#:#mcst_copy#:#Mediacast kopieren rbac#:#mcst_delete#:#Mediacast löschen oder verschieben diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 500bd3469826..4e2b5dcfb282 100755 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -13857,6 +13857,8 @@ rbac#:#blog_write#:#User can edit blog settings rbac#:#book_copy#:#User can copy booking pool rbac#:#book_delete#:#User can move or delete booking pool rbac#:#book_edit_permission#:#User can change permission settings for booking pool +rbac#:#book_manage_all_reservations#:#User can manage all reservations +rbac#:#book_manage_own_reservations#:#User can manage own reservations rbac#:#book_read#:#User can book resources / objects in booking pool rbac#:#book_visible#:#Booking pool is visible rbac#:#book_write#:#User can edit settings and content of booking pool @@ -14194,9 +14196,11 @@ rbac#:#mail_smtp_mail#:#User can send e-mails per SMTP to external addresses rbac#:#mail_to_global_roles#:#Global Mails rbac#:#mail_visible#:#Mail administration is visible rbac#:#mail_write#:#User can edit settings in Mail administration +rbac#:#manage_all_reservations#:#Manage All Reservations rbac#:#manage_comp#:#Edit Competences rbac#:#manage_comp_temp#:#Edit Competence Templates rbac#:#manage_materials#:#Manage Materials +rbac#:#manage_own_reservations#:#Manage Own Reservations rbac#:#manage_profiles#:#Edit Competence Profiles rbac#:#mcst_copy#:#User can copy mediacast rbac#:#mcst_delete#:#User can move or delete mediacast From 625f6bc7edb9cc4b8132029ef110b0b5b601b3a1 Mon Sep 17 00:00:00 2001 From: Alex Killing Date: Tue, 22 Oct 2024 16:27:53 +0200 Subject: [PATCH 13/75] survey pool: fixed offline sql query --- .../classes/class.ilObjSurveyQuestionPool.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/ILIAS/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php b/components/ILIAS/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php index e85e8b37425a..c87427ea3ad7 100755 --- a/components/ILIAS/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php +++ b/components/ILIAS/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php @@ -734,9 +734,9 @@ public static function _getAvailableQuestionpools( $qpls = ilUtil::_getObjectsByOperations("spl", $permission, $ilUser->getId(), -1); $titles = ilObject::_prepareCloneSelection($qpls, "spl", $showPath); $allqpls = array(); - $result = $ilDB->query("SELECT sq.obj_fi, od.online as isonline FROM svy_qpl sq JOIN object_data od ON ()"); + $result = $ilDB->query("SELECT sq.obj_fi, od.offline as offline FROM svy_qpl sq JOIN object_data od ON (sq.obj_fi = od.obj_id) WHERE sq.obj_fi > 0 AND sq.tstamp > 0 AND NOT(od.offline = 1)"); while ($row = $ilDB->fetchAssoc($result)) { - $allqpls[$row['obj_fi']] = $row['isonline']; + $allqpls[$row['obj_fi']] = !($row['offline']); } foreach ($qpls as $ref_id) { $obj_id = ilObject::_lookupObjectId($ref_id); From bd7d342a8df5f2418c6126fb1233ebaa54951604 Mon Sep 17 00:00:00 2001 From: Nils Haagen Date: Tue, 22 Oct 2024 16:53:34 +0200 Subject: [PATCH 14/75] UI/Fields: JS binding on wrapping fieldset (#8177) * UI/Fields: JS binding on wrapping fieldset, tabindex for 'grouped' elements * UI/Fields: JS binding on wrapping fieldset, adjust filter * MD (UI/Fields): 42235, fix onLoadCode for MD QuickEditor's SwitchableGroup * UI/Fields: fix copyrights for some JS files * UI/Fields: rebase and adjust tests --- .../resources/ilMetaCopyrightListener.js | 21 +- .../Scoring/Settings/ScoreSettingsTest.php | 89 +- .../js/Input/Field/dist/input.factory.min.js | 941 +----------------- .../resources/js/Input/Field/rollup.config.js | 36 +- .../Field/src/Textarea/textarea.class.js | 20 +- .../js/Input/Field/src/input.factory.js | 25 +- .../UI/resources/js/Input/Field/tagInput.js | 17 +- .../Field/DateTimeFilterContextRenderer.php | 9 +- .../Input/Field/FilterContextRenderer.php | 14 +- .../Component/Input/Field/Renderer.php | 206 ++-- .../default/Input/tpl.context_form.html | 6 +- .../templates/default/Input/tpl.duration.html | 2 +- .../src/templates/default/Input/tpl.file.html | 2 +- .../default/Input/tpl.multiselect.html | 2 +- .../Input/tpl.optionalgroup_label.html | 2 +- .../templates/default/Input/tpl.password.html | 2 +- .../templates/default/Input/tpl.radio.html | 2 +- .../templates/default/Input/tpl.rating.html | 2 +- .../Input/tpl.switchablegroup_label.html | 2 +- .../default/Input/tpl.tag_input.html | 2 +- .../Container/Filter/FilterInputTest.php | 6 +- .../Container/Filter/StandardFilterTest.php | 40 +- .../Input/Container/Form/StandardFormTest.php | 5 +- .../Input/Field/CheckboxInputTest.php | 4 +- .../Input/Field/ColorPickerInputTest.php | 5 +- .../Input/Field/CommonFieldRendering.php | 55 +- .../Input/Field/DateTimeInputTest.php | 15 + .../Input/Field/DurationInputTest.php | 13 +- .../Component/Input/Field/FileInputTest.php | 21 +- .../Component/Input/Field/HiddenInputTest.php | 12 + .../Component/Input/Field/LinkInputTest.php | 6 +- .../Component/Input/Field/MarkdownTest.php | 64 +- .../Input/Field/MultiSelectInputTest.php | 9 +- .../Input/Field/NumericInputTest.php | 7 +- .../Input/Field/OptionalGroupInputTest.php | 22 + .../Input/Field/PasswordInputTest.php | 11 +- .../Component/Input/Field/RadioInputTest.php | 5 +- .../Component/Input/Field/RatingInputTest.php | 7 +- .../Input/Field/SectionInputTest.php | 3 + .../Component/Input/Field/SelectInputTest.php | 7 +- .../Input/Field/SwitchableGroupInputTest.php | 49 +- .../Component/Input/Field/TagInputTest.php | 7 +- .../Component/Input/Field/TextInputTest.php | 12 +- .../Component/Input/Field/TextareaTest.php | 13 +- .../Component/Input/Field/UrlInputTest.php | 6 +- 45 files changed, 589 insertions(+), 1217 deletions(-) diff --git a/components/ILIAS/MetaData/resources/ilMetaCopyrightListener.js b/components/ILIAS/MetaData/resources/ilMetaCopyrightListener.js index 507f3e8a886f..fec67109449f 100755 --- a/components/ILIAS/MetaData/resources/ilMetaCopyrightListener.js +++ b/components/ILIAS/MetaData/resources/ilMetaCopyrightListener.js @@ -1,3 +1,18 @@ +/** + * This file is part of ILIAS, a powerful learning management system + * published by ILIAS open source e-Learning e.V. + * + * ILIAS is licensed with the GPL-3.0, + * see https://www.gnu.org/licenses/gpl-3.0.en.html + * You should have received a copy of said license along with the + * source code, too. + * + * If this is not the case or you just want to try ILIAS, you'll find + * us at: + * https://www.ilias.de + * https://github.com/ILIAS-eLearning + */ + /* eslint-env jquery */ /* eslint-env browser */ il.MetaDataCopyrightListener = { @@ -19,11 +34,9 @@ il.MetaDataCopyrightListener = { this.potentialOERValues = JSON.parse(potentialOERValues); this.radioGroupId = radioGroupId; - - this.form = $(`input[id^='${this.radioGroupId}']`)[0].form; + this.form = document.querySelector(`#${this.radioGroupId}`).form; this.formButton = $(':submit', this.form); - - this.initialValue = $(`input[id^='${this.radioGroupId}']:checked`).val(); + this.initialValue = this.form.querySelector(`#${this.radioGroupId} input:checked`).value; $(this.form).on( 'submit', diff --git a/components/ILIAS/Test/tests/Scoring/Settings/ScoreSettingsTest.php b/components/ILIAS/Test/tests/Scoring/Settings/ScoreSettingsTest.php index 3cc5f5f9e4a8..03ef1c30d331 100755 --- a/components/ILIAS/Test/tests/Scoring/Settings/ScoreSettingsTest.php +++ b/components/ILIAS/Test/tests/Scoring/Settings/ScoreSettingsTest.php @@ -146,7 +146,7 @@ public function testScoreSettingsSectionScoring(): void 'radio-field-input', 'tst_text_count_system', ' -
+
@@ -162,13 +162,14 @@ public function testScoreSettingsSectionScoring(): void ', null, null, + null, '' ); $i2 = $this->getFormWrappedHtml( 'radio-field-input', 'tst_score_cutting', ' -
+
@@ -184,13 +185,14 @@ public function testScoreSettingsSectionScoring(): void ', null, null, + null, '' ); $i3 = $this->getFormWrappedHtml( 'radio-field-input', 'tst_pass_scoring', ' -
+
@@ -206,6 +208,7 @@ public function testScoreSettingsSectionScoring(): void ', null, null, + null, '' ); @@ -214,7 +217,8 @@ public function testScoreSettingsSectionScoring(): void 'test_scoring', $i1 . $i2 . $i3, null, - '', + null, + null, '' ); $this->assertHTMLEquals($expected, $this->brutallyTrimSignals($actual)); @@ -262,101 +266,108 @@ public function testScoreSettingsSectionSummary(): void $i1_1_1 = $this->getFormWrappedHtml( 'group-field-input', - 'tst_results_access_always', + 'tst_results_access_always', '', 'tst_results_access_always_desc', - null, + 'id_2', null, '' ); $i1_1_2 = $this->getFormWrappedHtml( 'group-field-input', - 'tst_results_access_finished', + 'tst_results_access_finished', '', 'tst_results_access_finished_desc', - null, + 'id_3', null, '' ); $i1_1_3 = $this->getFormWrappedHtml( 'group-field-input', - 'tst_results_access_passed', + 'tst_results_access_passed', '', 'tst_results_access_passed_desc', - null, + 'id_4', null, '' ); $i1_1_4_1 = $this->getFormWrappedHtml( 'date-time-field-input', - 'tst_reporting_date*', + 'tst_reporting_date*', '
- +
', null, - 'id_2', + 'id_6', + null, '' ); $i1_1_4 = $this->getFormWrappedHtml( 'group-field-input', - 'tst_results_access_date*', + 'tst_results_access_date*', $i1_1_4_1, 'tst_results_access_date_desc', - null, + 'id_5', null, '' ); $i1_1 = $this->getFormWrappedHtml( 'switchable-group-field-input', - 'tst_results_access_setting*', + 'tst_results_access_setting*', $i1_1_1 . $i1_1_2 . $i1_1_3 . $i1_1_4, null, - '', + null, + null, '' ); $i1_2 = $this->getFormWrappedHtml( 'checkbox-field-input', 'tst_results_grading_opt_show_status', - '', + '', 'tst_results_grading_opt_show_status_desc', - 'id_4', + 'id_7', + null, '' ); $i1_3 = $this->getFormWrappedHtml( 'checkbox-field-input', 'tst_results_grading_opt_show_mark', - '', + '', 'tst_results_grading_opt_show_mark_desc', - 'id_5', + 'id_8', + null, '' ); $i1_4 = $this->getFormWrappedHtml( 'checkbox-field-input', 'tst_results_grading_opt_show_details', - '', + '', 'tst_results_grading_opt_show_details_desc', - 'id_6', + 'id_9', + null, '' ); $i1_5 = $this->getFormWrappedHtml( 'checkbox-field-input', 'tst_pass_deletion', - '', + '', 'tst_pass_deletion_allowed', - 'id_7', + 'id_10', + null, '' ); $i1 = $this->getFormWrappedHtml( 'optional-group-field-input', - 'tst_results_access_enabled', + 'tst_results_access_enabled', $i1_1 . $i1_2 . $i1_3 . $i1_4 . $i1_5, 'tst_results_access_enabled_desc', - '', + 'id_1', + null, '' ); @@ -365,7 +376,8 @@ public function testScoreSettingsSectionSummary(): void 'test_results', $i1, null, - '', + null, + null, '' ); $this->assertEquals($expected, $this->brutallyTrimSignals($actual)); @@ -405,6 +417,7 @@ public function testScoreSettingsSectionDetails(): void $field_html, $byline, 'id_' . $nr, + null, '' ); } @@ -414,7 +427,8 @@ public function testScoreSettingsSectionDetails(): void 'tst_results_details_options', $options, null, - '', + null, + null, '' ); $this->assertEquals($expected, $this->brutallyTrimSignals($actual)); @@ -430,8 +444,8 @@ public function testScoreSettingsSectionGamification(): void $fields = $this->getFormWrappedHtml( 'radio-field-input', - 'tst_highscore_mode*', - '
+ 'tst_highscore_mode*', + '
@@ -444,14 +458,16 @@ public function testScoreSettingsSectionGamification(): void
', null, null, + null, '' ); $fields .= $this->getFormWrappedHtml( 'numeric-field-input', - 'tst_highscore_top_num*', + 'tst_highscore_top_num*', '', 'tst_highscore_top_num_description', 'id_3', + null, '' ); @@ -474,16 +490,18 @@ public function testScoreSettingsSectionGamification(): void $field_html, $byline, 'id_' . $nr, + null, '' ); } $group = $this->getFormWrappedHtml( 'optional-group-field-input', - 'tst_highscore_enabled', + 'tst_highscore_enabled', $fields, 'tst_highscore_description', - '', + 'id_1', + null, '' ); @@ -492,7 +510,8 @@ public function testScoreSettingsSectionGamification(): void 'tst_results_gamification', $group, null, - '', + null, + null, '' ); $this->assertHTMLEquals($expected, $this->brutallyTrimSignals($actual)); diff --git a/components/ILIAS/UI/resources/js/Input/Field/dist/input.factory.min.js b/components/ILIAS/UI/resources/js/Input/Field/dist/input.factory.min.js index e6a2e1c4a872..3d04226432ee 100644 --- a/components/ILIAS/UI/resources/js/Input/Field/dist/input.factory.min.js +++ b/components/ILIAS/UI/resources/js/Input/Field/dist/input.factory.min.js @@ -1,934 +1,15 @@ /** - * @author Thibeau Fuhrer - */ -class Textarea { - /** - * @type {HTMLTextAreaElement} - */ - textarea - - /** - * @type {HTMLSpanElement|null} - */ - remainder = null; - - /** - * @param {string} input_id - * @throws {Error} if DOM elements are missing. - */ - constructor(input_id) { - this.textarea = document.getElementById(input_id); - - if (null === this.textarea) { - throw new Error(`Could not find textarea for input-id '${input_id}'.`); - } - - if (this.shouldShowRemainder()) { - this.remainder = this.textarea - .closest('.c-field-textarea') - ?.querySelector('[data-action="remainder"]'); - - if (!this.remainder instanceof HTMLSpanElement) { - throw new Error(`Could not find remainder-element for input-id '${input_id}'.`); - } - - this.textarea.addEventListener('input', () => { - this.updateRemainderCountHook(); - }); - } - } - - /** - * @return {void} - */ - updateRemainderCountHook() { - if (this.shouldShowRemainder() && null !== this.remainder) { - this.remainder.innerHTML = (this.textarea.maxLength - this.textarea.value.length).toString(); - } - } - - /** - * @param {string} content - * @param {number|null} selection_start - * @param {number|null} selection_end - * @return {void} - */ - updateTextareaContent(content, selection_start = null, selection_end = null) { - // don't update content if the textarea is disabled - if (this.isDisabled()) { - return; - } - - // only refocus the textarea if the content exceeds the max-limit. - if (this.isContentTooLarge(content)) { - this.updateRemainderCountHook(); - this.textarea.focus(); - return; - } - - selection_start = selection_start ?? this.textarea.selectionStart; - selection_end = selection_end ?? this.textarea.selectionEnd; - - this.textarea.value = content; - - if (selection_start < content.length) { - this.textarea.selectionStart = selection_start; - } - - if (selection_end < content.length) { - this.textarea.selectionEnd = selection_end; - } - - this.updateRemainderCountHook(); - this.textarea.focus(); - } - - /** - * Returns the smaller value of the current selection-start or -end position. - * - * @return {number} - */ - getAbsoluteSelectionStart() { - return (this.textarea.selectionStart < this.textarea.selectionEnd) ? - this.textarea.selectionStart : - this.textarea.selectionEnd; - } - - /** - * Returns the bigger value of the current selection-start or -end position. - * - * @return {number} - */ - getAbsoluteSelectionEnd() { - return (this.textarea.selectionStart > this.textarea.selectionEnd) ? - this.textarea.selectionStart : - this.textarea.selectionEnd; - } - - /** - * @return {string[]} - */ - getLinesBeforeSelection() { - return getLinesOf(this.textarea.value).slice(0, getLineCountOf(this.getTextBeforeSelection())); - } - - /** - * @return {string[]} - */ - getLinesAfterSelection() { - let lines_of_content = getLinesOf(this.textarea.value); - - return lines_of_content.slice( - getLineCountOf(this.getTextBeforeSelection() + this.getTextOfSelection()) + 1, - lines_of_content.length - ); - } - - /** - * @return {string[]} - */ - getLinesOfSelection() { - let lines_of_content = getLinesOf(this.textarea.value); - - return lines_of_content.slice( - this.getLinesBeforeSelection().length, - lines_of_content.length - this.getLinesAfterSelection().length - ); - } - - /** - * @param {string} content - * @return {boolean} - */ - isContentTooLarge(content) { - let max_limit = this.getMaxLength(); - - // content is never too large if there's no max-limit. - if (0 > max_limit) { - return false; - } - - return (max_limit < content.length); - } - - /** - * @return {string} - */ - getTextBeforeSelection() { - return this.textarea.value.substring(0, this.getAbsoluteSelectionStart()); - } - - /** - * @return {string} - */ - getTextAfterSelection() { - return this.textarea.value.substring(this.getAbsoluteSelectionEnd(), this.textarea.value.length); - } - - /** - * @return {string} - */ - getTextOfSelection() { - return this.textarea.value.substring(this.getAbsoluteSelectionStart(), this.getAbsoluteSelectionEnd()); - } - - /** - * @return {boolean} - */ - isMultilineTextSelected() { - return this.getTextOfSelection().includes('\n'); - } - - /** - * @return {boolean} - */ - isTextSelected() { - return (this.textarea.selectionStart !== this.textarea.selectionEnd); - } - - /** - * @return {boolean} - */ - shouldShowRemainder() { - return (0 < this.getMaxLength()); - } - - /** - * This method exists due to a jsdom bug which returns the wrong default value. - * This workaround has been adopted from: - * @see https://github.com/jsdom/jsdom/issues/2927 - * @return {number} - */ - getMaxLength() { - return Number(this.textarea.getAttribute('maxlength') ?? -1); - } - - /** - * @return {boolean} - */ - isDisabled() { - return this.textarea.disabled; - } -} - -/** - * @param {string} text - * @return {number} - */ -function getLineCountOf(text) { - return (text.match(/\n/g) ?? []).length; -} - -/** - * @param {string} text - * @return {string[]} - */ -function getLinesOf(text) { - return text.split(/\n/); -} - -/** - * @author Thibeau Fuhrer - */ -class TextareaFactory { - /** - * @type {Array} - */ - instances = []; - - /** - * @param {string} input_id - * @return {void} - * @throws {Error} if the input was already initialized. - */ - init(input_id) { - if (undefined !== this.instances[input_id]) { - throw new Error(`Textarea with input-id '${input_id}' has already been initialized.`); - } - - this.instances[input_id] = new Textarea(input_id); - } - - /** - * @param {string} input_id - * @return {Textarea|null} - */ - get(input_id) { - return this.instances[input_id] ?? null; - } -} - -/** - * @author Thibeau Fuhrer - */ -class PreviewRenderer { - /** - * @type {string} - */ - preview_parameter; - - /** - * @type {string} - */ - preview_url; - - /** - * @param {Markdown} markdown_input - * @param {string} preview_parameter - * @param {string} preview_url - */ - constructor(preview_parameter, preview_url) { - this.preview_parameter = preview_parameter; - this.preview_url = preview_url; - } - - /** - * @param {string} text - * @return {Promise} - */ - async getPreviewHtmlOf(text) { - if (0 === text.length) { - return ''; - } - - let data = new FormData(); - - data.append(this.preview_parameter, text); - - let response = await fetch(this.preview_url, { - method: 'POST', - body: data, - }); - - return response.text(); - } -} - -/** - * @type {string} - */ -const CONTENT_WRAPPER_KEY_TEXTAREA = 'textarea'; - -/** - * @type {string} - */ -const CONTENT_WRAPPER_KEY_PREVIEW = 'preview'; - -/** - * @author Thibeau Fuhrer - */ -class Markdown extends Textarea { - /** - * @type {string[]} - */ - preview_history = []; - - /** - * @type {PreviewRenderer} - */ - preview_renderer; - - /** - * @type {Map} - */ - content_wrappers; - - /** - * @type {HTMLButtonElement[]} - */ - view_controls; - - /** - * @type {HTMLButtonElement[]} - */ - actions; - - /** - * @param {PreviewRenderer} preview_renderer - * @param {string} input_id - * @throws {Error} if DOM elements are missing. - */ - constructor(preview_renderer, input_id) { - super(input_id); - - let input_wrapper = this.textarea.closest('.c-field-markdown'); - - if (null === input_wrapper) { - throw new Error(`Could not find input-wrapper for input-id '${input_id}'.`); - } - - this.preview_renderer = preview_renderer; - - this.content_wrappers = getContentWrappersOrAbort(input_wrapper); - this.view_controls = getViewControlsOrAbort(input_wrapper); - this.actions = getMarkdownActions(input_wrapper); - - let has_newline_been_inserted = true; - - this.textarea.addEventListener('keydown', (event) => { - has_newline_been_inserted = this.handleEnterKeyBeforeInsertionHook(event); - }); - - this.textarea.addEventListener('keyup', (event) => { - this.handleEnterKeyAfterInsertionHook(event, has_newline_been_inserted); - }); - - this.actions.forEach((action) => { - action.addEventListener('click', (event) => { - this.performMarkdownActionHook(event); - }); - }); - - this.view_controls.forEach((control) => { - control.addEventListener('click', () => { - this.toggleViewingModeHook(); - }); - }); - } - - /** - * Automatically inserts a bullet-point or enumeration on the newly added line - * according to the previous one. - * - * NOTE that this hook should only fire if the previous hook has inserted a - * newline, otherwise this would undo the previous action. - * - * @param {KeyboardEvent} event - * @param {boolean} newline_inserted - * @return {void} - */ - handleEnterKeyAfterInsertionHook(event, newline_inserted) { - // skip this hook if the previous one didn't insert a newline, - // otherwise this hook would undo the previous action. - if (!newline_inserted || !isEnterKeyPressed(event)) { - return; - } - - let previous_line = this.getLinesBeforeSelection().pop(); - - if (undefined !== previous_line && isBulletPointed(previous_line)) { - this.applyTransformationToSelection(toggleBulletPoints); - return; - } - - if (undefined !== previous_line && isEnumerated(previous_line)) { - this.insertSingleEnumeration(); - return; - } - } - - /** - * Removes the bullet-point or enumeration of the current line if there aren't - * any other characters. - * - * @param {KeyboardEvent} event - * @return {boolean} - */ - handleEnterKeyBeforeInsertionHook(event) { - if (!isEnterKeyPressed(event)) { - return false; - } - - let current_line = this.getLinesOfSelection().shift(); - - // nothing to do if the current line is not an empty list entry. - if (undefined === current_line || !isEmptyListEntry(current_line)) { - return true; - } - - let text_before_selection = this.getLinesBeforeSelection().join('\n'); - let text_after_selection = this.getLinesAfterSelection().join('\n'); - - if (0 < text_before_selection.length) { - text_before_selection += '\n'; - } - - if (0 < text_after_selection.length) { - text_after_selection = '\n' + text_after_selection; - } - - this.updateTextareaContent( - text_before_selection + text_after_selection, - this.getAbsoluteSelectionStart() - current_line.length, - this.getAbsoluteSelectionEnd() - current_line.length - ); - - // prevent newline from being added. - event.preventDefault(); - return false; - } - - /** - * @param {MouseEvent} event - * @return {void} - */ - performMarkdownActionHook(event) { - let markdown_action = getMarkdownActionOfButton(event.target); - - switch (markdown_action) { - case 'insert-heading': - this.insertCharactersAroundSelection('# ', ''); - break; - case 'insert-link': - this.insertCharactersAroundSelection('[', '](url)'); - break; - case 'insert-bold': - this.insertCharactersAroundSelection('**', '**'); - break; - case 'insert-italic': - this.insertCharactersAroundSelection('_', '_'); - break; - case 'insert-bullet-points': - this.applyTransformationToSelection(toggleBulletPoints); - break; - case 'insert-enumeration': - (this.isMultilineTextSelected()) ? - this.applyTransformationToSelection(toggleEnumeration) : - this.insertSingleEnumeration(); - break; - default: - throw new Error(`Could not perform markdown-action '${markdown_action}'.`); - } - } - - /** - * @return {void} - */ - toggleViewingModeHook() { - this.content_wrappers.forEach(function (wrapper) { - toggleClassOfElement(wrapper, 'hidden'); - }); - - this.view_controls.forEach(function (control) { - toggleClassOfElement(control, 'engaged'); - }); - - // only toggle actions if they weren't disabled initially. - if (!this.isDisabled()) { - this.actions.forEach(function (action) { - action.disabled = !action.disabled; - let glyph = action.querySelector('.glyph'); - if (null !== glyph) { - toggleClassOfElement(glyph, 'disabled'); - } - }); - } - - this.maybeUpdatePreviewContent(); - } - - /** - * Insert a new enumeration on the current line if it's not already one. - * All lines after that will be reindexed as long as they continue the - * current enumeration. - * - * @return {void} - */ - insertSingleEnumeration() { - let lines_of_selection = this.getLinesOfSelection(); - - // abort (refocus) if the current selection is not a single line or - // is already enumerated. - if (1 !== lines_of_selection.length) { - this.textarea.focus(); - return; - } - - let lines_before_selection = this.getLinesBeforeSelection(); - let last_index = lines_before_selection.length - 1; - let previous_number = (0 <= last_index) ? getFirstNumber(lines_before_selection[last_index]) ?? 0 : 0; - - let new_lines_of_selection = toggleEnumeration(lines_of_selection, ++previous_number); - let lines_after_selection = reindexContinuousLinesOfEnumeration(this.getLinesAfterSelection(), previous_number); - - let text_before_selection = lines_before_selection.join('\n'); - let text_after_selection = lines_after_selection.join('\n'); - let text_of_selection = new_lines_of_selection.join('\n'); - - if (0 < text_before_selection.length && 0 < text_of_selection.length) { - text_before_selection += '\n'; - } - - if (0 < text_of_selection.length && 0 < text_after_selection.length) { - text_of_selection += '\n'; - } - - let new_content = text_before_selection + text_of_selection + text_after_selection; - let character_diff = new_content.length - this.textarea.value.length; - - // the selection should be shifted by the amount of newly added/removed - // characters, so that the same text is still highlighted. - this.updateTextareaContent( - new_content, - this.getAbsoluteSelectionStart() + character_diff, - this.getAbsoluteSelectionEnd() + character_diff, - ); - } - - /** - * @param {function(string[]): string[]} transformation - * @return {void} - * @throws {Error} if the transformation does not return an array. - * if the transformation is not a function. - */ - applyTransformationToSelection(transformation) { - if (!transformation instanceof Function) { - throw new Error(`Transformation must be an instance of Function, ${typeof transformation} given.`); - } - - let transformed_selection = transformation(this.getLinesOfSelection()); - - if (!transformed_selection instanceof Array) { - throw new Error(`Transformation must return an instance of Array, ${typeof transformed_selection} returned.`); - } - - let is_multiline = (1 < transformed_selection.length); - - let text_before_selection = this.getLinesBeforeSelection().join('\n'); - let text_after_selection = this.getLinesAfterSelection().join('\n'); - let text_of_selection = transformed_selection.join('\n'); - - if (0 < text_before_selection.length && 0 < text_of_selection.length) { - text_before_selection += '\n'; - } - - if (0 < text_of_selection.length && 0 < text_after_selection.length) { - text_of_selection += '\n'; - } - - let new_content = text_before_selection + text_of_selection + text_after_selection; - let character_diff = new_content.length - this.textarea.value.length; - - // the new selection should hold all transformed lines if they're a - // multiline selection. Otherwise, the selection should be shifted - // by the amount of newly added/removed characters, so that the same - // text is still highlighted. - - let new_selection_start = (is_multiline) ? - text_before_selection.length : - this.getAbsoluteSelectionStart() + character_diff - ; - - let new_selection_end = (is_multiline) ? - new_selection_start + text_of_selection.length - 1 : - this.getAbsoluteSelectionEnd() + character_diff - ; - - this.updateTextareaContent(new_content, new_selection_start, new_selection_end); - } - - /** - * @param {string} chars_before_seletion - * @param {string} chars_after_selection - * @return {void} - */ - insertCharactersAroundSelection(chars_before_seletion, chars_after_selection) { - let new_content = - this.getTextBeforeSelection() + - chars_before_seletion + - this.getTextOfSelection() + - chars_after_selection + - this.getTextAfterSelection(); - - // selection must be moved by the length of chars inserted before the selection - // in order to keep the same text highlighted. - let new_selection_start = this.getAbsoluteSelectionStart() + chars_before_seletion.length; - let new_selection_end = this.getAbsoluteSelectionEnd() + chars_before_seletion.length; - - this.updateTextareaContent(new_content, new_selection_start, new_selection_end); - } - - /** - * Updates the current preview if the previously rendered content has changed. - * - * @return {void} - */ - maybeUpdatePreviewContent() { - let previous_content = this.preview_history[(this.preview_history.length - 1)] ?? ''; - let current_content = this.textarea.value; - - if (current_content === previous_content) { - return; - } - - this.preview_history.push(current_content); - this.preview_renderer - .getPreviewHtmlOf(current_content).then((html) => { - this.content_wrappers.get(CONTENT_WRAPPER_KEY_PREVIEW).innerHTML = html; - } - ); - } - - /** - * @return {function(string[]): string[]} - */ - getBulletPointTransformation() { - return toggleBulletPoints; - } - - /** - * @return {function(string[], number=1): string[]} - */ - getEnumerationTransformation() { - return toggleEnumeration; - } -} - -/** - * @param {HTMLDivElement} input_wrapper - * @return {Map} - * @throws {Error} - */ -function getContentWrappersOrAbort(input_wrapper) { - let content_wrappers = new Map(); - - content_wrappers.set(CONTENT_WRAPPER_KEY_TEXTAREA, input_wrapper.querySelector('textarea')); - content_wrappers.set(CONTENT_WRAPPER_KEY_PREVIEW, input_wrapper.querySelector('.c-field-markdown__preview')); - - content_wrappers.forEach(function (wrapper) { - if (null === wrapper) { - throw new Error(`Could not find all content-wrappers for markdown-input.`); - } - }); - - return content_wrappers; -} - -/** - * @param {HTMLDivElement} input_wrapper - * @return {HTMLButtonElement[]} - * @throws {Error} - */ -function getViewControlsOrAbort(input_wrapper) { - let controls = input_wrapper - .querySelector('.il-viewcontrol-mode') - ?.getElementsByTagName('button'); - - if (!controls instanceof HTMLCollection || 2 !== controls.length) { - throw new Error(`Could not find exactly two view-controls.`); - } - - return [...controls]; -} - -/** - * @param {HTMLDivElement} input_wrapper - * @return {HTMLButtonElement[]} - * @throws {Error} - */ -function getMarkdownActions(input_wrapper) { - let actions = input_wrapper - .querySelector('.c-field-markdown__actions') - ?.getElementsByTagName('button'); - - if (actions instanceof HTMLCollection) { - return [...actions]; - } - - return []; -} - -/** - * @param {HTMLButtonElement} button - * @return {string|null} - */ -function getMarkdownActionOfButton(button) { - let action_wrapper = button.parentNode.closest('span'); - if (!action_wrapper instanceof HTMLSpanElement) { - return null; - } - - if (!action_wrapper.hasAttribute('data-action')) { - return null; - } - - return action_wrapper.dataset.action; -} - -/** - * @param {string[]} lines_after_selection - * @param {number} previous_number - * @return {string[]} - */ -function reindexContinuousLinesOfEnumeration(lines_after_selection, previous_number = 0) { - if (1 > lines_after_selection.length) { - return []; - } - - let reindexed_lines = []; - for (let line of lines_after_selection) { - if (!isEnumerated(line)) { - break; - } - - reindexed_lines.push(line.replace(/([0-9]+)/, (++previous_number).toString())); - } - - // replace all reindexed lines in the actual array of lines if necessary. - if (0 < reindexed_lines.length) { - lines_after_selection = reindexed_lines.concat( - lines_after_selection.slice(reindexed_lines.length) - ); - } - - return lines_after_selection; -} - -/** - * @param {string[]} lines_of_selection - * @return {string[]} - */ -function toggleBulletPoints(lines_of_selection) { - let transformed_lines = []; - let to_list = !isBulletPointed(lines_of_selection[0] ?? ''); - for (let line of lines_of_selection) { - transformed_lines.push( - (to_list) ? `- ${line}` : removeBulletPointOrEnummeration(line) - ); - } - - return transformed_lines; -} - -/** - * @param {string[]} lines_of_selection - * @param {number} next_number - * @return {string[]} - */ -function toggleEnumeration(lines_of_selection, next_number = 1) { - let transformed_lines = []; - let to_list = !isEnumerated(lines_of_selection[0] ?? ''); - for (let line of lines_of_selection) { - transformed_lines.push( - (to_list) ? `${next_number++}. ${line}` : removeBulletPointOrEnummeration(line) - ); - } - - return transformed_lines; -} - -/** - * @param {string} line - * @return {number|null} - */ -function getFirstNumber(line) { - let numbers = line.match(/([0-9]+)/); - if (null !== numbers) { - return parseInt(numbers[0]); - } - - return null; -} - -/** - * @param {HTMLElement} element - * @param {string} css_class - * @return {void} - */ -function toggleClassOfElement(element, css_class) { - if (element.classList.contains(css_class)) { - element.classList.remove(css_class); - } else { - element.classList.add(css_class); - } -} - -/** - * @param {KeyboardEvent} event - * @return {boolean} - */ -function isEnterKeyPressed(event) { - if (event instanceof KeyboardEvent) { - return ('Enter' === event.code); - } - - return false; -} - -/** - * @param {string} line - * @return {string} - */ -function removeBulletPointOrEnummeration(line) { - return line.replace(/((^(\s*[-])|(^(\s*\d+\.)))\s*)/g, ''); -} - -/** - * @param {string} line - * @return {boolean} - */ -function isEmptyListEntry(line) { - return (0 < (line.match(/((^(\s*-)|(^(\s*\d+\.)))\s*)$/g) ?? []).length); -} - -/** - * @param {string} line - * @return {boolean} - */ -function isBulletPointed(line) { - return (0 < (line.match(/^(\s*[-])/g) ?? []).length); -} - -/** - * @param {string} line - * @return {boolean} - */ -function isEnumerated(line) { - return (0 < (line.match(/^(\s*\d+\.)/g) ?? []).length); -} - -/** - * @author Thibeau Fuhrer - */ -class MarkdownFactory { - /** - * @type {Array} - */ - instances = []; - - /** - * @param {string} input_id - * @param {string} preview_url - * @param {string} parameter_name - * @return {void} - * @throws {Error} if the input was already initialized. - */ - init(input_id, preview_url, parameter_name) { - if (undefined !== this.instances[input_id]) { - throw new Error(`Markdown with input-id '${input_id}' has already been initialized.`); - } - - this.instances[input_id] = new Markdown( - new PreviewRenderer(parameter_name, preview_url), - input_id - ); - } - - /** - * @param {string} input_id - * @param {Markdown|null} - */ - get(input_id) { - return this.instances[input_id] ?? null; - } -} - -/** - * This script serves as the bootstrap file for all inputs within the - * Field/src/ directory (which have been implemented as ES6 modules). + * This file is part of ILIAS, a powerful learning management system + * published by ILIAS open source e-Learning e.V. * - * @author Thibeau Fuhrer + * ILIAS is licensed with the GPL-3.0, + * see https://www.gnu.org/licenses/gpl-3.0.en.html + * You should have received a copy of said license along with the + * source code, too. * - * The script is necessary due to rollup.js bundeling, which creates - * duplicate declarations if e.g. classes were to extend from each- - * other and are bundled into separate files. + * If this is not the case or you just want to try ILIAS, you'll find + * us at: + * https://www.ilias.de + * https://github.com/ILIAS-eLearning */ - -var il = il || {}; -il.UI = il.UI || {}; -il.UI.Input = il.UI.Input || {}; - -(function (Input) { - Input.textarea = new TextareaFactory(); - Input.markdown = new MarkdownFactory(); -})(il.UI.Input); +class e{textarea;remainder=null;constructor(e){if(this.textarea=document.getElementById(e),null===this.textarea)throw new Error(`Could not find textarea for input-id '${e}'.`);if(this.shouldShowRemainder()){if(this.remainder=this.textarea.parentNode.querySelector('[data-action="remainder"]'),!this.remainder instanceof HTMLSpanElement)throw new Error(`Could not find remainder-element for input-id '${e}'.`);this.textarea.addEventListener("input",(()=>{this.updateRemainderCountHook()}))}}updateRemainderCountHook(){this.shouldShowRemainder()&&null!==this.remainder&&(this.remainder.innerHTML=(this.textarea.maxLength-this.textarea.value.length).toString())}updateTextareaContent(e,t=null,n=null){if(!this.isDisabled()){if(this.isContentTooLarge(e))return this.updateRemainderCountHook(),void this.textarea.focus();t=t??this.textarea.selectionStart,n=n??this.textarea.selectionEnd,this.textarea.value=e,tthis.textarea.selectionEnd?this.textarea.selectionStart:this.textarea.selectionEnd}getLinesBeforeSelection(){return n(this.textarea.value).slice(0,t(this.getTextBeforeSelection()))}getLinesAfterSelection(){const e=n(this.textarea.value);return e.slice(t(this.getTextBeforeSelection()+this.getTextOfSelection())+1,e.length)}getLinesOfSelection(){const e=n(this.textarea.value);return e.slice(this.getLinesBeforeSelection().length,e.length-this.getLinesAfterSelection().length)}isContentTooLarge(e){const t=this.getMaxLength();return!(t<0)&&t0}getMaxLength(){return Number(this.textarea.getAttribute("maxlength")??-1)}isDisabled(){return this.textarea.disabled}}function t(e){return(e.match(/\n/g)??[]).length}function n(e){return e.split(/\n/)}class i{instances=[];init(t){if(void 0!==this.instances[t])throw new Error(`Textarea with input-id '${t}' has already been initialized.`);this.instances[t]=new e(t)}get(e){return this.instances[e]??null}}class r{preview_parameter;preview_url;constructor(e,t){this.preview_parameter=e,this.preview_url=t}async getPreviewHtmlOf(e){if(0===e.length)return"";let t=new FormData;return t.append(this.preview_parameter,e),(await fetch(this.preview_url,{method:"POST",body:t})).text()}}const o="textarea",s="preview";class a extends e{preview_history=[];preview_renderer;content_wrappers;view_controls;actions;constructor(e,t){super(t);const n=this.textarea.closest(".c-field-markdown");if(null===n)throw new Error(`Could not find input-wrapper for input-id '${t}'.`);this.preview_renderer=e,this.content_wrappers=function(e){const t=new Map;return t.set(o,e.querySelector("textarea")),t.set(s,e.querySelector(".c-field-markdown__preview")),t.forEach((e=>{if(null===e)throw new Error("Could not find all content-wrappers for markdown-input.")})),t}(n),this.view_controls=function(e){const t=e.querySelector(".il-viewcontrol-mode")?.getElementsByTagName("button");if(!t instanceof HTMLCollection||2!==t.length)throw new Error("Could not find exactly two view-controls.");return[...t]}(n),this.actions=function(e){const t=e.querySelector(".c-field-markdown__actions")?.getElementsByTagName("button");if(t instanceof HTMLCollection)return[...t];return[]}(n);let i=!0;this.textarea.addEventListener("keydown",(e=>{i=this.handleEnterKeyBeforeInsertionHook(e)})),this.textarea.addEventListener("keyup",(e=>{this.handleEnterKeyAfterInsertionHook(e,i)})),this.actions.forEach((e=>{e.addEventListener("click",(e=>{this.performMarkdownActionHook(e)}))})),this.view_controls.forEach((e=>{e.addEventListener("click",(()=>{this.toggleViewingModeHook()}))}))}handleEnterKeyAfterInsertionHook(e,t){if(!t||!u(e))return;const n=this.getLinesBeforeSelection().pop();void 0!==n&&g(n)?this.applyTransformationToSelection(l):void 0!==n&&f(n)&&this.insertSingleEnumeration()}handleEnterKeyBeforeInsertionHook(e){if(!u(e))return!1;const t=this.getLinesOfSelection().shift();if(void 0===t||!((t.match(/((^(\s*-)|(^(\s*\d+\.)))\s*)$/g)??[]).length>0))return!0;let n=this.getLinesBeforeSelection().join("\n"),i=this.getLinesAfterSelection().join("\n");return n.length>0&&(n+="\n"),i.length>0&&(i=`\n${i}`),this.updateTextareaContent(n+i,this.getAbsoluteSelectionStart()-t.length,this.getAbsoluteSelectionEnd()-t.length),e.preventDefault(),!1}performMarkdownActionHook(e){const t=function(e){const t=e.parentNode.closest("span");if(!t instanceof HTMLSpanElement)return null;if(!t.hasAttribute("data-action"))return null;return t.dataset.action}(e.target);switch(t){case"insert-heading":this.insertCharactersAroundSelection("# ","");break;case"insert-link":this.insertCharactersAroundSelection("[","](url)");break;case"insert-bold":this.insertCharactersAroundSelection("**","**");break;case"insert-italic":this.insertCharactersAroundSelection("_","_");break;case"insert-bullet-points":this.applyTransformationToSelection(l);break;case"insert-enumeration":this.isMultilineTextSelected()?this.applyTransformationToSelection(h):this.insertSingleEnumeration();break;default:throw new Error(`Could not perform markdown-action '${t}'.`)}}toggleViewingModeHook(){this.content_wrappers.forEach((e=>{c(e,"hidden")})),this.view_controls.forEach((e=>{c(e,"engaged")})),this.isDisabled()||this.actions.forEach((e=>{e.disabled=!e.disabled;const t=e.querySelector(".glyph");null!==t&&c(t,"disabled")})),this.maybeUpdatePreviewContent()}insertSingleEnumeration(){const e=this.getLinesOfSelection();if(1!==e.length)return void this.textarea.focus();const t=this.getLinesBeforeSelection(),n=t.length-1;let i=n>=0?function(e){const t=e.match(/([0-9]+)/);if(null!==t)return parseInt(t[0]);return null}(t[n])??0:0;const r=h(e,++i),o=function(e,t=0){if(e.length<1)return[];const n=[];for(const i of e){if(!f(i))break;n.push(i.replace(/([0-9]+)/,(++t).toString()))}n.length>0&&(e=n.concat(e.slice(n.length)));return e}(this.getLinesAfterSelection(),i);let s=t.join("\n");const a=o.join("\n");let l=r.join("\n");s.length>0&&l.length>0&&(s+="\n"),l.length>0&&a.length>0&&(l+="\n");const c=s+l+a,u=c.length-this.textarea.value.length;this.updateTextareaContent(c,this.getAbsoluteSelectionStart()+u,this.getAbsoluteSelectionEnd()+u)}applyTransformationToSelection(e){if(!e instanceof Function)throw new Error(`Transformation must be an instance of Function, ${typeof e} given.`);const t=e(this.getLinesOfSelection());if(!t instanceof Array)throw new Error(`Transformation must return an instance of Array, ${typeof t} returned.`);const n=t.length>1;let i=this.getLinesBeforeSelection().join("\n");const r=this.getLinesAfterSelection().join("\n");let o=t.join("\n");i.length>0&&o.length>0&&(i+="\n"),o.length>0&&r.length>0&&(o+="\n");const s=i+o+r,a=s.length-this.textarea.value.length,l=n?i.length:this.getAbsoluteSelectionStart()+a,h=n?l+o.length-1:this.getAbsoluteSelectionEnd()+a;this.updateTextareaContent(s,l,h)}insertCharactersAroundSelection(e,t){const n=this.getTextBeforeSelection()+e+this.getTextOfSelection()+t+this.getTextAfterSelection(),i=this.getAbsoluteSelectionStart()+e.length,r=this.getAbsoluteSelectionEnd()+e.length;this.updateTextareaContent(n,i,r)}maybeUpdatePreviewContent(){const e=this.preview_history[this.preview_history.length-1]??"",t=this.textarea.value;t!==e&&(this.preview_history.push(t),this.preview_renderer.getPreviewHtmlOf(t).then((e=>{this.content_wrappers.get(s).innerHTML=e})))}getBulletPointTransformation(){return l}getEnumerationTransformation(){return h}}function l(e){const t=[],n=!g(e[0]??"");for(const i of e)t.push(n?`- ${i}`:d(i));return t}function h(e,t=1){const n=[],i=!f(e[0]??"");for(const r of e)n.push(i?`${t++}. ${r}`:d(r));return n}function c(e,t){e.classList.contains(t)?e.classList.remove(t):e.classList.add(t)}function u(e){return e instanceof KeyboardEvent&&"Enter"===e.code}function d(e){return e.replace(/((^(\s*[-])|(^(\s*\d+\.)))\s*)/g,"")}function g(e){return(e.match(/^(\s*[-])/g)??[]).length>0}function f(e){return(e.match(/^(\s*\d+\.)/g)??[]).length>0}class p{instances=[];init(e,t,n){if(void 0!==this.instances[e])throw new Error(`Markdown with input-id '${e}' has already been initialized.`);this.instances[e]=new a(new r(n,t),e)}get(e){return this.instances[e]??null}}var S,w=w||{};w.UI=w.UI||{},w.UI.Input=w.UI.Input||{},(S=w.UI.Input).textarea=new i,S.markdown=new p; diff --git a/components/ILIAS/UI/resources/js/Input/Field/rollup.config.js b/components/ILIAS/UI/resources/js/Input/Field/rollup.config.js index 0086b65aac55..498d5f004e7e 100755 --- a/components/ILIAS/UI/resources/js/Input/Field/rollup.config.js +++ b/components/ILIAS/UI/resources/js/Input/Field/rollup.config.js @@ -1,7 +1,33 @@ +/** + * This file is part of ILIAS, a powerful learning management system + * published by ILIAS open source e-Learning e.V. + * + * ILIAS is licensed with the GPL-3.0, + * see https://www.gnu.org/licenses/gpl-3.0.en.html + * You should have received a copy of said license along with the + * source code, too. + * + * If this is not the case or you just want to try ILIAS, you'll find + * us at: + * https://www.ilias.de + * https://github.com/ILIAS-eLearning + */ + +import terser from '@rollup/plugin-terser'; +import copyright from '../../../../../../../scripts/Copyright-Checker/copyright'; +import preserveCopyright from '../../../../../../../scripts/Copyright-Checker/preserveCopyright'; + export default { - input: './src/input.factory.js', - output: { - file: './dist/input.factory.min.js', - format: 'es' - }, + input: './src/input.factory.js', + output: { + file: './dist/input.factory.min.js', + format: 'es', + plugins: [ + terser({ + format: { + comments: preserveCopyright, + }, + }), + ], + }, }; diff --git a/components/ILIAS/UI/resources/js/Input/Field/src/Textarea/textarea.class.js b/components/ILIAS/UI/resources/js/Input/Field/src/Textarea/textarea.class.js index 067bd7c9b5ee..448d21f51408 100755 --- a/components/ILIAS/UI/resources/js/Input/Field/src/Textarea/textarea.class.js +++ b/components/ILIAS/UI/resources/js/Input/Field/src/Textarea/textarea.class.js @@ -1,3 +1,18 @@ +/** + * This file is part of ILIAS, a powerful learning management system + * published by ILIAS open source e-Learning e.V. + * + * ILIAS is licensed with the GPL-3.0, + * see https://www.gnu.org/licenses/gpl-3.0.en.html + * You should have received a copy of said license along with the + * source code, too. + * + * If this is not the case or you just want to try ILIAS, you'll find + * us at: + * https://www.ilias.de + * https://github.com/ILIAS-eLearning + */ + /** * @author Thibeau Fuhrer */ @@ -24,10 +39,7 @@ export default class Textarea { } if (this.shouldShowRemainder()) { - this.remainder = this.textarea - .closest('.c-field-textarea') - ?.querySelector('[data-action="remainder"]'); - + this.remainder = this.textarea.parentNode.querySelector('[data-action="remainder"]'); if (!this.remainder instanceof HTMLSpanElement) { throw new Error(`Could not find remainder-element for input-id '${input_id}'.`); } diff --git a/components/ILIAS/UI/resources/js/Input/Field/src/input.factory.js b/components/ILIAS/UI/resources/js/Input/Field/src/input.factory.js index d02e0283b1e2..1cf726e04006 100755 --- a/components/ILIAS/UI/resources/js/Input/Field/src/input.factory.js +++ b/components/ILIAS/UI/resources/js/Input/Field/src/input.factory.js @@ -1,3 +1,18 @@ +/** + * This file is part of ILIAS, a powerful learning management system + * published by ILIAS open source e-Learning e.V. + * + * ILIAS is licensed with the GPL-3.0, + * see https://www.gnu.org/licenses/gpl-3.0.en.html + * You should have received a copy of said license along with the + * source code, too. + * + * If this is not the case or you just want to try ILIAS, you'll find + * us at: + * https://www.ilias.de + * https://github.com/ILIAS-eLearning + */ + /** * This script serves as the bootstrap file for all inputs within the * Field/src/ directory (which have been implemented as ES6 modules). @@ -9,14 +24,14 @@ * other and are bundled into separate files. */ -import TextareaFactory from "./Textarea/textarea.factory"; -import MarkdownFactory from "./Markdown/markdown.factory"; +import TextareaFactory from './Textarea/textarea.factory'; +import MarkdownFactory from './Markdown/markdown.factory'; var il = il || {}; il.UI = il.UI || {}; il.UI.Input = il.UI.Input || {}; (function (Input) { - Input.textarea = new TextareaFactory(); - Input.markdown = new MarkdownFactory(); -})(il.UI.Input); + Input.textarea = new TextareaFactory(); + Input.markdown = new MarkdownFactory(); +}(il.UI.Input)); diff --git a/components/ILIAS/UI/resources/js/Input/Field/tagInput.js b/components/ILIAS/UI/resources/js/Input/Field/tagInput.js index 1f8c6a401ce1..c1ebcc6f42d3 100755 --- a/components/ILIAS/UI/resources/js/Input/Field/tagInput.js +++ b/components/ILIAS/UI/resources/js/Input/Field/tagInput.js @@ -1,3 +1,18 @@ +/** + * This file is part of ILIAS, a powerful learning management system + * published by ILIAS open source e-Learning e.V. + * + * ILIAS is licensed with the GPL-3.0, + * see https://www.gnu.org/licenses/gpl-3.0.en.html + * You should have received a copy of said license along with the + * source code, too. + * + * If this is not the case or you just want to try ILIAS, you'll find + * us at: + * https://www.ilias.de + * https://github.com/ILIAS-eLearning + */ + /** * Wraps the TagsInput * @@ -39,7 +54,7 @@ il.UI.Input = il.UI.Input || {}; // Initialize ID and Configuration _CONFIG = $.extend(_CONFIG, config); - _CONFIG.id = raw_id; + _CONFIG.id = document.querySelector(`#${raw_id} .c-input__field .c-field-tag__wrapper input`)?.id; const settings = _getSettings(); settings.delimiters = null; diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/Field/DateTimeFilterContextRenderer.php b/components/ILIAS/UI/src/Implementation/Component/Input/Field/DateTimeFilterContextRenderer.php index d28968255605..c105a223b83e 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Input/Field/DateTimeFilterContextRenderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Input/Field/DateTimeFilterContextRenderer.php @@ -34,17 +34,16 @@ protected function wrapInFormContext( FormInput $component, string $label, string $input_html, - string $id_pointing_to_input = '', - string $dependant_group_html = '', - bool $bind_label_with_for = true, + ?string $id_for_label = null, + ?string $dependant_group_html = null ): string { $tpl = $this->getTemplate("tpl.context_form.html", true, true); $tpl->setVariable("INPUT", $input_html); - if ($id_pointing_to_input && $bind_label_with_for) { + if ($id_for_label) { $tpl->setCurrentBlock("for"); - $tpl->setVariable("ID", $id_pointing_to_input); + $tpl->setVariable("ID", $id_for_label); $tpl->parseCurrentBlock(); } diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/Field/FilterContextRenderer.php b/components/ILIAS/UI/src/Implementation/Component/Input/Field/FilterContextRenderer.php index d9e2ff5aeca4..f65d35f0a9a2 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Input/Field/FilterContextRenderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Input/Field/FilterContextRenderer.php @@ -124,20 +124,18 @@ protected function wrapInFormContext( FormInput $component, string $label, string $input_html, - string $id_pointing_to_input = '', - string $dependant_group_html = '', - bool $bind_label_with_for = true + ?string $id_for_label = null, + ?string $dependant_group_html = null ): string { - return $this->wrapInFilterContext($component, $input_html, $this->getOriginalDefaultRenderer(), $id_pointing_to_input); + return $this->wrapInFilterContext($component, $input_html, $this->getOriginalDefaultRenderer(), $id_for_label); } protected function wrapInFilterContext( FormInput $component, string $input_html, RendererInterface $default_renderer, - string $id_pointing_to_input = '', - string $dependant_group_html = '', - bool $bind_label_with_for = true + ?string $id_pointing_to_input = null, + string $dependant_group_html = '' ): string { $f = $this->getUIFactory(); $tpl = $this->getTemplate("tpl.context_filter.html", true, true); @@ -152,7 +150,7 @@ protected function wrapInFilterContext( $tpl->setCurrentBlock("addon_left"); $tpl->setVariable("LABEL", $component->getLabel()); - if ($id_pointing_to_input && $bind_label_with_for) { + if ($id_pointing_to_input) { $tpl->setCurrentBlock("for"); $tpl->setVariable("ID", $id_pointing_to_input); $tpl->parseCurrentBlock(); diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/Field/Renderer.php b/components/ILIAS/UI/src/Implementation/Component/Input/Field/Renderer.php index ee6bf48cfcd5..ee1bce23c599 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Input/Field/Renderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Input/Field/Renderer.php @@ -163,26 +163,29 @@ protected function wrapInFormContext( FormInput $component, string $label, string $input_html, - string $id_pointing_to_input = '', - string $dependant_group_html = '', - bool $bind_label_with_for = true + ?string $id_for_label = null, + ?string $dependant_group_html = null ): string { $tpl = $this->getTemplate("tpl.context_form.html", true, true); $tpl->setVariable("LABEL", $label); $tpl->setVariable("INPUT", $input_html); + $tpl->setVariable("UI_COMPONENT_NAME", $this->getComponentCanonicalNameAttribute($component)); + $tpl->setVariable("INPUT_NAME", $component->getName()); + + if ($component->getOnLoadCode() !== null) { + $binding_id = $this->bindJavaScript($component) ?? $this->createId(); + $tpl->setVariable("BINDING_ID", $binding_id); + } - if ($id_pointing_to_input && $bind_label_with_for) { + if ($id_for_label) { $tpl->setCurrentBlock('for'); - $tpl->setVariable("ID", $id_pointing_to_input); + $tpl->setVariable("ID", $id_for_label); $tpl->parseCurrentBlock(); + } else { + $tpl->touchBlock('tabindex'); } - $ui_component = $this->getComponentCanonicalNameAttribute($component); - $tpl->setVariable("UI_COMPONENT", $ui_component); - $tpl->setVariable("INPUT_NAME", $component->getName()); - - $byline = $component->getByline(); if ($byline) { $tpl->setVariable("BYLINE", $byline); @@ -190,11 +193,13 @@ protected function wrapInFormContext( $required = $component->isRequired(); if ($required) { - $tpl->touchBlock("required"); + $tpl->setCurrentBlock('required'); + $tpl->setVariable("REQUIRED_ARIA", $this->txt('required_field')); + $tpl->parseCurrentBlock(); } if ($component->isDisabled()) { - $tpl->setVariable("DISABLED", 'disabled="disabled"'); + $tpl->touchBlock("disabled"); } $error = $component->getError(); @@ -203,21 +208,17 @@ protected function wrapInFormContext( $tpl->setVariable("ERROR_LABEL", $this->txt("ui_error")); $tpl->setVariable("ERROR_ID", $error_id); $tpl->setVariable("ERROR", $error); + if ($id_for_label) { + $tpl->setVariable("ERROR_FOR_ID", $id_for_label); + } } - if ($dependant_group_html !== '') { + if ($dependant_group_html) { $tpl->setVariable("DEPENDANT_GROUP", $dependant_group_html); } return $tpl->get(); } - protected function maybeDisable(FormInput $component, Template $tpl): void - { - if ($component->isDisabled()) { - $tpl->setVariable("DISABLED", 'disabled="disabled"'); - } - } - protected function applyName(FormInput $component, Template $tpl): ?string { $name = $component->getName(); @@ -273,10 +274,11 @@ protected function htmlEntities(): Closure protected function renderLinkField(F\Link $component, RendererInterface $default_renderer): string { + $input_html = $default_renderer->render($component->getInputs()); return $this->wrapInFormContext( $component, $component->getLabel(), - $default_renderer->render($component->getInputs()) + $input_html, ); } @@ -290,8 +292,10 @@ protected function renderTextField(F\Text $component): string } $this->applyValue($component, $tpl, $this->escapeSpecialChars()); - $id = $this->bindJSandApplyId($component, $tpl); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $id); + + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } protected function renderNumericField(F\Numeric $component, RendererInterface $default_renderer): string @@ -299,8 +303,10 @@ protected function renderNumericField(F\Numeric $component, RendererInterface $d $tpl = $this->getTemplate("tpl.numeric.html", true, true); $this->applyName($component, $tpl); $this->applyValue($component, $tpl, $this->escapeSpecialChars()); - $id = $this->bindJSandApplyId($component, $tpl); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $id); + + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } protected function renderCheckboxField(F\Checkbox $component, RendererInterface $default_renderer): string @@ -312,8 +318,9 @@ protected function renderCheckboxField(F\Checkbox $component, RendererInterface $tpl->touchBlock("value"); } - $id = $this->bindJSandApplyId($component, $tpl); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $id); + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } protected function renderOptionalGroup(F\OptionalGroup $component, RendererInterface $default_renderer): string @@ -324,24 +331,14 @@ protected function renderOptionalGroup(F\OptionalGroup $component, RendererInter if ($component->getValue()) { $tpl->setVariable("CHECKED", 'checked="checked"'); } - $id = $this->bindJavaScript($component) ?? $this->createId(); - $tpl->setVariable("OPTIONID", $id); - $label = $tpl->get(); - $input_html = ''; - foreach ($component->getInputs() as $key => $input) { - $input_html .= $default_renderer->render($input); - } + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); - return $this->wrapInFormContext( - $component, - $label, - $input_html, - //$id, - '', - '', - false - ); + $label = $tpl->get(); + $input_html = $default_renderer->render($component->getInputs()); + + return $this->wrapInFormContext($component, $label, $input_html, $label_id); } protected function renderSwitchableGroup(F\SwitchableGroup $component, RendererInterface $default_renderer): string @@ -351,7 +348,6 @@ protected function renderSwitchableGroup(F\SwitchableGroup $component, RendererI list($value, ) = $component->getValue(); } - $input_html = ''; foreach ($component->getInputs() as $key => $group) { $tpl = $this->getTemplate("tpl.switchablegroup_label.html", true, true); @@ -359,6 +355,9 @@ protected function renderSwitchableGroup(F\SwitchableGroup $component, RendererI $tpl->setVariable("NAME", $component->getName()); $tpl->setVariable("VALUE", $key); + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + if ($key == $value) { $tpl->setVariable("CHECKED", 'checked="checked"'); } @@ -366,20 +365,16 @@ protected function renderSwitchableGroup(F\SwitchableGroup $component, RendererI $input_html .= $this->wrapInFormContext( $group, $tpl->get(), - $default_renderer->render($group) + $default_renderer->render($group), + $label_id ); } - $id = $this->bindJavaScript($component) ?? $this->createId(); return $this->wrapInFormContext( $component, $component->getLabel(), - $input_html, - //$id, - '', - '', - false + $input_html ); } @@ -407,14 +402,15 @@ function ($id) use ($configuration, $value) { return "il.UI.Input.tagInput.init('{$id}', {$encoded}, {$value});"; } ); - $id = $this->bindJSandApplyId($component, $tpl); if ($component->isDisabled()) { $tpl->setVariable("DISABLED", "disabled"); $tpl->setVariable("READONLY", "readonly"); } - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $id); + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } protected function renderPasswordField(F\Password $component, RendererInterface $default_renderer): string @@ -427,15 +423,16 @@ protected function renderPasswordField(F\Password $component, RendererInterface $sig_reveal = $component->getRevealSignal(); $sig_mask = $component->getMaskSignal(); $component = $component->withAdditionalOnLoadCode(function ($id) use ($sig_reveal, $sig_mask) { - $container_id = $id . "_container"; return "$(document).on('$sig_reveal', function() { - $('#$container_id').addClass('revealed'); - $('#$container_id')[0].getElementsByTagName('input')[0].type='text'; + const fieldContainer = document.querySelector('#$id .c-input__field .c-field-password'); + fieldContainer.classList.add('revealed'); + fieldContainer.getElementsByTagName('input').item(0).type='text'; });" . "$(document).on('$sig_mask', function() { - $('#$container_id').removeClass('revealed'); - $('#$container_id')[0].getElementsByTagName('input')[0].type='password'; + const fieldContainer = document.querySelector('#$id .c-input__field .c-field-password'); + fieldContainer.classList.remove('revealed'); + fieldContainer.getElementsByTagName('input').item(0).type='password'; });"; }); @@ -448,10 +445,12 @@ protected function renderPasswordField(F\Password $component, RendererInterface $tpl->setVariable('PASSWORD_REVEAL', $default_renderer->render($glyph_reveal)); $tpl->setVariable('PASSWORD_MASK', $default_renderer->render($glyph_mask)); } - $id = $this->bindJSandApplyId($component, $tpl); - $tpl->setVariable('ID_CONTAINER', $id . "_container"); + $this->applyValue($component, $tpl, $this->escapeSpecialChars()); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $id); + + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } public function renderSelectField(F\Select $component, RendererInterface $default_renderer): string @@ -486,8 +485,9 @@ public function renderSelectField(F\Select $component, RendererInterface $defaul $tpl->parseCurrentBlock(); } - $id = $this->bindJSandApplyId($component, $tpl); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $id); + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } protected function renderMarkdownField(F\Markdown $component, RendererInterface $default_renderer): string @@ -496,8 +496,9 @@ protected function renderMarkdownField(F\Markdown $component, RendererInterface $component = $component->withAdditionalOnLoadCode( static function ($id) use ($component): string { return " + const id = document.querySelector('#$id .c-input__field textarea')?.id; il.UI.Input.markdown.init( - '$id', + id, '{$component->getMarkdownRenderer()->getAsyncUrl()}', '{$component->getMarkdownRenderer()->getParameterName()}' ); @@ -505,8 +506,9 @@ static function ($id) use ($component): string { } ); + $textarea_id = $this->createId(); $textarea_tpl = $this->getPreparedTextareaTemplate($component); - $textarea_id = $this->bindJSandApplyId($component, $textarea_tpl); + $textarea_tpl->setVariable('ID', $textarea_id); $markdown_tpl = $this->getTemplate("tpl.markdown.html", true, true); $markdown_tpl->setVariable('TEXTAREA', $textarea_tpl->get()); @@ -552,8 +554,7 @@ static function ($id) use ($component): string { $markdown_tpl->setVariable($tpl_variable, $default_renderer->render($action)); } - // label must point to the wrapped textarea input, not the markdown input. - return $this->wrapInFormContext($component, $component->getLabel(), $markdown_tpl->get(), $textarea_id); + return $this->wrapInFormContext($component, $component->getLabel(), $markdown_tpl->get()); } protected function renderTextareaField(F\Textarea $component, RendererInterface $default_renderer): string @@ -562,15 +563,17 @@ protected function renderTextareaField(F\Textarea $component, RendererInterface $component = $component->withAdditionalOnLoadCode( static function ($id): string { return " - il.UI.Input.textarea.init('$id'); + taId = document.querySelector('#$id .c-input__field textarea')?.id; + il.UI.Input.textarea.init(taId); "; } ); $tpl = $this->getPreparedTextareaTemplate($component); - $id = $this->bindJSandApplyId($component, $tpl); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $id); + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } protected function getPreparedTextareaTemplate(F\Textarea $component): Template @@ -589,15 +592,13 @@ protected function getPreparedTextareaTemplate(F\Textarea $component): Template $this->applyName($component, $tpl); $this->applyValue($component, $tpl, $this->htmlEntities()); - $this->maybeDisable($component, $tpl); - return $tpl; } protected function renderRadioField(F\Radio $component, RendererInterface $default_renderer): string { $tpl = $this->getTemplate("tpl.radio.html", true, true); - $id = $this->bindJSandApplyId($component, $tpl); + $id = $this->createId(); foreach ($component->getOptions() as $value => $label) { $opt_id = $id . '_' . $value . '_opt'; @@ -629,8 +630,6 @@ protected function renderRadioField(F\Radio $component, RendererInterface $defau protected function renderMultiSelectField(F\MultiSelect $component, RendererInterface $default_renderer): string { $tpl = $this->getTemplate("tpl.multiselect.html", true, true); - $id = $this->bindJSandApplyId($component, $tpl); - $tpl->setVariable("ID", $id); $options = $component->getOptions(); if (count($options) > 0) { @@ -645,10 +644,6 @@ protected function renderMultiSelectField(F\MultiSelect $component, RendererInte if ($value && in_array($opt_value, $value)) { $tpl->setVariable("CHECKED", 'checked="checked"'); } - - if ($component->isDisabled()) { - $tpl->setVariable("DISABLED", 'disabled="disabled"'); - } $tpl->parseCurrentBlock(); } } else { @@ -661,8 +656,9 @@ protected function renderMultiSelectField(F\MultiSelect $component, RendererInte protected function renderDateTimeField(F\DateTime $component, RendererInterface $default_renderer): string { list($component, $tpl) = $this->internalRenderDateTimeField($component, $default_renderer); - $id = $this->bindJSandApplyId($component, $tpl); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $id); + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } /** @@ -716,7 +712,6 @@ protected function internalRenderDateTimeField(F\DateTime $component, RendererIn } return null; }); - $this->maybeDisable($component, $tpl); return [$component, $tpl]; } @@ -726,30 +721,27 @@ protected function renderDurationField(F\Duration $component, RendererInterface $input = array_shift($inputs); //from list($input, $tpl) = $this->internalRenderDateTimeField($input, $default_renderer); - $first_input_id = $this->bindJSandApplyId($input, $tpl); - $input_html = $this->wrapInFormContext($input, $input->getLabel(), $tpl->get(), $first_input_id); + + $from_input_id = $this->createId(); + $tpl->setVariable('ID', $from_input_id); + $input_html = $this->wrapInFormContext($input, $input->getLabel(), $tpl->get(), $from_input_id); $input = array_shift($inputs) //until ->withAdditionalPickerconfig(['useCurrent' => false]); list($input, $tpl) = $this->internalRenderDateTimeField($input, $default_renderer); - $first_input_id = $this->bindJSandApplyId($input, $tpl); - - $input_html .= $this->wrapInFormContext($input, $input->getLabel(), $tpl->get(), $first_input_id); + $until_input_id = $this->createId(); + $tpl->setVariable('ID', $until_input_id); + $input_html .= $this->wrapInFormContext($input, $input->getLabel(), $tpl->get(), $until_input_id); $tpl = $this->getTemplate("tpl.duration.html", true, true); - $id = $this->bindJSandApplyId($component, $tpl); $tpl->setVariable('DURATION', $input_html); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $first_input_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get());//, $from_input_id); } protected function renderSection(F\Section $section, RendererInterface $default_renderer): string { - $inputs_html = ""; - foreach ($section->getInputs() as $input) { - $inputs_html .= $default_renderer->render($input); - } - $id = $this->bindJavaScript($section) ?? $this->createId(); - return $this->wrapInFormContext($section, $section->getLabel(), $inputs_html, $id, '', false); + $inputs_html = $default_renderer->render($section->getInputs()); + return $this->wrapInFormContext($section, $section->getLabel(), $inputs_html); } protected function renderUrlField(F\Url $component, RendererInterface $default_renderer): string @@ -757,8 +749,10 @@ protected function renderUrlField(F\Url $component, RendererInterface $default_r $tpl = $this->getTemplate("tpl.url.html", true, true); $this->applyName($component, $tpl); $this->applyValue($component, $tpl, $this->escapeSpecialChars()); - $id = $this->bindJSandApplyId($component, $tpl); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $id); + + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } protected function renderFileField(FI\File $input, RendererInterface $default_renderer): string @@ -806,15 +800,10 @@ protected function renderFileField(FI\File $input, RendererInterface $default_re ) )); - $js_id = $this->bindJSandApplyId($input, $template); return $this->wrapInFormContext( $input, $input->getLabel(), $template->get(), - //$default_renderer, - $js_id, - "", - false ); } @@ -823,7 +812,9 @@ protected function renderHiddenField(F\Hidden $input): string $template = $this->getTemplate('tpl.hidden.html', true, true); $this->applyName($input, $template); $this->applyValue($input, $template); - $this->maybeDisable($input, $template); + if ($input->isDisabled()) { + $template->setVariable("DISABLED", 'disabled="disabled"'); + } $this->bindJSandApplyId($input, $template); return $template->get(); } @@ -1026,15 +1017,16 @@ protected function renderColorPickerField(F\ColorPicker $component, RendererInte $tpl = $this->getTemplate("tpl.colorpicker.html", true, true); $this->applyName($component, $tpl); $tpl->setVariable('VALUE', $component->getValue()); - $id = $this->bindJSandApplyId($component, $tpl); - return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get()); + $label_id = $this->createId(); + $tpl->setVariable('ID', $label_id); + return $this->wrapInFormContext($component, $component->getLabel(), $tpl->get(), $label_id); } protected function renderRatingField(F\Rating $component, RendererInterface $default_renderer): string { $tpl = $this->getTemplate("tpl.rating.html", true, true); - $id = $this->bindJSandApplyId($component, $tpl); + $id = $this->createId(); $aria_description_id = $id . '_desc'; $tpl->setVariable('DESCRIPTION_SRC_ID', $aria_description_id); @@ -1076,9 +1068,7 @@ protected function renderRatingField(F\Rating $component, RendererInterface $def $tpl->touchBlock('disabled'); } if ($average = $component->getCurrentAverage()) { - $average_title = sprintf($this->txt('rating_average'), $average); - $tpl->setVariable('AVERAGE_VALUE', $average_title); $tpl->setVariable('AVERAGE_VALUE_PERCENT', $average / $option_count * self::CENTUM); } diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.context_form.html b/components/ILIAS/UI/src/templates/default/Input/tpl.context_form.html index 2f2fc86143cd..116c46e1112f 100755 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.context_form.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.context_form.html @@ -1,6 +1,6 @@ -
aria-describedby="{ERROR_ID}" {DISABLED}> +
disabled="disabled" aria-describedby="{ERROR_ID}" id="{BINDING_ID}" tabindex="0"> - +
{INPUT} @@ -14,4 +14,4 @@ -
+
\ No newline at end of file diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.duration.html b/components/ILIAS/UI/src/templates/default/Input/tpl.duration.html index d9fbaa1c3f71..8a415b6c854b 100755 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.duration.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.duration.html @@ -1,2 +1,2 @@ -
{DURATION}
+
{DURATION}
diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.file.html b/components/ILIAS/UI/src/templates/default/Input/tpl.file.html index 70ca743a772f..ad7cbf8a1477 100755 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.file.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.file.html @@ -1,4 +1,4 @@ -
+
diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.multiselect.html b/components/ILIAS/UI/src/templates/default/Input/tpl.multiselect.html index d8ca5ae15a0f..d885be68ac2c 100755 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.multiselect.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.multiselect.html @@ -1,4 +1,4 @@ -
    +
    • diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.optionalgroup_label.html b/components/ILIAS/UI/src/templates/default/Input/tpl.optionalgroup_label.html index 9b6b15e3fe92..2630c5296cad 100644 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.optionalgroup_label.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.optionalgroup_label.html @@ -1,5 +1,5 @@ {LABEL} - name="{NAME}" value="checked" {CHECKED}/> + name="{NAME}" value="checked" {CHECKED}/> diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.password.html b/components/ILIAS/UI/src/templates/default/Input/tpl.password.html index ea854bb23730..c2ddde61f995 100755 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.password.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.password.html @@ -1,4 +1,4 @@ -
      +
      name="{NAME}" value="{VALUE}" {DISABLED} autocomplete="off" /> diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.radio.html b/components/ILIAS/UI/src/templates/default/Input/tpl.radio.html index d756b1a12f4f..d63012468f7e 100755 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.radio.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.radio.html @@ -1,4 +1,4 @@ -
      +
      name="{NAME}" value="{VALUE}" {CHECKED} {DISABLED}/> diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.rating.html b/components/ILIAS/UI/src/templates/default/Input/tpl.rating.html index a2fb82ddf619..abd994dadae8 100644 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.rating.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.rating.html @@ -1,4 +1,4 @@ -
      +
      {TEXT} diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.switchablegroup_label.html b/components/ILIAS/UI/src/templates/default/Input/tpl.switchablegroup_label.html index 0d3b2d96ff11..585b378103f6 100644 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.switchablegroup_label.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.switchablegroup_label.html @@ -1,2 +1,2 @@ - name="{NAME}" value="{VALUE}" {CHECKED} {DISABLED}/> + name="{NAME}" value="{VALUE}" {CHECKED} {DISABLED}/> {LABEL} \ No newline at end of file diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.tag_input.html b/components/ILIAS/UI/src/templates/default/Input/tpl.tag_input.html index bdc02790eddc..ae00fc0b8e42 100755 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.tag_input.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.tag_input.html @@ -1,3 +1,3 @@ -
      +
      name="{NAME}" class="c-field-tag" {READONLY} value=""/>
      diff --git a/components/ILIAS/UI/tests/Component/Input/Container/Filter/FilterInputTest.php b/components/ILIAS/UI/tests/Component/Input/Container/Filter/FilterInputTest.php index fc6070a5626e..c24229aa3553 100644 --- a/components/ILIAS/UI/tests/Component/Input/Container/Filter/FilterInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Container/Filter/FilterInputTest.php @@ -205,10 +205,10 @@ public function testRenderMultiSelectWithFilterContext(): void
      - - + + - + diff --git a/components/ILIAS/UI/tests/Component/Input/Container/Filter/StandardFilterTest.php b/components/ILIAS/UI/tests/Component/Input/Container/Filter/StandardFilterTest.php index d4ecea4c1ebf..889776ecacdf 100755 --- a/components/ILIAS/UI/tests/Component/Input/Container/Filter/StandardFilterTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Container/Filter/StandardFilterTest.php @@ -231,10 +231,10 @@ public function testRenderActivatedCollapsed(): void
      - - + + - + @@ -242,14 +242,14 @@ public function testRenderActivatedCollapsed(): void
      -
      - +
      - +
      - +
      - +
      @@ -160,7 +160,8 @@ public function testRender(): void
      ', $byline, - null + null, + 'id_3' ); $this->assertEquals($expected, $this->render($file_input)); } @@ -174,6 +175,7 @@ public function testCommonRendering(): void $this->testWithNoByline($file_input); $this->testWithRequired($file_input); $this->testWithDisabled($file_input); + $this->testWithAdditionalOnloadCodeRendersId($file_input); } public function testRenderValue(): void @@ -197,7 +199,7 @@ public function testRenderValue(): void 'file-field-input', '', ' -
      +
      @@ -228,7 +230,8 @@ public function testRenderValue(): void
      ', null, - null + null, + 'id_4' ); $this->assertEquals($expected, $this->render($file_input)); } @@ -255,7 +258,7 @@ public function testRenderWithMetadata(): void 'file-field-input', $label, ' -
      +
      @@ -300,7 +303,8 @@ public function testRenderWithMetadata(): void
      ', null, - null + null, + 'id_6', ); $this->assertEquals($expected, $this->render($file_input)); } @@ -336,7 +340,7 @@ public function testRenderWithMetadataValue(): void 'file-field-input', $label, ' -
      +
      @@ -381,7 +385,8 @@ public function testRenderWithMetadataValue(): void
      ', null, - null + null, + 'id_6' ); $this->assertEquals($expected, $this->render($file_input)); } diff --git a/components/ILIAS/UI/tests/Component/Input/Field/HiddenInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/HiddenInputTest.php index 5ae66fea6b4f..c2b1b7faed39 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/HiddenInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/HiddenInputTest.php @@ -21,6 +21,7 @@ require_once(__DIR__ . "/../../../../../../../vendor/composer/vendor/autoload.php"); require_once(__DIR__ . "/../../../Base.php"); require_once(__DIR__ . "/InputTest.php"); +require_once(__DIR__ . "/CommonFieldRendering.php"); use ILIAS\UI\Implementation\Component as I; use ILIAS\Refinery\Factory as Refinery; @@ -28,6 +29,8 @@ class HiddenInputTest extends ILIAS_UI_TestBase { + use CommonFieldRendering; + protected DefNamesource $name_source; protected I\Input\Field\Hidden $input; @@ -83,4 +86,13 @@ public function testRenderValue(): void '); $this->assertEquals($expected, $html); } + + public function testCommonRendering(): void + { + $f = $this->getFieldFactory(); + $hidden = $f->hidden()->withNameFrom($this->name_source); + + $this->testWithNoByline($hidden); + $this->testWithAdditionalOnloadCodeRendersId($hidden); + } } diff --git a/components/ILIAS/UI/tests/Component/Input/Field/LinkInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/LinkInputTest.php index 470102203d68..477a2085eab8 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/LinkInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/LinkInputTest.php @@ -62,6 +62,7 @@ public function testRendering(): void '', null, 'id_1', + null, 'name_0/label_1' ); $f2 = $this->getFormWrappedHtml( @@ -70,6 +71,7 @@ public function testRendering(): void '', null, 'id_2', + null, 'name_0/url_2' ); @@ -77,8 +79,7 @@ public function testRendering(): void 'link-field-input', $label, $f1 . $f2, - $byline, - null + $byline ); $this->assertEquals($expected, $this->render($link)); } @@ -93,6 +94,7 @@ public function testCommonRendering(): void $this->testWithNoByline($link); $this->testWithRequired($link); $this->testWithDisabled($link); + $this->testWithAdditionalOnloadCodeRendersId($link); } public function testProducesNullWhenNoDataExists(): void diff --git a/components/ILIAS/UI/tests/Component/Input/Field/MarkdownTest.php b/components/ILIAS/UI/tests/Component/Input/Field/MarkdownTest.php index 19a49b995397..295e119125bb 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/MarkdownTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/MarkdownTest.php @@ -129,8 +129,8 @@ public function testRender(): void $expected = $this->brutallyTrimHTML( " -
      - +
      +
      @@ -184,8 +184,8 @@ public function testRenderWithByline(): void $expected = $this->brutallyTrimHTML( " -
      - +
      +
      @@ -246,8 +246,8 @@ public function testRenderWithLimits(): void $expected = $this->brutallyTrimHTML( " -
      - +
      +
      @@ -304,8 +304,8 @@ public function testRenderWithDisabled(): void $expected = $this->brutallyTrimHTML( " -
      - +
      +
      @@ -332,7 +332,7 @@ public function testRenderWithDisabled(): void
      - +
      @@ -361,8 +361,8 @@ public function testRenderWithRequired(): void $expected = $this->brutallyTrimHTML( " -
      - +
      +
      @@ -418,9 +418,45 @@ public function testRenderWithError(): void )->withError($error)->withNameFrom($this->name_source); $expected = $this->brutallyTrimHTML( - html: <<
      view_control_mode
      ui_error:test_error
      - EOF + " +
      + +
      + +
      +
      + view_control_mode +
      + + + + + + + + + + + + + + + + + + +
      +
      + +
      +
      +
      + +
      +
      ui_error:$error
      + +
      + " ); $html = $this->brutallyTrimHTML($this->getRendererWithStubs()->render($input)); diff --git a/components/ILIAS/UI/tests/Component/Input/Field/MultiSelectInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/MultiSelectInputTest.php index 0970c892a892..b199cac5780e 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/MultiSelectInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/MultiSelectInputTest.php @@ -123,7 +123,7 @@ public function testRender(): void $expected = $this->getFormWrappedHtml( 'multi-select-field-input', $label, - '
        ' + '
          ' . $expected_options . '
        ', $byline, @@ -169,7 +169,7 @@ public function testRenderValue(): void $expected = $this->getFormWrappedHtml( 'multi-select-field-input', $label, - '
          ' + '
            ' . $expected_options . '
          ', $byline, @@ -188,6 +188,7 @@ public function testCommonRendering(): void $this->testWithNoByline($multi_select); $this->testWithRequired($multi_select); $this->testWithDisabled($multi_select); + $this->testWithAdditionalOnloadCodeRendersId($multi_select); } public function testRenderNoOptions(): void @@ -202,10 +203,10 @@ public function testRenderNoOptions(): void $label = $ms->getLabel(); $byline = $ms->getByline(); $expected = ' -
          +
          -
            +
            • -
          diff --git a/components/ILIAS/UI/tests/Component/Input/Field/NumericInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/NumericInputTest.php index cabfd663a73c..fa5128264441 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/NumericInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/NumericInputTest.php @@ -62,7 +62,8 @@ public function testRender(): void 'numeric-field-input', $label, '', - $byline + $byline, + 'id_1' ); $this->assertEquals($expected, $this->render($numeric)); } @@ -77,6 +78,7 @@ public function testCommonRendering(): void $this->testWithNoByline($numeric); $this->testWithRequired($numeric); $this->testWithDisabled($numeric); + $this->testWithAdditionalOnloadCodeRendersId($numeric); } public function testRenderValue(): void @@ -90,7 +92,8 @@ public function testRenderValue(): void 'numeric-field-input', $label, '', - null + null, + 'id_1' ); $this->assertEquals($expected, $this->render($numeric)); } diff --git a/components/ILIAS/UI/tests/Component/Input/Field/OptionalGroupInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/OptionalGroupInputTest.php index 439d075cf362..ab1d55339414 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/OptionalGroupInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/OptionalGroupInputTest.php @@ -20,6 +20,7 @@ require_once(__DIR__ . "/../../../../../../../vendor/composer/vendor/autoload.php"); require_once(__DIR__ . "/../../../Base.php"); +require_once(__DIR__ . "/CommonFieldRendering.php"); use ILIAS\UI\Implementation\Component\Input\Field\OptionalGroup; use ILIAS\UI\Implementation\Component\Input\Field\FormInput; @@ -38,6 +39,8 @@ abstract class Input12 extends FormInput class OptionalGroupInputTest extends ILIAS_UI_TestBase { + use CommonFieldRendering; + /** * @var Input11|mixed|MockObject */ @@ -384,4 +387,23 @@ public function testWithInputDoesNotCallChildrenWhenUnchecked(): void $this->assertNotSame($this->optional_group, $new_group); $this->assertEquals($this->data_factory->ok("result"), $new_group->getContent()); } + + public function testCommonRendering(): void + { + $f = $this->getFieldFactory(); + $label = "label"; + $og = $f->optionalGroup( + [ + "field_1" => $f->text("f"), + "field_2" => $f->text("f2") + ], + $label + )->withNameFrom((new DefNamesource())); + + $this->testWithError($og); + $this->testWithNoByline($og); + $this->testWithRequired($og); + $this->testWithDisabled($og); + $this->testWithAdditionalOnloadCodeRendersId($og); + } } diff --git a/components/ILIAS/UI/tests/Component/Input/Field/PasswordInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/PasswordInputTest.php index addb4744c0c4..b599ffda3432 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/PasswordInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/PasswordInputTest.php @@ -88,11 +88,12 @@ public function testRender(): void 'password-field-input', $label, ' -
          +
          ', - $byline + $byline, + 'id_1' ); $this->assertEquals($expected, $this->render($pwd)); } @@ -107,6 +108,7 @@ public function testCommonRendering(): void $this->testWithNoByline($pwd); $this->testWithRequired($pwd); $this->testWithDisabled($pwd); + $this->testWithAdditionalOnloadCodeRendersId($pwd); } public function testRenderValue(): void @@ -120,11 +122,12 @@ public function testRenderValue(): void 'password-field-input', $label, ' -
          +
          ', - null + null, + 'id_1' ); $this->assertEquals($expected, $this->render($pwd)); } diff --git a/components/ILIAS/UI/tests/Component/Input/Field/RadioInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/RadioInputTest.php index 1d72d5035fbd..4f92246028df 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/RadioInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/RadioInputTest.php @@ -80,7 +80,7 @@ public function testRender(): void $expected = $this->getFormWrappedHtml( 'radio-field-input', $label, - '
          ' . $expected_options . '
          ', + '
          ' . $expected_options . '
          ', $byline, null ); @@ -113,7 +113,7 @@ public function testRenderValue(): void $expected = $this->getFormWrappedHtml( 'radio-field-input', $label, - '
          ' . $expected_options . '
          ', + '
          ' . $expected_options . '
          ', $byline, null ); @@ -129,6 +129,7 @@ public function testCommonRendering(): void $this->testWithNoByline($radio); $this->testWithRequired($radio); $this->testWithDisabled($radio); + $this->testWithAdditionalOnloadCodeRendersId($radio); } } diff --git a/components/ILIAS/UI/tests/Component/Input/Field/RatingInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/RatingInputTest.php index 9cef47f1d286..b20c9ce14831 100644 --- a/components/ILIAS/UI/tests/Component/Input/Field/RatingInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/RatingInputTest.php @@ -65,7 +65,7 @@ public function testRatingRenderBasic(): void 'rating-field-input', 'label', ' -
          +
          @@ -106,11 +106,11 @@ public function testRatingRenderFull(): void ->withCurrentAverage(3); $expected = $this->brutallyTrimHTML( - '
          + '
          -
          +
          question text
          @@ -162,6 +162,7 @@ public function testCommonRendering(): void $this->testWithNoByline($rating); $this->testWithRequired($rating); $this->testWithDisabled($rating); + $this->testWithAdditionalOnloadCodeRendersId($rating); } public function testRatingAverage(): void diff --git a/components/ILIAS/UI/tests/Component/Input/Field/SectionInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/SectionInputTest.php index a7536feed9e8..bb80d242ef08 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/SectionInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/SectionInputTest.php @@ -52,6 +52,7 @@ public function testSectionRendering(): void '', 'in 1', 'id_1', + null, 'name_0/name_1' ); $f2 = $this->getFormWrappedHtml( @@ -60,6 +61,7 @@ public function testSectionRendering(): void '', 'in 2', 'id_2', + null, 'name_0/name_2' ); $expected = $this->getFormWrappedHtml( @@ -86,5 +88,6 @@ public function testCommonRendering(): void $this->testWithNoByline($section); $this->testWithRequired($section); $this->testWithDisabled($section); + $this->testWithAdditionalOnloadCodeRendersId($section); } } diff --git a/components/ILIAS/UI/tests/Component/Input/Field/SelectInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/SelectInputTest.php index 5da551eae59b..405fd3809293 100644 --- a/components/ILIAS/UI/tests/Component/Input/Field/SelectInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/SelectInputTest.php @@ -131,7 +131,8 @@ public function testRender(): void ', - $byline + $byline, + 'id_1' ); $this->assertEquals($expected, $this->render($select)); } @@ -155,7 +156,8 @@ public function testRenderValue(): void ', - $byline + $byline, + 'id_1' ); $this->assertEquals($expected, $this->render($select)); } @@ -170,6 +172,7 @@ public function testCommonRendering(): void $this->testWithNoByline($select); $this->testWithRequired($select); $this->testWithDisabled($select); + $this->testWithAdditionalOnloadCodeRendersId($select); } diff --git a/components/ILIAS/UI/tests/Component/Input/Field/SwitchableGroupInputTest.php b/components/ILIAS/UI/tests/Component/Input/Field/SwitchableGroupInputTest.php index 1b463cbded98..eafb9c8afb90 100755 --- a/components/ILIAS/UI/tests/Component/Input/Field/SwitchableGroupInputTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Field/SwitchableGroupInputTest.php @@ -428,31 +428,31 @@ public function testRender(): SG ); $expected = << +
          -
          -