Ticket #708: 708.patch
| File 708.patch, 49.3 KB (added by mauser, 2 years ago) |
|---|
-
lang/en.php
200 200 'CoreUpdater_ExceptionArchiveIncomplete' => 'Archive is incomplete: some files are missing (eg. %s).', 201 201 'Actions_Actions' => 'Actions', 202 202 'Actions_SubmenuPages' => 'Pages', 203 'Actions_SubmenuPageTitles' => 'Page titles', 203 204 'Actions_SubmenuOutlinks' => 'Outlinks', 204 205 'Actions_SubmenuDownloads' => 'Downloads', 205 206 'Actions_ColumnClicks' => 'Clicks', … … 207 208 'Actions_ColumnDownloads' => 'Downloads', 208 209 'Actions_ColumnUniqueDownloads' => 'Unique Downloads', 209 210 'Actions_ColumnPageName' => 'Page Name', 211 'Actions_ColumnPageURL' => 'Page URL', 210 212 'Actions_ColumnClickedURL' => 'Clicked URL', 211 213 'Actions_ColumnDownloadURL' => 'Download URL', 212 214 'Dashboard_Dashboard' => 'Dashboard', -
plugins/Actions/API.php
50 50 $dataTable->queueFilter('ReplaceSummaryRowLabel'); 51 51 return $dataTable; 52 52 } 53 53 54 /* 55 * Backward compatibility. Use getPageUrls() method instead. 56 */ 54 57 public function getActions( $idSite, $period, $date, $expanded = false, $idSubtable = false ) 55 58 { 59 return $this->getPageUrls( $idSite, $period, $date, $expanded, $idSubtable ); 60 } 61 62 public function getPageUrls( $idSite, $period, $date, $expanded = false, $idSubtable = false ) 63 { 56 64 return $this->getDataTable('Actions_actions', $idSite, $period, $date, $expanded, $idSubtable ); 57 65 } 58 66 67 public function getPageTitles( $idSite, $period, $date, $expanded = false, $idSubtable = false) 68 { 69 $dataTable = $this->getDataTable('Actions_actions_name', $idSite, $period, $date, $expanded, $idSubtable); 70 return $dataTable; 71 } 72 59 73 public function getDownloads( $idSite, $period, $date, $expanded = false, $idSubtable = false ) 60 74 { 61 75 $dataTable = $this->getDataTable('Actions_downloads', $idSite, $period, $date, $expanded, $idSubtable ); -
plugins/Actions/tests/Actions.test.php
1 <?php 2 if(!defined("PIWIK_PATH_TEST_TO_ROOT")) { 3 define('PIWIK_PATH_TEST_TO_ROOT', getcwd().'/../../..'); 4 } 5 if(!defined('PIWIK_CONFIG_TEST_INCLUDED')) 6 { 7 require_once PIWIK_PATH_TEST_TO_ROOT . "/tests/config_test.php"; 8 } 9 10 require_once 'Actions/Actions.php'; 11 require_once 'Tracker/Action.php'; 12 require_once 'Tracker/Config.php'; 13 14 class Test_Piwik_Actions extends UnitTestCase 15 { 16 function test_extractUrlAndActionNameFromRequest() 17 { 18 $userFile = PIWIK_INCLUDE_PATH . '/tests/resources/plugins/Actions/Actions.config.ini.php'; 19 20 Piwik::createConfigObject($userFile); 21 22 $action = new Test_Piwik_Actions_extractUrlAndActionNameFromRequest(); 23 24 $tests = array( 25 array( 26 'params' => array( 'name' => 'http://example.org/', 'type' => Piwik_Tracker_Action::TYPE_ACTION), 27 'expected' => array('index' ), 28 ), 29 array( 30 'params' => array( 'name' => 'http://example.org/path/', 'type' => Piwik_Tracker_Action::TYPE_ACTION), 31 'expected' => array( 'path', 'index' ), 32 ), 33 array( 34 'params' => array( 'name' => 'http://example.org/test/path', 'type' => Piwik_Tracker_Action::TYPE_ACTION), 35 'expected' => array( 'test', 'path' ), 36 ), 37 array( 38 'params' => array( 'name' => 'Test / Path', 'type' => Piwik_Tracker_Action::TYPE_ACTION), 39 'expected' => array( 'Test', 'Path' ), 40 ), 41 array( 42 'params' => array( 'name' => ' Test trim ', 'type' => Piwik_Tracker_Action::TYPE_ACTION), 43 'expected' => array( 'Test trim' ), 44 ), 45 array( 46 'params' => array( 'name' => 'Category / Subcategory', 'type' => Piwik_Tracker_Action::TYPE_ACTION_NAME), 47 'expected' => array( 'Category', 'Subcategory' ), 48 ), 49 array( 50 'params' => array( 'name' => '/path/index.php?var=test', 'type' => Piwik_Tracker_Action::TYPE_ACTION_NAME), 51 'expected' => array( 'path', 'index.php?var=test' ), 52 ), 53 array( 54 'params' => array( 'name' => 'http://example.org/path/Default.aspx#anchor', 'type' => Piwik_Tracker_Action::TYPE_ACTION_NAME), 55 'expected' => array( 'path', 'Default.aspx' ), 56 ), 57 array( 58 'params' => array( 'name' => '', 'type' => Piwik_Tracker_Action::TYPE_ACTION_NAME), 59 'expected' => array( 'index' ), 60 ), 61 array( 62 'params' => array( 'name' => 'http://example.org/download.zip', 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD), 63 'expected' => array( 'example.org', '/download.zip' ), 64 ), 65 array( 66 'params' => array( 'name' => 'http://example.org/download/1/', 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD), 67 'expected' => array( 'example.org', '/download/1/' ), 68 ), 69 array( 70 'params' => array( 'name' => 'http://example.org/link', 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), 71 'expected' => array( 'example.org', '/link' ), 72 ), 73 array( 74 'params' => array( 'name' => 'http://example.org/some/path/', 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), 75 'expected' => array( 'example.org', '/some/path/' ), 76 ), 77 78 ); 79 foreach($tests as $test) { 80 $params = $test['params']; 81 $expected = $test['expected']; 82 $this->assertEqual($action->public_getActionExplodedNames($params['name'],$params['type']), $expected); 83 } 84 } 85 } 86 87 class Test_Piwik_Actions_extractUrlAndActionNameFromRequest extends Piwik_Actions { 88 public function public_getActionExplodedNames($name, $type) 89 { 90 return self::getActionExplodedNames($name, $type); 91 } 92 } 93 No newline at end of file -
plugins/Actions/Actions.php
20 20 class Piwik_Actions extends Piwik_Plugin 21 21 { 22 22 static protected $actionCategoryDelimiter = null; 23 static protected $defaultActionName = null; 23 24 static protected $limitLevelSubCategory = 10; // must be less than Piwik_DataTable::MAXIMUM_DEPTH_LEVEL_ALLOWED 24 25 protected $maximumRowsInDataTableLevelZero; 25 26 protected $maximumRowsInSubDataTable; … … 50 51 public function __construct() 51 52 { 52 53 self::$actionCategoryDelimiter = Zend_Registry::get('config')->General->action_category_delimiter; 54 self::$defaultActionName = Zend_Registry::get('config')->Tracker->default_action_name; 53 55 $this->columnToSortByBeforeTruncation = 'nb_visits'; 54 56 $this->maximumRowsInDataTableLevelZero = Zend_Registry::get('config')->General->datatable_archiving_maximum_rows_actions; 55 57 $this->maximumRowsInSubDataTable = Zend_Registry::get('config')->General->datatable_archiving_maximum_rows_subtable_actions; … … 57 59 58 60 function addWidgets() 59 61 { 60 Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuPages', 'Actions', 'getActions'); 62 Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuPages', 'Actions', 'getPageUrls'); 63 Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuPageTitles', 'Actions', 'getPageTitles'); 61 64 Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuOutlinks', 'Actions', 'getOutlinks'); 62 65 Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuDownloads', 'Actions', 'getDownloads'); 63 66 } 64 67 65 68 function addMenus() 66 69 { 67 Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPages', array('module' => 'Actions', 'action' => 'getActions')); 70 Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPages', array('module' => 'Actions', 'action' => 'getPageUrls')); 71 Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPageTitles', array('module' => 'Actions', 'action' => 'getPageTitles')); 68 72 Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuOutlinks', array('module' => 'Actions', 'action' => 'getOutlinks')); 69 Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuDownloads', array('module' => 'Actions', 'action' => 'getDownloads')); 73 Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuDownloads', array('module' => 'Actions', 'action' => 'getDownloads')); 70 74 } 71 75 72 76 static protected $invalidSummedColumnNameToRenamedNameForPeriodArchive = array( … … 88 92 'Actions_actions', 89 93 'Actions_downloads', 90 94 'Actions_outlink', 95 'Actions_actions_name', 91 96 ); 92 97 $archiveProcessing->archiveDataTable($dataTableToSum, self::$invalidSummedColumnNameToRenamedNameForPeriodArchive, $this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable, $this->columnToSortByBeforeTruncation); 93 98 } … … 109 114 Piwik_Tracker_Action::TYPE_ACTION => array(), 110 115 Piwik_Tracker_Action::TYPE_DOWNLOAD => array(), 111 116 Piwik_Tracker_Action::TYPE_OUTLINK => array(), 117 Piwik_Tracker_Action::TYPE_ACTION_NAME => array(), 112 118 ); 113 119 114 120 // This row is used in the case where an action is know as an exit_action … … 122 128 ))); 123 129 124 130 /* 125 * Actions global information131 * Actions urls global information 126 132 */ 127 133 $query = "SELECT name, 128 134 type, … … 131 137 count(*) as nb_hits 132 138 FROM (".$archiveProcessing->logTable." as t1 133 139 LEFT JOIN ".$archiveProcessing->logVisitActionTable." as t2 USING (idvisit)) 134 LEFT JOIN ".$archiveProcessing->logActionTable." as t3 USING (idaction)140 LEFT JOIN ".$archiveProcessing->logActionTable." as t3 ON (t2.idaction_url = t3.idaction) 135 141 WHERE visit_server_date = ? 136 142 AND idsite = ? 137 143 GROUP BY t3.idaction … … 139 145 $query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite )); 140 146 $modified = $this->updateActionsTableWithRowQuery($query); 141 147 142 143 148 /* 149 * Actions names global information 150 */ 151 $query = "SELECT name, 152 type, 153 count(distinct t1.idvisit) as nb_visits, 154 count(distinct visitor_idcookie) as nb_uniq_visitors, 155 count(*) as nb_hits 156 FROM (".$archiveProcessing->logTable." as t1 157 LEFT JOIN ".$archiveProcessing->logVisitActionTable." as t2 USING (idvisit)) 158 LEFT JOIN ".$archiveProcessing->logActionTable." as t3 ON (t2.idaction_name = t3.idaction) 159 WHERE visit_server_date = ? 160 AND idsite = ? 161 GROUP BY t3.idaction 162 ORDER BY nb_hits DESC"; 163 $query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite )); 164 $modified = $this->updateActionsTableWithRowQuery($query); 165 166 /* 144 167 * Entry actions 145 168 */ 146 169 $query = "SELECT name, … … 151 174 sum(visit_total_time) as entry_sum_visit_length, 152 175 sum(case visit_total_actions when 1 then 1 else 0 end) as entry_bounce_count 153 176 FROM ".$archiveProcessing->logTable." 154 JOIN ".$archiveProcessing->logActionTable." ON (visit_entry_idaction = idaction)177 JOIN ".$archiveProcessing->logActionTable." ON (visit_entry_idaction_url = idaction) 155 178 WHERE visit_server_date = ? 156 179 AND idsite = ? 157 GROUP BY visit_entry_idaction 180 GROUP BY visit_entry_idaction_url 158 181 "; 159 182 $query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite )); 160 183 $modified = $this->updateActionsTableWithRowQuery($query); … … 169 192 count(*) as exit_nb_visits, 170 193 sum(case visit_total_actions when 1 then 1 else 0 end) as exit_bounce_count 171 194 FROM ".$archiveProcessing->logTable." 172 JOIN ".$archiveProcessing->logActionTable." ON (visit_exit_idaction = idaction)195 JOIN ".$archiveProcessing->logActionTable." ON (visit_exit_idaction_url = idaction) 173 196 WHERE visit_server_date = ? 174 197 AND idsite = ? 175 GROUP BY visit_exit_idaction 198 GROUP BY visit_exit_idaction_url 176 199 "; 177 200 $query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite )); 178 201 $modified = $this->updateActionsTableWithRowQuery($query); … … 185 208 sum(time_spent_ref_action) as sum_time_spent 186 209 FROM (".$archiveProcessing->logTable." log_visit 187 210 JOIN ".$archiveProcessing->logVisitActionTable." log_link_visit_action USING (idvisit)) 188 JOIN ".$archiveProcessing->logActionTable." log_action ON (log_action.idaction = log_link_visit_action.idaction_ ref)211 JOIN ".$archiveProcessing->logActionTable." log_action ON (log_action.idaction = log_link_visit_action.idaction_url_ref) 189 212 WHERE visit_server_date = ? 190 213 AND idsite = ? 191 GROUP BY idaction_ ref214 GROUP BY idaction_url_ref 192 215 "; 193 216 $query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite )); 194 217 $modified = $this->updateActionsTableWithRowQuery($query); … … 215 238 $archiveProcessing->insertBlobRecord('Actions_outlink', $s); 216 239 destroy($dataTable); 217 240 241 $dataTable = Piwik_ArchiveProcessing_Day::generateDataTable($this->actionsTablesByType[Piwik_Tracker_Action::TYPE_ACTION_NAME]); 242 $this->deleteInvalidSummedColumnsFromDataTable($dataTable); 243 $s = $dataTable->getSerialized( $this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable, $this->columnToSortByBeforeTruncation ); 244 $archiveProcessing->insertBlobRecord('Actions_actions_name', $s); 245 destroy($dataTable); 246 218 247 unset($this->actionsTablesByType); 219 248 } 220 249 … … 232 261 } 233 262 } 234 263 } 264 265 /** 266 * Explodes action name into an array of elements. 267 * 268 * for downloads: 269 * we explode link http://piwik.org/some/path/piwik.zip into an array( 'piwik.org', '/some/path/piwik.zip' ); 270 * 271 * for outlinks: 272 * we explode link http://dev.piwik.org/some/path into an array( 'dev.piwik.org', '/some/path' ); 273 * 274 * for action urls: 275 * we explode link http://piwik.org/some/path into an array( 'some', 'path' ); 276 * 277 * for action names: 278 * we explode name 'Piwik / Category 1 / Category 2' into an array('Piwik', 'Category 1', 'Category 2'); 279 * 280 * @param string action name 281 * @param int action type 282 * @return array of exploded elements from $name 283 */ 235 284 static public function getActionExplodedNames($name, $type) 236 285 { 286 $matches = array(); 287 $isUrl = false; 288 289 preg_match('@^http[s]?://([^/]+)[/]?([^#]*)[#]?(.*)$@i', $name, $matches); 290 291 if( count($matches) ) 292 { 293 $isUrl = true; 294 $urlHost = $matches[1]; 295 $urlPath = $matches[2]; 296 $urlAnchor = $matches[3]; 297 } 298 237 299 if($type == Piwik_Tracker_Action::TYPE_DOWNLOAD 238 300 || $type == Piwik_Tracker_Action::TYPE_OUTLINK) 239 301 { 240 $matches = $split_arr = array(); 241 //TODO optimize with substring count rather than preg_match 242 if(preg_match("#://[^/]+(/)#", $name, $matches, PREG_OFFSET_CAPTURE)) 302 if( $isUrl ) 243 303 { 244 $host = substr($name, 0, $matches[1][1]); 245 return array($host, substr($name, strlen($host))); 304 return array($urlHost, '/' . $urlPath); 246 305 } 247 return array($name, "/");248 306 } 307 308 if( $isUrl ) 309 { 310 $name = $urlPath; 311 312 if( empty($name) || substr($name, -1) == '/' ) 313 { 314 $name .= self::$defaultActionName; 315 } 316 } 317 249 318 if(empty(self::$actionCategoryDelimiter)) 250 319 { 251 return array( $name);320 return array( trim($name) ); 252 321 } 253 return explode( self::$actionCategoryDelimiter, 254 $name, 255 self::$limitLevelSubCategory); 322 323 $split = explode(self::$actionCategoryDelimiter, $name, self::$limitLevelSubCategory); 324 325 // trim every category and remove empty categories 326 $split = array_map('trim', $split); 327 $split = array_filter($split); 328 329 if( empty($split) ) 330 { 331 return array( self::$defaultActionName ); 332 } 333 334 return array_values( $split ); 256 335 } 257 336 258 259 337 protected function updateActionsTableWithRowQuery($query) 260 338 { 261 339 $rowsProcessed = 0; … … 265 343 266 344 // we work on the root table of the given TYPE (either ACTION or DOWNLOAD or OUTLINK etc.) 267 345 $currentTable =& $this->actionsTablesByType[$row['type']]; 268 346 269 347 // go to the level of the subcategory 270 348 $end = count($actionExplodedNames)-1; 271 349 for($level = 0 ; $level < $end; $level++) … … 274 352 $currentTable =& $currentTable[$actionCategory]; 275 353 } 276 354 $actionName = $actionExplodedNames[$end]; 277 278 // we are careful to prefix the page Name with some value355 356 // we are careful to prefix the page URL / name with some value 279 357 // so that if a page has the same name as a category 280 358 // we don't merge both entries 281 if($row['type'] == Piwik_Tracker_Action::TYPE_ACTION )359 if($row['type'] == Piwik_Tracker_Action::TYPE_ACTION ) 282 360 { 283 361 $actionName = '/' . $actionName; 284 362 } 285 363 else if( $row['type'] == Piwik_Tracker_Action::TYPE_ACTION_NAME ) 364 { 365 $actionName = ' ' . $actionName; 366 } 367 286 368 // currentTable is now the array element corresponding the the action 287 369 // at this point we may be for example at the 4th level of depth in the hierarchy 288 370 $currentTable =& $currentTable[$actionName]; … … 290 372 // add the row to the matching sub category subtable 291 373 if(!($currentTable instanceof Piwik_DataTable_Row)) 292 374 { 293 $currentTable = new Piwik_DataTable_Row(array( 375 if( $row['type'] == Piwik_Tracker_Action::TYPE_ACTION_NAME ) 376 { 377 $currentTable = new Piwik_DataTable_Row(array( 294 378 Piwik_DataTable_Row::COLUMNS => array('label' => (string)$actionName), 379 )); 380 } 381 else 382 { 383 $currentTable = new Piwik_DataTable_Row(array( 384 Piwik_DataTable_Row::COLUMNS => array('label' => (string)$actionName), 295 385 Piwik_DataTable_Row::METADATA => array('url' => (string)$row['name']), 296 386 )); 387 } 297 388 } 298 389 299 390 foreach($row as $name => $value) … … 325 416 if($currentTable->getColumn('nb_hits') === false) 326 417 { 327 418 // to test this code: delete the entries in log_link_action_visit for 328 // a given exit_idaction 419 // a given exit_idaction_url 329 420 foreach($this->defaultRow->getColumns() as $name => $value) 330 421 { 331 422 $currentTable->addColumn($name, $value); -
plugins/Actions/Controller.php
17 17 */ 18 18 class Piwik_Actions_Controller extends Piwik_Controller 19 19 { 20 public function index()20 public function getPageUrls($fetch = false) 21 21 { 22 $view = Piwik_View ::factory('index');23 24 /* Actions, Downloads, Outlinks */25 $view->dataTableActions = $this->getActions( true );26 $view->dataTableDownloads = $this->getDownloads( true);27 $view-> dataTableOutlinks = $this->getOutlinks( true);28 29 echo $view->render();22 $view = Piwik_ViewDataTable::factory(); 23 $view->init( $this->pluginName, 24 __FUNCTION__, 25 'Actions.getPageUrls', 26 'getPageUrlsSubDataTable' ); 27 $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageURL')); 28 $this->configureViewActions($view); 29 return $this->renderView($view, $fetch); 30 30 } 31 31 32 public function get Actions($fetch = false)32 public function getPageUrlsSubDataTable($fetch = false) 33 33 { 34 34 $view = Piwik_ViewDataTable::factory(); 35 35 $view->init( $this->pluginName, 36 36 __FUNCTION__, 37 'Actions.get Actions',38 'getActionsSubDataTable' );37 'Actions.getPageUrls', 38 'getActionsSubDataTable' ); 39 39 $this->configureViewActions($view); 40 return $this->renderView($view, $fetch); 41 } 42 43 public function getPageTitles($fetch = false) 44 { 45 $view = Piwik_ViewDataTable::factory(); 46 $view->init( $this->pluginName, 47 __FUNCTION__, 48 'Actions.getPageTitles', 49 'getPageTitlesSubDataTable' ); 40 50 $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageName')); 51 $this->configureViewActions($view); 41 52 return $this->renderView($view, $fetch); 42 53 } 43 44 public function get ActionsSubDataTable($fetch = false)54 55 public function getPageTitlesSubDataTable($fetch = false) 45 56 { 46 57 $view = Piwik_ViewDataTable::factory(); 47 $view->init( $this->pluginName, 58 $view->init( $this->pluginName, 48 59 __FUNCTION__, 49 'Actions.get Actions',50 'get ActionsSubDataTable' );60 'Actions.getPageTitles', 61 'getPageTitlesSubDataTable' ); 51 62 $this->configureViewActions($view); 52 63 return $this->renderView($view, $fetch); 53 64 } 54 65 55 66 public function getDownloads($fetch = false) 56 67 { 57 68 $view = Piwik_ViewDataTable::factory(); … … 76 87 $view->disableSearchBox(); 77 88 return $this->renderView($view, $fetch); 78 89 } 79 90 80 91 public function getOutlinks($fetch = false) 81 92 { 82 93 $view = Piwik_ViewDataTable::factory(); … … 101 112 $view->disableSearchBox(); 102 113 return $this->renderView($view, $fetch); 103 114 } 104 115 105 116 protected function configureViewActions($view) 106 117 { 107 118 $view->setTemplate('CoreHome/templates/datatable_actions.tpl'); … … 123 134 124 135 $view->setLimit( 100 ); 125 136 $view->setColumnsToDisplay( array('label','nb_hits','nb_visits') ); 126 $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageName'));127 137 $view->setColumnTranslation('nb_hits', Piwik_Translate('General_ColumnPageviews')); 128 138 $view->setColumnTranslation('nb_visits', Piwik_Translate('General_ColumnUniquePageviews')); 129 139 … … 171 181 $view->disableExcludeLowPopulation(); 172 182 $view->setLimit( 15 ); 173 183 } 174 184 175 185 protected function getArrayFromRecursiveDataTable( $dataTable, $depth = 0 ) 176 186 { 177 187 $table = array(); -
web.config
1 <?xml version="1.0" encoding="UTF-8"?>2 <configuration>3 <system.webServer>4 <security>5 <requestFiltering>6 <hiddenSegments>7 <add segment="config" />8 <add segment="tmp" />9 </hiddenSegments>10 </requestFiltering>11 </security>12 <directoryBrowse enabled="false" />13 <defaultDocument>14 <files>15 <remove value="index.php" />16 <add value="index.php" />17 </files>18 </defaultDocument>19 </system.webServer>20 </configuration> -
core/Tracker/Action.php
21 21 const TYPE_ACTION = 1; 22 22 const TYPE_OUTLINK = 2; 23 23 const TYPE_DOWNLOAD = 3; 24 const TYPE_ACTION_NAME = 4; 24 25 25 26 public function setRequest($requestArray); 26 27 public function setIdSite( $idSite ); … … 29 30 public function getActionName(); 30 31 public function getActionType(); 31 32 public function record( $idVisit, $idRefererAction, $timeSpentRefererAction ); 32 public function getIdAction(); 33 public function getIdActionUrl(); 34 public function getIdActionName(); 33 35 public function getIdLinkVisitAction(); 34 36 } 35 37 … … 44 46 * - An action is defined by a name. 45 47 * - The name can be specified in the JS Code in the variable 'action_name' 46 48 * For example you can decide to use the javascript value document.title as an action_name 47 * - If the name is not specified, we use the URL(path+query) to build a default name. 48 * For example for "http://piwik.org/test/my_page/test.html" 49 * the name would be "test/my_page/test.html" 50 * - If the name is empty we set it to default_action_name found in global.ini.php 49 * - If the URL was not passed to piwik, it uses default_action_url defined in global.ini 51 50 * - Handling UTF8 in the action name 52 51 * PLUGIN_IDEA - An action is associated to URLs and link to the URL from the reports (currently actions do not link to the url of the pages) 53 52 * PLUGIN_IDEA - An action hit by a visitor is associated to the HTML title of the page that triggered the action and this HTML title is displayed in the interface … … 60 59 private $request; 61 60 private $idSite; 62 61 private $idLinkVisitAction; 63 private $idAction = null; 62 private $idActionName = null; 63 private $idActionUrl = null; 64 64 65 65 private $actionName; 66 66 private $actionType; 67 private $ url;67 private $actionUrl; 68 68 69 69 protected function getDefaultActionName() 70 70 { 71 71 return Piwik_Tracker_Config::getInstance()->Tracker['default_action_name']; 72 72 } 73 74 protected function getDefaultActionUrl() 75 { 76 return Piwik_Tracker_Config::getInstance()->Tracker['default_action_url']; 77 } 73 78 74 79 public function setRequest($requestArray) 75 80 { … … 92 97 { 93 98 return $this->actionType; 94 99 } 100 public function getActionNameType() 101 { 102 $actionNameType = null; 103 104 // we can add here action types for names of other actions than page views (like downloads, outlinks) 105 switch( $this->getActionType() ) 106 { 107 case Piwik_Tracker_Action_Interface::TYPE_ACTION: 108 $actionNameType = Piwik_Tracker_Action_Interface::TYPE_ACTION_NAME; 109 break; 110 } 111 112 return $actionNameType; 113 } 114 115 public function getIdActionUrl() 116 { 117 return $this->idActionUrl; 118 } 119 public function getIdActionName() 120 { 121 return $this->idActionName; 122 } 95 123 96 124 protected function setActionName($name) 97 125 { … … 115 143 } 116 144 117 145 /** 118 * Returns the idaction of the current action name.119 * Th is idaction is used in the visitor logging table to link the visit information146 * Loads the idaction of the current action name and the current action url. 147 * These idactions are used in the visitor logging table to link the visit information 120 148 * (entry action, exit action) to the actions. 121 * Th is idaction isalso used in the table that links the visits and their actions.149 * These idactions are also used in the table that links the visits and their actions. 122 150 * 123 * The methods takes care of creating a new record in the action table if the existing124 * action name doesn't exist yet.151 * The methods takes care of creating a new record(s) in the action table if the existing 152 * action name and action url doesn't exist yet. 125 153 * 126 * @return int Id action that is associated to this action name in the Actions table lookup127 154 */ 128 function getIdAction()155 function loadIdActionNameAndUrl() 129 156 { 130 if( !is_null($this->idAction))157 if( !is_null($this->idActionUrl) && !is_null($this->idActionName) ) 131 158 { 132 return $this->idAction;159 return; 133 160 } 134 $idAction = Piwik_Tracker::getDatabase()->fetch("/* SHARDING_ID_SITE = ".$this->idSite." */ SELECT idaction 161 $idAction = Piwik_Tracker::getDatabase()->fetchAll("/* SHARDING_ID_SITE = ".$this->idSite." */ 162 SELECT idaction, type 135 163 FROM ".Piwik_Common::prefixTable('log_action') 136 ." WHERE name = ? AND type = ?", 137 array($this->getActionName(), $this->getActionType()) 164 ." WHERE " 165 ." ( hash = CRC32(?) AND name = ? AND type = ? ) " 166 ." OR " 167 ." ( hash = CRC32(?) AND name = ? AND type = ? ) ", 168 array($this->getActionName(), $this->getActionName(), $this->getActionNameType(), 169 $this->getActionUrl(), $this->getActionUrl(), $this->getActionType()) 138 170 ); 139 140 // the action name has not been found, create it 141 if($idAction === false || $idAction == '') 171 172 if( $idAction !== false ) 142 173 { 143 Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = ".$this->idSite." */ 144 INSERT INTO ". Piwik_Common::prefixTable('log_action'). " ( name, type ) 145 VALUES (?,?)", 146 array($this->getActionName(),$this->getActionType()) 147 ); 148 $idAction = Piwik_Tracker::getDatabase()->lastInsertId(); 174 foreach($idAction as $row) 175 { 176 if( $row['type'] == Piwik_Tracker_Action_Interface::TYPE_ACTION_NAME ) 177 { 178 $this->idActionName = $row['idaction']; 179 } 180 else 181 { 182 $this->idActionUrl = $row['idaction']; 183 } 184 } 149 185 } 150 else 186 187 $sql = "/* SHARDING_ID_SITE = ".$this->idSite." */ 188 INSERT INTO ". Piwik_Common::prefixTable('log_action'). 189 "( name, hash, type ) VALUES (?,CRC32(?),?)"; 190 191 if( is_null($this->idActionName) && !is_null($this->getActionName()) && !is_null($this->getActionNameType()) ) 151 192 { 152 $idAction = $idAction['idaction']; 193 Piwik_Tracker::getDatabase()->query($sql, 194 array($this->getActionName(), $this->getActionName(), $this->getActionNameType())); 195 $this->idActionName = Piwik_Tracker::getDatabase()->lastInsertId(); 153 196 } 154 $this->idAction = $idAction; 155 return $this->idAction; 197 198 if( is_null($this->idActionUrl) ) 199 { 200 Piwik_Tracker::getDatabase()->query($sql, 201 array($this->getActionUrl(), $this->getActionUrl(), $this->getActionType())); 202 $this->idActionUrl = Piwik_Tracker::getDatabase()->lastInsertId(); 203 } 156 204 } 157 205 158 206 /** … … 174 222 */ 175 223 public function record( $idVisit, $idRefererAction, $timeSpentRefererAction) 176 224 { 177 Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = ".$this->idSite." */ INSERT INTO ".Piwik_Common::prefixTable('log_link_visit_action') 178 ." (idvisit, idaction, idaction_ref, time_spent_ref_action) VALUES (?,?,?,?)", 179 array($idVisit, $this->getIdAction(), $idRefererAction, $timeSpentRefererAction) 225 $this->loadIdActionNameAndUrl(); 226 227 Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = ".$this->idSite." */ INSERT INTO ".Piwik_Common::prefixTable('log_link_visit_action') 228 ." (idvisit, idaction_url, idaction_name, idaction_url_ref, time_spent_ref_action) VALUES (?,?,?,?,?)", 229 array($idVisit, $this->getIdActionUrl(), $this->getIdActionName(), $idRefererAction, $timeSpentRefererAction) 180 230 ); 181 231 182 232 $this->idLinkVisitAction = Piwik_Tracker::getDatabase()->lastInsertId(); … … 209 259 /** 210 260 * Generates the name of the action from the URL or the specified name. 211 261 * Sets the name as $this->actionName 262 * 263 * @return array 212 264 */ 213 265 protected function extractUrlAndActionNameFromRequest() 214 266 { 267 $actionName = null; 268 215 269 // download? 216 270 $downloadUrl = Piwik_Common::getRequestVar( 'download', '', 'string', $this->request); 217 271 if(!empty($downloadUrl)) … … 230 284 $url = $outlinkUrl; 231 285 } 232 286 } 233 287 288 $actionName = Piwik_Common::getRequestVar( 'action_name', '', 'string', $this->request); 289 234 290 // defaults to page view 235 291 if(empty($actionType)) 236 292 { 237 293 $actionType = self::TYPE_ACTION; 238 294 $url = Piwik_Common::getRequestVar( 'url', '', 'string', $this->request); 239 $actionName = Piwik_Common::getRequestVar( 'action_name', '', 'string', $this->request); 240 if( empty($ actionName) )295 296 if( empty($url) ) 241 297 { 242 $cleanedUrl = str_replace(array("\n", "\r", "\t"), "", $url); 243 $actionName = Piwik_Common::getPathAndQueryFromUrl($cleanedUrl); 244 // in case the $actionName is empty or ending with a slash, 245 // we append the defaultActionName: a/b/ becomes a/b/index 246 if(empty($actionName) 247 || substr($actionName, -1) == '/') 248 { 249 $actionName .= $this->getDefaultActionName(); 250 } 298 $url .= $this->getDefaultActionUrl(); 251 299 } 252 300 253 301 // get the delimiter, by default '/' … … 268 316 269 317 $url = trim($url); 270 318 $url = str_replace(array("\n", "\r"), "", $url); 271 if(empty($actionName))272 {273 $actionName = $url;274 }275 319 320 $actionName = trim($actionName); 321 $actionName = str_replace(array("\n", "\r"), "", $actionName); 322 276 323 return array( 277 'name' => $actionName,324 'name' => empty($actionName) ? null : $actionName, 278 325 'type' => $actionType, 279 326 'url' => $url, 280 327 ); -
core/Tracker/GoalManager.php
17 17 class Piwik_Tracker_GoalManager 18 18 { 19 19 /** 20 * @var Piwik_Cookie 20 * @var Piwik_Cookie 21 21 */ 22 22 protected $cookie = null; 23 23 /** … … 41 41 } 42 42 return array(); 43 43 } 44 44 45 45 static public function getGoalDefinition( $idSite, $idGoal ) 46 46 { 47 47 $goals = self::getGoalDefinitions( $idSite ); … … 54 54 } 55 55 throw new Exception("The goal id = $idGoal couldn't be found."); 56 56 } 57 57 58 58 static public function getGoalIds( $idSite ) 59 59 { 60 60 $goals = self::getGoalDefinitions( $idSite ); … … 65 65 } 66 66 return $goalIds; 67 67 } 68 68 69 69 private function isGoalPluginEnabled() 70 70 { 71 71 return Piwik_PluginsManager::getInstance()->isPluginActivated('Goals'); 72 72 } 73 74 //TODO does this code work for manually triggered goals, with custom revenue? 73 74 //TODO does this code work for manually triggered goals, with custom revenue? 75 75 function detectGoalsMatchingUrl($idSite, $action) 76 76 { 77 77 if(!$this->isGoalPluginEnabled()) … … 93 93 { 94 94 continue; 95 95 } 96 96 97 97 $pattern_type = $goal['pattern_type']; 98 98 99 99 switch($pattern_type) 100 100 { 101 101 case 'regex': … … 141 141 // var_dump($this->convertedGoals);exit; 142 142 return count($this->convertedGoals) > 0; 143 143 } 144 144 145 145 function detectGoalId($idSite, $idGoal, $request) 146 146 { 147 147 if(!$this->isGoalPluginEnabled()) … … 159 159 $this->convertedGoals[] = $goal; 160 160 return true; 161 161 } 162 162 163 163 function recordGoals($visitorInformation, $action) 164 164 { 165 165 $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']); 166 166 $location_continent = isset($visitorInformation['location_continent']) ? $visitorInformation['location_continent'] : Piwik_Common::getContinent($location_country); 167 167 168 168 $goal = array( 169 169 'idvisit' => $visitorInformation['idvisit'], 170 170 'idsite' => $visitorInformation['idsite'], … … 197 197 $newGoal['revenue'] = $convertedGoal['revenue']; 198 198 if(!is_null($action)) 199 199 { 200 $newGoal['idaction '] = $action->getIdAction();200 $newGoal['idaction_url'] = $action->getIdActionUrl(); 201 201 $newGoal['idlink_va'] = $action->getIdLinkVisitAction(); 202 202 } 203 203 printDebug($newGoal); 204 204 205 205 $fields = implode(", ", array_keys($newGoal)); 206 206 $bindFields = substr(str_repeat( "?,",count($newGoal)),0,-1); 207 207 208 208 try { 209 209 Piwik_Tracker::getDatabase()->query( 210 "INSERT INTO " . Piwik_Common::prefixTable('log_conversion') . " ($fields) 211 VALUES ($bindFields) ", array_values($newGoal) 210 "INSERT INTO " . Piwik_Common::prefixTable('log_conversion') . " ($fields) 211 VALUES ($bindFields) ", array_values($newGoal) 212 212 ); 213 213 } catch( Exception $e) { 214 214 if(Piwik_Tracker::isErrNo($e, '1062')) -
core/Tracker/Visit.php
95 95 96 96 $goalManager = new Piwik_Tracker_GoalManager(); 97 97 $someGoalsConverted = false; 98 $action Id = 0;98 $actionUrlId = 0; 99 99 $action = null; 100 100 101 101 $idGoal = Piwik_Common::getRequestVar('idgoal', 0, 'int', $this->request); … … 116 116 $action = $this->newAction(); 117 117 $this->handleAction($action); 118 118 $someGoalsConverted = $goalManager->detectGoalsMatchingUrl($this->idsite, $action); 119 $actionId = $action->getIdAction(); 119 120 $action->loadIdActionNameAndUrl(); 121 $actionUrlId = $action->getIdActionUrl(); 120 122 } 121 123 122 124 // the visitor and session … … 133 135 if( $this->isVisitorKnown() 134 136 && $isLastActionInTheSameVisit) 135 137 { 136 $idActionReferer = $this->visitorInfo['visit_exit_idaction '];138 $idActionReferer = $this->visitorInfo['visit_exit_idaction_url']; 137 139 try { 138 $this->handleKnownVisit($action Id, $someGoalsConverted);140 $this->handleKnownVisit($actionUrlId, $someGoalsConverted); 139 141 if(!is_null($action)) 140 142 { 141 143 $action->record( $this->visitorInfo['idvisit'], … … 156 158 if(!$this->isVisitorKnown() 157 159 || !$isLastActionInTheSameVisit) 158 160 { 159 $this->handleNewVisit($action Id, $someGoalsConverted);161 $this->handleNewVisit($actionUrlId, $someGoalsConverted); 160 162 if(!is_null($action)) 161 163 { 162 164 $action->record( $this->visitorInfo['idvisit'], 0, 0 ); … … 211 213 * 212 214 * 2) Update the visit information 213 215 */ 214 protected function handleKnownVisit($action Id, $someGoalsConverted)216 protected function handleKnownVisit($actionUrlId, $someGoalsConverted) 215 217 { 216 218 $serverTime = $this->getCurrentTimestamp(); 217 219 $datetimeServer = Piwik_Tracker::getDatetimeFromTimestamp($serverTime); … … 224 226 } 225 227 226 228 $sqlActionIdUpdate = ''; 227 if(!empty($action Id))229 if(!empty($actionUrlId)) 228 230 { 229 $sqlActionIdUpdate = "visit_exit_idaction = ". $actionId .",231 $sqlActionIdUpdate = "visit_exit_idaction_url = ". $actionUrlId .", 230 232 visit_total_actions = visit_total_actions + 1, "; 231 $this->visitorInfo['visit_exit_idaction '] = $actionId;233 $this->visitorInfo['visit_exit_idaction_url'] = $actionUrlId; 232 234 } 233 234 $result = Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = ". $this->idsite ." */ 235 $statement = Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = ". $this->idsite ." */ 235 236 UPDATE ". Piwik_Common::prefixTable('log_visit')." 236 237 SET $sqlActionIdUpdate 237 238 $sqlUpdateGoalConverted … … 244 245 $this->visitorInfo['idvisit'], 245 246 $this->visitorInfo['visitor_idcookie'] ) 246 247 ); 247 248 if(Piwik_Tracker::getDatabase()->rowCount($result) == 0) 248 if($statement->rowCount() == 0) 249 249 { 250 250 throw new Piwik_Tracker_Visit_VisitorNotFoundInDatabase("The visitor with visitor_idcookie=".$this->visitorInfo['visitor_idcookie']." and idvisit=".$this->visitorInfo['idvisit']." wasn't found in the DB, we fallback to a new visitor"); 251 251 } … … 267 267 * 268 268 * 2) Insert the visit information 269 269 */ 270 protected function handleNewVisit($action Id, $someGoalsConverted)270 protected function handleNewVisit($actionUrlId, $someGoalsConverted) 271 271 { 272 272 printDebug("New Visit."); 273 273 … … 297 297 'visit_first_action_time' => Piwik_Tracker::getDatetimeFromTimestamp($serverTime), 298 298 'visit_last_action_time' => Piwik_Tracker::getDatetimeFromTimestamp($serverTime), 299 299 'visit_server_date' => $serverDate, 300 'visit_entry_idaction ' => $actionId,301 'visit_exit_idaction ' => $actionId,300 'visit_entry_idaction_url' => $actionUrlId, 301 'visit_exit_idaction_url' => $actionUrlId, 302 302 'visit_total_actions' => 1, 303 303 'visit_total_time' => $defaultTimeOnePageVisit, 304 304 'visit_goal_converted' => $someGoalsConverted ? 1: 0, … … 531 531 $this->visitorInfo['visit_last_action_time'] = $timestampLastAction; 532 532 $this->visitorInfo['visit_first_action_time'] = $timestampFirstAction; 533 533 $this->visitorInfo['idvisit'] = $idVisit; 534 $this->visitorInfo['visit_exit_idaction '] = $idLastAction;534 $this->visitorInfo['visit_exit_idaction_url'] = $idLastAction; 535 535 536 536 $this->visitorKnown = true; 537 537 … … 569 569 $this->visitorInfo['visit_last_action_time'] = $visitRow['visit_last_action_time']; 570 570 $this->visitorInfo['visit_first_action_time'] = $visitRow['visit_first_action_time']; 571 571 $this->visitorInfo['idvisit'] = $visitRow['idvisit']; 572 $this->visitorInfo['visit_exit_idaction '] = $visitRow['visit_exit_idaction'];572 $this->visitorInfo['visit_exit_idaction_url'] = $visitRow['visit_exit_idaction_url']; 573 573 574 574 $this->visitorKnown = true; 575 575 … … 719 719 $this->visitorInfo['idvisit'] ); 720 720 721 721 // the last action ID is the current exit idaction 722 if(isset($this->visitorInfo['visit_exit_idaction '] ))722 if(isset($this->visitorInfo['visit_exit_idaction_url'] )) 723 723 { 724 724 $this->cookie->set( Piwik_Tracker::COOKIE_INDEX_ID_LAST_ACTION, 725 $this->visitorInfo['visit_exit_idaction '] );725 $this->visitorInfo['visit_exit_idaction_url'] ); 726 726 } 727 727 728 728 // for a new visit, we flag the visit with visitor_returning -
core/Updates/0.5-rc1.php
1 <?php 2 3 Piwik_Query('ALTER TABLE ' . Piwik::prefixTable('log_action'). ' ADD COLUMN `hash` INTEGER(10) UNSIGNED NOT NULL AFTER `name`;'); 4 Piwik_Query('UPDATE '. Piwik::prefixTable('log_action'). ' SET `hash` = CRC32(name);'); 5 Piwik_Query('CREATE INDEX index_type_hash ON '. Piwik::prefixTable('log_action') .' (type, hash);'); 6 Piwik_Query('DROP INDEX index_type_name ON '. Piwik::prefixTable('log_action') .';'); 7 8 Piwik_Query('ALTER TABLE '. Piwik::prefixTable('log_visit') .' CHANGE visit_exit_idaction visit_exit_idaction_url INTEGER(11) NOT NULL;'); 9 Piwik_Query('ALTER TABLE '. Piwik::prefixTable('log_visit') .' CHANGE visit_entry_idaction visit_entry_idaction_url INTEGER(11) NOT NULL;'); 10 11 Piwik_Query('ALTER TABLE ' . Piwik::prefixTable('log_link_visit_action'). ' CHANGE `idaction_ref` `idaction_url_ref` INTEGER(10) UNSIGNED NOT NULL;'); 12 Piwik_Query('ALTER TABLE ' . Piwik::prefixTable('log_link_visit_action'). ' CHANGE `idaction` `idaction_url` INTEGER(10) UNSIGNED NOT NULL;'); 13 Piwik_Query('ALTER TABLE ' . Piwik::prefixTable('log_link_visit_action'). ' ADD COLUMN `idaction_name` INTEGER(10) UNSIGNED AFTER `idaction_url_ref`;'); -
core/Piwik.php
609 609 'log_action' => "CREATE TABLE {$prefixTables}log_action ( 610 610 idaction INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT, 611 611 name VARCHAR(255) NOT NULL, 612 hash INTEGER(10) UNSIGNED NOT NULL, 612 613 type TINYINT UNSIGNED NULL, 613 614 PRIMARY KEY(idaction), 614 INDEX index_type_ name (type, name(15))615 INDEX index_type_hash (type, hash) 615 616 ) DEFAULT CHARSET=utf8 616 617 ", 617 618 … … 624 625 visit_first_action_time DATETIME NOT NULL, 625 626 visit_last_action_time DATETIME NOT NULL, 626 627 visit_server_date DATE NOT NULL, 627 visit_exit_idaction INTEGER(11) NOT NULL,628 visit_entry_idaction INTEGER(11) NOT NULL,628 visit_exit_idaction_url INTEGER(11) NOT NULL, 629 visit_entry_idaction_url INTEGER(11) NOT NULL, 629 630 visit_total_actions SMALLINT(5) UNSIGNED NOT NULL, 630 631 visit_total_time SMALLINT(5) UNSIGNED NOT NULL, 631 632 visit_goal_converted TINYINT(1) NOT NULL, … … 684 685 'log_link_visit_action' => "CREATE TABLE {$prefixTables}log_link_visit_action ( 685 686 idlink_va INTEGER(11) NOT NULL AUTO_INCREMENT, 686 687 idvisit INTEGER(10) UNSIGNED NOT NULL, 687 idaction INTEGER(10) UNSIGNED NOT NULL, 688 idaction_ref INTEGER(11) UNSIGNED NOT NULL, 688 idaction_url INTEGER(10) UNSIGNED NOT NULL, 689 idaction_url_ref INTEGER(10) UNSIGNED NOT NULL, 690 idaction_name INTEGER(10) UNSIGNED, 689 691 time_spent_ref_action INTEGER(10) UNSIGNED NOT NULL, 690 692 PRIMARY KEY(idlink_va), 691 693 INDEX index_idvisit(idvisit) -
core/ArchiveProcessing/Day.php
28 28 $this->db = Zend_Registry::get('db'); 29 29 $this->debugAlwaysArchive = Zend_Registry::get('config')->Debug->always_archive_data_day; 30 30 } 31 31 32 32 /** 33 33 * Main method to process logs for a day. The only logic done here is computing the number of visits, actions, etc. 34 34 * All the other reports are computed inside plugins listening to the event 'ArchiveProcessing_Day.compute'. -
tests/core/Tracker/Action.test.php
23 23 // outlinks 24 24 array( 25 25 'request' => array( 'link' => 'http://example.org'), 26 'expected' => array( 'name' => 'http://example.org',26 'expected' => array( 'name' => null, 27 27 'url' => 'http://example.org', 28 28 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), 29 29 ), 30 // outlinks with custom name 31 array( 32 'request' => array( 'link' => 'http://example.org', 'action_name' => 'Example.org'), 33 'expected' => array( 'name' => 'Example.org', 34 'url' => 'http://example.org', 35 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), 36 ), 30 37 // keep the case in urls, but trim 31 38 array( 32 39 'request' => array( 'link' => ' http://example.org/Category/Test/ '), 33 'expected' => array( 'name' => 'http://example.org/Category/Test/',40 'expected' => array( 'name' => null, 34 41 'url' => 'http://example.org/Category/Test/', 35 42 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), 36 43 ), 37 44 45 // trim the custom name 46 array( 47 'request' => array( 'link' => ' http://example.org/Category/Test/ ', 'action_name' => ' Example dot org '), 48 'expected' => array( 'name' => 'Example dot org', 49 'url' => 'http://example.org/Category/Test/', 50 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), 51 ), 52 38 53 // downloads 39 54 array( 40 55 'request' => array( 'download' => 'http://example.org/*$test.zip'), 41 'expected' => array( 'name' => 'http://example.org/*$test.zip',56 'expected' => array( 'name' => null, 42 57 'url' => 'http://example.org/*$test.zip', 43 58 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD), 44 59 ), 60 61 // downloads with custom name 62 array( 63 'request' => array( 'download' => 'http://example.org/*$test.zip', 'action_name' => 'Download test.zip'), 64 'expected' => array( 'name' => 'Download test.zip', 65 'url' => 'http://example.org/*$test.zip', 66 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD), 67 ), 68 45 69 // keep the case and multiple / in urls 46 70 array( 47 71 'request' => array( 'download' => 'http://example.org/CATEGORY/test///test.pdf'), 48 'expected' => array( 'name' => 'http://example.org/CATEGORY/test///test.pdf',72 'expected' => array( 'name' => null, 49 73 'url' => 'http://example.org/CATEGORY/test///test.pdf', 50 74 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD), 51 75 ), … … 53 77 // page view 54 78 array( 55 79 'request' => array( 'url' => 'http://example.org/'), 56 'expected' => array( 'name' => 'index',80 'expected' => array( 'name' => null, 57 81 'url' => 'http://example.org/', 58 82 'type' => Piwik_Tracker_Action::TYPE_ACTION), 59 83 ), 60 84 array( 85 'request' => array( 'url' => 'http://example.org/', 'action_name' => 'Example.org Website'), 86 'expected' => array( 'name' => 'Example.org Website', 87 'url' => 'http://example.org/', 88 'type' => Piwik_Tracker_Action::TYPE_ACTION), 89 ), 90 array( 61 91 'request' => array( 'url' => 'http://example.org/CATEGORY/'), 62 'expected' => array( 'name' => 'CATEGORY/index',92 'expected' => array( 'name' => null, 63 93 'url' => 'http://example.org/CATEGORY/', 64 94 'type' => Piwik_Tracker_Action::TYPE_ACTION), 65 95 ), 66 96 array( 97 'request' => array( 'url' => 'http://example.org/CATEGORY/TEST', 'action_name' => 'Example.org / Category / test /'), 98 'expected' => array( 'name' => 'Example.org/Category/test', 99 'url' => 'http://example.org/CATEGORY/TEST', 100 'type' => Piwik_Tracker_Action::TYPE_ACTION), 101 ), 102 103 // empty request 104 array( 105 'request' => array(), 106 'expected' => array( 'name' => null, 'url' => '/', 107 'type' => Piwik_Tracker_Action::TYPE_ACTION), 108 ), 109 array( 67 110 'request' => array( 'url' => 'http://example.org/category/', 68 111 'action_name' => 'custom name with/one delimiter/two delimiters/'), 69 112 'expected' => array( 'name' => 'custom name with/one delimiter/two delimiters', … … 80 123 // testing: delete tab, trimmed, not strtolowered 81 124 array( 82 125 'request' => array( 'url' => "http://example.org/category/test///test wOw "), 83 'expected' => array( 'name' => 'category/test/test wOw',126 'expected' => array( 'name' => null, 84 127 'url' => 'http://example.org/category/test///test wOw', 85 128 'type' => Piwik_Tracker_Action::TYPE_ACTION), 86 129 ), 87 130 // testing: inclusion of zero values in action name 88 131 array( 89 132 'request' => array( 'url' => "http://example.org/category/1/0/t/test"), 90 'expected' => array( 'name' => 'category/1/0/t/test',133 'expected' => array( 'name' => null, 91 134 'url' => 'http://example.org/category/1/0/t/test', 92 135 'type' => Piwik_Tracker_Action::TYPE_ACTION), 93 136 ), -
tests/core/Config.test.php
15 15 $globalFile = PIWIK_INCLUDE_PATH . '/tests/resources/Config/global.ini.php'; 16 16 17 17 $config = new Piwik_Config($userFile, $globalFile); 18 Zend_Registry::set('config', $config); 19 18 20 $config->init(); 21 19 22 $this->assertEqual($config->Category->key1, "value_overwritten"); 20 23 $this->assertEqual($config->Category->key2, "value2"); 21 24 $this->assertEqual($config->General->login, 'tes"t'); -
tests/resources/plugins/Actions/Actions.config.ini.php
1 [General] 2 action_category_delimiter = / 3 4 [Tracker] 5 default_action_name = index -
tests/resources/Tracker/Action.config.ini.php
1 1 [Tracker] 2 2 action_category_delimiter = / 3 default_action_name = index 4 default_action_url = / 5 No newline at end of file -
config/global.ini.php
134 134 ; this action name is used when the javascript variable piwik_action_name is not specified in the piwik javascript code, and when the URL has no path. 135 135 default_action_name = index 136 136 137 ; this action url is used when URL was not passed to Piwik (i.e. when javascript is disabled in browser and referer was not set in the request) 138 default_action_url = / 139 137 140 ; length of a visit in seconds. If a visitor comes back on the website visit_standard_length seconds after his last page view, it will be recorded as a new visit 138 141 visit_standard_length = 1800 139 142
