5
5
namespace KaririCode \ProcessorPipeline \Handler ;
6
6
7
7
use KaririCode \Contract \Processor \ProcessorBuilder ;
8
- use KaririCode \ProcessorPipeline \ AttributeHandler ;
8
+ use KaririCode \Contract \ Processor \ ValidatableProcessor ;
9
9
use KaririCode \ProcessorPipeline \Exception \ProcessorRuntimeException ;
10
+ use KaririCode \ProcessorPipeline \Processor \ProcessorConfigBuilder ;
11
+ use KaririCode \ProcessorPipeline \Processor \ProcessorValidator ;
10
12
use KaririCode \ProcessorPipeline \Result \ProcessingResultCollection ;
11
13
14
+ /**
15
+ * Handler for processing attributes with configured processors.
16
+ */
12
17
final class ProcessorAttributeHandler extends AttributeHandler
13
18
{
14
19
private ProcessingResultCollection $ results ;
15
20
16
21
public function __construct (
17
- string $ identifier ,
18
- ProcessorBuilder $ builder
22
+ private readonly string $ identifier ,
23
+ private readonly ProcessorBuilder $ builder ,
24
+ private readonly ProcessorValidator $ validator = new ProcessorValidator (),
25
+ private readonly ProcessorConfigBuilder $ configBuilder = new ProcessorConfigBuilder ()
19
26
) {
20
27
parent ::__construct ($ identifier , $ builder );
21
28
$ this ->results = new ProcessingResultCollection ();
22
29
}
23
30
24
- public function processPropertyValue (string $ property , mixed $ value ): mixed
31
+ public function handleAttribute (string $ propertyName , object $ attribute , mixed $ value ): mixed
25
32
{
26
- $ processorSpecs = $ this -> getPropertyProcessors ( $ property );
33
+ $ result = parent :: handleAttribute ( $ propertyName , $ attribute , $ value );
27
34
28
- if (empty ( $ processorSpecs ) ) {
29
- return $ value ;
35
+ if (null !== $ result ) {
36
+ $ this -> transferResults ( $ propertyName ) ;
30
37
}
31
38
32
- try {
33
- $ pipeline = $ this ->builder ->buildPipeline (
34
- $ this ->identifier ,
35
- $ processorSpecs
36
- );
39
+ return $ result ;
40
+ }
37
41
38
- $ processedValue = $ pipeline ->process ($ value );
39
- $ this ->results ->setProcessedData ($ property , $ processedValue );
42
+ /**
43
+ * Transfers results from parent handler to ProcessingResultCollection.
44
+ */
45
+ private function transferResults (string $ propertyName ): void
46
+ {
47
+ $ processedValues = parent ::getProcessedPropertyValues ();
48
+ $ errors = parent ::getProcessingResultErrors ();
40
49
41
- return $ processedValue ;
42
- } catch (\Exception $ e ) {
43
- throw ProcessorRuntimeException::processingFailed ($ property , $ e );
50
+ if (isset ($ processedValues [$ propertyName ])) {
51
+ $ this ->results ->setProcessedData (
52
+ $ propertyName ,
53
+ $ processedValues [$ propertyName ]['value ' ]
54
+ );
55
+ }
56
+
57
+ if (isset ($ errors [$ propertyName ])) {
58
+ foreach ($ errors [$ propertyName ] as $ processorName => $ error ) {
59
+ $ this ->results ->addError (
60
+ $ propertyName ,
61
+ $ error ['errorKey ' ] ?? 'processing_error ' ,
62
+ $ error ['message ' ] ?? 'Unknown error '
63
+ );
64
+ }
44
65
}
45
66
}
46
67
@@ -57,18 +78,66 @@ public function getProcessingResultErrors(): array
57
78
return $ this ->results ->getErrors ();
58
79
}
59
80
81
+ /**
82
+ * Checks if there are any processing errors.
83
+ */
60
84
public function hasErrors (): bool
61
85
{
62
86
return $ this ->results ->hasErrors ();
63
87
}
64
88
89
+ /**
90
+ * Gets the processing results collection.
91
+ */
65
92
public function getProcessingResults (): ProcessingResultCollection
66
93
{
67
94
return $ this ->results ;
68
95
}
69
96
97
+ /**
98
+ * Resets the processing state.
99
+ */
70
100
public function reset (): void
71
101
{
102
+ parent ::reset ();
72
103
$ this ->results = new ProcessingResultCollection ();
73
104
}
105
+
106
+ protected function validateProcessors (array $ processorsConfig , array $ messages ): array
107
+ {
108
+ $ errors = [];
109
+
110
+ foreach ($ processorsConfig as $ processorName => $ config ) {
111
+ $ processor = $ this ->builder ->build (
112
+ $ this ->identifier ,
113
+ $ processorName ,
114
+ $ config
115
+ );
116
+
117
+ if ($ processor instanceof ValidatableProcessor && !$ processor ->isValid ()) {
118
+ $ errorKey = $ processor ->getErrorKey ();
119
+ $ message = $ messages [$ processorName ] ?? "Validation failed for $ processorName " ;
120
+
121
+ $ errors [$ processorName ] = [
122
+ 'errorKey ' => $ errorKey ,
123
+ 'message ' => $ message ,
124
+ ];
125
+
126
+ $ this ->results ->addError ($ processorName , $ errorKey , $ message );
127
+ }
128
+ }
129
+
130
+ return $ errors ;
131
+ }
132
+
133
+ protected function processValue (mixed $ value , array $ config ): mixed
134
+ {
135
+ try {
136
+ return $ this ->builder
137
+ ->buildPipeline ($ this ->identifier , $ config )
138
+ ->process ($ value );
139
+ } catch (\Exception $ e ) {
140
+ throw ProcessorRuntimeException::processingFailed ($ value );
141
+ }
142
+ }
74
143
}
0 commit comments