/** * @param array $config an array of configuration parameters * @param \MicrosoftTranslator\HttpInterface|null $http if null, a new Http manager will be used * @param \MicrosoftTranslator\AuthInterface|null $auth if null, a new Auth manager will be used * @param \MicrosoftTranslator\LoggerInterface|null $logger if null, a new Logger manager will be used * * @throws Exception */ public function __construct($config = array(), $http = null, $auth = null, $logger = null) { // Init logger at first if (is_null($logger)) { $logger = new Logger($config); } if (!$logger instanceof LoggerInterface) { throw new Exception('Logger Manager is not an instance of MicrosoftTranslator\\LoggerInterface'); } $this->logger = $logger; // Load configuration for Client foreach ($this->config_keys as $key) { if (isset($config[$key])) { $this->{$key} = $config[$key]; $this->logger->debug(__CLASS__, 'config', sprintf('%s = %s', $key, $this->{$key})); } } // Init HTTP Manager if (is_null($http)) { $http = new Http($config, $logger); } if (!$http instanceof HttpInterface) { throw new Exception('HTTP Manager is not an instance of MicrosoftTranslator\\HttpInterface'); } $this->http = $http; // Init Auth Manager if (is_null($auth)) { $auth = new Auth($config, $logger, $http); } if (!$auth instanceof AuthInterface) { throw new Exception('Auth Manager is not an instance of MicrosoftTranslator\\AuthInterface'); } $this->auth = $auth; }
/** * Save AT and timestamp in file * * @param string $access_token * @param int $timestamp * * @return bool */ private function save($access_token, $timestamp) { unset($this->runtime_file_content); $bytes = @file_put_contents($this->getFilePath(), json_encode(array('a' => $access_token, 'e' => $timestamp))); if ($bytes === false) { // fatal log will throw an exception $this->logger->fatal(__CLASS__, 'store', sprintf('Unable to store access token in %s', $this->getFilePath())); } $this->logger->debug(__CLASS__, 'store', sprintf('Access token stored in %s', $this->getFilePath())); return true; }
/** * @return array|string * @throws \MicrosoftTranslator\Exception */ private function generateAndStoreNewAccessToken() { $url = trim($this->auth_base_url, "/ \t\n\r\v"); $access_token = null; $auth = array('grant_type' => 'client_credentials', 'client_id' => $this->api_client_id, 'client_secret' => $this->api_client_secret, 'scope' => $this->api_client_scope); $result = $this->http->post($url, null, $auth, null); if (Http::isRequestOk($result)) { $result['http_body'] = json_decode($result['http_body'], true); if (!isset($result['http_body']['access_token'])) { throw new Exception('Access token not found in response'); } if (!is_string($result['http_body']['access_token'])) { throw new Exception('Access token found in response but it is not a string'); } $access_token = strval(@$result['http_body']['access_token']); $expires_in = @(int) $result['http_body']['expires_in']; $this->logger->debug(__CLASS__, 'oauth', sprintf('New access_token generated %s...', substr($access_token, 0, 10))); $this->guard->storeAccessTokenForSeconds($access_token, $expires_in); } else { $this->logger->fatal(__CLASS__, 'oauth', 'Unable to generate a new access token : ' . json_encode($result)); } return $access_token; }
/** * @param string $url * @param string $method * @param string|null $access_token * @param string|array $parameters * @param string $contentType * * @return array */ private function doApiCall($url, $method, $access_token = null, $parameters = array(), $contentType = 'text/xml') { $request = array(); $headers = array(); $request[CURLOPT_TIMEOUT] = (int) $this->http_timeout; $request[CURLOPT_USERAGENT] = str_replace('%VERSION%', Client::VERSION, $this->http_user_agent); $request[CURLOPT_CUSTOMREQUEST] = $method; if (!empty($parameters)) { if ($method === 'GET') { $url = Tools::httpBuildUrl($url, array("query" => http_build_query($parameters)), Tools::HTTP_URL_JOIN_QUERY); } else { if (is_array($parameters)) { $request[CURLOPT_POSTFIELDS] = http_build_query($parameters); } else { if (is_string($parameters)) { $request[CURLOPT_POSTFIELDS] = $parameters; } } } } $request[CURLOPT_URL] = $url; if (!is_null($contentType)) { $headers[] = "Content-Type: {$contentType}"; } if (!is_null($access_token)) { $headers[] = 'Authorization: Bearer ' . $access_token; } if (!empty($this->http_proxy_host)) { $request[CURLOPT_PROXY] = $this->http_proxy_host; if (!empty($this->http_proxy_port)) { $request[CURLOPT_PROXYPORT] = $this->http_proxy_port; } if (!empty($this->http_proxy_type)) { $request[CURLOPT_PROXYTYPE] = $this->http_proxy_type; } if (!empty($this->http_proxy_auth)) { $request[CURLOPT_PROXYAUTH] = $this->http_proxy_auth; } if (!empty($this->http_proxy_user)) { $request[CURLOPT_PROXYUSERPWD] = $this->http_proxy_user . ':' . $this->http_proxy_pass; } } $request[CURLOPT_HTTPHEADER] = $headers; $this->logger->info(__CLASS__, 'api', sprintf('%s %s', $method, $url)); $start = microtime(true); @(list($result, $status_code, $error, $errno) = $this->execCurl($request)); $end = microtime(true); $duration = (int) round(($end - $start) * 1000); if ($errno === 0) { $return = array('http_code' => $status_code, 'http_body' => $result, 'duration' => $duration); if ($status_code >= 400) { $this->logger->error(__CLASS__, 'api', sprintf('Response HTTP code %s, body length %s bytes, duration %sms on endpoint %s %s', $status_code, strlen($result), $duration, $method, $url)); } else { if ($status_code >= 300) { $this->logger->warning(__CLASS__, 'api', sprintf('Response HTTP code %s, body length %s bytes, duration %sms on endpoint %s %s', $status_code, strlen($result), $duration, $method, $url)); } else { $this->logger->info(__CLASS__, 'api', sprintf('Response HTTP code %s, body length %s bytes, duration %sms', $status_code, strlen($result), $duration)); } } } else { $return = array('error_msg' => $error, 'error_num' => $errno, 'duration' => $duration); $this->logger->error(__CLASS__, 'api', sprintf('cURL error #%s : %s', $errno, $error)); } return $return; }