Beispiel #1
0
 /**
  * Returns an array containing the following information:
  * - referer_type
  *        - direct            -- absence of referrer URL OR referrer URL has the same host
  *        - site                -- based on the referrer URL
  *        - search_engine        -- based on the referrer URL
  *        - campaign            -- based on campaign URL parameter
  *
  * - referer_name
  *         - ()
  *         - piwik.net            -- site host name
  *         - google.fr            -- search engine host name
  *         - adwords-search    -- campaign name
  *
  * - referer_keyword
  *         - ()
  *         - ()
  *         - my keyword
  *         - my paid keyword
  *         - ()
  *         - ()
  *
  * - referer_url : the same for all the referrer types
  *
  * @param string $referrerUrl must be URL Encoded
  * @param string $currentUrl
  * @param int $idSite
  * @return array
  */
 public function getReferrerInformation($referrerUrl, $currentUrl, $idSite)
 {
     $this->idsite = $idSite;
     // default values for the referer_* fields
     $referrerUrl = Common::unsanitizeInputValue($referrerUrl);
     if (!empty($referrerUrl) && !UrlHelper::isLookLikeUrl($referrerUrl)) {
         $referrerUrl = '';
     }
     $currentUrl = PageUrl::cleanupUrl($currentUrl);
     $this->referrerUrl = $referrerUrl;
     $this->referrerUrlParse = @parse_url($this->referrerUrl);
     $this->currentUrlParse = @parse_url($currentUrl);
     $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY;
     $this->nameReferrerAnalyzed = '';
     $this->keywordReferrerAnalyzed = '';
     $this->referrerHost = '';
     if (isset($this->referrerUrlParse['host'])) {
         $this->referrerHost = $this->referrerUrlParse['host'];
     }
     $referrerDetected = $this->detectReferrerCampaign();
     if (!$referrerDetected) {
         if ($this->detectReferrerDirectEntry() || $this->detectReferrerSearchEngine()) {
             $referrerDetected = true;
         }
     }
     if (!empty($this->referrerHost) && !$referrerDetected) {
         $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_WEBSITE;
         $this->nameReferrerAnalyzed = Common::mb_strtolower($this->referrerHost);
     }
     $referrerInformation = array('referer_type' => $this->typeReferrerAnalyzed, 'referer_name' => $this->nameReferrerAnalyzed, 'referer_keyword' => $this->keywordReferrerAnalyzed, 'referer_url' => $this->referrerUrl);
     return $referrerInformation;
 }
Beispiel #2
0
 /** Render the area left of the iframe */
 public function renderSidebar()
 {
     $idSite = Common::getRequestVar('idSite');
     $period = Common::getRequestVar('period');
     $date = Common::getRequestVar('date');
     $currentUrl = Common::getRequestVar('currentUrl');
     $currentUrl = Common::unsanitizeInputValue($currentUrl);
     $normalizedCurrentUrl = PageUrl::excludeQueryParametersFromUrl($currentUrl, $idSite);
     $normalizedCurrentUrl = Common::unsanitizeInputValue($normalizedCurrentUrl);
     // load the appropriate row of the page urls report using the label filter
     ArchivingHelper::reloadConfig();
     $path = ArchivingHelper::getActionExplodedNames($normalizedCurrentUrl, Action::TYPE_PAGE_URL);
     $path = array_map('urlencode', $path);
     $label = implode('>', $path);
     $request = new Request('method=Actions.getPageUrls' . '&idSite=' . urlencode($idSite) . '&date=' . urlencode($date) . '&period=' . urlencode($period) . '&label=' . urlencode($label) . '&format=original' . '&format_metrics=0');
     $dataTable = $request->process();
     $formatter = new Metrics\Formatter\Html();
     $data = array();
     if ($dataTable->getRowsCount() > 0) {
         $row = $dataTable->getFirstRow();
         $translations = Metrics::getDefaultMetricTranslations();
         $showMetrics = array('nb_hits', 'nb_visits', 'nb_users', 'nb_uniq_visitors', 'bounce_rate', 'exit_rate', 'avg_time_on_page');
         foreach ($showMetrics as $metric) {
             $value = $row->getColumn($metric);
             if ($value === false) {
                 // skip unique visitors for period != day
                 continue;
             }
             if ($metric == 'bounce_rate' || $metric == 'exit_rate') {
                 $value = $formatter->getPrettyPercentFromQuotient($value);
             } else {
                 if ($metric == 'avg_time_on_page') {
                     $value = $formatter->getPrettyTimeFromSeconds($value, $displayAsSentence = true);
                 }
             }
             $data[] = array('name' => $translations[$metric], 'value' => $value);
         }
     }
     // generate page url string
     foreach ($path as &$part) {
         $part = preg_replace(';^/;', '', urldecode($part));
     }
     $page = '/' . implode('/', $path);
     $page = preg_replace(';/index$;', '/', $page);
     if ($page == '/') {
         $page = '/index';
     }
     // render template
     $view = new View('@Overlay/renderSidebar');
     $view->data = $data;
     $view->location = $page;
     $view->normalizedUrl = $normalizedCurrentUrl;
     $view->label = $label;
     $view->idSite = $idSite;
     $view->period = $period;
     $view->date = $date;
     $this->outputCORSHeaders();
     return $view->render();
 }
