logger_index++; $this->loggers[ $handle ] = $callable; return $handle; } /** * Remove a logger * * @param int $handle as returned by addLogger() */ public function removeLogger( $handle ) { unset( $this->loggers[ $handle ] ); } /** * Set an operator name - a person, who is responsible for the changes performed via the api call. * The name is only used for logging purposes. * * @param string $operator_name your application's user name (NOT a Digistore24 name) */ public function setOperator( $operator_name ) { $this->operator_name = $operator_name; } /** * Sets the language for the api's messages. * By default all messages are in the language set in the Digistore24 account of the api key owner. * * @param string $language 'de' or 'en' */ public function setLanguage( $language ) { $tokens = explode( '_', $language ); $language = $tokens[0]; $is_language_valid = in_array( $language, $this->_validLangs() ); if ($is_language_valid) { $this->language = $language; } } /** * Destroys the connection to the server. * */ public function disconnect() { $this->api_key = false; } /** * Execute api function on the Digistore24 server * * @param string $function_name * @param array $arguments * @throws DigistoreApiException */ public function __call( $function_name, $arguments ) { return $this->_exec( $function_name, $arguments ); } /** * Used for debug purposes. Returns the most recently used api url called. */ public function getLastUrl() { if ($this->last_url===false) { return false; } $querystring = http_build_query( $this->last_params, '', '&' ); return $this->last_url . '?' . $querystring; } /** * For debugging purposes only * * @param string $url */ public function setBaseUrl( $url='https://www.digistore24.com' ){ $this->base_url = $url; } private $api_key = ''; private $language = ''; private $operator_name = ''; private $loggers = array(); private $logger_index = 1; private $base_url = 'https://www.digistore24.com'; private $last_url = false; private $last_params = false; private function __construct( $api_key ) { $this->api_key = $api_key; } private function _log( $level, $msg, $arg1='', $arg2='', $arg3='' ) { if (empty($this->loggers)) { return; } $msg = sprintf( $msg, $arg1, $arg2, $arg3 ); foreach ($this->loggers as $one) { call_user_func( $one, $level, $msg ); } } private function _error( $code, $arg1='', $arg2='', $arg3='' ) { $msg = $this->_errorMsg( $code, $arg1, $arg2, $arg3 ); $this->_log( DS_LOG_ERROR, $msg ); throw new DigistoreApiException( $msg, $code ); } private function service_url() { $key = $this->api_key; if (!$key) { $this->_error( DS_ERR_NOT_CONNECTED ); } $base_url = $this->base_url; return "$base_url/api/call/$key/json/"; } private function _exec( $function_name, $arguments ) { if (!$this->api_key) { $this->_error( DS_ERR_NOT_CONNECTED ); } $this->_log( DS_LOG_INFO, "Call to '%s' - started", $function_name . '()' ); if (!$function_name || !is_array($arguments)) { $this->_error( DS_ERR_BAD_FUNCTION_PARAMS, "$function_name()" ); } $url = $this->service_url() . $function_name; $args = array(); foreach ($arguments as $index => $one) { $key = 'arg' . ($index+1); $this->_set_post_param( $args, $key, $one ); } $args['language'] = $this->language; $args['operator'] = $this->operator_name; $args['ds24ver' ] = self::digistore_api_connector_version; $data = $this->_http_request( $url, $args ); $this->_log( DS_LOG_INFO, "Call to %s - completed", $function_name . '()' ); return $data; } private function _http_request( $url, $params, $settings = array() ) { $this->last_url = $url; $this->last_params = $params; $querystring = http_build_query( $params, '', '&' ); $headers = array ( 'Content-type: application/x-www-form-urlencoded; charset=utf-8', 'Accept-Charset: utf-8', ); if (!function_exists('curl_init')) { $this->_error( DS_ERR_CURL, $ch_error_no=0, $ch_error_msg='PHP module Curl is required. Please ask your web admin to enable it.' ); } $ch = curl_init(); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true); curl_setopt( $ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false ); curl_setopt( $ch, CURLOPT_USERAGENT, 'DigiStore-API-Connector/1.0 (Linux; en-US; rv:1.0.0.0) php/20130430 curl/20130430' ); curl_setopt( $ch, CURLOPT_TIMEOUT, 30 ); curl_setopt( $ch, CURLOPT_URL, $url); curl_setopt( $ch, CURLOPT_POST, count($params)); curl_setopt( $ch, CURLOPT_POSTFIELDS, $querystring); curl_setopt( $ch, CURLOPT_ENCODING, "" ); curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); $contents = curl_exec($ch); $http_code = ''.curl_getinfo($ch, CURLINFO_HTTP_CODE); $ch_error_no = curl_errno($ch); $ch_error_msg = curl_error($ch); @curl_close($ch); if ($ch_error_msg) { $this->_error( DS_ERR_CURL, $ch_error_no, $ch_error_msg ); } $is_http_call_success = $http_code == 200; if (!$is_http_call_success) { $this->_error( DS_ERR_BAD_HTTP_CODE, $http_code ); } $result = @json_decode( $contents ); $debug_info = ''; if (!isset($result)) { global $DM_SUPPORT_URL_TEST; $must_report = (defined('NCORE_DEBUG') && NCORE_DEBUG) || !empty($DM_SUPPORT_URL_TEST); if ($must_report) { ob_start(); echo "
URL: $url\nQuery: $querystring\nParams: ";
                print_r( $params );
                echo "\nResponse:
$contents"; $debug_info = ob_get_clean(); $debug_info = str_replace( $this->api_key, 'DS24_APIKEY_PROTECTED', $debug_info ); trigger_error( "Invalid digistore24 api server response: $debug_info" ); } } $success = $result && is_a($result,'stdClass') && isset($result->api_version) && isset($result->result); if ($success) { $api_version = $result->api_version; $result_type = $result->result; switch ($result_type) { case 'error': $msg = $result->message; $code = $result->code; throw new DigistoreApiException( $msg, $code ); case 'success': $data = $result->data; return $data; } } $this->_error( DS_ERR_BAD_SERVER_RESPONSE, $contents ); } /** * Translates an error code in a human readable message for your application's users. * * @param int $code a DS_ERR_XXXXX constant */ private function _errorMsg( $code, $arg1='', $arg2='', $arg3='' ) { $error_messages = $this->_errorMsgList(); if ($code==='test') { $is_lang_valid = isset( $error_messages[ $this->language ] ); return $is_lang_valid; } $msgs = isset( $error_messages[ $this->language ] ) ? $error_messages[ $this->language ] : $error_messages[ 'en' ]; $msg = isset( $msgs[ $code ] ) ? $msgs[ $code ] : $msgs[ DS_ERR_UNKNOWN ]; return sprintf( $msg, $arg1, $arg2, $arg3 ); } private function _validLangs() { return array_keys( $this->_errorMsgList() ); } private function _errorMsgList() { return array( 'de' => array( DS_ERR_UNKNOWN => 'Unbekannter Fehler!', DS_ERR_NOT_CONNECTED => 'Nicht zum Digistore24-Server verbunden.', DS_ERR_BAD_API_CALL => 'Die Verbindungsparameter sind ungültig.', DS_ERR_BAD_FUNCTION_PARAMS => 'Ungültige Parameter bei Funktionsaufruf %s.', DS_ERR_BAD_SERVER_RESPONSE => 'Der Digistore24-Server hat eine ungültige Antwort geliefert. (Technische Information: %s)', DS_ERR_CURL => 'Fehler beim HTTP-Aufruf durch CURL (#%s - %s)', DS_ERR_BAD_HTTP_CODE => 'Der Digistore24-Server lieferte eine Antwort mit einem Ungültigen HTTP-Code (%s)', ), 'en' => array( DS_ERR_UNKNOWN => 'Unknown error!', DS_ERR_NOT_CONNECTED => 'Not connected to the Digistore24 server.', DS_ERR_BAD_API_CALL => 'Invalid connection parameters.', DS_ERR_BAD_FUNCTION_PARAMS => 'Invalid parameters for function call %s.', DS_ERR_BAD_SERVER_RESPONSE => 'The Digistore24 server delivered an invalid response. (Technical information: %s)', DS_ERR_CURL => 'Http call error reported by curl (#%s - %s)', DS_ERR_BAD_HTTP_CODE => 'The Digistore24 server responded with an invalid http code (%s)', ) ); } function _set_post_param( &$args, $key, $value ) { if (is_object($value)) { $value = (array) $value; } if (!is_array($value)) { $args[ $key ] = $value; return; } foreach ($value as $one_key => $one_value) { $one_name = $key . '[' . $one_key . ']'; $this->_set_post_param( $args, $one_name, $one_value ); } } } } // if class_exists