/** * Prepare query string and request body using variables to be sent in get and request_structure to be sent as JSON in body * from method definition. * * @param array $request_result Array returned by S2P_SDK_Rest_API_Request::do_curl() call * * @return array|bool Returns an array with parsed data from response buffer or false on error */ public function parse_response($request_result) { if (!$this->validate_definition()) { return false; } $return_arr = self::default_response_data(); $return_arr['func'] = $this->_functionality; $return_arr['response_array'] = array(); $return_arr['response_structure'] = self::RESPONSE_STRUCT_UNKNOWN; if (!($request_result = S2P_SDK_Rest_API_Request::validate_request_array($request_result)) or $request_result['response_buffer'] == '') { return $return_arr; } $return_arr['request_http_code'] = $request_result['http_code']; if ($http_code_error = self::get_http_code_error($request_result['http_code'])) { if ($generic_obj = new S2P_SDK_Structure_Generic_Error() and $json_array = $generic_obj->extract_info_from_response_buffer($request_result['response_buffer'], array('output_null_values' => true)) and !empty($json_array['message'])) { // a bit useless, but we might change return value in the future... $return_arr['response_structure'] = self::RESPONSE_STRUCT_UNKNOWN; $error_str = $http_code_error; if (!empty($json_array['message'])) { $error_str .= ' ' . $json_array['message']; } $this->set_error(self::ERR_RESPONSE_DATA, $error_str); return false; } elseif (!empty($this->_definition['error_structure'])) { $return_arr['response_structure'] = self::RESPONSE_STRUCT_ERROR; /** @var S2P_SDK_Scope_Structure $error_structure */ $error_structure = $this->_definition['error_structure']; if (!($json_array = $error_structure->extract_info_from_response_buffer($request_result['response_buffer'], array('output_null_values' => true))) or !is_array($json_array)) { if ($parsing_error = $error_structure->get_parsing_error()) { $this->copy_error_from_array($parsing_error); } elseif (!empty($http_code_error)) { $this->set_error(self::ERR_RESPONSE_DATA, $http_code_error); } else { $this->set_error(self::ERR_RESPONSE_DATA, self::s2p_t('Couldn\'t extract respose data or response data is empty.')); } return false; } if (!empty($this->_definition['mandatory_in_error']) and is_array($this->_definition['mandatory_in_error'])) { if (!$this->check_mandatory_fields($json_array, $this->_definition['mandatory_in_error'], array('scope_arr_type' => 'response error', 'structure_obj' => $error_structure))) { if (!$this->has_error()) { $this->set_error(self::ERR_RESPONSE_MANDATORY, self::s2p_t('Mandatory fields not found in response error.')); } return false; } } if (!empty($this->_definition['hide_in_error']) and is_array($this->_definition['hide_in_error'])) { $json_array = $this->remove_fields($json_array, $this->_definition['hide_in_error'], array('scope_arr_type' => 'response error')); } $return_arr['response_array'] = $json_array; } else { $this->set_error(self::ERR_HTTP_ERROR, self::s2p_t('Server returned error code %s (%s).', $request_result['http_code'], $http_code_error)); return false; } } elseif (!empty($this->_definition['response_structure'])) { $return_arr['response_structure'] = self::RESPONSE_STRUCT_RESPONSE; /** @var S2P_SDK_Scope_Structure $response_structure */ $response_structure = $this->_definition['response_structure']; if (!($json_array = $response_structure->extract_info_from_response_buffer($request_result['response_buffer'], array('output_null_values' => true))) or !is_array($json_array)) { if ($parsing_error = $response_structure->get_parsing_error()) { $this->copy_error_from_array($parsing_error); } else { $this->set_error(self::ERR_RESPONSE_DATA, self::s2p_t('Couldn\'t extract respose data or response data is empty.')); } return false; } if (!empty($this->_definition['mandatory_in_response']) and is_array($this->_definition['mandatory_in_response'])) { if (!$this->check_mandatory_fields($json_array, $this->_definition['mandatory_in_response'], array('scope_arr_type' => 'response', 'structure_obj' => $response_structure))) { if (!$this->has_error()) { $this->set_error(self::ERR_RESPONSE_MANDATORY, self::s2p_t('Mandatory fields not found in response.')); } return false; } } if (!empty($this->_definition['hide_in_response']) and is_array($this->_definition['hide_in_response'])) { $json_array = $this->remove_fields($json_array, $this->_definition['hide_in_response'], array('scope_arr_type' => 'response')); } $return_arr['response_array'] = $json_array; } return $return_arr; }
public function do_call($params = false) { $this->reset_call_result(); if (empty($params) or !is_array($params)) { $params = array(); } if (empty($params['user_agent']) or !is_string($params['user_agent'])) { $params['user_agent'] = ''; } if (empty($params['allow_remote_calls'])) { $params['allow_remote_calls'] = false; } if (empty($params['quick_return_request'])) { $params['quick_return_request'] = false; } if (empty($params['custom_validators']) or !is_array($params['custom_validators'])) { $params['custom_validators'] = array(); } if (empty($this->_method)) { $this->set_error(self::ERR_METHOD, self::s2p_t('Method not set')); return false; } if (!($api_key = $this->get_api_key())) { $this->set_error(self::ERR_APIKEY, self::s2p_t('API Key not set.')); return false; } if (!($site_id = $this->get_site_id())) { $this->set_error(self::ERR_SITE_ID, self::s2p_t('Site ID not set.')); return false; } if (!$this->validate_base_url() or empty($this->_base_url)) { $this->set_error(self::ERR_URL, self::s2p_t('Couldn\'t obtain base URL.')); return false; } if (!($request_data = $this->_method->prepare_for_request($params))) { if ($this->_method->has_error()) { $this->copy_error($this->_method); } else { $this->set_error(self::ERR_PREPARE_REQUEST, self::s2p_t('Couldn\'t prepare request data.')); } return false; } if ($hook_result = $this->trigger_hooks('rest_api_prepare_request_after', array('api_obj' => $this, 'request_data' => $request_data)) and is_array($hook_result)) { if (array_key_exists('request_data', $hook_result)) { $request_data = $hook_result['request_data']; } } $final_url = $this->_base_url . $request_data['full_query']; if (!empty($params['quick_return_request'])) { $return_arr = array(); $return_arr['final_url'] = $final_url; $return_arr['request_data'] = $request_data; return $return_arr; } if (!($this->_request = new S2P_SDK_Rest_API_Request())) { $this->set_error(self::ERR_PREPARE_REQUEST, self::s2p_t('Couldn\'t prepare API request.')); return false; } if (empty($request_data['http_method']) or !$this->_request->set_http_method($request_data['http_method'])) { $this->set_error(self::ERR_HTTP_METHOD, self::s2p_t('Couldn\'t set HTTP method.')); return false; } if (!$this->_request->set_url($final_url)) { $this->set_error(self::ERR_URL, self::s2p_t('Couldn\'t set final URL.')); return false; } if (!empty($request_data['request_body'])) { $this->_request->set_body($request_data['request_body']); } $this->_request->add_header('Content-Type', 'application/json; charset=utf-8'); $call_params = array(); if (empty($params['user_agent'])) { $call_params['user_agent'] = 'APISDK_' . S2P_SDK_VERSION . '/PHP_' . phpversion() . '/' . php_uname('s') . '_' . php_uname('r'); } else { $call_params['user_agent'] = trim($params['user_agent']); } $call_params['userpass'] = array('user' => $site_id, 'pass' => $api_key); $this->trigger_hooks('rest_api_call_before', array('api_obj' => $this)); if (!($request_result = $this->_request->do_curl($call_params))) { $request_result = null; } if ($hook_result = $this->trigger_hooks('rest_api_request_result', array('api_obj' => $this, 'request_result' => $request_result)) and is_array($hook_result)) { if (array_key_exists('request_result', $hook_result)) { $request_result = S2P_SDK_Rest_API_Request::validate_request_array($hook_result['request_result']); } } if (empty($request_result)) { if ($this->_request->has_error()) { $this->copy_error($this->_request); } else { $this->set_error(self::ERR_CURL_CALL, self::s2p_t('Error sending API call')); } return false; } $return_arr = self::default_call_result(); $return_arr['final_url'] = $final_url; $return_arr['request'] = $request_result; $this->_call_result = $return_arr; if (!in_array($request_result['http_code'], S2P_SDK_Rest_API_Codes::success_codes())) { $code_str = $request_result['http_code']; if ($code_details = S2P_SDK_Rest_API_Codes::valid_code($request_result['http_code'])) { $code_str .= ' (' . $code_details . ')'; } // Set a generic error as maybe we will get more specific errors later when parsing response. Don't throw this error yet... $this->set_error(self::ERR_CURL_CALL, self::s2p_t('Request responded with error code %s', $code_str), '', array('prevent_throwing_errors' => true)); if (empty($request_result['response_buffer'])) { // In case there's nothing to parse, throw generic error... if ($this->throw_errors()) { $this->throw_error(); } return false; } } if (!($response_data = $this->_method->parse_response($request_result))) { if ($this->_method->has_error()) { $this->copy_error($this->_method); } if ($this->has_error()) { if ($this->throw_errors()) { $this->throw_error(); } return false; } $this->set_error(self::ERR_PARSE_RESPONSE, self::s2p_t('Error parsing server response.')); return false; } if ($hook_result = $this->trigger_hooks('rest_rest_api_response_data', array('api_obj' => $this, 'response_data' => $response_data)) and is_array($hook_result)) { if (array_key_exists('response_data', $hook_result)) { $response_data = $hook_result['response_data']; } } if (!$this->_method->validate_response($response_data)) { if ($this->_method->has_error()) { $this->copy_error($this->_method); } else { $this->set_error(self::ERR_VALIDATE_RESPONSE, self::s2p_t('Error validating server response.')); } return false; } $return_arr['response'] = $response_data; $this->_call_result = $return_arr; // Make sure errors get thrown if any... if ($this->has_error() and $this->throw_errors()) { $this->throw_error(); return false; } return $return_arr; }