. */ namespace SP\Domain\Import\Services; use DOMDocument; use SP\Domain\File\Ports\FileHandlerInterface; use SP\Domain\Import\Ports\XmlFileService; use SP\Infrastructure\File\FileException; use ValueError; use function SP\__u; use function SP\logger; /** * Class XmlFile */ final readonly class XmlFile implements XmlFileService { private DOMDocument $document; public function __construct() { $this->createDocument(); } /** * @return void */ private function createDocument(): void { $this->document = new DOMDocument(); $this->document->formatOutput = false; $this->document->preserveWhiteSpace = false; } /** * @throws ImportException * @throws FileException */ public function builder(FileHandlerInterface $fileHandler): XmlFileService { $fileHandler->checkIsReadable(); $self = new self(); $self->readXMLFile($fileHandler->getFile()); return $self; } /** * Leer el archivo a un objeto XML. * * @throws ImportException */ protected function readXMLFile(string $file): void { libxml_use_internal_errors(true); if ($this->document->load($file, LIBXML_PARSEHUGE) === false) { foreach (libxml_get_errors() as $error) { logger(__METHOD__ . ' - ' . $error->message); } throw ImportException::error(__u('Internal error'), __u('Unable to process the XML file')); } } /** * Detectar la aplicación que generó el XML. * * @throws ImportException */ public function detectFormat(): XmlFormat { $nodes = $this->document->getElementsByTagName('Generator'); try { return XmlFormat::from(strtolower($nodes->item(0)?->nodeValue ?? '')); } catch (ValueError $e) { throw ImportException::error( __u('XML file not supported'), __u('Unable to guess the application which data was exported from'), $e->getCode() ); } } public function getDocument(): DOMDocument { return $this->document; } }