ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilHandler.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
23 use DOMDocument;
24 use Exception;
25 use ILIAS\Export\ImportHandler\I\File\ilHandlerInterface as ilFileHandlerInterface;
26 use ILIAS\Export\ImportHandler\I\File\Path\ilFactoryInterface as ilFilePathFactoryInterface;
27 use ILIAS\Export\ImportHandler\I\File\Path\ilHandlerInterface as ilFilePathHandlerInterface;
28 use ILIAS\Export\ImportHandler\I\File\Validation\ilHandlerInterface as ilFileValidationHandlerInterface;
29 use ILIAS\Export\ImportHandler\I\File\Validation\Set\ilCollectionInterface as ilFileValidationSetCollectionInterface;
30 use ILIAS\Export\ImportHandler\I\File\XML\ilHandlerInterface as ilXMLFileHandlerInterface;
32 use ILIAS\Export\ImportHandler\I\File\XSD\ilHandlerInterface as ilXSDFileHandlerInterface;
33 use ILIAS\Export\ImportHandler\I\Parser\ilFactoryInterface as ilParserFactoryInterface;
36 use ILIAS\Export\ImportStatus\I\ilFactoryInterface as ilImportStatusFactoryInterface;
39 use ilLogger;
40 use LibXMLError;
41 
42 class ilHandler implements ilFileValidationHandlerInterface
43 {
44  public const TMP_DIR_NAME = 'temp';
45  public const XML_DIR_NAME = 'xml';
46 
47  protected ilLogger $logger;
48  protected ilImportStatusFactoryInterface $import_status;
49  protected ilParserFactoryInterface $parser;
50  protected ilFilePathFactoryInterface $path;
52 
53  public function __construct(
54  ilLogger $logger,
55  ilParserFactoryInterface $parser,
56  ilImportStatusFactoryInterface $import_status,
57  ilFilePathFactoryInterface $path,
58  ) {
59  $this->logger = $logger;
60  $this->import_status = $import_status;
61  $this->parser = $parser;
62  $this->path = $path;
63  $this->success_status = $import_status->handler()
64  ->withType(StatusType::SUCCESS)
65  ->withContent($import_status->content()->builder()->string()->withString('Validation SUCCESS'));
66  }
67 
71  protected function checkIfFilesExist(array $file_handlers): ilImportStatusHandlerCollectionInterface
72  {
73  $status_collection = $this->import_status->collection()->withNumberingEnabled(true);
74  foreach ($file_handlers as $file_handler) {
75  if($file_handler->fileExists()) {
76  continue;
77  }
78  $status_collection->withAddedStatus($this->import_status->handler()
79  ->withType(StatusType::FAILED)
80  ->withContent($this->import_status->content()->builder()->string()
81  ->withString('File does not exist: ' . $file_handler->getFilePath())));
82  }
83  return $status_collection;
84  }
85 
89  protected function collectErrors(
90  ?ilXMLFileHandlerInterface $xml_file_handler = null,
91  ?ilXSDFileHandlerInterface $xsd_file_handler = null,
92  array $errors = []
94  $status_collection = $this->import_status->collection();
95  foreach ($errors as $error) {
96  $status_collection = $status_collection->getMergedCollectionWith(
97  $this->createErrorMessage($error->message, $xml_file_handler, $xsd_file_handler)
98  );
99  }
100  return $status_collection;
101  }
102 
103  protected function createErrorMessage(
104  string $msg,
105  ?ilXMLFileHandlerInterface $xml_file_handler = null,
106  ?ilXSDFileHandlerInterface $xsd_file_handler = null
108  $status_collection = $this->import_status->collection();
109  $xml_str = is_null($xml_file_handler)
110  ? ''
111  : "<br>XML-File: " . $xml_file_handler->getSubPathToDirBeginningAtPathEnd(self::TMP_DIR_NAME)->getFilePath();
112  $xsd_str = is_null($xsd_file_handler)
113  ? ''
114  : "<br>XSD-File: " . $xsd_file_handler->getSubPathToDirBeginningAtPathEnd(self::XML_DIR_NAME)->getFilePath();
115  $content = $this->import_status->content()->builder()->string()->withString(
116  "Validation FAILED"
117  . $xml_str
118  . $xsd_str
119  . "<br>ERROR Message: " . $msg
120  );
121  $status_collection = $status_collection->withAddedStatus(
122  $this->import_status->handler()->withType(StatusType::FAILED)->withContent($content)
123  );
124  return $status_collection;
125  }
126 
127 
128  protected function validateXMLAtNodes(
129  ilXMLFileHandlerInterface $xml_file_handler,
130  ilXSDFileHandlerInterface $xsd_file_handler,
131  ilXMLFileNodeInfoCollection $nodes
133  // Check if files exist
134  $status_collection = $this->checkIfFilesExist([$xsd_file_handler]);
135  if($status_collection->hasStatusType(StatusType::FAILED)) {
136  return $status_collection;
137  }
138  if(count($nodes) === 0) {
139  return $this->validateEmptyXML($xml_file_handler, $xsd_file_handler);
140  }
141  $old_value = libxml_use_internal_errors(true);
142  $status_collection = $this->import_status->collection()->withNumberingEnabled(true);
143  foreach ($nodes as $node) {
144  $doc = new DOMDocument();
145  $doc->loadXML($node->getXML(), LIBXML_NOBLANKS);
146  $doc->normalizeDocument();
147  foreach ($xml_file_handler->getNamespaces() as $namespace) {
148  $doc->createAttributeNS($namespace->getNamespace(), $namespace->getPrefix());
149  }
150  try {
151  if($doc->schemaValidate($xsd_file_handler->getFilePath())) {
152  continue;
153  }
154  } catch (Exception $e) {
155  // Catches xsd file related exceptions to allow for manual error handling
156  }
157  $errors = libxml_get_errors();
158  libxml_clear_errors();
159  $status_collection = $status_collection->getMergedCollectionWith($this->collectErrors(
160  $xml_file_handler,
161  $xsd_file_handler,
162  $errors
163  ));
164  }
165  libxml_use_internal_errors($old_value);
166  return $status_collection->hasStatusType(StatusType::FAILED)
167  ? $status_collection
168  : $this->import_status->collection()->withAddedStatus($this->success_status);
169  }
170 
171  protected function validateEmptyXML(
172  ilXMLFileHandlerInterface $xml_file_handler,
173  ilXSDFileHandlerInterface $xsd_file_handler
175  $old_value = libxml_use_internal_errors(true);
176  $status_collection = $this->import_status->collection()->withNumberingEnabled(true);
177  $doc = new DOMDocument();
178  $doc->schemaValidate($xsd_file_handler->getFilePath());
179  $errors = libxml_get_errors();
180  libxml_clear_errors();
181  libxml_use_internal_errors($old_value);
182  return $status_collection->getMergedCollectionWith($this->collectErrors(
183  $xml_file_handler,
184  $xsd_file_handler,
185  $errors
186  ));
187  }
188 
189  public function validateXMLFile(
190  ilXMLFileHandlerInterface $xml_file_handler,
191  ilXSDFileHandlerInterface $xsd_file_handler
193  return $this->validateXMLAtPath(
194  $xml_file_handler,
195  $xsd_file_handler,
196  $this->path->handler()->withNode($this->path->node()->anyElement())->withStartAtRoot(true)
197  );
198  }
199 
203  public function validateXMLAtPath(
204  ilXMLFileHandlerInterface $xml_file_handler,
205  ilXSDFileHandlerInterface $xsd_file_handler,
206  ilFilePathHandlerInterface $path_handler
208  return $this->validateXMLAtNodes(
209  $xml_file_handler,
210  $xsd_file_handler,
211  $this->parser->DOM()->withFileHandler($xml_file_handler)->getNodeInfoAt($path_handler)
212  );
213  }
214 
218  public function validateSets(
219  ilFileValidationSetCollectionInterface $sets
221  $status_collection = $this->import_status->collection();
222  foreach ($sets as $set) {
223  $status_collection = $status_collection->getMergedCollectionWith($this->validateXMLAtPath(
224  $set->getXMLFileHandler(),
225  $set->getXSDFileHandler(),
226  $set->getFilePathHandler()
227  ));
228  }
229  return $status_collection;
230  }
231 }
if($err=$client->getError()) $namespace
createErrorMessage(string $msg, ?ilXMLFileHandlerInterface $xml_file_handler=null, ?ilXSDFileHandlerInterface $xsd_file_handler=null)
validateXMLFile(ilXMLFileHandlerInterface $xml_file_handler, ilXSDFileHandlerInterface $xsd_file_handler)
__construct(ilLogger $logger, ilParserFactoryInterface $parser, ilImportStatusFactoryInterface $import_status, ilFilePathFactoryInterface $path,)
validateXMLAtNodes(ilXMLFileHandlerInterface $xml_file_handler, ilXSDFileHandlerInterface $xsd_file_handler, ilXMLFileNodeInfoCollection $nodes)
collectErrors(?ilXMLFileHandlerInterface $xml_file_handler=null, ?ilXSDFileHandlerInterface $xsd_file_handler=null, array $errors=[])
validateEmptyXML(ilXMLFileHandlerInterface $xml_file_handler, ilXSDFileHandlerInterface $xsd_file_handler)
validateXMLAtPath(ilXMLFileHandlerInterface $xml_file_handler, ilXSDFileHandlerInterface $xsd_file_handler, ilFilePathHandlerInterface $path_handler)
ilErrorHandling $error
Definition: class.ilias.php:55
validateSets(ilFileValidationSetCollectionInterface $sets)