From 526a70d9d2839eb998dbe1d756e0d621da38f83a Mon Sep 17 00:00:00 2001 From: Jansen Felipe Date: Wed, 22 Jul 2015 15:43:35 -0300 Subject: [PATCH] Update --- composer.json | 6 +- src/JMS/Serializer/PropertyMetadataCustom.php | 9 + .../XmlDeserializationVisitorCustom.php | 308 +++++++++++++++ .../XmlSerializationVisitorCustom.php | 373 ++++++++++++++++++ src/NFePHPSerialize.php | 7 + tests/NFePHPSerializeTest.php | 23 +- 6 files changed, 708 insertions(+), 18 deletions(-) create mode 100644 src/JMS/Serializer/PropertyMetadataCustom.php create mode 100644 src/JMS/Serializer/XmlDeserializationVisitorCustom.php create mode 100644 src/JMS/Serializer/XmlSerializationVisitorCustom.php diff --git a/composer.json b/composer.json index 9f9fb5b..290b47a 100644 --- a/composer.json +++ b/composer.json @@ -11,17 +11,13 @@ ], "require": { "php": ">=5.6.0", - "jms/serializer": "xsd2php-dev as 0.18.0" + "jms/serializer": "1.0.0" }, "require-dev": { "phpunit/phpunit": "^5.0@dev", "goetas/xsd2php": "2.*@dev", "goetas/xsd-reader": "2.*@dev" }, - "repositories": [{ - "type": "vcs", - "url": "https://github.com/goetas/serializer.git" - }], "autoload": { "psr-4": { "JansenFelipe\\NFePHPSerialize\\": "src" diff --git a/src/JMS/Serializer/PropertyMetadataCustom.php b/src/JMS/Serializer/PropertyMetadataCustom.php new file mode 100644 index 0000000..c98b92e --- /dev/null +++ b/src/JMS/Serializer/PropertyMetadataCustom.php @@ -0,0 +1,9 @@ +disableExternalEntities = false; + } + public function setNavigator(GraphNavigator $navigator) + { + $this->navigator = $navigator; + $this->objectStack = new SplStack; + $this->metadataStack = new SplStack; + $this->objectMetadataStack = new SplStack; + $this->result = null; + } + public function getNavigator() + { + return $this->navigator; + } + public function prepare($data) + { + $previous = libxml_use_internal_errors(true); + $previousEntityLoaderState = libxml_disable_entity_loader($this->disableExternalEntities); + $dom = new DOMDocument(); + $dom->loadXML($data); + foreach ($dom->childNodes as $child) { + if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { + $internalSubset = str_replace(array("\n", "\r"), '', $child->internalSubset); + if (!in_array($internalSubset, $this->doctypeWhitelist, true)) { + throw new InvalidArgumentException(sprintf( + 'The document type "%s" is not allowed. If it is safe, you may add it to the whitelist configuration.', + $internalSubset + )); + } + } + } + $doc = simplexml_load_string($data); + libxml_use_internal_errors($previous); + libxml_disable_entity_loader($previousEntityLoaderState); + if (false === $doc) { + throw new XmlErrorException(libxml_get_last_error()); + } + return $doc; + } + public function visitNull($data, array $type, Context $context) + { + return null; + } + public function visitString($data, array $type, Context $context) + { + $data = (string) $data; + if (null === $this->result) { + $this->result = $data; + } + return $data; + } + public function visitBoolean($data, array $type, Context $context) + { + $data = (string) $data; + if ('true' === $data || '1' === $data) { + $data = true; + } elseif ('false' === $data || '0' === $data) { + $data = false; + } else { + throw new RuntimeException(sprintf('Could not convert data to boolean. Expected "true", "false", "1" or "0", but got %s.', json_encode($data))); + } + if (null === $this->result) { + $this->result = $data; + } + return $data; + } + public function visitInteger($data, array $type, Context $context) + { + $data = (integer) $data; + if (null === $this->result) { + $this->result = $data; + } + return $data; + } + public function visitDouble($data, array $type, Context $context) + { + $data = (double) $data; + if (null === $this->result) { + $this->result = $data; + } + return $data; + } + public function visitArray($data, array $type, Context $context) + { + $entryName = null !== $this->currentMetadata && $this->currentMetadata->xmlEntryName ? $this->currentMetadata->xmlEntryName : 'entry'; + $namespace = null !== $this->currentMetadata && $this->currentMetadata->xmlEntryNamespace ? $this->currentMetadata->xmlEntryNamespace : null; + if ($namespace === null && $this->objectMetadataStack->count()) { + $classMetadata = $this->objectMetadataStack->top(); + $namespace = isset($classMetadata->xmlNamespaces[''])?$classMetadata->xmlNamespaces['']:$namespace; + } + if ( ! isset($data->$entryName) ) { + if (null === $this->result) { + return $this->result = array(); + } + return array(); + } + switch (count($type['params'])) { + case 0: + throw new RuntimeException(sprintf('The array type must be specified either as "array", or "array".')); + case 1: + $result = array(); + if (null === $this->result) { + $this->result = &$result; + } + $nodes = $data->children($namespace)->$entryName; + foreach ($nodes as $v) { + $result[] = $this->navigator->accept($v, $type['params'][0], $context); + } + return $result; + case 2: + if (null === $this->currentMetadata) { + throw new RuntimeException('Maps are not supported on top-level without metadata.'); + } + list($keyType, $entryType) = $type['params']; + $result = array(); + if (null === $this->result) { + $this->result = &$result; + } + $nodes = $data->children($namespace)->$entryName; + foreach ($nodes as $v) { + $attrs = $v->attributes(); + if (!isset($attrs[$this->currentMetadata->xmlKeyAttribute])) { + throw new RuntimeException(sprintf('The key attribute "%s" must be set for each entry of the map.', $this->currentMetadata->xmlKeyAttribute)); + } + $k = $this->navigator->accept($attrs[$this->currentMetadata->xmlKeyAttribute], $keyType, $context); + $result[$k] = $this->navigator->accept($v, $entryType, $context); + } + return $result; + default: + throw new LogicException(sprintf('The array type does not support more than 2 parameters, but got %s.', json_encode($type['params']))); + } + } + public function startVisitingObject(ClassMetadata $metadata, $object, array $type, Context $context) + { + $this->setCurrentObject($object); + $this->objectMetadataStack->push($metadata); + if (null === $this->result) { + $this->result = $this->currentObject; + } + } + + public function castAs($newClass) { + $obj = new $newClass; + foreach (get_object_vars($this) as $key => $name) { + $obj->$key = $name; + } + return $obj; + } + + public function visitProperty(PropertyMetadata $metadata, $data, Context $context){ + $metadataCustom = new PropertyMetadataCustom($metadata->class, $metadata->name); + + foreach (get_object_vars($metadata) as $key => $name) + $metadataCustom->$key = $name; + + $this->visitPropertyCustom($metadataCustom, $data, $context); + } + + public function visitPropertyCustom(PropertyMetadataCustom $metadata, $data, Context $context) + { + $name = $this->namingStrategy->translateName($metadata); + if (!$metadata->type) { + throw new RuntimeException(sprintf('You must define a type for %s::$%s.', $metadata->reflection->class, $metadata->name)); + } + if ($metadata->xmlAttribute) { + $attributes = $data->attributes($metadata->xmlNamespace); + if (isset($attributes[$name])) { + $v = $this->navigator->accept($attributes[$name], $metadata->type, $context); + $metadata->reflection->setValue($this->currentObject, $v); + } + return; + } + if ($metadata->xmlValue) { + $v = $this->navigator->accept($data, $metadata->type, $context); + $metadata->reflection->setValue($this->currentObject, $v); + return; + } + if ($metadata->xmlCollection) { + $enclosingElem = $data; + if (!$metadata->xmlCollectionInline) { + $enclosingElem = $data->children($metadata->xmlNamespace)->$name; + } + $this->setCurrentMetadata($metadata); + $v = $this->navigator->accept($enclosingElem, $metadata->type, $context); + $this->revertCurrentMetadata(); + $metadata->reflection->setValue($this->currentObject, $v); + return; + } + if ($metadata->xmlNamespace) { + $node = $data->children($metadata->xmlNamespace)->$name; + if (!$node->count()) { + return; + } + } else { + $namespaces = $data->getDocNamespaces(); + if (isset($namespaces[''])) { + $prefix = uniqid('ns-'); + $data->registerXPathNamespace($prefix, $namespaces['']); + $nodes = $data->xpath('./'.$prefix. ':'.$name ); + if (empty($nodes)) { + return; + } + $node = reset($nodes); + } else { + if (!isset($data->$name)) { + return; + } + $node = $data->$name; + } + } + $v = $this->navigator->accept($node, $metadata->type, $context); + if (null === $metadata->setter) { + $metadata->reflection->setValue($this->currentObject, $v); + return; + } + $this->currentObject->{$metadata->setter}($v); + } + public function endVisitingObject(ClassMetadata $metadata, $data, array $type, Context $context) + { + $rs = $this->currentObject; + $this->objectMetadataStack->pop(); + $this->revertCurrentObject(); + return $rs; + } + public function setCurrentObject($object) + { + $this->objectStack->push($this->currentObject); + $this->currentObject = $object; + } + public function getCurrentObject() + { + return $this->currentObject; + } + public function revertCurrentObject() + { + return $this->currentObject = $this->objectStack->pop(); + } + public function setCurrentMetadata(PropertyMetadata $metadata) + { + $metadataCustom = new PropertyMetadataCustom($metadata->class, $metadata->name); + + foreach (get_object_vars($metadata) as $key => $name) + $metadataCustom->$key = $name; + + $this->setCurrentMetadataCustom($metadataCustom); + } + public function setCurrentMetadataCustom(PropertyMetadataCustom $metadata) + { + $this->metadataStack->push($this->currentMetadata); + $this->currentMetadata = $metadata; + } + public function getCurrentMetadata() + { + return $this->currentMetadata; + } + public function revertCurrentMetadata() + { + return $this->currentMetadata = $this->metadataStack->pop(); + } + public function getResult() + { + return $this->result; + } + /** + * @param array $doctypeWhitelist + */ + public function setDoctypeWhitelist(array $doctypeWhitelist) + { + $this->doctypeWhitelist = $doctypeWhitelist; + } + /** + * @return array + */ + public function getDoctypeWhitelist() + { + return $this->doctypeWhitelist; + } +} \ No newline at end of file diff --git a/src/JMS/Serializer/XmlSerializationVisitorCustom.php b/src/JMS/Serializer/XmlSerializationVisitorCustom.php new file mode 100644 index 0000000..064ba0c --- /dev/null +++ b/src/JMS/Serializer/XmlSerializationVisitorCustom.php @@ -0,0 +1,373 @@ +objectMetadataStack = new SplStack; + } + public function setDefaultRootName($name, $namespace = null) + { + $this->defaultRootName = $name; + $this->defaultRootNamespace = $namespace; + } + /** + * @return boolean + */ + public function hasDefaultRootName() + { + return 'result' === $this->defaultRootName; + } + public function setDefaultVersion($version) + { + $this->defaultVersion = $version; + } + public function setDefaultEncoding($encoding) + { + $this->defaultEncoding = $encoding; + } + public function setNavigator(GraphNavigator $navigator) + { + $this->navigator = $navigator; + $this->document = null; + $this->stack = new SplStack; + $this->metadataStack = new SplStack; + } + public function getNavigator() + { + return $this->navigator; + } + public function visitNull($data, array $type, Context $context) + { + if (null === $this->document) { + $this->document = $this->createDocument(null, null, true); + $node = $this->document->createAttribute('xsi:nil'); + $node->value = 'true'; + $this->currentNode->appendChild($node); + $this->attachNullNamespace(); + return; + } + $node = $this->document->createAttribute('xsi:nil'); + $node->value = 'true'; + $this->attachNullNamespace(); + return $node; + } + public function visitString($data, array $type, Context $context) + { + if (null !== $this->currentMetadata) { + $doCData = $this->currentMetadata->xmlElementCData; + } else { + $doCData = true; + } + if (null === $this->document) { + $this->document = $this->createDocument(null, null, true); + $this->currentNode->appendChild($doCData ? $this->document->createCDATASection($data) : $this->document->createTextNode((string) $data)); + return; + } + return $doCData ? $this->document->createCDATASection($data) : $this->document->createTextNode((string) $data); + } + public function visitSimpleString($data, array $type, Context $context) + { + if (null === $this->document) { + $this->document = $this->createDocument(null, null, true); + $this->currentNode->appendChild($this->document->createTextNode((string) $data)); + return; + } + return $this->document->createTextNode((string) $data); + } + public function visitBoolean($data, array $type, Context $context) + { + if (null === $this->document) { + $this->document = $this->createDocument(null, null, true); + $this->currentNode->appendChild($this->document->createTextNode($data ? 'true' : 'false')); + return; + } + return $this->document->createTextNode($data ? 'true' : 'false'); + } + public function visitInteger($data, array $type, Context $context) + { + return $this->visitNumeric($data, $type); + } + public function visitDouble($data, array $type, Context $context) + { + return $this->visitNumeric($data, $type); + } + public function visitArray($data, array $type, Context $context) + { + if (null === $this->document) { + $this->document = $this->createDocument(null, null, true); + } + $entryName = (null !== $this->currentMetadata && null !== $this->currentMetadata->xmlEntryName) ? $this->currentMetadata->xmlEntryName : 'entry'; + $keyAttributeName = (null !== $this->currentMetadata && null !== $this->currentMetadata->xmlKeyAttribute) ? $this->currentMetadata->xmlKeyAttribute : null; + $namespace = (null !== $this->currentMetadata && null !== $this->currentMetadata->xmlEntryNamespace) ? $this->currentMetadata->xmlEntryNamespace : null; + foreach ($data as $k => $v) { + $tagName = (null !== $this->currentMetadata && $this->currentMetadata->xmlKeyValuePairs && $this->isElementNameValid($k)) ? $k : $entryName; + $entryNode = $this->createElement($tagName, $namespace); + $this->currentNode->appendChild($entryNode); + $this->setCurrentNode($entryNode); + if (null !== $keyAttributeName) { + $entryNode->setAttribute($keyAttributeName, (string) $k); + } + if (null !== $node = $this->navigator->accept($v, $this->getElementType($type), $context)) { + $this->currentNode->appendChild($node); + } + $this->revertCurrentNode(); + } + } + public function startVisitingObject(ClassMetadata $metadata, $data, array $type, Context $context) + { + $this->objectMetadataStack->push($metadata); + if (null === $this->document) { + $this->document = $this->createDocument(null, null, false); + if ($metadata->xmlRootName) { + $rootName = $metadata->xmlRootName; + $rootNamespace = $metadata->xmlRootNamespace?:$this->getClassDefaultNamespace($metadata); + } else { + $rootName = $this->defaultRootName; + $rootNamespace = $this->defaultRootNamespace; + } + if ($rootNamespace) { + $this->currentNode = $this->document->createElementNS($rootNamespace, $rootName); + } else { + $this->currentNode = $this->document->createElement($rootName); + } + $this->document->appendChild($this->currentNode); + } + $this->addNamespaceAttributes($metadata, $this->currentNode); + $this->hasValue = false; + } + public function visitProperty(PropertyMetadata $metadata, $object, Context $context) + { + $v = $metadata->getValue($object); + if (null === $v && !$context->shouldSerializeNull()) { + return; + } + if ($metadata->xmlAttribute) { + $this->setCurrentMetadata($metadata); + $node = $this->navigator->accept($v, $metadata->type, $context); + $this->revertCurrentMetadata(); + if (!$node instanceof DOMCharacterData) { + throw new RuntimeException(sprintf('Unsupported value for XML attribute for %s. Expected character data, but got %s.', $metadata->name, json_encode($v))); + } + $attributeName = $this->namingStrategy->translateName($metadata); + $this->setAttributeOnNode($this->currentNode, $attributeName, $node->nodeValue, $metadata->xmlNamespace); + return; + } + if (($metadata->xmlValue && $this->currentNode->childNodes->length > 0) + || (!$metadata->xmlValue && $this->hasValue)) { + throw new RuntimeException(sprintf('If you make use of @XmlValue, all other properties in the class must have the @XmlAttribute annotation. Invalid usage detected in class %s.', $metadata->class)); + } + if ($metadata->xmlValue) { + $this->hasValue = true; + $this->setCurrentMetadata($metadata); + $node = $this->navigator->accept($v, $metadata->type, $context); + $this->revertCurrentMetadata(); + if (!$node instanceof DOMCharacterData) { + throw new RuntimeException(sprintf('Unsupported value for property %s::$%s. Expected character data, but got %s.', $metadata->reflection->class, $metadata->reflection->name, is_object($node) ? get_class($node) : gettype($node))); + } + $this->currentNode->appendChild($node); + return; + } + if ($metadata->xmlAttributeMap) { + if (!is_array($v)) { + throw new RuntimeException(sprintf('Unsupported value type for XML attribute map. Expected array but got %s.', gettype($v))); + } + foreach ($v as $key => $value) { + $this->setCurrentMetadata($metadata); + $node = $this->navigator->accept($value, null, $context); + $this->revertCurrentMetadata(); + if (!$node instanceof DOMCharacterData) { + throw new RuntimeException(sprintf('Unsupported value for a XML attribute map value. Expected character data, but got %s.', json_encode($v))); + } + $this->setAttributeOnNode($this->currentNode, $key, $node->nodeValue, $metadata->xmlNamespace); + } + return; + } + if ($addEnclosingElement = (!$metadata->xmlCollection || !$metadata->xmlCollectionInline) && !$metadata->inline) { + $elementName = $this->namingStrategy->translateName($metadata); + if (null !== $metadata->xmlNamespace) { + $element = $this->createElement($elementName, $metadata->xmlNamespace); + } else { + $defaultNamespace = $this->getClassDefaultNamespace($this->objectMetadataStack->top()); + $element = $this->createElement($elementName, $defaultNamespace); + } + $this->setCurrentNode($element); + } + $this->setCurrentMetadata($metadata); + if (null !== $node = $this->navigator->accept($v, $metadata->type, $context)) { + $this->currentNode->appendChild($node); + } + $this->revertCurrentMetadata(); + if ($addEnclosingElement) { + $this->revertCurrentNode(); + if ($element->hasChildNodes() || $element->hasAttributes() + || (isset($metadata->type['name']) && $metadata->type['name'] === 'array' && isset($metadata->type['params'][1]))) { + $this->currentNode->appendChild($element); + } + } + $this->hasValue = false; + } + public function endVisitingObject(ClassMetadata $metadata, $data, array $type, Context $context) + { + $this->objectMetadataStack->pop(); + } + public function getResult() + { + return $this->document->saveXML(); + } + public function getCurrentNode() + { + return $this->currentNode; + } + public function getCurrentMetadata() + { + return $this->currentMetadata; + } + public function getDocument() + { + return $this->document; + } + public function setCurrentMetadata(PropertyMetadata $metadata) + { + $this->metadataStack->push($this->currentMetadata); + $this->currentMetadata = $metadata; + } + public function setCurrentNode(DOMNode $node) + { + $this->stack->push($this->currentNode); + $this->currentNode = $node; + } + public function revertCurrentNode() + { + return $this->currentNode = $this->stack->pop(); + } + public function revertCurrentMetadata() + { + return $this->currentMetadata = $this->metadataStack->pop(); + } + public function createDocument($version = null, $encoding = null, $addRoot = true) + { + $doc = new DOMDocument($version ?: $this->defaultVersion, $encoding ?: $this->defaultEncoding); + $doc->formatOutput = true; + if ($addRoot) { + if ($this->defaultRootNamespace) { + $rootNode = $doc->createElementNS($this->defaultRootNamespace, $this->defaultRootName); + } else { + $rootNode = $doc->createElement($this->defaultRootName); + } + $this->setCurrentNode($rootNode); + $doc->appendChild($rootNode); + } + return $doc; + } + public function prepare($data) + { + $this->nullWasVisited = false; + return $data; + } + private function visitNumeric($data, array $type) + { + if (null === $this->document) { + $this->document = $this->createDocument(null, null, true); + $this->currentNode->appendChild($textNode = $this->document->createTextNode((string) $data)); + return $textNode; + } + return $this->document->createTextNode((string) $data); + } + /** + * Checks that the name is a valid XML element name. + * + * @param string $name + * + * @return boolean + */ + private function isElementNameValid($name) + { + return $name && false === strpos($name, ' ') && preg_match('#^[\pL_][\pL0-9._-]*$#ui', $name); + } + private function attachNullNamespace() + { + if (!$this->nullWasVisited) { + $this->document->documentElement->setAttributeNS( + 'http://www.w3.org/2000/xmlns/', + 'xmlns:xsi', + 'http://www.w3.org/2001/XMLSchema-instance' + ); + $this->nullWasVisited = true; + } + } + /** + * Adds namespace attributes to the XML root element + * + * @param ClassMetadata $metadata + * @param DOMElement $element + */ + private function addNamespaceAttributes(ClassMetadata $metadata, DOMElement $element) + { + foreach ($metadata->xmlNamespaces as $prefix => $uri) { + $attribute = 'xmlns'; + if ($prefix !== '') { + $attribute .= ':'.$prefix; + } + $element->setAttributeNS('http://www.w3.org/2000/xmlns/', $attribute, $uri); + } + } + private function createElement($tagName, $namespace = null) + { + if (null !== $namespace) { + if ($this->currentNode->isDefaultNamespace($namespace)) { + return $this->document->createElementNS($namespace, $tagName); + } else { + if (!$prefix = $this->currentNode->lookupPrefix($namespace)) { + $prefix = 'ns-'. substr(sha1($namespace), 0, 8); + } + return $this->document->createElementNS($namespace, $prefix . ':' . $tagName); + } + } else { + return $this->document->createElement($tagName); + } + } + private function setAttributeOnNode(DOMElement $node, $name, $value, $namespace = null) + { + if (null !== $namespace) { + if (!$prefix = $node->lookupPrefix($namespace)) { + $prefix = 'ns-'. substr(sha1($namespace), 0, 8); + } + $node->setAttributeNS($namespace, $prefix.':'.$name, $value); + } else { + $node->setAttribute($name, $value); + } + } + private function getClassDefaultNamespace(ClassMetadata $metadata) + { + return (isset($metadata->xmlNamespaces[''])?$metadata->xmlNamespaces['']:null); + } +} \ No newline at end of file diff --git a/src/NFePHPSerialize.php b/src/NFePHPSerialize.php index b675ca0..b771a02 100644 --- a/src/NFePHPSerialize.php +++ b/src/NFePHPSerialize.php @@ -4,8 +4,12 @@ use Goetas\Xsd\XsdToPhp\Jms\Handler\BaseTypesHandler; use Goetas\Xsd\XsdToPhp\Jms\Handler\XmlSchemaDateHandler; +use JansenFelipe\NFePHPSerialize\JMS\Serializer\XmlDeserializationVisitorCustom; +use JansenFelipe\NFePHPSerialize\JMS\Serializer\XmlSerializationVisitorCustom; use JansenFelipe\NFePHPSerialize\NotaFiscal\NfeProc; use JMS\Serializer\Handler\HandlerRegistryInterface; +use JMS\Serializer\Naming\CamelCaseNamingStrategy; +use JMS\Serializer\Naming\SerializedNameAnnotationStrategy; use JMS\Serializer\Serializer; use JMS\Serializer\SerializerBuilder; @@ -41,6 +45,9 @@ public static function objectToXml(NfeProc $nfeProc) { private static function buildSerializer(){ $serializerBuilder = SerializerBuilder::create(); + $serializerBuilder->setSerializationVisitor('xml', new XmlSerializationVisitorCustom(new SerializedNameAnnotationStrategy(new CamelCaseNamingStrategy()))); + $serializerBuilder->setDeserializationVisitor('xml', new XmlDeserializationVisitorCustom(new SerializedNameAnnotationStrategy(new CamelCaseNamingStrategy()))); + $yamlDir = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'yaml'; $serializerBuilder->addMetadataDir($yamlDir.DIRECTORY_SEPARATOR.'NotaFiscal', 'JansenFelipe\NFePHPSerialize\NotaFiscal'); diff --git a/tests/NFePHPSerializeTest.php b/tests/NFePHPSerializeTest.php index f0a9ed8..843b37d 100644 --- a/tests/NFePHPSerializeTest.php +++ b/tests/NFePHPSerializeTest.php @@ -3,29 +3,26 @@ use JansenFelipe\NFePHPSerialize\NFePHPSerialize; use JansenFelipe\NFePHPSerialize\NotaFiscal\NfeProc; -class NFePHPSerializeTest extends PHPUnit_Framework_TestCase{ +class NFePHPSerializeTest extends PHPUnit_Framework_TestCase { public function testXml2Object() { //Nfe 2.00 $xml = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'nfe2.00.xml'); $this->assertInstanceOf(NfeProc::class, NFePHPSerialize::xmlToObject($xml)); - + //Nfe 3.10 $xml = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'nfe3.10.xml'); $this->assertInstanceOf(NfeProc::class, NFePHPSerialize::xmlToObject($xml)); - } - - public function testObject2Xml() { - $nfeProc = new NfeProc(); - $nfeProc->setVersao('8.00'); - - //Removing breaklines - $xml = preg_replace( "/\r|\n/", "", NFePHPSerialize::objectToXml($nfeProc)); - - $this->assertEquals('', $xml); - } + public function testObject2Xml() { + $nfeProc = new NfeProc(); + $nfeProc->setVersao('8.00'); + //Removing breaklines + $xml = preg_replace("/\r|\n/", "", NFePHPSerialize::objectToXml($nfeProc)); + + $this->assertEquals('', $xml); + } }