-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Blueprint building #6
base: master
Are you sure you want to change the base?
Changes from 31 commits
9bad536
1c0f4b2
985eb59
8e4bbb6
d1957bc
8326c72
e6941b0
aa5c23e
580d2fa
ab165fe
f423631
20b5e32
b9b3db2
ff97ad3
ca15bfe
83d4fbe
7e414c4
a8a5991
45d5461
9babfeb
d22d289
c11de98
5c22a4a
4049d30
94a9f37
9b48cf4
4e152a3
bfb49a7
30589be
029d3cc
73aa8d2
48f08e6
ce5f444
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,7 @@ | ||
composer.lock | ||
vendor | ||
vendor | ||
.idea | ||
.php_cs.cache | ||
.phpcs.cache | ||
data | ||
test/result |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
parameters: | ||
tmpDir: data/cache/phpstan-test | ||
includes: | ||
- vendor/phpstan/phpstan-phpunit/extension.neon | ||
- vendor/phpstan/phpstan-phpunit/rules.neon | ||
- vendor/phpstan/phpstan-strict-rules/rules.neon |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
includes: | ||
- vendor/phpstan/phpstan-strict-rules/rules.neon | ||
parameters: | ||
tmpDir: data/cache/phpstan |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?xml version="1.0"?> | ||
<ruleset name="ObjectBuilder"> | ||
<rule ref="PSR2"/> | ||
<rule ref="vendor/slevomat/coding-standard/SlevomatCodingStandard/ruleset.xml"> | ||
<exclude name="SlevomatCodingStandard.Classes.UnusedPrivateElements"/> | ||
<exclude name="SlevomatCodingStandard.Commenting.DisallowOneLinePropertyDocComment"/> | ||
<exclude name="SlevomatCodingStandard.ControlStructures.DisallowYodaComparison"/> | ||
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation"/> | ||
<exclude name="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly"/> | ||
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalFunctions"/> | ||
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions"/> | ||
<exclude name="SlevomatCodingStandard.Namespaces.UseOnlyWhitelistedNamespaces"/> | ||
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingPropertyTypeHint"/> | ||
<exclude name="SlevomatCodingStandard.Operators.DisallowIncrementAndDecrementOperators"/> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName"> | ||
<properties> | ||
<property name="rootNamespaces" type="array" value=" | ||
src=>RstGroup\ObjectBuilder, | ||
test=>RstGroup\ObjectBuilder\Test, | ||
"/> | ||
</properties> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Types.EmptyLinesAroundTypeBraces"> | ||
<properties> | ||
<property name="linesCountAfterOpeningBrace" type="int" value="0"/> | ||
<property name="linesCountBeforeClosingBrace" type="int" value="0"/> | ||
</properties> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Commenting.ForbiddenAnnotations"> | ||
<properties> | ||
<property name="forbiddenAnnotations" type="array" value="@author,@created,@version,@package,@copyright,@license" /> | ||
</properties> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration"> | ||
<properties> | ||
<property name="allAnnotationsAreUseful" type="boolean" value="true" /> | ||
</properties> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses"> | ||
<properties> | ||
<property name="searchAnnotations" type="boolean" value="true" /> | ||
</properties> | ||
</rule> | ||
</ruleset> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
<?php declare(strict_types=1); | ||
<?php declare(strict_types = 1); | ||
|
||
namespace RstGroup\ObjectBuilder; | ||
|
||
interface Builder | ||
{ | ||
/** @param mixed[] $data */ | ||
public function build(string $class, array $data): object; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace RstGroup\ObjectBuilder\Builder; | ||
|
||
use RstGroup\ObjectBuilder\Builder; | ||
|
||
final class Blueprint implements Builder | ||
{ | ||
/** @var Builder\Blueprint\Factory */ | ||
private $blueprintFactory; | ||
/** @var ParameterNameStrategy */ | ||
private $strategy; | ||
|
||
/** @codeCoverageIgnore */ | ||
public function __construct( | ||
Builder\Blueprint\Factory $factory, | ||
ParameterNameStrategy $strategy | ||
) { | ||
$this->blueprintFactory = $factory; | ||
$this->strategy = $strategy; | ||
} | ||
|
||
/** @param mixed[] $data */ | ||
public function build(string $class, array $data): object | ||
{ | ||
$blueprint = $this->blueprintFactory->create($class); | ||
|
||
$preparedData = $this->prepareData($data); | ||
|
||
return $blueprint($preparedData); | ||
} | ||
|
||
/** | ||
* @param mixed[] $data | ||
* @return mixed[] | ||
*/ | ||
private function prepareData(array $data): array | ||
{ | ||
$preparedData = []; | ||
|
||
foreach ($data as $key => $value) { | ||
if (is_array($value)) { | ||
$value = $this->prepareData($value); | ||
} | ||
|
||
if (!is_int($key)) { | ||
$key = $this->strategy->getName($key); | ||
} | ||
|
||
$preparedData[$key] = $value; | ||
} | ||
|
||
return $preparedData; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace RstGroup\ObjectBuilder\Builder\Blueprint; | ||
|
||
interface Factory | ||
{ | ||
public function create(string $class): callable; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace RstGroup\ObjectBuilder\Builder\Blueprint\Factory; | ||
|
||
use RstGroup\ObjectBuilder\Builder\Blueprint\Factory; | ||
use RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator\PatternGenerator; | ||
|
||
final class CodeGenerator implements Factory | ||
{ | ||
/** @var PatternGenerator */ | ||
private $generator; | ||
|
||
/** @codeCoverageIgnore */ | ||
public function __construct(PatternGenerator $generator) | ||
{ | ||
$this->generator = $generator; | ||
} | ||
|
||
public function create(string $class): callable | ||
{ | ||
$pattern = $this->generator->create($class); | ||
|
||
return eval($pattern); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should check this value before return to avoid typeerror |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator; | ||
|
||
abstract class Node | ||
{ | ||
/** @var string */ | ||
protected $name; | ||
/** @var mixed|null */ | ||
private $defaultValue; | ||
/** @var string */ | ||
private $type; | ||
/** @var bool */ | ||
private $nullable; | ||
|
||
/** @param mixed $defaultValue */ | ||
public function __construct(string $type, string $name, bool $nullable = false, $defaultValue = null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO it's better to expects all parameters |
||
{ | ||
$this->name = $name; | ||
$this->defaultValue = $defaultValue; | ||
$this->type = $type; | ||
$this->nullable = $nullable; | ||
} | ||
|
||
public function type(): string | ||
{ | ||
return $this->type; | ||
} | ||
|
||
public function name(): string | ||
{ | ||
return $this->name; | ||
} | ||
|
||
public function withDefaultValue(): bool | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like method which changes immutable object. hasDefaultValue? |
||
{ | ||
return null !== $this->defaultValue; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Null it's still value |
||
} | ||
|
||
public function nullable(): bool | ||
{ | ||
return $this->nullable; | ||
} | ||
|
||
/** @return mixed */ | ||
public function defaultValue() | ||
{ | ||
return $this->defaultValue; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator\Node; | ||
|
||
use RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator\Node; | ||
|
||
final class Complex extends Node | ||
{ | ||
/** @var Node[] */ | ||
private $nodes = []; | ||
|
||
public function add(Node $node): void | ||
{ | ||
$this->nodes[] = $node; | ||
} | ||
|
||
/** @return Node[] */ | ||
public function innerNodes(): iterable | ||
{ | ||
return $this->nodes; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator\Node; | ||
|
||
use RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator\Node; | ||
|
||
final class ObjectList extends Node | ||
{ | ||
/** @var Node */ | ||
private $objectNode; | ||
|
||
public function __construct(string $name, Node $objectNode) | ||
{ | ||
parent::__construct($objectNode->type(), $name); | ||
$this->objectNode = $objectNode; | ||
} | ||
|
||
public function objectNode(): Node | ||
{ | ||
return $this->objectNode; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator\Node; | ||
|
||
use RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator\Node; | ||
|
||
final class Scalar extends Node | ||
{ | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator\Node; | ||
|
||
use RstGroup\ObjectBuilder\Builder\Blueprint\Factory\CodeGenerator\Node; | ||
|
||
interface Serializer | ||
{ | ||
public function serialize(Node $node): string; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Key can any, not only int or string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The key can either be an integer or a string. The value can be of any type.
Other types are casted underlying to string or int.