55namespace KaririCode \ProcessorPipeline \Handler ;
66
77use KaririCode \Contract \Processor \ProcessorBuilder ;
8- use KaririCode \ProcessorPipeline \ AttributeHandler ;
8+ use KaririCode \Contract \ Processor \ ValidatableProcessor ;
99use KaririCode \ProcessorPipeline \Exception \ProcessorRuntimeException ;
10+ use KaririCode \ProcessorPipeline \Processor \ProcessorConfigBuilder ;
11+ use KaririCode \ProcessorPipeline \Processor \ProcessorValidator ;
1012use KaririCode \ProcessorPipeline \Result \ProcessingResultCollection ;
1113
14+ /**
15+ * Handler for processing attributes with configured processors.
16+ */
1217final class ProcessorAttributeHandler extends AttributeHandler
1318{
1419 private ProcessingResultCollection $ results ;
1520
1621 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 ()
1926 ) {
2027 parent ::__construct ($ identifier , $ builder );
2128 $ this ->results = new ProcessingResultCollection ();
2229 }
2330
24- public function processPropertyValue (string $ property , mixed $ value ): mixed
31+ public function handleAttribute (string $ propertyName , object $ attribute , mixed $ value ): mixed
2532 {
26- $ processorSpecs = $ this -> getPropertyProcessors ( $ property );
33+ $ result = parent :: handleAttribute ( $ propertyName , $ attribute , $ value );
2734
28- if (empty ( $ processorSpecs ) ) {
29- return $ value ;
35+ if (null !== $ result ) {
36+ $ this -> transferResults ( $ propertyName ) ;
3037 }
3138
32- try {
33- $ pipeline = $ this ->builder ->buildPipeline (
34- $ this ->identifier ,
35- $ processorSpecs
36- );
39+ return $ result ;
40+ }
3741
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 ();
4049
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+ }
4465 }
4566 }
4667
@@ -57,18 +78,66 @@ public function getProcessingResultErrors(): array
5778 return $ this ->results ->getErrors ();
5879 }
5980
81+ /**
82+ * Checks if there are any processing errors.
83+ */
6084 public function hasErrors (): bool
6185 {
6286 return $ this ->results ->hasErrors ();
6387 }
6488
89+ /**
90+ * Gets the processing results collection.
91+ */
6592 public function getProcessingResults (): ProcessingResultCollection
6693 {
6794 return $ this ->results ;
6895 }
6996
97+ /**
98+ * Resets the processing state.
99+ */
70100 public function reset (): void
71101 {
102+ parent ::reset ();
72103 $ this ->results = new ProcessingResultCollection ();
73104 }
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+ }
74143}
0 commit comments