Esempio n. 1
0
 /**
  * Returns singleton
  *
  * @return Piwik_Tracker_Config
  */
 public static function getInstance()
 {
     if (self::$instance == null) {
         self::$instance = new self();
     }
     return self::$instance;
 }
Esempio n. 2
0
 /**
  * Returns singleton
  *
  * @return Piwik_Tracker_Config
  */
 public static function getInstance()
 {
     if (self::$instance == null) {
         $c = __CLASS__;
         self::$instance = new $c();
     }
     return self::$instance;
 }
Esempio n. 3
0
 function checkHeader($notification)
 {
     $setting = @Piwik_Tracker_Config::getInstance()->Tracker['do_not_track'];
     if ($setting === '1' && (isset($_SERVER['HTTP_X_DO_NOT_TRACK']) && $_SERVER['HTTP_X_DO_NOT_TRACK'] === '1' || isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT'] === '1')) {
         $exclude =& $notification->getNotificationObject();
         $exclude = true;
         $trackingCookie = Piwik_Tracker_IgnoreCookie::getTrackingCookie();
         $trackingCookie->delete();
     }
 }
Esempio n. 4
0
 function test_extractUrlAndActionNameFromRequest()
 {
     $userFile = PIWIK_PATH_TEST_TO_ROOT . '/tests/resources/Tracker/Action.config.ini.php';
     $config = Piwik_Tracker_Config::getInstance();
     $config->init($userFile);
     $action = new Test_Piwik_TrackerAction_extractUrlAndActionNameFromRequest();
     $tests = array(array('request' => array('link' => 'http://example.org'), 'expected' => array('name' => 'http://example.org', 'url' => 'http://example.org', 'type' => Piwik_Tracker_Action::TYPE_OUTLINK)), array('request' => array('link' => '	http://example.org/Category/Test/  	'), 'expected' => array('name' => 'http://example.org/Category/Test/', 'url' => 'http://example.org/Category/Test/', 'type' => Piwik_Tracker_Action::TYPE_OUTLINK)), array('request' => array('download' => 'http://example.org/*$test.zip'), 'expected' => array('name' => 'http://example.org/*$test.zip', 'url' => 'http://example.org/*$test.zip', 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD)), array('request' => array('download' => 'http://example.org/CATEGORY/test///test.pdf'), 'expected' => array('name' => 'http://example.org/CATEGORY/test///test.pdf', 'url' => 'http://example.org/CATEGORY/test///test.pdf', 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD)), array('request' => array('url' => 'http://example.org/'), 'expected' => array('name' => 'index', 'url' => 'http://example.org/', 'type' => Piwik_Tracker_Action::TYPE_ACTION)), array('request' => array('url' => 'http://example.org/CATEGORY/'), 'expected' => array('name' => 'CATEGORY/index', 'url' => 'http://example.org/CATEGORY/', 'type' => Piwik_Tracker_Action::TYPE_ACTION)), array('request' => array('url' => 'http://example.org/category/', 'action_name' => 'custom name with/one delimiter/two delimiters/'), 'expected' => array('name' => 'custom name with/one delimiter/two delimiters', 'url' => 'http://example.org/category/', 'type' => Piwik_Tracker_Action::TYPE_ACTION)), array('request' => array('url' => 'http://example.org/category/', 'action_name' => 'http://custom action name look like url/'), 'expected' => array('name' => 'http:/custom action name look like url', 'url' => 'http://example.org/category/', 'type' => Piwik_Tracker_Action::TYPE_ACTION)), array('request' => array('url' => "http://example.org/category/test///test  wOw  \t"), 'expected' => array('name' => 'category/test/test  wOw', 'url' => 'http://example.org/category/test///test  wOw', 'type' => Piwik_Tracker_Action::TYPE_ACTION)), array('request' => array('url' => "http://example.org/category/1/0/t/test"), 'expected' => array('name' => 'category/1/0/t/test', 'url' => 'http://example.org/category/1/0/t/test', 'type' => Piwik_Tracker_Action::TYPE_ACTION)));
     foreach ($tests as $test) {
         $request = $test['request'];
         $expected = $test['expected'];
         $action->setRequest($request);
         $this->assertEqual($action->public_extractUrlAndActionNameFromRequest(), $expected);
     }
 }
Esempio n. 5
0
 /**
  * Returns the table name prefixed by the table prefix.
  * Works in both Tracker and UI mode.
  * 
  * @param string The table name to prefix, ie "log_visit"
  * @return string The table name prefixed, ie "piwik-production_log_visit"
  */
 public static function prefixTable($table)
 {
     static $prefixTable = null;
     if (is_null($prefixTable)) {
         if (defined('PIWIK_TRACKER_MODE') && PIWIK_TRACKER_MODE) {
             $prefixTable = Piwik_Tracker_Config::getInstance()->database['tables_prefix'];
         } else {
             $config = Zend_Registry::get('config');
             if ($config !== false) {
                 $prefixTable = $config->database->tables_prefix;
             }
         }
     }
     return $prefixTable . $table;
 }
Esempio n. 6
0
 public function testUserConfigOverwritesSectionGlobalConfigValue()
 {
     $userFile = PIWIK_PATH_TEST_TO_ROOT . '/tests/resources/Config/config.ini.php';
     $globalFile = PIWIK_PATH_TEST_TO_ROOT . '/tests/resources/Config/global.ini.php';
     $config = Piwik_Tracker_Config::getInstance();
     $config->init($userFile, $globalFile);
     $this->assertEqual($config->Category['key1'], "value_overwritten");
     $this->assertEqual($config->Category['key2'], "value2");
     $this->assertEqual($config->General['login'], 'tes"t');
     $this->assertEqual($config->CategoryOnlyInGlobalFile['key3'], "value3");
     $this->assertEqual($config->CategoryOnlyInGlobalFile['key4'], "value4");
     $expectedArray = array('plugin"1', 'plugin2', 'plugin3');
     $array = $config->TestArray;
     $this->assertEqual($array['installed'], $expectedArray);
     $expectedArray = array('value1', 'value2');
     $array = $config->TestArrayOnlyInGlobalFile;
     $this->assertEqual($array['my_array'], $expectedArray);
 }
Esempio n. 7
0
	/**
	 * Get ignore (visit) cookie
	 *
	 * @return Piwik_Cookie
	 */
	static public function getIgnoreCookie()
	{
		if(!empty($GLOBALS['PIWIK_TRACKER_MODE']))
		{
			$cookie_name = @Piwik_Tracker_Config::getInstance()->Tracker['ignore_visits_cookie_name'];
			$cookie_path = @Piwik_Tracker_Config::getInstance()->Tracker['cookie_path'];
		}
		else
		{
			$config = Zend_Registry::get('config');
			if($config !== false)
			{
				$cookie_name = @$config->Tracker->ignore_visits_cookie_name;
				$cookie_path = @$config->Tracker->cookie_path;
			}
		}

		return new Piwik_Cookie($cookie_name, null, $cookie_path);
	}
Esempio n. 8
0
 /**
  * Returns true if the last action was done during the last 30 minutes
  * @return bool
  */
 protected function isLastActionInTheSameVisit()
 {
     return isset($this->visitorInfo['visit_last_action_time']) && $this->visitorInfo['visit_last_action_time'] > $this->getCurrentTimestamp() - Piwik_Tracker_Config::getInstance()->Tracker['visit_standard_length'];
 }
Esempio n. 9
0
 protected function detectRefererCampaign()
 {
     if (isset($this->currentUrlParse['query'])) {
         $campaignVariableName = Piwik_Tracker_Config::getInstance()->Tracker['campaign_var_name'];
         $campaignName = Piwik_Common::getParameterFromQueryString($this->currentUrlParse['query'], $campaignVariableName);
         if (!empty($campaignName)) {
             $campaignKeywordVariableName = Piwik_Tracker_Config::getInstance()->Tracker['campaign_keyword_var_name'];
             $campaignKeyword = Piwik_Common::getParameterFromQueryString($this->currentUrlParse['query'], $campaignKeywordVariableName);
             $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_CAMPAIGN;
             $this->nameRefererAnalyzed = $campaignName;
             if (!empty($campaignKeyword)) {
                 $this->keywordRefererAnalyzed = $campaignKeyword;
             }
             return true;
         }
     }
     return false;
 }
Esempio n. 10
0
	protected static function cleanupString($string)
	{
		$string = trim($string);
		$string = str_replace(array("\n", "\r"), "", $string);
		$limit = Piwik_Tracker_Config::getInstance()->Tracker['page_maximum_length'];
		return substr($string, 0, $limit);
	}
Esempio n. 11
0
 /**
  * Returns the list of Campaign parameter names that will be read to classify 
  * a visit as coming from a Campaign
  * 
  * @return array array( 
  * 			0 => array( ... ) // campaign names parameters
  * 			1 => array( ... ) // campaign keyword parameters
  * ); 
  */
 public static function getCampaignParameters()
 {
     if (!empty($GLOBALS['PIWIK_TRACKER_MODE'])) {
         $return = array(Piwik_Tracker_Config::getInstance()->Tracker['campaign_var_name'], Piwik_Tracker_Config::getInstance()->Tracker['campaign_keyword_var_name']);
     } else {
         $return = array(Zend_Registry::get('config')->Tracker->campaign_var_name, Zend_Registry::get('config')->Tracker->campaign_keyword_var_name);
     }
     foreach ($return as &$list) {
         if (strpos($list, ',') !== false) {
             $list = explode(',', $list);
         } else {
             $list = array($list);
         }
     }
     array_walk_recursive($return, 'trim');
     return $return;
 }
Esempio n. 12
0
 /**
  * Returns the best possible IP of the current user, in the format A.B.C.D
  * For example, this could be the proxy client's IP address.
  *
  * @return string ip
  */
 public static function getIpString()
 {
     static $clientHeaders = null;
     if (is_null($clientHeaders)) {
         if (!empty($GLOBALS['PIWIK_TRACKER_MODE'])) {
             $clientHeaders = @Piwik_Tracker_Config::getInstance()->General['proxy_client_headers'];
         } else {
             $config = Zend_Registry::get('config');
             if ($config !== false && isset($config->General->proxy_client_headers)) {
                 $clientHeaders = $config->General->proxy_client_headers->toArray();
             }
         }
         if (!is_array($clientHeaders)) {
             $clientHeaders = array();
         }
     }
     $default = '0.0.0.0';
     if (isset($_SERVER['REMOTE_ADDR'])) {
         $default = $_SERVER['REMOTE_ADDR'];
     }
     return self::getProxyFromHeader($default, $clientHeaders);
 }
Esempio n. 13
0
 protected function handleDisabledTracker()
 {
     $saveStats = Piwik_Tracker_Config::getInstance()->Tracker['record_statistics'];
     if ($saveStats == 0) {
         $this->setState(self::STATE_LOGGING_DISABLE);
     }
 }
Esempio n. 14
0
 /**
  * Hook on Tracker.Visit.setVisitorIp to anonymize visitor IP addresses
  */
 function setVisitorIpAddress($notification)
 {
     $ip =& $notification->getNotificationObject();
     $ip = self::applyIPMask($ip, Piwik_Tracker_Config::getInstance()->Tracker['ip_address_mask_length']);
 }
Esempio n. 15
0
	/**
	 * Returns a non-proxy IP address from header
	 *
	 * @param string $default Default value to return if no matching proxy header
	 * @param array $proxyHeaders List of proxy headers
	 * @return string
	 */
	static public function getNonProxyIpFromHeader($default, $proxyHeaders)
	{
		$proxyIps = null;
		if(!empty($GLOBALS['PIWIK_TRACKER_MODE']))
		{
			$proxyIps = @Piwik_Tracker_Config::getInstance()->General['proxy_ips'];
		}
		else
		{
			$config = Zend_Registry::get('config');
			if($config !== false && isset($config->General->proxy_ips))
			{
				$proxyIps = $config->General->proxy_ips->toArray();
			}
		}
		if(!is_array($proxyIps))
		{
			$proxyIps = array();
		}
		$proxyIps[] = $default;

		// examine proxy headers
		foreach($proxyHeaders as $proxyHeader)
		{
			if(!empty($_SERVER[$proxyHeader]))
			{
				$proxyIp = self::getLastIpFromList($_SERVER[$proxyHeader], $proxyIps);
				if(strlen($proxyIp) && stripos($proxyIp, 'unknown') === false)
				{
					return $proxyIp;
				}
			}
		}

		return $default;
	}
Esempio n. 16
0
 /**
  * This method allows to set custom IP + server time when using Tracking API.
  * These two attributes can be only set by the Super User (passing token_auth).
  */
 protected function handleTrackingApi()
 {
     $shouldAuthenticate = Piwik_Tracker_Config::getInstance()->Tracker['tracking_requests_require_authentication'];
     if ($shouldAuthenticate) {
         if (!$this->authenticateSuperUserOrAdmin()) {
             return;
         }
         printDebug("token_auth is authenticated!");
     } else {
         printDebug("token_auth authentication not required");
     }
     // Custom IP to use for this visitor
     $customIp = Piwik_Common::getRequestVar('cip', false, 'string', $this->request);
     if (!empty($customIp)) {
         $this->setForceIp($customIp);
     }
     // Custom server date time to use
     $customDatetime = Piwik_Common::getRequestVar('cdt', false, 'string', $this->request);
     if (!empty($customDatetime)) {
         $this->setForceDateTime($customDatetime);
     }
     // Forced Visitor ID to record the visit / action
     $customVisitorId = Piwik_Common::getRequestVar('cid', false, 'string', $this->request);
     if (!empty($customVisitorId)) {
         $this->setForceVisitorId($customVisitorId);
     }
 }
Esempio n. 17
0
 /**
  * Get salt from [superuser] section
  *
  * @return string
  */
 public static function getSalt()
 {
     static $salt = null;
     if (is_null($salt)) {
         if (defined('PIWIK_TRACKER_MODE') && PIWIK_TRACKER_MODE) {
             $salt = Piwik_Tracker_Config::getInstance()->superuser['salt'];
         } else {
             $config = Zend_Registry::get('config');
             if ($config !== false) {
                 $salt = $config->superuser->salt;
             }
         }
     }
     return $salt;
 }
Esempio n. 18
0
 function recordGoals($idSite, $visitorInformation, $visitCustomVariables, $action, $referrerTimestamp, $referrerUrl, $referrerCampaignName, $referrerCampaignKeyword)
 {
     $location_country = isset($visitorInformation['location_country']) ? $visitorInformation['location_country'] : Piwik_Common::getCountry(Piwik_Common::getBrowserLanguage(), $enableLanguageToCountryGuess = Piwik_Tracker_Config::getInstance()->Tracker['enable_language_to_country_guess'], $visitorInformation['location_ip']);
     $location_continent = isset($visitorInformation['location_continent']) ? $visitorInformation['location_continent'] : Piwik_Common::getContinent($location_country);
     $goal = array('idvisit' => $visitorInformation['idvisit'], 'idsite' => $idSite, 'idvisitor' => $visitorInformation['idvisitor'], 'server_time' => Piwik_Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time']), 'location_country' => $location_country, 'location_continent' => $location_continent, 'visitor_returning' => $visitorInformation['visitor_returning'], 'visitor_days_since_first' => $visitorInformation['visitor_days_since_first'], 'visitor_count_visits' => $visitorInformation['visitor_count_visits']);
     // Attributing the correct Referrer to this conversion.
     // Priority order is as follows:
     // 1) Campaign name/kwd parsed in the JS
     // 2) Referrer URL stored in the _ref cookie
     // 3) If no info from the cookie, attribute to the current visit referrer
     // 3) Default values: current referrer
     $type = $visitorInformation['referer_type'];
     $name = $visitorInformation['referer_name'];
     $keyword = $visitorInformation['referer_keyword'];
     $time = $visitorInformation['visit_first_action_time'];
     // 1) Campaigns from 1st party cookie
     if (!empty($referrerCampaignName)) {
         $type = Piwik_Common::REFERER_TYPE_CAMPAIGN;
         $name = $referrerCampaignName;
         $keyword = $referrerCampaignKeyword;
         $time = $referrerTimestamp;
     } elseif (!empty($referrerUrl)) {
         $referrer = new Piwik_Tracker_Visit_Referer();
         $referrer = $referrer->getRefererInformation($referrerUrl, $currentUrl = '', $idSite);
         // if the parsed referer is interesting enough, ie. website or search engine
         if (in_array($referrer['referer_type'], array(Piwik_Common::REFERER_TYPE_SEARCH_ENGINE, Piwik_Common::REFERER_TYPE_WEBSITE))) {
             $type = $referrer['referer_type'];
             $name = $referrer['referer_name'];
             $keyword = $referrer['referer_keyword'];
             $time = $referrerTimestamp;
         }
     }
     $goal += array('referer_type' => $type, 'referer_name' => $name, 'referer_keyword' => $keyword, 'referer_visit_server_date' => date("Y-m-d", $time));
     $goal += $visitCustomVariables;
     foreach ($this->convertedGoals as $convertedGoal) {
         printDebug("- Goal " . $convertedGoal['idgoal'] . " matched. Recording...");
         $newGoal = $goal;
         $newGoal['idgoal'] = $convertedGoal['idgoal'];
         $newGoal['url'] = $convertedGoal['url'];
         $newGoal['revenue'] = $convertedGoal['revenue'];
         if (!is_null($action)) {
             $newGoal['idaction_url'] = $action->getIdActionUrl();
             $newGoal['idlink_va'] = $action->getIdLinkVisitAction();
         }
         // If multiple Goal conversions per visit, set a cache buster
         $newGoal['buster'] = $convertedGoal['allow_multiple'] == 0 ? '0' : $visitorInformation['visit_last_action_time'];
         $newGoalDebug = $newGoal;
         $newGoalDebug['idvisitor'] = bin2hex($newGoalDebug['idvisitor']);
         printDebug($newGoalDebug);
         $fields = implode(", ", array_keys($newGoal));
         $bindFields = substr(str_repeat("?,", count($newGoal)), 0, -1);
         $sql = "INSERT IGNORE INTO " . Piwik_Common::prefixTable('log_conversion') . "\t\n\t\t\t\t\t({$fields}) VALUES ({$bindFields}) ";
         $bind = array_values($newGoal);
         Piwik_Tracker::getDatabase()->query($sql, $bind);
     }
 }
Esempio n. 19
0
	/**
	 * Sends http request using the specified transport method
	 *
	 * @param string $method
	 * @param string $aUrl
	 * @param int $timeout
	 * @param string $userAgent
	 * @param string $destinationPath
	 * @param resource $file
	 * @param int $followDepth
	 * @return bool true (or string) on success; false on HTTP response error code (1xx or 4xx)
	 * @throws Exception for all other errors
	 */
	static public function sendHttpRequestBy($method = 'socket', $aUrl, $timeout, $userAgent = null, $destinationPath = null, $file = null, $followDepth = 0, $acceptLanguage = false)
	{
		if ($followDepth > 5)
		{
			throw new Exception('Too many redirects ('.$followDepth.')');
		}

		$strlen = function_exists('mb_orig_strlen') ? 'mb_orig_strlen' : 'strlen';
		$contentLength = 0;
		$fileLength = 0;

		// Piwik services behave like a proxy, so we should act like one.
		$xff = 'X-Forwarded-For: '
			. (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] . ',' : '')
			. Piwik_IP::getIpFromHeader();
		$via = 'Via: '
			. (isset($_SERVER['HTTP_VIA']) && !empty($_SERVER['HTTP_VIA']) ? $_SERVER['HTTP_VIA'] . ', ' : '')
			. Piwik_Version::VERSION . ' Piwik'
			. ($userAgent ? " ($userAgent)" : '');
		$acceptLanguage = $acceptLanguage ? 'Accept-Language:'.$acceptLanguage : '';
		$userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'Piwik/'.Piwik_Version::VERSION;

		// proxy configuration
		if(!empty($GLOBALS['PIWIK_TRACKER_MODE']))
		{
			$proxyHost = Piwik_Tracker_Config::getInstance()->proxy['host'];
			$proxyPort = Piwik_Tracker_Config::getInstance()->proxy['port'];
			$proxyUser = Piwik_Tracker_Config::getInstance()->proxy['username'];
			$proxyPassword = Piwik_Tracker_Config::getInstance()->proxy['password'];
		}
		else
		{
			$config = Zend_Registry::get('config');
			if($config !== false)
			{
				$proxyHost = $config->proxy->host;
				$proxyPort = $config->proxy->port;
				$proxyUser = $config->proxy->username;
				$proxyPassword = $config->proxy->password;
			}
		}

		if($method == 'socket')
		{
			// initialization
			$url = @parse_url($aUrl);
			if($url === false || !isset($url['scheme']))
			{
				throw new Exception('Malformed URL: '.$aUrl);
			}

			if($url['scheme'] != 'http')
			{
				throw new Exception('Invalid protocol/scheme: '.$url['scheme']);
			}
			$host = $url['host'];
			$port = isset($url['port)']) ? $url['port'] : 80;
			$path = isset($url['path']) ? $url['path'] : '/';
			if(isset($url['query']))
			{
				$path .= '?'.$url['query'];
			}
			$errno = null;
			$errstr = null;

			$proxyAuth = null;
			if(!empty($proxyHost) && !empty($proxyPort))
			{
				$connectHost = $proxyHost;
				$connectPort = $proxyPort;
				if(!empty($proxyUser) && !empty($proxyPassword))
				{
					$proxyAuth = 'Proxy-Authorization: Basic '.base64_encode("$proxyUser:$proxyPassword") ."\r\n";
				}
				$requestHeader = "GET $aUrl HTTP/1.1\r\n";
			}
			else
			{
				$connectHost = $host;
				$connectPort = $port;
				$requestHeader = "GET $path HTTP/1.0\r\n";
			}

			// connection attempt
			if (($fsock = @fsockopen($connectHost, $connectPort, $errno, $errstr, $timeout)) === false || !is_resource($fsock))
			{
				if(is_resource($file)) { @fclose($file); }
				throw new Exception("Error while connecting to: $host. Please try again later. $errstr");
			}

			// send HTTP request header
			$requestHeader .=
				"Host: $host".($port != 80 ? ':'.$port : '')."\r\n"
				.($proxyAuth ? $proxyAuth : '')
				.'User-Agent: '.$userAgent."\r\n"
				. ($acceptLanguage ? $acceptLanguage ."\r\n" : '') 
				.$xff."\r\n"
				.$via."\r\n"
				."Connection: close\r\n"
				."\r\n";
			fwrite($fsock, $requestHeader);

			$streamMetaData = array('timed_out' => false);
			@stream_set_blocking($fsock, true);
			@stream_set_timeout($fsock, $timeout);

			// process header
			$status = null;
			$expectRedirect = false;

			while(!feof($fsock))
			{
				$line = fgets($fsock, 4096);

				$streamMetaData = @stream_get_meta_data($fsock);
				if($streamMetaData['timed_out'])
				{
					if(is_resource($file)) { @fclose($file); }
					@fclose($fsock);
					throw new Exception('Timed out waiting for server response');
				}

				// a blank line marks the end of the server response header
				if(rtrim($line, "\r\n") == '')
				{
					break;
				}

				// parse first line of server response header
				if(!$status)
				{
					// expect first line to be HTTP response status line, e.g., HTTP/1.1 200 OK
					if(!preg_match('~^HTTP/(\d\.\d)\s+(\d+)(\s*.*)?~', $line, $m))
					{
						if(is_resource($file)) { @fclose($file); }
						@fclose($fsock);
						throw new Exception('Expected server response code.  Got '.rtrim($line, "\r\n"));
					}

					$status = (integer) $m[2];

					// Informational 1xx or Client Error 4xx
					if ($status < 200 || $status >= 400)
					{
						if(is_resource($file)) { @fclose($file); }
						@fclose($fsock);
						return false;
					}

					continue;
				}

				// handle redirect
				if(preg_match('/^Location:\s*(.+)/', rtrim($line, "\r\n"), $m))
				{
					if(is_resource($file)) { @fclose($file); }
					@fclose($fsock);
					// Successful 2xx vs Redirect 3xx
					if($status < 300)
					{
						throw new Exception('Unexpected redirect to Location: '.rtrim($line).' for status code '.$status);
					}
					return self::sendHttpRequestBy($method, trim($m[1]), $timeout, $userAgent, $destinationPath, $file, $followDepth+1, $acceptLanguage);
				}

				// save expected content length for later verification
				if(preg_match('/^Content-Length:\s*(\d+)/', $line, $m))
				{
					$contentLength = (integer) $m[1];
				}
			}

			if(feof($fsock))
			{
				throw new Exception('Unexpected end of transmission');
			}

			// process content/body
			$response = '';

			while(!feof($fsock))
			{
				$line = fread($fsock, 8192);

				$streamMetaData = @stream_get_meta_data($fsock);
				if($streamMetaData['timed_out'])
				{
					if(is_resource($file)) { @fclose($file); }
					@fclose($fsock);
					throw new Exception('Timed out waiting for server response');
				}

				$fileLength += $strlen($line);

				if(is_resource($file))
				{
					// save to file
					fwrite($file, $line);
				}
				else
				{
					// concatenate to response string
					$response .= $line;
				}
			}

			// determine success or failure
			@fclose(@$fsock);
		}
		else if($method == 'fopen')
		{
			$response = false;

			// we make sure the request takes less than a few seconds to fail
			// we create a stream_context (works in php >= 5.2.1)
			// we also set the socket_timeout (for php < 5.2.1)
			$default_socket_timeout = @ini_get('default_socket_timeout');
			@ini_set('default_socket_timeout', $timeout);

			$ctx = null;
			if(function_exists('stream_context_create')) {
				$stream_options = array(
					'http' => array(
						'header' => 'User-Agent: '.$userAgent."\r\n"
									.($acceptLanguage ? $acceptLanguage."\r\n" : '')
									.$xff."\r\n"
									.$via."\r\n",
						'max_redirects' => 5, // PHP 5.1.0
						'timeout' => $timeout, // PHP 5.2.1
					)
				);

				if(!empty($proxyHost) && !empty($proxyPort))
				{
					$stream_options['http']['proxy'] = 'tcp://'.$proxyHost.':'.$proxyPort;
					$stream_options['http']['request_fulluri'] = true; // required by squid proxy
					if(!empty($proxyUser) && !empty($proxyPassword))
					{
						$stream_options['http']['header'] .= 'Proxy-Authorization: Basic '.base64_encode("$proxyUser:$proxyPassword")."\r\n";
					}
				}

				$ctx = stream_context_create($stream_options);
			}

			// save to file
			if(is_resource($file))
			{
				$handle = fopen($aUrl, 'rb', false, $ctx);
				while(!feof($handle))
				{
					$response = fread($handle, 8192);
					$fileLength += $strlen($response);
					fwrite($file, $response);
				}
				fclose($handle);
			}
			else
			{
				$response = @file_get_contents($aUrl, 0, $ctx);
				$fileLength = $strlen($response);
			}

			// restore the socket_timeout value
			if(!empty($default_socket_timeout))
			{
				@ini_set('default_socket_timeout', $default_socket_timeout);
			}
		}
		else if($method == 'curl')
		{
			$ch = @curl_init();

			if(!empty($proxyHost) && !empty($proxyPort))
			{
				@curl_setopt($ch, CURLOPT_PROXY, $proxyHost.':'.$proxyPort);
				if(!empty($proxyUser) && !empty($proxyPassword))
				{
					// PROXYAUTH defaults to BASIC
					@curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyUser.':'.$proxyPassword);
				}
			}

			$curl_options = array(
				// internal to ext/curl
				CURLOPT_BINARYTRANSFER => is_resource($file),

				// curl options (sorted oldest to newest)
				CURLOPT_URL => $aUrl,
				CURLOPT_USERAGENT => $userAgent,
				CURLOPT_HTTPHEADER => array(
					$xff,
					$via,
					$acceptLanguage
				),
				CURLOPT_HEADER => false,
				CURLOPT_CONNECTTIMEOUT => $timeout,
			);
			@curl_setopt_array($ch, $curl_options);

			/*
			 * use local list of Certificate Authorities, if available
			 */
			if(file_exists(PIWIK_INCLUDE_PATH . '/core/DataFiles/cacert.pem'))
			{
				@curl_setopt($ch, CURLOPT_CAINFO, PIWIK_INCLUDE_PATH . '/core/DataFiles/cacert.pem');
			}

			/*
			 * as of php 5.2.0, CURLOPT_FOLLOWLOCATION can't be set if
			 * in safe_mode or open_basedir is set
			 */
			if((string)ini_get('safe_mode') == '' && ini_get('open_basedir') == '')
			{ 
				$curl_options = array(
					// curl options (sorted oldest to newest)
					CURLOPT_FOLLOWLOCATION => true,
					CURLOPT_MAXREDIRS => 5, 
				);
				@curl_setopt_array($ch, $curl_options);
			}

			if(is_resource($file))
			{
				// write output directly to file
				@curl_setopt($ch, CURLOPT_FILE, $file);
			}
			else
			{
				// internal to ext/curl
				@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			}

			ob_start();
			$response = @curl_exec($ch);
			ob_end_clean();

			if($response === true)
			{
				$response = '';
			}
			else if($response === false)
			{
				$errstr = curl_error($ch);
				if($errstr != '')
				{
					throw new Exception('curl_exec: '.$errstr);
				}
				$response = '';
			}

			$contentLength = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
			$fileLength = is_resource($file) ? curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD) : $strlen($response);

			@curl_close($ch);
			unset($ch);
		}
		else
		{
			throw new Exception('Invalid request method: '.$method);
		}

		if(is_resource($file))
		{
			fflush($file);
			@fclose($file);

			$fileSize = filesize($destinationPath);
			if((($contentLength > 0) && ($fileLength != $contentLength)) || ($fileSize != $fileLength))
			{
				throw new Exception('File size error: '.$destinationPath.'; expected '.$contentLength.' bytes; received '.$fileLength.' bytes; saved '.$fileSize.' bytes to file');
			}
			return true;
		}

		if(($contentLength > 0) && ($fileLength != $contentLength))
		{
			throw new Exception('Content length error: expected '.$contentLength.' bytes; received '.$fileLength.' bytes');
		}
		return trim($response);
	}