Beispiel #3
0
 protected function getActionsToLookup()
 {
     $actionUrl = false;
     $url = $this->getActionUrl();
     if (!empty($url)) {
         // normalize urls by stripping protocol and www
         $url = Tracker\PageUrl::normalizeUrl($url);
         $actionUrl = array($url['url'], $this->getActionType(), $url['prefixId']);
     }
     return array('idaction_url' => $actionUrl);
 }
Beispiel #4
0
 /**
  * Returns the extracted utm details from the url
  * @param  string  $currentUrl 
  * @param  int     $idSite     
  * @param  Request $request    
  * @return array            
  */
 private function getCampaignInformation($currentUrl, $idSite, Request $request)
 {
     $cacheKey = $currentUrl . $idSite;
     if (isset(self::$cachedReferrer[$cacheKey])) {
         return self::$cachedReferrer[$cacheKey];
     }
     $currentUrl = PageUrl::cleanupUrl($currentUrl);
     $this->currentUrlParse = @parse_url($currentUrl);
     $utmInformation = $this->extractUtmDetailsFromUrl();
     self::$cachedReferrer[$cacheKey] = $utmInformation;
     return $utmInformation;
 }
Beispiel #5
0
 /**
  * Returns an array containing the following information:
  * - referer_type
  *        - direct            -- absence of referrer URL OR referrer URL has the same host
  *        - site                -- based on the referrer URL
  *        - search_engine        -- based on the referrer URL
  *        - campaign            -- based on campaign URL parameter
  *
  * - referer_name
  *         - ()
  *         - piwik.net            -- site host name
  *         - google.fr            -- search engine host name
  *         - adwords-search    -- campaign name
  *
  * - referer_keyword
  *         - ()
  *         - ()
  *         - my keyword
  *         - my paid keyword
  *         - ()
  *         - ()
  *
  * - referer_url : the same for all the referrer types
  *
  * @param string $referrerUrl must be URL Encoded
  * @param string $currentUrl
  * @param int $idSite
  * @return array
  */
 protected function getReferrerInformation($referrerUrl, $currentUrl, $idSite, Request $request)
 {
     $cacheKey = $referrerUrl . $currentUrl . $idSite;
     if (isset(self::$cachedReferrer[$cacheKey])) {
         return self::$cachedReferrer[$cacheKey];
     }
     $this->idsite = $idSite;
     // default values for the referer_* fields
     $referrerUrl = Common::unsanitizeInputValue($referrerUrl);
     if (!empty($referrerUrl) && !UrlHelper::isLookLikeUrl($referrerUrl)) {
         $referrerUrl = '';
     }
     $currentUrl = PageUrl::cleanupUrl($currentUrl);
     $this->referrerUrl = $referrerUrl;
     $this->referrerUrlParse = @parse_url($this->referrerUrl);
     $this->currentUrlParse = @parse_url($currentUrl);
     $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY;
     $this->nameReferrerAnalyzed = '';
     $this->keywordReferrerAnalyzed = '';
     $this->referrerHost = '';
     if (isset($this->referrerUrlParse['host'])) {
         $this->referrerHost = $this->referrerUrlParse['host'];
     }
     $referrerDetected = $this->detectReferrerCampaign($request);
     if (!$referrerDetected) {
         if ($this->detectReferrerDirectEntry() || $this->detectReferrerSearchEngine()) {
             $referrerDetected = true;
         }
     }
     if (!$referrerDetected && !empty($this->referrerHost)) {
         $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_WEBSITE;
         $this->nameReferrerAnalyzed = Common::mb_strtolower($this->referrerHost);
         $urlsByHost = $this->getCachedUrlsByHostAndIdSite();
         $directEntry = new SiteUrls();
         $path = $directEntry->getPathMatchingUrl($this->referrerUrlParse, $urlsByHost);
         if (!empty($path) && $path !== '/') {
             $this->nameReferrerAnalyzed .= rtrim($path, '/');
         }
     }
     $referrerInformation = array('referer_type' => $this->typeReferrerAnalyzed, 'referer_name' => $this->nameReferrerAnalyzed, 'referer_keyword' => $this->keywordReferrerAnalyzed, 'referer_url' => $this->referrerUrl);
     self::$cachedReferrer[$cacheKey] = $referrerInformation;
     return $referrerInformation;
 }
Beispiel #6
0
 /**
  * Get following pages of a url.
  * This is done on the logs - not the archives!
  *
  * Note: if you use this method via the regular API, the number of results will be limited.
  * Make sure, you set filter_limit=-1 in the request.
  */
 public function getFollowingPages($url, $idSite, $period, $date, $segment = false)
 {
     $this->authenticate($idSite);
     $url = PageUrl::excludeQueryParametersFromUrl($url, $idSite);
     // we don't unsanitize $url here. it will be done in the Transitions plugin.
     $resultDataTable = new DataTable();
     try {
         $limitBeforeGrouping = Config::getInstance()->General['overlay_following_pages_limit'];
         $transitionsReport = APITransitions::getInstance()->getTransitionsForAction($url, $type = 'url', $idSite, $period, $date, $segment, $limitBeforeGrouping, $part = 'followingActions', $returnNormalizedUrls = true);
     } catch (Exception $e) {
         return $resultDataTable;
     }
     $reports = array('followingPages', 'outlinks', 'downloads');
     foreach ($reports as $reportName) {
         if (!isset($transitionsReport[$reportName])) {
             continue;
         }
         foreach ($transitionsReport[$reportName]->getRows() as $row) {
             // don't touch the row at all for performance reasons
             $resultDataTable->addRow($row);
         }
     }
     return $resultDataTable;
 }
