PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/_plugins_/phpmyvisites/core/include/Archive.class.php

https://bitbucket.org/pombredanne/spip-zone-treemap
PHP | 483 lines | 297 code | 75 blank | 111 comment | 32 complexity | 66e47a1c49b401eb1a962cd19c44266f MD5 | raw file
  1. <?php
  2. /*
  3. * phpMyVisites : website statistics and audience measurements
  4. * Copyright (C) 2002 - 2006
  5. * http://www.phpmyvisites.net/
  6. * phpMyVisites is free software (license GNU/GPL)
  7. * Authors : phpMyVisites team
  8. */
  9. // $Id: Archive.class.php,v 1.70 2006/01/13 01:24:49 matthieu_ Exp $
  10. $GLOBALS['test'] = ", sum(case total_pages when 1 then 1 else 0 end) as onepage," .
  11. " sum(total_pages) as sumpage, count(*) as s, sum(total_time) as sumtime";
  12. require_once INCLUDE_PATH."/core/include/Date.class.php";
  13. require_once INCLUDE_PATH."/core/include/Str.class.php";
  14. require_once INCLUDE_PATH."/core/include/Archive.functions.php";
  15. require_once INCLUDE_PATH."/core/include/functions.php";
  16. /**
  17. * Base class used by other ArchiveClass to assign some standard attributes
  18. *
  19. */
  20. class Archive
  21. {
  22. /**
  23. * @var object Site
  24. */
  25. var $site;
  26. /**
  27. * @var array fieldName => fieldValue to save in database
  28. */
  29. var $toRecord; // array 'field_name' => value to record
  30. /**
  31. * @var int Current idarchives of the archive process
  32. */
  33. var $idArchives;
  34. /**
  35. * @var int State of the current archive process (Must be DB_ARCHIVES_*)
  36. */
  37. var $state; // DB_x
  38. /**
  39. * @var object Date
  40. */
  41. var $date;
  42. var $date2;
  43. /**
  44. * @var int Type of the current archive period (Must be DB_ARCHIVES_PERIOD_*)
  45. */
  46. var $periodType;
  47. // int value
  48. /**
  49. * @var array integer arrays to sum conserving keys array( 3, 4, 6 );
  50. */
  51. var $intValuesToSum;
  52. // key => int value
  53. var $arrayOneDimToSum;
  54. // key => array('pmv_sum' => X, 'iddetail1' => Y, 'iddetail2' => Z);
  55. var $arrayPmvSumToSum;
  56. var $arrayIntToSum;
  57. var $archiveOk; // flag to known if finished, used when using current archive twice
  58. /**
  59. * @var string literal date corresponding to $this->date
  60. */
  61. var $literalDate;
  62. /**
  63. * @param object $site
  64. */
  65. function Archive($site)
  66. {
  67. $this->site = $site;
  68. $this->state = DB_ARCHIVES_DONE;
  69. $this->toRecord = array();
  70. $this->archiveOk = false;
  71. $this->intValuesToSum = array(
  72. 'nb_vis', 'nb_pag', 'nb_uniq_pag', 'nb_vis_1pag', 'sum_vis_lth',
  73. 'nb_direct', 'nb_search_engine', 'nb_site', 'nb_newsletter', 'nb_partner',
  74. 'nb_vis_returning', 'nb_pag_returning', 'nb_vis_1pag_returning', 'sum_vis_lth_returning'
  75. );
  76. // key => int value
  77. $this->arrayOneDimToSum = array(
  78. 'vis_st', 'vis_lt', 'pag_st', 'pag_lt', 'vis_lth', 'vis_nb_pag',
  79. 'vis_country', 'vis_continent', 'vis_provider', 'vis_config', 'vis_os', 'vis_browser', 'vis_browser_type',
  80. 'vis_resolution', 'vis_plugin', 'vis_depth',
  81. 'vis_newsletter',
  82. 'vis_nb_vis'
  83. );
  84. // key => array('pmv_sum' => X, 'iddetail1' => Y, 'iddetail2' => Z);
  85. $this->arrayPmvSumToSum = array(
  86. 'vis_search_engine', 'vis_keyword', 'vis_site', 'vis_partner'
  87. );
  88. $this->arrayIntToSum = array(
  89. 'int_lt', 'int_st', 'int_referer_type', 'int_search_engine', 'int_keyword', 'int_site', 'int_partner',
  90. 'int_newsletter', 'int_country', 'int_continent', 'int_os', 'int_browser', 'int_resolution',
  91. //'int_config',
  92. 'int_depth'
  93. );
  94. }
  95. /**
  96. * Update database, set var state
  97. */
  98. function updateDbState()
  99. {
  100. updateLine(
  101. T_ARCHIVES,
  102. array( 'done' => $this->state, 'idarchives' => $this->idArchives),
  103. 'idarchives');
  104. }
  105. /**
  106. * saves var toRecord values in the database, serializing arrays
  107. */
  108. function saveDb()
  109. {
  110. if(
  111. // day + simple day archive, means array empty, do NOT compress
  112. // ($this->periodType === DB_ARCHIVES_PERIOD_DAY && !CURRENT_DAY_SIMPLE_ARCHIVE)
  113. // ||
  114. // ($this->periodType !== DB_ARCHIVES_PERIOD_DAY && !CURRENT_PERIOD_SIMPLE_ARCHIVE)
  115. COMPRESS_DB_DATA
  116. && function_exists('gzcompress'))
  117. {
  118. $this->toRecord['compressed'] = 1;
  119. }
  120. else
  121. {
  122. $this->toRecord['compressed'] = 0;
  123. }
  124. foreach($this->toRecord as $fieldName => $a_value)
  125. {
  126. if(is_array($a_value))
  127. {
  128. $a_value = databaseEscape(compress(serialize($a_value), $this->toRecord['compressed']));
  129. }
  130. updateLine(
  131. T_ARCHIVES,
  132. array( $fieldName => $a_value, 'idarchives' => $this->idArchives),
  133. 'idarchives');
  134. }
  135. $this->updateDbState();
  136. }
  137. /**
  138. * set periodType
  139. *
  140. * @param int $type
  141. */
  142. function setPeriodType($type)
  143. {
  144. $this->periodType = $type;
  145. }
  146. function getLiteralDate()
  147. {
  148. return $this->literalDate;
  149. }
  150. function setLiteralDate()
  151. {
  152. switch($this->periodType)
  153. {
  154. case DB_ARCHIVES_PERIOD_DAY:
  155. $typeDateDisplay = 1;
  156. break;
  157. case DB_ARCHIVES_PERIOD_WEEK:
  158. $typeDateDisplay = 6;
  159. break;
  160. case DB_ARCHIVES_PERIOD_MONTH:
  161. $typeDateDisplay = 4;
  162. break;
  163. case DB_ARCHIVES_PERIOD_YEAR:
  164. $typeDateDisplay = 11;
  165. break;
  166. }
  167. $this->literalDate = getDateDisplay($typeDateDisplay, $this->date);
  168. }
  169. /**
  170. * init the database, inserting a new row for the current archive process
  171. * assigns var idArchives
  172. *
  173. * @return true
  174. */
  175. function initDb()
  176. {
  177. if($this->periodType !== DB_ARCHIVES_PERIOD_DAY )
  178. {
  179. // period
  180. // we want to delete archive period that are DONE
  181. // but for period that were not totaly finished when archived
  182. // mean for example : delete Month archive 2005-12-01 => 2005-12-12 (archived the 13th of december 2005)
  183. // simply delete archive corresponding to this one, but olded
  184. $r = query("DELETE
  185. FROM ".T_ARCHIVES."
  186. WHERE idsite = ".$this->site->getId()."
  187. AND done = ".DB_ARCHIVES_DONE."
  188. AND period = ".$this->periodType ."
  189. AND date1 = '".$this->date->get()."'
  190. ");
  191. }
  192. $r2 = query("INSERT INTO ".T_ARCHIVES." (idsite, done, period, date1, date2)" .
  193. " VALUES (".$this->site->getId().", " .
  194. " ". DB_ARCHIVES_FAIL."," .
  195. $this->periodType .", ".
  196. " '".$this->date->get()."'," .
  197. " '".$this->date2->get()."')"
  198. );
  199. $this->idArchives = mysql_insert_id();
  200. return true;
  201. }
  202. function deleteOldRecords( $force = false)
  203. {
  204. // delete failed archives
  205. // delete temp archives older than today
  206. // date2 <> yesterday because of monthly and weekly archive for months/week not finished yet
  207. // once on 10 calls
  208. if( $force
  209. || time() % 10 == 0)
  210. {
  211. $r = query("DELETE FROM ".T_ARCHIVES."
  212. WHERE done = ".DB_ARCHIVES_FAIL."
  213. OR (done = ".DB_ARCHIVES_TEMP."
  214. AND date1 <> '".date("Y-m-d")."'
  215. AND date2 <> '".date("Y-m-d")."'
  216. AND date2 <> '".date("Y-m-d", time()-86400)."'
  217. )
  218. ");
  219. }
  220. if( time() % 30 == 0)
  221. {
  222. $r = query("OPTIMIZE TABLE ".T_ARCHIVES);
  223. $r = query("OPTIMIZE TABLE ".T_VISIT);
  224. }
  225. // delete doubled archives
  226. // delete for days
  227. // double archive is when concat(idsite, date1) is the same
  228. // for period = DB_DAYS and done = DONE
  229. //$this->deleteDoubleArchives(true);
  230. // delete for other period than days (week/month/year)
  231. // double archive is when concat(idsite, date1, date2) is the same
  232. // for period <> DB_DAYS and done = DONE
  233. $this->deleteDoubleArchives(false);
  234. }
  235. function deleteDoubleArchives( $dayPeriod )
  236. {
  237. if($dayPeriod)
  238. {
  239. $concatSQL = 'CONCAT( idsite , period, date1)';
  240. $periodTest = '=';
  241. }
  242. else
  243. {
  244. $concatSQL = 'CONCAT( idsite , period, date1, date2)';
  245. $periodTest = '<>';
  246. }
  247. $r = query("SELECT count(*) as c, idsite, date1, date2, $concatSQL as ac
  248. FROM ".T_ARCHIVES."
  249. WHERE period ".$periodTest." ".DB_ARCHIVES_PERIOD_DAY."
  250. GROUP BY ac
  251. HAVING c > 1"
  252. );
  253. while($l = mysql_fetch_assoc($r))
  254. {
  255. //print($l['c'] . ": ". $l['idsite']." for date " . $l['date1']."<>".$l['date2']." ( ".$l['ac'].")<br>");
  256. $concatToLookFor = $l['ac'];
  257. // for the date select the archives to keep
  258. $r2 = query("SELECT idarchives as id
  259. FROM ".T_ARCHIVES."
  260. WHERE $concatSQL = '".$concatToLookFor."'
  261. ORDER BY idarchives DESC
  262. LIMIT 1");
  263. $l2 = mysql_fetch_assoc($r2);
  264. $idToKeep = $l2['id'];
  265. // print("keep id $idToKeep <br>");
  266. $r3 = query("DELETE
  267. FROM ".T_ARCHIVES."
  268. WHERE $concatSQL = '".$concatToLookFor."'
  269. AND idarchives <> $idToKeep
  270. ");
  271. //print("deleted ".mysql_affected_rows()." doublons <br>");
  272. }
  273. }
  274. /**
  275. * offset the date, considering the date of the first log record for the current site
  276. * and considering today date. It gives a date which is between these 2 dates.
  277. *
  278. * @param object $o_date
  279. */
  280. function offsetDate($o_date, $minDay = null)
  281. {
  282. $o_dateR = new Date($o_date->get());
  283. if(is_null($minDay))
  284. $minDay = $this->site->getMinDay();
  285. // Manage with future
  286. if($o_date->getTimestamp() > time())
  287. {
  288. $o_dateR = new Date(getDateFromTimestamp(time()));
  289. }
  290. // manage with past
  291. if($o_date->getTimestamp() < $minDay->getTimestamp())
  292. {
  293. $o_dateR = $minDay;
  294. }
  295. return $o_dateR;
  296. }
  297. /**
  298. * Returns limit of the period periodType containing $s_date
  299. * Works with weeks, month, years, and misc periods (in this case, minDate is the first day where there are logs)
  300. *
  301. * @param string $s_date
  302. */
  303. function getPeriodDatesLimit($s_date)
  304. {
  305. // objects
  306. $date = new Date($s_date);
  307. $minDate = $this->site->getMinDay();
  308. $date = $this->offsetDate($date);
  309. //printDebug("MinDate is ".$minDate->get()."<br>Date asked is $s_date<br>Date after Offset is ".$date->get()."<br>");
  310. switch ($this->periodType) {
  311. case DB_ARCHIVES_PERIOD_MONTH:
  312. // detect min day for the month
  313. // if the minimum date month is different, we surely take the whole month
  314. if($minDate->getMonth() == $date->getMonth()
  315. && $minDate->getYear() == $date->getYear())
  316. {
  317. $minDateForSure = $minDate->get();
  318. }
  319. else
  320. {
  321. $minDateForSure = $date->getYear()."-".$date->getMonth()."-01";
  322. }
  323. // detect max date for the month
  324. // if month asked is the current month then max day is today, else its the last day of the month
  325. if($date->getMonth() == date("m") && $date->getYear() == date("Y")) // >= because if month in future, take today
  326. {
  327. $maxDateForSure = getDateFromTimestamp(time()-86400);
  328. }
  329. else
  330. {
  331. $maxDateForSure = $date->getYear()."-".$date->getMonth()."-".date("t", $date->getTimestamp());
  332. }
  333. break;
  334. case DB_ARCHIVES_PERIOD_WEEK:
  335. $time = $date->getTimestamp();
  336. // detect beginning of the week
  337. while(date("W", $time-86400) == $date->getWeek()
  338. && $time-86400 >= $minDate->getTimestamp()
  339. )
  340. {
  341. $time -= 86400;
  342. }
  343. $minDateForSure = getDateFromTimestamp($time);
  344. // end of week
  345. while(date("W", $time+86400) == $date->getWeek()
  346. && $time+86400 <= time()
  347. )
  348. {
  349. $time += 86400;
  350. }
  351. $maxDateForSure = getDateFromTimestamp($time);
  352. break;
  353. case DB_ARCHIVES_PERIOD_MISC_PERIOD:
  354. $minDateForSure = $minDate->get();
  355. $maxDateForSure = $date->get();
  356. break;
  357. case DB_ARCHIVES_PERIOD_YEAR:
  358. // min is minDate if year common
  359. if($date->getYear() == date("Y", $minDate->getYear()))
  360. {
  361. $minDateForSure = $minDate->get();
  362. }
  363. else
  364. {
  365. $minDateForSure = $date->getYear()."-01-01";
  366. }
  367. // max date is today if year is current year
  368. if($date->getYear() == date("Y"))
  369. {
  370. $maxDateForSure = getDateFromTimestamp(time());
  371. }
  372. else
  373. {
  374. $maxDateForSure = $date->getYear()."-12-31";
  375. }
  376. break;
  377. default:
  378. break;
  379. }
  380. $this->date = new Date($minDateForSure);
  381. $this->date2 = new Date($maxDateForSure);
  382. $this->date = $this->offsetDate($this->date);
  383. $this->date2 = $this->offsetDate($this->date2);
  384. }
  385. function sortAndLimitToRecord()
  386. {
  387. $doNotSort = array('vis_st', 'vis_lt', 'pag_st', 'pag_lt', 'vis_lth', 'vis_nb_pag', 'vis_nb_vis');
  388. foreach ($this->arrayOneDimToSum as $name)
  389. {
  390. if( !in_array($name, $doNotSort))
  391. {
  392. arsort($this->toRecord[$name]);
  393. }
  394. $this->toRecord[$name] = getArrayOffsetLimit($this->toRecord[$name], 0, MAX_DISTINCT_ELEMENTS);
  395. }
  396. foreach($this->arrayPmvSumToSum as $name)
  397. {
  398. uasort($this->toRecord[$name], "sortingPmv");
  399. $this->toRecord[$name] = getArrayOffsetLimit($this->toRecord[$name], 0, MAX_DISTINCT_ELEMENTS);
  400. }
  401. foreach($this->arrayIntToSum as $name)
  402. {
  403. uasort($this->toRecord[$name], "sortingInterest");
  404. $this->toRecord[$name] = getArrayOffsetLimit($this->toRecord[$name], 0, MAX_DISTINCT_INTEREST_ELEMENTS);
  405. }
  406. }
  407. }
  408. ?>