Esempio n. 20
0
 /**
  * Records one or several goals matched in this request.
  */
 public function recordGoals($idSite, $visitorInformation, $visitCustomVariables, $action, $referrerTimestamp, $referrerUrl, $referrerCampaignName, $referrerCampaignKeyword)
 {
     $location_country = isset($visitorInformation['location_country']) ? $visitorInformation['location_country'] : Piwik_Common::getCountry(Piwik_Common::getBrowserLanguage(), $enableLanguageToCountryGuess = Piwik_Tracker_Config::getInstance()->Tracker['enable_language_to_country_guess'], $visitorInformation['location_ip']);
     $location_continent = isset($visitorInformation['location_continent']) ? $visitorInformation['location_continent'] : Piwik_Common::getContinent($location_country);
     $goal = array('idvisit' => $visitorInformation['idvisit'], 'idsite' => $idSite, 'idvisitor' => $visitorInformation['idvisitor'], 'server_time' => Piwik_Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time']), 'location_country' => $location_country, 'location_continent' => $location_continent, 'visitor_returning' => $visitorInformation['visitor_returning'], 'visitor_days_since_first' => $visitorInformation['visitor_days_since_first'], 'visitor_days_since_order' => $visitorInformation['visitor_days_since_order'], 'visitor_count_visits' => $visitorInformation['visitor_count_visits']);
     // Copy Custom Variables from Visit row to the Goal conversion
     for ($i = 1; $i <= Piwik_Tracker::MAX_CUSTOM_VARIABLES; $i++) {
         if (isset($visitorInformation['custom_var_k' . $i]) && strlen($visitorInformation['custom_var_k' . $i])) {
             $goal['custom_var_k' . $i] = $visitorInformation['custom_var_k' . $i];
         }
         if (isset($visitorInformation['custom_var_v' . $i]) && strlen($visitorInformation['custom_var_v' . $i])) {
             $goal['custom_var_v' . $i] = $visitorInformation['custom_var_v' . $i];
         }
     }
     // Otherwise, set the Custom Variables found in the cookie sent with this request
     $goal += $visitCustomVariables;
     // Attributing the correct Referrer to this conversion.
     // Priority order is as follows:
     // 0) In some cases, the campaign is not passed from the JS so we look it up from the current visit
     // 1) Campaign name/kwd parsed in the JS
     // 2) Referrer URL stored in the _ref cookie
     // 3) If no info from the cookie, attribute to the current visit referrer
     // 3) Default values: current referrer
     $type = $visitorInformation['referer_type'];
     $name = $visitorInformation['referer_name'];
     $keyword = $visitorInformation['referer_keyword'];
     $time = $visitorInformation['visit_first_action_time'];
     // 0) In some (unknown!?) cases the campaign is not found in the attribution cookie, but the URL ref was found.
     //    In this case we look up if the current visit is credited to a campaign and will credit this campaign rather than the URL ref (since campaigns have higher priority)
     if (empty($refererCampaignName) && $type == Piwik_Common::REFERER_TYPE_CAMPAIGN && !empty($name)) {
         // Use default values per above
     } elseif (!empty($referrerCampaignName)) {
         $type = Piwik_Common::REFERER_TYPE_CAMPAIGN;
         $name = $referrerCampaignName;
         $keyword = $referrerCampaignKeyword;
         $time = $referrerTimestamp;
     } elseif (!empty($referrerUrl)) {
         $referrer = new Piwik_Tracker_Visit_Referer();
         $referrer = $referrer->getRefererInformation($referrerUrl, $currentUrl = '', $idSite);
         // if the parsed referer is interesting enough, ie. website or search engine
         if (in_array($referrer['referer_type'], array(Piwik_Common::REFERER_TYPE_SEARCH_ENGINE, Piwik_Common::REFERER_TYPE_WEBSITE))) {
             $type = $referrer['referer_type'];
             $name = $referrer['referer_name'];
             $keyword = $referrer['referer_keyword'];
             $time = $referrerTimestamp;
         }
     }
     $goal += array('referer_type' => $type, 'referer_name' => $name, 'referer_keyword' => $keyword, 'referer_visit_server_date' => date("Y-m-d", $time));
     // some goals are converted, so must be ecommerce Order or Cart Update
     if ($this->requestIsEcommerce) {
         $this->recordEcommerceGoal($goal, $visitorInformation);
     } else {
         $this->recordStandardGoals($goal, $action, $visitorInformation);
     }
 }
Esempio n. 21
0
 protected function authenticateSuperUserOrAdmin()
 {
     $tokenAuth = Piwik_Common::getRequestVar('token_auth', false);
     if ($tokenAuth) {
         $superUserLogin = Piwik_Tracker_Config::getInstance()->superuser['login'];
         $superUserPassword = Piwik_Tracker_Config::getInstance()->superuser['password'];
         if (md5($superUserLogin . $superUserPassword) == $tokenAuth) {
             return true;
         }
         // Now checking the list of admin token_auth cached in the Tracker config file
         $idSite = Piwik_Common::getRequestVar('idsite', false, 'int', $this->request);
         if (!empty($idSite) && $idSite > 0) {
             $website = Piwik_Common::getCacheWebsiteAttributes($idSite);
             $adminTokenAuth = $website['admin_token_auth'];
             if (in_array($tokenAuth, $adminTokenAuth)) {
                 return true;
             }
         }
         printDebug("token_auth = {$tokenAuth} - Warning: Super User / Admin was NOT authenticated");
     }
     return false;
 }
Esempio n. 22
0
	/**
	 * Hook on Tracker.saveVisitorInformation to anonymize visitor IP addresses
	 */
	function anonymizeVisitorIpAddress($notification)
	{
		$visitorInfo =& $notification->getNotificationObject();
		$visitorInfo['location_ip'] = self::applyIPMask($visitorInfo['location_ip'], Piwik_Tracker_Config::getInstance()->Tracker['ip_address_mask_length']);
	}
Esempio n. 23
0
 /**
  * Generates the name of the action from the URL or the specified name.
  * Sets the name as $this->actionName
  * 
  * @return void
  */
 protected function extractUrlAndActionNameFromRequest()
 {
     // download?
     $downloadVariableName = Piwik_Tracker_Config::getInstance()->Tracker['download_url_var_name'];
     $downloadUrl = Piwik_Common::getRequestVar($downloadVariableName, '', 'string', $this->request);
     if (!empty($downloadUrl)) {
         $actionType = self::TYPE_DOWNLOAD;
         $url = $downloadUrl;
     }
     // outlink?
     if (empty($actionType)) {
         $outlinkVariableName = Piwik_Tracker_Config::getInstance()->Tracker['outlink_url_var_name'];
         $outlinkUrl = Piwik_Common::getRequestVar($outlinkVariableName, '', 'string', $this->request);
         if (!empty($outlinkUrl)) {
             $actionType = self::TYPE_OUTLINK;
             $url = $outlinkUrl;
         }
     }
     // defaults to page view
     if (empty($actionType)) {
         $actionType = self::TYPE_ACTION;
         $url = Piwik_Common::getRequestVar('url', '', 'string', $this->request);
         $actionName = Piwik_Common::getRequestVar('action_name', '', 'string', $this->request);
         if (empty($actionName)) {
             $cleanedUrl = str_replace(array("\n", "\r", "\t"), "", $url);
             $actionName = Piwik_Common::getPathAndQueryFromUrl($cleanedUrl);
             // in case the $actionName is empty or ending with a slash,
             // we append the defaultActionName: a/b/ becomes a/b/index
             if (empty($actionName) || substr($actionName, -1) == '/') {
                 $actionName .= $this->getDefaultActionName();
             }
         }
         // get the delimiter, by default '/'
         $actionCategoryDelimiter = Piwik_Tracker_Config::getInstance()->General['action_category_delimiter'];
         // create an array of the categories delimited by the delimiter
         $split = explode($actionCategoryDelimiter, $actionName);
         // trim every category
         $split = array_map('trim', $split);
         // remove empty categories
         $split = array_filter($split, 'strlen');
         // rebuild the name from the array of cleaned categories
         $actionName = implode($actionCategoryDelimiter, $split);
     }
     $url = trim($url);
     $url = str_replace(array("\n", "\r"), "", $url);
     if (empty($actionName)) {
         $actionName = $url;
     }
     return array('name' => $actionName, 'type' => $actionType, 'url' => $url);
 }
Esempio n. 24
0
 /**
  * Generates the name of the action from the URL or the specified name.
  * Sets the name as $this->actionName
  *
  * @return array
  */
 protected function extractUrlAndActionNameFromRequest()
 {
     $actionName = null;
     // download?
     $downloadUrl = Piwik_Common::getRequestVar('download', '', 'string', $this->request);
     if (!empty($downloadUrl)) {
         $actionType = self::TYPE_DOWNLOAD;
         $url = $downloadUrl;
     }
     // outlink?
     if (empty($actionType)) {
         $outlinkUrl = Piwik_Common::getRequestVar('link', '', 'string', $this->request);
         if (!empty($outlinkUrl)) {
             $actionType = self::TYPE_OUTLINK;
             $url = $outlinkUrl;
         }
     }
     $actionName = Piwik_Common::getRequestVar('action_name', '', 'string', $this->request);
     // defaults to page view
     if (empty($actionType)) {
         $actionType = self::TYPE_ACTION_URL;
         $url = Piwik_Common::getRequestVar('url', '', 'string', $this->request);
         // get the delimiter, by default '/'; BC, we read the old action_category_delimiter first (see #1067)
         $actionCategoryDelimiter = isset(Piwik_Tracker_Config::getInstance()->General['action_category_delimiter']) ? Piwik_Tracker_Config::getInstance()->General['action_category_delimiter'] : Piwik_Tracker_Config::getInstance()->General['action_url_category_delimiter'];
         // create an array of the categories delimited by the delimiter
         $split = explode($actionCategoryDelimiter, $actionName);
         // trim every category
         $split = array_map('trim', $split);
         // remove empty categories
         $split = array_filter($split, 'strlen');
         // rebuild the name from the array of cleaned categories
         $actionName = implode($actionCategoryDelimiter, $split);
     }
     $url = trim($url);
     $url = str_replace(array("\n", "\r"), "", $url);
     $actionName = trim($actionName);
     $actionName = str_replace(array("\n", "\r"), "", $actionName);
     return array('name' => empty($actionName) ? '' : $actionName, 'type' => $actionType, 'url' => $url);
 }
Esempio n. 25
0
 /**
  * Generates a new action for the current visitor.
  * We random generate some campaigns, action names, download or outlink clicks, etc.
  * We generate a new Referer, that would be read in the case the visit last page is older than 30 minutes.
  * 
  * This function tries to generate actions that use the features of Piwik (campaigns, downloads, outlinks, action_name set in the JS tag, etc.)
  * 
  * @return void
  * 
  */
 protected function generateActionVisit()
 {
     // we don't keep the previous action values
     // reinit them to empty string
     $this->setCurrentRequest(Piwik_Tracker_Config::getInstance()->Tracker['download_url_var_name'], '');
     $this->setCurrentRequest(Piwik_Tracker_Config::getInstance()->Tracker['outlink_url_var_name'], '');
     $this->setCurrentRequest('action_name', '');
     // generate new url referer ; case the visitor stays more than 30min
     // (when the visit is known this value will simply be ignored)
     $this->setCurrentRequest('urlref', $this->getRandom('urlref'));
     // generates the current URL
     $url = $this->getRandomUrlFromHost($this->host);
     // we generate a campaign
     $urlVars = $this->getRandom('piwik_vars_campaign');
     // if we actually generated a campaign
     if (!empty($urlVars)) {
         // campaign name
         $urlValue = $this->getRandomString(5, 3, 'lower');
         // add the parameter to the url
         $url .= '?' . $urlVars . '=' . $urlValue;
         // for a campaign of the CPC kind, we sometimes generate a keyword
         if ($urlVars == Piwik_Tracker_Config::getInstance()->Tracker['campaign_var_name'] && mt_rand(0, 1) == 0) {
             $url .= '&' . Piwik_Tracker_Config::getInstance()->Tracker['campaign_keyword_var_name'] . '=' . $this->getRandomString(6, 3, 'ALL');
         }
     } else {
         // we generate a download Or Outlink parameter in the GET request so that
         // the current action is counted as a download action OR a outlink click action
         $GETParamToAdd = $this->getRandom('piwik_downloadOrOutlink');
         if (!empty($GETParamToAdd)) {
             $possibleDownloadHosts = array('http://piwik.org/', $this->host);
             $nameDownload = $this->getRandomUrlFromHost($possibleDownloadHosts[mt_rand(0, 1)]);
             $extensions = array('.zip', '.tar.gz');
             $nameDownload .= $extensions[mt_rand(0, 1)];
             $urlValue = $nameDownload;
             // add the parameter to the url
             $this->setCurrentRequest($GETParamToAdd, $urlValue);
         } elseif (rand(0, 2) == 1) {
             $this->setCurrentRequest('action_name', $this->getRandomString(1, 1));
         }
     }
     $this->setCurrentRequest('url', $url);
     // setup the title of the page
     $this->setCurrentRequest('title', $this->getRandomString(15, 5));
 }
Esempio n. 26
0
 function recordGoals($visitorInformation, $action)
 {
     $location_country = isset($visitorInformation['location_country']) ? $visitorInformation['location_country'] : Piwik_Common::getCountry(Piwik_Common::getBrowserLanguage(), $enableLanguageToCountryGuess = Piwik_Tracker_Config::getInstance()->Tracker['enable_language_to_country_guess']);
     $location_continent = isset($visitorInformation['location_continent']) ? $visitorInformation['location_continent'] : Piwik_Common::getContinent($location_country);
     $goal = array('idvisit' => $visitorInformation['idvisit'], 'idsite' => $visitorInformation['idsite'], 'visitor_idcookie' => $visitorInformation['visitor_idcookie'], 'server_time' => Piwik_Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time']), 'visit_server_date' => $visitorInformation['visit_server_date'], 'location_country' => $location_country, 'location_continent' => $location_continent, 'visitor_returning' => $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_VISITOR_RETURNING));
     $referer_idvisit = $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_ID_VISIT);
     if ($referer_idvisit !== false) {
         $goal += array('referer_idvisit' => $referer_idvisit, 'referer_visit_server_date' => date("Y-m-d", $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_TIMESTAMP)), 'referer_type' => htmlspecialchars_decode($this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_TYPE)), 'referer_name' => htmlspecialchars_decode($this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_NAME)), 'referer_keyword' => htmlspecialchars_decode($this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_KEYWORD)));
     }
     foreach ($this->convertedGoals as $convertedGoal) {
         printDebug("- Goal " . $convertedGoal['idgoal'] . " matched. Recording...");
         $newGoal = $goal;
         $newGoal['idgoal'] = $convertedGoal['idgoal'];
         $newGoal['url'] = $convertedGoal['url'];
         $newGoal['revenue'] = $convertedGoal['revenue'];
         if (!is_null($action)) {
             $newGoal['idaction'] = $action->getIdAction();
             $newGoal['idlink_va'] = $action->getIdLinkVisitAction();
         }
         printDebug($newGoal);
         $fields = implode(", ", array_keys($newGoal));
         $bindFields = substr(str_repeat("?,", count($newGoal)), 0, -1);
         try {
             Piwik_Tracker::getDatabase()->query("INSERT INTO " . Piwik_Common::prefixTable('log_conversion') . "\t({$fields}) \n\t\t\t\t\tVALUES ({$bindFields}) ", array_values($newGoal));
         } catch (Exception $e) {
             if (strpos($e->getMessage(), '1062') !== false) {
                 // integrity violation when same visit converts to the same goal twice
                 printDebug("--> Goal already recorded for this (idvisit, idgoal)");
             } else {
                 throw $e;
             }
         }
         //$idlog_goal = Piwik_Tracker::getDatabase()->lastInsertId();
     }
 }