Beispiel #7
0
 private function getPageLabel(&$pageRecord, $type)
 {
     if ($type == Action::TYPE_PAGE_TITLE) {
         $label = $pageRecord['name'];
         if (empty($label)) {
             $label = ArchivingHelper::getUnknownActionName(Action::TYPE_PAGE_TITLE);
         }
         return $label;
     }
     if ($type == Action::TYPE_OUTLINK || $type == Action::TYPE_DOWNLOAD) {
         return PageUrl::reconstructNormalizedUrl($pageRecord['name'], $pageRecord['url_prefix']);
     }
     return $pageRecord['name'];
 }
Beispiel #8
0
 /**
  * Will search in the DataTable for a Label matching the searched string
  * and return only the matching row, or an empty datatable
  */
 protected function getFilterPageDatatableSearch($callBackParameters, $search, $actionType, $table = false, $searchTree = false)
 {
     if ($searchTree === false) {
         // build the query parts that are searched inside the tree
         if ($actionType == Action::TYPE_PAGE_TITLE) {
             $searchedString = Common::unsanitizeInputValue($search);
         } else {
             $idSite = $callBackParameters[1];
             try {
                 $searchedString = PageUrl::excludeQueryParametersFromUrl($search, $idSite);
             } catch (Exception $e) {
                 $searchedString = $search;
             }
         }
         ArchivingHelper::reloadConfig();
         $searchTree = ArchivingHelper::getActionExplodedNames($searchedString, $actionType);
     }
     if ($table === false) {
         // fetch the data table
         $table = call_user_func_array(array($this, 'getDataTableFromArchive'), $callBackParameters);
         if ($table instanceof DataTable\Map) {
             // search an array of tables, e.g. when using date=last30
             // note that if the root is an array, we filter all children
             // if an array occurs inside the nested table, we only look for the first match (see below)
             $dataTableMap = $table->getEmptyClone();
             foreach ($table->getDataTables() as $label => $subTable) {
                 $newSubTable = $this->doFilterPageDatatableSearch($callBackParameters, $subTable, $searchTree);
                 $dataTableMap->addTable($newSubTable, $label);
             }
             return $dataTableMap;
         }
     }
     return $this->doFilterPageDatatableSearch($callBackParameters, $table, $searchTree);
 }
Beispiel #9
0
 public function detectGoalId($idSite)
 {
     if (!Common::isGoalPluginEnabled()) {
         return false;
     }
     $goals = $this->getGoalDefinitions($idSite);
     if (!isset($goals[$this->idGoal])) {
         return false;
     }
     $goal = $goals[$this->idGoal];
     $url = $this->request->getParam('url');
     $goal['url'] = PageUrl::excludeQueryParametersFromUrl($url, $idSite);
     $this->convertedGoals[] = $goal;
     return true;
 }
Beispiel #10
0
 public static function getUrlIfLookValid($url)
 {
     $url = PageUrl::cleanupString($url);
     if (!UrlHelper::isLookLikeUrl($url)) {
         Common::printDebug("WARNING: URL looks invalid and is discarded");
         return false;
     }
     return $url;
 }
Beispiel #11
0
 protected function detectSiteSearch($originalUrl)
 {
     $website = Cache::getCacheWebsiteAttributes($this->request->getIdSite());
     if (empty($website['sitesearch'])) {
         Common::printDebug("Internal 'Site Search' tracking is not enabled for this site. ");
         return false;
     }
     $actionName = $url = $categoryName = $count = false;
     $originalUrl = PageUrl::cleanupUrl($originalUrl);
     // Detect Site search from Tracking API parameters rather than URL
     $searchKwd = $this->request->getParam('search');
     if (!empty($searchKwd)) {
         $actionName = $searchKwd;
         $isCategoryName = $this->request->getParam('search_cat');
         if (!empty($isCategoryName)) {
             $categoryName = $isCategoryName;
         }
         $isCount = $this->request->getParam('search_count');
         if ($this->isValidSearchCount($isCount)) {
             $count = $isCount;
         }
     }
     if (empty($actionName)) {
         $parsedUrl = @parse_url($originalUrl);
         // Detect Site Search from URL query parameters
         if (!empty($parsedUrl['query']) || !empty($parsedUrl['fragment'])) {
             // array($url, $actionName, $categoryName, $count);
             $searchInfo = $this->detectSiteSearchFromUrl($website, $parsedUrl);
             if (!empty($searchInfo)) {
                 list($url, $actionName, $categoryName, $count) = $searchInfo;
             }
         }
     }
     $actionName = trim($actionName);
     $categoryName = trim($categoryName);
     if (empty($actionName)) {
         Common::printDebug("(this is not a Site Search request)");
         return false;
     }
     Common::printDebug("Detected Site Search keyword '{$actionName}'. ");
     if (!empty($categoryName)) {
         Common::printDebug("- Detected Site Search Category '{$categoryName}'. ");
     }
     if ($count !== false) {
         Common::printDebug("- Search Results Count was '{$count}'. ");
     }
     if ($url != $originalUrl) {
         Common::printDebug("NOTE: The Page URL was changed / removed, during the Site Search detection, was '{$originalUrl}', now is '{$url}'");
     }
     return array($actionName, $url, $categoryName, $count);
 }
