/**
  * @param $params
  * @param $allowedParams
  * @param string $validationLevel allows override global validation level settings
  * @return array
  */
 public static function sanitize($params, $allowedParams, $validationLevel = null)
 {
     $notAllowedParams = self::getNotAllowedParams($params, $allowedParams);
     if (count($notAllowedParams) > 0) {
         if ($validationLevel === null) {
             $validationLevel = BlockCypherConfigManager::getInstance()->get('validation.level');
         }
         foreach ($notAllowedParams as $key => $value) {
             $validationMessage = "Param {$key} not allowed: It can be a typo in the param name or you should update the PHP SDK library.";
             switch ($validationLevel) {
                 case 'log':
                     // logs the error message to logger only (default)
                     $logger = BlockCypherLoggingManager::getInstance(__CLASS__);
                     $logger->warning($validationMessage);
                     break;
                 case 'strict':
                     // throws a php notice message
                     trigger_error($validationMessage, E_USER_NOTICE);
                     break;
                 case 'disable':
                     // disable the validation
                     break;
             }
         }
         if ($validationLevel == 'strict') {
             // Do not add not allowed params to the url
             $params = array_intersect_key($params, $allowedParams);
             return $params;
         }
         return $params;
     }
     return $params;
 }
 /**
  * Helper method for validating if the class contains accessor methods (getter and setter) for a given attribute
  *
  * @param BlockCypherModel $class An object of BlockCypherModel
  * @param string $attributeName Attribute name
  * @return bool
  */
 public static function validate(BlockCypherModel $class, $attributeName)
 {
     $mode = BlockCypherConfigManager::getInstance()->get('validation.level');
     // Default value if validation.level was not specified.
     if (is_array($mode)) {
         $mode = 'log';
     }
     // Check valid validation level
     if (!in_array($mode, array('log', 'strict', 'disabled'))) {
         trigger_error('Invalid validation.level in configuration', E_USER_NOTICE);
     }
     if (!empty($mode) && $mode != 'disabled') {
         //Check if $attributeName is string
         if (gettype($attributeName) !== 'string') {
             return false;
         }
         //If the mode is disabled, bypass the validation
         foreach (array('set' . $attributeName, 'get' . $attributeName) as $methodName) {
             if (get_class($class) == get_class(new BlockCypherModel())) {
                 // Silently return false on cases where you are using BlockCypherModel instance directly
                 return false;
             } elseif (!method_exists($class, $methodName)) {
                 //Delegate the error based on the choice
                 $className = is_object($class) ? get_class($class) : (string) $class;
                 $errorMessage = "Missing Accessor: {$className}:{$methodName}. You might be using older version of SDK. If not, create an issue at https://github.com/blockcypher/php-client/issues";
                 BlockCypherLoggingManager::getInstance(__CLASS__)->debug($errorMessage);
                 if ($mode == 'strict') {
                     trigger_error($errorMessage, E_USER_NOTICE);
                 }
                 return false;
             }
         }
         return true;
     }
     return false;
 }
 /**
  * Default Constructor
  *
  * @param ApiContext $apiContext
  */
 public function __construct(ApiContext $apiContext)
 {
     $this->apiContext = $apiContext;
     $this->logger = BlockCypherLoggingManager::getInstance(__CLASS__);
 }
 /**
  * Construct
  *
  * @param null $accessToken
  */
 public function __construct($accessToken)
 {
     $this->accessToken = $accessToken;
     $this->logger = BlockCypherLoggingManager::getInstance(__CLASS__);
 }
 /**
  * Executes an HTTP request
  *
  * @param string $data query string OR POST content as a string
  * @return mixed
  * @throws BlockCypherConnectionException
  */
 public function execute($data)
 {
     //Initialize the logger
     $this->logger->info($this->httpConfig->getMethod() . ' ' . $this->httpConfig->getUrl());
     //Initialize Curl Options
     $ch = curl_init($this->httpConfig->getUrl());
     curl_setopt_array($ch, $this->httpConfig->getCurlOptions());
     curl_setopt($ch, CURLOPT_URL, $this->httpConfig->getUrl());
     curl_setopt($ch, CURLOPT_HEADER, true);
     curl_setopt($ch, CURLINFO_HEADER_OUT, true);
     curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHttpHeaders());
     //Determine Curl Options based on Method
     switch ($this->httpConfig->getMethod()) {
         case 'POST':
             curl_setopt($ch, CURLOPT_POST, true);
         case 'PUT':
         case 'PATCH':
         case 'DELETE':
             curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
             break;
     }
     //Default Option if Method not of given types in switch case
     if ($this->httpConfig->getMethod() != NULL) {
         curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->httpConfig->getMethod());
     }
     //Logging Each Headers for debugging purposes
     foreach ($this->getHttpHeaders() as $header) {
         //TODO: Strip out credentials and other secure info when logging.
         // $this->logger->debug($header);
     }
     //Execute Curl Request
     $result = curl_exec($ch);
     //Retrieve Response Status
     $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     //Retry if Certificate Exception
     if (curl_errno($ch) == 60) {
         $this->logger->info("Invalid or no certificate authority found - Retrying using bundled CA certs file");
         curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
         $result = curl_exec($ch);
         //Retrieve Response Status
         $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     }
     //Retry if Failing
     $retries = 0;
     if (in_array($httpStatus, self::$retryCodes) && $this->httpConfig->getHttpRetryCount() != null) {
         $this->logger->info("Got {$httpStatus} response from server. Retrying");
         do {
             $result = curl_exec($ch);
             //Retrieve Response Status
             $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
         } while (in_array($httpStatus, self::$retryCodes) && ++$retries < $this->httpConfig->getHttpRetryCount());
     }
     //Throw Exception if Retries and Certificates does not work
     if (curl_errno($ch)) {
         $ex = new BlockCypherConnectionException($this->httpConfig->getUrl(), curl_error($ch), curl_errno($ch));
         curl_close($ch);
         throw $ex;
     }
     // Get Request and Response Headers
     $requestHeaders = curl_getinfo($ch, CURLINFO_HEADER_OUT);
     //Using alternative solution to CURLINFO_HEADER_SIZE as it throws invalid number when called using PROXY.
     $responseHeaderSize = strlen($result) - curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
     $responseHeaders = substr($result, 0, $responseHeaderSize);
     $result = substr($result, $responseHeaderSize);
     //$this->logger->debug("Request Retries \t: " . $retries);
     $this->logger->debug("Request Headers \t: " . str_replace("\r\n", ", ", $requestHeaders));
     $this->logger->debug(($data && $data != '' ? "Request Data\t\t: " . $data : "No Request Payload") . "\n" . str_repeat('-', 128) . "\n");
     $this->logger->info("Response Status \t: " . $httpStatus);
     $this->logger->debug("Response Headers\t: " . str_replace("\r\n", ", ", $responseHeaders));
     //Close the curl request
     curl_close($ch);
     //More Exceptions based on HttpStatus Code
     if (in_array($httpStatus, self::$retryCodes)) {
         $ex = new BlockCypherConnectionException($this->httpConfig->getUrl(), "Got Http response code {$httpStatus} when accessing {$this->httpConfig->getUrl()}. " . "Retried {$retries} times.");
         $ex->setData($result);
         $this->logger->error("Got Http response code {$httpStatus} when accessing {$this->httpConfig->getUrl()}. " . "Retried {$retries} times." . $result);
         $this->logger->debug("\n\n" . str_repeat('=', 128) . "\n");
         throw $ex;
     } else {
         if ($httpStatus < 200 || $httpStatus >= 300) {
             $ex = new BlockCypherConnectionException($this->httpConfig->getUrl(), "Got Http response code {$httpStatus} when accessing {$this->httpConfig->getUrl()}.", $httpStatus);
             $ex->setData($result);
             $this->logger->error("Got Http response code {$httpStatus} when accessing {$this->httpConfig->getUrl()}. " . $result);
             $this->logger->debug("\n\n" . str_repeat('=', 128) . "\n");
             throw $ex;
         }
     }
     $this->logger->debug(($result && $result != '' ? "Response Data \t: " . $result : "No Response Body") . "\n\n" . str_repeat('=', 128) . "\n");
     //Return result object
     return $result;
 }
