Skip to content

Commit a778aa4

Browse files
committed
Adding cipher targets
1 parent eb765dc commit a778aa4

20 files changed

+522
-45
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
}
1111
],
1212
"require": {
13-
"php": "~8.4"
13+
"php": "~8.4",
14+
"ext-openssl": "*"
1415
},
1516
"require-dev": {
1617
"phpstan/phpstan": "^2.0",

docs/PropertyAttributes.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Property Attributes
44
In order to provide more functionality to your DTOs, you can use the following attributes:
55
- [Computed](#Computed) - To define a property that is computed from other properties.
66
- [Aliases](#Aliases) - To define aliases for a property.
7+
- [CipherTarget](#CipherTarget) - To define a property that should be encrypted/decrypted.
78

89
Computed
910
-
@@ -46,10 +47,65 @@ final readonly class Person extends Data
4647
public function __construct(
4748
#[Aliases('first_name')]
4849
public string $firstName,
49-
#[Aliases('last_name')]
50+
#[Aliases('last_name', 'family_name')]
5051
public string $lastName
5152
) {}
5253
}
5354
```
5455

5556
This will make it possible to hydrate properties from multiple array keys.
57+
58+
CipherTarget
59+
-
60+
61+
Sometimes, we may need to specify that some properties are considered sensitive, and should be
62+
handled carefully, especially when saving it.
63+
64+
For this we can use encryption/decryption using the `CipherTarget` attribute.
65+
66+
```php
67+
use Nuxtifyts\PhpDto\Data;
68+
use Nuxtifyts\PhpDto\Attributes\Property\Types\ArrayOfData;
69+
use Nuxtifyts\PhpDto\Attributes\Property\CipherTarget;
70+
71+
final readonly class User extends Data
72+
{
73+
/**
74+
* @param list<UserConfigData> $userConfigs
75+
*/
76+
public function __construct(
77+
#[ArrayOfData(UserConfigData::class)]
78+
#[CipherTarget(
79+
secret: 'user-configs-secret-key', // By default, it uses the class name
80+
encoded: true // By default, it does not perform encoding
81+
)]
82+
public array $userConfigs
83+
) {}
84+
}
85+
86+
```
87+
88+
it is also possible to specify a custom DataCipher for the property,
89+
the new class should implement the `Nuxtifyts\PhpDto\DataCipher` interface.
90+
91+
```php
92+
93+
use Nuxtifyts\PhpDto\DataCiphers\DataCipher;
94+
95+
class CustomDataCipher implements DataCipher
96+
{
97+
// Implement the interface
98+
}
99+
```
100+
101+
Then you can specify the custom DataCipher in the `CipherTarget` attribute.
102+
103+
```php
104+
public function __construct(
105+
#[CipherTarget(
106+
dataCipherClass: CustomDataCipher::class,
107+
)]
108+
public UserConfigData $userConfig
109+
) {}
110+
```
111+

src/Attributes/Property/Aliases.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class Aliases
99
{
1010
/** @var list<string> */
11-
private(set) array $aliases;
11+
protected(set) array $aliases;
1212

1313
public function __construct(
1414
string $alias,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Attributes\Property;
4+
5+
use Attribute;
6+
use Nuxtifyts\PhpDto\DataCiphers\DataCipher;
7+
8+
#[Attribute(Attribute::TARGET_PROPERTY)]
9+
class CipherTarget
10+
{
11+
/**
12+
* @param class-string<DataCipher> $dataCipherClass
13+
*/
14+
public function __construct(
15+
protected(set) string $dataCipherClass = DataCipher::class,
16+
protected(set) string $secret = '',
17+
protected(set) bool $encoded = false
18+
) {
19+
}
20+
}

src/Attributes/Property/Types/ArrayOfBackedEnums.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
class ArrayOfBackedEnums
1212
{
1313
/** @var array<string, ReflectionEnum<BackedEnum>> */
14-
private static array $_enumReflections = [];
14+
protected static array $_enumReflections = [];
1515

1616
/** @var list<class-string<BackedEnum>> $enums */
17-
private(set) array $enums;
17+
protected(set) array $enums;
1818

1919
/** @var array<string, ReflectionEnum<BackedEnum>> */
20-
private(set) array $resolvedBackedEnumReflections = [];
20+
protected(set) array $resolvedBackedEnumReflections = [];
2121

2222
/**
2323
* @param class-string<BackedEnum>|list<class-string<BackedEnum>> $enums

src/Attributes/Property/Types/ArrayOfData.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
class ArrayOfData
1414
{
1515
/** @var array<string, ReflectionClass<Data>> */
16-
private static array $_dataReflections = [];
16+
protected static array $_dataReflections = [];
1717

1818
/** @var list<class-string<Data>> */
19-
private(set) array $dataClasses;
19+
protected(set) array $dataClasses;
2020

2121
/** @var array<string, ReflectionClass<Data>> */
22-
private(set) array $resolvedDataReflections = [];
22+
protected(set) array $resolvedDataReflections = [];
2323

2424
/**
2525
* @param class-string<Data>|list<class-string<Data>> $dataClasses

src/Attributes/Property/Types/ArrayOfDateTimes.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
class ArrayOfDateTimes
1515
{
1616
/** @var array<string, ReflectionClass<DateTime|DateTimeImmutable>> */
17-
private static array $_dateTimeReflections = [];
17+
protected static array $_dateTimeReflections = [];
1818

1919
/** @var list<class-string<DateTime|DateTimeImmutable>> */
20-
private(set) array $dateTimes;
20+
protected(set) array $dateTimes;
2121

2222
/** @var array<string, ReflectionClass<DateTime|DateTimeImmutable>> */
23-
private(set) array $resolvedDateTimeReflections = [];
23+
protected(set) array $resolvedDateTimeReflections = [];
2424

2525
/**
2626
* @param class-string<DateTime|DateTimeImmutable>|list<class-string<DateTime|DateTimeImmutable>> $dateTimes

src/Attributes/Property/Types/ArrayOfScalarTypes.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
class ArrayOfScalarTypes
1111
{
1212
/** @var list<Type> $types */
13-
private(set) array $types;
13+
protected(set) array $types;
1414

1515
/**
1616
* @param Type|list<Type> $types

src/Attributes/Property/WithRefiner.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
class WithRefiner
1010
{
1111
/** @var array<array-key, mixed> */
12-
private array $refinerArgs;
12+
protected array $refinerArgs;
1313

1414
/**
1515
* @param class-string<DataRefiner> $refinerClass
1616
*/
1717
public function __construct(
18-
private readonly string $refinerClass,
18+
protected readonly string $refinerClass,
1919
mixed ...$refinerArgs
2020
) {
2121
$this->refinerArgs = $refinerArgs;

src/Concerns/BaseData.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Nuxtifyts\PhpDto\Contexts\ClassContext;
66
use Nuxtifyts\PhpDto\Exceptions\DeserializeException;
77
use Nuxtifyts\PhpDto\Exceptions\SerializeException;
8+
use Nuxtifyts\PhpDto\Pipelines\DeserializePipeline\DecipherDataPipe;
89
use Nuxtifyts\PhpDto\Pipelines\DeserializePipeline\DeserializePipelinePassable;
910
use Nuxtifyts\PhpDto\Pipelines\DeserializePipeline\RefineDataPipe;
1011
use Nuxtifyts\PhpDto\Pipelines\DeserializePipeline\ResolveValuesFromAliasesPipe;
@@ -37,6 +38,7 @@ final public static function from(mixed $value): static
3738
$data = new Pipeline(DeserializePipelinePassable::class)
3839
->through(ResolveValuesFromAliasesPipe::class)
3940
->through(RefineDataPipe::class)
41+
->through(DecipherDataPipe::class)
4042
->sendThenReturn(new DeserializePipelinePassable(
4143
classContext: $context,
4244
data: $value
@@ -112,18 +114,18 @@ final public function jsonSerialize(): array
112114
try {
113115
$context = ClassContext::getInstance(new ReflectionClass($this));
114116

115-
$serializableArray = [];
117+
$serializedData = [];
116118
foreach ($context->properties as $propertyContext) {
117119
if ($propertyContext->isComputed) {
118120
continue;
119121
}
120122

121123
$propertyName = $propertyContext->propertyName;
122124

123-
$serializableArray[$propertyName] = $propertyContext->serializeFrom($this)[$propertyName];
125+
$serializedData[$propertyName] = $propertyContext->serializeFrom($this)[$propertyName];
124126
}
125127

126-
return $serializableArray;
128+
return $serializedData;
127129
} catch (Throwable $e) {
128130
throw new SerializeException($e->getMessage(), $e->getCode(), $e);
129131
}

0 commit comments

Comments
 (0)