Beispiel #12
0
 /**
  * @param $visitorDetailsArray
  * @param $actionsLimit
  * @param $timezone
  * @return array
  */
 public static function enrichVisitorArrayWithActions($visitorDetailsArray, $actionsLimit, $timezone)
 {
     $idVisit = $visitorDetailsArray['idVisit'];
     $model = new Model();
     $actionDetails = $model->queryActionsForVisit($idVisit, $actionsLimit);
     $formatter = new Formatter();
     $maxCustomVariables = CustomVariables::getNumUsableCustomVariables();
     foreach ($actionDetails as $actionIdx => &$actionDetail) {
         $actionDetail =& $actionDetails[$actionIdx];
         $customVariablesPage = array();
         for ($i = 1; $i <= $maxCustomVariables; $i++) {
             if (!empty($actionDetail['custom_var_k' . $i])) {
                 $cvarKey = $actionDetail['custom_var_k' . $i];
                 $cvarKey = static::getCustomVariablePrettyKey($cvarKey);
                 $customVariablesPage[$i] = array('customVariablePageName' . $i => $cvarKey, 'customVariablePageValue' . $i => $actionDetail['custom_var_v' . $i]);
             }
             unset($actionDetail['custom_var_k' . $i]);
             unset($actionDetail['custom_var_v' . $i]);
         }
         if (!empty($customVariablesPage)) {
             $actionDetail['customVariables'] = $customVariablesPage;
         }
         if ($actionDetail['type'] == Action::TYPE_CONTENT) {
             unset($actionDetails[$actionIdx]);
             continue;
         } elseif ($actionDetail['type'] == Action::TYPE_EVENT) {
             // Handle Event
             if (strlen($actionDetail['pageTitle']) > 0) {
                 $actionDetail['eventName'] = $actionDetail['pageTitle'];
             }
             unset($actionDetail['pageTitle']);
         } else {
             if ($actionDetail['type'] == Action::TYPE_SITE_SEARCH) {
                 // Handle Site Search
                 $actionDetail['siteSearchKeyword'] = $actionDetail['pageTitle'];
                 unset($actionDetail['pageTitle']);
             }
         }
         // Event value / Generation time
         if ($actionDetail['type'] == Action::TYPE_EVENT) {
             if (strlen($actionDetail['custom_float']) > 0) {
                 $actionDetail['eventValue'] = round($actionDetail['custom_float'], self::EVENT_VALUE_PRECISION);
             }
         } elseif ($actionDetail['custom_float'] > 0) {
             $actionDetail['generationTime'] = $formatter->getPrettyTimeFromSeconds($actionDetail['custom_float'] / 1000, true);
         }
         unset($actionDetail['custom_float']);
         if ($actionDetail['type'] != Action::TYPE_EVENT) {
             unset($actionDetail['eventCategory']);
             unset($actionDetail['eventAction']);
         }
         // Reconstruct url from prefix
         $url = Tracker\PageUrl::reconstructNormalizedUrl($actionDetail['url'], $actionDetail['url_prefix']);
         $url = Common::unsanitizeInputValue($url);
         $actionDetail['url'] = $url;
         unset($actionDetail['url_prefix']);
     }
     // If the visitor converted a goal, we shall select all Goals
     $goalDetails = $model->queryGoalConversionsForVisit($idVisit, $actionsLimit);
     $ecommerceDetails = $model->queryEcommerceConversionsForVisit($idVisit, $actionsLimit);
     foreach ($ecommerceDetails as &$ecommerceDetail) {
         if ($ecommerceDetail['type'] == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) {
             unset($ecommerceDetail['orderId']);
             unset($ecommerceDetail['revenueSubTotal']);
             unset($ecommerceDetail['revenueTax']);
             unset($ecommerceDetail['revenueShipping']);
             unset($ecommerceDetail['revenueDiscount']);
         }
         // 25.00 => 25
         foreach ($ecommerceDetail as $column => $value) {
             if (strpos($column, 'revenue') !== false) {
                 if ($value == round($value)) {
                     $ecommerceDetail[$column] = round($value);
                 }
             }
         }
     }
     // Enrich ecommerce carts/orders with the list of products
     usort($ecommerceDetails, array('static', 'sortByServerTime'));
     foreach ($ecommerceDetails as &$ecommerceConversion) {
         $idOrder = isset($ecommerceConversion['orderId']) ? $ecommerceConversion['orderId'] : GoalManager::ITEM_IDORDER_ABANDONED_CART;
         $itemsDetails = $model->queryEcommerceItemsForOrder($idVisit, $idOrder, $actionsLimit);
         foreach ($itemsDetails as &$detail) {
             if ($detail['price'] == round($detail['price'])) {
                 $detail['price'] = round($detail['price']);
             }
         }
         $ecommerceConversion['itemDetails'] = $itemsDetails;
     }
     // Enrich with time spent per action
     foreach ($actionDetails as $actionIdx => &$actionDetail) {
         // Set the time spent for this action (which is the timeSpentRef of the next action)
         $nextActionFound = isset($actionDetails[$actionIdx + 1]);
         if ($nextActionFound) {
             $actionDetail['timeSpent'] = $actionDetails[$actionIdx + 1]['timeSpentRef'];
         } else {
             // Last action of a visit.
             // By default, Piwik does not know how long the user stayed on the page
             // If enableHeartBeatTimer() is used in piwik.js then we can find the accurate time on page for the last pageview
             $timeOfLastActionOrPingInVisitRow = $visitorDetailsArray['lastActionTimestamp'];
             $timeOfLastAction = Date::factory($actionDetail['serverTimePretty'])->getTimestamp();
             $timeSpentOnPage = $timeOfLastActionOrPingInVisitRow - $timeOfLastAction;
             // Safe net, we assume the time is correct when it's more than 10 seconds
             if ($timeSpentOnPage > 10) {
                 $actionDetail['timeSpent'] = $timeSpentOnPage;
             }
         }
         if (isset($actionDetail['timeSpent'])) {
             $actionDetail['timeSpentPretty'] = $formatter->getPrettyTimeFromSeconds($actionDetail['timeSpent'], true);
         }
         unset($actionDetails[$actionIdx]['timeSpentRef']);
         // not needed after timeSpent is added
     }
     $actions = array_merge($actionDetails, $goalDetails, $ecommerceDetails);
     usort($actions, array('static', 'sortByServerTime'));
     foreach ($actions as &$action) {
         unset($action['idlink_va']);
     }
     $visitorDetailsArray['goalConversions'] = count($goalDetails);
     $visitorDetailsArray['actionDetails'] = $actions;
     foreach ($visitorDetailsArray['actionDetails'] as &$details) {
         switch ($details['type']) {
             case 'goal':
                 $details['icon'] = 'plugins/Morpheus/images/goal.png';
                 break;
             case Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER:
             case Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART:
                 $details['icon'] = 'plugins/Morpheus/images/' . $details['type'] . '.gif';
                 break;
             case Action::TYPE_DOWNLOAD:
                 $details['type'] = 'download';
                 $details['icon'] = 'plugins/Morpheus/images/download.png';
                 break;
             case Action::TYPE_OUTLINK:
                 $details['type'] = 'outlink';
                 $details['icon'] = 'plugins/Morpheus/images/link.gif';
                 break;
             case Action::TYPE_SITE_SEARCH:
                 $details['type'] = 'search';
                 $details['icon'] = 'plugins/Morpheus/images/search_ico.png';
                 break;
             case Action::TYPE_EVENT:
                 $details['type'] = 'event';
                 $details['icon'] = 'plugins/Morpheus/images/event.png';
                 break;
             default:
                 $details['type'] = 'action';
                 $details['icon'] = null;
                 break;
         }
         // Convert datetimes to the site timezone
         $dateTimeVisit = Date::factory($details['serverTimePretty'], $timezone);
         $details['serverTimePretty'] = $dateTimeVisit->getLocalized(Date::DATETIME_FORMAT_SHORT);
         $details['timestamp'] = $dateTimeVisit->getTimestamp();
     }
     return $visitorDetailsArray;
 }
