From c97692089f10fa73556601a3356e797bba705560 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Wed, 25 Oct 2023 16:45:22 +0200 Subject: [PATCH] Refactoring --- .../File/XML/Export/class.ilHandler.php | 81 +++++++++++++------ .../File/XML/Manifest/class.ilHandler.php | 13 +-- .../XML/Manifest/enum.ilExportObjectType.php | 1 + .../ImportHandler/File/class.ilHandler.php | 15 ---- .../Export/interface.ilHandlerInterface.php | 16 +++- .../I/interface.ilCollectionInterface.php | 5 ++ .../ImportStatus/class.ilCollection.php | 53 ++++++++---- .../classes/ImportStatus/class.ilFactory.php | 2 +- Services/Export/classes/class.ilImport.php | 63 ++++++++------- 9 files changed, 149 insertions(+), 100 deletions(-) diff --git a/Services/Export/classes/ImportHandler/File/XML/Export/class.ilHandler.php b/Services/Export/classes/ImportHandler/File/XML/Export/class.ilHandler.php index 9ee2b4660bf3..e5ee258fd054 100644 --- a/Services/Export/classes/ImportHandler/File/XML/Export/class.ilHandler.php +++ b/Services/Export/classes/ImportHandler/File/XML/Export/class.ilHandler.php @@ -26,6 +26,7 @@ use ImportHandler\I\File\XML\Node\Info\ilTreeInterface as ilXMLFileNodeInfoTreeInterface; use ImportHandler\I\File\XSD\ilHandlerInterface as ilXSDFileHandlerInterface; use ImportStatus\Exception\ilException as ilImportStatusException; +use ImportStatus\I\ilCollectionInterface as ilImportStatusCollectionInterface; use ImportStatus\I\ilFactoryInterface as ilImportStatusFactoryInterface; use ImportHandler\I\Parser\ilFactoryInterface as ilParserFactoryInterface; use ImportHandler\I\File\XSD\ilFactoryInterface as ilXSDFileFactoryInterface; @@ -33,7 +34,9 @@ use ImportHandler\I\File\Path\ilFactoryInterface as ilFilePathFactoryInterface; use ImportHandler\I\File\Path\ilHandlerInterface as ilFilePathHandlerInterface; use ImportHandler\I\File\XML\Node\Info\Attribute\ilFactoryInterface as ilXMlFileInfoNodeAttributeFactoryInterface; +use ImportHandler\I\File\XML\Node\Info\ilHandlerInterface as ilXMLFileNodeInfoInterface; use Schema\ilXmlSchemaFactory; +use ILIAS\Data\Version; use SplFileInfo; class ilHandler extends ilXMLFileHandler implements ilXMLExportFileHandlerInterface @@ -45,6 +48,10 @@ class ilHandler extends ilXMLFileHandler implements ilXMLExportFileHandlerInterf protected ilXMlFileInfoNodeAttributeFactoryInterface $attribute; protected ilLogger $logger; + protected Version $version; + protected string $type; + protected string $subtype; + public function __construct( ilImportStatusFactoryInterface $status, ilXmlSchemaFactory $schema, @@ -70,36 +77,55 @@ public function withFileInfo(SplFileInfo $file_info): ilHandler return $clone; } - /** - * @throws ilImportStatusException - */ - public function getXSDFileHandler(): ilXSDFileHandlerInterface + public function loadExportInfo(): ilImportStatusCollectionInterface { $path_to_export = $this->path->handler() ->withStartAtRoot(true) ->withNode($this->path->node()->simple()->withName('exp:Export')); - $export_node_info = $this->parser->handler() - ->withFileHandler($this) - ->getNodeInfoAt($path_to_export) - ->current(); - $type_str = $export_node_info->getValueOfAttribute('Entity'); - $types = (str_contains($type_str, '_')) - ? explode('_', $type_str) - : [$type_str]; - $latest_file_info = count($types) === 1 - ? $this->schema->getLatest($types[0]) - : $this->schema->getLatest($types[0], $types[1]); - if (is_null($latest_file_info)) { - $statuses = $this->status->collection()->withAddedStatus($this->status->handler() - ->withType(StatusType::DEBUG) - ->withContent($this->status->content()->builder()->string()->withString( - 'Missing schema xsd file for entity of type: ' . implode('_', $types) - ))); - $exception = $this->status->exception($statuses->toString(StatusType::DEBUG)); - $exception->setStatuses($statuses); - throw $exception; + $node_info = null; + try { + $node_info = $this->parser->handler() + ->withFileHandler($this) + ->getNodeInfoAt($path_to_export) + ->current(); + } catch (ilImportStatusException $e) { + return $e->getStatuses(); } - return $this->xsd_file->handler()->withFileInfo($latest_file_info); + $type_str = $node_info->getValueOfAttribute('Entity'); + $types = str_contains($type_str, '_') + ? explode('_', $type_str) + : [$type_str, '']; + $version_str = $node_info->getValueOfAttribute('SchemaVersion'); + $this->type = $types[0]; + $this->subtype = $types[1]; + $this->version = new Version($version_str); + return $this->status->collection(); + } + + public function getVersion(): Version + { + return $this->version; + } + + public function getType(): string + { + return $this->type; + } + + public function getSubType(): string + { + return $this->subtype; + } + + /** + * @throws ilImportStatusException + */ + public function getXSDFileHandler(): ilXSDFileHandlerInterface|null + { + $latest_file_info = $this->schema->getByVersionOrLatest($this->version, $this->type, $this->subtype); + return is_null($latest_file_info) + ? null + : $this->xsd_file->handler()->withFileInfo($latest_file_info); } public function getILIASPath(ilXMLFileNodeInfoTreeInterface $component_tree): string @@ -117,4 +143,9 @@ public function getILIASPath(ilXMLFileNodeInfoTreeInterface $component_tree): st ? '' : $node->getAttributePath('Title', DIRECTORY_SEPARATOR); } + + public function isContainerExportXML(): bool + { + return $this->getSubPathToDirBeginningAtPathEnd('temp')->pathContainsFolderName('Container'); + } } diff --git a/Services/Export/classes/ImportHandler/File/XML/Manifest/class.ilHandler.php b/Services/Export/classes/ImportHandler/File/XML/Manifest/class.ilHandler.php index 3bd11d581625..e9ca30901804 100644 --- a/Services/Export/classes/ImportHandler/File/XML/Manifest/class.ilHandler.php +++ b/Services/Export/classes/ImportHandler/File/XML/Manifest/class.ilHandler.php @@ -105,18 +105,7 @@ public function getExportObjectType(): ilExportObjectType $export_file_node_info->count() > 0 && $export_set_node_info->count() > 0 ) { - $statuses = $this->status->collection()->withAddedStatus( - $this->status->handler()->withType(StatusType::FAILED)->withContent( - $this->status->content()->builder()->string()->withString( - "XML:" - . $this->getSubPathToDirBeginningAtPathEnd('temp')->getFilePath() - . "\nFound export and set elements in manifest xml." - ) - ) - ); - $exception = $this->status->exception($statuses->toString(StatusType::FAILED)); - $exception->setStatuses($statuses); - throw $exception; + return ilExportObjectType::MIXED; } if ($export_file_node_info->count() > 0) { return ilExportObjectType::EXPORT_FILE; diff --git a/Services/Export/classes/ImportHandler/File/XML/Manifest/enum.ilExportObjectType.php b/Services/Export/classes/ImportHandler/File/XML/Manifest/enum.ilExportObjectType.php index 40f66e1e4b5f..691468e60246 100644 --- a/Services/Export/classes/ImportHandler/File/XML/Manifest/enum.ilExportObjectType.php +++ b/Services/Export/classes/ImportHandler/File/XML/Manifest/enum.ilExportObjectType.php @@ -22,6 +22,7 @@ enum ilExportObjectType { + case MIXED; case EXPORT_SET; case EXPORT_FILE; case NONE; diff --git a/Services/Export/classes/ImportHandler/File/class.ilHandler.php b/Services/Export/classes/ImportHandler/File/class.ilHandler.php index 645b36375d5c..ebd766b5e27b 100644 --- a/Services/Export/classes/ImportHandler/File/class.ilHandler.php +++ b/Services/Export/classes/ImportHandler/File/class.ilHandler.php @@ -35,22 +35,13 @@ public function withFileInfo(SplFileInfo $file_info): ilFileHandlerInterface return $clone; } - protected function checkIfFileInfoIsSet(): void - { - if(!isset($this->xml_file_info)) { - throw new ilImportException("Missing file info."); - } - } - public function getFileName(): string { - $this->checkIfFileInfoIsSet(); return $this->xml_file_info->getFilename(); } public function getFilePath(): string { - $this->checkIfFileInfoIsSet(); return $this->fileExists() ? $this->xml_file_info->getRealPath() : $this->xml_file_info->getPath() . DIRECTORY_SEPARATOR . $this->xml_file_info->getFilename(); @@ -58,7 +49,6 @@ public function getFilePath(): string public function getSubPathToDirBeginningAtPathEnd(string $dir_name): ilFileHandlerInterface { - $this->checkIfFileInfoIsSet(); $parts = explode(DIRECTORY_SEPARATOR, $this->getFilePath()); $trimmed_str = ''; for ($i = count($parts) - 1; $i >= 0; $i--) { @@ -76,7 +66,6 @@ public function getSubPathToDirBeginningAtPathEnd(string $dir_name): ilFileHandl public function getSubPathToDirBeginningAtPathStart(string $dir_name): ilFileHandlerInterface { - $this->checkIfFileInfoIsSet(); $parts = explode(DIRECTORY_SEPARATOR, $this->getFilePath()); $trimmed_str = ''; for ($i = 0; $i < count($parts); $i++) { @@ -94,19 +83,16 @@ public function getSubPathToDirBeginningAtPathStart(string $dir_name): ilFileHan public function getPathToFileLocation(): string { - $this->checkIfFileInfoIsSet(); return $this->xml_file_info->getPath(); } public function fileExists(): bool { - $this->checkIfFileInfoIsSet(); return $this->xml_file_info->getRealPath() !== false; } public function getPathPart(string $pattern): string|null { - $this->checkIfFileInfoIsSet(); $path_parts = explode(DIRECTORY_SEPARATOR, $this->getFilePath()); foreach ($path_parts as $path_part) { if (preg_match($pattern, $path_part) === 1) { @@ -118,7 +104,6 @@ public function getPathPart(string $pattern): string|null public function pathContainsFolderName(string $folder_name): bool { - $this->checkIfFileInfoIsSet(); $path_parts = explode(DIRECTORY_SEPARATOR, $this->getFilePath()); if (in_array($folder_name, $path_parts, true)) { return true; diff --git a/Services/Export/classes/ImportHandler/I/File/XML/Export/interface.ilHandlerInterface.php b/Services/Export/classes/ImportHandler/I/File/XML/Export/interface.ilHandlerInterface.php index 548410616ec2..3f4f493e4151 100644 --- a/Services/Export/classes/ImportHandler/I/File/XML/Export/interface.ilHandlerInterface.php +++ b/Services/Export/classes/ImportHandler/I/File/XML/Export/interface.ilHandlerInterface.php @@ -20,16 +20,28 @@ namespace ImportHandler\I\File\XML\Export; +use ILIAS\Data\Version; use ImportHandler\I\File\XML\ilHandlerInterface as ilXMLFileHandlerInterface; use ImportHandler\I\File\XSD\ilHandlerInterface as ilXSDFileHandlerInterface; use ImportHandler\I\File\XML\Node\Info\ilTreeInterface as ilXMLFileNodeInfoTreeInterface; +use ImportStatus\I\ilCollectionInterface as ilImportStatusCollectionInterface; use SplFileInfo; interface ilHandlerInterface extends ilXMLFileHandlerInterface { - public function getXSDFileHandler(): ilXSDFileHandlerInterface; + public function getXSDFileHandler(): ilXSDFileHandlerInterface|null; - public function withFileInfo(SplFileInfo $file_info): ilHandlerInterface; + public function getVersion(): Version; + + public function getType(): string; + + public function getSubType(): string; public function getILIASPath(ilXMLFileNodeInfoTreeInterface $component_tree): string; + + public function withFileInfo(SplFileInfo $file_info): ilHandlerInterface; + + public function loadExportInfo(): ilImportStatusCollectionInterface; + + public function isContainerExportXML(): bool; } diff --git a/Services/Export/classes/ImportStatus/I/interface.ilCollectionInterface.php b/Services/Export/classes/ImportStatus/I/interface.ilCollectionInterface.php index 6437ba3b5bb8..16ab6d9d0f8a 100644 --- a/Services/Export/classes/ImportStatus/I/interface.ilCollectionInterface.php +++ b/Services/Export/classes/ImportStatus/I/interface.ilCollectionInterface.php @@ -40,6 +40,11 @@ public function withNumberingEnabled(bool $enabled): ilCollectionInterface; public function toString(StatusType ...$types): string; + public function mergeContentToElements( + ilImportStatusContentHandlerInterface $content, + bool $at_front = true + ): ilCollectionInterface; + /** * @return ilImportStatusHandlerInterface[] */ diff --git a/Services/Export/classes/ImportStatus/class.ilCollection.php b/Services/Export/classes/ImportStatus/class.ilCollection.php index 674c875c07d1..9ed17b493fe3 100644 --- a/Services/Export/classes/ImportStatus/class.ilCollection.php +++ b/Services/Export/classes/ImportStatus/class.ilCollection.php @@ -20,28 +20,30 @@ namespace ImportStatus; +use ImportStatus\I\Content\ilHandlerInterface as ilImportStatusContentHandlerInterface; use ImportStatus\I\ilCollectionInterface; use ImportStatus\I\ilHandlerInterface; +use ImportStatus\I\ilFactoryInterface as ilImportStatusFactoryInterface; class ilCollection implements ilCollectionInterface { + protected ilImportStatusFactoryInterface $status; /** * @var ilHandlerInterface[] */ - protected array $status_collection; + protected array $elements; protected int $index; protected int $minIndex; protected bool $is_numbering_enabled; - /** - * @param ilHandlerInterface[] $initial_values - */ - public function __construct(array $initial_values = []) - { - $this->status_collection = $initial_values; + public function __construct( + ilImportStatusFactoryInterface $status, + ) { + $this->elements = []; $this->minIndex = 0; $this->index = $this->minIndex; $this->is_numbering_enabled = false; + $this->status = $status; } /** @@ -65,23 +67,27 @@ public function hasStatusType(StatusType $type): bool public function withAddedStatus(ilHandlerInterface $import_status): ilCollection { $clone = clone $this; - $clone->status_collection[] = $import_status; + $clone->elements[] = $import_status; return $clone; } public function getCollectionOfAllByType(StatusType $type): ilCollectionInterface { - return new ilCollection($this->getArrayOfElementsWithType($type)); + $clone = clone $this; + $clone->elements = $this->getArrayOfElementsWithType($type); + return $clone; } public function getMergedCollectionWith(ilCollectionInterface $other): ilCollectionInterface { - return new ilCollection(array_merge($this->toArray(), $other->toArray())); + $clone = clone $this; + $clone->elements = array_merge($this->toArray(), $other->toArray()); + return $clone; } public function current(): ilHandlerInterface { - return $this->status_collection[$this->index]; + return $this->elements[$this->index]; } public function next(): void @@ -106,7 +112,7 @@ public function rewind(): void public function count(): int { - return count($this->status_collection); + return count($this->elements); } /** @@ -114,7 +120,7 @@ public function count(): int */ public function toArray(): array { - return $this->status_collection; + return $this->elements; } public function withNumberingEnabled(bool $enabled): ilCollectionInterface @@ -126,7 +132,7 @@ public function withNumberingEnabled(bool $enabled): ilCollectionInterface public function toString(StatusType ...$types): string { - $collection = new ilCollection(); + $collection = $this->status->collection(); $msg = "
Listing status messages (of type(s)"; foreach ($types as $type) { $msg .= " " . $type->name; @@ -144,4 +150,23 @@ public function toString(StatusType ...$types): string } return $msg; } + + public function mergeContentToElements( + ilImportStatusContentHandlerInterface $content, + bool $at_front = true + ): ilCollectionInterface { + $clone = clone $this; + $new_elements = []; + foreach ($clone->toArray() as $element) { + $new_elements[] = $at_front + ? $this->status->handler() + ->withType($element->getType()) + ->withContent($content->mergeWith($element->getContent())) + : $this->status->handler() + ->withType($element->getType()) + ->withContent($element->getContent()->mergeWith($content)); + } + $clone->elements = $new_elements; + return $clone; + } } diff --git a/Services/Export/classes/ImportStatus/class.ilFactory.php b/Services/Export/classes/ImportStatus/class.ilFactory.php index 677f3858ff0a..d544ec4d40ac 100644 --- a/Services/Export/classes/ImportStatus/class.ilFactory.php +++ b/Services/Export/classes/ImportStatus/class.ilFactory.php @@ -44,7 +44,7 @@ public function handler(): ilImportStatusHandlerInterface public function collection(): ilImportStatusHandlerCollectionInterface { - return new ilImportStatusHandlerCollection(); + return new ilImportStatusHandlerCollection($this); } public function exception(string $msg): ilImportStatusExceptionInterface diff --git a/Services/Export/classes/class.ilImport.php b/Services/Export/classes/class.ilImport.php index c6810f1d8bb4..203f6adaa70b 100644 --- a/Services/Export/classes/class.ilImport.php +++ b/Services/Export/classes/class.ilImport.php @@ -29,7 +29,6 @@ use ImportStatus\I\ilCollectionInterface as ilImportStatusHandlerCollectionInterface; use ImportStatus\StatusType; use ImportStatus\Exception\ilException as ilImportStatusException; -use Schema\ilXmlSchemaFactory; /** * Import class @@ -177,9 +176,9 @@ protected function unzipFile( protected function validateXMLFiles(SplFileInfo $manifest_spl): ilImportStatusHandlerCollectionInterface { $export_files = $this->import->file()->xml()->export()->collection(); - $schema_factory = new ilXmlSchemaFactory(); $manifest_handlers = $this->import->file()->xml()->manifest()->handlerCollection(); $statuses = $this->import_status->collection(); + // Find export xmls try { $manifest_handlers = $manifest_handlers->withElement( $this->import->file()->xml()->manifest()->handler()->withFileInfo($manifest_spl) @@ -214,42 +213,44 @@ protected function validateXMLFiles(SplFileInfo $manifest_spl): ilImportStatusHa ->withNode($this->import->file()->path()->node()->anyNode()); $component_tree = $this->import->file()->xml()->node()->info()->tree(); foreach ($export_files as $export_file) { - if (!$export_file - ->getSubPathToDirBeginningAtPathEnd('temp') - ->pathContainsFolderName('Container') - ) { - continue; + if ($export_file->isContainerExportXML()) { + $component_tree = $component_tree->withRootInFile($export_file, $path_to_export_item_child); + break; } - $component_tree = $component_tree->withRootInFile( - $export_file, - $path_to_export_item_child - ); - break; } foreach ($export_files as $export_file) { - $found_statuses = $this->import_status->collection(); - try { - $found_statuses = $this->import->file()->validation()->handler()->validateXMLAtPath( - $export_file, - $export_file->getXSDFileHandler(), - $path_to_export_item_child - ); - } catch (ilImportStatusException $e) { - $found_statuses = $e->getStatuses(); + $found_statuses = $export_file->loadExportInfo(); + $xsd_file = $found_statuses->hasStatusType(StatusType::FAILED) + ? null + : $export_file->getXSDFileHandler(); + if (!$found_statuses->hasStatusType(StatusType::FAILED) && is_null($xsd_file)) { + $found_statuses = $found_statuses->withAddedStatus($this->import_status->handler() + ->withType(StatusType::DEBUG) + ->withContent($this->import_status->content()->builder()->string()->withString( + 'Missing schema xsd file for entity of type: ' + . $export_file->getType() + . ($export_file->getSubType() === '' ? '' : '_' . $export_file->getSubType()) + ))); + } + if(!$found_statuses->hasStatusType(StatusType::FAILED) && !is_null($xsd_file)) { + try { + $found_statuses = $this->import->file()->validation()->handler()->validateXMLAtPath( + $export_file, + $xsd_file, + $path_to_export_item_child + ); + } catch (ilImportStatusException $e) { + $found_statuses = $e->getStatuses(); + } } if (!$found_statuses->hasStatusType(StatusType::FAILED)) { continue; } - // Append location - $ilias_path = $export_file->getILIASPath($component_tree); - $info_str = "
Location: " . $ilias_path . "
"; - foreach ($found_statuses as $status) { - $extra_content = $this->import_status->content()->builder()->string()->withString($info_str); - $old_content = $status->getContent(); - $new_content = $extra_content->mergeWith($old_content); - $new_status = $this->import_status->handler()->withType($status->getType())->withContent($new_content); - $statuses = $statuses->withAddedStatus($new_status); - } + $info_str = "
Location: " . $export_file->getILIASPath($component_tree) . "
"; + $found_statuses = $found_statuses->mergeContentToElements( + $this->import_status->content()->builder()->string()->withString($info_str) + ); + $statuses = $statuses->getMergedCollectionWith($found_statuses); } return $statuses; }