public function go($endpoint_name, $endpoint_vars = array(), $local_vars = array()) { if (is_array($local_vars)) { $this->local_vars = $local_vars; } // must set endpoint name before checking for bypass_prerequisites $this->config->custom_endpoint_name = $endpoint_name; $this->config->set_actual_endpoint_name(); $this->config->apply_custom_endpoint_params(); if (empty($this->config->settings->endpoints->{$this->config->custom_endpoint_name}->bypass_prerequisites)) { $this->process_prerequisites(); } // must set endpoint name after processing prerequisites to setup requested endpoint $this->config->custom_endpoint_name = $endpoint_name; $this->config->set_actual_endpoint_name(); $this->config->apply_custom_endpoint_params(); if (empty($this->config->settings->endpoints->{$this->config->actual_endpoint_name})) { throw new SDKlessException("specified endpoint does not exist in config: {$this->config->actual_endpoint_name}"); } if (is_array($endpoint_vars)) { $this->endpoint_vars = $endpoint_vars; } else { $this->endpoint_vars = array(); } if (!empty($this->endpoint_vars['array_set'])) { $this->config->apply_endpoint_array_set_vars($this->endpoint_vars['array_set']); } $this->config->apply_endpoint_vars($this->endpoint_vars); $this->config->set_method(); $this->auth->setup_oauth_header($this->global_vars); $this->time_limit = array_key_exists('time_limit', $this->local_vars) ? $this->local_vars['time_limit'] : $this->config->get_endpoint_setting('time_limit'); $output = array(); $total_count = 0; // loop for paging while (true) { $response = $this->response->get($this->config, $this->time_limit); if (empty($response)) { break; } $response_count = $this->output->populate($this->config, $response, $output); if ($response_count == 0) { break; } $total_count += $response_count; // if total count >= limit, truncate/break $limit = $this->config->get_endpoint_setting('limit'); if (!empty($limit) && $total_count >= $limit) { if (is_array($output)) { $output = array_slice($output, 0, $limit); } break; } // if paging, setup next page param $paging = $this->config->get_endpoint_setting('paging'); if (empty($paging->parameters)) { break; } $paging_type = empty($paging->type) ? "page_number" : $paging->type; $endpoint_params = $this->config->get_endpoint_setting('parameters'); $page_size_param = empty($paging->parameters->page_size->name) ? "page_size" : $paging->parameters->page_size->name; $page_size = empty($endpoint_params->{$page_size_param}) ? null : $endpoint_params->{$page_size_param}; $paging_base = isset($paging->parameters->{$paging_type}->base) ? $paging->parameters->{$paging_type}->base : 1; switch ($paging_type) { case 'page_number': if (empty($paging->parameters->{$paging_type}->name)) { throw new SDKlessException("paging {$paging_type} name required"); } $paging_counter_param = $paging->parameters->{$paging_type}->name; if (!isset($paging_counter)) { $paging_counter = $paging_base; } $paging_counter++; $keys = array('parameters', $paging_counter_param); $this->config->set_endpoint_setting($keys, $paging_counter); // response count is less than page size; break if (!empty($page_size) && $response_count < $page_size) { break 2; } break; case 'record_offset': if (empty($paging->parameters->{$paging_type}->name)) { throw new SDKlessException("paging {$paging_type} name required"); } $paging_counter_param = $paging->parameters->{$paging_type}->name; if (!isset($paging_counter)) { $paging_counter = $paging_base; } if (empty($page_size)) { throw new SDKlessException("endpoint page size parameter required for offset paging"); } $paging_counter += $page_size; $keys = array('parameters', $paging_counter_param); $this->config->set_endpoint_setting($keys, $paging_counter); // response count is less than page size; break if (!empty($page_size) && $response_count < $page_size) { break 2; } break; case 'cursor': if (empty($paging->parameters->{$paging_type}->location) || !is_array($paging->parameters->{$paging_type}->location)) { throw new SDKlessException("paging {$paging_type} location array required"); } $data = json_decode(json_encode($response)); // make copy of response (can't be output; may no longer contain paging info) foreach ($paging->parameters->{$paging_type}->location as $location_key) { $data = Utilities::get_by_key($data, $location_key); } if (empty($data)) { break 2; } $this->config->set_endpoint_setting('uri', $data); break; } } $output_config = $this->config->get_endpoint_setting('output'); // filter output if (Utilities::is_structure($output) && !empty($output_config->filter)) { $unfiltered_output = json_decode(json_encode($output)); $output = array(); if (!Utilities::is_structure($output_config->filter)) { throw new SDKlessException("config endpoint output filter must be a structure"); } foreach ($output_config->filter as $filter) { $match_found = false; if (empty($filter->search_key) || !isset($filter->search_value)) { throw new SDKlessException("search_key and search_value are required for output filtering"); } foreach ($unfiltered_output as $item) { $item_value = Utilities::get_by_key($item, $filter->search_key); if (is_null($item_value)) { continue; } if ($item_value == $filter->search_value) { $match_found = true; if (!empty($filter->return_key)) { $return_key = $filter->return_key; return Utilities::get_by_key($item, $return_key); } $output[] = $item; } } if (!empty($filter->return_type)) { switch ($filter->return_type) { case 'boolean': return $match_found; break; case '!boolean': return !$match_found; break; } } } } $this->config->reset_to_unmerged(); return $output; }
private function get_item($data) { $output_config = $this->config->get_endpoint_setting('output'); $output_item = array(); foreach ($output_config->data->items->locations as $location_key => $location) { if (is_scalar($location)) { if (isset($data[$location])) { $output_item[$location_key] = $data[$location]; } else { $output_item[$location_key] = null; } } else { // locations entry is an array like: ["email_addresses", 0, "email_address"], $data_copy = $data; foreach ($location as $location_item) { if (is_scalar($location_item)) { $data_copy = Utilities::get_by_key($data_copy, $location_item); if (is_null($data_copy)) { throw new SDKlessException("specified key not found in response: {$location_item}"); } $output_item[$location_key] = $data_copy; } else { // if location item is a structure, this indicates a search; data must be a structure $this->set_item_by_search($data_copy, $location_item, $location_key, $output_item); } } } } return $output_item; }
private function error_check($output) { $output_config = $this->config->get_endpoint_setting('output'); if (!empty($output_config->error->location)) { $error_location = $output_config->error->location; } if (empty($error_location)) { return; } if (!is_array($error_location)) { $this->responses[$this->config->actual_endpoint_name][] = $output; throw new SDKlessException("config error location must be an array"); } // drill down to desired data foreach ($error_location as $location_key) { $output = Utilities::get_by_key($output, $location_key); if (empty($output)) { break; } } if (!empty($output)) { $this->responses[$this->config->actual_endpoint_name][] = $output; throw new SDKlessException("API returned error: {$output}"); } }