Beispiel #13
0
 public function detectGoalId($idSite, Request $request)
 {
     if (!Common::isGoalPluginEnabled()) {
         return null;
     }
     $idGoal = $request->getParam('idgoal');
     $goals = $this->getGoalDefinitions($idSite);
     if (!isset($goals[$idGoal])) {
         return null;
     }
     $goal = $goals[$idGoal];
     $url = $request->getParam('url');
     $goal['url'] = PageUrl::excludeQueryParametersFromUrl($url, $idSite);
     return $goal;
 }
Beispiel #14
0
 private static function parseNameFromPageUrl($name, $type, $urlPrefix)
 {
     $urlRegexAfterDomain = '([^/]+)[/]?([^#]*)[#]?(.*)';
     if ($urlPrefix === null) {
         // match url with protocol (used for outlinks / downloads)
         $urlRegex = '@^http[s]?://' . $urlRegexAfterDomain . '$@i';
     } else {
         // the name is a url that does not contain protocol and www anymore
         // we know that normalization has been done on db level because $urlPrefix is set
         $urlRegex = '@^' . $urlRegexAfterDomain . '$@i';
     }
     $matches = array();
     preg_match($urlRegex, $name, $matches);
     if (!count($matches)) {
         return $name;
     }
     $urlHost = $matches[1];
     $urlPath = $matches[2];
     $urlFragment = $matches[3];
     if (in_array($type, array(Action::TYPE_DOWNLOAD, Action::TYPE_OUTLINK))) {
         $path = '/' . trim($urlPath);
         if (!empty($urlFragment)) {
             $path .= '#' . $urlFragment;
         }
         return array(trim($urlHost), $path);
     }
     $name = $urlPath;
     if ($name === '' || substr($name, -1) == '/') {
         $name .= self::$defaultActionName;
     }
     $urlFragment = PageUrl::processUrlFragment($urlFragment);
     if (!empty($urlFragment)) {
         $name .= '#' . $urlFragment;
     }
     return $name;
 }
 protected function aggregateFromActions($valueField)
 {
     $resultSet = $this->queryCustomDimensionActions($this->dataArray, $valueField);
     while ($row = $resultSet->fetch()) {
         $label = $row[$valueField];
         $label = $this->cleanCustomDimensionValue($label);
         $this->dataArray->sumMetricsActions($label, $row);
         // make sure we always work with normalized URL no matter how the individual action stores it
         $normalized = Tracker\PageUrl::normalizeUrl($row['url']);
         $row['url'] = $normalized['url'];
         $subLabel = $row['url'];
         if (empty($subLabel)) {
             continue;
         }
         $this->dataArray->sumMetricsActionCustomDimensionsPivot($label, $subLabel, $row);
     }
 }