Example #6
0
 /**
  * Fills object value from Array list
  *
  * @param $arr
  * @return $this
  */
 public function fromArray($arr)
 {
     if (!empty($arr)) {
         // Iterate over each element in array
         foreach ($arr as $k => $v) {
             // If the value is an array, it means, it is an object after conversion
             if (is_array($v)) {
                 // Determine the class of the object
                 if (($clazz = ReflectionUtil::getPropertyClass(get_class($this), $k)) != null) {
                     // If the value is an associative array, it means, its an object. Just make recursive call to it.
                     if (empty($v)) {
                         if (ReflectionUtil::isPropertyClassArray(get_class($this), $k)) {
                             // It means, it is an array of objects.
                             $this->assignValue($k, array());
                             continue;
                         }
                         $o = new $clazz();
                         //$arr = array();
                         $this->assignValue($k, $o);
                     } elseif (ArrayUtil::isAssocArray($v)) {
                         /** @var BlockCypherModel $o */
                         $o = new $clazz();
                         $o->fromArray($v);
                         $this->assignValue($k, $o);
                     } else {
                         // Else, value is an array of object/data
                         $arr = array();
                         // Iterate through each element in that array.
                         foreach ($v as $nk => $nv) {
                             if (is_array($nv)) {
                                 //BlockCypherLoggingManager::getInstance()->debug("new instance of class: $clazz");
                                 if (!class_exists($clazz)) {
                                     BlockCypherLoggingManager::getInstance()->error("Class not found: {$clazz}");
                                 } else {
                                     try {
                                         $o = new $clazz();
                                         $o->fromArray($nv);
                                         $arr[$nk] = $o;
                                     } catch (\Exception $e) {
                                         BlockCypherLoggingManager::getInstance()->error($e->getMessage());
                                     }
                                 }
                             } else {
                                 $arr[$nk] = $nv;
                             }
                         }
                         $this->assignValue($k, $arr);
                     }
                 } else {
                     $this->assignValue($k, $v);
                 }
             } else {
                 $this->assignValue($k, $v);
             }
         }
     }
     return $this;
 }
 /**
  * Sets up the fixture, for example, opens a network connection.
  * This method is called before a test is executed.
  */
 protected function setUp()
 {
     $this->object = BlockCypherLoggingManager::getInstance('AddressTest');
 }