public static function get_http($url, $headers = array()) { static $_error2 = FALSE; PKHelper::DebugLogger('START: PKHelper::get_http(' . $url . ',' . print_r($headers, true) . ')'); // class: Context is not loaded when using piwik.php proxy on prestashop 1.4 if (class_exists('Context', FALSE)) { $lng = strtolower(isset(Context::getContext()->language->iso_code) ? Context::getContext()->language->iso_code : 'en'); } else { $lng = 'en'; } $timeout = 5; // should go in module conf if (self::$httpAuthUsername == "" || self::$httpAuthUsername === false) { self::$httpAuthUsername = Configuration::get(PKHelper::CPREFIX . 'PAUTHUSR'); } if (self::$httpAuthPassword == "" || self::$httpAuthPassword === false) { self::$httpAuthPassword = Configuration::get(PKHelper::CPREFIX . 'PAUTHPWD'); } $httpauth_usr = self::$httpAuthUsername; $httpauth_pwd = self::$httpAuthPassword; $use_cURL = (bool) Configuration::get(PKHelper::CPREFIX . 'USE_CURL'); if ($use_cURL === FALSE) { PKHelper::DebugLogger('Using \'file_get_contents\' to fetch remote'); $httpauth = ""; if (!empty($httpauth_usr) && !is_null($httpauth_usr) && $httpauth_usr !== false && (!empty($httpauth_pwd) && !is_null($httpauth_pwd) && $httpauth_pwd !== false)) { $httpauth = "Authorization: Basic " . base64_encode("{$httpauth_usr}:{$httpauth_pwd}") . "\r\n"; } $options = array('http' => array('user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : PKHelper::FAKEUSERAGENT, 'method' => "GET", 'timeout' => $timeout, 'header' => (!empty($headers) ? implode('', $headers) : "Accept-language: {$lng}\r\n") . $httpauth)); $context = stream_context_create($options); PKHelper::DebugLogger('Calling: ' . $url . (!empty($httpauth) ? "\n\t- With Http auth" : "")); $result = @file_get_contents($url, false, $context); if ($result === FALSE) { $http_response = ""; if (isset($http_response_header) && is_array($http_response_header)) { foreach ($http_response_header as $value) { if (preg_match("/^HTTP\\/.*/i", $value)) { $http_response = ':' . $value; } } } PKHelper::DebugLogger('request returned ERROR: http response: ' . $http_response); if (isset($http_response_header)) { PKHelper::DebugLogger('$http_response_header: ' . print_r($http_response_header, true)); } if (!$_error2) { self::$error = sprintf(self::l('Unable to connect to api%s'), " {$http_response}"); self::$errors[] = self::$error; $_error2 = TRUE; PKHelper::DebugLogger('Last error message: ' . self::$error); } } else { PKHelper::DebugLogger('request returned OK'); } PKHelper::DebugLogger('END: PKHelper::get_http(): OK'); return $result; } else { PKHelper::DebugLogger('Using \'cURL\' to fetch remote'); try { $ch = curl_init(); PKHelper::DebugLogger("\t: \$ch = curl_init()"); curl_setopt($ch, CURLOPT_URL, $url); PKHelper::DebugLogger("\t: curl_setopt(\$ch, CURLOPT_URL, {$url})"); !empty($headers) ? curl_setopt($ch, CURLOPT_HTTPHEADER, $headers) : curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept-language: {$lng}\r\n")); PKHelper::DebugLogger("\t: curl_setopt(\$ch, CURLOPT_HTTPHEADER, array(...))"); curl_setopt($ch, CURLOPT_USERAGENT, isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : PKHelper::FAKEUSERAGENT); if (!empty($httpauth_usr) && !is_null($httpauth_usr) && $httpauth_usr !== false && (!empty($httpauth_pwd) && !is_null($httpauth_pwd) && $httpauth_pwd !== false)) { curl_setopt($ch, CURLOPT_USERPWD, $httpauth_usr . ":" . $httpauth_pwd); } curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_HTTPGET, 1); // just to be safe curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_FAILONERROR, true); if (($return = curl_exec($ch)) === false) { if (!$_error2) { self::$error = curl_error($ch); self::$errors[] = self::$error; $_error2 = TRUE; } $return = false; } curl_close($ch); PKHelper::DebugLogger('END: PKHelper::get_http(): OK'); return $return; } catch (Exception $ex) { self::$errors[] = $ex->getMessage(); PKHelper::DebugLogger('Exception: ' . $ex->getMessage()); PKHelper::DebugLogger('END: PKHelper::get_http(): ERROR'); return false; } } }
PKHelper::ErrorLogger($value); } } sendHeader($_SERVER['SERVER_PROTOCOL'] . '505 Internal server error'); } } exit; } @ini_set('magic_quotes_runtime', 0); // 2) PIWIK.PHP PROXY: GET parameters found, this is a tracking request, we redirect it to Piwik $url = sprintf("%spiwik.php?cip=%s&token_auth=%s&", $PIWIK_URL, getVisitIp(), $TOKEN_AUTH); foreach ($_GET as $key => $value) { $url .= urlencode($key) . '=' . urlencode($value) . '&'; } sendHeader("Content-Type: image/gif"); $content = PKHelper::get_http($url . (version_compare(PHP_VERSION, '5.3.0', '<') ? '&send_image=1' : ''), array(sprintf("Accept-Language: %s\r\n", @str_replace(array("\n", "\t", "\r"), "", arrayValue($_SERVER, 'HTTP_ACCEPT_LANGUAGE', ''))))); // Forward the HTTP response code // not for cURL, working on it. (@todo cURL response_header [piwik.php]) if (!headers_sent() && isset($http_response_header[0])) { header($http_response_header[0]); } echo $content; function getVisitIp() { $matchIp = '/^([0-9]{1,3}\\.){3}[0-9]{1,3}$/'; $ipKeys = array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_CF_CONNECTING_IP'); foreach ($ipKeys as $ipKey) { if (isset($_SERVER[$ipKey]) && preg_match($matchIp, $_SERVER[$ipKey])) { return $_SERVER[$ipKey]; } }
/** * Method used when making ajax calls to Piwik API, * this method outputs json data. * * NOTE: only methods defiend in "PKHelper::$acp" can be called */ private function __pkapicall() { $apiMethod = Tools::getValue('pkapicall'); if (method_exists('PKHelper', $apiMethod) && isset(PKHelper::$acp[$apiMethod])) { $required = PKHelper::$acp[$apiMethod]['required']; // $optional = PKHelper::$acp[$apiMethod]['optional']; $order = PKHelper::$acp[$apiMethod]['order']; foreach ($required as $requiredOption) { if (!Tools::getIsset($requiredOption)) { PKHelper::DebugLogger("__pkapicall():\n\t- Required parameter \"" . $requiredOption . '" is missing'); die(Tools::jsonEncode(array('error' => true, 'message' => sprintf($this->l('Required parameter "%s" is missing'), $requiredOption)))); } } foreach ($order as &$value) { if (Tools::getIsset($value)) { $value = Tools::getValue($value); } else { $value = NULL; } } if (Tools::getIsset('httpUser')) { PKHelper::$httpAuthUsername = Tools::getValue('httpUser'); } if (Tools::getIsset('httpPasswd')) { PKHelper::$httpAuthPassword = Tools::getValue('httpPasswd'); } if (Tools::getIsset('piwikhost')) { PKHelper::$piwikHost = Tools::getValue('piwikhost'); } PKHelper::DebugLogger("__pkapicall():\n\t- Call PKHelper::" . $apiMethod); $result = call_user_func_array(array('PKHelper', $apiMethod), $order); if ($result === FALSE) { $lastError = ""; if (!empty(PKHelper::$errors)) { $lastError = "\n" . PKHelper::$error; } die(Tools::jsonEncode(array('error' => TRUE, 'message' => sprintf($this->l('Unknown error occurred%s'), $lastError)))); } else { PKHelper::DebugLogger("__pkapicall():\n\t- All good"); if (is_array($result) && isset($result[0])) { $message = $result; } else { if (is_object($result)) { $message = $result; } else { $message = is_string($result) && !is_bool($result) ? $result : (is_array($result) ? implode(', ', $result) : TRUE); } } if (is_bool($message)) { die(Tools::jsonEncode(array('error' => FALSE, 'message' => $this->l('Successfully Updated')))); } else { die(Tools::jsonEncode(array('error' => FALSE, 'message' => $message))); } } } else { die(Tools::jsonEncode(array('error' => true, 'message' => sprintf($this->l('Method "%s" dos not exists in class PKHelper'), $apiMethod)))); } }
public function __construct() { PKHelper::DebugLogger('START: PiwikAnalyticsJSPiwikModuleFrontController::__construct();'); // Edit the line below, and replace http://your-piwik-domain.example.org/piwik/ // with your Piwik URL ending with a slash. // This URL will never be revealed to visitors or search engines. $PIWIK_URL = ((bool) Configuration::get('PIWIK_CRHTTPS') ? 'https://' : 'http://') . Configuration::get('PIWIK_HOST'); // Edit the line below, and replace xyz by the token_auth for the user "UserTrackingAPI" // which you created when you followed instructions above. $TOKEN_AUTH = Configuration::get('PIWIK_TOKEN_AUTH'); PKHelper::DebugLogger('Config values Loaded'); // 1) PIWIK.JS PROXY: No _GET parameter, we serve the JS file if (count($_GET) == 3 && Tools::getIsset('module') && Tools::getIsset('controller') && Tools::getIsset('fc') || count($_GET) == 4 && Tools::getIsset('module') && Tools::getIsset('controller') && Tools::getIsset('fc') && Tools::getIsset('id_lang') || count($_GET) == 5 && Tools::getIsset('module') && Tools::getIsset('controller') && Tools::getIsset('fc') && Tools::getIsset('id_lang') && Tools::getIsset('isolang')) { PKHelper::DebugLogger('Got piwik.js request with _GET count of : ' . count($_GET) . "\n" . str_repeat('==', 50) . "\n" . print_r($_GET, true) . "\n" . str_repeat('==', 50)); $modifiedSince = false; if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $modifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE']; // strip any trailing data appended to header if (false !== ($semicolon = strpos($modifiedSince, ';'))) { $modifiedSince = substr($modifiedSince, 0, $semicolon); } $modifiedSince = strtotime($modifiedSince); } // Re-download the piwik.js once a day maximum $lastModified = time() - 86400; // set HTTP response headers $this->sendHeader('Vary: Accept-Encoding'); // Returns 304 if not modified since if (!empty($modifiedSince) && $modifiedSince < $lastModified) { PKHelper::DebugLogger('Set Header 304 Not Modified'); $this->sendHeader(sprintf("%s 304 Not Modified", $_SERVER['SERVER_PROTOCOL'])); } else { $this->sendHeader('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); $this->sendHeader('Content-Type: application/javascript; charset=UTF-8'); PKHelper::DebugLogger('Send request to Piwik'); PKHelper::DebugLogger("\t: {$PIWIK_URL}piwik.js"); $exHeaders = array(sprintf("Accept-Language: %s\r\n", @str_replace(array("\n", "\t", "\r"), "", $this->arrayValue($_SERVER, 'HTTP_ACCEPT_LANGUAGE', '')))); PKHelper::DebugLogger("\t: Extra heders\n" . str_repeat('==', 50) . "\n" . print_r($exHeaders, true) . "\n" . str_repeat('==', 50)); if ($piwikJs = PKHelper::get_http($PIWIK_URL . 'piwik.js', $exHeaders)) { PKHelper::DebugLogger('Send Piwik js to client'); die($piwikJs); } else { if (!empty(PKHelper::$errors)) { foreach (PKHelper::$errors as $value) { PKHelper::ErrorLogger($value); } } PKHelper::DebugLogger('Error:....' . "\n" . str_repeat('==', 50) . print_r(PKHelper::$error, true) . "\n" . str_repeat('==', 50) . "\n" . print_r(PKHelper::$errors, true) . "\n" . str_repeat('==', 50)); $this->sendHeader($_SERVER['SERVER_PROTOCOL'] . '505 Internal server error'); } } PKHelper::DebugLogger('END: PiwikAnalyticsJSPiwikModuleFrontController::__construct();'); die; } PKHelper::DebugLogger('Got piwik image request with _GET count of :' . count($_GET) . "\n" . str_repeat('==', 50) . "\n" . print_r($_GET, true) . "\n" . str_repeat('==', 50)); // 2) PIWIK.PHP PROXY: GET parameters found, this is a tracking request, we redirect it to Piwik $url = sprintf("%spiwik.php?cip=%s&token_auth=%s&", $PIWIK_URL, $this->getVisitIp(), $TOKEN_AUTH); foreach ($_GET as $key => $value) { $url .= urlencode($key) . '=' . urlencode($value) . '&'; } PKHelper::DebugLogger('Send request to Piwik ::: ' . $url . (version_compare(PHP_VERSION, '5.3.0', '<') ? '&send_image=1' : '')); $this->sendHeader("Content-Type: image/gif"); $content = PKHelper::get_http($url . (version_compare(PHP_VERSION, '5.3.0', '<') ? '&send_image=1' : ''), array(sprintf("Accept-Language: %s\r\n", @str_replace(array("\n", "\t", "\r"), "", $this->arrayValue($_SERVER, 'HTTP_ACCEPT_LANGUAGE', ''))))); PKHelper::DebugLogger('Piwik request complete'); // Forward the HTTP response code // not for cURL, working on it. (@todo cURL response_header [piwik.php]) if (!headers_sent() && isset($http_response_header[0])) { header($http_response_header[0]); } PKHelper::DebugLogger('END: PiwikAnalyticsJSPiwikModuleFrontController::__construct();'); die($content); }