Beispiel #16
0
 protected function getUrlAndType()
 {
     $url = $this->getActionUrl();
     if (!empty($url)) {
         // normalize urls by stripping protocol and www
         $url = PageUrl::normalizeUrl($url);
         return array($url['url'], self::TYPE_PAGE_URL, $url['prefixId']);
     }
     return false;
 }
Beispiel #17
0
 /**
  * @param $visitorDetailsArray
  * @param $actionsLimit
  * @param $timezone
  * @return array
  */
 public static function enrichVisitorArrayWithActions($visitorDetailsArray, $actionsLimit, $timezone)
 {
     $idVisit = $visitorDetailsArray['idVisit'];
     $maxCustomVariables = CustomVariables::getMaxCustomVariables();
     $sqlCustomVariables = '';
     for ($i = 1; $i <= $maxCustomVariables; $i++) {
         $sqlCustomVariables .= ', custom_var_k' . $i . ', custom_var_v' . $i;
     }
     // The second join is a LEFT join to allow returning records that don't have a matching page title
     // eg. Downloads, Outlinks. For these, idaction_name is set to 0
     $sql = "\n\t\t\t\tSELECT\n\t\t\t\t\tCOALESCE(log_action_event_category.type, log_action.type, log_action_title.type) AS type,\n\t\t\t\t\tlog_action.name AS url,\n\t\t\t\t\tlog_action.url_prefix,\n\t\t\t\t\tlog_action_title.name AS pageTitle,\n\t\t\t\t\tlog_action.idaction AS pageIdAction,\n\t\t\t\t\tlog_link_visit_action.server_time as serverTimePretty,\n\t\t\t\t\tlog_link_visit_action.time_spent_ref_action as timeSpentRef,\n\t\t\t\t\tlog_link_visit_action.idlink_va AS pageId,\n\t\t\t\t\tlog_link_visit_action.custom_float\n\t\t\t\t\t" . $sqlCustomVariables . ",\n\t\t\t\t\tlog_action_event_category.name AS eventCategory,\n\t\t\t\t\tlog_action_event_action.name as eventAction\n\t\t\t\tFROM " . Common::prefixTable('log_link_visit_action') . " AS log_link_visit_action\n\t\t\t\t\tLEFT JOIN " . Common::prefixTable('log_action') . " AS log_action\n\t\t\t\t\tON  log_link_visit_action.idaction_url = log_action.idaction\n\t\t\t\t\tLEFT JOIN " . Common::prefixTable('log_action') . " AS log_action_title\n\t\t\t\t\tON  log_link_visit_action.idaction_name = log_action_title.idaction\n\t\t\t\t\tLEFT JOIN " . Common::prefixTable('log_action') . " AS log_action_event_category\n\t\t\t\t\tON  log_link_visit_action.idaction_event_category = log_action_event_category.idaction\n\t\t\t\t\tLEFT JOIN " . Common::prefixTable('log_action') . " AS log_action_event_action\n\t\t\t\t\tON  log_link_visit_action.idaction_event_action = log_action_event_action.idaction\n\t\t\t\tWHERE log_link_visit_action.idvisit = ?\n\t\t\t\tORDER BY server_time ASC\n\t\t\t\tLIMIT 0, {$actionsLimit}\n\t\t\t\t ";
     $actionDetails = Db::fetchAll($sql, array($idVisit));
     foreach ($actionDetails as $actionIdx => &$actionDetail) {
         $actionDetail =& $actionDetails[$actionIdx];
         $customVariablesPage = array();
         for ($i = 1; $i <= $maxCustomVariables; $i++) {
             if (!empty($actionDetail['custom_var_k' . $i])) {
                 $cvarKey = $actionDetail['custom_var_k' . $i];
                 $cvarKey = static::getCustomVariablePrettyKey($cvarKey);
                 $customVariablesPage[$i] = array('customVariablePageName' . $i => $cvarKey, 'customVariablePageValue' . $i => $actionDetail['custom_var_v' . $i]);
             }
             unset($actionDetail['custom_var_k' . $i]);
             unset($actionDetail['custom_var_v' . $i]);
         }
         if (!empty($customVariablesPage)) {
             $actionDetail['customVariables'] = $customVariablesPage;
         }
         if ($actionDetail['type'] == Action::TYPE_CONTENT) {
             unset($actionDetails[$actionIdx]);
             continue;
         } elseif ($actionDetail['type'] == Action::TYPE_EVENT_CATEGORY) {
             // Handle Event
             if (strlen($actionDetail['pageTitle']) > 0) {
                 $actionDetail['eventName'] = $actionDetail['pageTitle'];
             }
             unset($actionDetail['pageTitle']);
         } else {
             if ($actionDetail['type'] == Action::TYPE_SITE_SEARCH) {
                 // Handle Site Search
                 $actionDetail['siteSearchKeyword'] = $actionDetail['pageTitle'];
                 unset($actionDetail['pageTitle']);
             }
         }
         // Event value / Generation time
         if ($actionDetail['type'] == Action::TYPE_EVENT_CATEGORY) {
             if (strlen($actionDetail['custom_float']) > 0) {
                 $actionDetail['eventValue'] = round($actionDetail['custom_float'], self::EVENT_VALUE_PRECISION);
             }
         } elseif ($actionDetail['custom_float'] > 0) {
             $actionDetail['generationTime'] = \Piwik\MetricsFormatter::getPrettyTimeFromSeconds($actionDetail['custom_float'] / 1000);
         }
         unset($actionDetail['custom_float']);
         if ($actionDetail['type'] != Action::TYPE_EVENT_CATEGORY) {
             unset($actionDetail['eventCategory']);
             unset($actionDetail['eventAction']);
         }
         // Reconstruct url from prefix
         $actionDetail['url'] = Tracker\PageUrl::reconstructNormalizedUrl($actionDetail['url'], $actionDetail['url_prefix']);
         unset($actionDetail['url_prefix']);
         // Set the time spent for this action (which is the timeSpentRef of the next action)
         if (isset($actionDetails[$actionIdx + 1])) {
             $actionDetail['timeSpent'] = $actionDetails[$actionIdx + 1]['timeSpentRef'];
             $actionDetail['timeSpentPretty'] = \Piwik\MetricsFormatter::getPrettyTimeFromSeconds($actionDetail['timeSpent']);
         }
         unset($actionDetails[$actionIdx]['timeSpentRef']);
         // not needed after timeSpent is added
     }
     // If the visitor converted a goal, we shall select all Goals
     $sql = "\n\t\t\t\tSELECT\n\t\t\t\t\t\t'goal' as type,\n\t\t\t\t\t\tgoal.name as goalName,\n\t\t\t\t\t\tgoal.idgoal as goalId,\n\t\t\t\t\t\tgoal.revenue as revenue,\n\t\t\t\t\t\tlog_conversion.idlink_va as goalPageId,\n\t\t\t\t\t\tlog_conversion.server_time as serverTimePretty,\n\t\t\t\t\t\tlog_conversion.url as url\n\t\t\t\tFROM " . Common::prefixTable('log_conversion') . " AS log_conversion\n\t\t\t\tLEFT JOIN " . Common::prefixTable('goal') . " AS goal\n\t\t\t\t\tON (goal.idsite = log_conversion.idsite\n\t\t\t\t\t\tAND\n\t\t\t\t\t\tgoal.idgoal = log_conversion.idgoal)\n\t\t\t\t\tAND goal.deleted = 0\n\t\t\t\tWHERE log_conversion.idvisit = ?\n\t\t\t\t\tAND log_conversion.idgoal > 0\n                ORDER BY server_time ASC\n\t\t\t\tLIMIT 0, {$actionsLimit}\n\t\t\t";
     $goalDetails = Db::fetchAll($sql, array($idVisit));
     $sql = "SELECT\n\t\t\t\t\t\tcase idgoal when " . GoalManager::IDGOAL_CART . " then '" . Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART . "' else '" . Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER . "' end as type,\n\t\t\t\t\t\tidorder as orderId,\n\t\t\t\t\t\t" . LogAggregator::getSqlRevenue('revenue') . " as revenue,\n\t\t\t\t\t\t" . LogAggregator::getSqlRevenue('revenue_subtotal') . " as revenueSubTotal,\n\t\t\t\t\t\t" . LogAggregator::getSqlRevenue('revenue_tax') . " as revenueTax,\n\t\t\t\t\t\t" . LogAggregator::getSqlRevenue('revenue_shipping') . " as revenueShipping,\n\t\t\t\t\t\t" . LogAggregator::getSqlRevenue('revenue_discount') . " as revenueDiscount,\n\t\t\t\t\t\titems as items,\n\n\t\t\t\t\t\tlog_conversion.server_time as serverTimePretty\n\t\t\t\t\tFROM " . Common::prefixTable('log_conversion') . " AS log_conversion\n\t\t\t\t\tWHERE idvisit = ?\n\t\t\t\t\t\tAND idgoal <= " . GoalManager::IDGOAL_ORDER . "\n\t\t\t\t\tORDER BY server_time ASC\n\t\t\t\t\tLIMIT 0, {$actionsLimit}";
     $ecommerceDetails = Db::fetchAll($sql, array($idVisit));
     foreach ($ecommerceDetails as &$ecommerceDetail) {
         if ($ecommerceDetail['type'] == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) {
             unset($ecommerceDetail['orderId']);
             unset($ecommerceDetail['revenueSubTotal']);
             unset($ecommerceDetail['revenueTax']);
             unset($ecommerceDetail['revenueShipping']);
             unset($ecommerceDetail['revenueDiscount']);
         }
         // 25.00 => 25
         foreach ($ecommerceDetail as $column => $value) {
             if (strpos($column, 'revenue') !== false) {
                 if ($value == round($value)) {
                     $ecommerceDetail[$column] = round($value);
                 }
             }
         }
     }
     // Enrich ecommerce carts/orders with the list of products
     usort($ecommerceDetails, array('static', 'sortByServerTime'));
     foreach ($ecommerceDetails as &$ecommerceConversion) {
         $sql = "SELECT\n\t\t\t\t\t\t\tlog_action_sku.name as itemSKU,\n\t\t\t\t\t\t\tlog_action_name.name as itemName,\n\t\t\t\t\t\t\tlog_action_category.name as itemCategory,\n\t\t\t\t\t\t\t" . LogAggregator::getSqlRevenue('price') . " as price,\n\t\t\t\t\t\t\tquantity as quantity\n\t\t\t\t\t\tFROM " . Common::prefixTable('log_conversion_item') . "\n\t\t\t\t\t\t\tINNER JOIN " . Common::prefixTable('log_action') . " AS log_action_sku\n\t\t\t\t\t\t\tON  idaction_sku = log_action_sku.idaction\n\t\t\t\t\t\t\tLEFT JOIN " . Common::prefixTable('log_action') . " AS log_action_name\n\t\t\t\t\t\t\tON  idaction_name = log_action_name.idaction\n\t\t\t\t\t\t\tLEFT JOIN " . Common::prefixTable('log_action') . " AS log_action_category\n\t\t\t\t\t\t\tON idaction_category = log_action_category.idaction\n\t\t\t\t\t\tWHERE idvisit = ?\n\t\t\t\t\t\t\tAND idorder = ?\n\t\t\t\t\t\t\tAND deleted = 0\n\t\t\t\t\t\tLIMIT 0, {$actionsLimit}\n\t\t\t\t";
         $bind = array($idVisit, isset($ecommerceConversion['orderId']) ? $ecommerceConversion['orderId'] : GoalManager::ITEM_IDORDER_ABANDONED_CART);
         $itemsDetails = Db::fetchAll($sql, $bind);
         foreach ($itemsDetails as &$detail) {
             if ($detail['price'] == round($detail['price'])) {
                 $detail['price'] = round($detail['price']);
             }
         }
         $ecommerceConversion['itemDetails'] = $itemsDetails;
     }
     $actions = array_merge($actionDetails, $goalDetails, $ecommerceDetails);
     usort($actions, array('static', 'sortByServerTime'));
     $visitorDetailsArray['actionDetails'] = $actions;
     foreach ($visitorDetailsArray['actionDetails'] as &$details) {
         switch ($details['type']) {
             case 'goal':
                 $details['icon'] = 'plugins/Morpheus/images/goal.png';
                 break;
             case Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER:
             case Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART:
                 $details['icon'] = 'plugins/Morpheus/images/' . $details['type'] . '.gif';
                 break;
             case Action::TYPE_DOWNLOAD:
                 $details['type'] = 'download';
                 $details['icon'] = 'plugins/Morpheus/images/download.png';
                 break;
             case Action::TYPE_OUTLINK:
                 $details['type'] = 'outlink';
                 $details['icon'] = 'plugins/Morpheus/images/link.gif';
                 break;
             case Action::TYPE_SITE_SEARCH:
                 $details['type'] = 'search';
                 $details['icon'] = 'plugins/Morpheus/images/search_ico.png';
                 break;
             case Action::TYPE_EVENT_CATEGORY:
                 $details['type'] = 'event';
                 $details['icon'] = 'plugins/Morpheus/images/event.png';
                 break;
             default:
                 $details['type'] = 'action';
                 $details['icon'] = null;
                 break;
         }
         // Convert datetimes to the site timezone
         $dateTimeVisit = Date::factory($details['serverTimePretty'], $timezone);
         $details['serverTimePretty'] = $dateTimeVisit->getLocalized(Piwik::translate('CoreHome_ShortDateFormat') . ' %time%');
     }
     $visitorDetailsArray['goalConversions'] = count($goalDetails);
     return $visitorDetailsArray;
 }
Beispiel #18
0
 /**
  * Testing with some website specific and some global excluded query parameters
  * @group Core
  * @dataProvider getTestUrls
  */
 public function testExcludeQueryParametersSiteAndGlobalExcluded($url, $filteredUrl)
 {
     // testing also that query parameters are case insensitive
     $excludedQueryParameters = 'P2,var[value][date]';
     $excludedGlobalParameters = 'blabla, P4';
     $this->setUpRootAccess();
     $idSite = API::getInstance()->addSite("site1", array('http://example.org'), $ecommerce = 0, $siteSearch = 1, $searchKeywordParameters = null, $searchCategoryParameters = null, $excludedIps = '', $excludedQueryParameters, $timezone = null, $currency = null, $group = null, $startDate = null, $excludedUserAgents = null, $keepURLFragments = 1);
     API::getInstance()->setGlobalExcludedQueryParameters($excludedGlobalParameters);
     $this->assertEquals($filteredUrl[1], PageUrl::excludeQueryParametersFromUrl($url, $idSite));
 }