/** * @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; }
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']; }
/** * Ideally this should use the DataArray object instead of custom data structure * * @param Zend_Db_Statement|PDOStatement $query * @param string|bool $fieldQueried * @param array $actionsTablesByType * @return int */ public static function updateActionsTableWithRowQuery($query, $fieldQueried, &$actionsTablesByType, $metricsConfig) { $rowsProcessed = 0; while ($row = $query->fetch()) { if (empty($row['idaction'])) { $row['type'] = $fieldQueried == 'idaction_url' ? Action::TYPE_PAGE_URL : Action::TYPE_PAGE_TITLE; // This will be replaced with 'X not defined' later $row['name'] = ''; // Yes, this is kind of a hack, so we don't mix 'page url not defined' with 'page title not defined' etc. $row['idaction'] = -$row['type']; } if ($row['type'] != Action::TYPE_SITE_SEARCH) { unset($row[PiwikMetrics::INDEX_SITE_SEARCH_HAS_NO_RESULT]); } if (in_array($row['type'], array(Action::TYPE_CONTENT, Action::TYPE_EVENT))) { continue; } // This will appear as <url /> in the API, which is actually very important to keep // eg. When there's at least one row in a report that does not have a URL, not having this <url/> would break HTML/PDF reports. $url = ''; if ($row['type'] == Action::TYPE_SITE_SEARCH || $row['type'] == Action::TYPE_PAGE_TITLE) { $url = null; } elseif (!empty($row['name']) && $row['name'] != DataTable::LABEL_SUMMARY_ROW) { $url = PageUrl::reconstructNormalizedUrl((string) $row['name'], $row['url_prefix']); } if (isset($row['name']) && isset($row['type'])) { $actionName = $row['name']; $actionType = $row['type']; $urlPrefix = $row['url_prefix']; $idaction = $row['idaction']; // in some unknown case, the type field is NULL, as reported in #1082 - we ignore this page view if (empty($actionType)) { if ($idaction != DataTable::LABEL_SUMMARY_ROW) { self::setCachedActionRow($idaction, $actionType, false); } continue; } $actionRow = self::getActionRow($actionName, $actionType, $urlPrefix, $actionsTablesByType); self::setCachedActionRow($idaction, $actionType, $actionRow); } else { $actionRow = self::getCachedActionRow($row['idaction'], $row['type']); // Action processed as "to skip" for some reasons if ($actionRow === false) { continue; } } if (is_null($actionRow)) { continue; } // Here we do ensure that, the Metadata URL set for a given row, is the one from the Pageview with the most hits. // This is to ensure that when, different URLs are loaded with the same page name. // For example http://piwik.org and http://id.piwik.org are reported in Piwik > Actions > Pages with /index // But, we must make sure http://piwik.org is used to link & for transitions // Note: this code is partly duplicated from Row->sumRowMetadata() if (!is_null($url) && !$actionRow->isSummaryRow()) { if (($existingUrl = $actionRow->getMetadata('url')) !== false) { if (!empty($row[PiwikMetrics::INDEX_PAGE_NB_HITS]) && $row[PiwikMetrics::INDEX_PAGE_NB_HITS] > $actionRow->maxVisitsSummed) { $actionRow->setMetadata('url', $url); $actionRow->maxVisitsSummed = $row[PiwikMetrics::INDEX_PAGE_NB_HITS]; } } else { $actionRow->setMetadata('url', $url); $actionRow->maxVisitsSummed = !empty($row[PiwikMetrics::INDEX_PAGE_NB_HITS]) ? $row[PiwikMetrics::INDEX_PAGE_NB_HITS] : 0; } } if ($row['type'] != Action::TYPE_PAGE_URL && $row['type'] != Action::TYPE_PAGE_TITLE) { // only keep performance metrics when they're used (i.e. for URLs and page titles) if (array_key_exists(PiwikMetrics::INDEX_PAGE_SUM_TIME_GENERATION, $row)) { unset($row[PiwikMetrics::INDEX_PAGE_SUM_TIME_GENERATION]); } if (array_key_exists(PiwikMetrics::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION, $row)) { unset($row[PiwikMetrics::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION]); } if (array_key_exists(PiwikMetrics::INDEX_PAGE_MIN_TIME_GENERATION, $row)) { unset($row[PiwikMetrics::INDEX_PAGE_MIN_TIME_GENERATION]); } if (array_key_exists(PiwikMetrics::INDEX_PAGE_MAX_TIME_GENERATION, $row)) { unset($row[PiwikMetrics::INDEX_PAGE_MAX_TIME_GENERATION]); } } unset($row['name']); unset($row['type']); unset($row['idaction']); unset($row['url_prefix']); foreach ($row as $name => $value) { // in some edge cases, we have twice the same action name with 2 different idaction // - this happens when 2 visitors visit the same new page at the same time, and 2 actions get recorded for the same name // - this could also happen when 2 URLs end up having the same label (eg. 2 subdomains get aggregated to the "/index" page name) if (($alreadyValue = $actionRow->getColumn($name)) !== false) { $newValue = self::getColumnValuesMerged($name, $alreadyValue, $value, $metricsConfig); $actionRow->setColumn($name, $newValue); } else { $actionRow->addColumn($name, $value); } } // if the exit_action was not recorded properly in the log_link_visit_action // there would be an error message when getting the nb_hits column // we must fake the record and add the columns if ($actionRow->getColumn(PiwikMetrics::INDEX_PAGE_NB_HITS) === false) { // to test this code: delete the entries in log_link_action_visit for // a given exit_idaction_url foreach (self::getDefaultRow()->getColumns() as $name => $value) { $actionRow->addColumn($name, $value); } } $rowsProcessed++; } // just to make sure php copies the last $actionRow in the $parentTable array $actionRow =& $actionsTablesByType; return $rowsProcessed; }
/** * @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; }
/** * Test removing hash tag * @group Core * @dataProvider getTestUrlsHashtag */ public function testRemoveTrailingHashtag($url, $expectedUrl) { $this->assertEquals(PageUrl::reconstructNormalizedUrl($url, PageUrl::$urlPrefixMap['http://']), $expectedUrl); }