Skip to content
Snippets Groups Projects
Commit 0ef8c357 authored by Jan Kuchař's avatar Jan Kuchař
Browse files

Merge branch 'single-namespace-mapper' into 'master'

introducing single namespace mapper

See merge request grifart-internal/stateful!6
parents 76989a2b 699db984
No related branches found
Tags 0.2.2
1 merge request!6introducing single namespace mapper
Pipeline #11735 passed
<?php declare(strict_types=1);
namespace Grifart\Stateful\Mapper;
use Grifart\Stateful\Exceptions\MapperException;
final class SingleNamespaceMapper implements Mapper
{
/** @var string */
private $transferPrefix;
/** @var string */
private $phpNamespaceSeparator = '\\';
/** @var string */
private $namespaceForMapping;
public function __construct(string $namespaceForMapping, string $transferPrefix)
{
$this->transferPrefix = $transferPrefix;
$this->namespaceForMapping = $namespaceForMapping;
}
/**
* Converts fully qualified class name to name that is used for serialization.
*
* @param string $fullyQualifiedName
* @return string
*/
public function toTransferName(string $fullyQualifiedName): ?string
{
// https://regex101.com/r/IWD9wD/4
if (!\preg_match('#^(|(.*?)\\\\)([^\\\\]*)$#', $fullyQualifiedName, $matches)) {
throw MapperException::invalidClassNameGiven($fullyQualifiedName);
}
$namespace = $matches[2] ?? ''; // because 2nd matching group can be skipped when there is no namespace
$className = $matches[3];
if ($className === '') {
throw MapperException::fullyQualifiedNameCannotEndWithNamespaceSeparator($fullyQualifiedName);
}
if ($namespace !== $this->namespaceForMapping) {
return NULL;
}
return $this->transferPrefix . $className;
}
/**
* Converts serialization name to fully qualified.
*
* @param string $transferName
* @return string
*/
public function toFullyQualifiedName(string $transferName): ?string
{
if(!$this->startsWith($transferName, $this->transferPrefix)) {
return NULL;
}
$rest = substr($transferName, strlen($this->transferPrefix));
// regexp is from: http://php.net/manual/en/language.oop5.basic.php
$classNameValid = \preg_match('#^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$#', $rest) === 1;
$fqn = $this->namespaceForMapping . $this->phpNamespaceSeparator . $rest;
return $classNameValid ? $fqn : null;
}
private function startsWith(string $string, string $query): bool
{
return $query === '' || strpos($string, $query) === 0;
}
}
......@@ -199,6 +199,11 @@ final class MapperException extends UsageException {
{
return new self('Namespace separator must have one character only.');
}
public static function invalidClassNameGiven(string $className): self
{
return new self("Invalid class name given '$className'.");
}
}
final class ExternalSerializerException extends UsageException {
......
<?php declare(strict_types=1);
namespace Grifart\TaxLibrary\Resolve\Infrastructure\Payload\Mapper;
use Grifart\Stateful\Exceptions\MapperException;
use Grifart\Stateful\Mapper\SimpleMapper;
use Grifart\Stateful\Mapper\SingleNamespaceMapper;
use Tester\Assert;
require __DIR__ . '/../../bootstrap.php';
$mapper = new SingleNamespaceMapper('MyApp\\Model\\Domain\\Events', 'Events.');
// To transfer name
Assert::null( $mapper->toTransferName('unknown-prefix') );
Assert::null( $mapper->toTransferName('unknown-prefix\\MyApp\\Model\\Domain\\Events') );
Assert::null( $mapper->toTransferName('MyApp\\Model\\Domain\\Events') );
Assert::exception(
function () use ($mapper) {
$mapper->toTransferName('MyApp\\Model\\Domain\\Events\\');
},
MapperException::class,
"Fully qualified name cannot end with namespace separator. 'MyApp\\Model\\Domain\\Events\\' given"
);
Assert::same( 'Events.Bla', $mapper->toTransferName('MyApp\\Model\\Domain\\Events\\Bla') );
Assert::null( $mapper->toTransferName('MyApp\\Model\\Domain\\Events\\Bla\\Bla') );
Assert::null(
$mapper->toTransferName('MyApp\\Model\\Domain\\Events\\MyApp\\Model\\Domain\\Events')
);
Assert::exception(
function () use ($mapper) {
$mapper->toTransferName('MyApp\\Model\\Domain\\Events\\MyApp\\Model\\Domain\\Events\\');
},
MapperException::class,
"Fully qualified name cannot end with namespace separator. 'MyApp\\Model\\Domain\\Events\\MyApp\\Model\\Domain\\Events\\' given"
);
Assert::null( $mapper->toTransferName('MyApp\\Model\\Domain\\EventsMigrator') );
// to qualified name
Assert::null($mapper->toFullyQualifiedName('Bla'));
Assert::null($mapper->toFullyQualifiedName('transfer.My.Class'));
Assert::null($mapper->toFullyQualifiedName('transferNamespace'));
Assert::null(
$mapper->toFullyQualifiedName('Events.My.Class')
);
Assert::same(
'MyApp\\Model\\Domain\\Events\\Events',
$mapper->toFullyQualifiedName('Events.Events')
);
Assert::null( $mapper->toFullyQualifiedName('EventsMigrator') );
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment