From 4065332b92de0477de88e506c7afc456a2410ef0 Mon Sep 17 00:00:00 2001 From: liquetsoft Date: Fri, 25 Oct 2024 19:25:45 +0200 Subject: [PATCH 1/2] Refactor BaseXmlReader --- src/XmlReader/BaseXmlReader.php | 62 +++++++++++++++------------------ 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/src/XmlReader/BaseXmlReader.php b/src/XmlReader/BaseXmlReader.php index df38411a..370459ac 100644 --- a/src/XmlReader/BaseXmlReader.php +++ b/src/XmlReader/BaseXmlReader.php @@ -10,37 +10,40 @@ /** * Объект, который читает данные из xml файла с помощью XmlReader. */ -class BaseXmlReader implements XmlReaderInterface +final class BaseXmlReader implements XmlReaderInterface { + private const XML_READER_CHARSET = 'UTF-8'; + private const XML_READER_PARAMS = \LIBXML_COMPACT | \LIBXML_NONET | \LIBXML_NOBLANKS; + /** * Файл, который открыт в данный момент. */ - protected ?\SplFileInfo $file = null; + private ?\SplFileInfo $file = null; /** * Xpath, по которому следует искать данные. */ - protected string $xpath = ''; + private string $xpath = ''; /** * Объект XMLReader для чтения документа. */ - protected ?\XMLReader $reader = null; + private ?\XMLReader $reader = null; /** * Текущее смещение внутри массива. */ - protected int $position = 0; + private int $position = 0; /** * Флаг, который указывает, что данные были прочитаны в буфер. */ - protected bool $isBufferFull = false; + private bool $isBufferFull = false; /** * Массив с буфером, для isValid и current. */ - protected ?string $buffer = null; + private ?string $buffer = null; /** * {@inheritdoc} @@ -48,9 +51,7 @@ class BaseXmlReader implements XmlReaderInterface public function open(\SplFileInfo $file, string $xpath): bool { if (!$file->isFile() || !$file->isReadable()) { - throw new XmlException( - "File '" . $file->getPathname() . "' isn't readable or doesn't exist" - ); + throw XmlException::create("File '%s' isn't readable or doesn't exist", $file->getPathname()); } $this->file = $file; @@ -132,26 +133,16 @@ public function valid(): bool return $this->buffer !== null; } - /** - * Деструктор. - * - * Закрывает файл, если он все еще открыт. - */ - public function __destruct() - { - $this->close(); - } - /** * Возвращает строку из файла, соответствующую элементу, или null, если разбор * файла завершен. * * @throws XmlException */ - protected function getLine(): ?string + private function getLine(): ?string { if (!$this->reader) { - throw new XmlException('Reader and xpath must be set before reading'); + throw XmlException::create('Reader and xpath must be set before reading'); } $return = null; @@ -170,9 +161,9 @@ protected function getLine(): ?string $this->reader->next(); } } catch (\Throwable $e) { - $fileName = $this->file ? $this->file->getPathname() : ''; - $message = "Error while parsing xml '{$fileName}' by '{$this->xpath}' path."; - throw new XmlException($message, 0, $e); + $fileName = $this->file?->getPathname() ?? ''; + $message = "Error while parsing xml '{$fileName}' by '{$this->xpath}' path"; + throw new XmlException(message: $message, previous: $e); } return $return; @@ -182,7 +173,7 @@ protected function getLine(): ?string * Пропускает все xml элементы в текущем ридере, у которых имя или вложенность * не совпадают с указанным параметром. */ - protected function skipUselessXml(string $nodeName, int $nodeDepth): void + private function skipUselessXml(string $nodeName, int $nodeDepth): void { while ( $this->reader @@ -207,7 +198,7 @@ protected function skipUselessXml(string $nodeName, int $nodeDepth): void * * @throws XmlException */ - protected function seekXmlPath(): bool + private function seekXmlPath(): bool { $reader = $this->resetReader(); @@ -238,19 +229,22 @@ protected function seekXmlPath(): bool * * @throws XmlException */ - protected function resetReader(): \XMLReader + private function resetReader(): \XMLReader { if (!$this->file || !$this->xpath) { - throw new XmlException("File doesn't open."); + throw XmlException::create("File doesn't open"); } $this->unsetReader(); $this->reader = new \XMLReader(); - if ($this->reader->open($this->file->getPathname(), 'UTF-8', \LIBXML_COMPACT | \LIBXML_NONET | \LIBXML_NOBLANKS) === false) { - throw new XmlException( - "Can't open file '" . $this->file->getPathname() . "' for reading." - ); + $res = $this->reader->open( + $this->file->getPathname(), + self::XML_READER_CHARSET, + self::XML_READER_PARAMS + ); + if ($res === false) { + throw XmlException::create("Can't open file '%s' for reading", $this->file->getPathname()); } return $this->reader; @@ -259,7 +253,7 @@ protected function resetReader(): \XMLReader /** * Закрывает открытые ресурсы и сбрасывает все внутренние счетчики. */ - protected function unsetReader(): void + private function unsetReader(): void { if ($this->reader) { $this->reader->close(); From 18888a79bba0df151d0c61a06de4981cdd53f171 Mon Sep 17 00:00:00 2001 From: liquetsoft Date: Fri, 25 Oct 2024 19:51:43 +0200 Subject: [PATCH 2/2] XmlEncoder::TYPE_CAST_ATTRIBUTES --- src/Serializer/FiasSerializer.php | 6 +++++- tests/src/Serializer/FiasSerializerTest.php | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Serializer/FiasSerializer.php b/src/Serializer/FiasSerializer.php index 90ed0998..6440fbd8 100644 --- a/src/Serializer/FiasSerializer.php +++ b/src/Serializer/FiasSerializer.php @@ -51,7 +51,11 @@ public function __construct(?array $normalizers = null, ?array $encoders = null) if ($encoders === null) { $encoders = [ - new XmlEncoder(), + new XmlEncoder( + [ + XmlEncoder::TYPE_CAST_ATTRIBUTES => false, + ] + ), ]; } diff --git a/tests/src/Serializer/FiasSerializerTest.php b/tests/src/Serializer/FiasSerializerTest.php index 62ca6fe3..0e12806f 100644 --- a/tests/src/Serializer/FiasSerializerTest.php +++ b/tests/src/Serializer/FiasSerializerTest.php @@ -26,7 +26,7 @@ public function testDenormalize(): void ACTSTATID="2" NAME="Не актуальный" TESTDATE="2019-10-10T10:10:10.02" - KOD_T_ST="10" + KOD_T_ST="227010000010000016740025000000000" EMPTYSTRINGINT="" /> EOT; @@ -41,7 +41,7 @@ public function testDenormalize(): void $this->assertInstanceOf(FiasSerializerMock::class, $object); $this->assertSame(2, $object->getActstatid()); $this->assertSame('Не актуальный', $object->getName()); - $this->assertSame('10', $object->getKodtst()); + $this->assertSame('227010000010000016740025000000000', $object->getKodtst()); $this->assertSame(0, $object->getEmptyStringInt()); $date = $object->getTestDate();