Skip to content

Commit f606e32

Browse files
authored
Merge pull request #14 from event-engine/feature/special-key
Add special key support e. g. snake_case
2 parents 7fbb831 + 15bed07 commit f606e32

22 files changed

+1370
-33
lines changed

.coveralls.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# for php-coveralls
2+
service_name: travis-ci
3+
coverage_clover: build/logs/clover.xml

.travis.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
language: php
2+
3+
matrix:
4+
fast_finish: true
5+
include:
6+
- php: 7.2
7+
env:
8+
- DEPENDENCIES=""
9+
- php: 7.3
10+
env:
11+
- DEPENDENCIES=""
12+
- EXECUTE_CS_CHECK=true
13+
- php: 7.4
14+
env:
15+
- DEPENDENCIES=""
16+
- TEST_COVERAGE=true
17+
18+
cache:
19+
directories:
20+
- $HOME/.composer/cache
21+
- $HOME/.php-cs-fixer
22+
- $HOME/.local
23+
24+
before_script:
25+
- mkdir -p "$HOME/.php-cs-fixer"
26+
- phpenv config-rm xdebug.ini
27+
- composer self-update
28+
- composer update --prefer-source $DEPENDENCIES
29+
30+
script:
31+
- if [[ $TEST_COVERAGE == 'true' ]]; then php -dzend_extension=xdebug.so ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml; else ./vendor/bin/phpunit; fi
32+
- if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/php-cs-fixer fix src -v --diff --dry-run; fi
33+
- if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/docheader check examples/ src/ tests/; fi
34+
35+
after_success:
36+
- if [[ $TEST_COVERAGE == 'true' ]]; then php ./vendor/bin/php-coveralls -v; fi
37+
38+
notifications:
39+
webhooks:
40+
urls:
41+
- https://webhooks.gitter.im/e/61c75218816eebde4486
42+
on_success: change # options: [always|never|change] default: always
43+
on_failure: always # options: [always|never|change] default: always
44+
on_start: never # options: [always|never|change] default: always

