1111use PE \Enums \ActionVariable ;
1212use PE \Exceptions \EncoderException ;
1313use PE \Options \EncoderOptions ;
14+ use PE \Variables \Types \NodeAccessor ;
15+ use PE \Variables \Types \ObjectAccessor ;
1416
1517/**
1618 * Class Encoder
@@ -59,10 +61,11 @@ protected function decodeRawToArray($nodeName, $node, $array) {
5961 foreach ($ decodedData as $ decodedName => $ data ) {
6062 // if data belongs to a child
6163 if ($ nodeType ->childNodeExists ($ decodedName )) {
64+ $ childNodeSetter = $ nodeType ->getChild ($ decodedName )->getSetter ();
6265 // decode it, unset it and add it back into the array at the correct place
6366 $ childArrDecoded = $ this ->decodeRawToArray ($ decodedName , $ nodeChildData , $ array );
6467 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 ));
6669 }
6770 // if data belongs to an attribute simply
6871 else if (is_array ($ data )) {
@@ -116,8 +119,10 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
116119 $ addAfterAttributes = true ;
117120 if ($ parentNode ) {
118121 $ 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 ();
121126 }
122127
123128 $ objects = array ();
@@ -129,6 +134,7 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
129134 $ nodeChildType = $ proxyNode ->getObjectType ($ parentObject , $ nodeDataItem );
130135 $ nodeType = ($ nodeChildType !== null && !empty ($ nodeChildType ) ? $ nodeChildType : $ proxyNode ->getDefaultType ());
131136 $ type = $ proxyNode ->getType ($ nodeType );
137+ $ variableCollection = $ type ->getVariableCollection ();
132138
133139 // make sure the variables are all dashed as this is the default
134140 foreach ($ nodeDataItem as $ nodeDataName => $ nodeDataValue ) {
@@ -139,18 +145,24 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
139145 }
140146 }
141147
148+ $ preNodeStaticOptions = array (
149+ NodeAccessor::VARIABLE_NODE => $ type ,
150+ NodeAccessor::VARIABLE_PARENT => $ parentObject
151+ );
142152 // call node methods. It can be useful when you want to change the outcome of the node data in the node
143153 // 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 )) {
154166 $ nodeDataItem = $ newNode ;
155167 }
156168 }
@@ -183,12 +195,15 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
183195 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 ));
184196 }
185197 $ 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 ));
189201 }
190202
191- array_push ($ requiredVariableValues , $ processedRequiredValue );
203+ $ objectSetter = $ objectSetterVariable ->getObjectSetter ();
204+ $ processedRequiredValue = $ objectSetter ->processValue ($ requiredValue );
205+
206+ $ requiredVariableValues [$ processedVariable ] = $ processedRequiredValue ;
192207 unset($ nodeDataItem [$ processedVariable ]);
193208 }
194209
@@ -203,14 +218,40 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
203218 $ parentNode ->addChildrenToObject ($ nodeName , $ parentObject , array ($ nodeInstance ));
204219 }
205220
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+ }
214255 }
215256
216257 if (!$ addAfterDecode && $ addAfterAttributes ) {
@@ -222,7 +263,7 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
222263 if ($ type ->childNodeExists ($ childName )) {
223264 $ children = $ this ->_decodeNode ($ childName , $ nodeDataItem , $ options , $ type , $ nodeInstance , $ nodeDataItem );
224265
225- if ($ type ->getChild ($ childName )->setAfterChildren ()) {
266+ if ($ type ->getChild ($ childName )->getSetter ()-> setAfterChildren ()) {
226267 $ isSingleChildNode = $ type ->isSingleNode ($ childName );
227268 $ type ->addChildrenToObject ($ childName , $ nodeInstance , $ isSingleChildNode ? array ($ children ) : $ children );
228269 }
@@ -232,7 +273,7 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En
232273
233274 $ nodeIndex ++;
234275 }
235- $ proxyNode -> variablesAreValid ($ decodedChildren , true );
276+ $ variableCollection -> objectVariablesAreValidWithData ($ decodedChildren , true );
236277
237278 if ($ isSingleNode ) {
238279 return $ objects [0 ];
@@ -295,38 +336,64 @@ public function encode($object, EncoderOptions $options = null) {
295336 }
296337
297338 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 ();
299341
300342 $ optionNodeIndex = $ node ->getNodeName () . '[ ' . $ childObjectIterationIndex . '] ' ;
301343
302344 $ attributesRaw = array ();
303- foreach ($ variables as $ variable ) {
304- if (!$ variable ->hasGetterAction () || $ variable ->alwaysExecute ()) {
305345
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+ );
307354
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 ;
314366 }
315-
316- $ attributesRaw [$ variableId ] = $ attributeValue ;
317367 }
318368 }
319369
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+ }
327396
328- $ nodeMethodVariables = $ node ->getVariablesGetterActionByType (EncoderNodeVariable::ACTION_TYPE_NODE );
329- $ attributesRaw = $ this ->loopNodeVariables ($ node , $ nodeMethodVariables , $ attributesRaw , $ actionVariables );
330397
331398 $ optionNodeKey = $ options ->option ('key ' , $ node );
332399 $ optionNodeValue = $ options ->option ('value ' , $ node );
@@ -367,7 +434,7 @@ protected function _encode($object, EncoderNode $node, EncoderOptions $options,
367434 $ isIterated = $ optionChildIteration !== null ;
368435 $ childIteration = $ optionChildIteration === null ? 1 : $ optionChildIteration ;
369436
370- $ getChildObjectsMethod = $ child ->getGetterMethod ();
437+ $ getChildObjectsMethod = $ child ->getGetter ()-> getMethod ();
371438 if (!method_exists ($ object , $ getChildObjectsMethod )) {
372439 throw new EncoderException (sprintf ('Getter method "%s" for node "%s" does not exist in class "%s" ' , $ getChildObjectsMethod , $ childNodeName , get_class ($ object )));
373440 }
@@ -473,25 +540,4 @@ protected function encodeNodeChildren(EncoderNode $node, $nodeName, EncoderNodeC
473540 protected function encodeAttributes ($ attributes ) {
474541 return $ attributes ;
475542 }
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- }
497543}
0 commit comments