1+ <?php
2+
3+ namespace Patchlevel \Hydrator \Cryptography ;
4+
5+ use Closure ;
6+ use Patchlevel \Hydrator \Cryptography \Cipher \DecryptionFailed ;
7+ use Patchlevel \Hydrator \Cryptography \Store \CipherKeyNotExists ;
8+ use Patchlevel \Hydrator \Normalizer \ContextAwareNormalizer ;
9+ use Patchlevel \Hydrator \Normalizer \InvalidArgument ;
10+ use Patchlevel \Hydrator \Normalizer \Normalizer ;
11+
12+ final class CryptoNormalizer implements Normalizer, ContextAwareNormalizer
13+ {
14+ public function __construct (
15+ private readonly Cryptographer $ cryptographer ,
16+ private readonly string $ subjectIdName ,
17+ private readonly mixed $ fallback = null ,
18+ private readonly Normalizer |null $ normalizer = null ,
19+ ) {
20+ }
21+
22+ /**
23+ * @param array<string, mixed> $context
24+ *
25+ * @throws InvalidArgument
26+ */
27+ public function normalize (mixed $ value , array $ context = []): mixed
28+ {
29+ if ($ this ->normalizer !== null ) {
30+ $ value = $ this ->normalizer ->normalize ($ value , $ context );
31+ }
32+
33+ if ($ value === null ) {
34+ return null ;
35+ }
36+
37+ $ subjectId = $ context [SubjectIds::class]->get ($ this ->subjectIdName );
38+
39+ return ['__enc ' => $ this ->cryptographer ->encrypt ($ subjectId , $ value )];
40+ }
41+
42+ /**
43+ * @param array<string, mixed> $context
44+ *
45+ * @throws InvalidArgument
46+ */
47+ public function denormalize (mixed $ value , array $ context = []): mixed
48+ {
49+ if (!is_array ($ value ) || !array_key_exists ('__enc ' , $ value )) {
50+ if ($ this ->normalizer === null ) {
51+ return $ value ;
52+ }
53+
54+ return $ this ->normalizer ->denormalize ($ value , $ context );
55+ }
56+
57+ $ subjectId = $ context [SubjectIds::class]->get ($ this ->subjectIdName );
58+
59+ try {
60+ $ data = $ this ->cryptographer ->decrypt ($ subjectId , $ value ['__enc ' ]);
61+ } catch (DecryptionFailed |CipherKeyNotExists ) {
62+ if ($ this ->fallback instanceof Closure) {
63+ return ($ this ->fallback )($ subjectId , $ value ['__enc ' ]);
64+ }
65+
66+ return $ this ->fallback ;
67+ }
68+
69+ if ($ this ->normalizer === null ) {
70+ return $ data ;
71+ }
72+
73+ return $ this ->normalizer ->denormalize ($ data , $ context );
74+ }
75+ }
0 commit comments