11
11
use PE \Enums \ActionVariable ;
12
12
use PE \Exceptions \EncoderException ;
13
13
use PE \Options \EncoderOptions ;
14
+ use PE \Variables \Types \NodeAccessor ;
15
+ use PE \Variables \Types \ObjectAccessor ;
14
16
15
17
/**
16
18
* Class Encoder
@@ -59,10 +61,11 @@ protected function decodeRawToArray($nodeName, $node, $array) {
59
61
foreach ($ decodedData as $ decodedName => $ data ) {
60
62
// if data belongs to a child
61
63
if ($ nodeType ->childNodeExists ($ decodedName )) {
64
+ $ childNodeSetter = $ nodeType ->getChild ($ decodedName )->getSetter ();
62
65
// decode it, unset it and add it back into the array at the correct place
63
66
$ childArrDecoded = $ this ->decodeRawToArray ($ decodedName , $ nodeChildData , $ array );
64
67
unset($ decodedData [$ decodedName ]);
65
- $ decodedData = $ nodeType -> getChild ( $ decodedName ) ->setAfterChildren () === false ? array ($ decodedName => $ childArrDecoded ) + $ decodedData : array_merge ($ decodedData , array ($ decodedName => $ childArrDecoded ));
68
+ $ decodedData = $ childNodeSetter ->setAfterChildren () === false ? array ($ decodedName => $ childArrDecoded ) + $ decodedData : array_merge ($ decodedData , array ($ decodedName => $ childArrDecoded ));
66
69
}
67
70
// if data belongs to an attribute simply
68
71
else if (is_array ($ data )) {
@@ -116,8 +119,10 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
116
119
$ addAfterAttributes = true ;
117
120
if ($ parentNode ) {
118
121
$ childNode = $ parentNode ->getChild ($ nodeName );
119
- $ addAfterDecode = $ childNode ->setAfterChildren ();
120
- $ addAfterAttributes = $ childNode ->setAfterAttributes ();
122
+
123
+ $ childNodeSetter = $ childNode ->getSetter ();
124
+ $ addAfterDecode = $ childNodeSetter ->setAfterChildren ();
125
+ $ addAfterAttributes = $ childNodeSetter ->setAfterAttributes ();
121
126
}
122
127
123
128
$ objects = array ();
@@ -129,6 +134,7 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
129
134
$ nodeChildType = $ proxyNode ->getObjectType ($ parentObject , $ nodeDataItem );
130
135
$ nodeType = ($ nodeChildType !== null && !empty ($ nodeChildType ) ? $ nodeChildType : $ proxyNode ->getDefaultType ());
131
136
$ type = $ proxyNode ->getType ($ nodeType );
137
+ $ variableCollection = $ type ->getVariableCollection ();
132
138
133
139
// make sure the variables are all dashed as this is the default
134
140
foreach ($ nodeDataItem as $ nodeDataName => $ nodeDataValue ) {
@@ -139,18 +145,24 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
139
145
}
140
146
}
141
147
148
+ $ preNodeStaticOptions = array (
149
+ NodeAccessor::VARIABLE_NODE => $ type ,
150
+ NodeAccessor::VARIABLE_PARENT => $ parentObject
151
+ );
142
152
// call node methods. It can be useful when you want to change the outcome of the node data in the node
143
153
// that does not have a certain setter but is used in other ways
144
- $ nodeMethodVariables = $ type ->getVariablesSetterActionByType (EncoderNodeVariable::ACTION_TYPE_NODE );
145
- foreach ($ nodeMethodVariables as $ variableId => $ nodeMethodVariable ) {
146
- if (isset ($ nodeDataItem [$ variableId ])) {
147
- $ setterOptions = array (
148
- ActionVariable::SETTER_NODE_DATA => $ nodeDataItem ,
149
- ActionVariable::SETTER_NAME => $ variableId ,
150
- ActionVariable::SETTER_PARENT => $ parentObject ,
151
- ActionVariable::SETTER_VALUE => $ nodeDataItem [$ variableId ]
152
- );
153
- if ($ newNode = $ nodeMethodVariable ->callNodeSetterAction ($ type , $ setterOptions )) {
154
+ $ preNodeSetterVariables = $ variableCollection ->getPreNodeSetterVariables ();
155
+ foreach ($ preNodeSetterVariables as $ preNodeSetterVariable ) {
156
+ $ variableId = $ preNodeSetterVariable ->getId ();
157
+ $ variableIsset = isset ($ nodeDataItem [$ variableId ]);
158
+ $ preNodeSetter = $ preNodeSetterVariable ->getPreNodeSetter ();
159
+ if (isset ($ nodeDataItem [$ variableId ]) || $ preNodeSetter ->alwaysExecute ()) {
160
+ $ setterOptions = array_merge ($ preNodeStaticOptions , array (
161
+ NodeAccessor::VARIABLE_NODE_DATA => $ nodeDataItem ,
162
+ NodeAccessor::VARIABLE_NAME => $ variableId ,
163
+ NodeAccessor::VARIABLE_VALUE => $ variableIsset ? $ nodeDataItem [$ variableId ] : null
164
+ ));
165
+ if ($ newNode = $ preNodeSetter ->apply ($ setterOptions )) {
154
166
$ nodeDataItem = $ newNode ;
155
167
}
156
168
}
@@ -183,12 +195,15 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
183
195
throw new EncoderException (sprintf ('Variable "%s" for "%s" does not exist but is required to create an object for node "%s" (Node type: "%s") at index "%s" ' , $ processedVariable , $ nodeClassName , $ nodeName , $ type ->getNodeName (), $ nodeIndex ));
184
196
}
185
197
$ requiredValue = $ nodeDataItem [$ processedVariable ];
186
- $ processedRequiredValue = $ type -> processValue ($ processedVariable, $ requiredValue );
187
- if ($ processedRequiredValue === null ) {
188
- throw new EncoderException (sprintf ('Variable "%s" for "%s" cannot process its value (%s). Presumably because the NodeType does not recognize the variable ' , $ processedVariable , $ nodeClassName , $ requiredValue ));
198
+ $ objectSetterVariable = $ variableCollection -> getVariableById ($ processedVariable );
199
+ if (! $ objectSetterVariable ) {
200
+ throw new EncoderException (sprintf ('Variable "%s" for "%s" is required but there is no EncoderNodeVariable available to retrieve the value for node "%s" (Node type: "%s") at index "%s". ' , $ processedVariable , $ nodeClassName , $ nodeName , $ type -> getNodeName (), $ nodeIndex ));
189
201
}
190
202
191
- array_push ($ requiredVariableValues , $ processedRequiredValue );
203
+ $ objectSetter = $ objectSetterVariable ->getObjectSetter ();
204
+ $ processedRequiredValue = $ objectSetter ->processValue ($ requiredValue );
205
+
206
+ $ requiredVariableValues [$ processedVariable ] = $ processedRequiredValue ;
192
207
unset($ nodeDataItem [$ processedVariable ]);
193
208
}
194
209
@@ -203,14 +218,40 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
203
218
$ parentNode ->addChildrenToObject ($ nodeName , $ parentObject , array ($ nodeInstance ));
204
219
}
205
220
206
- foreach ($ nodeDataItem as $ name => $ value ) {
207
- $ type ->applyToVariable ($ name , array (
208
- ActionVariable::SETTER_NODE_DATA => $ nodeDataItem ,
209
- ActionVariable::SETTER_OBJECT => $ nodeInstance ,
210
- ActionVariable::SETTER_PARENT => $ parentObject ,
211
- ActionVariable::SETTER_NAME => $ name ,
212
- ActionVariable::SETTER_VALUE => $ value
213
- ));
221
+ // run the post setter variable types
222
+ $ postNodeStaticOptions = array_merge ($ preNodeStaticOptions , array (
223
+ ObjectAccessor::VARIABLE_OBJECT => $ nodeInstance ,
224
+ ));
225
+ $ postNodeSetterVariables = $ variableCollection ->getPostNodeSetterVariables ();
226
+ foreach ($ postNodeSetterVariables as $ postNodeSetterVariable ) {
227
+ $ variableId = $ postNodeSetterVariable ->getId ();
228
+ $ variableIsset = isset ($ nodeDataItem [$ variableId ]);
229
+ $ postNodeSetter = $ postNodeSetterVariable ->getPostNodeSetter ();
230
+ if ($ variableIsset || $ postNodeSetter ->alwaysExecute ()) {
231
+ $ setterOptions = array_merge ($ postNodeStaticOptions , array (
232
+ NodeAccessor::VARIABLE_NODE_DATA => $ nodeDataItem ,
233
+ NodeAccessor::VARIABLE_NAME => $ variableId ,
234
+ NodeAccessor::VARIABLE_VALUE => $ variableIsset ? $ nodeDataItem [$ variableId ] : null
235
+ ));
236
+ if ($ newNode = $ postNodeSetter ->apply ($ setterOptions )) {
237
+ $ nodeDataItem = $ newNode ;
238
+ }
239
+ }
240
+ }
241
+
242
+ // run the optional object setter variable types
243
+ $ objectSetterVariables = $ variableCollection ->getObjectSetterVariables ();
244
+ foreach ($ objectSetterVariables as $ objectSetterVariable ) {
245
+ $ variableId = $ objectSetterVariable ->getId ();
246
+ if (array_key_exists ($ variableId , $ requiredVariableValues )) {
247
+ // if the variable was an required variable do not try to set it again
248
+ continue ;
249
+ }
250
+ $ variableIsset = isset ($ nodeDataItem [$ variableId ]);
251
+ $ objectSetter = $ objectSetterVariable ->getObjectSetter ();
252
+ if ($ variableIsset || $ objectSetter ->alwaysExecute ()) {
253
+ $ objectSetter ->apply ($ nodeInstance , $ variableIsset ? $ nodeDataItem [$ variableId ] : null );
254
+ }
214
255
}
215
256
216
257
if (!$ addAfterDecode && $ addAfterAttributes ) {
@@ -222,7 +263,7 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
222
263
if ($ type ->childNodeExists ($ childName )) {
223
264
$ children = $ this ->_decodeNode ($ childName , $ nodeDataItem , $ options , $ type , $ nodeInstance , $ nodeDataItem );
224
265
225
- if ($ type ->getChild ($ childName )->setAfterChildren ()) {
266
+ if ($ type ->getChild ($ childName )->getSetter ()-> setAfterChildren ()) {
226
267
$ isSingleChildNode = $ type ->isSingleNode ($ childName );
227
268
$ type ->addChildrenToObject ($ childName , $ nodeInstance , $ isSingleChildNode ? array ($ children ) : $ children );
228
269
}
@@ -232,7 +273,7 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
232
273
233
274
$ nodeIndex ++;
234
275
}
235
- $ proxyNode -> variablesAreValid ($ decodedChildren , true );
276
+ $ variableCollection -> objectVariablesAreValidWithData ($ decodedChildren , true );
236
277
237
278
if ($ isSingleNode ) {
238
279
return $ objects [0 ];
@@ -295,38 +336,64 @@ public function encode($object, EncoderOptions $options = null) {
295
336
}
296
337
297
338
protected function _encode ($ object , EncoderNode $ node , EncoderOptions $ options , $ parent = null , $ nodeIterationIndex = null , $ childObjectIterationIndex = null ) {
298
- $ variables = $ node ->getVariables ();
339
+ $ variableCollection = $ node ->getVariableCollection ();
340
+ $ objectGetterVariables = $ variableCollection ->getObjectGetterVariables ();
299
341
300
342
$ optionNodeIndex = $ node ->getNodeName () . '[ ' . $ childObjectIterationIndex . '] ' ;
301
343
302
344
$ attributesRaw = array ();
303
- foreach ($ variables as $ variable ) {
304
- if (!$ variable ->hasGetterAction () || $ variable ->alwaysExecute ()) {
305
345
306
- $ variableId = $ variable ->getId ();
346
+ $ postNodeStaticOptions = array (
347
+ NodeAccessor::VARIABLE_NODE => $ node ,
348
+ NodeAccessor::VARIABLE_OBJECT => $ object ,
349
+ NodeAccessor::VARIABLE_PARENT => $ parent ,
350
+ NodeAccessor::VARIABLE_OPTIONS => $ options ,
351
+ NodeAccessor::VARIABLE_NODE_ITERATION_INDEX => $ nodeIterationIndex ,
352
+ NodeAccessor::VARIABLE_CHILD_OBJECT_ITERATION_INDEX => $ childObjectIterationIndex ,
353
+ );
307
354
308
- $ attributeValue = null ;
309
- $ getAttributeMethod = $ variable ->getGetterMethod ();
310
- if (method_exists ($ object , $ getAttributeMethod )) {
311
- $ attributeValue = $ object ->$ getAttributeMethod ();
312
- } else {
313
- throw new EncoderException (sprintf ('Getter method "%s" does not exist in object "%s" for node type "%s" (%s) and variable with id "%s". ' , $ getAttributeMethod , get_class ($ object ), $ node ->getNodeTypeName (), get_class ($ node ), $ variableId ));
355
+ $ preNodeGetterVariables = $ variableCollection ->getPreNodeGetterVariables ();
356
+ foreach ($ preNodeGetterVariables as $ preNodeGetterVariable ) {
357
+ $ variableId = $ preNodeGetterVariable ->getId ();
358
+ $ postNodeGetter = $ preNodeGetterVariable ->getPreNodeGetter ();
359
+ $ actionOptions = array_merge ($ postNodeStaticOptions , array (
360
+ NodeAccessor::VARIABLE_NODE_DATA => $ attributesRaw ,
361
+ NodeAccessor::VARIABLE_NAME => $ variableId ,
362
+ ));
363
+ if ($ newAttributeData = $ postNodeGetter ->apply ($ actionOptions )) {
364
+ if (is_array ($ newAttributeData )) {
365
+ $ attributesRaw = $ newAttributeData ;
314
366
}
315
-
316
- $ attributesRaw [$ variableId ] = $ attributeValue ;
317
367
}
318
368
}
319
369
320
- $ actionVariables = array (
321
- ActionVariable::GETTER_OBJECT => $ object ,
322
- ActionVariable::GETTER_PARENT => $ parent ,
323
- ActionVariable::GETTER_OPTIONS => $ options ,
324
- ActionVariable::GETTER_NODE_ITERATION_INDEX => $ nodeIterationIndex ,
325
- ActionVariable::GETTER_CHILD_OBJECT_ITERATION_INDEX => $ childObjectIterationIndex ,
326
- );
370
+ // get all the variables values from the object
371
+ foreach ($ objectGetterVariables as $ objectGetterVariable ) {
372
+ $ variableId = $ objectGetterVariable ->getId ();
373
+
374
+ $ objectGetter = $ objectGetterVariable ->getObjectGetter ();
375
+ $ attributesRaw [$ variableId ] = $ objectGetter ->apply ($ object );
376
+ }
377
+
378
+ $ postNodeGetterVariables = $ variableCollection ->getPostNodeGetterVariables ();
379
+ foreach ($ postNodeGetterVariables as $ postNodeGetterVariable ) {
380
+ $ variableId = $ postNodeGetterVariable ->getId ();
381
+ $ hasVariable = array_key_exists ($ variableId , $ attributesRaw );
382
+ $ postNodeGetter = $ postNodeGetterVariable ->getPostNodeGetter ();
383
+ if ($ hasVariable || $ postNodeGetter ->alwaysExecute ()) {
384
+ $ actionOptions = array_merge ($ postNodeStaticOptions , array (
385
+ NodeAccessor::VARIABLE_NODE_DATA => $ attributesRaw ,
386
+ NodeAccessor::VARIABLE_NAME => $ variableId ,
387
+ NodeAccessor::VARIABLE_VALUE => $ hasVariable ? $ attributesRaw [$ variableId ] : null ,
388
+ ));
389
+ if ($ newAttributeData = $ postNodeGetter ->apply ($ actionOptions )) {
390
+ if (is_array ($ newAttributeData )) {
391
+ $ attributesRaw = $ newAttributeData ;
392
+ }
393
+ }
394
+ }
395
+ }
327
396
328
- $ nodeMethodVariables = $ node ->getVariablesGetterActionByType (EncoderNodeVariable::ACTION_TYPE_NODE );
329
- $ attributesRaw = $ this ->loopNodeVariables ($ node , $ nodeMethodVariables , $ attributesRaw , $ actionVariables );
330
397
331
398
$ optionNodeKey = $ options ->option ('key ' , $ node );
332
399
$ optionNodeValue = $ options ->option ('value ' , $ node );
@@ -367,7 +434,7 @@ protected function _encode($object, EncoderNode $node, EncoderOptions $options,
367
434
$ isIterated = $ optionChildIteration !== null ;
368
435
$ childIteration = $ optionChildIteration === null ? 1 : $ optionChildIteration ;
369
436
370
- $ getChildObjectsMethod = $ child ->getGetterMethod ();
437
+ $ getChildObjectsMethod = $ child ->getGetter ()-> getMethod ();
371
438
if (!method_exists ($ object , $ getChildObjectsMethod )) {
372
439
throw new EncoderException (sprintf ('Getter method "%s" for node "%s" does not exist in class "%s" ' , $ getChildObjectsMethod , $ childNodeName , get_class ($ object )));
373
440
}
@@ -473,25 +540,4 @@ protected function encodeNodeChildren(EncoderNode $node, $nodeName, EncoderNodeC
473
540
protected function encodeAttributes ($ attributes ) {
474
541
return $ attributes ;
475
542
}
476
-
477
-
478
- protected function loopNodeVariables ($ node , $ variables , $ data , $ actionOptions ) {
479
- $ temp = $ data ;
480
- foreach ($ variables as $ variableId => $ nodeMethodVariable ) {
481
- $ hasVariable = array_key_exists ($ variableId , $ data );
482
- if ($ hasVariable || $ nodeMethodVariable ->alwaysExecute ()) {
483
- $ actionOptions = array_merge (array (
484
- ActionVariable::GETTER_NODE_DATA => $ data ,
485
- ActionVariable::GETTER_NAME => $ variableId ,
486
- ActionVariable::GETTER_VALUE => $ hasVariable ? $ data [$ variableId ] : null ,
487
- ), $ actionOptions );
488
- if ($ newAttributeData = $ nodeMethodVariable ->callNodeGetterAction ($ node , $ actionOptions )) {
489
- if (is_array ($ newAttributeData )) {
490
- $ temp = $ newAttributeData ;
491
- }
492
- }
493
- }
494
- }
495
- return $ temp ;
496
- }
497
543
}
0 commit comments