Esempio n. 27
0
	/**
	 * Records one or several goals matched in this request.
	 */
	public function recordGoals($idSite, $visitorInformation, $visitCustomVariables, $action, $referrerTimestamp, $referrerUrl, $referrerCampaignName, $referrerCampaignKeyword)
	{
		$location_country = isset($visitorInformation['location_country']) 
							? $visitorInformation['location_country'] 
							: Piwik_Common::getCountry( 
										Piwik_Common::getBrowserLanguage(), 
										$enableLanguageToCountryGuess = Piwik_Tracker_Config::getInstance()->Tracker['enable_language_to_country_guess'], $visitorInformation['location_ip'] 
							);
							
		$location_continent = isset($visitorInformation['location_continent']) 
								? $visitorInformation['location_continent'] 
								: Piwik_Common::getContinent($location_country);

		$goal = array(
			'idvisit' 			=> $visitorInformation['idvisit'],
			'idsite' 			=> $idSite,
			'idvisitor' 		=> $visitorInformation['idvisitor'],
			'server_time' 		=> Piwik_Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time']),
			'location_country'  => $location_country,
			'location_continent'=> $location_continent,
			'visitor_returning' => $visitorInformation['visitor_returning'],
			'visitor_days_since_first' => $visitorInformation['visitor_days_since_first'],
			'visitor_days_since_order' => $visitorInformation['visitor_days_since_order'],
			'visitor_count_visits' => $visitorInformation['visitor_count_visits'],
		
		);

		// Attributing the correct Referrer to this conversion. 
		// Priority order is as follows:
		// 1) Campaign name/kwd parsed in the JS
		// 2) Referrer URL stored in the _ref cookie
		// 3) If no info from the cookie, attribute to the current visit referrer
		
		// 3) Default values: current referrer
        $type = $visitorInformation['referer_type'];
        $name = $visitorInformation['referer_name'];
        $keyword = $visitorInformation['referer_keyword'];
        $time = $visitorInformation['visit_first_action_time'];
        
        // 1) Campaigns from 1st party cookie
		if(!empty($referrerCampaignName))
		{
			$type = Piwik_Common::REFERER_TYPE_CAMPAIGN;
			$name = $referrerCampaignName;
			$keyword = $referrerCampaignKeyword;
			$time = $referrerTimestamp;
		}
		// 2) Referrer URL parsing
		elseif(!empty($referrerUrl))
		{
			$referrer = new Piwik_Tracker_Visit_Referer();  
            $referrer = $referrer->getRefererInformation($referrerUrl, $currentUrl = '', $idSite);
            
            // if the parsed referer is interesting enough, ie. website or search engine 
            if(in_array($referrer['referer_type'], array(Piwik_Common::REFERER_TYPE_SEARCH_ENGINE, Piwik_Common::REFERER_TYPE_WEBSITE)))
            {
            	$type = $referrer['referer_type'];
            	$name = $referrer['referer_name'];
            	$keyword = $referrer['referer_keyword'];
				$time = $referrerTimestamp;
            }
		}
		$goal += array(
			'referer_type' 				=> $type,
			'referer_name' 				=> $name,
			'referer_keyword' 			=> $keyword,
			// this field is currently unused
			'referer_visit_server_date' => date("Y-m-d", $time),
		);

		$goal += $visitCustomVariables;
		
		// some goals are converted, so must be ecommerce Order or Cart Update 
		if($this->requestIsEcommerce)
		{
			$this->recordEcommerceGoal($goal, $visitorInformation);
		}
		else
		{
			$this->recordStandardGoals($goal, $action, $visitorInformation);
		}
	}