Skip to content

Commit

Permalink
Serializer format check (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
marvin255 authored Sep 30, 2024
1 parent 47ce5bf commit 85a5c3d
Show file tree
Hide file tree
Showing 14 changed files with 283 additions and 93 deletions.
4 changes: 1 addition & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@
"ext-xmlreader": "*",
"ext-zip": "*",
"ext-json": "*",
"ext-curl": "*",
"symfony/serializer": "^5.0|^6.0|^7.0",
"symfony/property-access": "^5.0|^6.0|^7.0",
"symfony/property-info": "^5.0|^6.0|^7.0",
"psr/log": "^1.1|^2.0|^3.0",
"ramsey/uuid": "^3.0|^4.0",
"symfony/process": "^5.0|^6.0|^7.0",
"psr/log": "^1.0|^2.0|^3.0",
"marvin255/file-system-helper": "^1.1"
},
"require-dev": {
Expand Down
25 changes: 25 additions & 0 deletions src/Helper/IdHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Liquetsoft\Fias\Component\Helper;

/**
* Класс, который содержит функции для генерации уникальных идентификаторов.
*/
final class IdHelper
{
private const RANDOM_BYTE_SIZE = 30;

private function __construct()
{
}

/**
* Создает строку, содержащую уникальны идентификатор.
*/
public static function createUniqueId(): string
{
return md5(time() . random_bytes(self::RANDOM_BYTE_SIZE));
}
}
4 changes: 2 additions & 2 deletions src/Pipeline/Pipe/ArrayPipe.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
namespace Liquetsoft\Fias\Component\Pipeline\Pipe;

use Liquetsoft\Fias\Component\Exception\PipeException;
use Liquetsoft\Fias\Component\Helper\IdHelper;
use Liquetsoft\Fias\Component\Pipeline\State\State;
use Liquetsoft\Fias\Component\Pipeline\Task\LoggableTask;
use Liquetsoft\Fias\Component\Pipeline\Task\Task;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Ramsey\Uuid\Uuid;

/**
* Объект, который содержит внутренний массив со списком операций для исполнения.
Expand Down Expand Up @@ -38,7 +38,7 @@ final class ArrayPipe implements Pipe
*/
public function __construct(iterable $tasks, ?Task $cleanupTask = null, ?LoggerInterface $logger = null)
{
$this->id = Uuid::uuid4()->toString();
$this->id = IdHelper::createUniqueId();
$this->tasks = $this->checkAndReturnTaskArray($tasks);
$this->cleanupTask = $cleanupTask;
$this->logger = $logger;
Expand Down
46 changes: 26 additions & 20 deletions src/Pipeline/Task/DataAbstractTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,28 @@
use Liquetsoft\Fias\Component\Exception\XmlException;
use Liquetsoft\Fias\Component\Pipeline\State\State;
use Liquetsoft\Fias\Component\Pipeline\State\StateParameter;
use Liquetsoft\Fias\Component\Serializer\FiasSerializerContextParam;
use Liquetsoft\Fias\Component\Serializer\FiasSerializerFormat;
use Liquetsoft\Fias\Component\Storage\Storage;
use Liquetsoft\Fias\Component\XmlReader\XmlReader;
use Psr\Log\LogLevel;
use Symfony\Component\Serializer\SerializerInterface;

/**
* Абстрактная задача, которая переносит данные из xml в хранилище данных.
*
* @internal
*/
abstract class DataAbstractTask implements LoggableTask, Task
{
use LoggableTaskTrait;

protected EntityManager $entityManager;

protected XmlReader $xmlReader;

protected Storage $storage;

protected SerializerInterface $serializer;

public function __construct(EntityManager $entityManager, XmlReader $xmlReader, Storage $storage, SerializerInterface $serializer)
{
$this->entityManager = $entityManager;
$this->xmlReader = $xmlReader;
$this->storage = $storage;
$this->serializer = $serializer;
public function __construct(
protected readonly EntityManager $entityManager,
protected readonly XmlReader $xmlReader,
protected readonly Storage $storage,
protected readonly SerializerInterface $serializer,
) {
}

/**
Expand Down Expand Up @@ -92,7 +88,7 @@ protected function processDataFromFile(\SplFileInfo $fileInfo, string $xpath, st
{
$this->log(
LogLevel::INFO,
"Start processing '{$fileInfo->getRealPath()}' file for '{$entityClass}' entity.",
"Start processing '{$fileInfo->getRealPath()}' file for '{$entityClass}' entity",
[
'entity' => $entityClass,
'path' => $fileInfo->getRealPath(),
Expand All @@ -119,7 +115,7 @@ protected function processDataFromFile(\SplFileInfo $fileInfo, string $xpath, st

$this->log(
LogLevel::INFO,
"Complete processing '{$fileInfo->getRealPath()}' file for '{$entityClass}' entity. {$total} items processed.",
"Completed processing '{$fileInfo->getRealPath()}' file for '{$entityClass}' entity. {$total} items processed",
[
'entity' => $entityClass,
'path' => $fileInfo->getRealPath(),
Expand All @@ -135,14 +131,24 @@ protected function processDataFromFile(\SplFileInfo $fileInfo, string $xpath, st
protected function deserializeXmlStringToObject(?string $xml, string $entityClass): object
{
try {
$entity = $this->serializer->deserialize($xml, $entityClass, 'xml');
$entity = $this->serializer->deserialize(
$xml,
$entityClass,
FiasSerializerFormat::XML->value,
[
FiasSerializerContextParam::FIAS_FLAG->value => true,
FiasSerializerContextParam::FIAS_ENTITY->value => $entityClass,
]
);
} catch (\Throwable $e) {
$message = "Deserialization error while deserialization of '{$xml}' string to object with '{$entityClass}' class.";
throw new TaskException($message, 0, $e);
throw new TaskException(
message: "Deserialization error while deserialization of '{$xml}' string to object with '{$entityClass}' class",
previous: $e
);
}

if (!\is_object($entity)) {
throw new TaskException('Serializer must returns an object instance.');
throw new TaskException('Serializer must returns an object instance');
}

return $entity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Денормалайзер, который фильтрует пустые строки и передает оставшиеся для дальнейшей обработки.
*/
final class FilterEmptyStringsDenormalizer implements DenormalizerAwareInterface, DenormalizerInterface
final class FiasFilterEmptyStringsDenormalizer implements DenormalizerAwareInterface, DenormalizerInterface
{
private ?DenormalizerInterface $denormalizer = null;

Expand All @@ -27,7 +27,7 @@ public function setDenormalizer(DenormalizerInterface $denormalizer): void
*/
public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): mixed
{
if ($this->isXML($format) && \is_array($data)) {
if (FiasSerializerFormat::XML->isEqual($format) && \is_array($data)) {
$filteredData = [];
foreach ($data as $key => $value) {
if ($value !== '') {
Expand All @@ -38,7 +38,7 @@ public function denormalize(mixed $data, string $type, ?string $format = null, a
$filteredData = $data;
}

if ($this->denormalizer) {
if ($this->denormalizer !== null) {
return $this->denormalizer->denormalize($filteredData, $type, $format, $context);
} else {
return $filteredData;
Expand All @@ -50,7 +50,7 @@ public function denormalize(mixed $data, string $type, ?string $format = null, a
*/
public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool
{
if ($this->isXML($format) && \is_array($data)) {
if (FiasSerializerFormat::XML->isEqual($format) && \is_array($data)) {
foreach ($data as $value) {
if ($value === '') {
return true;
Expand All @@ -66,20 +66,12 @@ public function supportsDenormalization(mixed $data, string $type, ?string $form
*/
public function getSupportedTypes(?string $format): array
{
if ($this->isXML($format)) {
if (FiasSerializerFormat::XML->isEqual($format)) {
return [
'*' => true,
'*' => false,
];
}

return [];
}

/**
* Возвращает правду, если указанный формат - XML.
*/
private function isXML(mixed $format): bool
{
return \is_string($format) && strtolower(trim($format)) === 'xml';
}
}
30 changes: 20 additions & 10 deletions src/Serializer/FiasNameConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,37 @@
*/
class FiasNameConverter implements NameConverterInterface
{
public function normalize(string $propertyName): string
/**
* {@inheritdoc}
*/
public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
{
$propertyName = trim($propertyName);
$return = $propertyName;
if (!FiasSerializerFormat::XML->isEqual($format)) {
return $propertyName;
}

$propertyName = trim($propertyName);
if (strpos($propertyName, '@') !== 0) {
$return = '@' . $propertyName;
return '@' . $propertyName;
}

return $return;
return $propertyName;
}

public function denormalize(string $propertyName): string
/**
* {@inheritdoc}
*/
public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
{
$propertyName = trim($propertyName);
$return = $propertyName;
if (!FiasSerializerFormat::XML->isEqual($format)) {
return $propertyName;
}

$propertyName = trim($propertyName);
if (strpos($propertyName, '@') === 0) {
$return = substr($propertyName, 1);
return substr($propertyName, 1);
}

return $return;
return $propertyName;
}
}
2 changes: 1 addition & 1 deletion src/Serializer/FiasSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function __construct(?array $normalizers = null, ?array $encoders = null)
];
}

array_unshift($normalizers, new FilterEmptyStringsDenormalizer());
array_unshift($normalizers, new FiasFilterEmptyStringsDenormalizer());

if ($encoders === null) {
$encoders = [
Expand Down
14 changes: 14 additions & 0 deletions src/Serializer/FiasSerializerContextParam.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Liquetsoft\Fias\Component\Serializer;

/**
* Список параметров контекста, которые поддерживает сериализатор.
*/
enum FiasSerializerContextParam: string
{
case FIAS_FLAG = 'is_fias';
case FIAS_ENTITY = 'fias_entity';
}
22 changes: 22 additions & 0 deletions src/Serializer/FiasSerializerFormat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Liquetsoft\Fias\Component\Serializer;

/**
* Список форматов, которые поддерживает сериализатор.
*/
enum FiasSerializerFormat: string
{
case XML = 'xml';
case TEST = 'test';

/**
* Проверяет, что указанная строка совпадает с текущим форматом.
*/
public function isEqual(mixed $format): bool
{
return \is_string($format) && strtolower(trim($format)) === $this->value;
}
}
26 changes: 26 additions & 0 deletions tests/src/Helper/IdHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Liquetsoft\Fias\Component\Tests\Helper;

use Liquetsoft\Fias\Component\Helper\IdHelper;
use Liquetsoft\Fias\Component\Tests\BaseCase;

/**
* Тест для класса, который содержит методы для генерации уникальных идентификаторов.
*
* @internal
*/
class IdHelperTest extends BaseCase
{
/**
* Проверяет, что метод вернет уникальный идентификатор.
*/
public function testCreateUniqueId(): void
{
$id = IdHelper::createUniqueId();

$this->assertSame(32, \strlen($id));
}
}
Loading

0 comments on commit 85a5c3d

Please sign in to comment.