protected function _encode($object, EncoderNode $node, EncoderOptions $options, $parent = null, $nodeIterationIndex = null, $childObjectIterationIndex = null) { $variableCollection = $node->getVariableCollection(); $objectGetterVariables = $variableCollection->getObjectGetterVariables(); $optionNodeIndex = $node->getNodeName() . '[' . $childObjectIterationIndex . ']'; $attributesRaw = array(); $postNodeStaticOptions = array(NodeAccessor::VARIABLE_NODE => $node, NodeAccessor::VARIABLE_OBJECT => $object, NodeAccessor::VARIABLE_PARENT => $parent, NodeAccessor::VARIABLE_OPTIONS => $options, NodeAccessor::VARIABLE_NODE_ITERATION_INDEX => $nodeIterationIndex, NodeAccessor::VARIABLE_CHILD_OBJECT_ITERATION_INDEX => $childObjectIterationIndex); $preNodeGetterVariables = $variableCollection->getPreNodeGetterVariables(); foreach ($preNodeGetterVariables as $preNodeGetterVariable) { $variableId = $preNodeGetterVariable->getId(); $postNodeGetter = $preNodeGetterVariable->getPreNodeGetter(); $actionOptions = array_merge($postNodeStaticOptions, array(NodeAccessor::VARIABLE_NODE_DATA => $attributesRaw, NodeAccessor::VARIABLE_NAME => $variableId)); if ($newAttributeData = $postNodeGetter->apply($actionOptions)) { if (is_array($newAttributeData)) { $attributesRaw = $newAttributeData; } } } // get all the variables values from the object foreach ($objectGetterVariables as $objectGetterVariable) { $variableId = $objectGetterVariable->getId(); $objectGetter = $objectGetterVariable->getObjectGetter(); $attributesRaw[$variableId] = $objectGetter->apply($object); } $postNodeGetterVariables = $variableCollection->getPostNodeGetterVariables(); foreach ($postNodeGetterVariables as $postNodeGetterVariable) { $variableId = $postNodeGetterVariable->getId(); $hasVariable = array_key_exists($variableId, $attributesRaw); $postNodeGetter = $postNodeGetterVariable->getPostNodeGetter(); if ($hasVariable || $postNodeGetter->alwaysExecute()) { $actionOptions = array_merge($postNodeStaticOptions, array(NodeAccessor::VARIABLE_NODE_DATA => $attributesRaw, NodeAccessor::VARIABLE_NAME => $variableId, NodeAccessor::VARIABLE_VALUE => $hasVariable ? $attributesRaw[$variableId] : null)); if ($newAttributeData = $postNodeGetter->apply($actionOptions)) { if (is_array($newAttributeData)) { $attributesRaw = $newAttributeData; } } } } $optionNodeKey = $options->option('key', $node); $optionNodeValue = $options->option('value', $node); $optionEncodeAttributes = $options->option('attributes', $node); $optionEncodeChildren = $options->option('children', $node); // should we encode the node's children or not? $encodeChildren = true; // should we encode the node's attributes or not? $encodeAttributes = true; if (is_bool($optionEncodeAttributes)) { $encodeAttributes = $optionEncodeAttributes; } if (is_bool($optionEncodeChildren)) { $encodeChildren = $optionEncodeChildren; } if ($optionNodeValue !== null || $optionNodeKey !== null) { $encodeAttributes = false; } $nodesRaw = array(); $childrenProcessed = array(); if ($encodeChildren === true) { $children = $node->getChildren(); foreach ($children as $childNodeName => $child) { if (!EncoderNode::nodeExists($child->getChildNodeName())) { throw new EncoderException(sprintf('Cannot set the node name (%s) of a node child because it doesn\'t exist. Please add the requested node with "EncoderNode::addNode()". Current node name "%s" with class name "%s"', $child->getChildNodeName(), $node->getNodeName(), get_class($node))); } $childOptionPath = $optionNodeIndex . ':' . $childNodeName; $optionChildIteration = $options->option('iterate', $childOptionPath); $optionChildKey = $options->option('key', $childOptionPath); $isIterated = $optionChildIteration !== null; $childIteration = $optionChildIteration === null ? 1 : $optionChildIteration; $getChildObjectsMethod = $child->getGetter()->getMethod(); if (!method_exists($object, $getChildObjectsMethod)) { throw new EncoderException(sprintf('Getter method "%s" for node "%s" does not exist in class "%s"', $getChildObjectsMethod, $childNodeName, get_class($object))); } $childObjects = $object->{$getChildObjectsMethod}(); if (!$child->isArray()) { $childObjects = array($childObjects); } else { if (!is_array($childObjects)) { throw new EncoderException(sprintf('Children object for node "%s" must be an array. EncoderNodeChilds are returning an array by default. If this behavior is not desired, turn it off using "$childNode->isArray(false)" or set "isArray" as an options to the EncoderNodeChild instance', $childNodeName)); } } $rawChildrenInformationIteration = array(); $nodeIteration = 0; for ($i = 0; $i < $childIteration; $i++) { $childObjectIteration = 0; foreach ($childObjects as $childObject) { $childNodeType = EncoderNode::getNodeTypeByObject($childObject); if ($childNodeType === null) { throw new EncoderException(sprintf('Child node type for object "%s (child of "%s")" for node "%s" not found', get_class($childObject), $node->getNodeName(), $childNodeName)); } $childNodeData = $this->_encode($childObject, $childNodeType, $options, $object, $nodeIteration, $childObjectIteration); $rawChildNode = $childNodeData['raw']; $rawChildNodeAttributes = $rawChildNode['attributes']; $rawChildNodeChildren = $rawChildNode['children']; $processedChildNode = $childNodeData['processed']; $rawChildrenInformationIteration[$nodeIteration][$childObjectIteration] = array('attributes' => $rawChildNodeAttributes, 'children' => $rawChildNodeChildren, 'nodeName' => $childNodeName); if ($optionChildKey !== null) { if ($isIterated) { $childrenProcessed[$nodeIteration][$rawChildNodeAttributes[$optionChildKey]] = $processedChildNode; } else { $childrenProcessed[$rawChildNodeAttributes[$optionChildKey]] = $processedChildNode; } } else { if (!isset($childrenProcessed[$childNodeName])) { $childrenProcessed[$childNodeName] = array(); } $childrenProcessedTemp = array($childObjectIteration => $processedChildNode); if ($isIterated) { $childrenProcessed[$childNodeName] = array_merge_recursive($childrenProcessed[$childNodeName], $this->encodeNodeChildren($childNodeType, $childNodeName, $child, array($nodeIteration => $childrenProcessedTemp))); } else { $childrenProcessed[$childNodeName] = array_merge_recursive($childrenProcessed[$childNodeName], $this->encodeNodeChildren($childNodeType, $childNodeName, $child, $childrenProcessedTemp)); } } $childObjectIteration++; } $nodeIteration++; } if (count($rawChildrenInformationIteration)) { $rawIteratedChildren = $isIterated ? $rawChildrenInformationIteration : $rawChildrenInformationIteration[0]; $nodesRaw[$childNodeName] = $rawIteratedChildren; } } } $attributesProcessed = $this->encodeAttributes($attributesRaw); if (!$encodeAttributes) { $attributesProcessed = array(); } $nodeData = array_merge($attributesProcessed, $childrenProcessed); if ($optionNodeValue !== null) { if (!array_key_exists($optionNodeValue, $attributesRaw)) { throw new EncoderException(sprintf('Option "value" cannot be mapped to "%s" because it does not exist in "%s"', $optionNodeValue, $node->getNodeName())); } $nodeData = $attributesRaw[$optionNodeValue]; } return array('processed' => $nodeData, 'raw' => array('attributes' => $attributesRaw, 'children' => $nodesRaw, 'nodeName' => $node->getNodeName())); }