src/DataConverter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
2+
23
/**
34
* This file is part of event-engine/php-data.
4-
* (c) 2018-2019 prooph software GmbH <contact@prooph.de>
5+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
56
*
67
* For the full copyright and license information, please view the LICENSE
78
* file that was distributed with this source code.

src/ImmutableRecord.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
2+
23
/**
34
* This file is part of event-engine/php-data.
4-
* (c) 2018-2019 prooph software GmbH <contact@prooph.de>
5+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
56
*
67
* For the full copyright and license information, please view the LICENSE
78
* file that was distributed with this source code.

src/ImmutableRecordDataConverter.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
2+
23
/**
34
* This file is part of event-engine/php-data.
4-
* (c) 2018-2019 prooph software GmbH <contact@prooph.de>
5+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
56
*
67
* For the full copyright and license information, please view the LICENSE
78
* file that was distributed with this source code.
@@ -26,7 +27,7 @@ public function convertDataToArray(string $type, $data): array
2627
return $data;
2728
}
2829

29-
if ($data instanceof ImmutableRecord || is_callable([$data, 'toArray'])) {
30+
if ($data instanceof ImmutableRecord || \is_callable([$data, 'toArray'])) {
3031
return $data->toArray();
3132
}
3233

@@ -37,11 +38,11 @@ public function canConvertTypeToData(string $type): bool
3738
{
3839
$class = $this->getClassOfType($type);
3940

40-
if(!class_exists($class)) {
41+
if (! \class_exists($class)) {
4142
return false;
4243
}
4344

44-
return is_callable([$class, 'fromArray']);
45+
return \is_callable([$class, 'fromArray']);
4546
}
4647

4748
public function convertArrayToData(string $type, array $data)

src/ImmutableRecordLogic.php

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
2+
23
/**
34
* This file is part of event-engine/php-data.
4-
* (c) 2018-2019 prooph software GmbH <contact@prooph.de>
5+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
56
*
67
* For the full copyright and license information, please view the LICENSE
78
* file that was distributed with this source code.
@@ -36,7 +37,7 @@ private function init(): void
3637
* @param array $recordData
3738
* @return self
3839
*/
39-
public static function fromRecordData(array $recordData)
40+
public static function fromRecordData(array $recordData): self
4041
{
4142
return new self($recordData);
4243
}
@@ -45,7 +46,7 @@ public static function fromRecordData(array $recordData)
4546
* @param array $nativeData
4647
* @return self
4748
*/
48-
public static function fromArray(array $nativeData)
49+
public static function fromArray(array $nativeData): self
4950
{
5051
return new self(null, $nativeData);
5152
}
@@ -73,7 +74,7 @@ private function __construct(array $recordData = null, array $nativeData = null)
7374
* @param array $recordData
7475
* @return self
7576
*/
76-
public function with(array $recordData)
77+
public function with(array $recordData): self
7778
{
7879
$copy = clone $this;
7980
$copy->setRecordData($recordData);
@@ -87,31 +88,37 @@ public function toArray(): array
8788
$arrayPropItemTypeMap = self::getArrayPropItemTypeMapFromMethodOrCache();
8889

8990
foreach (self::$__propTypeMap as $key => [$type, $isNative, $isNullable]) {
91+
$specialKey = $key;
92+
93+
if ($this instanceof SpecialKeySupport) {
94+
$specialKey = $this->convertKeyForArray($key);
95+
}
96+
9097
switch ($type) {
9198
case ImmutableRecord::PHP_TYPE_STRING:
9299
case ImmutableRecord::PHP_TYPE_INT:
93100
case ImmutableRecord::PHP_TYPE_FLOAT:
94101
case ImmutableRecord::PHP_TYPE_BOOL:
95102
case ImmutableRecord::PHP_TYPE_ARRAY:
96103
if (\array_key_exists($key, $arrayPropItemTypeMap) && ! self::isScalarType($arrayPropItemTypeMap[$key])) {
97-
if ($isNullable && $this->{$key}() === null) {
98-
$nativeData[$key] = null;
104+
if ($isNullable && $this->{$key} === null) {
105+
$nativeData[$specialKey] = null;
99106
continue 2;
100107
}
101108

102-
$nativeData[$key] = \array_map(function ($item) use ($key, &$arrayPropItemTypeMap) {
109+
$nativeData[$specialKey] = \array_map(function ($item) use ($key, &$arrayPropItemTypeMap) {
103110
return $this->voTypeToNative($item, $key, $arrayPropItemTypeMap[$key]);
104-
}, $this->{$key}());
111+
}, $this->{$key});
105112
} else {
106-
$nativeData[$key] = $this->{$key}();
113+
$nativeData[$specialKey] = $this->{$key};
107114
}
108115
break;
109116
default:
110-
if ($isNullable && $this->{$key}() === null) {
111-
$nativeData[$key] = null;
117+
if ($isNullable && (! isset($this->{$key}))) {
118+
$nativeData[$specialKey] = null;
112119
continue 2;
113120
}
114-
$nativeData[$key] = $this->voTypeToNative($this->{$key}(), $key, $type);
121+
$nativeData[$specialKey] = $this->voTypeToNative($this->{$key}, $key, $type);
115122
}
116123
}
117124

@@ -120,38 +127,50 @@ public function toArray(): array
120127

121128
public function equals(ImmutableRecord $other): bool
122129
{
123-
if(get_class($this) !== get_class($other)) {
130+
if (\get_class($this) !== \get_class($other)) {
124131
return false;
125132
}
126133

127134
return $this->toArray() === $other->toArray();
128135
}
129136

130-
private function setRecordData(array $recordData)
137+
private function setRecordData(array $recordData): void
131138
{
132139
foreach ($recordData as $key => $value) {
133-
$this->assertType($key, $value);
134-
$this->{$key} = $value;
140+
$specialKey = $key;
141+
142+
if ($this instanceof SpecialKeySupport) {
143+
$specialKey = $this->convertKeyForRecord($key);
144+
}
145+
146+
$this->assertType($specialKey, $value);
147+
$this->{$specialKey} = $value;
135148
}
136149
}
137150

138-
private function setNativeData(array $nativeData)
151+
private function setNativeData(array $nativeData): void
139152
{
140153
$recordData = [];
141154
$arrayPropItemTypeMap = self::getArrayPropItemTypeMapFromMethodOrCache();
142155

143156
foreach ($nativeData as $key => $val) {
144-
if (! isset(self::$__propTypeMap[$key])) {
157+
$specialKey = $key;
158+
159+
if ($this instanceof SpecialKeySupport) {
160+
$specialKey = $this->convertKeyForRecord($key);
161+
}
162+
163+
if (! isset(self::$__propTypeMap[$specialKey])) {
145164
throw new \InvalidArgumentException(\sprintf(
146-
'Invalid property passed to Record %s. Got property with key ' . $key,
165+
'Invalid property passed to Record %s. Got property with key ' . $specialKey,
147166
\get_called_class()
148167
));
149168
}
150-
[$type, $isNative, $isNullable] = self::$__propTypeMap[$key];
169+
[$type, $isNative, $isNullable] = self::$__propTypeMap[$specialKey];
151170

152171
if ($val === null) {
153172
if (! $isNullable) {
154-
throw new \RuntimeException("Got null for non nullable property $key of Record " . \get_called_class());
173+
throw new \RuntimeException("Got null for non nullable property $specialKey of Record " . \get_called_class());
155174
}
156175

157176
$recordData[$key] = null;
@@ -182,10 +201,10 @@ private function setNativeData(array $nativeData)
182201
$this->setRecordData($recordData);
183202
}
184203

185-
private function assertAllNotNull()
204+
private function assertAllNotNull(): void
186205
{
187206
foreach (self::$__propTypeMap as $key => [$type, $isNative, $isNullable]) {
188-
if (null === $this->{$key} && ! $isNullable) {
207+
if (! isset($this->{$key}) && ! $isNullable) {
189208
throw new \InvalidArgumentException(\sprintf(
190209
'Missing record data for key %s of record %s.',
191210
$key,
@@ -195,7 +214,7 @@ private function assertAllNotNull()
195214
}
196215
}
197216

198-
private function assertType(string $key, $value)
217+
private function assertType(string $key, $value): void
199218
{
200219
if (! isset(self::$__propTypeMap[$key])) {
201220
throw new \InvalidArgumentException(\sprintf(
@@ -264,7 +283,7 @@ private function isType(string $type, string $key, $value): bool
264283
}
265284
}
266285

267-
private static function buildPropTypeMap()
286+
private static function buildPropTypeMap(): array
268287
{
269288
$refObj = new \ReflectionClass(__CLASS__);
270289

@@ -384,12 +403,12 @@ private static function getArrayPropItemTypeMapFromMethodOrCache(): array
384403
}
385404

386405
/**
387-
* @var array
406+
* @var array|null
388407
*/
389408
private static $__propTypeMap;
390409

391410
/**
392-
* @var array
411+
* @var array|null
393412
*/
394413
private static $__arrayPropItemTypeMap;
395414
}

src/SpecialKeySupport.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/**
4+
* This file is part of event-engine/php-data.
5+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace EventEngine\Data;
14+
15+
/**
16+
* Implement this interface in your ImmutableRecord class if you have special keys like snake_case.
17+
*/
18+
interface SpecialKeySupport
19+
{
20+
/**
21+
* Converts the given key to key name for the record. For example if the key is first_name and you have a class
22+
* property firstName then you have to convert it to camel case.
23+
*
24+
* @param string $key
25+
* @return string
26+
*/
27+
public function convertKeyForRecord(string $key): string;
28+
29+
/**
30+
* Converts the given key to key name for the array data. For example if you have a class property firstName
31+
* and want to have snake case array keys then you have to convert it to first_name.
32+
*
33+
* @param string $key
34+
* @return string
35+
*/
36+
public function convertKeyForArray(string $key): string;
37+
}

0 commit comments

Comments
 (0)