PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/braintree/braintree_php/lib/Braintree/Xml/Parser.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 173 lines | 95 code | 20 blank | 58 comment | 19 complexity | c01a36c60fda72e76efa36cc8c32fccb MD5 | raw file
  1. <?php
  2. /**
  3. * Braintree XML Parser
  4. *
  5. * @copyright 2014 Braintree, a division of PayPal, Inc.
  6. */
  7. /**
  8. * Parses incoming Xml into arrays using PHP's
  9. * built-in SimpleXML, and its extension via
  10. * Iterator, SimpleXMLIterator
  11. *
  12. * @copyright 2014 Braintree, a division of PayPal, Inc.
  13. */
  14. class Braintree_Xml_Parser
  15. {
  16. private static $_xmlRoot;
  17. private static $_responseType;
  18. /**
  19. * sets up the SimpleXMLIterator and starts the parsing
  20. * @access public
  21. * @param string $xml
  22. * @return array array mapped to the passed xml
  23. */
  24. public static function arrayFromXml($xml)
  25. {
  26. // SimpleXML provides the root information on construct
  27. $iterator = new SimpleXMLIterator($xml);
  28. $xmlRoot = $iterator->getName();
  29. $type = $iterator->attributes()->type;
  30. self::$_xmlRoot = $iterator->getName();
  31. self::$_responseType = $type;
  32. // return the mapped array with the root element as the header
  33. $array = array($xmlRoot => self::_iteratorToArray($iterator));
  34. return Braintree_Util::delimiterToCamelCaseArray($array);
  35. }
  36. /**
  37. * processes SimpleXMLIterator objects recursively
  38. *
  39. * @access protected
  40. * @param object $iterator
  41. * @return array xml converted to array
  42. */
  43. private static function _iteratorToArray($iterator)
  44. {
  45. $xmlArray = array();
  46. $value = null;
  47. // rewind the iterator and check if the position is valid
  48. // if not, return the string it contains
  49. $iterator->rewind();
  50. if (!$iterator->valid()) {
  51. return self::_typecastXmlValue($iterator);
  52. }
  53. for ($iterator->rewind(); $iterator->valid(); $iterator->next()) {
  54. $tmpArray = null;
  55. $value = null;
  56. // get the attribute type string for use in conditions below
  57. $attributeType = $iterator->attributes()->type;
  58. // extract the parent element via xpath query
  59. $parentElement = $iterator->xpath($iterator->key() . '/..');
  60. if ($parentElement[0] instanceof SimpleXMLIterator) {
  61. $parentElement = $parentElement[0];
  62. } else {
  63. $parentElement = null;
  64. }
  65. $key = $iterator->key();
  66. // process children recursively
  67. if ($iterator->hasChildren()) {
  68. // return the child elements
  69. $value = self::_iteratorToArray($iterator->current());
  70. // if the element is an array type,
  71. // use numeric keys to allow multiple values
  72. if ($attributeType != 'array') {
  73. $tmpArray[$key] = $value;
  74. }
  75. } else {
  76. // cast values according to attributes
  77. $tmpArray[$key] = self::_typecastXmlValue($iterator->current());
  78. }
  79. // set the output string
  80. $output = isset($value) ? $value : $tmpArray[$key];
  81. // determine if there are multiple tags of this name at the same level
  82. if (isset($parentElement) &&
  83. ($parentElement->attributes()->type == 'collection') &&
  84. $iterator->hasChildren()) {
  85. $xmlArray[$key][] = $output;
  86. continue;
  87. }
  88. // if the element was an array type, output to a numbered key
  89. // otherwise, use the element name
  90. if ($attributeType == 'array') {
  91. $xmlArray[] = $output;
  92. } else {
  93. $xmlArray[$key] = $output;
  94. }
  95. }
  96. return $xmlArray;
  97. }
  98. /**
  99. * typecast xml value based on attributes
  100. * @param object $valueObj SimpleXMLElement
  101. * @return mixed value for placing into array
  102. */
  103. private static function _typecastXmlValue($valueObj)
  104. {
  105. // get the element attributes
  106. $attribs = $valueObj->attributes();
  107. // the element is null, so jump out here
  108. if (isset($attribs->nil) && $attribs->nil) {
  109. return null;
  110. }
  111. // switch on the type attribute
  112. // switch works even if $attribs->type isn't set
  113. switch ($attribs->type) {
  114. case 'datetime':
  115. return self::_timestampToUTC((string) $valueObj);
  116. break;
  117. case 'date':
  118. return new DateTime((string)$valueObj);
  119. break;
  120. case 'integer':
  121. return (int) $valueObj;
  122. break;
  123. case 'boolean':
  124. $value = (string) $valueObj;
  125. // look for a number inside the string
  126. if(is_numeric($value)) {
  127. return (bool) $value;
  128. } else {
  129. // look for the string "true", return false in all other cases
  130. return ($value != "true") ? FALSE : TRUE;
  131. }
  132. break;
  133. case 'array':
  134. return array();
  135. default:
  136. return (string) $valueObj;
  137. }
  138. }
  139. /**
  140. * convert xml timestamps into DateTime
  141. * @param string $timestamp
  142. * @return string UTC formatted datetime string
  143. */
  144. private static function _timestampToUTC($timestamp)
  145. {
  146. $tz = new DateTimeZone('UTC');
  147. // strangely DateTime requires an explicit set below
  148. // to show the proper time zone
  149. $dateTime = new DateTime($timestamp, $tz);
  150. $dateTime->setTimezone($tz);
  151. return $dateTime;
  152. }
  153. }