BraintreeUtil

Braintree Utility methods PHP version 5.

Defined (1)

The class is defined in the following location(s).

/classes/lib/Braintree/Braintree/Util.php  
  1. class Util 
  2. /** 
  3. * extracts an attribute and returns an array of objects 
  4. * extracts the requested element from an array, and converts the contents 
  5. * of its child arrays to objects of type $attributeName, or returns 
  6. * an array with a single element containing the value of that array element 
  7. * @param array $attribArray attributes from a search response 
  8. * @param string $attributeName indicates which element of the passed array to extract 
  9. * @return array array of $attributeName objects, or a single element array 
  10. */ 
  11. public static function extractAttributeAsArray(&$attribArray, $attributeName) 
  12. if(!isset($attribArray[$attributeName])): 
  13. return []; 
  14. endif; 
  15.  
  16. // get what should be an array from the passed array 
  17. $data = $attribArray[$attributeName]; 
  18. // set up the class that will be used to convert each array element 
  19. $classFactory = self::buildClassName($attributeName) . '::factory'; 
  20. if(is_array($data)): 
  21. // create an object from the data in each element 
  22. $objectArray = array_map($classFactory, $data); 
  23. else: 
  24. return [$data]; 
  25. endif; 
  26.  
  27. unset($attribArray[$attributeName]); 
  28. return $objectArray; 
  29. /** 
  30. * throws an exception based on the type of error 
  31. * @param string $statusCode HTTP status code to throw exception from 
  32. * @param null|string $message 
  33. * @throws Exception multiple types depending on the error 
  34. * @return void 
  35. */ 
  36. public static function throwStatusCodeException($statusCode, $message=null) 
  37. switch($statusCode) { 
  38. case 401: 
  39. throw new Exception\Authentication(); 
  40. break; 
  41. case 403: 
  42. throw new Exception\Authorization($message); 
  43. break; 
  44. case 404: 
  45. throw new Exception\NotFound(); 
  46. break; 
  47. case 426: 
  48. throw new Exception\UpgradeRequired(); 
  49. break; 
  50. case 500: 
  51. throw new Exception\ServerError(); 
  52. break; 
  53. case 503: 
  54. throw new Exception\DownForMaintenance(); 
  55. break; 
  56. default: 
  57. throw new Exception\Unexpected('Unexpected HTTP_RESPONSE #' . $statusCode); 
  58. break; 
  59.  
  60. /** 
  61. * @param string $className 
  62. * @param object $resultObj 
  63. * @return object returns the passed object if successful 
  64. * @throws Exception\ValidationsFailed 
  65. */ 
  66. public static function returnObjectOrThrowException($className, $resultObj) 
  67. $resultObjName = self::cleanClassName($className); 
  68. if ($resultObj->success) { 
  69. return $resultObj->$resultObjName; 
  70. } else { 
  71. throw new Exception\ValidationsFailed(); 
  72.  
  73. /** 
  74. * removes the header from a classname 
  75. * @param string $name ClassName 
  76. * @return camelCased classname minus header 
  77. */ 
  78. public static function cleanClassName($name) 
  79. $classNamesToResponseKeys = [ 
  80. 'Braintree\CreditCard' => 'creditCard',  
  81. 'Braintree_CreditCard' => 'creditCard',  
  82. 'Braintree\CreditCardGateway' => 'creditCard',  
  83. 'Braintree_CreditCardGateway' => 'creditCard',  
  84. 'Braintree\Customer' => 'customer',  
  85. 'Braintree_Customer' => 'customer',  
  86. 'Braintree\CustomerGateway' => 'customer',  
  87. 'Braintree_CustomerGateway' => 'customer',  
  88. 'Braintree\Subscription' => 'subscription',  
  89. 'Braintree_Subscription' => 'subscription',  
  90. 'Braintree\SubscriptionGateway' => 'subscription',  
  91. 'Braintree_SubscriptionGateway' => 'subscription',  
  92. 'Braintree\Transaction' => 'transaction',  
  93. 'Braintree_Transaction' => 'transaction',  
  94. 'Braintree\TransactionGateway' => 'transaction',  
  95. 'Braintree_TransactionGateway' => 'transaction',  
  96. 'Braintree\CreditCardVerification' => 'verification',  
  97. 'Braintree_CreditCardVerification' => 'verification',  
  98. 'Braintree\CreditCardVerificationGateway' => 'verification',  
  99. 'Braintree_CreditCardVerificationGateway' => 'verification',  
  100. 'Braintree\AddOn' => 'addOn',  
  101. 'Braintree_AddOn' => 'addOn',  
  102. 'Braintree\AddOnGateway' => 'addOn',  
  103. 'Braintree_AddOnGateway' => 'addOn',  
  104. 'Braintree\Discount' => 'discount',  
  105. 'Braintree_Discount' => 'discount',  
  106. 'Braintree\DiscountGateway' => 'discount',  
  107. 'Braintree_DiscountGateway' => 'discount',  
  108. 'Braintree\Plan' => 'plan',  
  109. 'Braintree_Plan' => 'plan',  
  110. 'Braintree\PlanGateway' => 'plan',  
  111. 'Braintree_PlanGateway' => 'plan',  
  112. 'Braintree\Address' => 'address',  
  113. 'Braintree_Address' => 'address',  
  114. 'Braintree\AddressGateway' => 'address',  
  115. 'Braintree_AddressGateway' => 'address',  
  116. 'Braintree\SettlementBatchSummary' => 'settlementBatchSummary',  
  117. 'Braintree_SettlementBatchSummary' => 'settlementBatchSummary',  
  118. 'Braintree\SettlementBatchSummaryGateway' => 'settlementBatchSummary',  
  119. 'Braintree_SettlementBatchSummaryGateway' => 'settlementBatchSummary',  
  120. 'Braintree\Merchant' => 'merchant',  
  121. 'Braintree_Merchant' => 'merchant',  
  122. 'Braintree\MerchantGateway' => 'merchant',  
  123. 'Braintree_MerchantGateway' => 'merchant',  
  124. 'Braintree\MerchantAccount' => 'merchantAccount',  
  125. 'Braintree_MerchantAccount' => 'merchantAccount',  
  126. 'Braintree\MerchantAccountGateway' => 'merchantAccount',  
  127. 'Braintree_MerchantAccountGateway' => 'merchantAccount',  
  128. 'Braintree\OAuthCredentials' => 'credentials',  
  129. 'Braintree_OAuthCredentials' => 'credentials',  
  130. 'Braintree\PayPalAccount' => 'paypalAccount',  
  131. 'Braintree_PayPalAccount' => 'paypalAccount',  
  132. 'Braintree\PayPalAccountGateway' => 'paypalAccount',  
  133. 'Braintree_PayPalAccountGateway' => 'paypalAccount',  
  134. ]; 
  135.  
  136. return $classNamesToResponseKeys[$name]; 
  137.  
  138. /** 
  139. * @param string $name className 
  140. * @return string ClassName 
  141. */ 
  142. public static function buildClassName($name) 
  143. $responseKeysToClassNames = [ 
  144. 'creditCard' => 'Braintree\CreditCard',  
  145. 'customer' => 'Braintree\Customer',  
  146. 'subscription' => 'Braintree\Subscription',  
  147. 'transaction' => 'Braintree\Transaction',  
  148. 'verification' => 'Braintree\CreditCardVerification',  
  149. 'addOn' => 'Braintree\AddOn',  
  150. 'discount' => 'Braintree\Discount',  
  151. 'plan' => 'Braintree\Plan',  
  152. 'address' => 'Braintree\Address',  
  153. 'settlementBatchSummary' => 'Braintree\SettlementBatchSummary',  
  154. 'merchantAccount' => 'Braintree\MerchantAccount',  
  155. ]; 
  156.  
  157. return (string) $responseKeysToClassNames[$name]; 
  158.  
  159. /** 
  160. * convert alpha-beta-gamma to alphaBetaGamma 
  161. * @access public 
  162. * @param string $string 
  163. * @param null|string $delimiter 
  164. * @return string modified string 
  165. */ 
  166. public static function delimiterToCamelCase($string, $delimiter = '[\-\_]') 
  167. // php doesn't garbage collect functions created by create_function() 
  168. // so use a static variable to avoid adding a new function to memory 
  169. // every time this function is called. 
  170. static $callback = null; 
  171. if ($callback === null) { 
  172. $callback = create_function('$matches', 'return strtoupper($matches[1]);'); 
  173.  
  174. return preg_replace_callback('/' . $delimiter . '(\w)/', $callback, $string); 
  175.  
  176. /** 
  177. * convert alpha-beta-gamma to alpha_beta_gamma 
  178. * @access public 
  179. * @param string $string 
  180. * @return string modified string 
  181. */ 
  182. public static function delimiterToUnderscore($string) 
  183. return preg_replace('/-/', '_', $string); 
  184.  
  185.  
  186. /** 
  187. * find capitals and convert to delimiter + lowercase 
  188. * @access public 
  189. * @param string $string 
  190. * @param null|string $delimiter 
  191. * @return string modified string 
  192. */ 
  193. public static function camelCaseToDelimiter($string, $delimiter = '-') 
  194. return strtolower(preg_replace('/([A-Z])/', "$delimiter\\1", $string)); 
  195.  
  196. public static function delimiterToCamelCaseArray($array, $delimiter = '[\-\_]') 
  197. $converted = []; 
  198. foreach ($array as $key => $value) { 
  199. if (is_string($key)) { 
  200. $key = self::delimiterToCamelCase($key, $delimiter); 
  201.  
  202. if (is_array($value)) { 
  203. // Make an exception for custom fields, which must be underscore (can't be 
  204. // camelCase). 
  205. if ($key === 'customFields') { 
  206. $value = self::delimiterToUnderscoreArray($value); 
  207. } else { 
  208. $value = self::delimiterToCamelCaseArray($value, $delimiter); 
  209. $converted[$key] = $value; 
  210. return $converted; 
  211.  
  212. public static function camelCaseToDelimiterArray($array, $delimiter = '-') 
  213. $converted = []; 
  214. foreach ($array as $key => $value) { 
  215. if (is_string($key)) { 
  216. $key = self::camelCaseToDelimiter($key, $delimiter); 
  217. if (is_array($value)) { 
  218. $value = self::camelCaseToDelimiterArray($value, $delimiter); 
  219. $converted[$key] = $value; 
  220. return $converted; 
  221.  
  222. public static function delimiterToUnderscoreArray($array) 
  223. $converted = []; 
  224. foreach ($array as $key => $value) { 
  225. $key = self::delimiterToUnderscore($key); 
  226. $converted[$key] = $value; 
  227. return $converted; 
  228.  
  229. /** 
  230. * @param array $array associative array to implode 
  231. * @param string $separator (optional, defaults to =) 
  232. * @param string $glue (optional, defaults to ', ') 
  233. * @return bool 
  234. */ 
  235. public static function implodeAssociativeArray($array, $separator = '=', $glue = ', ') 
  236. // build a new array with joined keys and values 
  237. $tmpArray = null; 
  238. foreach ($array AS $key => $value) { 
  239. if ($value instanceof DateTime) { 
  240. $value = $value->format('r'); 
  241. $tmpArray[] = $key . $separator . $value; 
  242. // implode and return the new array 
  243. return (is_array($tmpArray)) ? implode($glue, $tmpArray) : false; 
  244.  
  245. public static function attributesToString($attributes) { 
  246. $printableAttribs = []; 
  247. foreach ($attributes AS $key => $value) { 
  248. if (is_array($value)) { 
  249. $pAttrib = self::attributesToString($value); 
  250. } else if ($value instanceof DateTime) { 
  251. $pAttrib = $value->format(DateTime::RFC850); 
  252. } else { 
  253. $pAttrib = $value; 
  254. $printableAttribs[$key] = sprintf('%s', $pAttrib); 
  255. return self::implodeAssociativeArray($printableAttribs); 
  256.  
  257. /** 
  258. * verify user request structure 
  259. * compares the expected signature of a gateway request 
  260. * against the actual structure sent by the user 
  261. * @param array $signature 
  262. * @param array $attributes 
  263. */ 
  264. public static function verifyKeys($signature, $attributes) 
  265. $validKeys = self::_flattenArray($signature); 
  266. $userKeys = self::_flattenUserKeys($attributes); 
  267. $invalidKeys = array_diff($userKeys, $validKeys); 
  268. $invalidKeys = self::_removeWildcardKeys($validKeys, $invalidKeys); 
  269.  
  270. if(!empty($invalidKeys)) { 
  271. asort($invalidKeys); 
  272. $sortedList = join(', ', $invalidKeys); 
  273. throw new InvalidArgumentException('invalid keys: ' . $sortedList); 
  274. /** 
  275. * flattens a numerically indexed nested array to a single level 
  276. * @param array $keys 
  277. * @param string $namespace 
  278. * @return array 
  279. */ 
  280. private static function _flattenArray($keys, $namespace = null) 
  281. $flattenedArray = []; 
  282. foreach($keys AS $key) { 
  283. if(is_array($key)) { 
  284. $theKeys = array_keys($key); 
  285. $theValues = array_values($key); 
  286. $scope = $theKeys[0]; 
  287. $fullKey = empty($namespace) ? $scope : $namespace . '[' . $scope . ']'; 
  288. $flattenedArray = array_merge($flattenedArray, self::_flattenArray($theValues[0], $fullKey)); 
  289. } else { 
  290. $fullKey = empty($namespace) ? $key : $namespace . '[' . $key . ']'; 
  291. $flattenedArray[] = $fullKey; 
  292. sort($flattenedArray); 
  293. return $flattenedArray; 
  294.  
  295. private static function _flattenUserKeys($keys, $namespace = null) 
  296. $flattenedArray = []; 
  297.  
  298. foreach($keys AS $key => $value) { 
  299. $fullKey = empty($namespace) ? $key : $namespace; 
  300. if (!is_numeric($key) && $namespace != null) { 
  301. $fullKey .= '[' . $key . ']'; 
  302. if (is_numeric($key) && is_string($value)) { 
  303. $fullKey .= '[' . $value . ']'; 
  304. if(is_array($value)) { 
  305. $more = self::_flattenUserKeys($value, $fullKey); 
  306. $flattenedArray = array_merge($flattenedArray, $more); 
  307. } else { 
  308. $flattenedArray[] = $fullKey; 
  309. sort($flattenedArray); 
  310. return $flattenedArray; 
  311.  
  312. /** 
  313. * removes wildcard entries from the invalid keys array 
  314. * @param array $validKeys 
  315. * @param <array $invalidKeys 
  316. * @return array 
  317. */ 
  318. private static function _removeWildcardKeys($validKeys, $invalidKeys) 
  319. foreach($validKeys AS $key) { 
  320. if (stristr($key, '[_anyKey_]')) { 
  321. $wildcardKey = str_replace('[_anyKey_]', '', $key); 
  322. foreach ($invalidKeys AS $index => $invalidKey) { 
  323. if (stristr($invalidKey, $wildcardKey)) { 
  324. unset($invalidKeys[$index]); 
  325. return $invalidKeys;